diff options
author | 2023-04-10 16:34:10 +0200 | |
---|---|---|
committer | 2023-04-10 16:42:06 +0200 | |
commit | 05f06f6a072e8421c48ebe7c2bafcbbe056163ed (patch) | |
tree | 690128cfc6b63912fef2a0a9cf6b68295ac9592b /src | |
parent | 9fa4c26929116ad896ab81bb02edfca8685087a3 (diff) | |
download | it-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.vue | 57 | ||||
-rw-r--r-- | src/components/TextareaCopyable.vue | 2 | ||||
-rw-r--r-- | src/composable/validation.ts | 2 | ||||
-rw-r--r-- | src/tools/json-minify/json-minify.vue | 66 |
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> |