@hywax/cms-console 1.0.0
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/.nuxt/cms-console/button-copy-text.ts +19 -0
- package/.nuxt/cms-console/button-delete-confirm.ts +5 -0
- package/.nuxt/cms-console/editor/index.ts +0 -0
- package/.nuxt/cms-console/form-panel-aside-section.ts +9 -0
- package/.nuxt/cms-console/form-panel-section.ts +8 -0
- package/.nuxt/cms-console/form-panel.ts +15 -0
- package/.nuxt/cms-console/index.ts +11 -0
- package/.nuxt/cms-console/input-seo.ts +5 -0
- package/.nuxt/cms-console/input-slug.ts +5 -0
- package/.nuxt/cms-console/input-uplora-image.ts +27 -0
- package/.nuxt/cms-console/modal-confirm.ts +5 -0
- package/.nuxt/cms-console/table-panel.ts +8 -0
- package/.nuxt/cms-console/table-search-input.ts +6 -0
- package/.nuxt/cms-console.css +31 -0
- package/dist/module.d.mts +11 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +387 -0
- package/dist/runtime/components/AutocompleteSelect.d.vue.ts +56 -0
- package/dist/runtime/components/AutocompleteSelect.vue +225 -0
- package/dist/runtime/components/AutocompleteSelect.vue.d.ts +56 -0
- package/dist/runtime/components/ButtonCopyText.d.vue.ts +28 -0
- package/dist/runtime/components/ButtonCopyText.vue +70 -0
- package/dist/runtime/components/ButtonCopyText.vue.d.ts +28 -0
- package/dist/runtime/components/ButtonDeleteConfirm.d.vue.ts +38 -0
- package/dist/runtime/components/ButtonDeleteConfirm.vue +62 -0
- package/dist/runtime/components/ButtonDeleteConfirm.vue.d.ts +38 -0
- package/dist/runtime/components/DatePicker.d.vue.ts +43 -0
- package/dist/runtime/components/DatePicker.vue +232 -0
- package/dist/runtime/components/DatePicker.vue.d.ts +43 -0
- package/dist/runtime/components/EditorFull.d.vue.ts +13 -0
- package/dist/runtime/components/EditorFull.vue +139 -0
- package/dist/runtime/components/EditorFull.vue.d.ts +13 -0
- package/dist/runtime/components/EditorLinkPopover.d.vue.ts +8 -0
- package/dist/runtime/components/EditorLinkPopover.vue +137 -0
- package/dist/runtime/components/EditorLinkPopover.vue.d.ts +8 -0
- package/dist/runtime/components/FormPanel.d.vue.ts +47 -0
- package/dist/runtime/components/FormPanel.vue +73 -0
- package/dist/runtime/components/FormPanel.vue.d.ts +47 -0
- package/dist/runtime/components/FormPanelAsideSection.d.vue.ts +24 -0
- package/dist/runtime/components/FormPanelAsideSection.vue +41 -0
- package/dist/runtime/components/FormPanelAsideSection.vue.d.ts +24 -0
- package/dist/runtime/components/FormPanelSection.d.vue.ts +21 -0
- package/dist/runtime/components/FormPanelSection.vue +31 -0
- package/dist/runtime/components/FormPanelSection.vue.d.ts +21 -0
- package/dist/runtime/components/InputSeo.d.vue.ts +21 -0
- package/dist/runtime/components/InputSeo.vue +73 -0
- package/dist/runtime/components/InputSeo.vue.d.ts +21 -0
- package/dist/runtime/components/InputSlug.d.vue.ts +30 -0
- package/dist/runtime/components/InputSlug.vue +70 -0
- package/dist/runtime/components/InputSlug.vue.d.ts +30 -0
- package/dist/runtime/components/InputUploraImage.d.vue.ts +39 -0
- package/dist/runtime/components/InputUploraImage.vue +163 -0
- package/dist/runtime/components/InputUploraImage.vue.d.ts +39 -0
- package/dist/runtime/components/Layout.d.vue.ts +30 -0
- package/dist/runtime/components/Layout.vue +82 -0
- package/dist/runtime/components/Layout.vue.d.ts +30 -0
- package/dist/runtime/components/ModalConfirm.d.vue.ts +33 -0
- package/dist/runtime/components/ModalConfirm.vue +97 -0
- package/dist/runtime/components/ModalConfirm.vue.d.ts +33 -0
- package/dist/runtime/components/TableColumnSorting.d.vue.ts +17 -0
- package/dist/runtime/components/TableColumnSorting.vue +81 -0
- package/dist/runtime/components/TableColumnSorting.vue.d.ts +17 -0
- package/dist/runtime/components/TableColumnVisibility.d.vue.ts +24 -0
- package/dist/runtime/components/TableColumnVisibility.vue +110 -0
- package/dist/runtime/components/TableColumnVisibility.vue.d.ts +24 -0
- package/dist/runtime/components/TableFilters.d.vue.ts +90 -0
- package/dist/runtime/components/TableFilters.vue +199 -0
- package/dist/runtime/components/TableFilters.vue.d.ts +90 -0
- package/dist/runtime/components/TablePanel.d.vue.ts +95 -0
- package/dist/runtime/components/TablePanel.vue +297 -0
- package/dist/runtime/components/TablePanel.vue.d.ts +95 -0
- package/dist/runtime/components/TableSearchInput.d.vue.ts +33 -0
- package/dist/runtime/components/TableSearchInput.vue +97 -0
- package/dist/runtime/components/TableSearchInput.vue.d.ts +33 -0
- package/dist/runtime/composables/useAdmin.d.ts +6 -0
- package/dist/runtime/composables/useAdmin.js +14 -0
- package/dist/runtime/composables/useEditorDragHandle.d.ts +17 -0
- package/dist/runtime/composables/useEditorDragHandle.js +95 -0
- package/dist/runtime/composables/useEditorSuggestions.d.ts +74 -0
- package/dist/runtime/composables/useEditorSuggestions.js +25 -0
- package/dist/runtime/composables/useEditorToolbar.d.ts +121 -0
- package/dist/runtime/composables/useEditorToolbar.js +87 -0
- package/dist/runtime/composables/useQueryState.d.ts +28 -0
- package/dist/runtime/composables/useQueryState.js +105 -0
- package/dist/runtime/composables/useRouteQuery.d.ts +37 -0
- package/dist/runtime/composables/useRouteQuery.js +81 -0
- package/dist/runtime/composables/useSeoStats.d.ts +12 -0
- package/dist/runtime/composables/useSeoStats.js +44 -0
- package/dist/runtime/composables/useTable.d.ts +25 -0
- package/dist/runtime/composables/useTable.js +84 -0
- package/dist/runtime/composables/useTableColumns.d.ts +28 -0
- package/dist/runtime/composables/useTableColumns.js +54 -0
- package/dist/runtime/editor/uplora-image/EditorUploraImage.d.ts +18 -0
- package/dist/runtime/editor/uplora-image/EditorUploraImage.js +42 -0
- package/dist/runtime/editor/uplora-image/EditorUploraImageNode.d.vue.ts +4 -0
- package/dist/runtime/editor/uplora-image/EditorUploraImageNode.vue +23 -0
- package/dist/runtime/editor/uplora-image/EditorUploraImageNode.vue.d.ts +4 -0
- package/dist/runtime/index.css +1 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/tv.d.ts +1 -0
- package/dist/runtime/tv.js +4 -0
- package/dist/runtime/types/app.config.d.ts +6 -0
- package/dist/runtime/types/date.d.ts +5 -0
- package/dist/runtime/types/date.js +0 -0
- package/dist/runtime/types/dictionaries.d.ts +1 -0
- package/dist/runtime/types/dictionaries.js +0 -0
- package/dist/runtime/types/index.d.ts +30 -0
- package/dist/runtime/types/index.js +30 -0
- package/dist/runtime/types/seo.d.ts +4 -0
- package/dist/runtime/types/seo.js +0 -0
- package/dist/runtime/utils/auth.d.ts +2 -0
- package/dist/runtime/utils/auth.js +5 -0
- package/dist/runtime/utils/date.d.ts +5 -0
- package/dist/runtime/utils/date.js +15 -0
- package/dist/runtime/utils/formatters.d.ts +5 -0
- package/dist/runtime/utils/formatters.js +24 -0
- package/dist/runtime/utils/index.d.ts +4 -0
- package/dist/runtime/utils/index.js +4 -0
- package/dist/runtime/utils/slugify.d.ts +1 -0
- package/dist/runtime/utils/slugify.js +11 -0
- package/dist/types.d.mts +11 -0
- package/package.json +89 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { useAppConfig } from "#imports";
|
|
2
|
+
import { mapEditorItems } from "@nuxt/ui/utils/editor";
|
|
3
|
+
import { upperFirst } from "scule";
|
|
4
|
+
import { ref, toValue } from "vue";
|
|
5
|
+
export function useEditorDragHandle(customHandlers) {
|
|
6
|
+
const appConfig = useAppConfig();
|
|
7
|
+
const selectedNode = ref();
|
|
8
|
+
const getItems = (editor) => {
|
|
9
|
+
if (!selectedNode.value?.node?.type) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
return mapEditorItems(editor, [
|
|
13
|
+
[
|
|
14
|
+
{
|
|
15
|
+
type: "label",
|
|
16
|
+
label: upperFirst(selectedNode.value.node.type)
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
label: "\u0417\u0430\u043C\u0435\u043D\u0438\u0442\u044C",
|
|
20
|
+
icon: appConfig.ui.icons.repeat,
|
|
21
|
+
children: [
|
|
22
|
+
{ kind: "paragraph", label: "\u041F\u0430\u0440\u0430\u0433\u0440\u0430\u0444", icon: appConfig.ui.icons.paragraph },
|
|
23
|
+
{ kind: "heading", level: 1, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 1", icon: appConfig.ui.icons.heading1 },
|
|
24
|
+
{ kind: "heading", level: 2, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 2", icon: appConfig.ui.icons.heading2 },
|
|
25
|
+
{ kind: "heading", level: 3, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 3", icon: appConfig.ui.icons.heading3 },
|
|
26
|
+
{ kind: "heading", level: 4, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 4", icon: appConfig.ui.icons.heading4 },
|
|
27
|
+
{ kind: "bulletList", label: "\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0441\u043F\u0438\u0441\u043E\u043A", icon: appConfig.ui.icons.list },
|
|
28
|
+
{ kind: "orderedList", label: "\u041D\u0443\u043C\u0435\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0441\u043F\u0438\u0441\u043E\u043A", icon: appConfig.ui.icons.listOrdered },
|
|
29
|
+
{ kind: "blockquote", label: "\u0426\u0438\u0442\u0430\u0442\u0430", icon: appConfig.ui.icons.blockquote },
|
|
30
|
+
{ kind: "codeBlock", label: "\u0411\u043B\u043E\u043A \u043A\u043E\u0434\u0430", icon: appConfig.ui.icons.codeBlock }
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
kind: "clearFormatting",
|
|
35
|
+
pos: selectedNode.value?.pos,
|
|
36
|
+
label: "\u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435",
|
|
37
|
+
icon: appConfig.ui.icons.reload
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
{
|
|
42
|
+
kind: "duplicate",
|
|
43
|
+
pos: selectedNode.value?.pos,
|
|
44
|
+
label: "\u0414\u0443\u0431\u043B\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
|
|
45
|
+
icon: appConfig.ui.icons.copy
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
|
|
49
|
+
icon: appConfig.ui.icons.clipboard,
|
|
50
|
+
onSelect: async () => {
|
|
51
|
+
if (!selectedNode.value) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const pos = selectedNode.value.pos;
|
|
55
|
+
const node = editor.state.doc.nodeAt(pos);
|
|
56
|
+
if (node) {
|
|
57
|
+
await navigator.clipboard.writeText(node.textContent);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
{
|
|
64
|
+
kind: "moveUp",
|
|
65
|
+
pos: selectedNode.value?.pos,
|
|
66
|
+
label: "\u041F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u0432\u0432\u0435\u0440\u0445",
|
|
67
|
+
icon: appConfig.ui.icons.arrowUp
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
kind: "moveDown",
|
|
71
|
+
pos: selectedNode.value?.pos,
|
|
72
|
+
label: "\u041F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u0432\u043D\u0438\u0437",
|
|
73
|
+
icon: appConfig.ui.icons.arrowDown
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
{
|
|
78
|
+
kind: "delete",
|
|
79
|
+
pos: selectedNode.value?.pos,
|
|
80
|
+
label: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C",
|
|
81
|
+
color: "error",
|
|
82
|
+
icon: appConfig.ui.icons.trash
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
], toValue(customHandlers));
|
|
86
|
+
};
|
|
87
|
+
const onNodeChange = (event) => {
|
|
88
|
+
selectedNode.value = event;
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
selectedNode,
|
|
92
|
+
getItems,
|
|
93
|
+
onNodeChange
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { EditorCustomHandlers } from '@nuxt/ui';
|
|
2
|
+
import type { MaybeRefOrGetter } from 'vue';
|
|
3
|
+
export declare function useEditorSuggestions<T extends EditorCustomHandlers>(_customHandlers?: MaybeRefOrGetter<T>): {
|
|
4
|
+
items: (({
|
|
5
|
+
type: "label";
|
|
6
|
+
label: string;
|
|
7
|
+
kind?: undefined;
|
|
8
|
+
icon?: undefined;
|
|
9
|
+
level?: undefined;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "paragraph";
|
|
12
|
+
label: string;
|
|
13
|
+
icon: any;
|
|
14
|
+
type?: undefined;
|
|
15
|
+
level?: undefined;
|
|
16
|
+
} | {
|
|
17
|
+
kind: "heading";
|
|
18
|
+
level: 1;
|
|
19
|
+
label: string;
|
|
20
|
+
icon: any;
|
|
21
|
+
type?: undefined;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "heading";
|
|
24
|
+
level: 2;
|
|
25
|
+
label: string;
|
|
26
|
+
icon: any;
|
|
27
|
+
type?: undefined;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "heading";
|
|
30
|
+
level: 3;
|
|
31
|
+
label: string;
|
|
32
|
+
icon: any;
|
|
33
|
+
type?: undefined;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "bulletList";
|
|
36
|
+
label: string;
|
|
37
|
+
icon: any;
|
|
38
|
+
type?: undefined;
|
|
39
|
+
level?: undefined;
|
|
40
|
+
} | {
|
|
41
|
+
kind: "orderedList";
|
|
42
|
+
label: string;
|
|
43
|
+
icon: any;
|
|
44
|
+
type?: undefined;
|
|
45
|
+
level?: undefined;
|
|
46
|
+
} | {
|
|
47
|
+
kind: "blockquote";
|
|
48
|
+
label: string;
|
|
49
|
+
icon: any;
|
|
50
|
+
type?: undefined;
|
|
51
|
+
level?: undefined;
|
|
52
|
+
} | {
|
|
53
|
+
kind: "codeBlock";
|
|
54
|
+
label: string;
|
|
55
|
+
icon: any;
|
|
56
|
+
type?: undefined;
|
|
57
|
+
level?: undefined;
|
|
58
|
+
})[] | ({
|
|
59
|
+
type: "label";
|
|
60
|
+
label: string;
|
|
61
|
+
kind?: undefined;
|
|
62
|
+
icon?: undefined;
|
|
63
|
+
} | {
|
|
64
|
+
kind: "horizontalRule";
|
|
65
|
+
label: string;
|
|
66
|
+
icon: any;
|
|
67
|
+
type?: undefined;
|
|
68
|
+
} | {
|
|
69
|
+
kind: "uploraImage";
|
|
70
|
+
label: string;
|
|
71
|
+
icon: any;
|
|
72
|
+
type?: undefined;
|
|
73
|
+
})[])[];
|
|
74
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useAppConfig } from "#imports";
|
|
2
|
+
export function useEditorSuggestions(_customHandlers) {
|
|
3
|
+
const appConfig = useAppConfig();
|
|
4
|
+
const items = [
|
|
5
|
+
[
|
|
6
|
+
{ type: "label", label: "\u0422\u0438\u043F" },
|
|
7
|
+
{ kind: "paragraph", label: "\u041F\u0430\u0440\u0430\u0433\u0440\u0430\u0444", icon: appConfig.ui.icons.paragraph },
|
|
8
|
+
{ kind: "heading", level: 1, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 1", icon: appConfig.ui.icons.heading1 },
|
|
9
|
+
{ kind: "heading", level: 2, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 2", icon: appConfig.ui.icons.heading2 },
|
|
10
|
+
{ kind: "heading", level: 3, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 3", icon: appConfig.ui.icons.heading3 },
|
|
11
|
+
{ kind: "bulletList", label: "\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0441\u043F\u0438\u0441\u043E\u043A", icon: appConfig.ui.icons.list },
|
|
12
|
+
{ kind: "orderedList", label: "\u041D\u0443\u043C\u0435\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0441\u043F\u0438\u0441\u043E\u043A", icon: appConfig.ui.icons.listOrdered },
|
|
13
|
+
{ kind: "blockquote", label: "\u0426\u0438\u0442\u0430\u0442\u0430", icon: appConfig.ui.icons.blockquote },
|
|
14
|
+
{ kind: "codeBlock", label: "\u0411\u043B\u043E\u043A \u043A\u043E\u0434\u0430", icon: appConfig.ui.icons.codeBlock }
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
{ type: "label", label: "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044C" },
|
|
18
|
+
{ kind: "horizontalRule", label: "\u0413\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u0430\u044F \u043B\u0438\u043D\u0438\u044F", icon: appConfig.ui.icons.horizontalRule },
|
|
19
|
+
{ kind: "uploraImage", label: "\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435", icon: appConfig.ui.icons.image }
|
|
20
|
+
]
|
|
21
|
+
];
|
|
22
|
+
return {
|
|
23
|
+
items
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { EditorCustomHandlers, EditorToolbarItem } from '@nuxt/ui';
|
|
2
|
+
import type { Editor } from '@tiptap/vue-3';
|
|
3
|
+
import type { MaybeRefOrGetter } from 'vue';
|
|
4
|
+
export declare function useEditorToolbar<T extends EditorCustomHandlers>(_customHandlers?: MaybeRefOrGetter<T>): {
|
|
5
|
+
toolbarItems: EditorToolbarItem<T>[][];
|
|
6
|
+
bubbleToolbarItems: import("vue").ComputedRef<({
|
|
7
|
+
label: string;
|
|
8
|
+
trailingIcon: any;
|
|
9
|
+
activeColor: "neutral";
|
|
10
|
+
activeVariant: "ghost";
|
|
11
|
+
tooltip: {
|
|
12
|
+
text: string;
|
|
13
|
+
};
|
|
14
|
+
content: {
|
|
15
|
+
align: "start";
|
|
16
|
+
};
|
|
17
|
+
ui: {
|
|
18
|
+
label: string;
|
|
19
|
+
};
|
|
20
|
+
items: ({
|
|
21
|
+
type: "label";
|
|
22
|
+
label: string;
|
|
23
|
+
kind?: undefined;
|
|
24
|
+
icon?: undefined;
|
|
25
|
+
level?: undefined;
|
|
26
|
+
} | {
|
|
27
|
+
kind: "paragraph";
|
|
28
|
+
label: string;
|
|
29
|
+
icon: any;
|
|
30
|
+
type?: undefined;
|
|
31
|
+
level?: undefined;
|
|
32
|
+
} | {
|
|
33
|
+
kind: "heading";
|
|
34
|
+
level: 1;
|
|
35
|
+
icon: any;
|
|
36
|
+
label: string;
|
|
37
|
+
type?: undefined;
|
|
38
|
+
} | {
|
|
39
|
+
kind: "heading";
|
|
40
|
+
level: 2;
|
|
41
|
+
icon: any;
|
|
42
|
+
label: string;
|
|
43
|
+
type?: undefined;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "heading";
|
|
46
|
+
level: 3;
|
|
47
|
+
icon: any;
|
|
48
|
+
label: string;
|
|
49
|
+
type?: undefined;
|
|
50
|
+
} | {
|
|
51
|
+
kind: "heading";
|
|
52
|
+
level: 4;
|
|
53
|
+
icon: any;
|
|
54
|
+
label: string;
|
|
55
|
+
type?: undefined;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "bulletList";
|
|
58
|
+
icon: any;
|
|
59
|
+
label: string;
|
|
60
|
+
type?: undefined;
|
|
61
|
+
level?: undefined;
|
|
62
|
+
} | {
|
|
63
|
+
kind: "orderedList";
|
|
64
|
+
icon: any;
|
|
65
|
+
label: string;
|
|
66
|
+
type?: undefined;
|
|
67
|
+
level?: undefined;
|
|
68
|
+
} | {
|
|
69
|
+
kind: "blockquote";
|
|
70
|
+
icon: any;
|
|
71
|
+
label: string;
|
|
72
|
+
type?: undefined;
|
|
73
|
+
level?: undefined;
|
|
74
|
+
} | {
|
|
75
|
+
kind: "codeBlock";
|
|
76
|
+
icon: any;
|
|
77
|
+
label: string;
|
|
78
|
+
type?: undefined;
|
|
79
|
+
level?: undefined;
|
|
80
|
+
})[];
|
|
81
|
+
}[] | ({
|
|
82
|
+
kind: "mark";
|
|
83
|
+
mark: "bold";
|
|
84
|
+
icon: any;
|
|
85
|
+
tooltip: {
|
|
86
|
+
text: string;
|
|
87
|
+
};
|
|
88
|
+
} | {
|
|
89
|
+
kind: "mark";
|
|
90
|
+
mark: "italic";
|
|
91
|
+
icon: any;
|
|
92
|
+
tooltip: {
|
|
93
|
+
text: string;
|
|
94
|
+
};
|
|
95
|
+
} | {
|
|
96
|
+
kind: "mark";
|
|
97
|
+
mark: "underline";
|
|
98
|
+
icon: any;
|
|
99
|
+
tooltip: {
|
|
100
|
+
text: string;
|
|
101
|
+
};
|
|
102
|
+
} | {
|
|
103
|
+
kind: "mark";
|
|
104
|
+
mark: "strike";
|
|
105
|
+
icon: any;
|
|
106
|
+
tooltip: {
|
|
107
|
+
text: string;
|
|
108
|
+
};
|
|
109
|
+
} | {
|
|
110
|
+
kind: "mark";
|
|
111
|
+
mark: "code";
|
|
112
|
+
icon: any;
|
|
113
|
+
tooltip: {
|
|
114
|
+
text: string;
|
|
115
|
+
};
|
|
116
|
+
})[] | {
|
|
117
|
+
slot: "link";
|
|
118
|
+
icon: any;
|
|
119
|
+
}[])[]>;
|
|
120
|
+
getImageToolbarItems: (editor: Editor) => EditorToolbarItem<T>[][];
|
|
121
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { useAppConfig } from "#imports";
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
export function useEditorToolbar(_customHandlers) {
|
|
4
|
+
const appConfig = useAppConfig();
|
|
5
|
+
const toolbarItems = [];
|
|
6
|
+
const bubbleToolbarItems = computed(() => [
|
|
7
|
+
[
|
|
8
|
+
{
|
|
9
|
+
label: "\u041F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u0442\u044C",
|
|
10
|
+
trailingIcon: appConfig.ui.icons.chevronDown,
|
|
11
|
+
activeColor: "neutral",
|
|
12
|
+
activeVariant: "ghost",
|
|
13
|
+
tooltip: { text: "\u041F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u0442\u044C" },
|
|
14
|
+
content: { align: "start" },
|
|
15
|
+
ui: { label: "text-xs" },
|
|
16
|
+
items: [
|
|
17
|
+
{ type: "label", label: "\u041F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u0442\u044C" },
|
|
18
|
+
{ kind: "paragraph", label: "\u041F\u0430\u0440\u0430\u0433\u0440\u0430\u0444", icon: appConfig.ui.icons.paragraph },
|
|
19
|
+
{ kind: "heading", level: 1, icon: appConfig.ui.icons.heading1, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 1" },
|
|
20
|
+
{ kind: "heading", level: 2, icon: appConfig.ui.icons.heading2, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 2" },
|
|
21
|
+
{ kind: "heading", level: 3, icon: appConfig.ui.icons.heading3, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 3" },
|
|
22
|
+
{ kind: "heading", level: 4, icon: appConfig.ui.icons.heading4, label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A 4" },
|
|
23
|
+
{ kind: "bulletList", icon: appConfig.ui.icons.list, label: "\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0441\u043F\u0438\u0441\u043E\u043A" },
|
|
24
|
+
{ kind: "orderedList", icon: appConfig.ui.icons.listOrdered, label: "\u041D\u0443\u043C\u0435\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0441\u043F\u0438\u0441\u043E\u043A" },
|
|
25
|
+
{ kind: "blockquote", icon: appConfig.ui.icons.blockquote, label: "\u0426\u0438\u0442\u0430\u0442\u0430" },
|
|
26
|
+
{ kind: "codeBlock", icon: appConfig.ui.icons.codeBlock, label: "\u0411\u043B\u043E\u043A \u043A\u043E\u0434\u0430" }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
[
|
|
31
|
+
{ kind: "mark", mark: "bold", icon: appConfig.ui.icons.bold, tooltip: { text: "\u0416\u0438\u0440\u043D\u044B\u0439" } },
|
|
32
|
+
{ kind: "mark", mark: "italic", icon: appConfig.ui.icons.italic, tooltip: { text: "\u041A\u0443\u0440\u0441\u0438\u0432" } },
|
|
33
|
+
{ kind: "mark", mark: "underline", icon: appConfig.ui.icons.underline, tooltip: { text: "\u041F\u043E\u0434\u0447\u0435\u0440\u043A\u043D\u0443\u0442\u044B\u0439" } },
|
|
34
|
+
{ kind: "mark", mark: "strike", icon: appConfig.ui.icons.strikethrough, tooltip: { text: "\u0417\u0430\u0447\u0435\u0440\u043A\u043D\u0443\u0442\u044B\u0439" } },
|
|
35
|
+
{ kind: "mark", mark: "code", icon: appConfig.ui.icons.code, tooltip: { text: "\u041A\u043E\u0434" } }
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
{ slot: "link", icon: appConfig.ui.icons.link }
|
|
39
|
+
]
|
|
40
|
+
]);
|
|
41
|
+
const getImageToolbarItems = (editor) => {
|
|
42
|
+
const node = editor.state.doc.nodeAt(editor.state.selection.from);
|
|
43
|
+
return [
|
|
44
|
+
[
|
|
45
|
+
{
|
|
46
|
+
icon: appConfig.ui.icons.download,
|
|
47
|
+
to: node?.attrs?.src,
|
|
48
|
+
download: true,
|
|
49
|
+
tooltip: { text: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C" }
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
icon: appConfig.ui.icons.reload,
|
|
53
|
+
tooltip: { text: "\u0417\u0430\u043C\u0435\u043D\u0438\u0442\u044C" },
|
|
54
|
+
onClick: () => {
|
|
55
|
+
const { state } = editor;
|
|
56
|
+
const { selection } = state;
|
|
57
|
+
const pos = selection.from;
|
|
58
|
+
const node2 = state.doc.nodeAt(pos);
|
|
59
|
+
if (node2 && node2.type.name === "image") {
|
|
60
|
+
editor.chain().focus().deleteRange({ from: pos, to: pos + node2.nodeSize }).insertContentAt(pos, { type: "imageUpload" }).run();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
{
|
|
67
|
+
icon: appConfig.ui.icons.trash,
|
|
68
|
+
tooltip: { text: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C" },
|
|
69
|
+
onClick: () => {
|
|
70
|
+
const { state } = editor;
|
|
71
|
+
const { selection } = state;
|
|
72
|
+
const pos = selection.from;
|
|
73
|
+
const node2 = state.doc.nodeAt(pos);
|
|
74
|
+
if (node2 && node2.type.name === "image") {
|
|
75
|
+
editor.chain().focus().deleteRange({ from: pos, to: pos + node2.nodeSize }).run();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
];
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
toolbarItems,
|
|
84
|
+
bubbleToolbarItems,
|
|
85
|
+
getImageToolbarItems
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
import type { LocationQueryValue } from 'vue-router';
|
|
3
|
+
type RouteQueryValueRaw = LocationQueryValue | LocationQueryValue[] | undefined;
|
|
4
|
+
type QueryTransformGetter<Default, Value = Default> = (queryOrDefault: Default | RouteQueryValueRaw) => Value;
|
|
5
|
+
type QueryTransform<Default, Value = Default> = QueryTransformGetter<Default, Value> | ({
|
|
6
|
+
get?: QueryTransformGetter<Default, Value>;
|
|
7
|
+
set?: (value: Value) => RouteQueryValueRaw;
|
|
8
|
+
});
|
|
9
|
+
interface Transforms<Default> {
|
|
10
|
+
number: QueryTransformGetter<number | Default>;
|
|
11
|
+
boolean: QueryTransformGetter<boolean | Default>;
|
|
12
|
+
date: QueryTransformGetter<string | Default>;
|
|
13
|
+
dateRange: QueryTransform<{
|
|
14
|
+
end: string;
|
|
15
|
+
start: string;
|
|
16
|
+
} | Default>;
|
|
17
|
+
arrayString: QueryTransformGetter<any[] extends Default ? Default : string[]>;
|
|
18
|
+
}
|
|
19
|
+
type GetTransform<T> = keyof {
|
|
20
|
+
[P in keyof Transforms<T> as Transforms<T>[P] extends QueryTransform<any, T> ? P : never]: P;
|
|
21
|
+
};
|
|
22
|
+
export type GetQueryTransforms<T> = {
|
|
23
|
+
[P in keyof T as T[P] extends Exclude<RouteQueryValueRaw, any[]> ? never : P]: GetTransform<T[P]> | QueryTransform<T[P], T[P]>;
|
|
24
|
+
} & {
|
|
25
|
+
[P in keyof T as T[P] extends Exclude<RouteQueryValueRaw, any[]> ? P : never]?: GetTransform<T[P]> | QueryTransform<T[P], T[P]>;
|
|
26
|
+
};
|
|
27
|
+
export declare function useQueryState<T extends Record<string, any>>(defaults: MaybeRefOrGetter<T>, stateTransforms: GetQueryTransforms<T>): Ref<T>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useRoute, useRouter } from "#imports";
|
|
2
|
+
import { computed, customRef, reactive, toValue, watch } from "vue";
|
|
3
|
+
import { formatServerDateTime } from "../utils/date.js";
|
|
4
|
+
import { useRouteQuery } from "./useRouteQuery.js";
|
|
5
|
+
const valuesCache = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
const queryTransforms = {
|
|
7
|
+
number: (val) => val === null || val === void 0 ? val : Number(val),
|
|
8
|
+
boolean: (val) => val === null || val === void 0 ? val : val === "true" ? true : val === "false" ? false : Boolean(val),
|
|
9
|
+
date: (val) => val === null || val === void 0 ? val : formatServerDateTime(val),
|
|
10
|
+
dateRange: {
|
|
11
|
+
get: (val) => {
|
|
12
|
+
if (!Array.isArray(val)) {
|
|
13
|
+
return val;
|
|
14
|
+
}
|
|
15
|
+
if (valuesCache.has(val)) {
|
|
16
|
+
return valuesCache.get(val);
|
|
17
|
+
}
|
|
18
|
+
const date = {
|
|
19
|
+
start: formatServerDateTime(val[0]),
|
|
20
|
+
end: formatServerDateTime(val[1])
|
|
21
|
+
};
|
|
22
|
+
valuesCache.set(val, date);
|
|
23
|
+
return date;
|
|
24
|
+
},
|
|
25
|
+
set: (value) => {
|
|
26
|
+
if (!value || typeof value !== "object") {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
return [value.start, value.end];
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
arrayString: (val) => {
|
|
33
|
+
if (typeof val === "string") {
|
|
34
|
+
val = [val];
|
|
35
|
+
}
|
|
36
|
+
if (!Array.isArray(val)) {
|
|
37
|
+
return val;
|
|
38
|
+
}
|
|
39
|
+
if (valuesCache.has(val)) {
|
|
40
|
+
return valuesCache.get(val);
|
|
41
|
+
} else {
|
|
42
|
+
valuesCache.set(val, val);
|
|
43
|
+
}
|
|
44
|
+
return val;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
export function useQueryState(defaults, stateTransforms) {
|
|
48
|
+
const route = useRoute();
|
|
49
|
+
const router = useRouter();
|
|
50
|
+
const defaultsValue = computed(() => toValue(defaults));
|
|
51
|
+
const proxy = customRef((track, trigger) => {
|
|
52
|
+
let queryState = { _initial: true };
|
|
53
|
+
return {
|
|
54
|
+
get: () => {
|
|
55
|
+
track();
|
|
56
|
+
return queryState;
|
|
57
|
+
},
|
|
58
|
+
set: (newValue) => {
|
|
59
|
+
if (newValue === queryState) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (typeof newValue !== "object" || newValue === null) {
|
|
63
|
+
queryState = newValue;
|
|
64
|
+
return trigger();
|
|
65
|
+
}
|
|
66
|
+
const defaultValuesValue = defaultsValue.value;
|
|
67
|
+
const newQueryState = {};
|
|
68
|
+
for (const key in newValue) {
|
|
69
|
+
const query = createQuery(key, defaultValuesValue[key]);
|
|
70
|
+
const newValueField = newValue[key];
|
|
71
|
+
if (query.value !== newValueField && !queryState._initial) {
|
|
72
|
+
query.value = newValueField;
|
|
73
|
+
}
|
|
74
|
+
newQueryState[key] = query;
|
|
75
|
+
}
|
|
76
|
+
queryState = reactive(newQueryState);
|
|
77
|
+
trigger();
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
watch(() => toValue(defaults), (value) => {
|
|
82
|
+
proxy.value = value;
|
|
83
|
+
}, { immediate: true });
|
|
84
|
+
function getTransform(key) {
|
|
85
|
+
if (!stateTransforms[key]) {
|
|
86
|
+
return void 0;
|
|
87
|
+
}
|
|
88
|
+
const transform = stateTransforms[key];
|
|
89
|
+
if (typeof transform !== "function" && typeof transform !== "string") {
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
92
|
+
if (typeof transform === "string") {
|
|
93
|
+
return queryTransforms[transform];
|
|
94
|
+
}
|
|
95
|
+
return transform;
|
|
96
|
+
}
|
|
97
|
+
function createQuery(key, value) {
|
|
98
|
+
return useRouteQuery(key, value, {
|
|
99
|
+
transform: getTransform(key),
|
|
100
|
+
route,
|
|
101
|
+
router
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return proxy;
|
|
105
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { MaybeRef, MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
import type { RouteParamValueRaw } from 'vue-router';
|
|
3
|
+
import { useRoute, useRouter } from '#imports';
|
|
4
|
+
/**
|
|
5
|
+
* Скопировано из vueuse, модифицированно для поддержки не примитивов:
|
|
6
|
+
* @see https://github.com/vueuse/vueuse/blob/main/packages/router/useRouteQuery/index.ts
|
|
7
|
+
*/
|
|
8
|
+
export type RouteQueryValueRaw = RouteParamValueRaw | string[];
|
|
9
|
+
interface ReactiveRouteOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Mode to update the router query, ref is also acceptable
|
|
12
|
+
*
|
|
13
|
+
* @default 'replace'
|
|
14
|
+
*/
|
|
15
|
+
mode?: MaybeRef<'replace' | 'push'>;
|
|
16
|
+
/**
|
|
17
|
+
* Route instance, use `useRoute()` if not given
|
|
18
|
+
*/
|
|
19
|
+
route?: ReturnType<typeof useRoute>;
|
|
20
|
+
/**
|
|
21
|
+
* Router instance, use `useRouter()` if not given
|
|
22
|
+
*/
|
|
23
|
+
router?: ReturnType<typeof useRouter>;
|
|
24
|
+
}
|
|
25
|
+
interface ReactiveRouteOptionsWithTransform<V, R> extends ReactiveRouteOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Function to transform data before return, or an object with one or both functions:
|
|
28
|
+
* `get` to transform data before returning, and `set` to transform data before setting
|
|
29
|
+
*/
|
|
30
|
+
transform?: ((val: V) => R) | ({
|
|
31
|
+
get?: (value: V) => R;
|
|
32
|
+
set?: (value: R) => V;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export declare function useRouteQuery(name: string): Ref<undefined | null | string | string[]>;
|
|
36
|
+
export declare function useRouteQuery<T extends RouteQueryValueRaw = RouteQueryValueRaw, K = T>(name: string, defaultValue?: MaybeRefOrGetter<T>, options?: ReactiveRouteOptionsWithTransform<T, K>): Ref<K>;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { useRoute, useRouter } from "#imports";
|
|
2
|
+
import { tryOnScopeDispose } from "@vueuse/core";
|
|
3
|
+
import { customRef, nextTick, toValue, watch } from "vue";
|
|
4
|
+
const _queue = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
export function useRouteQuery(name, defaultValue, options = {}) {
|
|
6
|
+
const {
|
|
7
|
+
mode = "replace",
|
|
8
|
+
route = useRoute(),
|
|
9
|
+
router = useRouter(),
|
|
10
|
+
transform
|
|
11
|
+
} = options;
|
|
12
|
+
let transformGet = (value) => value;
|
|
13
|
+
let transformSet = (value) => value;
|
|
14
|
+
if (typeof transform === "function") {
|
|
15
|
+
transformGet = transform;
|
|
16
|
+
} else if (transform) {
|
|
17
|
+
if (transform.get) {
|
|
18
|
+
transformGet = transform.get;
|
|
19
|
+
}
|
|
20
|
+
if (transform.set) {
|
|
21
|
+
transformSet = transform.set;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!_queue.has(router)) {
|
|
25
|
+
_queue.set(router, /* @__PURE__ */ new Map());
|
|
26
|
+
}
|
|
27
|
+
const _queriesQueue = _queue.get(router);
|
|
28
|
+
let query = route.query[name];
|
|
29
|
+
tryOnScopeDispose(() => {
|
|
30
|
+
query = void 0;
|
|
31
|
+
});
|
|
32
|
+
let _trigger;
|
|
33
|
+
const proxy = customRef((track, trigger) => {
|
|
34
|
+
_trigger = trigger;
|
|
35
|
+
return {
|
|
36
|
+
get() {
|
|
37
|
+
track();
|
|
38
|
+
return transformGet(query !== void 0 ? query : toValue(defaultValue));
|
|
39
|
+
},
|
|
40
|
+
set(v) {
|
|
41
|
+
v = transformSet(v);
|
|
42
|
+
if (query === v) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
query = v === toValue(defaultValue) ? void 0 : v;
|
|
46
|
+
_queriesQueue.set(name, v === toValue(defaultValue) ? void 0 : v);
|
|
47
|
+
trigger();
|
|
48
|
+
nextTick(() => {
|
|
49
|
+
if (_queriesQueue.size === 0) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const newQueries = Object.fromEntries(_queriesQueue.entries());
|
|
53
|
+
_queriesQueue.clear();
|
|
54
|
+
const { params, query: query2, hash } = route;
|
|
55
|
+
router[toValue(mode)]({
|
|
56
|
+
params,
|
|
57
|
+
query: { ...query2, ...newQueries },
|
|
58
|
+
hash
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
watch(
|
|
65
|
+
() => route.query[name],
|
|
66
|
+
(v) => {
|
|
67
|
+
const newQueryValue = transformSet(transformGet(v));
|
|
68
|
+
if (query === newQueryValue) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (JSON.stringify(query) === JSON.stringify(newQueryValue)) {
|
|
72
|
+
query = v;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
query = v;
|
|
76
|
+
_trigger();
|
|
77
|
+
},
|
|
78
|
+
{ flush: "sync" }
|
|
79
|
+
);
|
|
80
|
+
return proxy;
|
|
81
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComputedRef, MaybeRefOrGetter } from 'vue';
|
|
2
|
+
import type { SEO } from '../types';
|
|
3
|
+
interface SEOStats {
|
|
4
|
+
progress: number;
|
|
5
|
+
color: 'error' | 'warning' | 'success';
|
|
6
|
+
}
|
|
7
|
+
interface UseSeoStatsReturn {
|
|
8
|
+
title: ComputedRef<SEOStats>;
|
|
9
|
+
description: ComputedRef<SEOStats>;
|
|
10
|
+
}
|
|
11
|
+
export declare function useSeoStats(options: MaybeRefOrGetter<SEO>): UseSeoStatsReturn;
|
|
12
|
+
export {};
|