first commit

This commit is contained in:
2023-11-10 16:00:27 +02:00
commit 93953e52d7
25 changed files with 2385 additions and 0 deletions

71
src/App.vue Normal file
View 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
View 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
View 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;
}

View 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
View 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
View File

7
src/utils/unproxy.js Normal file
View File

@ -0,0 +1,7 @@
function unproxy(obj) {
return JSON.parse(JSON.stringify(obj));
}
export {
unproxy,
}

View 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
View File

@ -0,0 +1,7 @@
<template>
/home
</template>
<style lang="scss">
</style>

View 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
View 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
View 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>