@abraca/nuxt 2.9.0 → 2.11.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/dist/module.d.mts +14 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -0
- package/dist/runtime/assets/editor.css +1 -1
- package/dist/runtime/components/AConnectionBadge.d.vue.ts +29 -0
- package/dist/runtime/components/AConnectionBadge.vue +79 -0
- package/dist/runtime/components/AConnectionBadge.vue.d.ts +29 -0
- package/dist/runtime/components/AEditor.d.vue.ts +2 -2
- package/dist/runtime/components/AEditor.vue +11 -1
- package/dist/runtime/components/AEditor.vue.d.ts +2 -2
- package/dist/runtime/components/AEncryptionModePicker.d.vue.ts +33 -0
- package/dist/runtime/components/AEncryptionModePicker.vue +211 -0
- package/dist/runtime/components/AEncryptionModePicker.vue.d.ts +33 -0
- package/dist/runtime/components/AModalShell.d.vue.ts +48 -0
- package/dist/runtime/components/AModalShell.vue +105 -0
- package/dist/runtime/components/AModalShell.vue.d.ts +48 -0
- package/dist/runtime/components/ANodePanel.d.vue.ts +8 -6
- package/dist/runtime/components/ANodePanel.vue +25 -0
- package/dist/runtime/components/ANodePanel.vue.d.ts +8 -6
- package/dist/runtime/components/ANodePanelHeader.d.vue.ts +20 -10
- package/dist/runtime/components/ANodePanelHeader.vue +17 -3
- package/dist/runtime/components/ANodePanelHeader.vue.d.ts +20 -10
- package/dist/runtime/components/ANodeSettingsPanel.d.vue.ts +2 -0
- package/dist/runtime/components/ANodeSettingsPanel.vue +21 -1
- package/dist/runtime/components/ANodeSettingsPanel.vue.d.ts +2 -0
- package/dist/runtime/components/ASnapshotPreviewModal.d.vue.ts +33 -0
- package/dist/runtime/components/ASnapshotPreviewModal.vue +430 -0
- package/dist/runtime/components/ASnapshotPreviewModal.vue.d.ts +33 -0
- package/dist/runtime/components/docs/ADocsSearch.d.vue.ts +2 -2
- package/dist/runtime/components/docs/ADocsSearch.vue.d.ts +2 -2
- package/dist/runtime/components/editor/ALocationPickerPopover.vue +28 -7
- package/dist/runtime/components/registry/APluginDetail.d.vue.ts +2 -2
- package/dist/runtime/components/registry/APluginDetail.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/AProseRenderer.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/AProseRenderer.vue.d.ts +2 -2
- package/dist/runtime/components/shell/ABreadcrumbForDoc.d.vue.ts +6 -0
- package/dist/runtime/components/shell/ABreadcrumbForDoc.vue +75 -3
- package/dist/runtime/components/shell/ABreadcrumbForDoc.vue.d.ts +6 -0
- package/dist/runtime/components/shell/ADocPanelServerSettings.d.vue.ts +17 -0
- package/dist/runtime/components/shell/ADocPanelServerSettings.vue +253 -0
- package/dist/runtime/components/shell/ADocPanelServerSettings.vue.d.ts +17 -0
- package/dist/runtime/components/shell/ADocPanelSettings.d.vue.ts +2 -0
- package/dist/runtime/components/shell/ADocPanelSettings.vue +15 -4
- package/dist/runtime/components/shell/ADocPanelSettings.vue.d.ts +2 -0
- package/dist/runtime/components/shell/AUserMenu.d.vue.ts +2 -2
- package/dist/runtime/components/shell/AUserMenu.vue.d.ts +2 -2
- package/dist/runtime/composables/useDocBreadcrumb.d.ts +17 -2
- package/dist/runtime/composables/useDocBreadcrumb.js +17 -3
- package/dist/runtime/composables/useDocSnapshots.d.ts +2 -1
- package/dist/runtime/composables/useDocSnapshots.js +5 -0
- package/dist/runtime/composables/useEditor.d.ts +1 -1
- package/dist/runtime/composables/useEditor.js +120 -0
- package/dist/runtime/composables/useEditorToolbar.d.ts +12 -4
- package/dist/runtime/composables/useEditorToolbar.js +78 -56
- package/dist/runtime/composables/useNodeContextMenu.d.ts +10 -0
- package/dist/runtime/composables/useNodeContextMenu.js +41 -1
- package/dist/runtime/composables/useSwipeGesture.d.ts +48 -0
- package/dist/runtime/composables/useSwipeGesture.js +140 -0
- package/dist/runtime/extensions/document-header.js +16 -6
- package/dist/runtime/extensions/document-meta.js +344 -19
- package/dist/runtime/extensions/meta-field.js +42 -0
- package/dist/runtime/extensions/views/DocumentMetaView.vue +33 -7
- package/dist/runtime/extensions/views/FieldView.vue +51 -19
- package/dist/runtime/extensions/views/MetaFieldView.vue +30 -4
- package/dist/runtime/middleware/abracadabra-auth.d.ts +1 -1
- package/dist/runtime/plugin-abracadabra.client.d.ts +1 -1
- package/dist/runtime/plugin-abracadabra.client.js +12 -2
- package/dist/runtime/plugin-abracadabra.server.d.ts +1 -1
- package/dist/runtime/plugin-shared-globals.client.d.ts +1 -1
- package/package.json +1 -4
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref } from "vue";
|
|
3
|
+
import { useResizeObserver } from "@vueuse/core";
|
|
4
|
+
import { useSwipeGesture } from "../composables/useSwipeGesture";
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
open: { type: Boolean, required: true },
|
|
7
|
+
maxWidth: { type: String, required: false, default: "sm:max-w-xl" },
|
|
8
|
+
closeable: { type: Boolean, required: false, default: true },
|
|
9
|
+
title: { type: String, required: false },
|
|
10
|
+
subtitle: { type: String, required: false },
|
|
11
|
+
dismissible: { type: Boolean, required: false, default: true },
|
|
12
|
+
swipeable: { type: Boolean, required: false, default: false },
|
|
13
|
+
canSwipeForward: { type: Boolean, required: false, default: false },
|
|
14
|
+
canSwipeBack: { type: Boolean, required: false, default: false }
|
|
15
|
+
});
|
|
16
|
+
const emit = defineEmits(["update:open", "swipe-forward", "swipe-back"]);
|
|
17
|
+
const innerRef = ref();
|
|
18
|
+
const contentHeight = ref(void 0);
|
|
19
|
+
useResizeObserver(innerRef, (entries) => {
|
|
20
|
+
const entry = entries[0];
|
|
21
|
+
if (entry && entry.contentRect.height > 0) contentHeight.value = entry.contentRect.height;
|
|
22
|
+
});
|
|
23
|
+
const swipeRef = ref(null);
|
|
24
|
+
const swipeDirection = ref(null);
|
|
25
|
+
const { swipeOffset, isSwiping } = useSwipeGesture({
|
|
26
|
+
el: swipeRef,
|
|
27
|
+
axis: "x",
|
|
28
|
+
disabled: computed(() => !props.swipeable),
|
|
29
|
+
canSwipeLeft: computed(() => props.canSwipeForward),
|
|
30
|
+
canSwipeRight: computed(() => props.canSwipeBack),
|
|
31
|
+
onSwipeLeft() {
|
|
32
|
+
swipeDirection.value = "forward";
|
|
33
|
+
emit("swipe-forward");
|
|
34
|
+
},
|
|
35
|
+
onSwipeRight() {
|
|
36
|
+
swipeDirection.value = "back";
|
|
37
|
+
emit("swipe-back");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const transitionName = computed(
|
|
41
|
+
() => swipeDirection.value === "back" ? "ams-step-fade-reverse" : "ams-step-fade"
|
|
42
|
+
);
|
|
43
|
+
function onAfterLeave() {
|
|
44
|
+
swipeDirection.value = null;
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<UModal
|
|
50
|
+
:open="props.open"
|
|
51
|
+
:closeable="closeable"
|
|
52
|
+
:dismissible="dismissible"
|
|
53
|
+
:ui="{
|
|
54
|
+
content: `${maxWidth} divide-y-0`,
|
|
55
|
+
header: 'hidden'
|
|
56
|
+
}"
|
|
57
|
+
@update:open="emit('update:open', $event)"
|
|
58
|
+
>
|
|
59
|
+
<template #body>
|
|
60
|
+
<div class="flex flex-col gap-6 p-4 sm:p-6">
|
|
61
|
+
<div
|
|
62
|
+
v-if="title || subtitle"
|
|
63
|
+
class="flex flex-col gap-1"
|
|
64
|
+
>
|
|
65
|
+
<h2
|
|
66
|
+
v-if="title"
|
|
67
|
+
class="text-base font-semibold text-(--ui-text-highlighted)"
|
|
68
|
+
>
|
|
69
|
+
{{ title }}
|
|
70
|
+
</h2>
|
|
71
|
+
<p
|
|
72
|
+
v-if="subtitle"
|
|
73
|
+
class="text-sm text-(--ui-text-muted)"
|
|
74
|
+
>
|
|
75
|
+
{{ subtitle }}
|
|
76
|
+
</p>
|
|
77
|
+
</div>
|
|
78
|
+
<div
|
|
79
|
+
ref="swipeRef"
|
|
80
|
+
class="ams-height-wrap"
|
|
81
|
+
:style="{
|
|
82
|
+
...contentHeight !== void 0 ? { height: contentHeight + 'px' } : {},
|
|
83
|
+
...isSwiping ? { transform: `translateX(${swipeOffset.x}px)`, transition: 'none' } : {}
|
|
84
|
+
}"
|
|
85
|
+
>
|
|
86
|
+
<div ref="innerRef">
|
|
87
|
+
<Transition
|
|
88
|
+
:name="transitionName"
|
|
89
|
+
mode="out-in"
|
|
90
|
+
@after-leave="onAfterLeave"
|
|
91
|
+
>
|
|
92
|
+
<slot />
|
|
93
|
+
</Transition>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<slot name="footer" />
|
|
98
|
+
</div>
|
|
99
|
+
</template>
|
|
100
|
+
</UModal>
|
|
101
|
+
</template>
|
|
102
|
+
|
|
103
|
+
<style scoped>
|
|
104
|
+
.ams-height-wrap{overflow:hidden;transition:height .35s cubic-bezier(.4,0,.2,1),transform .3s ease}.ams-step-fade-enter-active{transition:opacity .3s ease,transform .35s cubic-bezier(.4,0,.2,1)}.ams-step-fade-leave-active{transition:opacity .2s ease,transform .2s cubic-bezier(.4,0,.2,1)}.ams-step-fade-enter-from{opacity:0;transform:translateX(16px) scale(.97)}.ams-step-fade-leave-to{opacity:0;transform:translateX(-12px) scale(.98)}.ams-step-fade-reverse-enter-active{transition:opacity .3s ease,transform .35s cubic-bezier(.4,0,.2,1)}.ams-step-fade-reverse-leave-active{transition:opacity .2s ease,transform .2s cubic-bezier(.4,0,.2,1)}.ams-step-fade-reverse-enter-from{opacity:0;transform:translateX(-16px) scale(.97)}.ams-step-fade-reverse-leave-to{opacity:0;transform:translateX(12px) scale(.98)}
|
|
105
|
+
</style>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
/** Tailwind max-width class for the modal content (e.g. `sm:max-w-3xl`). */
|
|
4
|
+
maxWidth?: string;
|
|
5
|
+
closeable?: boolean;
|
|
6
|
+
/** Standard modal heading — guarantees the canonical look every modal shares. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** Optional muted line under the title (e.g. a short description). */
|
|
9
|
+
subtitle?: string;
|
|
10
|
+
/** When false, Esc / overlay-click cannot dismiss the modal (forced choice). */
|
|
11
|
+
dismissible?: boolean;
|
|
12
|
+
/** Enable horizontal swipe gestures for multi-step navigation. */
|
|
13
|
+
swipeable?: boolean;
|
|
14
|
+
/** Whether forward (swipe left) navigation is available. */
|
|
15
|
+
canSwipeForward?: boolean;
|
|
16
|
+
/** Whether backward (swipe right) navigation is available. */
|
|
17
|
+
canSwipeBack?: boolean;
|
|
18
|
+
};
|
|
19
|
+
declare var __VLS_19: {}, __VLS_21: {};
|
|
20
|
+
type __VLS_Slots = {} & {
|
|
21
|
+
default?: (props: typeof __VLS_19) => any;
|
|
22
|
+
} & {
|
|
23
|
+
footer?: (props: typeof __VLS_21) => any;
|
|
24
|
+
};
|
|
25
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
26
|
+
"update:open": (v: boolean) => any;
|
|
27
|
+
"swipe-forward": () => any;
|
|
28
|
+
"swipe-back": () => any;
|
|
29
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
30
|
+
"onUpdate:open"?: ((v: boolean) => any) | undefined;
|
|
31
|
+
"onSwipe-forward"?: (() => any) | undefined;
|
|
32
|
+
"onSwipe-back"?: (() => any) | undefined;
|
|
33
|
+
}>, {
|
|
34
|
+
maxWidth: string;
|
|
35
|
+
closeable: boolean;
|
|
36
|
+
dismissible: boolean;
|
|
37
|
+
swipeable: boolean;
|
|
38
|
+
canSwipeForward: boolean;
|
|
39
|
+
canSwipeBack: boolean;
|
|
40
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
41
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
42
|
+
declare const _default: typeof __VLS_export;
|
|
43
|
+
export default _default;
|
|
44
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
45
|
+
new (): {
|
|
46
|
+
$slots: S;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -7,13 +7,15 @@ type __VLS_Props = {
|
|
|
7
7
|
docType?: string;
|
|
8
8
|
labels?: Partial<AbracadabraLocale['nodePanel']>;
|
|
9
9
|
/** Tab to open initially. Defaults to 'editor'. */
|
|
10
|
-
initialTab?: 'editor' | 'properties' | 'chat' | 'settings' | string;
|
|
10
|
+
initialTab?: 'editor' | 'properties' | 'chat' | 'settings' | 'serverSettings' | string;
|
|
11
11
|
/**
|
|
12
|
-
* Built-in tabs to render. Defaults to
|
|
13
|
-
* tabs appear (useful when a developer wants
|
|
14
|
-
*
|
|
12
|
+
* Built-in tabs to render. Defaults to editor/properties/chat/settings on;
|
|
13
|
+
* pass an array to limit which tabs appear (useful when a developer wants
|
|
14
|
+
* only properties + chat). `serverSettings` is OPT-IN — only rendered when
|
|
15
|
+
* explicitly included (it targets a server hub doc). Plugin-registered tab
|
|
16
|
+
* slots are unaffected.
|
|
15
17
|
*/
|
|
16
|
-
tabs?: Array<'editor' | 'properties' | 'chat' | 'settings'>;
|
|
18
|
+
tabs?: Array<'editor' | 'properties' | 'chat' | 'settings' | 'serverSettings'>;
|
|
17
19
|
};
|
|
18
20
|
declare var __VLS_11: {
|
|
19
21
|
nodeId: string | null;
|
|
@@ -30,7 +32,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
30
32
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
31
33
|
onClose?: (() => any) | undefined;
|
|
32
34
|
}>, {
|
|
33
|
-
initialTab: "editor" | "properties" | "chat" | "settings" | string;
|
|
35
|
+
initialTab: "editor" | "properties" | "chat" | "settings" | "serverSettings" | string;
|
|
34
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
37
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
36
38
|
declare const _default: typeof __VLS_export;
|
|
@@ -12,6 +12,7 @@ import { useRuntimeConfig } from "#imports";
|
|
|
12
12
|
import { useChat } from "../composables/useChat";
|
|
13
13
|
const ANodeChatPanel = defineAsyncComponent(() => import("./chat/ANodeChatPanel.vue"));
|
|
14
14
|
const ANodeSettingsPanel = defineAsyncComponent(() => import("./ANodeSettingsPanel.vue"));
|
|
15
|
+
const ADocPanelServerSettings = defineAsyncComponent(() => import("./shell/ADocPanelServerSettings.vue"));
|
|
15
16
|
import { META_FIELD_DEFINITIONS } from "../utils/metaFieldDefinitions";
|
|
16
17
|
import { resolveDocType } from "../utils/docTypes";
|
|
17
18
|
const props = defineProps({
|
|
@@ -89,6 +90,7 @@ const showChatTab = computed(() => {
|
|
|
89
90
|
const showEditorTab = computed(() => !props.tabs || props.tabs.includes("editor"));
|
|
90
91
|
const showPropertiesTab = computed(() => !props.tabs || props.tabs.includes("properties"));
|
|
91
92
|
const showSettingsTab = computed(() => !props.tabs || props.tabs.includes("settings"));
|
|
93
|
+
const showServerSettingsTab = computed(() => !!props.tabs && props.tabs.includes("serverSettings"));
|
|
92
94
|
const _chat = useChat();
|
|
93
95
|
const chatUnread = computed(() => {
|
|
94
96
|
if (!props.nodeId) return 0;
|
|
@@ -204,6 +206,7 @@ const addFieldMenuItems = computed(
|
|
|
204
206
|
:node-label="nodeLabel"
|
|
205
207
|
:icon="meta.icon ?? docTypeDef.icon"
|
|
206
208
|
:icon-color="meta.color"
|
|
209
|
+
:provider="childProvider"
|
|
207
210
|
:editor="activeTab === 'editor' && !usesPageRenderer ? tiptapEditor : null"
|
|
208
211
|
@expand="navigateTo(`/app/${nodeId}`)"
|
|
209
212
|
>
|
|
@@ -256,6 +259,15 @@ const addFieldMenuItems = computed(
|
|
|
256
259
|
:variant="activeTab === 'settings' ? 'soft' : 'ghost'"
|
|
257
260
|
@click="activeTab = 'settings'"
|
|
258
261
|
/>
|
|
262
|
+
<UButton
|
|
263
|
+
v-if="showServerSettingsTab"
|
|
264
|
+
icon="i-lucide-server-cog"
|
|
265
|
+
label="Server"
|
|
266
|
+
size="xs"
|
|
267
|
+
:color="activeTab === 'serverSettings' ? 'primary' : 'neutral'"
|
|
268
|
+
:variant="activeTab === 'serverSettings' ? 'soft' : 'ghost'"
|
|
269
|
+
@click="activeTab = 'serverSettings'"
|
|
270
|
+
/>
|
|
259
271
|
<UButton
|
|
260
272
|
v-for="slot in pluginSlots"
|
|
261
273
|
:key="slot.id"
|
|
@@ -332,11 +344,24 @@ const addFieldMenuItems = computed(
|
|
|
332
344
|
v-if="nodeId"
|
|
333
345
|
:doc-id="nodeId"
|
|
334
346
|
:doc-type-key="currentType"
|
|
347
|
+
:doc-label="nodeLabel"
|
|
335
348
|
:doc-meta="meta"
|
|
336
349
|
@update-meta="patchMeta"
|
|
337
350
|
/>
|
|
338
351
|
</div>
|
|
339
352
|
|
|
353
|
+
<!-- Server-settings tab (opt-in via `tabs`) — hub-doc server status. -->
|
|
354
|
+
<div
|
|
355
|
+
v-if="showServerSettingsTab"
|
|
356
|
+
v-show="activeTab === 'serverSettings'"
|
|
357
|
+
class="min-h-[60vh] -mx-4 -mb-4 sm:-mx-6"
|
|
358
|
+
>
|
|
359
|
+
<ADocPanelServerSettings
|
|
360
|
+
v-if="nodeId"
|
|
361
|
+
:doc-id="nodeId"
|
|
362
|
+
/>
|
|
363
|
+
</div>
|
|
364
|
+
|
|
340
365
|
<!-- Properties tab -->
|
|
341
366
|
<div
|
|
342
367
|
v-show="activeTab === 'properties'"
|
|
@@ -7,13 +7,15 @@ type __VLS_Props = {
|
|
|
7
7
|
docType?: string;
|
|
8
8
|
labels?: Partial<AbracadabraLocale['nodePanel']>;
|
|
9
9
|
/** Tab to open initially. Defaults to 'editor'. */
|
|
10
|
-
initialTab?: 'editor' | 'properties' | 'chat' | 'settings' | string;
|
|
10
|
+
initialTab?: 'editor' | 'properties' | 'chat' | 'settings' | 'serverSettings' | string;
|
|
11
11
|
/**
|
|
12
|
-
* Built-in tabs to render. Defaults to
|
|
13
|
-
* tabs appear (useful when a developer wants
|
|
14
|
-
*
|
|
12
|
+
* Built-in tabs to render. Defaults to editor/properties/chat/settings on;
|
|
13
|
+
* pass an array to limit which tabs appear (useful when a developer wants
|
|
14
|
+
* only properties + chat). `serverSettings` is OPT-IN — only rendered when
|
|
15
|
+
* explicitly included (it targets a server hub doc). Plugin-registered tab
|
|
16
|
+
* slots are unaffected.
|
|
15
17
|
*/
|
|
16
|
-
tabs?: Array<'editor' | 'properties' | 'chat' | 'settings'>;
|
|
18
|
+
tabs?: Array<'editor' | 'properties' | 'chat' | 'settings' | 'serverSettings'>;
|
|
17
19
|
};
|
|
18
20
|
declare var __VLS_11: {
|
|
19
21
|
nodeId: string | null;
|
|
@@ -30,7 +32,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
30
32
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
31
33
|
onClose?: (() => any) | undefined;
|
|
32
34
|
}>, {
|
|
33
|
-
initialTab: "editor" | "properties" | "chat" | "settings" | string;
|
|
35
|
+
initialTab: "editor" | "properties" | "chat" | "settings" | "serverSettings" | string;
|
|
34
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
37
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
36
38
|
declare const _default: typeof __VLS_export;
|
|
@@ -10,12 +10,19 @@ type __VLS_Props = {
|
|
|
10
10
|
iconColor?: string;
|
|
11
11
|
/** TipTap editor — when passed, default undo/redo buttons render */
|
|
12
12
|
editor?: Editor | null;
|
|
13
|
+
/**
|
|
14
|
+
* The doc's child provider. When passed, the default `#status` slot renders
|
|
15
|
+
* an <AConnectionBadge> so an offline / auth-rejected doc shows a status dot.
|
|
16
|
+
*/
|
|
17
|
+
provider?: any;
|
|
13
18
|
/** Show undo/redo buttons in default slot. Default: true when editor passed */
|
|
14
19
|
showUndoRedo?: boolean;
|
|
15
20
|
/** Show expand-to-full-page button. Default: true when nodeId passed */
|
|
16
21
|
showExpand?: boolean;
|
|
17
22
|
/** Show presence facepile in default presence slot. Default: true when nodeId passed */
|
|
18
23
|
showPresence?: boolean;
|
|
24
|
+
/** Show the connection badge in default `#status` slot. Default: true when provider passed */
|
|
25
|
+
showConnectionBadge?: boolean;
|
|
19
26
|
/** Tooltip text for the expand button */
|
|
20
27
|
expandTooltip?: string;
|
|
21
28
|
};
|
|
@@ -24,34 +31,37 @@ declare var __VLS_1: {
|
|
|
24
31
|
color: string | undefined;
|
|
25
32
|
}, __VLS_8: {
|
|
26
33
|
label: string | undefined;
|
|
27
|
-
}, __VLS_10: {},
|
|
34
|
+
}, __VLS_10: {}, __VLS_17: {}, __VLS_19: {}, __VLS_26: {
|
|
28
35
|
editor: Editor | null | undefined;
|
|
29
|
-
},
|
|
30
|
-
expand: () => void;
|
|
36
|
+
}, __VLS_38: {}, __VLS_40: {
|
|
37
|
+
expand: (e?: MouseEvent) => void;
|
|
31
38
|
};
|
|
32
39
|
type __VLS_Slots = {} & {
|
|
33
40
|
icon?: (props: typeof __VLS_1) => any;
|
|
34
41
|
} & {
|
|
35
42
|
title?: (props: typeof __VLS_8) => any;
|
|
36
43
|
} & {
|
|
37
|
-
|
|
44
|
+
status?: (props: typeof __VLS_10) => any;
|
|
38
45
|
} & {
|
|
39
|
-
|
|
46
|
+
'actions-left'?: (props: typeof __VLS_17) => any;
|
|
40
47
|
} & {
|
|
41
|
-
|
|
48
|
+
presence?: (props: typeof __VLS_19) => any;
|
|
42
49
|
} & {
|
|
43
|
-
'
|
|
50
|
+
'undo-redo'?: (props: typeof __VLS_26) => any;
|
|
44
51
|
} & {
|
|
45
|
-
|
|
52
|
+
'actions-right'?: (props: typeof __VLS_38) => any;
|
|
53
|
+
} & {
|
|
54
|
+
expand?: (props: typeof __VLS_40) => any;
|
|
46
55
|
};
|
|
47
56
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
48
|
-
expand: () => any;
|
|
57
|
+
expand: (event?: MouseEvent | undefined) => any;
|
|
49
58
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
50
|
-
onExpand?: (() => any) | undefined;
|
|
59
|
+
onExpand?: ((event?: MouseEvent | undefined) => any) | undefined;
|
|
51
60
|
}>, {
|
|
52
61
|
showUndoRedo: boolean;
|
|
53
62
|
showExpand: boolean;
|
|
54
63
|
showPresence: boolean;
|
|
64
|
+
showConnectionBadge: boolean;
|
|
55
65
|
expandTooltip: string;
|
|
56
66
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
57
67
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import AFacepile from "./aware/AFacepile.vue";
|
|
4
|
+
import AConnectionBadge from "./AConnectionBadge.vue";
|
|
4
5
|
import AEditorUndoButton from "./editor/AEditorUndoButton.vue";
|
|
5
6
|
import AEditorRedoButton from "./editor/AEditorRedoButton.vue";
|
|
6
7
|
const props = defineProps({
|
|
@@ -9,9 +10,11 @@ const props = defineProps({
|
|
|
9
10
|
icon: { type: String, required: false },
|
|
10
11
|
iconColor: { type: String, required: false },
|
|
11
12
|
editor: { type: [Object, null], required: false },
|
|
13
|
+
provider: { type: null, required: false },
|
|
12
14
|
showUndoRedo: { type: Boolean, required: false, default: void 0 },
|
|
13
15
|
showExpand: { type: Boolean, required: false, default: void 0 },
|
|
14
16
|
showPresence: { type: Boolean, required: false, default: void 0 },
|
|
17
|
+
showConnectionBadge: { type: Boolean, required: false, default: void 0 },
|
|
15
18
|
expandTooltip: { type: String, required: false, default: "Open as full page" }
|
|
16
19
|
});
|
|
17
20
|
const emit = defineEmits(["expand"]);
|
|
@@ -29,6 +32,9 @@ const expandEnabled = computed(
|
|
|
29
32
|
const presenceEnabled = computed(
|
|
30
33
|
() => props.showPresence === void 0 ? !!props.nodeId : props.showPresence
|
|
31
34
|
);
|
|
35
|
+
const connectionBadgeEnabled = computed(
|
|
36
|
+
() => props.showConnectionBadge === void 0 ? !!props.provider : props.showConnectionBadge
|
|
37
|
+
);
|
|
32
38
|
</script>
|
|
33
39
|
|
|
34
40
|
<template>
|
|
@@ -55,6 +61,14 @@ const presenceEnabled = computed(
|
|
|
55
61
|
<span class="font-medium truncate flex-1">{{ nodeLabel || "Document" }}</span>
|
|
56
62
|
</slot>
|
|
57
63
|
|
|
64
|
+
<!-- connection status dot (offline / auth-rejected) for this doc's provider -->
|
|
65
|
+
<slot name="status">
|
|
66
|
+
<AConnectionBadge
|
|
67
|
+
v-if="connectionBadgeEnabled"
|
|
68
|
+
:provider="provider"
|
|
69
|
+
/>
|
|
70
|
+
</slot>
|
|
71
|
+
|
|
58
72
|
<!-- left-of-presence actions (badges, status indicators, etc.) -->
|
|
59
73
|
<slot name="actions-left" />
|
|
60
74
|
|
|
@@ -82,10 +96,10 @@ const presenceEnabled = computed(
|
|
|
82
96
|
<!-- right-of-undo extension actions -->
|
|
83
97
|
<slot name="actions-right" />
|
|
84
98
|
|
|
85
|
-
<!-- expand to full page -->
|
|
99
|
+
<!-- expand to full page (modifier-aware: see the `expand` emit docs) -->
|
|
86
100
|
<slot
|
|
87
101
|
name="expand"
|
|
88
|
-
:expand="() => emit('expand')"
|
|
102
|
+
:expand="(e) => emit('expand', e)"
|
|
89
103
|
>
|
|
90
104
|
<UTooltip
|
|
91
105
|
v-if="expandEnabled"
|
|
@@ -97,7 +111,7 @@ const presenceEnabled = computed(
|
|
|
97
111
|
size="xs"
|
|
98
112
|
variant="ghost"
|
|
99
113
|
color="neutral"
|
|
100
|
-
@click="emit('expand')"
|
|
114
|
+
@click="(e) => emit('expand', e)"
|
|
101
115
|
/>
|
|
102
116
|
</UTooltip>
|
|
103
117
|
</slot>
|
|
@@ -10,12 +10,19 @@ type __VLS_Props = {
|
|
|
10
10
|
iconColor?: string;
|
|
11
11
|
/** TipTap editor — when passed, default undo/redo buttons render */
|
|
12
12
|
editor?: Editor | null;
|
|
13
|
+
/**
|
|
14
|
+
* The doc's child provider. When passed, the default `#status` slot renders
|
|
15
|
+
* an <AConnectionBadge> so an offline / auth-rejected doc shows a status dot.
|
|
16
|
+
*/
|
|
17
|
+
provider?: any;
|
|
13
18
|
/** Show undo/redo buttons in default slot. Default: true when editor passed */
|
|
14
19
|
showUndoRedo?: boolean;
|
|
15
20
|
/** Show expand-to-full-page button. Default: true when nodeId passed */
|
|
16
21
|
showExpand?: boolean;
|
|
17
22
|
/** Show presence facepile in default presence slot. Default: true when nodeId passed */
|
|
18
23
|
showPresence?: boolean;
|
|
24
|
+
/** Show the connection badge in default `#status` slot. Default: true when provider passed */
|
|
25
|
+
showConnectionBadge?: boolean;
|
|
19
26
|
/** Tooltip text for the expand button */
|
|
20
27
|
expandTooltip?: string;
|
|
21
28
|
};
|
|
@@ -24,34 +31,37 @@ declare var __VLS_1: {
|
|
|
24
31
|
color: string | undefined;
|
|
25
32
|
}, __VLS_8: {
|
|
26
33
|
label: string | undefined;
|
|
27
|
-
}, __VLS_10: {},
|
|
34
|
+
}, __VLS_10: {}, __VLS_17: {}, __VLS_19: {}, __VLS_26: {
|
|
28
35
|
editor: Editor | null | undefined;
|
|
29
|
-
},
|
|
30
|
-
expand: () => void;
|
|
36
|
+
}, __VLS_38: {}, __VLS_40: {
|
|
37
|
+
expand: (e?: MouseEvent) => void;
|
|
31
38
|
};
|
|
32
39
|
type __VLS_Slots = {} & {
|
|
33
40
|
icon?: (props: typeof __VLS_1) => any;
|
|
34
41
|
} & {
|
|
35
42
|
title?: (props: typeof __VLS_8) => any;
|
|
36
43
|
} & {
|
|
37
|
-
|
|
44
|
+
status?: (props: typeof __VLS_10) => any;
|
|
38
45
|
} & {
|
|
39
|
-
|
|
46
|
+
'actions-left'?: (props: typeof __VLS_17) => any;
|
|
40
47
|
} & {
|
|
41
|
-
|
|
48
|
+
presence?: (props: typeof __VLS_19) => any;
|
|
42
49
|
} & {
|
|
43
|
-
'
|
|
50
|
+
'undo-redo'?: (props: typeof __VLS_26) => any;
|
|
44
51
|
} & {
|
|
45
|
-
|
|
52
|
+
'actions-right'?: (props: typeof __VLS_38) => any;
|
|
53
|
+
} & {
|
|
54
|
+
expand?: (props: typeof __VLS_40) => any;
|
|
46
55
|
};
|
|
47
56
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
48
|
-
expand: () => any;
|
|
57
|
+
expand: (event?: MouseEvent | undefined) => any;
|
|
49
58
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
50
|
-
onExpand?: (() => any) | undefined;
|
|
59
|
+
onExpand?: ((event?: MouseEvent | undefined) => any) | undefined;
|
|
51
60
|
}>, {
|
|
52
61
|
showUndoRedo: boolean;
|
|
53
62
|
showExpand: boolean;
|
|
54
63
|
showPresence: boolean;
|
|
64
|
+
showConnectionBadge: boolean;
|
|
55
65
|
expandTooltip: string;
|
|
56
66
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
57
67
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -4,6 +4,8 @@ type __VLS_Props = {
|
|
|
4
4
|
docId: string;
|
|
5
5
|
/** Document type key (drives metaSchema form). */
|
|
6
6
|
docTypeKey?: string;
|
|
7
|
+
/** Document label — used as the title when serializing a snapshot preview. */
|
|
8
|
+
docLabel?: string;
|
|
7
9
|
/** Document meta to read/write. */
|
|
8
10
|
docMeta?: DocPageMeta | null;
|
|
9
11
|
/** Permission entries — left to the consumer (varies per backend). */
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, toRef } from "vue";
|
|
2
|
+
import { computed, ref, toRef, watch } from "vue";
|
|
3
3
|
import { useDocSnapshots } from "../composables/useDocSnapshots";
|
|
4
4
|
import { useAbracadabra } from "../composables/useAbracadabra";
|
|
5
5
|
import ADocPanelSettings from "./shell/ADocPanelSettings.vue";
|
|
6
|
+
import ASnapshotPreviewModal from "./ASnapshotPreviewModal.vue";
|
|
6
7
|
const props = defineProps({
|
|
7
8
|
docId: { type: String, required: true },
|
|
8
9
|
docTypeKey: { type: String, required: false },
|
|
10
|
+
docLabel: { type: String, required: false },
|
|
9
11
|
docMeta: { type: [Object, null], required: false },
|
|
10
12
|
permissions: { type: Array, required: false, default: () => [] },
|
|
11
13
|
loadingPermissions: { type: Boolean, required: false, default: false },
|
|
@@ -16,6 +18,10 @@ const emit = defineEmits(["grant-permission", "change-role", "revoke-permission"
|
|
|
16
18
|
const abra = useAbracadabra();
|
|
17
19
|
const docIdRef = toRef(props, "docId");
|
|
18
20
|
const snaps = useDocSnapshots(docIdRef);
|
|
21
|
+
watch(docIdRef, (id) => {
|
|
22
|
+
if (id) snaps.fetchList();
|
|
23
|
+
}, { immediate: true });
|
|
24
|
+
const previewVersion = ref(null);
|
|
19
25
|
const effectiveRole = computed(() => abra.provider.value?.effectiveRole ?? null);
|
|
20
26
|
const userName = computed(() => abra.userName?.value ?? "");
|
|
21
27
|
const syncStatusIcon = computed(() => abra.provider.value ? "i-lucide-cloud" : "i-lucide-cloud-off");
|
|
@@ -54,6 +60,20 @@ const syncStatusLabel = computed(() => abra.provider.value ? "Connected" : "Disc
|
|
|
54
60
|
@delete-snapshot="(v) => snaps.remove(v)"
|
|
55
61
|
@restore-snapshot="(v) => snaps.restore(v)"
|
|
56
62
|
@fork-snapshot="(v) => snaps.fork(v)"
|
|
63
|
+
@preview-snapshot="(v) => previewVersion = v"
|
|
57
64
|
@load-more-snapshots="snaps.loadMore"
|
|
58
65
|
/>
|
|
66
|
+
|
|
67
|
+
<ASnapshotPreviewModal
|
|
68
|
+
v-model:version="previewVersion"
|
|
69
|
+
:snapshots="snaps.snapshots.value"
|
|
70
|
+
:get-snapshot="snaps.getSnapshot"
|
|
71
|
+
:doc-label="docLabel"
|
|
72
|
+
:doc-type="docTypeKey"
|
|
73
|
+
:doc-meta="docMeta"
|
|
74
|
+
:is-owner="isOwner"
|
|
75
|
+
@restore="(v) => snaps.restore(v)"
|
|
76
|
+
@fork="(v) => snaps.fork(v)"
|
|
77
|
+
@delete="(v) => snaps.remove(v)"
|
|
78
|
+
/>
|
|
59
79
|
</template>
|
|
@@ -4,6 +4,8 @@ type __VLS_Props = {
|
|
|
4
4
|
docId: string;
|
|
5
5
|
/** Document type key (drives metaSchema form). */
|
|
6
6
|
docTypeKey?: string;
|
|
7
|
+
/** Document label — used as the title when serializing a snapshot preview. */
|
|
8
|
+
docLabel?: string;
|
|
7
9
|
/** Document meta to read/write. */
|
|
8
10
|
docMeta?: DocPageMeta | null;
|
|
9
11
|
/** Permission entries — left to the consumer (varies per backend). */
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SnapshotData, SnapshotMeta } from '@abraca/dabra';
|
|
2
|
+
import type { DocPageMeta } from '../types.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
/** Selected version — null closes the modal. The parent owns this. */
|
|
5
|
+
version: number | null;
|
|
6
|
+
/** The loaded snapshot metadata list (compare-baseline candidates). */
|
|
7
|
+
snapshots?: SnapshotMeta[];
|
|
8
|
+
/** Fetch a single snapshot's data blob (e.g. `useDocSnapshots().getSnapshot`). */
|
|
9
|
+
getSnapshot: (version: number) => Promise<SnapshotData | null>;
|
|
10
|
+
/** Document label — used as the title when serializing. */
|
|
11
|
+
docLabel?: string;
|
|
12
|
+
/** Document page type — passed to the markdown serializer. */
|
|
13
|
+
docType?: string;
|
|
14
|
+
/** Document meta — passed to the markdown serializer. */
|
|
15
|
+
docMeta?: DocPageMeta | null;
|
|
16
|
+
/** Whether the current user may delete snapshots. */
|
|
17
|
+
isOwner?: boolean;
|
|
18
|
+
};
|
|
19
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
20
|
+
delete: (version: number) => any;
|
|
21
|
+
restore: (version: number) => any;
|
|
22
|
+
fork: (version: number) => any;
|
|
23
|
+
"update:version": (value: number | null) => any;
|
|
24
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
25
|
+
onDelete?: ((version: number) => any) | undefined;
|
|
26
|
+
onRestore?: ((version: number) => any) | undefined;
|
|
27
|
+
onFork?: ((version: number) => any) | undefined;
|
|
28
|
+
"onUpdate:version"?: ((value: number | null) => any) | undefined;
|
|
29
|
+
}>, {
|
|
30
|
+
snapshots: SnapshotMeta[];
|
|
31
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
|
+
declare const _default: typeof __VLS_export;
|
|
33
|
+
export default _default;
|