@agent-native/core 0.176.5-nightly-20260903175350 → 0.176.5
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/corpus/README.md +1 -1
- package/corpus/templates/calendar/CHANGELOG.md +18 -0
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +13 -7
- package/corpus/templates/content/CHANGELOG.md +1 -0
- package/corpus/templates/content/actions/_collection-export.ts +925 -0
- package/corpus/templates/content/actions/export-document.ts +79 -255
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +39 -38
- package/corpus/templates/content/app/components/editor/database/DatabaseExportDialog.tsx +444 -113
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +4 -0
- package/corpus/templates/content/app/i18n-data.ts +99 -0
- package/corpus/templates/content/docs/product/capabilities/content.portability.collection-export.md +139 -0
- package/corpus/templates/content/docs/product/encyclopedia.md +12 -8
- package/corpus/templates/content/docs/product/features/content.feature.take-the-whole-vault-with-you.md +5 -1
- package/corpus/templates/content/docs/product/roadmap.md +1 -1
- package/corpus/templates/content/shared/database-collection-export.ts +161 -0
- package/corpus/templates/content/shared/database-csv-export.ts +6 -3
- package/corpus/templates/design/CHANGELOG.md +1 -0
- package/corpus/templates/factory/CHANGELOG.md +20 -0
- package/corpus/templates/mail/CHANGELOG.md +12 -0
- package/corpus/templates/plan/CHANGELOG.md +6 -0
- package/corpus/templates/slides/CHANGELOG.md +9 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/realtime-token.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1,41 +1,22 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core/action";
|
|
2
2
|
import { buildDeepLink } from "@agent-native/core/server";
|
|
3
|
-
import {
|
|
4
|
-
import { accessFilter, resolveAccess } from "@agent-native/core/sharing";
|
|
5
|
-
import { and, asc, eq, isNull, or } from "drizzle-orm";
|
|
3
|
+
import { resolveAccess } from "@agent-native/core/sharing";
|
|
6
4
|
import { z } from "zod";
|
|
7
5
|
|
|
8
|
-
import { getDb, schema } from "../server/db/index.js";
|
|
9
|
-
import type {
|
|
10
|
-
ContentDatabaseItem,
|
|
11
|
-
ContentDatabaseTableQuery,
|
|
12
|
-
} from "../shared/api.js";
|
|
13
6
|
import { blocksContentHash } from "../shared/blocks-field-identity.js";
|
|
14
|
-
import { renderDatabaseCsv } from "../shared/database-csv-export.js";
|
|
15
|
-
import { applyContentDatabaseTableQuery } from "../shared/database-query.js";
|
|
16
7
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from "../shared/
|
|
8
|
+
renderCollectionCsv,
|
|
9
|
+
renderCollectionHtml,
|
|
10
|
+
renderCollectionMarkdownArchive,
|
|
11
|
+
} from "../shared/database-collection-export.js";
|
|
12
|
+
import { buildDocumentExport } from "../shared/document-export.js";
|
|
21
13
|
import {
|
|
22
14
|
isBlocksPropertyType,
|
|
23
15
|
isPrimaryBlocksField,
|
|
24
16
|
} from "../shared/properties.js";
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
CONTENT_DATABASE_MAX_READ_LIMIT,
|
|
29
|
-
getDatabaseByDocumentId,
|
|
30
|
-
} from "./_database-utils.js";
|
|
31
|
-
import {
|
|
32
|
-
listPropertiesForAllDocumentDatabases,
|
|
33
|
-
listPropertiesForDatabase,
|
|
34
|
-
listPropertiesForDatabaseDocuments,
|
|
35
|
-
parseDatabaseViewConfig,
|
|
36
|
-
} from "./_property-utils.js";
|
|
37
|
-
|
|
38
|
-
const COLLECTION_EXPORT_ACCESS_CONCURRENCY = 8;
|
|
17
|
+
import { buildCollectionExportProjection } from "./_collection-export.js";
|
|
18
|
+
import { getDatabaseByDocumentId } from "./_database-utils.js";
|
|
19
|
+
import { listPropertiesForAllDocumentDatabases } from "./_property-utils.js";
|
|
39
20
|
|
|
40
21
|
const collectionSchema = z.object({
|
|
41
22
|
scope: z.discriminatedUnion("kind", [
|
|
@@ -84,218 +65,24 @@ const collectionSchema = z.object({
|
|
|
84
65
|
}),
|
|
85
66
|
]),
|
|
86
67
|
propertyIds: z.array(z.string().min(1)).max(200),
|
|
68
|
+
includePrimaryBody: z.boolean().default(false),
|
|
69
|
+
blockPropertyIds: z.array(z.string().min(1)).max(200).default([]),
|
|
87
70
|
});
|
|
88
71
|
|
|
89
72
|
type CollectionExport = z.infer<typeof collectionSchema>;
|
|
90
73
|
|
|
91
|
-
function
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
throw new Error(`Unknown database property "${key}" in export query`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async function databaseCsvContent(
|
|
103
|
-
documentId: string,
|
|
104
|
-
collection: CollectionExport,
|
|
105
|
-
) {
|
|
106
|
-
const database = await getDatabaseByDocumentId(documentId);
|
|
107
|
-
if (!database) throw new Error("CSV export requires a database document");
|
|
108
|
-
|
|
109
|
-
const properties = await listPropertiesForDatabase(database.id);
|
|
110
|
-
const propertyById = new Map(
|
|
111
|
-
properties.map((property) => [property.definition.id, property]),
|
|
112
|
-
);
|
|
113
|
-
if (new Set(collection.propertyIds).size !== collection.propertyIds.length) {
|
|
114
|
-
throw new Error("CSV export property IDs must be unique");
|
|
115
|
-
}
|
|
116
|
-
const selectedProperties = collection.propertyIds.map((propertyId) => {
|
|
117
|
-
const property = propertyById.get(propertyId);
|
|
118
|
-
if (!property) throw new Error(`Unknown database property "${propertyId}"`);
|
|
119
|
-
return property;
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const query =
|
|
123
|
-
collection.scope.kind === "current_view" ? collection.scope.query : null;
|
|
124
|
-
const scope = collection.scope;
|
|
125
|
-
if (scope.kind === "current_view") {
|
|
126
|
-
const view = parseDatabaseViewConfig(database.viewConfigJson).views.find(
|
|
127
|
-
(candidate) => candidate.id === scope.viewId,
|
|
128
|
-
);
|
|
129
|
-
if (!view) throw new Error(`Database view "${scope.viewId}" not found`);
|
|
130
|
-
assertValidQuery(query!, new Set(propertyById.keys()));
|
|
131
|
-
}
|
|
132
|
-
const blocksAreNeeded =
|
|
133
|
-
selectedProperties.some((property) =>
|
|
134
|
-
isBlocksPropertyType(property.definition.type),
|
|
135
|
-
) ||
|
|
136
|
-
(!!query &&
|
|
137
|
-
(query.search.trim().length > 0 ||
|
|
138
|
-
[...query.filters, ...query.sorts].some((constraint) => {
|
|
139
|
-
const property = propertyById.get(constraint.key);
|
|
140
|
-
return !!property && isBlocksPropertyType(property.definition.type);
|
|
141
|
-
})));
|
|
142
|
-
|
|
143
|
-
const userEmail = getRequestUserEmail();
|
|
144
|
-
const memberships = userEmail
|
|
145
|
-
? await listContentOrganizationMemberships(userEmail)
|
|
146
|
-
: [];
|
|
147
|
-
const accessClauses = [accessFilter(schema.documents, schema.documentShares)];
|
|
148
|
-
for (const membership of memberships) {
|
|
149
|
-
accessClauses.push(
|
|
150
|
-
accessFilter(schema.documents, schema.documentShares, {
|
|
151
|
-
userEmail: userEmail!,
|
|
152
|
-
orgId: membership.orgId,
|
|
153
|
-
}),
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
const rows = await getDb()
|
|
157
|
-
.select({
|
|
158
|
-
item: schema.contentDatabaseItems,
|
|
159
|
-
document: schema.documents,
|
|
160
|
-
})
|
|
161
|
-
.from(schema.contentDatabaseItems)
|
|
162
|
-
.innerJoin(
|
|
163
|
-
schema.documents,
|
|
164
|
-
eq(schema.documents.id, schema.contentDatabaseItems.documentId),
|
|
165
|
-
)
|
|
166
|
-
.where(
|
|
167
|
-
and(
|
|
168
|
-
eq(schema.contentDatabaseItems.databaseId, database.id),
|
|
169
|
-
isNull(schema.documents.trashedAt),
|
|
170
|
-
or(...accessClauses),
|
|
171
|
-
),
|
|
172
|
-
)
|
|
173
|
-
.orderBy(
|
|
174
|
-
asc(schema.contentDatabaseItems.position),
|
|
175
|
-
asc(schema.contentDatabaseItems.createdAt),
|
|
176
|
-
asc(schema.contentDatabaseItems.id),
|
|
177
|
-
)
|
|
178
|
-
.limit(CONTENT_DATABASE_MAX_READ_LIMIT + 1);
|
|
179
|
-
if (rows.length > CONTENT_DATABASE_MAX_READ_LIMIT) {
|
|
180
|
-
throw new Error(
|
|
181
|
-
`CSV export supports up to ${CONTENT_DATABASE_MAX_READ_LIMIT} accessible rows.`,
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
if (blocksAreNeeded) {
|
|
185
|
-
for (const { item } of rows) {
|
|
186
|
-
if (
|
|
187
|
-
item.bodyHydrationStatus !== "hydrated" &&
|
|
188
|
-
item.bodyHydrationStatus !== "unavailable"
|
|
189
|
-
) {
|
|
190
|
-
throw new Error(
|
|
191
|
-
`Database item "${item.documentId}" is not ready for export`,
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
const documents = rows.map((row) => row.document);
|
|
197
|
-
const propertiesByDocumentId = await listPropertiesForDatabaseDocuments(
|
|
198
|
-
database.id,
|
|
199
|
-
documents,
|
|
200
|
-
);
|
|
201
|
-
const queryItems: ContentDatabaseItem[] = rows.map((row) => ({
|
|
202
|
-
id: row.item.id,
|
|
203
|
-
databaseId: row.item.databaseId,
|
|
204
|
-
document: {
|
|
205
|
-
id: row.document.id,
|
|
206
|
-
parentId: row.document.parentId,
|
|
207
|
-
title: row.document.title,
|
|
208
|
-
content: row.document.content,
|
|
209
|
-
description: row.document.description ?? undefined,
|
|
210
|
-
icon: row.document.icon,
|
|
211
|
-
position: row.document.position,
|
|
212
|
-
isFavorite: row.document.isFavorite === 1,
|
|
213
|
-
hideFromSearch: row.document.hideFromSearch === 1,
|
|
214
|
-
createdAt: row.document.createdAt,
|
|
215
|
-
updatedAt: row.document.updatedAt,
|
|
216
|
-
},
|
|
217
|
-
position: row.item.position,
|
|
218
|
-
properties: propertiesByDocumentId.get(row.document.id) ?? [],
|
|
219
|
-
}));
|
|
220
|
-
const selectedRows = query
|
|
221
|
-
? applyContentDatabaseTableQuery(queryItems, properties, query)
|
|
222
|
-
: queryItems;
|
|
223
|
-
return renderDatabaseCsv(
|
|
224
|
-
selectedProperties.map((property) => ({
|
|
225
|
-
id: property.definition.id,
|
|
226
|
-
name: property.definition.name,
|
|
227
|
-
property,
|
|
228
|
-
})),
|
|
229
|
-
selectedRows.map((row) => ({
|
|
230
|
-
title: row.document.title,
|
|
231
|
-
values: new Map(
|
|
232
|
-
row.properties.map((property) => [
|
|
233
|
-
property.definition.id,
|
|
234
|
-
property.value,
|
|
235
|
-
]),
|
|
236
|
-
),
|
|
237
|
-
})),
|
|
74
|
+
function exportBaseName(title: string | null | undefined) {
|
|
75
|
+
return (
|
|
76
|
+
(title || "untitled")
|
|
77
|
+
.replace(/[^a-z0-9]+/gi, "-")
|
|
78
|
+
.replace(/^-+|-+$/g, "")
|
|
79
|
+
.toLowerCase() || "untitled"
|
|
238
80
|
);
|
|
239
81
|
}
|
|
240
82
|
|
|
241
|
-
async function databaseExportContent(documentId: string) {
|
|
242
|
-
const database = await getDatabaseByDocumentId(documentId);
|
|
243
|
-
if (!database) return null;
|
|
244
|
-
|
|
245
|
-
const members = await getDb()
|
|
246
|
-
.select({
|
|
247
|
-
documentId: schema.contentDatabaseItems.documentId,
|
|
248
|
-
bodyHydrationStatus: schema.contentDatabaseItems.bodyHydrationStatus,
|
|
249
|
-
})
|
|
250
|
-
.from(schema.contentDatabaseItems)
|
|
251
|
-
.where(eq(schema.contentDatabaseItems.databaseId, database.id))
|
|
252
|
-
.orderBy(
|
|
253
|
-
asc(schema.contentDatabaseItems.position),
|
|
254
|
-
asc(schema.contentDatabaseItems.createdAt),
|
|
255
|
-
asc(schema.contentDatabaseItems.id),
|
|
256
|
-
);
|
|
257
|
-
const items: CollectionExportItem[] = [];
|
|
258
|
-
|
|
259
|
-
for (
|
|
260
|
-
let offset = 0;
|
|
261
|
-
offset < members.length;
|
|
262
|
-
offset += COLLECTION_EXPORT_ACCESS_CONCURRENCY
|
|
263
|
-
) {
|
|
264
|
-
const batch = members.slice(
|
|
265
|
-
offset,
|
|
266
|
-
offset + COLLECTION_EXPORT_ACCESS_CONCURRENCY,
|
|
267
|
-
);
|
|
268
|
-
const resolved = await Promise.all(
|
|
269
|
-
batch.map(async (member) => ({
|
|
270
|
-
member,
|
|
271
|
-
access: await resolveContentDocumentAccess(member.documentId),
|
|
272
|
-
})),
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
for (const { member, access } of resolved) {
|
|
276
|
-
if (!access || access.resource.trashedAt) continue;
|
|
277
|
-
if (
|
|
278
|
-
member.bodyHydrationStatus !== "hydrated" &&
|
|
279
|
-
member.bodyHydrationStatus !== "unavailable"
|
|
280
|
-
) {
|
|
281
|
-
throw new Error(
|
|
282
|
-
`Database item "${member.documentId}" is not ready for export`,
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
items.push({
|
|
287
|
-
title: access.resource.title,
|
|
288
|
-
content: access.resource.content,
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return collectionItemsMarkdown(items);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
83
|
export default defineAction({
|
|
297
84
|
description:
|
|
298
|
-
"Export a Content
|
|
85
|
+
"Export a Content page or bounded Database/View collection as CSV, a Markdown package, standalone HTML, or PDF-ready HTML for the browser print dialog.",
|
|
299
86
|
schema: z.object({
|
|
300
87
|
id: z.string().describe("Document ID (required)"),
|
|
301
88
|
format: z
|
|
@@ -304,7 +91,9 @@ export default defineAction({
|
|
|
304
91
|
.describe("Export format: pdf, markdown, html, or csv."),
|
|
305
92
|
collection: collectionSchema
|
|
306
93
|
.optional()
|
|
307
|
-
.describe(
|
|
94
|
+
.describe(
|
|
95
|
+
"Database export scope, selected scalar property IDs, primary body choice, and selected additional Blocks property IDs.",
|
|
96
|
+
),
|
|
308
97
|
title: z
|
|
309
98
|
.string()
|
|
310
99
|
.max(500)
|
|
@@ -323,30 +112,66 @@ export default defineAction({
|
|
|
323
112
|
if (!access) throw new Error(`Document "${id}" not found`);
|
|
324
113
|
|
|
325
114
|
const doc = access.resource;
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
115
|
+
const database = await getDatabaseByDocumentId(doc.id);
|
|
116
|
+
const effectiveCollection: CollectionExport | null = collection
|
|
117
|
+
? collection
|
|
118
|
+
: database && format !== "csv"
|
|
119
|
+
? {
|
|
120
|
+
scope: { kind: "all_members" },
|
|
121
|
+
propertyIds: [],
|
|
122
|
+
includePrimaryBody: true,
|
|
123
|
+
blockPropertyIds: [],
|
|
124
|
+
}
|
|
125
|
+
: null;
|
|
126
|
+
if (format === "csv" && !effectiveCollection) {
|
|
127
|
+
throw new Error("CSV export requires collection options");
|
|
128
|
+
}
|
|
129
|
+
if (effectiveCollection) {
|
|
130
|
+
const projection = await buildCollectionExportProjection(
|
|
131
|
+
doc.id,
|
|
132
|
+
effectiveCollection,
|
|
133
|
+
);
|
|
134
|
+
const baseName = exportBaseName(doc.title);
|
|
135
|
+
const deepLink = buildDeepLink({
|
|
136
|
+
app: "content",
|
|
137
|
+
view: "editor",
|
|
138
|
+
params: { documentId: doc.id },
|
|
139
|
+
});
|
|
140
|
+
if (format === "csv") {
|
|
141
|
+
const content = renderCollectionCsv(projection);
|
|
142
|
+
return {
|
|
143
|
+
id: doc.id,
|
|
144
|
+
title: doc.title || "Untitled",
|
|
145
|
+
format,
|
|
146
|
+
filename: `${baseName}.csv`,
|
|
147
|
+
mimeType: "text/csv;charset=utf-8",
|
|
148
|
+
content,
|
|
149
|
+
print: false,
|
|
150
|
+
deepLink,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (format === "markdown") {
|
|
154
|
+
const archiveFiles = renderCollectionMarkdownArchive(projection);
|
|
155
|
+
return {
|
|
156
|
+
id: doc.id,
|
|
157
|
+
title: doc.title || "Untitled",
|
|
158
|
+
format,
|
|
159
|
+
filename: `${baseName}.zip`,
|
|
160
|
+
mimeType: "application/zip",
|
|
161
|
+
content: archiveFiles[0]?.content ?? "",
|
|
162
|
+
archiveFiles,
|
|
163
|
+
print: false,
|
|
164
|
+
deepLink,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
330
167
|
return {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
format,
|
|
334
|
-
filename: `${
|
|
335
|
-
(doc.title || "untitled")
|
|
336
|
-
.replace(/[^a-z0-9]+/gi, "-")
|
|
337
|
-
.replace(/^-+|-+$/g, "")
|
|
338
|
-
.toLowerCase() || "untitled"
|
|
339
|
-
}.csv`,
|
|
340
|
-
mimeType: "text/csv;charset=utf-8",
|
|
341
|
-
content,
|
|
342
|
-
print: false,
|
|
343
|
-
deepLink: buildDeepLink({
|
|
344
|
-
app: "content",
|
|
345
|
-
view: "editor",
|
|
346
|
-
params: { documentId: doc.id },
|
|
347
|
-
}),
|
|
168
|
+
...renderCollectionHtml(projection, format),
|
|
169
|
+
deepLink,
|
|
348
170
|
};
|
|
349
171
|
}
|
|
172
|
+
if (format === "csv") {
|
|
173
|
+
throw new Error("CSV export requires collection options");
|
|
174
|
+
}
|
|
350
175
|
const properties = await listPropertiesForAllDocumentDatabases(doc);
|
|
351
176
|
const blocksFields = properties
|
|
352
177
|
.filter((property) => isBlocksPropertyType(property.definition.type))
|
|
@@ -381,11 +206,10 @@ export default defineAction({
|
|
|
381
206
|
identity,
|
|
382
207
|
};
|
|
383
208
|
});
|
|
384
|
-
const collectionContent = await databaseExportContent(doc.id);
|
|
385
209
|
const payload = buildDocumentExport({
|
|
386
210
|
id: doc.id,
|
|
387
211
|
title: title ?? doc.title,
|
|
388
|
-
content:
|
|
212
|
+
content: content ?? doc.content,
|
|
389
213
|
updatedAt: doc.updatedAt,
|
|
390
214
|
format,
|
|
391
215
|
blocksFields,
|
|
@@ -1115,48 +1115,50 @@ export function DocumentToolbar({
|
|
|
1115
1115
|
</DropdownMenuItem>
|
|
1116
1116
|
</DropdownMenuGroup>
|
|
1117
1117
|
<DropdownMenuSeparator />
|
|
1118
|
-
|
|
1119
|
-
<
|
|
1120
|
-
{
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
<IconDownload className="me-2 h-4 w-4" />
|
|
1124
|
-
)}
|
|
1118
|
+
{databaseExportContext ? (
|
|
1119
|
+
<DropdownMenuItem
|
|
1120
|
+
onSelect={() => setDatabaseExportOpen(true)}
|
|
1121
|
+
>
|
|
1122
|
+
<IconDownload className="me-2 h-4 w-4" />
|
|
1125
1123
|
{t("editor.toolbar.export")}
|
|
1126
|
-
</
|
|
1127
|
-
|
|
1128
|
-
|
|
1124
|
+
</DropdownMenuItem>
|
|
1125
|
+
) : (
|
|
1126
|
+
<DropdownMenuSub>
|
|
1127
|
+
<DropdownMenuSubTrigger
|
|
1128
|
+
disabled={exportDocument.isPending}
|
|
1129
|
+
>
|
|
1130
|
+
{exportDocument.isPending ? (
|
|
1131
|
+
<IconLoader2 className="me-2 h-4 w-4 animate-spin" />
|
|
1132
|
+
) : (
|
|
1133
|
+
<IconDownload className="me-2 h-4 w-4" />
|
|
1134
|
+
)}
|
|
1135
|
+
{t("editor.toolbar.export")}
|
|
1136
|
+
</DropdownMenuSubTrigger>
|
|
1137
|
+
<DropdownMenuSubContent className="w-44">
|
|
1129
1138
|
<DropdownMenuItem
|
|
1130
1139
|
disabled={exportDocument.isPending}
|
|
1131
|
-
onSelect={() =>
|
|
1140
|
+
onSelect={() => void handleExport("pdf")}
|
|
1132
1141
|
>
|
|
1133
|
-
<
|
|
1134
|
-
|
|
1142
|
+
<IconFileTypePdf className="me-2 h-4 w-4" />
|
|
1143
|
+
PDF
|
|
1135
1144
|
</DropdownMenuItem>
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
</
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
onSelect={() => void handleExport("html")}
|
|
1154
|
-
>
|
|
1155
|
-
<IconFileTypeHtml className="me-2 h-4 w-4" />
|
|
1156
|
-
HTML
|
|
1157
|
-
</DropdownMenuItem>
|
|
1158
|
-
</DropdownMenuSubContent>
|
|
1159
|
-
</DropdownMenuSub>
|
|
1145
|
+
<DropdownMenuItem
|
|
1146
|
+
disabled={exportDocument.isPending}
|
|
1147
|
+
onSelect={() => void handleExport("markdown")}
|
|
1148
|
+
>
|
|
1149
|
+
<IconMarkdown className="me-2 h-4 w-4" />
|
|
1150
|
+
Markdown
|
|
1151
|
+
</DropdownMenuItem>
|
|
1152
|
+
<DropdownMenuItem
|
|
1153
|
+
disabled={exportDocument.isPending}
|
|
1154
|
+
onSelect={() => void handleExport("html")}
|
|
1155
|
+
>
|
|
1156
|
+
<IconFileTypeHtml className="me-2 h-4 w-4" />
|
|
1157
|
+
HTML
|
|
1158
|
+
</DropdownMenuItem>
|
|
1159
|
+
</DropdownMenuSubContent>
|
|
1160
|
+
</DropdownMenuSub>
|
|
1161
|
+
)}
|
|
1160
1162
|
</>
|
|
1161
1163
|
)}
|
|
1162
1164
|
<DropdownMenuSeparator />
|
|
@@ -1561,7 +1563,6 @@ export function DocumentToolbar({
|
|
|
1561
1563
|
<DatabaseExportDialog
|
|
1562
1564
|
documentId={documentId}
|
|
1563
1565
|
context={databaseExportContext ?? null}
|
|
1564
|
-
defaultScope="current_view"
|
|
1565
1566
|
open={databaseExportOpen}
|
|
1566
1567
|
onOpenChange={setDatabaseExportOpen}
|
|
1567
1568
|
/>
|