diff --git a/docs/structure.md b/docs/structure.md
index de928f9..27579af 100644
--- a/docs/structure.md
+++ b/docs/structure.md
@@ -37,6 +37,7 @@ The following YAML example defines a simplified section for an admin panel, spec
sections:
home: # Customizable key
label: Home page
+ title: My data # Optional (to be displayed in the data sidebar)
fields:
title: # Customizable key
type: i18n
diff --git a/package.json b/package.json
index ec81b1d..dd72aa6 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "@json.ms/www",
"private": true,
"type": "module",
- "version": "1.2.20",
+ "version": "1.2.21",
"scripts": {
"dev": "vite --host",
"build": "run-p type-check \"build-only {@}\" --",
diff --git a/src/components/ActionBar.vue b/src/components/ActionBar.vue
index 51af7a5..d8b38f1 100644
--- a/src/components/ActionBar.vue
+++ b/src/components/ActionBar.vue
@@ -79,7 +79,7 @@ const reset = () => {
-
+
@@ -155,8 +155,9 @@ const reset = () => {
:readonly="userDataSaved"
:color="canSave ? 'primary' : undefined"
:class="['w-100', {
- 'pr-16': globalStore.admin.structure
+ 'pr-10': globalStore.admin.structure
}]"
+ size="small"
@click.stop.prevent="save"
>
@@ -177,8 +178,9 @@ const reset = () => {
v-if="globalStore.admin.structure"
v-bind="props"
:disabled="!userDataHasChanged"
- variant="flat"
:color="userDataHasChanged ? 'primary' : undefined"
+ variant="flat"
+ size="small"
class="position-absolute"
style="right: 0; border-top-left-radius: 0; border-bottom-left-radius: 0"
min-width="0"
@@ -210,6 +212,7 @@ const reset = () => {
diff --git a/src/components/DataEditor.vue b/src/components/DataEditor.vue
index 76fc093..1360235 100644
--- a/src/components/DataEditor.vue
+++ b/src/components/DataEditor.vue
@@ -82,7 +82,7 @@ const canEditData = computed((): boolean => {
- {{ selectedSection.label }}
+ {{ selectedSection.title || selectedSection.label }}
diff --git a/src/components/GlobalComponents.vue b/src/components/GlobalComponents.vue
index 1d82e0d..df0ead0 100644
--- a/src/components/GlobalComponents.vue
+++ b/src/components/GlobalComponents.vue
@@ -2,12 +2,10 @@
import Prompt from '@/components/Prompt.vue';
import Error from '@/components/Error.vue';
import Snack from '@/components/Snack.vue';
-import IntroductionDialog from '@/components/IntroductionDialog.vue';
-
diff --git a/src/components/JSONms.vue b/src/components/JSONms.vue
index cff5a0a..e80e402 100644
--- a/src/components/JSONms.vue
+++ b/src/components/JSONms.vue
@@ -398,7 +398,7 @@ if (globalStore.session.loggedIn) {
-
+
Data
@@ -467,8 +467,9 @@ if (globalStore.session.loggedIn) {
v-if="showActionBar"
flat
location="bottom"
- style="border-top: rgba(0, 0, 0, 0.1) solid 1px"
- class="pl-3"
+ color="background"
+ class="pl-3 py-0"
+ height="44"
>
{
const padding = (globalStore.userSettings.data.layoutSitePreviewPadding ? 96 : 63);
const result = windowHeight.value - padding;
- if (expanded.value) {
+ if (globalStore.admin.editorExpanded) {
return result + 32;
}
return result - layoutSize.value.preview.height;
@@ -244,11 +243,11 @@ defineExpose({
- Collapse
+ Collapse
Expand
-
+
diff --git a/src/composables/typings.ts b/src/composables/typings.ts
index e3ee4af..90f296a 100644
--- a/src/composables/typings.ts
+++ b/src/composables/typings.ts
@@ -51,7 +51,6 @@ export function useTypings() {
keys['i18n:' + key] = keys[key];
})
keys.i18n = 'string';
-
let type = keys[field.type || 'string'];
if (field?.items && typeof field.items === 'string' && field.items.startsWith('enums.')) {
const name = field.items.split('enums.');
@@ -65,7 +64,7 @@ export function useTypings() {
if (!field.required && !field.multiple) {
i18nType += ' | null';
}
- type = `JmsLocaleSet<${i18nType}>`;
+ type = `JmsLocaleSet<${i18nType}> | null`;
} else if (!field.required && !field.multiple && type !== '[]') {
type += ' | null';
} else if (field.multiple) {
@@ -85,14 +84,15 @@ export function useTypings() {
if (lastKey) {
if (isFieldType(field, 'array')) {
const name = getStructureName(nameKey + '.' + lastKey + '.items');
- const jmsArrStructure = { name, fields: [] };
+ const nameSingular = getStructureName(nameKey + '.' + lastKey + '.item');
+ const jmsArrStructure = { name: nameSingular, fields: [] };
const fields = structuredClone(field.fields);
fields.hash = { type: 'string', required: true, label: '', fields: {} }
innerLoop(fields, lastKey, jmsArrStructure, nameKey);
if (isFieldI18n(field)) {
- jmsStructure.fields.push({ key: lastKey, type: `JmsLocaleSet` })
+ jmsStructure.fields.push({ key: lastKey, type: `JmsLocaleSet` })
} else {
- jmsStructure.fields.push({ key: lastKey, type: `Jms${name}[]` })
+ jmsStructure.fields.push({ key: lastKey, type: `Jms${nameSingular}[]` })
}
} else if (isFieldType(field, 'node')) {
const nodeKey = nameKey + '.' + path;
diff --git a/src/interfaces.ts b/src/interfaces.ts
index 57d4622..de48218 100644
--- a/src/interfaces.ts
+++ b/src/interfaces.ts
@@ -33,6 +33,7 @@ export interface IAdmin {
previewMode: 'mobile' | 'desktop' | null,
dataTab: 'data' | 'settings' | 'docs',
editorTab: 'structure' | 'blueprints' | 'settings' | 'integration',
+ editorExpanded: boolean,
}
export interface ISnack {
diff --git a/src/stores/global.ts b/src/stores/global.ts
index 5567c0b..ff0b5aa 100644
--- a/src/stores/global.ts
+++ b/src/stores/global.ts
@@ -46,6 +46,7 @@ export const useGlobalStore = defineStore('global', {
previewMode: window.innerWidth >= 1400 ? 'desktop' : 'mobile',
dataTab: 'data',
editorTab: 'structure',
+ editorExpanded: false,
},
session: {
loggedIn: false,
diff --git a/src/styles/settings.scss b/src/styles/settings.scss
index 3ccea66..9431d62 100644
--- a/src/styles/settings.scss
+++ b/src/styles/settings.scss
@@ -16,7 +16,7 @@ html {
overflow-y: scroll !important;
}
.v-toolbar__content {
- height: 4rem !important;
+ height: 4rem;
}
body.ajax-loading,
body.ajax-loading * {
diff --git a/src/utils.ts b/src/utils.ts
index 11bd2ce..425dca1 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -263,7 +263,7 @@ export const getFieldDefaultValue = (field: IField, locales: {[key: string]: str
}
return finalItems;
}
- return field.default ?? null;
+ return field.default ?? (field.multiple ? [] : null);
}
export const processObject = (
@@ -554,13 +554,13 @@ export async function downloadFilesAsZip(urls: string[], jsonData: object | fals
}
// Fetch each URL and add it as a blob to the zip
- const files = await urlsToBlobArray(urls, modelStore.structure.server_secret);
- files.forEach(file => {
- zip.file(file.filename, file.blob);
- })
-
- // Generate the zip file
try {
+ const files = await urlsToBlobArray(urls, modelStore.structure.server_secret)
+ files.forEach(file => {
+ zip.file(file.filename, file.blob);
+ })
+
+ // Generate the zip file
const content = await zip.generateAsync({ type: "blob" });
const link = document.createElement('a');
link.href = URL.createObjectURL(content);
@@ -569,7 +569,8 @@ export async function downloadFilesAsZip(urls: string[], jsonData: object | fals
link.click();
document.body.removeChild(link);
resolve(content);
- } catch (error) {
+ }
+ catch (error) {
reject(error);
}
})