@cou.sh/nuxt 1.0.1
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/README.md +84 -0
- package/dist/module.d.mts +49 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +126 -0
- package/dist/runtime/components/ActivityTimeline.d.vue.ts +17 -0
- package/dist/runtime/components/ActivityTimeline.vue +108 -0
- package/dist/runtime/components/ActivityTimeline.vue.d.ts +17 -0
- package/dist/runtime/components/AuthForm.d.vue.ts +20 -0
- package/dist/runtime/components/AuthForm.vue +78 -0
- package/dist/runtime/components/AuthForm.vue.d.ts +20 -0
- package/dist/runtime/components/CommentThread.d.vue.ts +10 -0
- package/dist/runtime/components/CommentThread.vue +149 -0
- package/dist/runtime/components/CommentThread.vue.d.ts +10 -0
- package/dist/runtime/components/ConnectionStatus.d.vue.ts +13 -0
- package/dist/runtime/components/ConnectionStatus.vue +27 -0
- package/dist/runtime/components/ConnectionStatus.vue.d.ts +13 -0
- package/dist/runtime/components/DocumentBreadcrumb.d.vue.ts +13 -0
- package/dist/runtime/components/DocumentBreadcrumb.vue +38 -0
- package/dist/runtime/components/DocumentBreadcrumb.vue.d.ts +13 -0
- package/dist/runtime/components/DocumentCard.d.vue.ts +30 -0
- package/dist/runtime/components/DocumentCard.vue +88 -0
- package/dist/runtime/components/DocumentCard.vue.d.ts +30 -0
- package/dist/runtime/components/DocumentSearchPalette.d.vue.ts +22 -0
- package/dist/runtime/components/DocumentSearchPalette.vue +99 -0
- package/dist/runtime/components/DocumentSearchPalette.vue.d.ts +22 -0
- package/dist/runtime/components/DocumentTree.d.vue.ts +32 -0
- package/dist/runtime/components/DocumentTree.vue +497 -0
- package/dist/runtime/components/DocumentTree.vue.d.ts +32 -0
- package/dist/runtime/components/Editor.d.vue.ts +11 -0
- package/dist/runtime/components/Editor.vue +328 -0
- package/dist/runtime/components/Editor.vue.d.ts +11 -0
- package/dist/runtime/components/ExportMenu.d.vue.ts +9 -0
- package/dist/runtime/components/ExportMenu.vue +55 -0
- package/dist/runtime/components/ExportMenu.vue.d.ts +9 -0
- package/dist/runtime/components/FileUploader.d.vue.ts +22 -0
- package/dist/runtime/components/FileUploader.vue +148 -0
- package/dist/runtime/components/FileUploader.vue.d.ts +22 -0
- package/dist/runtime/components/MemberManager.d.vue.ts +9 -0
- package/dist/runtime/components/MemberManager.vue +153 -0
- package/dist/runtime/components/MemberManager.vue.d.ts +9 -0
- package/dist/runtime/components/OfflineIndicator.d.vue.ts +9 -0
- package/dist/runtime/components/OfflineIndicator.vue +44 -0
- package/dist/runtime/components/OfflineIndicator.vue.d.ts +9 -0
- package/dist/runtime/components/PermissionGuard.d.vue.ts +25 -0
- package/dist/runtime/components/PermissionGuard.vue +16 -0
- package/dist/runtime/components/PermissionGuard.vue.d.ts +25 -0
- package/dist/runtime/components/RoleBadge.d.vue.ts +11 -0
- package/dist/runtime/components/RoleBadge.vue +30 -0
- package/dist/runtime/components/RoleBadge.vue.d.ts +11 -0
- package/dist/runtime/components/ShareDialog.d.vue.ts +15 -0
- package/dist/runtime/components/ShareDialog.vue +119 -0
- package/dist/runtime/components/ShareDialog.vue.d.ts +15 -0
- package/dist/runtime/components/SnapshotTimeline.d.vue.ts +15 -0
- package/dist/runtime/components/SnapshotTimeline.vue +118 -0
- package/dist/runtime/components/SnapshotTimeline.vue.d.ts +15 -0
- package/dist/runtime/components/SpaceSettings.d.vue.ts +7 -0
- package/dist/runtime/components/SpaceSettings.vue +105 -0
- package/dist/runtime/components/SpaceSettings.vue.d.ts +7 -0
- package/dist/runtime/components/SpaceSwitcher.d.vue.ts +18 -0
- package/dist/runtime/components/SpaceSwitcher.vue +104 -0
- package/dist/runtime/components/SpaceSwitcher.vue.d.ts +18 -0
- package/dist/runtime/components/TrashBin.d.vue.ts +7 -0
- package/dist/runtime/components/TrashBin.vue +159 -0
- package/dist/runtime/components/TrashBin.vue.d.ts +7 -0
- package/dist/runtime/components/UserMenu.d.vue.ts +13 -0
- package/dist/runtime/components/UserMenu.vue +50 -0
- package/dist/runtime/components/UserMenu.vue.d.ts +13 -0
- package/dist/runtime/components/UserPresence.d.vue.ts +13 -0
- package/dist/runtime/components/UserPresence.vue +34 -0
- package/dist/runtime/components/UserPresence.vue.d.ts +13 -0
- package/dist/runtime/components/editor/CollaborationUsers.d.vue.ts +7 -0
- package/dist/runtime/components/editor/CollaborationUsers.vue +31 -0
- package/dist/runtime/components/editor/CollaborationUsers.vue.d.ts +7 -0
- package/dist/runtime/components/editor/CompletionExtension.d.ts +43 -0
- package/dist/runtime/components/editor/CompletionExtension.js +133 -0
- package/dist/runtime/components/editor/ImageUploadExtension.d.ts +10 -0
- package/dist/runtime/components/editor/ImageUploadExtension.js +31 -0
- package/dist/runtime/components/editor/ImageUploadNode.d.vue.ts +4 -0
- package/dist/runtime/components/editor/ImageUploadNode.vue +59 -0
- package/dist/runtime/components/editor/ImageUploadNode.vue.d.ts +4 -0
- package/dist/runtime/components/editor/LinkPopover.d.vue.ts +8 -0
- package/dist/runtime/components/editor/LinkPopover.vue +131 -0
- package/dist/runtime/components/editor/LinkPopover.vue.d.ts +8 -0
- package/dist/runtime/components/widgets/ButtonWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/ButtonWidget.vue +32 -0
- package/dist/runtime/components/widgets/ButtonWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/CalendarWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/CalendarWidget.vue +36 -0
- package/dist/runtime/components/widgets/CalendarWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/CheckboxWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/CheckboxWidget.vue +32 -0
- package/dist/runtime/components/widgets/CheckboxWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/ColorPickerWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/ColorPickerWidget.vue +30 -0
- package/dist/runtime/components/widgets/ColorPickerWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/IconWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/IconWidget.vue +102 -0
- package/dist/runtime/components/widgets/IconWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/InputDateWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/InputDateWidget.vue +38 -0
- package/dist/runtime/components/widgets/InputDateWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/ScrollAreaWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/ScrollAreaWidget.vue +41 -0
- package/dist/runtime/components/widgets/ScrollAreaWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/SliderWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/SliderWidget.vue +42 -0
- package/dist/runtime/components/widgets/SliderWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/SwitchWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/SwitchWidget.vue +35 -0
- package/dist/runtime/components/widgets/SwitchWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/TabPanelWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/TabPanelWidget.vue +22 -0
- package/dist/runtime/components/widgets/TabPanelWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/TabsWidget.d.vue.ts +4 -0
- package/dist/runtime/components/widgets/TabsWidget.vue +109 -0
- package/dist/runtime/components/widgets/TabsWidget.vue.d.ts +4 -0
- package/dist/runtime/components/widgets/index.d.ts +13 -0
- package/dist/runtime/components/widgets/index.js +278 -0
- package/dist/runtime/composables/index.d.ts +14 -0
- package/dist/runtime/composables/index.js +13 -0
- package/dist/runtime/composables/useCollabStatus.d.ts +10 -0
- package/dist/runtime/composables/useCollabStatus.js +23 -0
- package/dist/runtime/composables/useDocumentPermissions.d.ts +11 -0
- package/dist/runtime/composables/useDocumentPermissions.js +44 -0
- package/dist/runtime/composables/useEditorCollaboration.d.ts +25 -0
- package/dist/runtime/composables/useEditorCollaboration.js +141 -0
- package/dist/runtime/composables/useEditorCompletion.d.ts +60 -0
- package/dist/runtime/composables/useEditorCompletion.js +42 -0
- package/dist/runtime/composables/useEditorDragHandle.d.ts +10 -0
- package/dist/runtime/composables/useEditorDragHandle.js +130 -0
- package/dist/runtime/composables/useEditorEmojis.d.ts +4 -0
- package/dist/runtime/composables/useEditorEmojis.js +9 -0
- package/dist/runtime/composables/useEditorMentions.d.ts +4 -0
- package/dist/runtime/composables/useEditorMentions.js +27 -0
- package/dist/runtime/composables/useEditorSuggestions.d.ts +149 -0
- package/dist/runtime/composables/useEditorSuggestions.js +114 -0
- package/dist/runtime/composables/useEditorToolbar.d.ts +12 -0
- package/dist/runtime/composables/useEditorToolbar.js +194 -0
- package/dist/runtime/composables/useLucideIcons.d.ts +4 -0
- package/dist/runtime/composables/useLucideIcons.js +16 -0
- package/dist/runtime/composables/useOnlineStatus.d.ts +6 -0
- package/dist/runtime/composables/useOnlineStatus.js +44 -0
- package/dist/runtime/composables/useSpaces.d.ts +36 -0
- package/dist/runtime/composables/useSpaces.js +29 -0
- package/dist/runtime/middleware/collab-auth.d.ts +2 -0
- package/dist/runtime/middleware/collab-auth.js +18 -0
- package/dist/runtime/plugin.d.ts +7 -0
- package/dist/runtime/plugin.js +39 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/types.d.mts +3 -0
- package/package.json +66 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
spaceId: { type: String, required: true }
|
|
4
|
+
});
|
|
5
|
+
const client = useCollabClient();
|
|
6
|
+
const toast = useToast();
|
|
7
|
+
const space = ref(null);
|
|
8
|
+
const loading = ref(true);
|
|
9
|
+
const activeTab = ref("general");
|
|
10
|
+
const saving = ref(false);
|
|
11
|
+
const editName = ref("");
|
|
12
|
+
const tabs = [
|
|
13
|
+
{ label: "General", value: "general", icon: "i-lucide-settings" },
|
|
14
|
+
{ label: "Members", value: "members", icon: "i-lucide-users" },
|
|
15
|
+
{ label: "Danger Zone", value: "danger", icon: "i-lucide-alert-triangle" }
|
|
16
|
+
];
|
|
17
|
+
async function loadSpace() {
|
|
18
|
+
loading.value = true;
|
|
19
|
+
try {
|
|
20
|
+
space.value = await client.spaces.get(props.spaceId);
|
|
21
|
+
editName.value = space.value.name;
|
|
22
|
+
} finally {
|
|
23
|
+
loading.value = false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function saveName() {
|
|
27
|
+
if (!editName.value.trim() || editName.value === space.value?.name) return;
|
|
28
|
+
saving.value = true;
|
|
29
|
+
try {
|
|
30
|
+
await client.spaces.create({ name: editName.value.trim(), slug: space.value?.slug });
|
|
31
|
+
toast.add({ title: "Space updated", color: "success" });
|
|
32
|
+
await loadSpace();
|
|
33
|
+
} catch {
|
|
34
|
+
toast.add({ title: "Failed to update space", color: "error" });
|
|
35
|
+
} finally {
|
|
36
|
+
saving.value = false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
watch(() => props.spaceId, loadSpace, { immediate: true });
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<USkeleton v-if="loading" class="h-64" />
|
|
44
|
+
|
|
45
|
+
<div v-else-if="space" class="space-y-6">
|
|
46
|
+
<div>
|
|
47
|
+
<h2 class="text-lg font-semibold">{{ space.name }}</h2>
|
|
48
|
+
<p class="text-sm text-(--ui-text-muted)">
|
|
49
|
+
{{ space.memberCount ?? 0 }} members · {{ space.documentCount ?? 0 }} documents
|
|
50
|
+
</p>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<UTabs :items="tabs" v-model="activeTab">
|
|
54
|
+
<template #content="{ item }">
|
|
55
|
+
<!-- General -->
|
|
56
|
+
<div v-if="item.value === 'general'" class="space-y-4 pt-4">
|
|
57
|
+
<UFormField label="Space name">
|
|
58
|
+
<div class="flex items-center gap-2">
|
|
59
|
+
<UInput v-model="editName" class="flex-1" />
|
|
60
|
+
<UButton
|
|
61
|
+
label="Save"
|
|
62
|
+
:loading="saving"
|
|
63
|
+
:disabled="!editName.trim() || editName === space.name"
|
|
64
|
+
@click="saveName"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
</UFormField>
|
|
68
|
+
|
|
69
|
+
<UFormField label="Slug">
|
|
70
|
+
<UInput :model-value="space.slug" disabled />
|
|
71
|
+
</UFormField>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<!-- Members -->
|
|
75
|
+
<div v-else-if="item.value === 'members'" class="pt-4">
|
|
76
|
+
<CollabMemberManager
|
|
77
|
+
:space-id="spaceId"
|
|
78
|
+
:current-user-role="space.role"
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<!-- Danger Zone -->
|
|
83
|
+
<div v-else-if="item.value === 'danger'" class="pt-4">
|
|
84
|
+
<UCard color="error" variant="subtle">
|
|
85
|
+
<div class="space-y-3">
|
|
86
|
+
<div>
|
|
87
|
+
<div class="text-sm font-medium">Delete space</div>
|
|
88
|
+
<div class="text-xs text-(--ui-text-muted)">
|
|
89
|
+
Permanently delete this space and all its documents. This action cannot be undone.
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
<UButton
|
|
93
|
+
label="Delete Space"
|
|
94
|
+
color="error"
|
|
95
|
+
variant="soft"
|
|
96
|
+
icon="i-lucide-trash-2"
|
|
97
|
+
disabled
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
</UCard>
|
|
101
|
+
</div>
|
|
102
|
+
</template>
|
|
103
|
+
</UTabs>
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
/** Space ID to manage */
|
|
3
|
+
spaceId: string;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Space } from "@rgby/collab-core";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
/** Currently selected space ID */
|
|
4
|
+
modelValue?: string;
|
|
5
|
+
/** Show "Create new space" action */
|
|
6
|
+
showCreate?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
create: (space: Space) => any;
|
|
10
|
+
"update:modelValue": (spaceId: string) => any;
|
|
11
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
+
onCreate?: ((space: Space) => any) | undefined;
|
|
13
|
+
"onUpdate:modelValue"?: ((spaceId: string) => any) | undefined;
|
|
14
|
+
}>, {
|
|
15
|
+
showCreate: boolean;
|
|
16
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
modelValue: { type: String, required: false },
|
|
4
|
+
showCreate: { type: Boolean, required: false, default: true }
|
|
5
|
+
});
|
|
6
|
+
const emit = defineEmits(["update:modelValue", "create"]);
|
|
7
|
+
const client = useCollabClient();
|
|
8
|
+
const spaces = ref([]);
|
|
9
|
+
const loading = ref(true);
|
|
10
|
+
const selectedId = computed({
|
|
11
|
+
get: () => props.modelValue,
|
|
12
|
+
set: (val) => {
|
|
13
|
+
if (val) emit("update:modelValue", val);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const items = computed(
|
|
17
|
+
() => spaces.value.map((s) => ({
|
|
18
|
+
label: s.name,
|
|
19
|
+
value: s.id,
|
|
20
|
+
icon: "i-lucide-layout-grid",
|
|
21
|
+
suffix: s.memberCount != null ? `${s.memberCount} members` : void 0
|
|
22
|
+
}))
|
|
23
|
+
);
|
|
24
|
+
async function loadSpaces() {
|
|
25
|
+
loading.value = true;
|
|
26
|
+
try {
|
|
27
|
+
spaces.value = await client.spaces.list();
|
|
28
|
+
} finally {
|
|
29
|
+
loading.value = false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const showCreateModal = ref(false);
|
|
33
|
+
const newSpaceName = ref("");
|
|
34
|
+
const creating = ref(false);
|
|
35
|
+
async function createSpace() {
|
|
36
|
+
if (!newSpaceName.value.trim()) return;
|
|
37
|
+
creating.value = true;
|
|
38
|
+
try {
|
|
39
|
+
const space = await client.spaces.create({
|
|
40
|
+
name: newSpaceName.value.trim(),
|
|
41
|
+
slug: newSpaceName.value.trim().toLowerCase().replace(/\s+/g, "-")
|
|
42
|
+
});
|
|
43
|
+
spaces.value.push(space);
|
|
44
|
+
emit("update:modelValue", space.id);
|
|
45
|
+
emit("create", space);
|
|
46
|
+
newSpaceName.value = "";
|
|
47
|
+
showCreateModal.value = false;
|
|
48
|
+
} finally {
|
|
49
|
+
creating.value = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
onMounted(loadSpaces);
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<template>
|
|
56
|
+
<div class="flex items-center gap-2">
|
|
57
|
+
<USelectMenu
|
|
58
|
+
v-model="selectedId"
|
|
59
|
+
:items="items"
|
|
60
|
+
value-key="value"
|
|
61
|
+
placeholder="Select a space..."
|
|
62
|
+
icon="i-lucide-layout-grid"
|
|
63
|
+
:loading="loading"
|
|
64
|
+
class="w-full"
|
|
65
|
+
/>
|
|
66
|
+
|
|
67
|
+
<UButton
|
|
68
|
+
v-if="showCreate"
|
|
69
|
+
icon="i-lucide-plus"
|
|
70
|
+
variant="ghost"
|
|
71
|
+
color="neutral"
|
|
72
|
+
size="sm"
|
|
73
|
+
@click="showCreateModal = true"
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
<UModal v-model:open="showCreateModal" title="Create Space" description="Create a new collaboration space.">
|
|
77
|
+
<template #body>
|
|
78
|
+
<UFormField label="Space name" required class="w-full">
|
|
79
|
+
<UInput
|
|
80
|
+
v-model="newSpaceName"
|
|
81
|
+
placeholder="My Space"
|
|
82
|
+
class="w-full"
|
|
83
|
+
autofocus
|
|
84
|
+
@keydown.enter="createSpace"
|
|
85
|
+
/>
|
|
86
|
+
</UFormField>
|
|
87
|
+
</template>
|
|
88
|
+
<template #footer>
|
|
89
|
+
<UButton
|
|
90
|
+
variant="ghost"
|
|
91
|
+
color="neutral"
|
|
92
|
+
label="Cancel"
|
|
93
|
+
@click="showCreateModal = false"
|
|
94
|
+
/>
|
|
95
|
+
<UButton
|
|
96
|
+
label="Create"
|
|
97
|
+
:loading="creating"
|
|
98
|
+
:disabled="!newSpaceName.trim()"
|
|
99
|
+
@click="createSpace"
|
|
100
|
+
/>
|
|
101
|
+
</template>
|
|
102
|
+
</UModal>
|
|
103
|
+
</div>
|
|
104
|
+
</template>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Space } from "@rgby/collab-core";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
/** Currently selected space ID */
|
|
4
|
+
modelValue?: string;
|
|
5
|
+
/** Show "Create new space" action */
|
|
6
|
+
showCreate?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
create: (space: Space) => any;
|
|
10
|
+
"update:modelValue": (spaceId: string) => any;
|
|
11
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
+
onCreate?: ((space: Space) => any) | undefined;
|
|
13
|
+
"onUpdate:modelValue"?: ((spaceId: string) => any) | undefined;
|
|
14
|
+
}>, {
|
|
15
|
+
showCreate: boolean;
|
|
16
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
/** Space ID */
|
|
3
|
+
spaceId: string;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
spaceId: { type: String, required: true }
|
|
4
|
+
});
|
|
5
|
+
const client = useCollabClient();
|
|
6
|
+
const toast = useToast();
|
|
7
|
+
const deletedDocs = ref([]);
|
|
8
|
+
const loading = ref(true);
|
|
9
|
+
const hasMore = ref(false);
|
|
10
|
+
const offset = ref(0);
|
|
11
|
+
const limit = 20;
|
|
12
|
+
const confirmDelete = ref(false);
|
|
13
|
+
const deleteTarget = ref(null);
|
|
14
|
+
const deleting = ref(false);
|
|
15
|
+
async function loadDeleted(append = false) {
|
|
16
|
+
loading.value = true;
|
|
17
|
+
try {
|
|
18
|
+
const result = await client.documents.listDeleted(props.spaceId, {
|
|
19
|
+
limit,
|
|
20
|
+
offset: offset.value
|
|
21
|
+
});
|
|
22
|
+
if (append) {
|
|
23
|
+
deletedDocs.value.push(...result.items);
|
|
24
|
+
} else {
|
|
25
|
+
deletedDocs.value = result.items;
|
|
26
|
+
}
|
|
27
|
+
hasMore.value = result.pagination.hasMore;
|
|
28
|
+
} finally {
|
|
29
|
+
loading.value = false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function restore(doc) {
|
|
33
|
+
try {
|
|
34
|
+
await client.documents.restore(props.spaceId, doc.id);
|
|
35
|
+
deletedDocs.value = deletedDocs.value.filter((d) => d.id !== doc.id);
|
|
36
|
+
toast.add({ title: "Document restored", color: "success", icon: "i-lucide-check" });
|
|
37
|
+
} catch {
|
|
38
|
+
toast.add({ title: "Failed to restore document", color: "error" });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function promptDelete(doc) {
|
|
42
|
+
deleteTarget.value = doc;
|
|
43
|
+
confirmDelete.value = true;
|
|
44
|
+
}
|
|
45
|
+
async function confirmPermanentDelete() {
|
|
46
|
+
if (!deleteTarget.value) return;
|
|
47
|
+
deleting.value = true;
|
|
48
|
+
try {
|
|
49
|
+
await client.documents.deletePermanent(props.spaceId, deleteTarget.value.id);
|
|
50
|
+
deletedDocs.value = deletedDocs.value.filter((d) => d.id !== deleteTarget.value.id);
|
|
51
|
+
toast.add({ title: "Permanently deleted", color: "success" });
|
|
52
|
+
confirmDelete.value = false;
|
|
53
|
+
} catch {
|
|
54
|
+
toast.add({ title: "Failed to delete", color: "error" });
|
|
55
|
+
} finally {
|
|
56
|
+
deleting.value = false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function loadMore() {
|
|
60
|
+
offset.value += limit;
|
|
61
|
+
loadDeleted(true);
|
|
62
|
+
}
|
|
63
|
+
function formatDate(dateStr) {
|
|
64
|
+
if (!dateStr) return "";
|
|
65
|
+
return new Date(dateStr).toLocaleDateString(void 0, {
|
|
66
|
+
month: "short",
|
|
67
|
+
day: "numeric",
|
|
68
|
+
year: "numeric"
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
watch(() => props.spaceId, () => {
|
|
72
|
+
offset.value = 0;
|
|
73
|
+
loadDeleted();
|
|
74
|
+
}, { immediate: true });
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<div class="space-y-4">
|
|
79
|
+
<div class="flex items-center justify-between">
|
|
80
|
+
<h3 class="text-sm font-medium">Trash</h3>
|
|
81
|
+
<UButton
|
|
82
|
+
icon="i-lucide-refresh-cw"
|
|
83
|
+
variant="ghost"
|
|
84
|
+
color="neutral"
|
|
85
|
+
size="xs"
|
|
86
|
+
@click="offset = 0;
|
|
87
|
+
loadDeleted()"
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<USkeleton v-if="loading && deletedDocs.length === 0" class="h-32" />
|
|
92
|
+
|
|
93
|
+
<UEmpty
|
|
94
|
+
v-else-if="deletedDocs.length === 0"
|
|
95
|
+
icon="i-lucide-trash-2"
|
|
96
|
+
title="Trash is empty"
|
|
97
|
+
description="Deleted documents will appear here."
|
|
98
|
+
size="sm"
|
|
99
|
+
/>
|
|
100
|
+
|
|
101
|
+
<div v-else class="space-y-1">
|
|
102
|
+
<div
|
|
103
|
+
v-for="doc in deletedDocs"
|
|
104
|
+
:key="doc.id"
|
|
105
|
+
class="flex items-center justify-between gap-3 px-2 py-2 rounded-(--ui-radius) hover:bg-(--ui-bg-elevated)"
|
|
106
|
+
>
|
|
107
|
+
<div class="flex items-center gap-2 min-w-0">
|
|
108
|
+
<UIcon name="i-lucide-file-text" class="size-4 shrink-0 text-(--ui-text-muted)" />
|
|
109
|
+
<div class="min-w-0">
|
|
110
|
+
<div class="text-sm truncate">{{ doc.name || "Untitled" }}</div>
|
|
111
|
+
<div v-if="doc.updatedAt" class="text-xs text-(--ui-text-muted)">
|
|
112
|
+
Deleted {{ formatDate(doc.updatedAt) }}
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="flex items-center gap-1 shrink-0">
|
|
118
|
+
<UButton
|
|
119
|
+
icon="i-lucide-rotate-ccw"
|
|
120
|
+
label="Restore"
|
|
121
|
+
variant="ghost"
|
|
122
|
+
color="neutral"
|
|
123
|
+
size="xs"
|
|
124
|
+
@click="restore(doc)"
|
|
125
|
+
/>
|
|
126
|
+
<UButton
|
|
127
|
+
icon="i-lucide-trash-2"
|
|
128
|
+
variant="ghost"
|
|
129
|
+
color="error"
|
|
130
|
+
size="xs"
|
|
131
|
+
@click="promptDelete(doc)"
|
|
132
|
+
/>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<div v-if="hasMore" class="pt-2 text-center">
|
|
137
|
+
<UButton
|
|
138
|
+
label="Load more"
|
|
139
|
+
variant="ghost"
|
|
140
|
+
color="neutral"
|
|
141
|
+
size="xs"
|
|
142
|
+
:loading="loading"
|
|
143
|
+
@click="loadMore"
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<UModal
|
|
149
|
+
v-model:open="confirmDelete"
|
|
150
|
+
title="Delete Permanently"
|
|
151
|
+
description="This document will be permanently deleted and cannot be recovered."
|
|
152
|
+
>
|
|
153
|
+
<template #footer>
|
|
154
|
+
<UButton variant="ghost" color="neutral" label="Cancel" @click="confirmDelete = false" />
|
|
155
|
+
<UButton label="Delete Forever" color="error" :loading="deleting" @click="confirmPermanentDelete" />
|
|
156
|
+
</template>
|
|
157
|
+
</UModal>
|
|
158
|
+
</div>
|
|
159
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
/** Space ID */
|
|
3
|
+
spaceId: string;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
/** Show email in the trigger */
|
|
3
|
+
showEmail?: boolean;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
logout: () => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
8
|
+
onLogout?: (() => any) | undefined;
|
|
9
|
+
}>, {
|
|
10
|
+
showEmail: boolean;
|
|
11
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
defineProps({
|
|
3
|
+
showEmail: { type: Boolean, required: false, default: false }
|
|
4
|
+
});
|
|
5
|
+
const emit = defineEmits(["logout"]);
|
|
6
|
+
const { user, isAuthenticated, logout } = useAuth();
|
|
7
|
+
const colorMode = useColorMode();
|
|
8
|
+
const menuItems = computed(() => [
|
|
9
|
+
[
|
|
10
|
+
{
|
|
11
|
+
label: user.value?.name || "User",
|
|
12
|
+
icon: "i-lucide-user",
|
|
13
|
+
disabled: true
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
label: colorMode.preference === "dark" ? "Light Mode" : "Dark Mode",
|
|
19
|
+
icon: colorMode.preference === "dark" ? "i-lucide-sun" : "i-lucide-moon",
|
|
20
|
+
onSelect: () => {
|
|
21
|
+
colorMode.preference = colorMode.preference === "dark" ? "light" : "dark";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
{
|
|
27
|
+
label: "Log out",
|
|
28
|
+
icon: "i-lucide-log-out",
|
|
29
|
+
color: "error",
|
|
30
|
+
onSelect: async () => {
|
|
31
|
+
await logout();
|
|
32
|
+
emit("logout");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
]);
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<UDropdownMenu v-if="isAuthenticated" :items="menuItems">
|
|
41
|
+
<UButton variant="ghost" color="neutral" class="gap-2">
|
|
42
|
+
<UAvatar
|
|
43
|
+
:src="user?.image"
|
|
44
|
+
:alt="user?.name || 'User'"
|
|
45
|
+
size="2xs"
|
|
46
|
+
/>
|
|
47
|
+
<span v-if="showEmail" class="text-sm truncate max-w-32">{{ user?.email }}</span>
|
|
48
|
+
</UButton>
|
|
49
|
+
</UDropdownMenu>
|
|
50
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
/** Show email in the trigger */
|
|
3
|
+
showEmail?: boolean;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
logout: () => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
8
|
+
onLogout?: (() => any) | undefined;
|
|
9
|
+
}>, {
|
|
10
|
+
showEmail: boolean;
|
|
11
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShallowRef } from "vue";
|
|
2
|
+
import type { CollabProvider } from "@rgby/collab-core";
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
provider: ShallowRef<CollabProvider | null> | CollabProvider | null;
|
|
5
|
+
max?: number;
|
|
6
|
+
size?: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
9
|
+
size: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
10
|
+
max: number;
|
|
11
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
provider: { type: null, required: true },
|
|
4
|
+
max: { type: Number, required: false, default: 5 },
|
|
5
|
+
size: { type: String, required: false, default: "xs" }
|
|
6
|
+
});
|
|
7
|
+
const providerRef = computed(() => {
|
|
8
|
+
if (!props.provider) return null;
|
|
9
|
+
if ("value" in props.provider) return props.provider.value;
|
|
10
|
+
return props.provider;
|
|
11
|
+
});
|
|
12
|
+
const { states: users } = useAwareness(providerRef);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<UAvatarGroup v-if="users.length > 0" :max="max" :size="size">
|
|
17
|
+
<UTooltip
|
|
18
|
+
v-for="u in users"
|
|
19
|
+
:key="u.clientId"
|
|
20
|
+
:text="u.user?.name || 'Anonymous'"
|
|
21
|
+
>
|
|
22
|
+
<UAvatar
|
|
23
|
+
:alt="u.user?.name || 'Anonymous'"
|
|
24
|
+
:src="u.user?.avatar"
|
|
25
|
+
:style="{
|
|
26
|
+
'--tw-ring-color': u.user?.color || '#ccc',
|
|
27
|
+
backgroundColor: u.user?.color || '#ccc'
|
|
28
|
+
}"
|
|
29
|
+
/>
|
|
30
|
+
</UTooltip>
|
|
31
|
+
</UAvatarGroup>
|
|
32
|
+
|
|
33
|
+
<span v-else class="text-xs text-(--ui-text-muted)">No one online</span>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShallowRef } from "vue";
|
|
2
|
+
import type { CollabProvider } from "@rgby/collab-core";
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
provider: ShallowRef<CollabProvider | null> | CollabProvider | null;
|
|
5
|
+
max?: number;
|
|
6
|
+
size?: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
9
|
+
size: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
10
|
+
max: number;
|
|
11
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CollaborationUser } from '../../composables/useEditorCollaboration.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
users: CollaborationUser[];
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
defineProps({
|
|
3
|
+
users: { type: Array, required: true }
|
|
4
|
+
});
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<template v-if="users.length > 0">
|
|
9
|
+
<UAvatarGroup>
|
|
10
|
+
<template
|
|
11
|
+
v-for="user in users"
|
|
12
|
+
:key="user.name"
|
|
13
|
+
>
|
|
14
|
+
<UTooltip :text="user.name">
|
|
15
|
+
<UAvatar
|
|
16
|
+
:alt="user.name"
|
|
17
|
+
size="sm"
|
|
18
|
+
:style="{
|
|
19
|
+
color: user.color
|
|
20
|
+
}"
|
|
21
|
+
/>
|
|
22
|
+
</UTooltip>
|
|
23
|
+
</template>
|
|
24
|
+
</UAvatarGroup>
|
|
25
|
+
|
|
26
|
+
<USeparator
|
|
27
|
+
orientation="vertical"
|
|
28
|
+
class="h-7"
|
|
29
|
+
/>
|
|
30
|
+
</template>
|
|
31
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CollaborationUser } from '../../composables/useEditorCollaboration.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
users: CollaborationUser[];
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
3
|
+
import type { Editor } from '@tiptap/vue-3';
|
|
4
|
+
export interface CompletionOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Whether to automatically trigger completion while typing
|
|
7
|
+
* @defaultValue false
|
|
8
|
+
*/
|
|
9
|
+
autoTrigger?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Debounce delay in ms before triggering completion
|
|
12
|
+
* @defaultValue 250
|
|
13
|
+
*/
|
|
14
|
+
debounce?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Characters that should prevent completion from triggering
|
|
17
|
+
* @defaultValue ['/', ':', '@']
|
|
18
|
+
*/
|
|
19
|
+
triggerCharacters?: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Called when completion should be triggered, receives the editor instance
|
|
22
|
+
*/
|
|
23
|
+
onTrigger?: (editor: Editor) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Called when suggestion is accepted
|
|
26
|
+
*/
|
|
27
|
+
onAccept?: () => void;
|
|
28
|
+
/**
|
|
29
|
+
* Called when suggestion is dismissed
|
|
30
|
+
*/
|
|
31
|
+
onDismiss?: () => void;
|
|
32
|
+
}
|
|
33
|
+
export interface CompletionStorage {
|
|
34
|
+
suggestion: string;
|
|
35
|
+
position: number | undefined;
|
|
36
|
+
visible: boolean;
|
|
37
|
+
debouncedTrigger: ((editor: Editor) => void) | null;
|
|
38
|
+
setSuggestion: (text: string) => void;
|
|
39
|
+
clearSuggestion: () => void;
|
|
40
|
+
}
|
|
41
|
+
export declare const completionPluginKey: PluginKey<any>;
|
|
42
|
+
export declare const Completion: Extension<CompletionOptions, CompletionStorage>;
|
|
43
|
+
export default Completion;
|