rimelight-components 2.2.3 → 2.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/components/blocks/AddBlockModal.vue +18 -12
- package/dist/runtime/components/blocks/editor/SectionBlockEditor.vue +13 -31
- package/dist/runtime/components/content/Callout.vue +2 -2
- package/dist/runtime/components/content/Section.vue +19 -22
- package/dist/runtime/components/notes/TodoCard.vue +1 -1
- package/dist/runtime/components/page/PageEditor.vue +14 -1
- package/dist/runtime/components/page/PagePropertiesEditor.vue +1 -1
- package/dist/runtime/components/page/PagePropertiesRenderer.vue +1 -1
- package/dist/runtime/components/page/modals/CreatePageModal.vue +8 -3
- package/dist/runtime/composables/pages/useInfobox.d.ts +3 -2
- package/dist/runtime/composables/pages/useInfobox.js +5 -2
- package/dist/runtime/composables/pages/useInfobox.mjs +5 -2
- package/dist/runtime/internal/injectionKeys.d.ts +2 -0
- package/dist/runtime/internal/injectionKeys.js +1 -0
- package/dist/runtime/internal/injectionKeys.mjs +1 -0
- package/dist/runtime/utils/page.js +15 -4
- package/dist/runtime/utils/page.mjs +15 -4
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { readdirSync } from 'node:fs';
|
|
|
4
4
|
import { basename } from 'node:path';
|
|
5
5
|
|
|
6
6
|
const name = "rimelight-components";
|
|
7
|
-
const version = "2.2.
|
|
7
|
+
const version = "2.2.7";
|
|
8
8
|
const homepage = "https://rimelight.com/tools/rimelight-components";
|
|
9
9
|
|
|
10
10
|
const defaultOptions = {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref, computed } from "vue";
|
|
2
|
+
import { ref, computed, inject } from "vue";
|
|
3
3
|
import { BLOCK_DEFINITIONS, CATEGORY_ORDER } from "../../utils/blocks";
|
|
4
4
|
import { useRC } from "../../composables";
|
|
5
5
|
import { useI18n } from "vue-i18n";
|
|
6
6
|
import { tv } from "../../internal/tv";
|
|
7
|
+
import { SECTION_LEVEL_KEY } from "../../internal/injectionKeys";
|
|
7
8
|
const open = defineModel("open", { type: Boolean, ...{ default: false } });
|
|
8
9
|
const { rc: rcProp } = defineProps({
|
|
9
10
|
open: { type: Boolean, required: false },
|
|
@@ -45,10 +46,15 @@ const {
|
|
|
45
46
|
} = addBlockModalStyles();
|
|
46
47
|
const { t } = useI18n();
|
|
47
48
|
const searchQuery = ref("");
|
|
49
|
+
const sectionLevel = inject(SECTION_LEVEL_KEY, computed(() => 1));
|
|
48
50
|
const filteredBlocks = computed(() => {
|
|
49
|
-
|
|
51
|
+
let blocks = BLOCK_DEFINITIONS;
|
|
52
|
+
if (sectionLevel.value >= 6) {
|
|
53
|
+
blocks = blocks.filter((b) => b.type !== "SectionBlock");
|
|
54
|
+
}
|
|
55
|
+
if (!searchQuery.value) return blocks;
|
|
50
56
|
const query = searchQuery.value.toLowerCase();
|
|
51
|
-
return
|
|
57
|
+
return blocks.filter(
|
|
52
58
|
(block) => block.label.toLowerCase().includes(query) || block.type.toLowerCase().includes(query) || block.category.toLowerCase().includes(query) || block.description?.toLowerCase().includes(query)
|
|
53
59
|
);
|
|
54
60
|
});
|
|
@@ -121,18 +127,18 @@ const handleSelect = (block) => {
|
|
|
121
127
|
:class="blockItem({ class: rc.blockItem })"
|
|
122
128
|
@click="handleSelect(block)"
|
|
123
129
|
>
|
|
124
|
-
<
|
|
130
|
+
<span :class="blockIcon({ class: rc.blockIcon })">
|
|
125
131
|
<UIcon :name="block.icon" size="20" />
|
|
126
|
-
</
|
|
127
|
-
<
|
|
128
|
-
<
|
|
132
|
+
</span>
|
|
133
|
+
<span class="flex-1 text-left">
|
|
134
|
+
<span class="flex items-center justify-between gap-2">
|
|
129
135
|
<span :class="blockLabel({ class: rc.blockLabel })">{{ block.label }}</span>
|
|
130
|
-
<span class="text-[10px] font-mono text-dimmed px-1.5 py-0.5 bg-neutral-100 dark:bg-neutral-900 rounded">{{ block.type }}</span>
|
|
131
|
-
</
|
|
132
|
-
<
|
|
136
|
+
<span class="text-[10px] font-mono text-dimmed px-1.5 py-0.5 bg-neutral-100 dark:bg-neutral-900 rounded shrink-0">{{ block.type }}</span>
|
|
137
|
+
</span>
|
|
138
|
+
<span v-if="block.description" :class="blockDescription({ class: rc.blockDescription })" class="block">
|
|
133
139
|
{{ block.description }}
|
|
134
|
-
</
|
|
135
|
-
</
|
|
140
|
+
</span>
|
|
141
|
+
</span>
|
|
136
142
|
</button>
|
|
137
143
|
</div>
|
|
138
144
|
</div>
|
|
@@ -3,6 +3,7 @@ import { inject, ref, computed, watch, nextTick, shallowRef } from "vue";
|
|
|
3
3
|
import {} from "../../../types";
|
|
4
4
|
import { tv } from "../../../internal/tv";
|
|
5
5
|
import { useRC } from "../../../composables";
|
|
6
|
+
import { SECTION_LEVEL_KEY } from "../../../internal/injectionKeys";
|
|
6
7
|
const props = defineProps({
|
|
7
8
|
id: { type: String, required: true },
|
|
8
9
|
rc: { type: Object, required: false },
|
|
@@ -18,20 +19,21 @@ const { rc } = useRC("SectionBlockEditor", rcProp);
|
|
|
18
19
|
const sectionBlockEditorStyles = tv({
|
|
19
20
|
slots: {
|
|
20
21
|
root: "flex flex-col gap-sm",
|
|
21
|
-
headerContainer: "flex flex-row gap-xs",
|
|
22
|
+
headerContainer: "flex flex-row items-center gap-xs",
|
|
22
23
|
titleInput: "w-full"
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
26
|
const { root, headerContainer, titleInput } = sectionBlockEditorStyles();
|
|
26
27
|
const editorApi = inject("block-editor-api");
|
|
27
|
-
const localLevel = ref(props.level);
|
|
28
28
|
const localTitle = ref(props.title);
|
|
29
29
|
const localDescription = ref(props.description);
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
const parentLevel = inject(SECTION_LEVEL_KEY, computed(() => 1));
|
|
31
|
+
const currentLevel = computed(() => Math.min(6, parentLevel.value + 1));
|
|
32
|
+
watch(currentLevel, (newLevel) => {
|
|
33
|
+
if (editorApi && props.id && newLevel !== props.level) {
|
|
34
|
+
editorApi.updateBlockProps(props.id, { level: newLevel });
|
|
35
|
+
}
|
|
36
|
+
}, { immediate: true });
|
|
35
37
|
const updateLocalTitle = (e) => {
|
|
36
38
|
localTitle.value = e.target.value;
|
|
37
39
|
};
|
|
@@ -48,11 +50,6 @@ const commitDescriptionOnBlur = () => {
|
|
|
48
50
|
editorApi.updateBlockProps(props.id, { description: localDescription.value });
|
|
49
51
|
}
|
|
50
52
|
};
|
|
51
|
-
watch(localLevel, (newLocalLevel) => {
|
|
52
|
-
if (editorApi && props.id && newLocalLevel !== props.level) {
|
|
53
|
-
editorApi.updateBlockProps(props.id, { level: newLocalLevel });
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
53
|
watch(
|
|
57
54
|
() => props.title,
|
|
58
55
|
(newVal) => {
|
|
@@ -61,14 +58,6 @@ watch(
|
|
|
61
58
|
}
|
|
62
59
|
}
|
|
63
60
|
);
|
|
64
|
-
watch(
|
|
65
|
-
() => props.level,
|
|
66
|
-
(newVal) => {
|
|
67
|
-
if (newVal !== localLevel.value) {
|
|
68
|
-
localLevel.value = newVal;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
61
|
watch(
|
|
73
62
|
() => props.description,
|
|
74
63
|
(newVal) => {
|
|
@@ -93,19 +82,12 @@ const handleChildrenMutation = () => {
|
|
|
93
82
|
|
|
94
83
|
<template>
|
|
95
84
|
<div :class="root({ class: rc.root })">
|
|
96
|
-
<RCSection :
|
|
85
|
+
<RCSection :title="localTitle" :description="description" is-editing>
|
|
97
86
|
<template #title>
|
|
98
87
|
<div :class="headerContainer({ class: rc.headerContainer })">
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
value-key="value"
|
|
103
|
-
label-key="label"
|
|
104
|
-
variant="ghost"
|
|
105
|
-
placeholder="Select Heading Level"
|
|
106
|
-
size="sm"
|
|
107
|
-
color="neutral"
|
|
108
|
-
/>
|
|
88
|
+
<span class="text-xs font-mono text-dimmed shrink-0 leading-none">
|
|
89
|
+
H{{ currentLevel }}
|
|
90
|
+
</span>
|
|
109
91
|
<UInput
|
|
110
92
|
:model-value="localTitle"
|
|
111
93
|
variant="ghost"
|
|
@@ -35,7 +35,7 @@ const tooltip = computed(() => config.value.tooltip);
|
|
|
35
35
|
</script>
|
|
36
36
|
|
|
37
37
|
<template>
|
|
38
|
-
<
|
|
38
|
+
<NuxtLink :to="to" :target="target">
|
|
39
39
|
<UAlert
|
|
40
40
|
:title="t(title)"
|
|
41
41
|
:color="variant"
|
|
@@ -61,5 +61,5 @@ const tooltip = computed(() => config.value.tooltip);
|
|
|
61
61
|
</UTooltip>
|
|
62
62
|
</template>
|
|
63
63
|
</UAlert>
|
|
64
|
-
</
|
|
64
|
+
</NuxtLink>
|
|
65
65
|
</template>
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useRoute } from "#imports";
|
|
3
3
|
import { useToast } from "@nuxt/ui/composables/useToast";
|
|
4
|
-
import { computed } from "vue";
|
|
4
|
+
import { computed, inject, provide } from "vue";
|
|
5
5
|
import { useClipboard } from "@vueuse/core";
|
|
6
6
|
import { tv } from "../../internal/tv";
|
|
7
7
|
import { useRC } from "../../composables";
|
|
8
8
|
import { slugify } from "../../utils";
|
|
9
|
+
import { SECTION_LEVEL_KEY } from "../../internal/injectionKeys";
|
|
9
10
|
defineOptions({
|
|
10
11
|
name: "SectionComponent"
|
|
11
12
|
});
|
|
12
|
-
const {
|
|
13
|
-
level = 1,
|
|
14
|
-
title,
|
|
15
|
-
description,
|
|
16
|
-
isEditing = false,
|
|
17
|
-
rc: rcProp
|
|
18
|
-
} = defineProps({
|
|
13
|
+
const props = defineProps({
|
|
19
14
|
level: { type: Number, required: false },
|
|
20
15
|
title: { type: String, required: true },
|
|
21
16
|
description: { type: String, required: false },
|
|
22
17
|
isEditing: { type: Boolean, required: false },
|
|
23
18
|
rc: { type: Object, required: false }
|
|
24
19
|
});
|
|
20
|
+
const {
|
|
21
|
+
title,
|
|
22
|
+
description,
|
|
23
|
+
isEditing = false,
|
|
24
|
+
rc: rcProp
|
|
25
|
+
} = props;
|
|
26
|
+
const parentLevel = inject(SECTION_LEVEL_KEY, computed(() => 1));
|
|
27
|
+
const level = computed(() => Math.min(6, parentLevel.value + 1));
|
|
28
|
+
provide(SECTION_LEVEL_KEY, level);
|
|
25
29
|
const emit = defineEmits([]);
|
|
26
30
|
const slots = defineSlots();
|
|
27
31
|
const { rc } = useRC("Section", rcProp);
|
|
@@ -87,14 +91,7 @@ const sectionStyles = tv({
|
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
93
|
});
|
|
90
|
-
const {
|
|
91
|
-
section,
|
|
92
|
-
link,
|
|
93
|
-
heading,
|
|
94
|
-
descriptionText,
|
|
95
|
-
separator,
|
|
96
|
-
content
|
|
97
|
-
} = sectionStyles({ level });
|
|
94
|
+
const styles = computed(() => sectionStyles({ level: level.value }));
|
|
98
95
|
const { copy } = useClipboard();
|
|
99
96
|
const toast = useToast();
|
|
100
97
|
const route = useRoute();
|
|
@@ -123,16 +120,16 @@ const fullSectionUrl = computed(() => {
|
|
|
123
120
|
</script>
|
|
124
121
|
|
|
125
122
|
<template>
|
|
126
|
-
<section :id="sectionId" :class="section({ class: rc.section })" v-bind="$attrs">
|
|
123
|
+
<section :id="sectionId" :class="styles.section({ class: rc.section })" v-bind="$attrs">
|
|
127
124
|
<component
|
|
128
125
|
:id="`${sectionId}-heading`"
|
|
129
126
|
:is="`h${level}`"
|
|
130
|
-
:class="heading({ class: rc.heading })"
|
|
127
|
+
:class="styles.heading({ class: rc.heading })"
|
|
131
128
|
>
|
|
132
129
|
<NuxtLink
|
|
133
130
|
v-if="!isEditing"
|
|
134
131
|
:href="`#${sectionId}`"
|
|
135
|
-
:class="link({ class: rc.link })"
|
|
132
|
+
:class="styles.link({ class: rc.link })"
|
|
136
133
|
class="group relative lg:-ms-2 lg:ps-2 inline-block w-full"
|
|
137
134
|
>
|
|
138
135
|
<ClientOnly>
|
|
@@ -155,12 +152,12 @@ const fullSectionUrl = computed(() => {
|
|
|
155
152
|
<slot v-else name="title">{{ title }}</slot>
|
|
156
153
|
</component>
|
|
157
154
|
<slot name="description">
|
|
158
|
-
<p v-if="description" :class="descriptionText({ class: rc.descriptionText })">
|
|
155
|
+
<p v-if="description" :class="styles.descriptionText({ class: rc.descriptionText })">
|
|
159
156
|
{{ description }}
|
|
160
157
|
</p>
|
|
161
158
|
</slot>
|
|
162
|
-
<USeparator :class="separator({ class: rc.separator })" />
|
|
163
|
-
<div :class="content({ class: rc.content })">
|
|
159
|
+
<USeparator :class="styles.separator({ class: rc.separator })" />
|
|
160
|
+
<div :class="styles.content({ class: rc.content })">
|
|
164
161
|
<slot />
|
|
165
162
|
</div>
|
|
166
163
|
</section>
|
|
@@ -15,7 +15,7 @@ const emit = defineEmits(["toggle", "archive", "restore", "delete"]);
|
|
|
15
15
|
<template v-if="!todo.isArchived">
|
|
16
16
|
<UCheckbox
|
|
17
17
|
:model-value="todo.completed"
|
|
18
|
-
@update:model-value="(val) => emit('toggle', val)"
|
|
18
|
+
@update:model-value="(val) => emit('toggle', val === true)"
|
|
19
19
|
/>
|
|
20
20
|
</template>
|
|
21
21
|
<template v-else>
|
|
@@ -3,7 +3,7 @@ import { ref, computed, useTemplateRef, provide } from "vue";
|
|
|
3
3
|
import { navigateTo } from "#imports";
|
|
4
4
|
import {} from "../../types";
|
|
5
5
|
import { usePageEditor, usePageRegistry, useRC, useHeaderStack, useConfirm } from "../../composables";
|
|
6
|
-
import { getLocalizedContent } from "../../utils";
|
|
6
|
+
import { getLocalizedContent, syncPageWithDefinition } from "../../utils";
|
|
7
7
|
import { useI18n } from "vue-i18n";
|
|
8
8
|
import { tv } from "../../internal/tv";
|
|
9
9
|
const {
|
|
@@ -85,6 +85,13 @@ const { getTypeLabelKey } = usePageRegistry();
|
|
|
85
85
|
const { t, locale } = useI18n();
|
|
86
86
|
const { undo, redo, canUndo, canRedo, captureSnapshot, resetHistory, pauseHistory, resumeHistory } = usePageEditor(page);
|
|
87
87
|
const { confirm } = useConfirm();
|
|
88
|
+
const currentDefinition = computed(() => pageDefinitions[page.value.type]);
|
|
89
|
+
watch([() => page.value.id, () => versionId.value, () => page.value.type], () => {
|
|
90
|
+
if (page.value && currentDefinition.value) {
|
|
91
|
+
console.log("[PageEditor] Syncing page with definition", page.value.id, versionId.value);
|
|
92
|
+
syncPageWithDefinition(page.value, currentDefinition.value);
|
|
93
|
+
}
|
|
94
|
+
}, { immediate: true });
|
|
88
95
|
const handleViewPage = async () => {
|
|
89
96
|
if (canUndo.value) {
|
|
90
97
|
const confirmed = await confirm({
|
|
@@ -103,6 +110,9 @@ const handleViewPage = async () => {
|
|
|
103
110
|
}
|
|
104
111
|
};
|
|
105
112
|
const handleSave = () => {
|
|
113
|
+
if (currentDefinition.value) {
|
|
114
|
+
syncPageWithDefinition(page.value, currentDefinition.value);
|
|
115
|
+
}
|
|
106
116
|
const dataToPersist = JSON.parse(JSON.stringify(page.value));
|
|
107
117
|
emit("save", dataToPersist);
|
|
108
118
|
};
|
|
@@ -114,6 +124,9 @@ const handlePublish = async () => {
|
|
|
114
124
|
cancelLabel: t("common.cancel", "Cancel")
|
|
115
125
|
});
|
|
116
126
|
if (confirmed) {
|
|
127
|
+
if (currentDefinition.value) {
|
|
128
|
+
syncPageWithDefinition(page.value, currentDefinition.value);
|
|
129
|
+
}
|
|
117
130
|
const dataToPersist = JSON.parse(JSON.stringify(page.value));
|
|
118
131
|
emit("publish", dataToPersist);
|
|
119
132
|
}
|
|
@@ -41,7 +41,7 @@ const {
|
|
|
41
41
|
links
|
|
42
42
|
} = pagePropertiesEditorStyles();
|
|
43
43
|
const { getTypeLabelKey } = usePageRegistry();
|
|
44
|
-
const { isFieldVisible, shouldRenderGroup, getSortedFields, getSortedGroups } = useInfobox(page.value.properties);
|
|
44
|
+
const { isFieldVisible, shouldRenderGroup, getSortedFields, getSortedGroups } = useInfobox(() => page.value.properties);
|
|
45
45
|
const { locale, t } = useI18n();
|
|
46
46
|
const imageTabs = computed(() => {
|
|
47
47
|
if (!page.value.images?.length) return [];
|
|
@@ -61,7 +61,7 @@ const {
|
|
|
61
61
|
links
|
|
62
62
|
} = pagePropertiesRendererStyles();
|
|
63
63
|
const { getTypeLabelKey } = usePageRegistry();
|
|
64
|
-
const { isFieldVisible, shouldRenderGroup, getSortedFields, getSortedGroups } = useInfobox(page.value.properties);
|
|
64
|
+
const { isFieldVisible, shouldRenderGroup, getSortedFields, getSortedGroups } = useInfobox(() => page.value.properties);
|
|
65
65
|
const { t, locale } = useI18n();
|
|
66
66
|
const { share } = useShare();
|
|
67
67
|
const { copy } = useClipboard();
|
|
@@ -53,9 +53,12 @@ const handleConfirm = () => {
|
|
|
53
53
|
}
|
|
54
54
|
const properties = {};
|
|
55
55
|
Object.entries(definition.properties).forEach(([groupKey, group]) => {
|
|
56
|
-
properties[groupKey] = {
|
|
56
|
+
properties[groupKey] = {
|
|
57
|
+
...group,
|
|
58
|
+
fields: {}
|
|
59
|
+
};
|
|
57
60
|
Object.entries(group.fields).forEach(([fieldKey, field2]) => {
|
|
58
|
-
properties[groupKey][fieldKey] = field2
|
|
61
|
+
properties[groupKey].fields[fieldKey] = { ...field2 };
|
|
59
62
|
});
|
|
60
63
|
});
|
|
61
64
|
const newPage = {
|
|
@@ -63,7 +66,9 @@ const handleConfirm = () => {
|
|
|
63
66
|
title: { en: title.value },
|
|
64
67
|
slug: slug.value,
|
|
65
68
|
properties,
|
|
66
|
-
blocks: definition.initialBlocks ? definition.initialBlocks() : []
|
|
69
|
+
blocks: definition.initialBlocks ? definition.initialBlocks() : [],
|
|
70
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
71
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
67
72
|
};
|
|
68
73
|
emit("confirm", newPage);
|
|
69
74
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { type MaybeRefOrGetter } from "vue";
|
|
1
2
|
import type { Property, PropertyGroup, BasePageProperties } from "../../types/index.js";
|
|
2
|
-
export declare const useInfobox: (
|
|
3
|
+
export declare const useInfobox: (propertiesRef: MaybeRefOrGetter<BasePageProperties>) => {
|
|
3
4
|
isFieldVisible: (schema: Property, isReadOnly: boolean) => boolean;
|
|
4
5
|
shouldRenderGroup: (group: PropertyGroup, isReadOnly: boolean) => boolean;
|
|
5
6
|
getSortedFields: (fields: Record<string, Property>) => [string, Property<any>][];
|
|
6
|
-
getSortedGroups: (props: BasePageProperties) => [string, PropertyGroup][];
|
|
7
|
+
getSortedGroups: (props: MaybeRefOrGetter<BasePageProperties>) => [string, PropertyGroup][];
|
|
7
8
|
locale: import("vue").WritableComputedRef<string, string>;
|
|
8
9
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useI18n } from "vue-i18n";
|
|
2
|
-
|
|
2
|
+
import { toValue } from "vue";
|
|
3
|
+
export const useInfobox = (propertiesRef) => {
|
|
3
4
|
const { locale } = useI18n();
|
|
4
5
|
const isFieldVisible = (schema, isReadOnly) => {
|
|
6
|
+
const properties = toValue(propertiesRef);
|
|
5
7
|
const passesLogic = !schema.visibleIf || schema.visibleIf(properties);
|
|
6
8
|
if (!passesLogic) return false;
|
|
7
9
|
if (isReadOnly) {
|
|
@@ -19,7 +21,8 @@ export const useInfobox = (properties) => {
|
|
|
19
21
|
return Object.entries(fields).sort(([, a], [, b]) => (a.order ?? 0) - (b.order ?? 0));
|
|
20
22
|
};
|
|
21
23
|
const getSortedGroups = (props) => {
|
|
22
|
-
|
|
24
|
+
const p = toValue(props);
|
|
25
|
+
return Object.entries(p).sort(
|
|
23
26
|
([, a], [, b]) => (a.order ?? 0) - (b.order ?? 0)
|
|
24
27
|
);
|
|
25
28
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useI18n } from "vue-i18n";
|
|
2
|
-
|
|
2
|
+
import { toValue } from "vue";
|
|
3
|
+
export const useInfobox = (propertiesRef) => {
|
|
3
4
|
const { locale } = useI18n();
|
|
4
5
|
const isFieldVisible = (schema, isReadOnly) => {
|
|
6
|
+
const properties = toValue(propertiesRef);
|
|
5
7
|
const passesLogic = !schema.visibleIf || schema.visibleIf(properties);
|
|
6
8
|
if (!passesLogic) return false;
|
|
7
9
|
if (isReadOnly) {
|
|
@@ -19,7 +21,8 @@ export const useInfobox = (properties) => {
|
|
|
19
21
|
return Object.entries(fields).sort(([, a], [, b]) => (a.order ?? 0) - (b.order ?? 0));
|
|
20
22
|
};
|
|
21
23
|
const getSortedGroups = (props) => {
|
|
22
|
-
|
|
24
|
+
const p = toValue(props);
|
|
25
|
+
return Object.entries(p).sort(
|
|
23
26
|
([, a], [, b]) => (a.order ?? 0) - (b.order ?? 0)
|
|
24
27
|
);
|
|
25
28
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SECTION_LEVEL_KEY = Symbol("SECTION_LEVEL");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SECTION_LEVEL_KEY = Symbol("SECTION_LEVEL");
|
|
@@ -21,11 +21,11 @@ export function syncPageWithDefinition(page, definition) {
|
|
|
21
21
|
const existingField = existingGroup?.fields ? existingGroup.fields[fieldId] : void 0;
|
|
22
22
|
if (existingField !== void 0) {
|
|
23
23
|
updatedGroupFields[fieldId] = {
|
|
24
|
-
...definitionField,
|
|
24
|
+
...JSON.parse(JSON.stringify(definitionField)),
|
|
25
25
|
value: existingField.value
|
|
26
26
|
};
|
|
27
27
|
} else {
|
|
28
|
-
updatedGroupFields[fieldId] =
|
|
28
|
+
updatedGroupFields[fieldId] = JSON.parse(JSON.stringify(definitionField));
|
|
29
29
|
hasChanged = true;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -69,7 +69,7 @@ export function syncPageWithDefinition(page, definition) {
|
|
|
69
69
|
if (existingIndex !== -1) {
|
|
70
70
|
lastExistingIdealIndex = existingIndex;
|
|
71
71
|
} else {
|
|
72
|
-
filteredCurrent.splice(lastExistingIdealIndex + 1, 0,
|
|
72
|
+
filteredCurrent.splice(lastExistingIdealIndex + 1, 0, JSON.parse(JSON.stringify(idealBlock)));
|
|
73
73
|
lastExistingIdealIndex++;
|
|
74
74
|
hasChanged = true;
|
|
75
75
|
}
|
|
@@ -94,6 +94,17 @@ export function convertVersionToPage(version) {
|
|
|
94
94
|
blocks: JSON.parse(JSON.stringify(blocks)),
|
|
95
95
|
// Deep copy to avoid reference issues
|
|
96
96
|
properties: properties ? JSON.parse(JSON.stringify(properties)) : {},
|
|
97
|
-
authorsIds: version.authorsIds || []
|
|
97
|
+
authorsIds: version.authorsIds || [],
|
|
98
|
+
createdAt: version.createdAt ? new Date(version.createdAt) : /* @__PURE__ */ new Date(),
|
|
99
|
+
updatedAt: version.updatedAt ? new Date(version.updatedAt) : /* @__PURE__ */ new Date(),
|
|
100
|
+
postedAt: version.postedAt ? new Date(version.postedAt) : null,
|
|
101
|
+
banner: version.banner,
|
|
102
|
+
icon: version.icon,
|
|
103
|
+
images: version.images || [],
|
|
104
|
+
title: version.title || { en: "" },
|
|
105
|
+
slug: version.slug || "",
|
|
106
|
+
description: version.description || { en: "" },
|
|
107
|
+
tags: version.tags || [],
|
|
108
|
+
links: version.links || []
|
|
98
109
|
};
|
|
99
110
|
}
|
|
@@ -21,11 +21,11 @@ export function syncPageWithDefinition(page, definition) {
|
|
|
21
21
|
const existingField = existingGroup?.fields ? existingGroup.fields[fieldId] : void 0;
|
|
22
22
|
if (existingField !== void 0) {
|
|
23
23
|
updatedGroupFields[fieldId] = {
|
|
24
|
-
...definitionField,
|
|
24
|
+
...JSON.parse(JSON.stringify(definitionField)),
|
|
25
25
|
value: existingField.value
|
|
26
26
|
};
|
|
27
27
|
} else {
|
|
28
|
-
updatedGroupFields[fieldId] =
|
|
28
|
+
updatedGroupFields[fieldId] = JSON.parse(JSON.stringify(definitionField));
|
|
29
29
|
hasChanged = true;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -69,7 +69,7 @@ export function syncPageWithDefinition(page, definition) {
|
|
|
69
69
|
if (existingIndex !== -1) {
|
|
70
70
|
lastExistingIdealIndex = existingIndex;
|
|
71
71
|
} else {
|
|
72
|
-
filteredCurrent.splice(lastExistingIdealIndex + 1, 0,
|
|
72
|
+
filteredCurrent.splice(lastExistingIdealIndex + 1, 0, JSON.parse(JSON.stringify(idealBlock)));
|
|
73
73
|
lastExistingIdealIndex++;
|
|
74
74
|
hasChanged = true;
|
|
75
75
|
}
|
|
@@ -94,6 +94,17 @@ export function convertVersionToPage(version) {
|
|
|
94
94
|
blocks: JSON.parse(JSON.stringify(blocks)),
|
|
95
95
|
// Deep copy to avoid reference issues
|
|
96
96
|
properties: properties ? JSON.parse(JSON.stringify(properties)) : {},
|
|
97
|
-
authorsIds: version.authorsIds || []
|
|
97
|
+
authorsIds: version.authorsIds || [],
|
|
98
|
+
createdAt: version.createdAt ? new Date(version.createdAt) : /* @__PURE__ */ new Date(),
|
|
99
|
+
updatedAt: version.updatedAt ? new Date(version.updatedAt) : /* @__PURE__ */ new Date(),
|
|
100
|
+
postedAt: version.postedAt ? new Date(version.postedAt) : null,
|
|
101
|
+
banner: version.banner,
|
|
102
|
+
icon: version.icon,
|
|
103
|
+
images: version.images || [],
|
|
104
|
+
title: version.title || { en: "" },
|
|
105
|
+
slug: version.slug || "",
|
|
106
|
+
description: version.description || { en: "" },
|
|
107
|
+
tags: version.tags || [],
|
|
108
|
+
links: version.links || []
|
|
98
109
|
};
|
|
99
110
|
}
|