Refactor views structure

This commit is contained in:
2024-09-29 10:06:13 +03:00
parent f75809c12d
commit 029adcbc17
31 changed files with 58 additions and 56 deletions

View File

@@ -0,0 +1,72 @@
<template>
<h2 class="tool-title">Fix ru-en keyboard</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<textarea id="data" v-model="toolData.data" v-on:keyup="result"></textarea>
</div>
<div class="input-group">
<label>Mode</label>
<div>
<input id="keyboard_mode_en_ru" value="en-ru" name="keyboard_mode" v-model="toolData.keyboardMode"
v-on:change="result" type="radio"> <label for="keyboard_mode_en_ru">en -> ru</label><br>
<input id="keyboard_mode_ru_en" value="ru-en" name="keyboard_mode" v-model="toolData.keyboardMode"
v-on:change="result" type="radio"> <label for="keyboard_mode_ru_en">ru -> en</label>
</div>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import { unproxy } from "@/utils/unproxy";
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: "",
keyboardMode: "en-ru"
},
dictionary: {
"en-ru": "`~!@#$%^&qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?",
"ru-en": "ёЁ!\"№;%:?йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,"
},
toolResult: ""
};
},
methods: {
result() {
let data = unproxy(this.toolData.data).split("");
const dict = this.dictionary[this.toolData.keyboardMode];
const dictOpposite = this.dictionary[this.toolData.keyboardMode === "en-ru" ? "ru-en" : "en-ru"];
for (let i = 0; i < data.length; i++) {
const dictPos = dict.indexOf(data[i]);
if (dictPos === -1) continue;
data[i] = unproxy(dictOpposite[dictPos]);
}
this.toolResult = data.join("");
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,76 @@
<template>
<h2 class="tool-title">Str length</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<textarea id="data" v-model="toolData.data" v-on:keyup="result"></textarea>
</div>
<div class="input-group">
<label for="data_delimiter">Delimiter</label>
<input id="data_delimiter" v-model="toolData.dataDelimiter" v-on:keyup="result" placeholder="," type="text">
<div>
<input id="count_mode_characters" value="characters" name="count_mode" v-model="toolData.countMode"
v-on:change="result" :disabled="toolData.dataDelimiter.length" type="radio"> <label
for="count_mode_characters">characters</label><br>
<input id="count_mode_words" value="words" name="count_mode" v-model="toolData.countMode" v-on:change="result"
:disabled="toolData.dataDelimiter.length" type="radio"> <label for="count_mode_words">words</label><br>
<input id="count_mode_lines" value="lines" name="count_mode" v-model="toolData.countMode" v-on:change="result"
:disabled="toolData.dataDelimiter.length" type="radio"> <label for="count_mode_lines">lines</label>
</div>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: "",
dataDelimiter: "",
countMode: "characters"
},
toolResult: ""
};
},
methods: {
result() {
if (!this.toolData.data.length) {
this.toolResult = 0;
} else if (this.toolData.dataDelimiter.length) {
this.toolResult = this.toolData.data.split(this.toolData.dataDelimiter).length;
} else {
switch (this.toolData.countMode) {
case "characters":
this.toolResult = this.toolData.data.length;
break;
case "words":
this.toolResult = this.toolData.data.trim().split(/\s+/).length;
break;
case "lines":
this.toolResult = this.toolData.data.split("\n").length;
break;
}
}
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,55 @@
<template>
<h2 class="tool-title">Str to NATO alphabet</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<input id="data" v-model="toolData.data" v-on:keyup="result" type="text">
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="php" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import axios from "axios";
import { config } from "../../../config";
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: ""
},
toolResult: ""
};
},
methods: {
result() {
const natoAlphabet = {
"A": "Alpha", "B": "Bravo", "C": "Charlie", "D": "Delta",
"E": "Echo", "F": "Foxtrot", "G": "Golf", "H": "Hotel",
"I": "India", "J": "Juliett", "K": "Kilo", "L": "Lima",
"M": "Mike", "N": "November", "O": "Oscar", "P": "Papa",
"Q": "Quebec", "R": "Romeo", "S": "Sierra", "T": "Tango",
"U": "Uniform", "V": "Victor", "W": "Whiskey", "X": "X-ray",
"Y": "Yankee", "Z": "Zulu"
};
this.toolResult = this.toolData.data.toUpperCase().split("").map(char => natoAlphabet[char] || char).join(" ");
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,55 @@
<template>
<h2 class="tool-title">Str numeronym</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<input id="data" v-model="toolData.data" v-on:keyup="result" type="text">
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
import { unproxy } from "../../utils/unproxy";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: ""
},
toolResult: ""
};
},
methods: {
result() {
const word = unproxy(this.toolData.data);
if (word.length <= 3) {
this.toolResult = word;
return;
}
const firstLetter = word[0];
const lastLetter = word[word.length - 1];
const numberOfLetters = word.length - 2;
this.toolResult = `${firstLetter}${numberOfLetters}${lastLetter}`;
}
}
};
</script>
<style lang="scss">
</style>

102
src/views/strings/Pad.vue Normal file
View File

@@ -0,0 +1,102 @@
<template>
<h2 class="tool-title">Str pad</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<textarea id="data" v-model="toolData.data" v-on:keyup="result"></textarea>
</div>
<div class="input-group">
<label for="data">Symbol</label>
<input id="data" class="input" v-model="toolData.padSymbol" v-on:keyup="result" placeholder="0" type="text">
</div>
<div class="input-group">
<label for="data">Pad count / Fixed length</label>
<input id="data" class="input" v-model="toolData.padCount" v-on:keyup="result" placeholder="0" type="text">
</div>
<div class="input-group">
<label>Pad position</label>
<div>
<input id="pad_pos_begin" value="begin" name="pad_pos" v-model="toolData.padPos" v-on:change="result"
type="radio"> <label for="pad_pos_begin">begin</label><br>
<input id="pad_pos_end" value="end" name="pad_pos" v-model="toolData.padPos" v-on:change="result" type="radio">
<label for="pad_pos_end">end</label>
</div>
</div>
<div class="input-group">
<label>Pad by</label>
<div>
<input id="pad_by_repeat_symbol" value="repeat_symbol" name="pad_by" v-model="toolData.padBy" v-on:change="result"
type="radio"> <label for="pad_by_repeat_symbol">repeat symbol</label><br>
<input id="pad_by_string_length" value="string_length" name="pad_by" v-model="toolData.padBy" v-on:change="result"
type="radio"> <label for="pad_by_string_length">to string length</label>
</div>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: "",
padSymbol: "0",
padCount: 3,
padPos: "begin",
padBy: "string_length"
},
toolResult: ""
};
},
methods: {
result() {
const lines = this.toolData.data.split("\n");
const paddedLines = lines.map((line) => {
if (this.toolData.padBy === "string_length") {
const padLength = Math.max(0, this.toolData.padCount - line.length);
const padding = this.toolData.padSymbol.repeat(padLength);
if (this.toolData.padPos === "begin") {
return padding + line;
} else {
return line + padding;
}
} else {
const padding = this.toolData.padSymbol.repeat(this.toolData.padCount);
if (this.toolData.padPos === "begin") {
return padding + line;
} else {
return line + padding;
}
}
});
this.toolResult = paddedLines.join("\n");
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,47 @@
<template>
<h2 class="tool-title">Str remove duplicate lines</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<textarea id="data" v-model="toolData.data" v-on:keyup="result"></textarea>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
function arrayUnique(value, index, array) {
return array.indexOf(value) === index;
}
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: ""
},
toolResult: ""
};
},
methods: {
result() {
this.toolResult = this.toolData.data.split("\n").filter(arrayUnique).join("\n");
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,95 @@
<template>
<h2 class="tool-title">Str sort lines</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<textarea id="data" v-model="toolData.data" v-on:keyup="result"></textarea>
</div>
<div class="input-group">
<label>Mode</label>
<div>
<input id="sort_mode_alpha" value="alpha" name="sort_mode" v-model="toolData.sortMode" v-on:change="result"
type="radio"> <label for="sort_mode_alpha">alphabetically</label><br>
<input id="sort_mode_numerically" value="numerically" name="sort_mode" v-model="toolData.sortMode"
v-on:change="result" type="radio"> <label for="sort_mode_numerically">numerically</label><br>
<input id="sort_mode_by_length" value="by_length" name="sort_mode" v-model="toolData.sortMode"
v-on:change="result" type="radio"> <label for="sort_mode_by_length">by length</label><br>
<input id="sort_mode_random" value="random" name="sort_mode" v-model="toolData.sortMode" v-on:change="result"
type="radio"> <label for="sort_mode_random">random</label><br>
<br>
<input id="sort_mode_reverse" value="random" name="sort_mode_reverse" v-model="toolData.sortModeReverse"
v-on:change="result" type="checkbox"> <label for="sort_mode_reverse">reverse</label>
</div>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: "",
sortMode: "alpha",
sortModeReverse: false
},
toolResult: ""
};
},
methods: {
result() {
let result = [];
const data = this.toolData.data.split("\n");
switch (this.toolData.sortMode) {
case "alpha":
result = data.sort(function(a, b) {
return a.localeCompare(b);
});
break;
case "numerically":
const collator = new Intl.Collator([], { numeric: true });
result = data.sort(function(a, b) {
return collator.compare(a, b);
});
break;
case "by_length":
result = data.sort(function(a, b) {
return a.length - b.length;
});
break;
case "random":
result = data.sort(function(a, b) {
return Math.random() - .5;
});
break;
}
if (this.toolData.sortModeReverse) {
result = result.reverse();
}
this.toolResult = result.join("\n");
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,62 @@
<template>
<h2 class="tool-title">Str to lower/upper</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<textarea id="data" v-model="toolData.data" v-on:keyup="result"></textarea>
</div>
<div class="input-group">
<label>Mode</label>
<div>
<input id="case_mode_lower" value="lower" name="case_mode" v-model="toolData.caseMode" v-on:change="result"
type="radio"> <label for="case_mode_lower">to lower</label><br>
<input id="case_mode_upper" value="upper" name="case_mode" v-model="toolData.caseMode" v-on:change="result"
type="radio"> <label for="case_mode_upper">to upper</label>
</div>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: "",
caseMode: "upper"
},
toolResult: ""
};
},
methods: {
result() {
switch (this.toolData.caseMode) {
case "lower":
this.toolResult = this.toolData.data.toLocaleLowerCase();
break;
case "upper":
this.toolResult = this.toolData.data.toLocaleUpperCase();
break;
}
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,62 @@
<template>
<h2 class="tool-title">URL encode/decode</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<textarea id="data" v-model="toolData.data" v-on:keyup="result"></textarea>
</div>
<div class="input-group">
<label>Mode</label>
<div>
<input id="encode_mode_encode" value="encode" name="encode_mode" v-model="toolData.encodeMode"
v-on:change="result" type="radio"> <label for="encode_mode_encode">encode</label><br>
<input id="encode_mode_decode" value="decode" name="encode_mode" v-model="toolData.encodeMode"
v-on:change="result" type="radio"> <label for="encode_mode_decode">decode</label>
</div>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
data: "",
encodeMode: "decode"
},
toolResult: ""
};
},
methods: {
result() {
switch (this.toolData.encodeMode) {
case "encode":
this.toolResult = this.toolData.data.split("\n").map(encodeURIComponent).join("\n");
break;
case "decode":
this.toolResult = this.toolData.data.split("\n").map(decodeURIComponent).join("\n");
break;
}
}
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,86 @@
<template>
<h2 class="tool-title">URL query viewer</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="data">Data</label>
<input id="data" v-model="toolData.data" v-on:keyup="result" type="url">
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<table>
<tbody>
<tr v-for="row in toolData.queryParts">
<td><input :value="row.key" style="width: 100%;" type="text" readonly></td>
<td><input :value="row.value" style="width: 100%;" type="text" readonly></td>
</tr>
</tbody>
</table>
<p v-if="!toolData.queryParts.length">invalid url</p>
</div>
</template>
<script>
function isValidUrl(string) {
let url;
try {
url = new URL(string);
} catch (_) {
return false;
}
return url.protocol === "http:" || url.protocol === "https:";
}
export default {
data() {
return {
toolData: {
data: "",
queryParts: []
},
toolResult: ""
};
},
methods: {
result() {
// Reset
this.toolData.queryParts = [];
// Check url
if (!isValidUrl(this.toolData.data)) {
return;
}
const url = new URL(this.toolData.data);
// Parse query
const queryParams = [];
for (let [key, value] of url.searchParams.entries()) {
queryParams.push({
key: key,
value: value
});
}
this.toolData.queryParts = queryParams.sort((a, b) => {
return a.key.localeCompare(b.key);
});
}
}
};
</script>
<style lang="scss">
table tr:nth-child(even) input {
background-color: #fbfbfb;
}
table tr:nth-child(odd) input {
background-color: #eee;
}
</style>