@xleddyl/nuxt-cms 0.2.0 → 0.2.2
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 +17 -6
- package/dist/runtime/app/components/cms/BrandMark.vue +2 -3
- package/dist/runtime/app/components/cms/ConfirmModal.vue +14 -1
- package/dist/runtime/app/components/cms/Drawer.vue +5 -9
- package/dist/runtime/app/components/cms/EntryDrawer.vue +11 -3
- package/dist/runtime/app/components/cms/EntryForm.vue +0 -1
- package/dist/runtime/app/components/cms/Input.d.vue.ts +0 -1
- package/dist/runtime/app/components/cms/Input.vue +7 -4
- package/dist/runtime/app/components/cms/Input.vue.d.ts +0 -1
- package/dist/runtime/app/components/cms/LocaleSwitch.vue +1 -1
- package/dist/runtime/app/components/cms/MediaFolderPicker.d.vue.ts +0 -1
- package/dist/runtime/app/components/cms/MediaFolderPicker.vue +1 -3
- package/dist/runtime/app/components/cms/MediaFolderPicker.vue.d.ts +0 -1
- package/dist/runtime/app/components/cms/MediaGallery.vue +89 -11
- package/dist/runtime/app/components/cms/Modal.vue +5 -11
- package/dist/runtime/app/components/cms/PasswordInput.vue +9 -5
- package/dist/runtime/app/components/cms/RelationField.vue +7 -2
- package/dist/runtime/app/components/cms/SelectMenu.d.vue.ts +0 -1
- package/dist/runtime/app/components/cms/SelectMenu.vue +1 -6
- package/dist/runtime/app/components/cms/SelectMenu.vue.d.ts +0 -1
- package/dist/runtime/app/components/cms/SettingsEntry.vue +1 -8
- package/dist/runtime/app/components/cms/SettingsModal.vue +5 -10
- package/dist/runtime/app/components/cms/SettingsUsers.vue +8 -4
- package/dist/runtime/app/components/cms/Table.d.vue.ts +0 -7
- package/dist/runtime/app/components/cms/Table.vue +7 -49
- package/dist/runtime/app/components/cms/Table.vue.d.ts +0 -7
- package/dist/runtime/app/components/cms/Textarea.d.vue.ts +0 -1
- package/dist/runtime/app/components/cms/Textarea.vue +1 -2
- package/dist/runtime/app/components/cms/Textarea.vue.d.ts +0 -1
- package/dist/runtime/app/composables/cms-confirm.d.ts +16 -7
- package/dist/runtime/app/composables/cms-confirm.js +1 -0
- package/dist/runtime/app/composables/cms-entry-disabled.js +1 -1
- package/dist/runtime/app/composables/cms-media-keys.d.ts +1 -0
- package/dist/runtime/app/composables/cms-media-keys.js +5 -0
- package/dist/runtime/app/composables/cms-media-library.d.ts +1 -2
- package/dist/runtime/app/composables/cms-media-library.js +15 -19
- package/dist/runtime/app/composables/cms-media-uploader.d.ts +0 -1
- package/dist/runtime/app/composables/cms-media-uploader.js +1 -1
- package/dist/runtime/app/composables/cms-overlay.d.ts +4 -0
- package/dist/runtime/app/composables/cms-overlay.js +23 -0
- package/dist/runtime/app/composables/cms-settings.d.ts +0 -1
- package/dist/runtime/app/composables/cms-settings.js +1 -1
- package/dist/runtime/app/pages/admin-entry.vue +1 -0
- package/dist/runtime/app/utils/ui.d.ts +0 -2
- package/dist/runtime/assets/main.css +1 -1
- package/dist/runtime/generate.js +1 -1
- package/dist/runtime/seed.js +11 -1
- package/dist/runtime/server/api/collection.get.js +1 -1
- package/dist/runtime/server/api/collection.post.js +20 -14
- package/dist/runtime/server/api/collection.put.js +12 -12
- package/dist/runtime/server/api/item.put.js +14 -13
- package/dist/runtime/server/api/media-folder.patch.js +10 -16
- package/dist/runtime/server/api/media-move.post.js +12 -8
- package/dist/runtime/server/api/media.delete.js +3 -2
- package/dist/runtime/server/api/media.post.js +4 -2
- package/dist/runtime/server/api/media.put.js +4 -2
- package/dist/runtime/server/api/users.post.js +13 -9
- package/dist/runtime/server/plugins/migrate-sqlite.js +2 -2
- package/dist/runtime/server/routes/auth/login.post.js +30 -24
- package/dist/runtime/server/utils/db-d1.d.ts +0 -1
- package/dist/runtime/server/utils/db-d1.js +3 -4
- package/dist/runtime/server/utils/db-libsql.d.ts +0 -1
- package/dist/runtime/server/utils/db-libsql.js +3 -4
- package/dist/runtime/server/utils/db-postgres.d.ts +0 -1
- package/dist/runtime/server/utils/db-postgres.js +1 -4
- package/dist/runtime/server/utils/db-sqlite.d.ts +0 -1
- package/dist/runtime/server/utils/db-sqlite.js +4 -10
- package/dist/runtime/server/utils/graphql-depth.js +12 -5
- package/dist/runtime/server/utils/graphql.js +4 -3
- package/dist/runtime/server/utils/libsql-migrations.d.ts +1 -0
- package/dist/runtime/server/utils/libsql-migrations.js +1 -1
- package/dist/runtime/server/utils/media-folders.js +23 -24
- package/dist/runtime/server/utils/media.d.ts +1 -0
- package/dist/runtime/server/utils/media.js +6 -1
- package/dist/runtime/server/utils/migrate.d.ts +1 -0
- package/dist/runtime/server/utils/migrate.js +33 -1
- package/dist/runtime/server/utils/registry.d.ts +3 -0
- package/dist/runtime/server/utils/registry.js +10 -1
- package/dist/runtime/server/utils/relations.d.ts +1 -1
- package/dist/runtime/server/utils/relations.js +6 -9
- package/dist/runtime/server/utils/require-admin.d.ts +0 -2
- package/dist/runtime/server/utils/require-admin.js +0 -1
- package/dist/runtime/server/utils/timestamps.d.ts +12 -0
- package/dist/runtime/server/utils/timestamps.js +48 -0
- package/dist/runtime/server/utils/users.js +3 -2
- package/dist/runtime/server/utils/write-statements.d.ts +33 -0
- package/dist/runtime/server/utils/write-statements.js +75 -0
- package/dist/runtime/shared/index.d.ts +14 -0
- package/dist/runtime/shared/index.js +13 -0
- package/dist/runtime/shared/layout.d.ts +0 -1
- package/dist/runtime/shared/layout.js +0 -3
- package/dist/runtime/shared/timestamps.d.ts +4 -0
- package/dist/runtime/shared/timestamps.js +24 -0
- package/package.json +1 -1
|
@@ -224,11 +224,15 @@ async function create() {
|
|
|
224
224
|
}
|
|
225
225
|
async function copyCredentials() {
|
|
226
226
|
if (!created.value) return;
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
try {
|
|
228
|
+
await navigator.clipboard.writeText(
|
|
229
|
+
`Email: ${created.value.email}
|
|
229
230
|
Password: ${created.value.password}`
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
);
|
|
232
|
+
copied.value = true;
|
|
233
|
+
} catch {
|
|
234
|
+
copied.value = false;
|
|
235
|
+
}
|
|
232
236
|
}
|
|
233
237
|
const resetting = ref(null);
|
|
234
238
|
const reset = ref({ password: "" });
|
|
@@ -4,7 +4,6 @@ interface Column {
|
|
|
4
4
|
accessorKey?: string;
|
|
5
5
|
accessorFn?: (row: Row) => unknown;
|
|
6
6
|
header?: string;
|
|
7
|
-
reorderable?: boolean;
|
|
8
7
|
sortable?: boolean;
|
|
9
8
|
}
|
|
10
9
|
interface TableSort {
|
|
@@ -15,11 +14,9 @@ type __VLS_Props = {
|
|
|
15
14
|
data: Row[];
|
|
16
15
|
columns: Column[];
|
|
17
16
|
selectable?: boolean;
|
|
18
|
-
rowKey?: string;
|
|
19
17
|
};
|
|
20
18
|
type __VLS_ModelProps = {
|
|
21
19
|
'selected'?: string[];
|
|
22
|
-
'columnVisibility'?: Record<string, boolean>;
|
|
23
20
|
'sort'?: TableSort | null;
|
|
24
21
|
};
|
|
25
22
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
@@ -35,17 +32,13 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
35
32
|
select: (event: Event, row: {
|
|
36
33
|
original: Row;
|
|
37
34
|
}) => any;
|
|
38
|
-
reorder: (from: string, to: string) => any;
|
|
39
35
|
"update:selected": (value: string[]) => any;
|
|
40
|
-
"update:columnVisibility": (value: Record<string, boolean>) => any;
|
|
41
36
|
"update:sort": (value: TableSort | null) => any;
|
|
42
37
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
43
38
|
onSelect?: ((event: Event, row: {
|
|
44
39
|
original: Row;
|
|
45
40
|
}) => any) | undefined;
|
|
46
|
-
onReorder?: ((from: string, to: string) => any) | undefined;
|
|
47
41
|
"onUpdate:selected"?: ((value: string[]) => any) | undefined;
|
|
48
|
-
"onUpdate:columnVisibility"?: ((value: Record<string, boolean>) => any) | undefined;
|
|
49
42
|
"onUpdate:sort"?: ((value: TableSort | null) => any) | undefined;
|
|
50
43
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
51
44
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -13,22 +13,14 @@
|
|
|
13
13
|
/>
|
|
14
14
|
</th>
|
|
15
15
|
<th
|
|
16
|
-
v-for="column in
|
|
16
|
+
v-for="column in columns"
|
|
17
17
|
:key="columnId(column)"
|
|
18
18
|
:class="{
|
|
19
|
-
'is-dragging': draggingId === columnId(column),
|
|
20
|
-
'is-drop-target': dropTargetId === columnId(column),
|
|
21
19
|
'is-sortable': column.sortable,
|
|
22
20
|
'is-sorted': sort?.key === columnId(column)
|
|
23
21
|
}"
|
|
24
|
-
:draggable="column.reorderable || void 0"
|
|
25
22
|
:aria-sort="ariaSort(column)"
|
|
26
23
|
@click="toggleSort(column)"
|
|
27
|
-
@dragstart="onDragStart($event, column)"
|
|
28
|
-
@dragover="onDragOver($event, column)"
|
|
29
|
-
@dragleave="onDragLeave(column)"
|
|
30
|
-
@drop="onDrop($event, column)"
|
|
31
|
-
@dragend="resetDrag"
|
|
32
24
|
>
|
|
33
25
|
<span class="cms-th-label">
|
|
34
26
|
{{ column.header }}
|
|
@@ -44,7 +36,7 @@
|
|
|
44
36
|
<tbody>
|
|
45
37
|
<tr
|
|
46
38
|
v-for="(row, index) in data"
|
|
47
|
-
:key="
|
|
39
|
+
:key="keyOf(row)"
|
|
48
40
|
class="__clickable"
|
|
49
41
|
:class="{ 'is-selected': isSelected(row) }"
|
|
50
42
|
:style="{ '--cms-row-delay': `${Math.min(index, 14) * 24}ms` }"
|
|
@@ -57,7 +49,7 @@
|
|
|
57
49
|
@toggle="toggleRow(row)"
|
|
58
50
|
/>
|
|
59
51
|
</td>
|
|
60
|
-
<td v-for="column in
|
|
52
|
+
<td v-for="column in columns" :key="columnId(column)">
|
|
61
53
|
<slot :name="`${columnId(column)}-cell`" :row="{ original: row }">
|
|
62
54
|
{{ cellValue(column, row) }}
|
|
63
55
|
</slot>
|
|
@@ -70,16 +62,15 @@
|
|
|
70
62
|
</template>
|
|
71
63
|
|
|
72
64
|
<script setup>
|
|
73
|
-
import { computed
|
|
65
|
+
import { computed } from "#imports";
|
|
74
66
|
const props = defineProps({
|
|
75
67
|
data: { type: Array, required: true },
|
|
76
68
|
columns: { type: Array, required: true },
|
|
77
|
-
selectable: { type: Boolean, required: false }
|
|
78
|
-
rowKey: { type: String, required: false }
|
|
69
|
+
selectable: { type: Boolean, required: false }
|
|
79
70
|
});
|
|
80
71
|
const selected = defineModel("selected", { type: Array, ...{ default: () => [] } });
|
|
81
72
|
function keyOf(row) {
|
|
82
|
-
return String(row
|
|
73
|
+
return String(row.id);
|
|
83
74
|
}
|
|
84
75
|
function isSelected(row) {
|
|
85
76
|
return selected.value.includes(keyOf(row));
|
|
@@ -95,9 +86,8 @@ const someSelected = computed(() => !allSelected.value && selected.value.length
|
|
|
95
86
|
function toggleAll() {
|
|
96
87
|
selected.value = allSelected.value ? [] : props.data.map(keyOf);
|
|
97
88
|
}
|
|
98
|
-
const visibility = defineModel("columnVisibility", { type: Object, ...{ default: () => ({}) } });
|
|
99
89
|
const sort = defineModel("sort", { type: [Object, null], ...{ default: null } });
|
|
100
|
-
const emit = defineEmits(["select"
|
|
90
|
+
const emit = defineEmits(["select"]);
|
|
101
91
|
function columnId(column) {
|
|
102
92
|
return column.id ?? column.accessorKey ?? "";
|
|
103
93
|
}
|
|
@@ -117,38 +107,6 @@ function ariaSort(column) {
|
|
|
117
107
|
if (sort.value?.key !== columnId(column)) return "none";
|
|
118
108
|
return sort.value.order === "asc" ? "ascending" : "descending";
|
|
119
109
|
}
|
|
120
|
-
const draggingId = ref(null);
|
|
121
|
-
const dropTargetId = ref(null);
|
|
122
|
-
function resetDrag() {
|
|
123
|
-
draggingId.value = null;
|
|
124
|
-
dropTargetId.value = null;
|
|
125
|
-
}
|
|
126
|
-
function onDragStart(event, column) {
|
|
127
|
-
if (!column.reorderable) return;
|
|
128
|
-
draggingId.value = columnId(column);
|
|
129
|
-
event.dataTransfer?.setData("text/plain", columnId(column));
|
|
130
|
-
if (event.dataTransfer) event.dataTransfer.effectAllowed = "move";
|
|
131
|
-
}
|
|
132
|
-
function onDragOver(event, column) {
|
|
133
|
-
if (!draggingId.value || !column.reorderable) return;
|
|
134
|
-
event.preventDefault();
|
|
135
|
-
if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
|
|
136
|
-
dropTargetId.value = columnId(column);
|
|
137
|
-
}
|
|
138
|
-
function onDragLeave(column) {
|
|
139
|
-
if (dropTargetId.value === columnId(column)) dropTargetId.value = null;
|
|
140
|
-
}
|
|
141
|
-
function onDrop(event, column) {
|
|
142
|
-
if (!draggingId.value || !column.reorderable) return;
|
|
143
|
-
event.preventDefault();
|
|
144
|
-
const from = draggingId.value;
|
|
145
|
-
const to = columnId(column);
|
|
146
|
-
resetDrag();
|
|
147
|
-
if (from !== to) emit("reorder", from, to);
|
|
148
|
-
}
|
|
149
|
-
const visibleColumns = computed(
|
|
150
|
-
() => props.columns.filter((column) => visibility.value[columnId(column)] !== false)
|
|
151
|
-
);
|
|
152
110
|
function cellValue(column, row) {
|
|
153
111
|
if (column.accessorFn) return column.accessorFn(row);
|
|
154
112
|
if (column.accessorKey) return row[column.accessorKey];
|
|
@@ -4,7 +4,6 @@ interface Column {
|
|
|
4
4
|
accessorKey?: string;
|
|
5
5
|
accessorFn?: (row: Row) => unknown;
|
|
6
6
|
header?: string;
|
|
7
|
-
reorderable?: boolean;
|
|
8
7
|
sortable?: boolean;
|
|
9
8
|
}
|
|
10
9
|
interface TableSort {
|
|
@@ -15,11 +14,9 @@ type __VLS_Props = {
|
|
|
15
14
|
data: Row[];
|
|
16
15
|
columns: Column[];
|
|
17
16
|
selectable?: boolean;
|
|
18
|
-
rowKey?: string;
|
|
19
17
|
};
|
|
20
18
|
type __VLS_ModelProps = {
|
|
21
19
|
'selected'?: string[];
|
|
22
|
-
'columnVisibility'?: Record<string, boolean>;
|
|
23
20
|
'sort'?: TableSort | null;
|
|
24
21
|
};
|
|
25
22
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
@@ -35,17 +32,13 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
35
32
|
select: (event: Event, row: {
|
|
36
33
|
original: Row;
|
|
37
34
|
}) => any;
|
|
38
|
-
reorder: (from: string, to: string) => any;
|
|
39
35
|
"update:selected": (value: string[]) => any;
|
|
40
|
-
"update:columnVisibility": (value: Record<string, boolean>) => any;
|
|
41
36
|
"update:sort": (value: TableSort | null) => any;
|
|
42
37
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
43
38
|
onSelect?: ((event: Event, row: {
|
|
44
39
|
original: Row;
|
|
45
40
|
}) => any) | undefined;
|
|
46
|
-
onReorder?: ((from: string, to: string) => any) | undefined;
|
|
47
41
|
"onUpdate:selected"?: ((value: string[]) => any) | undefined;
|
|
48
|
-
"onUpdate:columnVisibility"?: ((value: Record<string, boolean>) => any) | undefined;
|
|
49
42
|
"onUpdate:sort"?: ((value: TableSort | null) => any) | undefined;
|
|
50
43
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
51
44
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<textarea
|
|
3
3
|
:rows="rows ?? 3"
|
|
4
4
|
:value="model ?? ''"
|
|
5
|
-
:class="['cms-field',
|
|
5
|
+
:class="['cms-field', 'cms-field-md', { 'is-error': color === 'error' }]"
|
|
6
6
|
@input="model = $event.target.value"
|
|
7
7
|
/>
|
|
8
8
|
</template>
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
<script setup>
|
|
11
11
|
defineProps({
|
|
12
12
|
rows: { type: Number, required: false },
|
|
13
|
-
size: { type: String, required: false },
|
|
14
13
|
color: { type: String, required: false }
|
|
15
14
|
});
|
|
16
15
|
const model = defineModel({ type: [String, null] });
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
export interface
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export interface CmsConfirmLink {
|
|
2
|
+
title: string;
|
|
3
|
+
meta: string;
|
|
4
|
+
to: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CmsConfirmGroup {
|
|
7
|
+
title: string;
|
|
8
|
+
links: CmsConfirmLink[];
|
|
9
|
+
}
|
|
10
|
+
export interface CmsConfirmOptions {
|
|
4
11
|
title?: string;
|
|
5
12
|
confirmLabel?: string;
|
|
13
|
+
groups?: CmsConfirmGroup[];
|
|
14
|
+
}
|
|
15
|
+
export interface CmsConfirmState extends CmsConfirmOptions {
|
|
16
|
+
open: boolean;
|
|
17
|
+
message: string;
|
|
6
18
|
resolve?: (value: boolean) => void;
|
|
7
19
|
}
|
|
8
20
|
export declare function useCmsConfirmState(): import("vue").Ref<CmsConfirmState, CmsConfirmState>;
|
|
9
|
-
export declare function useCmsConfirm(): (message: string, options?:
|
|
10
|
-
title?: string;
|
|
11
|
-
confirmLabel?: string;
|
|
12
|
-
}) => Promise<boolean>;
|
|
21
|
+
export declare function useCmsConfirm(): (message: string, options?: CmsConfirmOptions) => Promise<boolean>;
|
|
@@ -17,7 +17,7 @@ export function useCmsCollection(name, options = {}) {
|
|
|
17
17
|
export function useCmsPage(path, options = {}) {
|
|
18
18
|
const { locale, key, default: fallback } = options;
|
|
19
19
|
return useAsyncData(
|
|
20
|
-
`cms-page:${String(path)}:${locale ?? ""}`,
|
|
20
|
+
key ?? `cms-page:${String(path)}:${locale ?? ""}`,
|
|
21
21
|
async () => fallback ? fallback() : null
|
|
22
22
|
);
|
|
23
23
|
}
|
|
@@ -6,9 +6,14 @@ function load() {
|
|
|
6
6
|
known.value = result.source.kind === "none" ? null : new Set(result.items.map((item) => item.key));
|
|
7
7
|
}).catch(() => {
|
|
8
8
|
known.value = null;
|
|
9
|
+
loading = null;
|
|
9
10
|
});
|
|
10
11
|
return loading;
|
|
11
12
|
}
|
|
13
|
+
export function invalidateCmsMediaKeys() {
|
|
14
|
+
loading = null;
|
|
15
|
+
known.value = null;
|
|
16
|
+
}
|
|
12
17
|
export function useCmsMediaKeys() {
|
|
13
18
|
if (import.meta.client) void load();
|
|
14
19
|
function isMissing(key) {
|
|
@@ -71,5 +71,4 @@ export declare function useCmsMediaLibrary(): {
|
|
|
71
71
|
usage: (keys: string[]) => Promise<Record<string, MediaUsage[]> | null>;
|
|
72
72
|
};
|
|
73
73
|
export type CmsMediaLibrary = ReturnType<typeof useCmsMediaLibrary>;
|
|
74
|
-
export declare function
|
|
75
|
-
export declare function usageLink(usage: MediaUsage): string;
|
|
74
|
+
export declare function usageLink(usage: Pick<MediaUsage, 'collection' | 'id'>): string;
|
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
} from "../../shared/index.js";
|
|
7
7
|
import { computed, ref } from "#imports";
|
|
8
8
|
import { errorMessage } from "../utils/ui.js";
|
|
9
|
+
import { invalidateCmsMediaKeys } from "./cms-media-keys.js";
|
|
9
10
|
import { useCmsToast } from "./cms-toast.js";
|
|
10
11
|
const endpoint = "/api/cms/admin/media";
|
|
12
|
+
const USAGE_CHUNK = 1e3;
|
|
11
13
|
export function useCmsMediaLibrary() {
|
|
12
14
|
const toast = useCmsToast();
|
|
13
15
|
const items = ref([]);
|
|
@@ -81,6 +83,7 @@ export function useCmsMediaLibrary() {
|
|
|
81
83
|
method: "DELETE",
|
|
82
84
|
query: { name, recursive: "true" }
|
|
83
85
|
});
|
|
86
|
+
invalidateCmsMediaKeys();
|
|
84
87
|
await reload({ quiet: true });
|
|
85
88
|
});
|
|
86
89
|
}
|
|
@@ -93,6 +96,7 @@ export function useCmsMediaLibrary() {
|
|
|
93
96
|
function deleteItems(keys) {
|
|
94
97
|
return attempt("Delete failed", async () => {
|
|
95
98
|
await $fetch(`${endpoint}/delete`, { method: "POST", body: { keys } });
|
|
99
|
+
invalidateCmsMediaKeys();
|
|
96
100
|
await reload({ quiet: true });
|
|
97
101
|
});
|
|
98
102
|
}
|
|
@@ -103,13 +107,18 @@ export function useCmsMediaLibrary() {
|
|
|
103
107
|
});
|
|
104
108
|
}
|
|
105
109
|
async function usage(keys) {
|
|
106
|
-
|
|
110
|
+
const unique = [...new Set(keys)];
|
|
111
|
+
if (!unique.length) return {};
|
|
107
112
|
try {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
const merged = {};
|
|
114
|
+
for (let index = 0; index < unique.length; index += USAGE_CHUNK) {
|
|
115
|
+
const result = await $fetch(
|
|
116
|
+
`${endpoint}/usage`,
|
|
117
|
+
{ method: "POST", body: { keys: unique.slice(index, index + USAGE_CHUNK) } }
|
|
118
|
+
);
|
|
119
|
+
Object.assign(merged, result.usage);
|
|
120
|
+
}
|
|
121
|
+
return merged;
|
|
113
122
|
} catch {
|
|
114
123
|
return null;
|
|
115
124
|
}
|
|
@@ -133,19 +142,6 @@ export function useCmsMediaLibrary() {
|
|
|
133
142
|
usage
|
|
134
143
|
};
|
|
135
144
|
}
|
|
136
|
-
export function usageSummary(usage, keys) {
|
|
137
|
-
if (!usage) return "";
|
|
138
|
-
const entries = /* @__PURE__ */ new Set();
|
|
139
|
-
let used = 0;
|
|
140
|
-
for (const key of keys) {
|
|
141
|
-
const list = usage[key] ?? [];
|
|
142
|
-
if (list.length) used++;
|
|
143
|
-
for (const item of list) entries.add(`${item.collection}:${item.id ?? ""}`);
|
|
144
|
-
}
|
|
145
|
-
if (!used) return "";
|
|
146
|
-
const files = keys.length === 1 ? "It is" : `${used} of them are`;
|
|
147
|
-
return `${files} used in ${entries.size} entr${entries.size === 1 ? "y" : "ies"}, which will keep a broken link.`;
|
|
148
|
-
}
|
|
149
145
|
export function usageLink(usage) {
|
|
150
146
|
return usage.id === null ? `/cms/${usage.collection}` : `/cms/${usage.collection}/${usage.id}`;
|
|
151
147
|
}
|
|
@@ -39,7 +39,7 @@ async function mediaDimensions(file) {
|
|
|
39
39
|
if (file.type.startsWith("video/")) return videoDimensions(file);
|
|
40
40
|
return {};
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
function matchesAccept(file, accept) {
|
|
43
43
|
if (!accept) return true;
|
|
44
44
|
return accept.split(",").some((raw) => {
|
|
45
45
|
const pattern = raw.trim().toLowerCase();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { onBeforeUnmount } from "#imports";
|
|
2
|
+
const stack = [];
|
|
3
|
+
function onKeydown(event) {
|
|
4
|
+
if (event.key !== "Escape") return;
|
|
5
|
+
stack[stack.length - 1]?.close();
|
|
6
|
+
}
|
|
7
|
+
export function useCmsOverlay(close) {
|
|
8
|
+
const entry = { close };
|
|
9
|
+
function activate() {
|
|
10
|
+
if (import.meta.server || stack.includes(entry)) return;
|
|
11
|
+
stack.push(entry);
|
|
12
|
+
if (stack.length === 1) document.addEventListener("keydown", onKeydown);
|
|
13
|
+
}
|
|
14
|
+
function deactivate() {
|
|
15
|
+
if (import.meta.server) return;
|
|
16
|
+
const index = stack.indexOf(entry);
|
|
17
|
+
if (index === -1) return;
|
|
18
|
+
stack.splice(index, 1);
|
|
19
|
+
if (stack.length === 0) document.removeEventListener("keydown", onKeydown);
|
|
20
|
+
}
|
|
21
|
+
onBeforeUnmount(deactivate);
|
|
22
|
+
return { activate, deactivate };
|
|
23
|
+
}
|
|
@@ -7,7 +7,6 @@ export declare function useCmsSettings(): {
|
|
|
7
7
|
reset: (name: string) => Promise<void>;
|
|
8
8
|
};
|
|
9
9
|
export declare function entryFields(name: string): Record<string, import("#nuxt-cms").FieldConfig>;
|
|
10
|
-
export declare function defaultFormLayout(name: string, fields?: Record<string, import("#nuxt-cms").FieldConfig>): CmsFormLayout;
|
|
11
10
|
export declare function entryFormLayout(name: string, settings: CmsSettingsMap, fields?: Record<string, import("#nuxt-cms").FieldConfig>): CmsFormLayout;
|
|
12
11
|
export declare function listExtraColumns(name: string): string[];
|
|
13
12
|
export declare function entryListColumns(name: string, settings: CmsSettingsMap): string[];
|
|
@@ -36,7 +36,7 @@ export function entryFields(name) {
|
|
|
36
36
|
if (!entry) return {};
|
|
37
37
|
return entry.kind === "page" ? pageAllFields(entry) : entry.fields;
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
function defaultFormLayout(name, fields = entryFields(name)) {
|
|
40
40
|
return resolveFormLayout(fields, layoutFromConfig(entryOf(name)?.layout));
|
|
41
41
|
}
|
|
42
42
|
export function entryFormLayout(name, settings, fields = entryFields(name)) {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { InjectionKey, Reactive } from 'vue';
|
|
2
2
|
import type { FieldConfig } from '#nuxt-cms';
|
|
3
|
-
/** Shared reactive map of field-name -> error message, provided by CmsForm and
|
|
4
|
-
* read by CmsFormField to render inline validation errors. */
|
|
5
3
|
export declare const CMS_FORM_ERRORS: InjectionKey<Reactive<Record<string, string>>>;
|
|
6
4
|
export declare function errorMessage(error: unknown): string | undefined;
|
|
7
5
|
export declare function fieldIcon(field: FieldConfig): string;
|