@happyvertical/smrt-content 0.44.0 → 0.44.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/agents/content-list.md +61 -5
- package/dist/chunks/{content-corrections-BxfA3tW1.js → content-corrections-B4mPd_th.js} +6 -3
- package/dist/chunks/content-corrections-B4mPd_th.js.map +1 -0
- package/dist/chunks/{content-query-B4cHfrig.js → content-query-D1bLBzMT.js} +6 -6
- package/dist/chunks/{content-query-B4cHfrig.js.map → content-query-D1bLBzMT.js.map} +1 -1
- package/dist/chunks/{content-reviews-BWrYEQc6.js → content-reviews-lBoqJY7Y.js} +6 -3
- package/dist/chunks/content-reviews-lBoqJY7Y.js.map +1 -0
- package/dist/chunks/{content-versions-OEYQVrUf.js → content-versions-B0OUI1ut.js} +6 -3
- package/dist/chunks/content-versions-B0OUI1ut.js.map +1 -0
- package/dist/chunks/{contents-BrGxWH3s.js → contents-CRG2Snrb.js} +2 -2
- package/dist/chunks/{contents-BrGxWH3s.js.map → contents-CRG2Snrb.js.map} +1 -1
- package/dist/content-contribution.d.ts +1 -1
- package/dist/content-contribution.d.ts.map +1 -1
- package/dist/index.js +12 -9
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +33 -6
- package/dist/server/content-list-actions.d.ts +10 -3
- package/dist/server/content-list-actions.d.ts.map +1 -1
- package/dist/server/content-list-lifecycle.d.ts +20 -0
- package/dist/server/content-list-lifecycle.d.ts.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +189 -25
- package/dist/server.js.map +1 -1
- package/dist/smrt-knowledge.json +17 -5
- package/dist/svelte/components/ContentList.svelte +193 -22
- package/dist/svelte/components/ContentList.svelte.d.ts +5 -0
- package/dist/svelte/components/ContentList.svelte.d.ts.map +1 -1
- package/dist/svelte/components/ContentListLifecyclePanel.svelte +341 -0
- package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts +17 -0
- package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts.map +1 -0
- package/dist/svelte/content-list-lifecycle.d.ts +132 -0
- package/dist/svelte/content-list-lifecycle.d.ts.map +1 -0
- package/dist/svelte/content-list-lifecycle.js +439 -0
- package/dist/svelte/i18n.contribution.d.ts +27 -0
- package/dist/svelte/i18n.contribution.d.ts.map +1 -1
- package/dist/svelte/i18n.contribution.js +27 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +1 -0
- package/package.json +15 -15
- package/dist/chunks/content-corrections-BxfA3tW1.js.map +0 -1
- package/dist/chunks/content-reviews-BWrYEQc6.js.map +0 -1
- package/dist/chunks/content-versions-OEYQVrUf.js.map +0 -1
|
@@ -45,6 +45,11 @@ import { Button, Pagination } from '@happyvertical/smrt-ui/ui';
|
|
|
45
45
|
import type { Snippet } from 'svelte';
|
|
46
46
|
import { untrack } from 'svelte';
|
|
47
47
|
import type { ContentData } from '../../mock-smrt-client.js';
|
|
48
|
+
import type { ContentListLifecycleBinding } from '../content-list-lifecycle.js';
|
|
49
|
+
import {
|
|
50
|
+
readContentListLifecycleSummary,
|
|
51
|
+
reconcileContentListLifecycleSelection,
|
|
52
|
+
} from '../content-list-lifecycle.js';
|
|
48
53
|
import {
|
|
49
54
|
applyContentListFilter,
|
|
50
55
|
buildContentListColumns,
|
|
@@ -123,6 +128,7 @@ import {
|
|
|
123
128
|
readContentListViewStateFromSearchParams,
|
|
124
129
|
} from '../content-list-url-state.js';
|
|
125
130
|
import { M } from '../i18n.contribution.js';
|
|
131
|
+
import ContentListLifecyclePanel from './ContentListLifecyclePanel.svelte';
|
|
126
132
|
import ImageThumbnail from './ImageThumbnail.svelte';
|
|
127
133
|
|
|
128
134
|
const { t } = useI18n();
|
|
@@ -335,6 +341,10 @@ interface Props {
|
|
|
335
341
|
jobs?: ContentListJobBinding;
|
|
336
342
|
/** Opt-in, authenticated preview/apply client for bulk workflows (#2453). */
|
|
337
343
|
workflows?: ContentListWorkflowBinding;
|
|
344
|
+
/** Opt-in, server-authoritative trash/restore/permanent-delete lifecycle. */
|
|
345
|
+
lifecycle?: ContentListLifecycleBinding;
|
|
346
|
+
/** Locks the status query to deleted content and exposes trash actions. */
|
|
347
|
+
lifecycleMode?: 'active' | 'trash';
|
|
338
348
|
}
|
|
339
349
|
|
|
340
350
|
let {
|
|
@@ -356,6 +366,8 @@ let {
|
|
|
356
366
|
savedViews = undefined,
|
|
357
367
|
jobs = undefined,
|
|
358
368
|
workflows = undefined,
|
|
369
|
+
lifecycle = undefined,
|
|
370
|
+
lifecycleMode = 'active',
|
|
359
371
|
}: Props = $props();
|
|
360
372
|
|
|
361
373
|
const initialQuery = untrack(() => query);
|
|
@@ -425,6 +437,7 @@ const urlStateOptions: ContentListUrlStateOptions = {
|
|
|
425
437
|
|
|
426
438
|
const controller = createContentListController({
|
|
427
439
|
type: untrack(() => type),
|
|
440
|
+
...(untrack(() => lifecycleMode) === 'trash' ? { status: 'deleted' } : {}),
|
|
428
441
|
// Local mode keeps the historical unpaginated list.
|
|
429
442
|
...(serverPageSize === null ? {} : { pageSize: serverPageSize }),
|
|
430
443
|
});
|
|
@@ -454,6 +467,10 @@ let resultNotices = $state<ContentListQueryNotices>({
|
|
|
454
467
|
* its own total ever arrived.
|
|
455
468
|
*/
|
|
456
469
|
let settledSignature = $state<string | undefined>(undefined);
|
|
470
|
+
let settledLifecycleQuery = $state<ContentListDataQueryRequest | undefined>(
|
|
471
|
+
undefined,
|
|
472
|
+
);
|
|
473
|
+
let settledLifecycleFingerprint = $state<string | undefined>(undefined);
|
|
457
474
|
|
|
458
475
|
function toSearchParams(
|
|
459
476
|
input: URLSearchParams | string | null | undefined,
|
|
@@ -480,22 +497,34 @@ if (initialUrlState?.params !== undefined && initialUrlState?.params !== null) {
|
|
|
480
497
|
// the same link just restored. Folding the lock into the restored patch keeps
|
|
481
498
|
// it to one `replaceState`, and leaves the effect's first run a no-op.
|
|
482
499
|
const initialLockedType = normalizeContentListTypeLock(untrack(() => type));
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
500
|
+
const initialTrashMode = untrack(() => lifecycleMode) === 'trash';
|
|
501
|
+
const lockedFilters = [...(reading.state.filters ?? [])].filter(
|
|
502
|
+
(filter) =>
|
|
503
|
+
(initialLockedType === null ||
|
|
504
|
+
filter.columnId !== CONTENT_LIST_TYPE_FILTER_ID) &&
|
|
505
|
+
(!initialTrashMode ||
|
|
506
|
+
filter.columnId !== CONTENT_LIST_STATUS_FILTER_ID),
|
|
507
|
+
);
|
|
508
|
+
if (initialLockedType !== null) {
|
|
509
|
+
lockedFilters.push({
|
|
510
|
+
columnId: CONTENT_LIST_TYPE_FILTER_ID,
|
|
511
|
+
operator: 'equals',
|
|
512
|
+
value: initialLockedType,
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
if (initialTrashMode) {
|
|
516
|
+
lockedFilters.push({
|
|
517
|
+
columnId: CONTENT_LIST_STATUS_FILTER_ID,
|
|
518
|
+
operator: 'equals',
|
|
519
|
+
value: 'deleted',
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
const patch = {
|
|
523
|
+
...reading.state,
|
|
524
|
+
...(initialLockedType !== null || initialTrashMode
|
|
525
|
+
? { filters: lockedFilters }
|
|
526
|
+
: {}),
|
|
527
|
+
};
|
|
499
528
|
applyContentListViewState(controller, patch, restoreOptions);
|
|
500
529
|
restoreDrops = reading.dropped;
|
|
501
530
|
}
|
|
@@ -515,6 +544,7 @@ const queryRequestOptions: ContentListQueryRequestOptions | undefined =
|
|
|
515
544
|
}
|
|
516
545
|
: undefined;
|
|
517
546
|
const serverBacked = queryBinding !== undefined;
|
|
547
|
+
let locallyRemovedLifecycleIds = $state<Set<string>>(new Set());
|
|
518
548
|
|
|
519
549
|
let snapshot = $state(controller.snapshot());
|
|
520
550
|
let viewMode: ContentListViewMode = $state(untrack(() => defaultViewMode));
|
|
@@ -532,6 +562,7 @@ const MAX_DEFERRED_JOB_COMPLETIONS = 50;
|
|
|
532
562
|
let completedJobs = $state<ContentListJob[]>([]);
|
|
533
563
|
let completedJobsOverflowed = $state(false);
|
|
534
564
|
let activeQueryKey = $state<string | undefined>(undefined);
|
|
565
|
+
let lifecycleRefreshPending = $state(false);
|
|
535
566
|
|
|
536
567
|
// Job state is subscribed once so hosts can use a framework-free controller.
|
|
537
568
|
// Only transitions observed after the initial snapshot are completion events;
|
|
@@ -697,8 +728,20 @@ const columnLabels = $derived({
|
|
|
697
728
|
|
|
698
729
|
const queryColumns = $derived(buildContentListColumns(columnLabels));
|
|
699
730
|
const sourceContents = $derived(
|
|
700
|
-
|
|
731
|
+
(queryBinding
|
|
732
|
+
? contentListQueryRowsToContents(queryBinding.rows)
|
|
733
|
+
: contents
|
|
734
|
+
).filter((content) => !locallyRemovedLifecycleIds.has(String(content.id))),
|
|
701
735
|
);
|
|
736
|
+
|
|
737
|
+
$effect(() => {
|
|
738
|
+
if (!queryBinding || refreshing || isLoading) return;
|
|
739
|
+
const removed = locallyRemovedLifecycleIds;
|
|
740
|
+
if (removed.size === 0) return;
|
|
741
|
+
const visible = new Set(queryBinding.rows.map((row) => String(row.id)));
|
|
742
|
+
const retained = new Set([...removed].filter((id) => visible.has(id)));
|
|
743
|
+
if (retained.size !== removed.size) locallyRemovedLifecycleIds = retained;
|
|
744
|
+
});
|
|
702
745
|
const rows = $derived(toContentListRows(sourceContents));
|
|
703
746
|
const visibleRowIds = $derived(
|
|
704
747
|
new Set(rows.filter((row) => row.identified).map((row) => String(row.id))),
|
|
@@ -843,12 +886,38 @@ function refreshQuery(): void {
|
|
|
843
886
|
void queryBinding
|
|
844
887
|
.refresh()
|
|
845
888
|
.then((result) => {
|
|
846
|
-
if (result !== undefined && activeQueryKey === key)
|
|
847
|
-
|
|
889
|
+
if (result !== undefined && activeQueryKey === key) {
|
|
890
|
+
if (executedWorkflowQuery) {
|
|
891
|
+
settleWorkflowQueryResult(
|
|
892
|
+
result,
|
|
893
|
+
executedWorkflowQuery,
|
|
894
|
+
querySignature,
|
|
895
|
+
);
|
|
896
|
+
} else {
|
|
897
|
+
resultNotices = readContentListQueryNotices(result);
|
|
898
|
+
}
|
|
899
|
+
settleLifecycleResult(result, lifecycleQueryRequest, querySignature);
|
|
900
|
+
}
|
|
848
901
|
})
|
|
849
902
|
.catch(() => undefined);
|
|
850
903
|
}
|
|
851
904
|
|
|
905
|
+
function requestLifecycleRefresh(): void {
|
|
906
|
+
if (!queryBinding?.refresh) return;
|
|
907
|
+
if (refreshing || isLoading) {
|
|
908
|
+
lifecycleRefreshPending = true;
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
lifecycleRefreshPending = false;
|
|
912
|
+
refreshQuery();
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
$effect(() => {
|
|
916
|
+
if (!lifecycleRefreshPending || refreshing || isLoading) return;
|
|
917
|
+
lifecycleRefreshPending = false;
|
|
918
|
+
refreshQuery();
|
|
919
|
+
});
|
|
920
|
+
|
|
852
921
|
function settleWorkflowQueryResult(
|
|
853
922
|
result: unknown,
|
|
854
923
|
request: ContentListDataQueryRequest,
|
|
@@ -878,6 +947,27 @@ function settleWorkflowQueryResult(
|
|
|
878
947
|
settledWorkflowRevision = null;
|
|
879
948
|
}
|
|
880
949
|
|
|
950
|
+
function settleLifecycleResult(
|
|
951
|
+
result: unknown,
|
|
952
|
+
request: ContentListDataQueryRequest | undefined,
|
|
953
|
+
signature: string,
|
|
954
|
+
): void {
|
|
955
|
+
if (
|
|
956
|
+
!request ||
|
|
957
|
+
result === null ||
|
|
958
|
+
typeof result !== 'object' ||
|
|
959
|
+
Array.isArray(result)
|
|
960
|
+
) {
|
|
961
|
+
settledLifecycleQuery = undefined;
|
|
962
|
+
settledLifecycleFingerprint = undefined;
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const fingerprint = (result as Record<string, unknown>).queryFingerprint;
|
|
966
|
+
settledLifecycleQuery = request;
|
|
967
|
+
settledLifecycleFingerprint =
|
|
968
|
+
typeof fingerprint === 'string' ? fingerprint : undefined;
|
|
969
|
+
settledSignature = signature;
|
|
970
|
+
}
|
|
881
971
|
/**
|
|
882
972
|
* A retry re-reads the same query, so its answer replaces the rendered rows —
|
|
883
973
|
* and therefore has to replace the completeness flags that describe them too.
|
|
@@ -903,6 +993,7 @@ function retryQuery(): void {
|
|
|
903
993
|
)
|
|
904
994
|
return;
|
|
905
995
|
settleWorkflowQueryResult(result, request, signature);
|
|
996
|
+
settleLifecycleResult(result, lifecycleQueryRequest, signature);
|
|
906
997
|
})
|
|
907
998
|
.catch(() => undefined);
|
|
908
999
|
}
|
|
@@ -930,6 +1021,7 @@ const querySignature = $derived(
|
|
|
930
1021
|
let executedSignature: string | undefined;
|
|
931
1022
|
let executedWorkflowQuery: ContentListDataQueryRequest | null = null;
|
|
932
1023
|
let publishedUrlSignature: string | undefined;
|
|
1024
|
+
let lifecycleQueryRequest: ContentListDataQueryRequest | undefined;
|
|
933
1025
|
|
|
934
1026
|
$effect(() => {
|
|
935
1027
|
const signature = querySignature;
|
|
@@ -976,6 +1068,7 @@ $effect(() => {
|
|
|
976
1068
|
// flags, which the binding itself does not expose.
|
|
977
1069
|
activeQueryKey = contentListQueryRequestKey(translated.request);
|
|
978
1070
|
executedWorkflowQuery = translated.request;
|
|
1071
|
+
lifecycleQueryRequest = translated.request;
|
|
979
1072
|
void queryBinding
|
|
980
1073
|
.execute(translated.request)
|
|
981
1074
|
.then((result) => {
|
|
@@ -985,6 +1078,7 @@ $effect(() => {
|
|
|
985
1078
|
// may be clamped against them and workflows may bind to the exact
|
|
986
1079
|
// settled request.
|
|
987
1080
|
settleWorkflowQueryResult(result, translated.request, signature);
|
|
1081
|
+
settleLifecycleResult(result, translated.request, signature);
|
|
988
1082
|
})
|
|
989
1083
|
.catch(() => undefined);
|
|
990
1084
|
}
|
|
@@ -1124,6 +1218,23 @@ const workflowQueuedJob = $derived(
|
|
|
1124
1218
|
workflowQueuedJobs.find((job) => job.intent === workflowIntentSignature()) ??
|
|
1125
1219
|
workflowQueuedJobs[0],
|
|
1126
1220
|
);
|
|
1221
|
+
const lifecycleViewKey = $derived(
|
|
1222
|
+
JSON.stringify([
|
|
1223
|
+
lifecycleMode,
|
|
1224
|
+
querySignature,
|
|
1225
|
+
[...tableState.selectedRowIds].map(String).sort(),
|
|
1226
|
+
]),
|
|
1227
|
+
);
|
|
1228
|
+
const lifecycleQuery = $derived(
|
|
1229
|
+
serverBacked && settledSignature === querySignature
|
|
1230
|
+
? settledLifecycleQuery
|
|
1231
|
+
: undefined,
|
|
1232
|
+
);
|
|
1233
|
+
const lifecycleExactMatchingCount = $derived(
|
|
1234
|
+
serverBacked && settledSignature === querySignature
|
|
1235
|
+
? contentListQueryExactTotal(queryBinding?.total)
|
|
1236
|
+
: queryRows.length,
|
|
1237
|
+
);
|
|
1127
1238
|
|
|
1128
1239
|
/** Synthetic ids the adapter minted for rows that carry no durable identity. */
|
|
1129
1240
|
const unidentifiedRowKeys = $derived(
|
|
@@ -1153,6 +1264,23 @@ $effect(() => {
|
|
|
1153
1264
|
);
|
|
1154
1265
|
});
|
|
1155
1266
|
|
|
1267
|
+
// Trash is a view, not an editable select value. Keep its status predicate
|
|
1268
|
+
// locked against URL restores and agent-driven filter commands.
|
|
1269
|
+
$effect(() => {
|
|
1270
|
+
if (lifecycleMode !== 'trash') return;
|
|
1271
|
+
if (
|
|
1272
|
+
isContentListFilterExactly(
|
|
1273
|
+
tableState,
|
|
1274
|
+
CONTENT_LIST_STATUS_FILTER_ID,
|
|
1275
|
+
'deleted',
|
|
1276
|
+
)
|
|
1277
|
+
)
|
|
1278
|
+
return;
|
|
1279
|
+
untrack(() =>
|
|
1280
|
+
applyContentListFilter(controller, CONTENT_LIST_STATUS_FILTER_ID, 'deleted'),
|
|
1281
|
+
);
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1156
1284
|
/**
|
|
1157
1285
|
* What each toolbar select may display, and whether it can display the live
|
|
1158
1286
|
* predicate at all.
|
|
@@ -2052,7 +2180,29 @@ function handleFilter(columnId: string, value: string) {
|
|
|
2052
2180
|
}
|
|
2053
2181
|
|
|
2054
2182
|
function rowActions(row: ContentListRow) {
|
|
2055
|
-
return contentListRowActions(row, {
|
|
2183
|
+
return contentListRowActions(row, {
|
|
2184
|
+
getViewHref,
|
|
2185
|
+
canEdit: lifecycleMode !== 'trash',
|
|
2186
|
+
canDelete: lifecycleMode !== 'trash' && lifecycle === undefined,
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
function handleLifecycleComplete(
|
|
2191
|
+
result: import('@happyvertical/smrt-ui/data').DataSurfaceActionResult,
|
|
2192
|
+
) {
|
|
2193
|
+
const removed = new Set(locallyRemovedLifecycleIds);
|
|
2194
|
+
for (const outcome of readContentListLifecycleSummary(result).outcomes) {
|
|
2195
|
+
if (outcome.status === 'accepted') removed.add(String(outcome.rowId));
|
|
2196
|
+
}
|
|
2197
|
+
locallyRemovedLifecycleIds = removed;
|
|
2198
|
+
controller.dispatch({
|
|
2199
|
+
type: 'setSelectedRows',
|
|
2200
|
+
rowIds: reconcileContentListLifecycleSelection(
|
|
2201
|
+
tableState.selectedRowIds,
|
|
2202
|
+
result,
|
|
2203
|
+
),
|
|
2204
|
+
});
|
|
2205
|
+
requestLifecycleRefresh();
|
|
2056
2206
|
}
|
|
2057
2207
|
|
|
2058
2208
|
function viewHref(row: ContentListRow): string | null {
|
|
@@ -2127,7 +2277,11 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
2127
2277
|
</script>
|
|
2128
2278
|
|
|
2129
2279
|
{#snippet tableEmptyState()}
|
|
2130
|
-
<p class="table-empty-state">
|
|
2280
|
+
<p class="table-empty-state">
|
|
2281
|
+
{lifecycleMode === 'trash'
|
|
2282
|
+
? t(M['content.content_list.trash_empty'])
|
|
2283
|
+
: t(M['content.content_list.empty'])}
|
|
2284
|
+
</p>
|
|
2131
2285
|
{/snippet}
|
|
2132
2286
|
|
|
2133
2287
|
{#snippet selectHeader()}
|
|
@@ -2267,6 +2421,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
2267
2421
|
</Select>
|
|
2268
2422
|
{/if}
|
|
2269
2423
|
|
|
2424
|
+
{#if lifecycleMode !== 'trash'}
|
|
2270
2425
|
<Select
|
|
2271
2426
|
aria-label={t(M['content.content_list.filter_status'])}
|
|
2272
2427
|
value={selectedStatus}
|
|
@@ -2289,6 +2444,7 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
2289
2444
|
</option>
|
|
2290
2445
|
{/if}
|
|
2291
2446
|
</Select>
|
|
2447
|
+
{/if}
|
|
2292
2448
|
|
|
2293
2449
|
{#if savedViews}
|
|
2294
2450
|
<div class="saved-views" role="group" aria-label={t(M['content.content_list.saved_views'])}>
|
|
@@ -2568,6 +2724,19 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
2568
2724
|
</div>
|
|
2569
2725
|
{/if}
|
|
2570
2726
|
|
|
2727
|
+
{#if lifecycle}
|
|
2728
|
+
<ContentListLifecyclePanel
|
|
2729
|
+
binding={lifecycle}
|
|
2730
|
+
mode={lifecycleMode}
|
|
2731
|
+
selectedRowIds={tableState.selectedRowIds}
|
|
2732
|
+
query={lifecycleQuery}
|
|
2733
|
+
queryFingerprint={settledLifecycleFingerprint}
|
|
2734
|
+
exactMatchingCount={lifecycleExactMatchingCount}
|
|
2735
|
+
viewKey={lifecycleViewKey}
|
|
2736
|
+
oncomplete={handleLifecycleComplete}
|
|
2737
|
+
/>
|
|
2738
|
+
{/if}
|
|
2739
|
+
|
|
2571
2740
|
{#if workflows && (selectedCount > 0 || workflowError || workflowResult)}
|
|
2572
2741
|
<section class="content-workflows" aria-label={t(M['content.content_list.bulk_workflows'])}>
|
|
2573
2742
|
<Select
|
|
@@ -2711,7 +2880,9 @@ const tableColumns: DataTableColumn<ContentListRow>[] = $derived([
|
|
|
2711
2880
|
</div>
|
|
2712
2881
|
{:else if pageRows.length === 0}
|
|
2713
2882
|
<div class="state-panel empty-state">
|
|
2714
|
-
{
|
|
2883
|
+
{lifecycleMode === 'trash'
|
|
2884
|
+
? t(M['content.content_list.trash_empty'])
|
|
2885
|
+
: t(M['content.content_list.empty'])}
|
|
2715
2886
|
</div>
|
|
2716
2887
|
{:else if viewMode === 'detailed'}
|
|
2717
2888
|
<div class="content-detailed">
|
|
@@ -25,6 +25,7 @@ export interface ContentListUrlStateBinding {
|
|
|
25
25
|
}
|
|
26
26
|
import type { Snippet } from 'svelte';
|
|
27
27
|
import type { ContentData } from '../../mock-smrt-client.js';
|
|
28
|
+
import type { ContentListLifecycleBinding } from '../content-list-lifecycle.js';
|
|
28
29
|
import { type ContentListDataSurface, type ContentListViewMode } from '../content-list-controller.js';
|
|
29
30
|
import { type ContentListQuerySource } from '../content-list-query.js';
|
|
30
31
|
import { type ContentListJobBinding } from '../content-list-runtime.js';
|
|
@@ -76,6 +77,10 @@ interface Props {
|
|
|
76
77
|
jobs?: ContentListJobBinding;
|
|
77
78
|
/** Opt-in, authenticated preview/apply client for bulk workflows (#2453). */
|
|
78
79
|
workflows?: ContentListWorkflowBinding;
|
|
80
|
+
/** Opt-in, server-authoritative trash/restore/permanent-delete lifecycle. */
|
|
81
|
+
lifecycle?: ContentListLifecycleBinding;
|
|
82
|
+
/** Locks the status query to deleted content and exposes trash actions. */
|
|
83
|
+
lifecycleMode?: 'active' | 'trash';
|
|
79
84
|
}
|
|
80
85
|
declare const ContentList: import("svelte").Component<Props, {}, "">;
|
|
81
86
|
type ContentList = ReturnType<typeof ContentList>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentList.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentList.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,IAAI,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACvG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,6BAA6B,KACjC,IAAI,CAAC;IACV,uEAAuE;IACvE,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC;AAcD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EASL,KAAK,sBAAsB,EAE3B,KAAK,mBAAmB,EAiBzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAOL,KAAK,sBAAsB,EAU5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,qBAAqB,EAG3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,yBAAyB,EAG/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,0BAA0B,EAOhC,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"ContentList.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentList.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,IAAI,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACvG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,6BAA6B,KACjC,IAAI,CAAC;IACV,uEAAuE;IACvE,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC;AAcD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAKhF,OAAO,EASL,KAAK,sBAAsB,EAE3B,KAAK,mBAAmB,EAiBzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAOL,KAAK,sBAAsB,EAU5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,qBAAqB,EAG3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,KAAK,yBAAyB,EAG/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,0BAA0B,EAOhC,MAAM,8BAA8B,CAAC;AAiBtC,UAAU,KAAK;IACb,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,6DAA6D;IAC7D,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,MAAM,GAAG,IAAI,CAAC;IACtD,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,0BAA0B,CAAC;IACtC,oFAAoF;IACpF,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,6EAA6E;IAC7E,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,0BAA0B,CAAC;IACvC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC,2EAA2E;IAC3E,aAAa,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CACpC;AAgnFD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|