first commit
This commit is contained in:
commit
93953e52d7
14
.eslintrc.cjs
Normal file
14
.eslintrc.cjs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
require("@rushstack/eslint-patch/modern-module-resolution");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"root": true,
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/vue3-essential",
|
||||||
|
"eslint:recommended",
|
||||||
|
"@vue/eslint-config-prettier"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"vue/setup-compiler-macros": true
|
||||||
|
}
|
||||||
|
}
|
27
.gitignore
vendored
Normal file
27
.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
config.js
|
||||||
|
config.prod.js
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
FROM debian:bullseye-slim
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND="noninteractive"
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get -y upgrade \
|
||||||
|
&& apt-get -y install \
|
||||||
|
curl nodejs npm \
|
||||||
|
&& npm install -g vue vite n \
|
||||||
|
&& n stable \
|
||||||
|
&& mkdir /app \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* /usr/share/man/* /usr/share/doc/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY ./public public
|
||||||
|
COPY ./src src
|
||||||
|
COPY ./config.prod.js ./config.js
|
||||||
|
COPY ./index.html .
|
||||||
|
COPY ./package.json .
|
||||||
|
COPY ./package-lock.json .
|
||||||
|
COPY ./postcss.config.js .
|
||||||
|
COPY ./tailwind.config.js .
|
||||||
|
COPY ./vite.config.js .
|
||||||
|
|
||||||
|
RUN npm install && npm run build
|
||||||
|
|
||||||
|
FROM nginx
|
||||||
|
COPY --from=0 /app/dist /usr/share/nginx/html
|
||||||
|
COPY ./nginx/conf /etc/nginx/conf.d/
|
1
README.md
Normal file
1
README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Random tools collection
|
6
config.js.example
Normal file
6
config.js.example
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const config = {
|
||||||
|
APP_URL: 'http://localhost:3000',
|
||||||
|
// API_URL: 'http://localhost:8080/v1',
|
||||||
|
};
|
||||||
|
|
||||||
|
export { config }
|
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<link rel="icon" href="/favicon.ico"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<title>Tools</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
23
nginx/conf/default.conf
Normal file
23
nginx/conf/default.conf
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
#access_log /var/log/nginx/host.access.log main;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /map/\d+$ {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# redirect server error pages to the static page /50x.html
|
||||||
|
#
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
1768
package-lock.json
generated
Normal file
1768
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
33
package.json
Normal file
33
package.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "yourmap-tracker",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "vite build",
|
||||||
|
"lint": "eslint .. --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
|
||||||
|
"dev": "vite",
|
||||||
|
"preview": "vite preview --port 3000"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"autoprefixer": "^10",
|
||||||
|
"axios": "^0.27.2",
|
||||||
|
"mitt": "^3.0.0",
|
||||||
|
"pinia": "^2.0.14",
|
||||||
|
"postcss": "^8",
|
||||||
|
"tailwindcss": "^3",
|
||||||
|
"vue": "^3.2.36",
|
||||||
|
"vue-axios": "^3.4.1",
|
||||||
|
"vue-router": "^4.0.15"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@rushstack/eslint-patch": "^1.1.0",
|
||||||
|
"@vitejs/plugin-vue": "^2.3.3",
|
||||||
|
"@vue/eslint-config-prettier": "^7.0.0",
|
||||||
|
"autoprefixer": "^10.4.7",
|
||||||
|
"eslint": "^8.5.0",
|
||||||
|
"eslint-plugin-vue": "^8.2.0",
|
||||||
|
"prettier": "^2.5.1",
|
||||||
|
"sass": "^1.52.3",
|
||||||
|
"vite": "^2.9.9",
|
||||||
|
"vue-cli-plugin-tailwind": "~3.0.0"
|
||||||
|
}
|
||||||
|
}
|
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
71
src/App.vue
Normal file
71
src/App.vue
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="w-full flex flex-col sm:flex-row flex-grow"
|
||||||
|
:class="{ 'sidebar-toggle': sidebarToggle }">
|
||||||
|
<aside
|
||||||
|
class="hidden md:block h-screen overflow-y-auto no-scrollbar border-r">
|
||||||
|
<Sidebar/>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<main role="main" class="w-full h-full flex-grow overflow-auto p-3">
|
||||||
|
<RouterView/>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<button class="sidebar-toggle-btn md:hidden" v-on:click="toggleSidebar">
|
||||||
|
<svg class="svg-icon" style="width: 30px; height: 30px;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M682.666667 682.666667h170.666666v170.666666h-170.666666v-170.666666z m-256 0h170.666666v170.666666h-170.666666v-170.666666z m-256 0h170.666666v170.666666H170.666667v-170.666666z m512-256h170.666666v170.666666h-170.666666v-170.666666z m-256 0h170.666666v170.666666h-170.666666v-170.666666z m-256 0h170.666666v170.666666H170.666667v-170.666666z m512-256h170.666666v170.666666h-170.666666V170.666667z m-256 0h170.666666v170.666666h-170.666666V170.666667zM170.666667 170.666667h170.666666v170.666666H170.666667V170.666667z" fill="#000000" /></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { RouterView } from 'vue-router'
|
||||||
|
import Sidebar from '@/components/Sidebar.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Sidebar,
|
||||||
|
RouterView,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sidebarToggle: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleSidebar() {
|
||||||
|
this.sidebarToggle = !this.sidebarToggle;
|
||||||
|
|
||||||
|
this.emitter.emit('sidebar.toggle');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
aside {
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.sidebar-toggle {
|
||||||
|
aside {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
max-width: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-btn {
|
||||||
|
right: 10px;
|
||||||
|
bottom: 10px;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
23
src/app.js
Normal file
23
src/app.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
import axios from 'axios'
|
||||||
|
import VueAxios from 'vue-axios'
|
||||||
|
import mitt from 'mitt';
|
||||||
|
|
||||||
|
import './assets/app.scss'
|
||||||
|
|
||||||
|
import App from './App.vue'
|
||||||
|
import router from './router'
|
||||||
|
|
||||||
|
axios.defaults.withCredentials = true;
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
|
||||||
|
app.config.globalProperties.emitter = mitt();
|
||||||
|
|
||||||
|
app.use(createPinia())
|
||||||
|
app.use(VueAxios, axios)
|
||||||
|
|
||||||
|
app.use(router)
|
||||||
|
|
||||||
|
app.mount('#app')
|
27
src/assets/app.scss
Normal file
27
src/assets/app.scss
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
@import "tailwindcss/base";
|
||||||
|
@import "tailwindcss/components";
|
||||||
|
@import "tailwindcss/utilities";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components
|
||||||
|
*/
|
||||||
|
input[type=text], input[type=number], textarea {
|
||||||
|
@apply appearance-none border leading-tight focus:outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tools
|
||||||
|
*/
|
||||||
|
.tool-title {
|
||||||
|
@apply font-bold;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
@apply flex flex-col mb-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group > label {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
31
src/components/Sidebar.vue
Normal file
31
src/components/Sidebar.vue
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<header class="flex">
|
||||||
|
<span class="my-auto ml-2 font-bold">Tools</span>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<hr class="mt-2 mb-2">
|
||||||
|
|
||||||
|
<nav class="flex flex-col ml-2">
|
||||||
|
<router-link v-for="[key, value] of Object.entries(menuRoutes)" :to="{name:key}" tag="button">{{ value }}</router-link>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Sidebar",
|
||||||
|
components: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
menuRoutes: {
|
||||||
|
'home': 'Home',
|
||||||
|
'sql_split_in': 'SQL split IN',
|
||||||
|
'str_to_upper': 'Str to upper',
|
||||||
|
'str_to_lower': 'Str to lower',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
40
src/router/index.js
Normal file
40
src/router/index.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
|
routes: [
|
||||||
|
/**
|
||||||
|
* General
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'home',
|
||||||
|
component: () => import('../views/HomeView.vue'),
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String manipulation
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
path: '/str_to_upper',
|
||||||
|
name: 'str_to_upper',
|
||||||
|
component: () => import('../views/StrToUpper.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/str_to_lower',
|
||||||
|
name: 'str_to_lower',
|
||||||
|
component: () => import('../views/StrToLower.vue'),
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL manipulation
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
path: '/sql_split_in',
|
||||||
|
name: 'sql_split_in',
|
||||||
|
component: () => import('../views/SQLSplitInView.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
0
src/stores/.gitkeep
Normal file
0
src/stores/.gitkeep
Normal file
7
src/utils/unproxy.js
Normal file
7
src/utils/unproxy.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
function unproxy(obj) {
|
||||||
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
unproxy,
|
||||||
|
}
|
36
src/utils/useDebouncedRef.js
Normal file
36
src/utils/useDebouncedRef.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { ref, customRef } from 'vue'
|
||||||
|
|
||||||
|
const debounce = (fn, delay = 0, immediate = false) => {
|
||||||
|
let timeout
|
||||||
|
return (...args) => {
|
||||||
|
if (immediate && !timeout) fn(...args)
|
||||||
|
clearTimeout(timeout)
|
||||||
|
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
fn(...args)
|
||||||
|
}, delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const useDebouncedRef = (initialValue, delay, immediate) => {
|
||||||
|
const state = ref(initialValue)
|
||||||
|
const debouncedRef = customRef((track, trigger) => ({
|
||||||
|
get() {
|
||||||
|
track()
|
||||||
|
return state.value
|
||||||
|
},
|
||||||
|
set: debounce(
|
||||||
|
value => {
|
||||||
|
state.value = value
|
||||||
|
trigger()
|
||||||
|
},
|
||||||
|
delay,
|
||||||
|
immediate
|
||||||
|
),
|
||||||
|
}))
|
||||||
|
return debouncedRef
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
useDebouncedRef,
|
||||||
|
}
|
7
src/views/HomeView.vue
Normal file
7
src/views/HomeView.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
/home
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
103
src/views/SQLSplitInView.vue
Normal file
103
src/views/SQLSplitInView.vue
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<h2 class="tool-title">SQL split IN</h2>
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="field_name">Field name</label>
|
||||||
|
<input id="field_name" v-model="toolData.fieldName" placeholder="D.ID" type="text">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="data">Data</label>
|
||||||
|
<textarea id="data" v-model="toolData.data" style="height: 150px"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="data_delimiter">Delimiter</label>
|
||||||
|
<input id="data_delimiter" v-model="toolData.dataDelimiter" placeholder="," type="text">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label>Wrap in quotes</label>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input id="wrap_in_quotes_no" value="" name="wrap_in_quotes" v-model="toolData.wrapInQuotes" type="radio"> <label for="wrap_in_quotes_no">No</label><br>
|
||||||
|
<input id="wrap_in_quotes_single" value="single" name="wrap_in_quotes" v-model="toolData.wrapInQuotes" type="radio"> <label for="wrap_in_quotes_single">Single</label><br>
|
||||||
|
<input id="wrap_in_quotes_double" value="double" name="wrap_in_quotes" v-model="toolData.wrapInQuotes" type="radio"> <label for="wrap_in_quotes_double">Double</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="chunk_by">Chunk by</label>
|
||||||
|
<input id="chunk_by" v-model="toolData.chunkBy" placeholder="900" type="number">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="result">Result</label>
|
||||||
|
<textarea id="result" v-model="toolResult" style="height: 150px"></textarea>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function arrayChunk(arr, chunkSize) {
|
||||||
|
const res = [];
|
||||||
|
while (arr.length > 0) {
|
||||||
|
const chunk = arr.splice(0, chunkSize);
|
||||||
|
res.push(chunk);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
toolData: {
|
||||||
|
fieldName: '',
|
||||||
|
data: '',
|
||||||
|
dataDelimiter: '',
|
||||||
|
wrapInQuotes: '',
|
||||||
|
chunkBy: 900,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
toolResult() {
|
||||||
|
let data = this.toolData.data
|
||||||
|
.split(this.toolData.dataDelimiter ? this.toolData.dataDelimiter : '\n');
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
let value = data[i];
|
||||||
|
|
||||||
|
switch (this.toolData.wrapInQuotes) {
|
||||||
|
case 'single':
|
||||||
|
value = "'" + value.replace("'", "\\'") + "'";
|
||||||
|
break;
|
||||||
|
case 'double':
|
||||||
|
value = '"' + value.replace('"', '\\"') + '"';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[i] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = arrayChunk(data, this.toolData.chunkBy);
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
let chunk = data[i];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data[i] = '(' + chunk.join(',') + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '(' + this.toolData.fieldName + ' IN ' + data.join(' OR ' + this.toolData.fieldName + ' IN ') + ')';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
37
src/views/StrToLower.vue
Normal file
37
src/views/StrToLower.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<h2 class="tool-title">Str to lower</h2>
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="data">Data</label>
|
||||||
|
<textarea id="data" v-model="toolData.data" style="height: 150px"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="result">Result</label>
|
||||||
|
<textarea id="result" v-model="toolResult" style="height: 150px"></textarea>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
toolData: {
|
||||||
|
data: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
toolResult() {
|
||||||
|
return this.toolData.data.toLocaleLowerCase();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
37
src/views/StrToUpper.vue
Normal file
37
src/views/StrToUpper.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<h2 class="tool-title">Str to upper</h2>
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="data">Data</label>
|
||||||
|
<textarea id="data" v-model="toolData.data" style="height: 150px"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-5 mb-5">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="result">Result</label>
|
||||||
|
<textarea id="result" v-model="toolResult" style="height: 150px"></textarea>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
toolData: {
|
||||||
|
data: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
toolResult() {
|
||||||
|
return this.toolData.data.toLocaleUpperCase();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
17
tailwind.config.js
Normal file
17
tailwind.config.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
"./index.html",
|
||||||
|
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||||
|
// "./node_modules/flowbite/**/*.js",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
zIndex: {
|
||||||
|
'500': '500',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
// require('flowbite/plugin')
|
||||||
|
],
|
||||||
|
}
|
29
vite.config.js
Normal file
29
vite.config.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import {fileURLToPath, URL} from 'url'
|
||||||
|
|
||||||
|
import {defineConfig} from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
function pathTo(path) {
|
||||||
|
return fileURLToPath(new URL(path, import.meta.url));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': pathTo('./src', import.meta.url),
|
||||||
|
'@node_modules': pathTo('./node_modules'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
host: true,
|
||||||
|
port: 3000,
|
||||||
|
cors: false,
|
||||||
|
},
|
||||||
|
preview: {
|
||||||
|
host: true,
|
||||||
|
port: 3000,
|
||||||
|
cors: false,
|
||||||
|
}
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user