diff --git a/package.json b/package.json index dd72aa6..e2e223a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@json.ms/www", "private": true, "type": "module", - "version": "1.2.21", + "version": "1.3.0", "scripts": { "dev": "vite --host", "build": "run-p type-check \"build-only {@}\" --", diff --git a/src/components/FieldItemErrorTooltip.vue b/src/components/FieldItemErrorTooltip.vue index 9dc1fbe..2b1f0ca 100644 --- a/src/components/FieldItemErrorTooltip.vue +++ b/src/components/FieldItemErrorTooltip.vue @@ -35,17 +35,17 @@ const errorMessage = computed((): string | null => { if (errors.value.general.length > 0) { const item = errors.value.general[0].split('.').pop(); if (item) { - return `${fields[item].label} field has an issue`; + return `${fields[item].label} field is missing a value`; } } else if (errors.value.currentI18n.length > 0) { const errorField = getFieldByPath(root.sections, errors.value.currentI18n[0]); - return `${errorField.label} field has an issue`; + return `${errorField.label} field is missing a value`; } else if (errors.value.i18n.length > 0) { const items = errors.value.i18n[0].split('.'); const key = items.pop(); const errorField = getFieldByPath(root.sections, errors.value.i18n[0]); if (errorField && key) { - return `${errorField.label} field has an issue in ${locales[key]}` + return `${errorField.label} field is missing a value in ${locales[key]}` } } return null; @@ -56,10 +56,10 @@ const errors = ref({ currentI18n: [], general: [], }); -watch([() => fieldKey, () => value.value, () => locale.value], () => { +watch([() => fieldKey, () => value.value, () => locale], () => { const userDataErrors = getUserDataErrors( fields, - fieldKey + (index ? '[' + index + ']' : ''), + fieldKey + (index >= 0 ? ('[' + index + ']') : ''), parent, ); const allErrorKeys = Object.keys(userDataErrors); @@ -80,7 +80,7 @@ watch([() => fieldKey, () => value.value, () => locale.value], () => { location="bottom" > fieldKey, () => value.value, () => locale.value], () => { location="bottom" > diff --git a/src/components/JSONms.vue b/src/components/JSONms.vue index e80e402..0d5961d 100644 --- a/src/components/JSONms.vue +++ b/src/components/JSONms.vue @@ -486,6 +486,7 @@ if (globalStore.session.loggedIn) { v-model="editJsonContent" v-model:visible="showEditJson" @apply="onApplyJsonContent" + @clean="onEditJson" /> diff --git a/src/components/JsonEditModal.vue b/src/components/JsonEditModal.vue index a9ec01f..8fc9bca 100644 --- a/src/components/JsonEditModal.vue +++ b/src/components/JsonEditModal.vue @@ -4,8 +4,9 @@ import {useGlobalStore} from '@/stores/global'; import {type Ref, ref, watch} from "vue"; import type {VAceEditorInstance} from "vue3-ace-editor/types"; import ModalDialog from '@/components/ModalDialog.vue'; +import {useUserData} from "@/composables/user-data"; -const emit = defineEmits(['apply']); +const emit = defineEmits(['apply', 'clean']); const editor: Ref = ref(null); const content = defineModel({ required: true }); const visible = defineModel('visible', { required: true }); @@ -15,6 +16,7 @@ const options = ref({ tabSize: 2, }); const globalStore = useGlobalStore(); +const { cleanUserData } = useUserData(); const apply = () => { try { @@ -35,6 +37,23 @@ const close = () => { visible.value = false; } +const onCleanUserData = () => { + globalStore.setPrompt({ + ...globalStore.prompt, + visible: true, + title: 'Clean data', + body: 'Are you sure you want to clean your data? This will remove any property and value that doesn\'t match your structure.', + btnText: 'Clean data', + btnIcon: 'mdi-vacuum-outline', + btnColor: 'warning', + callback: () => new Promise(resolve => { + cleanUserData() + emit('clean'); + resolve(); + }) + }) +} + watch(() => globalStore.userSettings.data, () => { options.value.fontSize = globalStore.userSettings.data.editorFontSize; options.value.tabSize = globalStore.userSettings.data.editorTabSize; @@ -67,6 +86,14 @@ watch(() => globalStore.userSettings.data, () => { /> + + void - onCollapsableHeader?: (item: any, index: number) => ({ title?: string, thumbnail?: string}) + onCollapsableHeader?: (item: any, index: number) => ({ title: string, thumbnail: string | boolean}) }>() const panel = ref(null); diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index e37bc38..9e28ef3 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -53,18 +53,18 @@ const getErrorMsg = (section: ISection, sectionKey: string | number): string | n const locales = structureParsedData.value.locales; if (errors.general.length > 0) { const path = errors.general[0]; - return `Field path "${path}" has an issue` + return `Field path "${path}" is missing a value` } else if (errors.currentI18n.length > 0) { const items = errors.currentI18n[0].split('.'); items.pop(); const path = items.join('.') - return `Field path "${path}" has an issue`; + return `Field path "${path}" is missing a value`; } else if (errors.i18n.length > 0) { const items = errors.i18n[0].split('.'); const locale = items.pop(); const path = items.join('.'); if (locale) { - return `Field path "${path}" field has an issue in ${locales[locale]}` + return `Field path "${path}" is missing a value in ${locales[locale]}` } } return null; @@ -133,7 +133,7 @@ watch(() => serverSettings.version, () => { max-width="400" > serverSettings.version, () => { max-width="400" > diff --git a/src/components/Toolbar.vue b/src/components/Toolbar.vue index 64928b6..9692b0a 100644 --- a/src/components/Toolbar.vue +++ b/src/components/Toolbar.vue @@ -34,7 +34,7 @@ const { smAndDown } = useDisplay(); const { windowWidth, layoutSize } = useLayout(); const { serverSettings, createStructure } = useStructure() const { migrating } = useMigration() -const { downloadUserData, downloading, userDataLoading, setUserData, cleanUserData, fetchUserData, canFetchUserData, canInteractWithServer, getUserDataErrors } = useUserData(); +const { downloadUserData, downloading, userDataLoading, setUserData, fetchUserData, canFetchUserData, canInteractWithServer, getUserDataErrors } = useUserData(); const { reloading } = useIframe() const emit = defineEmits(['locale', 'preview', 'refresh', 'update:model-value', 'create', 'save', 'delete', 'edit-json', 'migrate-data', 'logout']) @@ -116,22 +116,6 @@ const onFetchUserData = () => { }) } -const onCleanUserData = () => { - globalStore.setPrompt({ - ...globalStore.prompt, - visible: true, - title: 'Clean data', - body: 'Are you sure you want to clean your data? This will remove any property and value that doesn\'t match your structure.', - btnText: 'Clean data', - btnIcon: 'mdi-vacuum-outline', - btnColor: 'warning', - callback: () => new Promise(resolve => { - cleanUserData() - resolve(); - }) - }) -} - const onClearUserData = () => { globalStore.setPrompt({ ...globalStore.prompt, @@ -384,12 +368,6 @@ watch(() => currentRoute.params.locale, () => { prepend-icon="mdi-folder-arrow-left-right-outline" @click="onMigrateData" /> - { - parent[key].push(getParsedFields(field.fields, locales, overrideItem)); + parent[key].push(getParsedFields(field.fields, locales, overrideItem, clean)); }) } else if (field.items && Array.isArray(overrideValue)) { return parent[key] = overrideValue;