aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Corentin Thomasset <corentin.thomasset74@gmail.com> 2023-04-10 16:34:10 +0200
committerGravatar Corentin THOMASSET <corentin.thomasset74@gmail.com> 2023-04-10 16:42:06 +0200
commit05f06f6a072e8421c48ebe7c2bafcbbe056163ed (patch)
tree690128cfc6b63912fef2a0a9cf6b68295ac9592b /src
parent9fa4c26929116ad896ab81bb02edfca8685087a3 (diff)
downloadit-tools-05f06f6a072e8421c48ebe7c2bafcbbe056163ed.tar.gz
it-tools-05f06f6a072e8421c48ebe7c2bafcbbe056163ed.tar.zst
it-tools-05f06f6a072e8421c48ebe7c2bafcbbe056163ed.zip
refactor(dx): generic data transformer
Diffstat (limited to 'src')
-rw-r--r--src/components/FormatTransformer.vue57
-rw-r--r--src/components/TextareaCopyable.vue2
-rw-r--r--src/composable/validation.ts2
-rw-r--r--src/tools/json-minify/json-minify.vue66
4 files changed, 77 insertions, 50 deletions
diff --git a/src/components/FormatTransformer.vue b/src/components/FormatTransformer.vue
new file mode 100644
index 0000000..dea5d56
--- /dev/null
+++ b/src/components/FormatTransformer.vue
@@ -0,0 +1,57 @@
+<template>
+ <n-form-item :label="inputLabel" v-bind="validationAttrs">
+ <n-input
+ ref="inputElement"
+ v-model:value="input"
+ :placeholder="inputPlaceholder"
+ type="textarea"
+ rows="20"
+ autocomplete="off"
+ autocorrect="off"
+ autocapitalize="off"
+ spellcheck="false"
+ :input-props="{ 'data-test-id': 'input' }"
+ />
+ </n-form-item>
+ <n-form-item :label="outputLabel">
+ <textarea-copyable :value="output" :language="outputLanguage" :follow-height-of="inputElement" />
+ </n-form-item>
+</template>
+
+<script setup lang="ts">
+import { useValidation, type UseValidationRule } from '@/composable/validation';
+import _ from 'lodash';
+
+const props = withDefaults(
+ defineProps<{
+ transformer?: (v: string) => string;
+ inputValidationRules?: UseValidationRule<string>[];
+ inputLabel?: string;
+ inputPlaceholder?: string;
+ inputDefault?: string;
+ outputLabel?: string;
+ outputLanguage?: string;
+ }>(),
+ {
+ transformer: _.identity,
+ inputValidationRules: () => [],
+ inputLabel: 'Input',
+ inputDefault: '',
+ inputPlaceholder: 'Input...',
+ outputLabel: 'Output',
+ outputLanguage: '',
+ },
+);
+
+const { transformer, inputValidationRules, inputLabel, outputLabel, outputLanguage, inputPlaceholder, inputDefault } =
+ toRefs(props);
+
+const inputElement = ref();
+
+const input = ref(inputDefault.value);
+const output = computed(() => transformer.value(input.value));
+
+const { attrs: validationAttrs } = useValidation({ source: input, rules: inputValidationRules.value });
+</script>
+
+<style scoped></style>
diff --git a/src/components/TextareaCopyable.vue b/src/components/TextareaCopyable.vue
index 9bcb65c..6be5652 100644
--- a/src/components/TextareaCopyable.vue
+++ b/src/components/TextareaCopyable.vue
@@ -7,7 +7,7 @@
:style="height ? `min-height: ${height - 40 /* card padding */ + 10 /* negative margin compensation */}px` : ''"
>
<n-config-provider :hljs="hljs">
- <n-code :code="value" :language="language" :trim="false" />
+ <n-code :code="value" :language="language" :trim="false" data-test-id="area-content" />
</n-config-provider>
</n-scrollbar>
<n-tooltip v-if="value" trigger="hover">
diff --git a/src/composable/validation.ts b/src/composable/validation.ts
index 2c58b60..527aafa 100644
--- a/src/composable/validation.ts
+++ b/src/composable/validation.ts
@@ -3,7 +3,7 @@ import { reactive, watch, type Ref } from 'vue';
type ValidatorReturnType = unknown;
-interface UseValidationRule<T> {
+export interface UseValidationRule<T> {
validator: (value: T) => ValidatorReturnType;
message: string;
}
diff --git a/src/tools/json-minify/json-minify.vue b/src/tools/json-minify/json-minify.vue
index 92ab7d2..d7e9d15 100644
--- a/src/tools/json-minify/json-minify.vue
+++ b/src/tools/json-minify/json-minify.vue
@@ -1,57 +1,27 @@
<template>
- <n-form-item
- label="Your raw json"
- :feedback="rawJsonValidation.message"
- :validation-status="rawJsonValidation.status"
- >
- <n-input
- ref="inputElement"
- v-model:value="rawJson"
- placeholder="Paste your raw json here..."
- type="textarea"
- rows="20"
- autocomplete="off"
- autocorrect="off"
- autocapitalize="off"
- spellcheck="false"
- />
- </n-form-item>
- <n-form-item label="Minify version of your JSON">
- <textarea-copyable :value="cleanJson" language="json" :follow-height-of="inputElement" />
- </n-form-item>
+ <format-transformer
+ input-label="Your raw json"
+ :input-default="defaultValue"
+ input-placeholder="Paste your raw json here..."
+ output-label="Minify version of your JSON"
+ output-language="json"
+ :input-validation-rules="rules"
+ :transformer="transformer"
+ />
</template>
<script setup lang="ts">
-import TextareaCopyable from '@/components/TextareaCopyable.vue';
-import { useValidation } from '@/composable/validation';
+import type { UseValidationRule } from '@/composable/validation';
import { withDefaultOnError } from '@/utils/defaults';
import JSON5 from 'json5';
-import { computed, ref } from 'vue';
-const inputElement = ref<HTMLElement>();
+const defaultValue = '{\n\t"hello": [\n\t\t"world"\n\t]\n}';
+const transformer = (value: string) => withDefaultOnError(() => JSON.stringify(JSON5.parse(value), null, 0), '');
-const rawJson = ref('{\n\t"hello": [\n\t\t"world"\n\t]\n}');
-const cleanJson = computed(() => withDefaultOnError(() => JSON.stringify(JSON5.parse(rawJson.value), null, 0), ''));
-
-const rawJsonValidation = useValidation({
- source: rawJson,
- rules: [
- {
- validator: (v) => v === '' || JSON5.parse(v),
- message: 'Provided JSON is not valid.',
- },
- ],
-});
+const rules: UseValidationRule<string>[] = [
+ {
+ validator: (v: string) => v === '' || JSON5.parse(v),
+ message: 'Provided JSON is not valid.',
+ },
+];
</script>
-
-<style lang="less" scoped>
-.result-card {
- position: relative;
-
- .copy-button {
- position: absolute;
- top: 10px;
- right: 10px;
- }
-}
-</style>