@agent-native/creative-context 0.7.18 → 0.7.19-nightly-20260901231700
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/actions/list-creative-contexts.d.ts +1 -0
- package/dist/client/CreativeContextPanel.d.ts.map +1 -1
- package/dist/client/CreativeContextPanel.js +3 -1
- package/dist/client/CreativeContextPanel.js.map +1 -1
- package/dist/client/CreativeContextShareTab.d.ts.map +1 -1
- package/dist/client/CreativeContextShareTab.js +90 -55
- package/dist/client/CreativeContextShareTab.js.map +1 -1
- package/dist/client/actions.d.ts +1 -0
- package/dist/client/actions.d.ts.map +1 -1
- package/dist/client/actions.js.map +1 -1
- package/dist/client/messages.d.ts +28 -1
- package/dist/client/messages.d.ts.map +1 -1
- package/dist/client/messages.js +275 -0
- package/dist/client/messages.js.map +1 -1
- package/dist/store/contexts.d.ts +1 -0
- package/dist/store/contexts.d.ts.map +1 -1
- package/dist/store/contexts.js +2 -0
- package/dist/store/contexts.js.map +1 -1
- package/package.json +3 -3
- package/src/client/CreativeContextPanel.tsx +3 -1
- package/src/client/CreativeContextShareTab.tsx +248 -216
- package/src/client/actions.ts +1 -0
- package/src/client/messages.ts +326 -1
- package/src/store/contexts.ts +3 -0
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
+
import { cn } from "@agent-native/toolkit";
|
|
3
|
+
import { ShareDisclosureSection } from "@agent-native/toolkit/sharing";
|
|
1
4
|
import {
|
|
2
5
|
Badge,
|
|
3
6
|
Button,
|
|
@@ -10,13 +13,8 @@ import {
|
|
|
10
13
|
SelectValue,
|
|
11
14
|
Sheet,
|
|
12
15
|
SheetContent,
|
|
13
|
-
SheetDescription,
|
|
14
16
|
SheetHeader,
|
|
15
17
|
SheetTitle,
|
|
16
|
-
Tabs,
|
|
17
|
-
TabsContent,
|
|
18
|
-
TabsList,
|
|
19
|
-
TabsTrigger,
|
|
20
18
|
Textarea,
|
|
21
19
|
} from "@agent-native/toolkit/ui";
|
|
22
20
|
import {
|
|
@@ -24,7 +22,6 @@ import {
|
|
|
24
22
|
IconFileText,
|
|
25
23
|
IconLink,
|
|
26
24
|
IconPlus,
|
|
27
|
-
IconShieldCheck,
|
|
28
25
|
IconX,
|
|
29
26
|
} from "@tabler/icons-react";
|
|
30
27
|
import { useEffect, useState } from "react";
|
|
@@ -38,7 +35,6 @@ import {
|
|
|
38
35
|
useManageCreativeContext,
|
|
39
36
|
type CreativeContextMembership,
|
|
40
37
|
type CreativeContextMembershipRank,
|
|
41
|
-
type CreativeContextPolicy,
|
|
42
38
|
type CreativeContextSummary,
|
|
43
39
|
} from "./actions.js";
|
|
44
40
|
|
|
@@ -83,6 +79,7 @@ export function normalizeCreativeContextResources(
|
|
|
83
79
|
}
|
|
84
80
|
|
|
85
81
|
const VISIBILITY_RANK = { private: 0, org: 1, public: 2 } as const;
|
|
82
|
+
type CreativeContextTranslate = ReturnType<typeof useT>;
|
|
86
83
|
|
|
87
84
|
export function requiresBroaderPublication(
|
|
88
85
|
resource: CreativeContextResourceDescriptor,
|
|
@@ -111,27 +108,6 @@ export function creativeContextSafePreviewUrl(url: string | undefined) {
|
|
|
111
108
|
}
|
|
112
109
|
}
|
|
113
110
|
|
|
114
|
-
function policyCopy(policy: CreativeContextPolicy) {
|
|
115
|
-
switch (policy) {
|
|
116
|
-
case "review":
|
|
117
|
-
return "New resources wait for reviewer approval before they are reused.";
|
|
118
|
-
case "admins-only":
|
|
119
|
-
return "Only administrators can approve or remove resources.";
|
|
120
|
-
default:
|
|
121
|
-
return "New resources are published after submission.";
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function formatResourceTimestamp(value: string | undefined) {
|
|
126
|
-
if (!value) return null;
|
|
127
|
-
const date = new Date(value);
|
|
128
|
-
if (!Number.isFinite(date.getTime())) return null;
|
|
129
|
-
return new Intl.DateTimeFormat(undefined, {
|
|
130
|
-
dateStyle: "medium",
|
|
131
|
-
timeStyle: "short",
|
|
132
|
-
}).format(date);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
111
|
function ResourcePreview({
|
|
136
112
|
resource,
|
|
137
113
|
}: {
|
|
@@ -143,13 +119,13 @@ function ResourcePreview({
|
|
|
143
119
|
<img
|
|
144
120
|
src={imageUrl}
|
|
145
121
|
alt={resource.preview?.alt ?? ""}
|
|
146
|
-
className="size-
|
|
122
|
+
className="size-9 rounded-md border border-border object-cover"
|
|
147
123
|
/>
|
|
148
124
|
);
|
|
149
125
|
}
|
|
150
126
|
return (
|
|
151
|
-
<div className="flex size-
|
|
152
|
-
<IconFileText className="size-
|
|
127
|
+
<div className="flex size-9 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground">
|
|
128
|
+
<IconFileText className="size-4" />
|
|
153
129
|
</div>
|
|
154
130
|
);
|
|
155
131
|
}
|
|
@@ -210,6 +186,7 @@ export async function submitCreativeContextResources({
|
|
|
210
186
|
|
|
211
187
|
function MembershipRow({
|
|
212
188
|
membership,
|
|
189
|
+
t,
|
|
213
190
|
updateAvailable,
|
|
214
191
|
canReview,
|
|
215
192
|
canWithdraw,
|
|
@@ -218,6 +195,7 @@ function MembershipRow({
|
|
|
218
195
|
onAction,
|
|
219
196
|
}: {
|
|
220
197
|
membership: CreativeContextMembership;
|
|
198
|
+
t: CreativeContextTranslate;
|
|
221
199
|
updateAvailable: boolean;
|
|
222
200
|
canReview: boolean;
|
|
223
201
|
canWithdraw: boolean;
|
|
@@ -228,45 +206,71 @@ function MembershipRow({
|
|
|
228
206
|
) => void;
|
|
229
207
|
}) {
|
|
230
208
|
const pending = Boolean(membership.pendingSubmissionId);
|
|
209
|
+
const rankLabel = {
|
|
210
|
+
canonical: t("creativeContext.share.canonical", {
|
|
211
|
+
defaultValue: "Canonical",
|
|
212
|
+
}),
|
|
213
|
+
exemplar: t("creativeContext.exemplar"),
|
|
214
|
+
normal: t("creativeContext.share.reference", {
|
|
215
|
+
defaultValue: "Reference",
|
|
216
|
+
}),
|
|
217
|
+
}[membership.rank];
|
|
231
218
|
return (
|
|
232
|
-
<article className="flex flex-wrap items-center justify-between gap-
|
|
233
|
-
<div>
|
|
234
|
-
<
|
|
235
|
-
{pending
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
219
|
+
<article className="flex flex-wrap items-center justify-between gap-2 border-t border-border/60 py-2.5 first:border-t-0">
|
|
220
|
+
<div className="flex min-w-0 items-center gap-2">
|
|
221
|
+
<Badge variant={pending ? "outline" : "secondary"} className="shrink-0">
|
|
222
|
+
{pending
|
|
223
|
+
? t("creativeContext.share.pendingResource", {
|
|
224
|
+
defaultValue: "Pending resource",
|
|
225
|
+
})
|
|
226
|
+
: t("creativeContext.share.publishedResource", {
|
|
227
|
+
defaultValue: "Published resource",
|
|
228
|
+
})}
|
|
229
|
+
</Badge>
|
|
230
|
+
<span className="min-w-0 truncate text-xs text-muted-foreground">
|
|
231
|
+
{membership.purpose ?? rankLabel}
|
|
232
|
+
</span>
|
|
233
|
+
{updateAvailable ? (
|
|
234
|
+
<span className="shrink-0 text-xs text-muted-foreground">
|
|
235
|
+
{t("creativeContext.updateAvailable")}
|
|
236
|
+
</span>
|
|
237
|
+
) : null}
|
|
241
238
|
</div>
|
|
242
|
-
<div className="flex flex-wrap gap-
|
|
239
|
+
<div className="flex flex-wrap justify-end gap-1">
|
|
243
240
|
{pending ? (
|
|
244
|
-
<Badge variant="outline">
|
|
241
|
+
<Badge variant="outline">
|
|
242
|
+
{t("creativeContext.share.pendingReview", {
|
|
243
|
+
defaultValue: "Pending review",
|
|
244
|
+
})}
|
|
245
|
+
</Badge>
|
|
245
246
|
) : (
|
|
246
|
-
<
|
|
247
|
+
<span className="sr-only">
|
|
248
|
+
{t("creativeContext.share.published", {
|
|
249
|
+
defaultValue: "Published",
|
|
250
|
+
})}
|
|
251
|
+
</span>
|
|
247
252
|
)}
|
|
248
|
-
{updateAvailable ? (
|
|
249
|
-
<Badge variant="outline">Update available</Badge>
|
|
250
|
-
) : null}
|
|
251
253
|
{pending && canWithdraw ? (
|
|
252
254
|
<Button
|
|
253
255
|
type="button"
|
|
254
256
|
variant="outline"
|
|
255
257
|
size="sm"
|
|
258
|
+
className="h-8 px-2 text-xs"
|
|
256
259
|
disabled={busy}
|
|
257
260
|
onClick={() => onAction("withdraw")}
|
|
258
261
|
>
|
|
259
|
-
Withdraw
|
|
262
|
+
{t("creativeContext.share.withdraw", { defaultValue: "Withdraw" })}
|
|
260
263
|
</Button>
|
|
261
264
|
) : null}
|
|
262
265
|
{pending && canReview ? (
|
|
263
266
|
<Button
|
|
264
267
|
type="button"
|
|
265
268
|
size="sm"
|
|
269
|
+
className="h-8 px-2 text-xs"
|
|
266
270
|
disabled={busy}
|
|
267
271
|
onClick={() => onAction("approve")}
|
|
268
272
|
>
|
|
269
|
-
<IconCheck />
|
|
273
|
+
<IconCheck /> {t("creativeContext.approve")}
|
|
270
274
|
</Button>
|
|
271
275
|
) : null}
|
|
272
276
|
{pending && canReview ? (
|
|
@@ -274,10 +278,13 @@ function MembershipRow({
|
|
|
274
278
|
type="button"
|
|
275
279
|
size="sm"
|
|
276
280
|
variant="outline"
|
|
281
|
+
className="h-8 px-2 text-xs"
|
|
277
282
|
disabled={busy}
|
|
278
283
|
onClick={() => onAction("request-changes")}
|
|
279
284
|
>
|
|
280
|
-
|
|
285
|
+
{t("creativeContext.share.requestChanges", {
|
|
286
|
+
defaultValue: "Request changes",
|
|
287
|
+
})}
|
|
281
288
|
</Button>
|
|
282
289
|
) : null}
|
|
283
290
|
{canRemove ? (
|
|
@@ -285,10 +292,12 @@ function MembershipRow({
|
|
|
285
292
|
type="button"
|
|
286
293
|
size="sm"
|
|
287
294
|
variant="ghost"
|
|
295
|
+
className="h-8 px-2 text-xs"
|
|
288
296
|
disabled={busy}
|
|
289
297
|
onClick={() => onAction("remove")}
|
|
290
298
|
>
|
|
291
|
-
<IconX />
|
|
299
|
+
<IconX />{" "}
|
|
300
|
+
{t("creativeContext.share.remove", { defaultValue: "Remove" })}
|
|
292
301
|
</Button>
|
|
293
302
|
) : null}
|
|
294
303
|
</div>
|
|
@@ -299,16 +308,24 @@ function MembershipRow({
|
|
|
299
308
|
function ContextSelect({
|
|
300
309
|
contexts,
|
|
301
310
|
contextId,
|
|
311
|
+
t,
|
|
302
312
|
onValueChange,
|
|
313
|
+
disabled = false,
|
|
303
314
|
}: {
|
|
304
315
|
contexts: CreativeContextSummary[];
|
|
305
316
|
contextId: string;
|
|
317
|
+
t: CreativeContextTranslate;
|
|
306
318
|
onValueChange: (value: string) => void;
|
|
319
|
+
disabled?: boolean;
|
|
307
320
|
}) {
|
|
308
321
|
return (
|
|
309
322
|
<Select value={contextId} onValueChange={onValueChange}>
|
|
310
|
-
<SelectTrigger>
|
|
311
|
-
<SelectValue
|
|
323
|
+
<SelectTrigger className="w-full" disabled={disabled}>
|
|
324
|
+
<SelectValue
|
|
325
|
+
placeholder={t("creativeContext.share.chooseContext", {
|
|
326
|
+
defaultValue: "Choose a context",
|
|
327
|
+
})}
|
|
328
|
+
/>
|
|
312
329
|
</SelectTrigger>
|
|
313
330
|
{/* This tab is embedded inside ShareButton's high z-index popover
|
|
314
331
|
(see z-[100010]+ overrides in design/content/slides toolbars).
|
|
@@ -332,6 +349,7 @@ export function CreativeContextShareTab({
|
|
|
332
349
|
resources,
|
|
333
350
|
className,
|
|
334
351
|
}: CreativeContextShareTabProps) {
|
|
352
|
+
const t = useT();
|
|
335
353
|
const contextsQuery = useCreativeContexts();
|
|
336
354
|
const manageContext = useManageCreativeContext();
|
|
337
355
|
const manageMembership = useManageContextMembership();
|
|
@@ -341,7 +359,6 @@ export function CreativeContextShareTab({
|
|
|
341
359
|
resources,
|
|
342
360
|
);
|
|
343
361
|
const primaryResource = selectedResources[0];
|
|
344
|
-
const updatedAt = formatResourceTimestamp(primaryResource?.updatedAt);
|
|
345
362
|
const [contextId, setContextId] = useState("");
|
|
346
363
|
const membershipsQuery = useContextMemberships(
|
|
347
364
|
contextId ? { contextId } : null,
|
|
@@ -360,7 +377,9 @@ export function CreativeContextShareTab({
|
|
|
360
377
|
useState(false);
|
|
361
378
|
const busy = manageContext.isPending || manageMembership.isPending;
|
|
362
379
|
const selectedContext = contexts.find((context) => context.id === contextId);
|
|
363
|
-
const canCreateContext =
|
|
380
|
+
const canCreateContext =
|
|
381
|
+
contextsQuery.data?.canCreateContext === true &&
|
|
382
|
+
contexts.some((context) => context.access.canAdmin);
|
|
364
383
|
const needsBroaderPublicationConfirmation = selectedResources.some((item) =>
|
|
365
384
|
requiresBroaderPublication(item, selectedContext),
|
|
366
385
|
);
|
|
@@ -398,12 +417,28 @@ export function CreativeContextShareTab({
|
|
|
398
417
|
setConfirmedBroaderPublication(false);
|
|
399
418
|
setSubmitSummary(
|
|
400
419
|
result.failed
|
|
401
|
-
?
|
|
402
|
-
|
|
420
|
+
? t("creativeContext.share.partialSubmission", {
|
|
421
|
+
submitted: result.submitted,
|
|
422
|
+
failed: result.failed,
|
|
423
|
+
defaultValue:
|
|
424
|
+
"{{submitted}} submitted; {{failed}} could not be submitted.",
|
|
425
|
+
})
|
|
426
|
+
: t(
|
|
427
|
+
result.submitted === 1
|
|
428
|
+
? "creativeContext.share.resourceSubmitted"
|
|
429
|
+
: "creativeContext.share.resourcesSubmitted",
|
|
430
|
+
{
|
|
431
|
+
count: result.submitted,
|
|
432
|
+
defaultValue:
|
|
433
|
+
result.submitted === 1
|
|
434
|
+
? "{{count}} resource submitted."
|
|
435
|
+
: "{{count}} resources submitted.",
|
|
436
|
+
},
|
|
437
|
+
),
|
|
403
438
|
);
|
|
404
439
|
await refresh();
|
|
405
440
|
} catch {
|
|
406
|
-
setError("
|
|
441
|
+
setError(t("creativeContext.submitUpdateFailed"));
|
|
407
442
|
}
|
|
408
443
|
}
|
|
409
444
|
|
|
@@ -421,7 +456,7 @@ export function CreativeContextShareTab({
|
|
|
421
456
|
await contextsQuery.refetch();
|
|
422
457
|
if (result.context?.id) setContextId(result.context.id);
|
|
423
458
|
} catch {
|
|
424
|
-
setError("
|
|
459
|
+
setError(t("creativeContext.saveFailed"));
|
|
425
460
|
}
|
|
426
461
|
}
|
|
427
462
|
|
|
@@ -439,97 +474,83 @@ export function CreativeContextShareTab({
|
|
|
439
474
|
});
|
|
440
475
|
await refresh();
|
|
441
476
|
} catch {
|
|
442
|
-
setError("
|
|
477
|
+
setError(t("creativeContext.saveFailed"));
|
|
443
478
|
}
|
|
444
479
|
}
|
|
445
480
|
|
|
446
481
|
return (
|
|
447
|
-
<section
|
|
448
|
-
|
|
449
|
-
|
|
482
|
+
<section
|
|
483
|
+
className={cn("space-y-3", className)}
|
|
484
|
+
aria-label={t("creativeContext.share.title", {
|
|
485
|
+
defaultValue: "Creative context",
|
|
486
|
+
})}
|
|
487
|
+
>
|
|
488
|
+
{primaryResource ? (
|
|
489
|
+
<div className="flex min-w-0 items-center gap-2 border-b border-border/70 pb-3">
|
|
450
490
|
<ResourcePreview resource={primaryResource} />
|
|
451
|
-
|
|
452
|
-
<div className="min-w-0">
|
|
453
|
-
<p className="truncate text-sm font-medium">
|
|
454
|
-
{selectedResources.length === 1
|
|
455
|
-
? primaryResource?.title
|
|
456
|
-
: `${selectedResources.length} selected resources`}
|
|
457
|
-
</p>
|
|
458
|
-
<p className="mt-0.5 text-xs text-muted-foreground">
|
|
491
|
+
<p className="min-w-0 truncate text-sm font-medium">
|
|
459
492
|
{selectedResources.length === 1
|
|
460
|
-
?
|
|
461
|
-
|
|
462
|
-
|
|
493
|
+
? primaryResource.title
|
|
494
|
+
: t("creativeContext.share.selectedResources", {
|
|
495
|
+
count: selectedResources.length,
|
|
496
|
+
defaultValue: "{{count}} selected resources",
|
|
497
|
+
})}
|
|
463
498
|
</p>
|
|
464
|
-
{selectedResources.length === 1 && updatedAt ? (
|
|
465
|
-
<p className="mt-0.5 text-xs text-muted-foreground">
|
|
466
|
-
Current version · {updatedAt}
|
|
467
|
-
</p>
|
|
468
|
-
) : null}
|
|
469
499
|
</div>
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
<
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
)
|
|
489
|
-
<
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
{
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
<p className="text-sm font-medium">
|
|
525
|
-
{memberships.some((membership) => membership.publishedItem)
|
|
526
|
-
? "Submit update for "
|
|
527
|
-
: "Add "}
|
|
528
|
-
{selectedResources.length === 1
|
|
529
|
-
? "this resource"
|
|
530
|
-
: `${selectedResources.length} resources`}
|
|
531
|
-
</p>
|
|
532
|
-
<div className="mt-2 grid gap-2 sm:grid-cols-2">
|
|
500
|
+
) : null}
|
|
501
|
+
{contexts.length ? (
|
|
502
|
+
<ContextSelect
|
|
503
|
+
contexts={contexts}
|
|
504
|
+
contextId={contextId}
|
|
505
|
+
t={t}
|
|
506
|
+
onValueChange={setContextId}
|
|
507
|
+
disabled={busy}
|
|
508
|
+
/>
|
|
509
|
+
) : (
|
|
510
|
+
<p className="text-sm text-muted-foreground">
|
|
511
|
+
{t("creativeContext.share.noContexts", {
|
|
512
|
+
defaultValue: "No contexts are available yet.",
|
|
513
|
+
})}
|
|
514
|
+
</p>
|
|
515
|
+
)}
|
|
516
|
+
{contextId && selectedResources.length === 1 && memberships.length ? (
|
|
517
|
+
<div>
|
|
518
|
+
{memberships.map((membership) => (
|
|
519
|
+
<MembershipRow
|
|
520
|
+
key={membership.id}
|
|
521
|
+
membership={membership}
|
|
522
|
+
t={t}
|
|
523
|
+
updateAvailable={Boolean(
|
|
524
|
+
primaryResource?.updatedAt &&
|
|
525
|
+
membership.publishedItem?.sourceModifiedAt &&
|
|
526
|
+
primaryResource.updatedAt !==
|
|
527
|
+
membership.publishedItem.sourceModifiedAt,
|
|
528
|
+
)}
|
|
529
|
+
canReview={selectedContext?.access.canReview === true}
|
|
530
|
+
canWithdraw={
|
|
531
|
+
selectedContext?.access.canReview === true ||
|
|
532
|
+
selectedContext?.access.canSubmit === true
|
|
533
|
+
}
|
|
534
|
+
canRemove={selectedContext?.access.canAdmin === true}
|
|
535
|
+
busy={busy}
|
|
536
|
+
onAction={(operation) => void act(membership.id, operation)}
|
|
537
|
+
/>
|
|
538
|
+
))}
|
|
539
|
+
</div>
|
|
540
|
+
) : null}
|
|
541
|
+
{contextId && selectedResources.length ? (
|
|
542
|
+
<div className="border-t border-border/60 pt-3">
|
|
543
|
+
<div className="flex items-start gap-2">
|
|
544
|
+
<ShareDisclosureSection
|
|
545
|
+
label={
|
|
546
|
+
memberships.some((membership) => membership.publishedItem)
|
|
547
|
+
? t("creativeContext.submitUpdate")
|
|
548
|
+
: t("creativeContext.addToContext")
|
|
549
|
+
}
|
|
550
|
+
className="min-w-0 flex-1"
|
|
551
|
+
contentClassName="space-y-2"
|
|
552
|
+
>
|
|
553
|
+
<div className="grid gap-2 sm:grid-cols-2">
|
|
533
554
|
<Select
|
|
534
555
|
value={rank}
|
|
535
556
|
onValueChange={(value) =>
|
|
@@ -543,94 +564,103 @@ export function CreativeContextShareTab({
|
|
|
543
564
|
data-agent-native-share-overlay=""
|
|
544
565
|
className="z-[100020]"
|
|
545
566
|
>
|
|
546
|
-
<SelectItem value="canonical">
|
|
547
|
-
|
|
548
|
-
|
|
567
|
+
<SelectItem value="canonical">
|
|
568
|
+
{t("creativeContext.share.canonical", {
|
|
569
|
+
defaultValue: "Canonical",
|
|
570
|
+
})}
|
|
571
|
+
</SelectItem>
|
|
572
|
+
<SelectItem value="exemplar">
|
|
573
|
+
{t("creativeContext.exemplar")}
|
|
574
|
+
</SelectItem>
|
|
575
|
+
<SelectItem value="normal">
|
|
576
|
+
{t("creativeContext.share.reference", {
|
|
577
|
+
defaultValue: "Reference",
|
|
578
|
+
})}
|
|
579
|
+
</SelectItem>
|
|
549
580
|
</SelectContent>
|
|
550
581
|
</Select>
|
|
551
582
|
<Input
|
|
552
583
|
value={purpose}
|
|
553
584
|
onChange={(event) => setPurpose(event.target.value)}
|
|
554
|
-
placeholder="
|
|
585
|
+
placeholder={t("creativeContext.share.purpose", {
|
|
586
|
+
defaultValue: "Purpose",
|
|
587
|
+
})}
|
|
555
588
|
/>
|
|
556
589
|
</div>
|
|
557
590
|
<Textarea
|
|
558
|
-
className="mt-2"
|
|
559
591
|
value={note}
|
|
560
592
|
onChange={(event) => setNote(event.target.value)}
|
|
561
|
-
placeholder="
|
|
593
|
+
placeholder={t("creativeContext.share.reviewerNote", {
|
|
594
|
+
defaultValue: "Note for reviewers",
|
|
595
|
+
})}
|
|
562
596
|
rows={2}
|
|
563
597
|
/>
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
(
|
|
587
|
-
!confirmedBroaderPublication)
|
|
598
|
+
</ShareDisclosureSection>
|
|
599
|
+
<Button
|
|
600
|
+
type="button"
|
|
601
|
+
size="sm"
|
|
602
|
+
className="shrink-0"
|
|
603
|
+
disabled={
|
|
604
|
+
busy ||
|
|
605
|
+
selectedContext?.access.canSubmit !== true ||
|
|
606
|
+
(needsBroaderPublicationConfirmation &&
|
|
607
|
+
!confirmedBroaderPublication)
|
|
608
|
+
}
|
|
609
|
+
onClick={() => void submit()}
|
|
610
|
+
>
|
|
611
|
+
<IconLink />{" "}
|
|
612
|
+
{t("creativeContext.share.submit", { defaultValue: "Submit" })}
|
|
613
|
+
</Button>
|
|
614
|
+
</div>
|
|
615
|
+
{needsBroaderPublicationConfirmation ? (
|
|
616
|
+
<label className="flex items-start gap-2 text-xs text-muted-foreground">
|
|
617
|
+
<Checkbox
|
|
618
|
+
checked={confirmedBroaderPublication}
|
|
619
|
+
onCheckedChange={(checked) =>
|
|
620
|
+
setConfirmedBroaderPublication(checked === true)
|
|
588
621
|
}
|
|
589
|
-
onClick={() => void submit()}
|
|
590
|
-
>
|
|
591
|
-
<IconLink /> Submit
|
|
592
|
-
</Button>
|
|
593
|
-
</div>
|
|
594
|
-
) : null}
|
|
595
|
-
{canCreateContext ? (
|
|
596
|
-
<div className="flex gap-2 border-t border-border/60 pt-3">
|
|
597
|
-
<Input
|
|
598
|
-
value={newContextName}
|
|
599
|
-
onChange={(event) => setNewContextName(event.target.value)}
|
|
600
|
-
placeholder="New context name"
|
|
601
622
|
/>
|
|
602
|
-
<
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
<IconPlus /> New
|
|
610
|
-
</Button>
|
|
611
|
-
</div>
|
|
623
|
+
<span>
|
|
624
|
+
{t("creativeContext.share.broaderPublication", {
|
|
625
|
+
defaultValue:
|
|
626
|
+
"This context is shared more broadly than this resource. Publishing creates a governed copy available to the context's audience.",
|
|
627
|
+
})}
|
|
628
|
+
</span>
|
|
629
|
+
</label>
|
|
612
630
|
) : null}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
className="space-y-3 text-sm text-muted-foreground"
|
|
631
|
+
</div>
|
|
632
|
+
) : null}
|
|
633
|
+
{canCreateContext ? (
|
|
634
|
+
<ShareDisclosureSection
|
|
635
|
+
label={t("creativeContext.share.newContextName", {
|
|
636
|
+
defaultValue: "New context name",
|
|
637
|
+
})}
|
|
621
638
|
>
|
|
622
|
-
<div className="flex gap-2
|
|
623
|
-
<
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
639
|
+
<div className="flex gap-2">
|
|
640
|
+
<Input
|
|
641
|
+
value={newContextName}
|
|
642
|
+
onChange={(event) => setNewContextName(event.target.value)}
|
|
643
|
+
placeholder={t("creativeContext.share.newContextName", {
|
|
644
|
+
defaultValue: "New context name",
|
|
645
|
+
})}
|
|
646
|
+
/>
|
|
647
|
+
<Button
|
|
648
|
+
type="button"
|
|
649
|
+
variant="outline"
|
|
650
|
+
size="sm"
|
|
651
|
+
disabled={busy || !newContextName.trim()}
|
|
652
|
+
onClick={() => void createContext()}
|
|
653
|
+
>
|
|
654
|
+
<IconPlus />{" "}
|
|
655
|
+
{t("creativeContext.share.new", { defaultValue: "New" })}
|
|
656
|
+
</Button>
|
|
628
657
|
</div>
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
658
|
+
</ShareDisclosureSection>
|
|
659
|
+
) : null}
|
|
660
|
+
{error ? <p className="text-xs text-destructive">{error}</p> : null}
|
|
661
|
+
{submitSummary ? (
|
|
662
|
+
<p className="text-xs text-muted-foreground">{submitSummary}</p>
|
|
663
|
+
) : null}
|
|
634
664
|
</section>
|
|
635
665
|
);
|
|
636
666
|
}
|
|
@@ -645,14 +675,16 @@ export function CreativeContextShareSheet({
|
|
|
645
675
|
open: boolean;
|
|
646
676
|
onOpenChange: (open: boolean) => void;
|
|
647
677
|
}) {
|
|
678
|
+
const t = useT();
|
|
648
679
|
return (
|
|
649
680
|
<Sheet open={open} onOpenChange={onOpenChange}>
|
|
650
681
|
<SheetContent side="right" className="w-full overflow-y-auto sm:max-w-lg">
|
|
651
682
|
<SheetHeader>
|
|
652
|
-
<SheetTitle>
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
683
|
+
<SheetTitle>
|
|
684
|
+
{t("creativeContext.share.title", {
|
|
685
|
+
defaultValue: "Creative context",
|
|
686
|
+
})}
|
|
687
|
+
</SheetTitle>
|
|
656
688
|
</SheetHeader>
|
|
657
689
|
<CreativeContextShareTab
|
|
658
690
|
resource={resource}
|