@agimon-ai/po-template-advanced 0.0.0-alpha.21 → 0.0.0-alpha.22
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/extensions/native.mjs +404 -11
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/web.mjs +9 -12
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/webClient.cjs +9 -12
- package/dist/webClient.cjs.map +1 -1
- package/dist/webClient.mjs +9 -12
- package/dist/webClient.mjs.map +1 -1
- package/package.json +7 -7
|
@@ -3,10 +3,23 @@ import { View } from "react-native-unistyles/components/native/View";
|
|
|
3
3
|
import { Text } from "react-native-unistyles/components/native/Text";
|
|
4
4
|
import { ScrollView } from "react-native-unistyles/components/native/ScrollView";
|
|
5
5
|
import { Pressable } from "react-native-unistyles/components/native/Pressable";
|
|
6
|
-
import { ActivityIcon, AlertIcon, Badge, BranchIcon, Button, EmptyState, FolderIcon, ForkIcon, Input, KebabIcon, Label, ListRow, PlusIcon, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, Spinner, UsersIcon, fontOf } from "@agimon-ai/po-native-components";
|
|
6
|
+
import { ActivityIcon, AlertIcon, Badge, BranchIcon, Button, CheckIcon, EditIcon, EmptyState, FolderIcon, ForkIcon, Input, KebabIcon, Label, ListRow, PlusIcon, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, Spinner, TrashIcon, UsersIcon, fontOf } from "@agimon-ai/po-native-components";
|
|
7
7
|
import { useEffect, useState } from "react";
|
|
8
8
|
import { StyleSheet } from "react-native-unistyles";
|
|
9
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
/** Every group some session uses, in rail order, with the other sessions in it. */
|
|
11
|
+
function sessionGroupOptions(sessions, editedId, extra = []) {
|
|
12
|
+
return [.../* @__PURE__ */ new Set([...sessions.flatMap((session) => session.groups ?? []), ...extra])].map((name) => ({
|
|
13
|
+
name,
|
|
14
|
+
members: sessions.filter((session) => session.id !== editedId && session.groups?.includes(name) === true).map((session) => session.name || "Untitled")
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
/** Why a typed name cannot become a group, or undefined when it can. */
|
|
18
|
+
function createProblem(name, count) {
|
|
19
|
+
if (name.length > 32) return `group names are at most ${String(32)} characters.`;
|
|
20
|
+
if (count >= 8) return `a session can belong to at most ${String(8)} groups.`;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
10
23
|
//#region src/extensions/(frontend)/template/_components/AdvancedSessionMenus.native.tsx
|
|
11
24
|
function Items({ items }) {
|
|
12
25
|
return /* @__PURE__ */ jsx(View, {
|
|
@@ -31,8 +44,8 @@ function Items({ items }) {
|
|
|
31
44
|
}, item.label))
|
|
32
45
|
});
|
|
33
46
|
}
|
|
34
|
-
/** A session card's ⋮: the cockpit's rename, resume, restart and remove, with remove confirmed first. */
|
|
35
|
-
function SessionMenuSheet({ session, actions, onClose }) {
|
|
47
|
+
/** A session card's ⋮: the cockpit's rename, groups, resume, restart and remove, with remove confirmed first. */
|
|
48
|
+
function SessionMenuSheet({ session, actions, onGroups, onClose }) {
|
|
36
49
|
const [step, setStep] = useState("menu");
|
|
37
50
|
const [draft, setDraft] = useState("");
|
|
38
51
|
const [busy, setBusy] = useState(false);
|
|
@@ -125,6 +138,14 @@ function SessionMenuSheet({ session, actions, onClose }) {
|
|
|
125
138
|
setStep("rename");
|
|
126
139
|
}
|
|
127
140
|
},
|
|
141
|
+
...onGroups ? [{
|
|
142
|
+
label: "Groups",
|
|
143
|
+
hint: "Sessions in a group can message each other",
|
|
144
|
+
onPress: () => {
|
|
145
|
+
close();
|
|
146
|
+
onGroups(session);
|
|
147
|
+
}
|
|
148
|
+
}] : [],
|
|
128
149
|
{
|
|
129
150
|
label: "Resume",
|
|
130
151
|
hint: "Open an earlier conversation in this session",
|
|
@@ -239,6 +260,317 @@ function WorkspaceMenuSheet({ workspace, actions, onClose }) {
|
|
|
239
260
|
})] }) })
|
|
240
261
|
});
|
|
241
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* The cockpit's groups dialog as a sheet. Rows check groups on and off and the typed name can
|
|
265
|
+
* become a new one; rename and delete act on every session in the group at once, the checks wait for Save.
|
|
266
|
+
*/
|
|
267
|
+
function SessionGroupsSheet({ session, sessions, actions, onClose }) {
|
|
268
|
+
const [forId, setForId] = useState(null);
|
|
269
|
+
const [value, setValue] = useState([]);
|
|
270
|
+
const [query, setQuery] = useState("");
|
|
271
|
+
const [renaming, setRenaming] = useState();
|
|
272
|
+
const [deleting, setDeleting] = useState();
|
|
273
|
+
const [error, setError] = useState("");
|
|
274
|
+
const [busy, setBusy] = useState(false);
|
|
275
|
+
if ((session?.id ?? null) !== forId) {
|
|
276
|
+
setForId(session?.id ?? null);
|
|
277
|
+
setValue([...session?.groups ?? []]);
|
|
278
|
+
setQuery("");
|
|
279
|
+
setRenaming(void 0);
|
|
280
|
+
setDeleting(void 0);
|
|
281
|
+
setError("");
|
|
282
|
+
}
|
|
283
|
+
const close = () => {
|
|
284
|
+
if (!busy) onClose();
|
|
285
|
+
};
|
|
286
|
+
const rowCancel = () => {
|
|
287
|
+
setRenaming(void 0);
|
|
288
|
+
setDeleting(void 0);
|
|
289
|
+
};
|
|
290
|
+
const run = async (work, done) => {
|
|
291
|
+
setBusy(true);
|
|
292
|
+
setError("");
|
|
293
|
+
const result = await work();
|
|
294
|
+
setBusy(false);
|
|
295
|
+
if (result === void 0) done();
|
|
296
|
+
else setError(result.error);
|
|
297
|
+
};
|
|
298
|
+
const typed = query.trim();
|
|
299
|
+
const options = session === null ? [] : sessionGroupOptions(sessions, session.id, value);
|
|
300
|
+
const shown = options.filter((group) => group.name.includes(typed));
|
|
301
|
+
const canCreate = typed !== "" && !options.some((group) => group.name === typed);
|
|
302
|
+
const problem = canCreate ? createProblem(typed, value.length) : void 0;
|
|
303
|
+
const toggle = (group) => {
|
|
304
|
+
setError("");
|
|
305
|
+
if (value.includes(group)) setValue(value.filter((name) => name !== group));
|
|
306
|
+
else if (value.length >= 8) setError(createProblem("", value.length) ?? "");
|
|
307
|
+
else setValue([...value, group]);
|
|
308
|
+
};
|
|
309
|
+
const create = () => {
|
|
310
|
+
if (!canCreate || problem !== void 0) return;
|
|
311
|
+
setValue([...value, typed]);
|
|
312
|
+
setQuery("");
|
|
313
|
+
};
|
|
314
|
+
const renameConfirm = () => {
|
|
315
|
+
if (renaming === void 0) return;
|
|
316
|
+
const to = renaming.draft.trim();
|
|
317
|
+
if (to === "" || to === renaming.group) return rowCancel();
|
|
318
|
+
run(() => actions.renameGroup(renaming.group, to), () => {
|
|
319
|
+
setValue((current) => [...new Set(current.map((name) => name === renaming.group ? to : name))]);
|
|
320
|
+
rowCancel();
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
const deleteConfirm = () => {
|
|
324
|
+
if (deleting === void 0) return;
|
|
325
|
+
run(() => actions.deleteGroup(deleting), () => {
|
|
326
|
+
setValue((current) => current.filter((name) => name !== deleting));
|
|
327
|
+
rowCancel();
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
return /* @__PURE__ */ jsx(Sheet, {
|
|
331
|
+
open: session !== null,
|
|
332
|
+
onOpenChange: (open) => !open && close(),
|
|
333
|
+
children: /* @__PURE__ */ jsx(SheetContent, { children: session === null ? null : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SheetHeader, { children: /* @__PURE__ */ jsx(SheetTitle, { children: "Session groups" }) }), /* @__PURE__ */ jsxs(SheetBody, {
|
|
334
|
+
style: styles$1.body,
|
|
335
|
+
children: [
|
|
336
|
+
/* @__PURE__ */ jsx(Text, {
|
|
337
|
+
style: styles$1.meta,
|
|
338
|
+
children: "Sessions that share a group can message each other."
|
|
339
|
+
}),
|
|
340
|
+
/* @__PURE__ */ jsx(Input, {
|
|
341
|
+
value: query,
|
|
342
|
+
onChangeText: setQuery,
|
|
343
|
+
placeholder: value.length === 0 ? "Find or create a group" : "Add another",
|
|
344
|
+
autoCapitalize: "none",
|
|
345
|
+
autoCorrect: false,
|
|
346
|
+
returnKeyType: "done",
|
|
347
|
+
onSubmitEditing: () => {
|
|
348
|
+
if (canCreate) create();
|
|
349
|
+
else if (shown[0] !== void 0) {
|
|
350
|
+
toggle(shown[0].name);
|
|
351
|
+
setQuery("");
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
accessibilityLabel: "Find or create a group"
|
|
355
|
+
}),
|
|
356
|
+
shown.length > 0 || canCreate ? /* @__PURE__ */ jsxs(View, {
|
|
357
|
+
style: styles$1.list,
|
|
358
|
+
children: [shown.map((group, index) => {
|
|
359
|
+
const on = value.includes(group.name);
|
|
360
|
+
const total = group.members.length + (on ? 1 : 0);
|
|
361
|
+
const reach = total === 1 ? "its one session" : `all ${String(total)} sessions`;
|
|
362
|
+
const edge = index > 0 && styles$1.divider;
|
|
363
|
+
if (renaming?.group === group.name) return /* @__PURE__ */ jsxs(View, {
|
|
364
|
+
style: [styles$1.rowEdit, edge],
|
|
365
|
+
children: [
|
|
366
|
+
/* @__PURE__ */ jsx(Input, {
|
|
367
|
+
value: renaming.draft,
|
|
368
|
+
onChangeText: (draft) => setRenaming({
|
|
369
|
+
...renaming,
|
|
370
|
+
draft
|
|
371
|
+
}),
|
|
372
|
+
autoFocus: true,
|
|
373
|
+
autoCapitalize: "none",
|
|
374
|
+
autoCorrect: false,
|
|
375
|
+
onSubmitEditing: renameConfirm,
|
|
376
|
+
accessibilityLabel: `Rename ${group.name}`
|
|
377
|
+
}),
|
|
378
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
379
|
+
style: styles$1.meta,
|
|
380
|
+
children: [
|
|
381
|
+
"Renames it on ",
|
|
382
|
+
reach,
|
|
383
|
+
"."
|
|
384
|
+
]
|
|
385
|
+
}),
|
|
386
|
+
/* @__PURE__ */ jsxs(View, {
|
|
387
|
+
style: styles$1.rowActions,
|
|
388
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
389
|
+
variant: "ghost",
|
|
390
|
+
size: "sm",
|
|
391
|
+
disabled: busy,
|
|
392
|
+
onPress: rowCancel,
|
|
393
|
+
children: "Cancel"
|
|
394
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
395
|
+
variant: "outline",
|
|
396
|
+
size: "sm",
|
|
397
|
+
disabled: renaming.draft.trim() === "",
|
|
398
|
+
loading: busy,
|
|
399
|
+
loadingLabel: "Renaming",
|
|
400
|
+
onPress: renameConfirm,
|
|
401
|
+
children: "Rename"
|
|
402
|
+
})]
|
|
403
|
+
})
|
|
404
|
+
]
|
|
405
|
+
}, group.name);
|
|
406
|
+
if (deleting === group.name) return /* @__PURE__ */ jsxs(View, {
|
|
407
|
+
style: [styles$1.rowEdit, edge],
|
|
408
|
+
children: [/* @__PURE__ */ jsxs(Text, {
|
|
409
|
+
style: styles$1.text,
|
|
410
|
+
children: [
|
|
411
|
+
"Remove ",
|
|
412
|
+
/* @__PURE__ */ jsx(Text, {
|
|
413
|
+
style: styles$1.strong,
|
|
414
|
+
children: group.name
|
|
415
|
+
}),
|
|
416
|
+
" from ",
|
|
417
|
+
reach,
|
|
418
|
+
"? They can no longer message through it."
|
|
419
|
+
]
|
|
420
|
+
}), /* @__PURE__ */ jsxs(View, {
|
|
421
|
+
style: styles$1.rowActions,
|
|
422
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
423
|
+
variant: "ghost",
|
|
424
|
+
size: "sm",
|
|
425
|
+
disabled: busy,
|
|
426
|
+
onPress: rowCancel,
|
|
427
|
+
children: "Cancel"
|
|
428
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
429
|
+
variant: "danger",
|
|
430
|
+
size: "sm",
|
|
431
|
+
loading: busy,
|
|
432
|
+
loadingLabel: "Deleting",
|
|
433
|
+
onPress: deleteConfirm,
|
|
434
|
+
children: "Delete"
|
|
435
|
+
})]
|
|
436
|
+
})]
|
|
437
|
+
}, group.name);
|
|
438
|
+
return /* @__PURE__ */ jsx(ListRow, {
|
|
439
|
+
title: group.name,
|
|
440
|
+
description: group.members.length === 0 ? "No other sessions yet" : group.members.join(", "),
|
|
441
|
+
selected: on,
|
|
442
|
+
leading: /* @__PURE__ */ jsx(View, {
|
|
443
|
+
style: styles$1.check,
|
|
444
|
+
children: on ? /* @__PURE__ */ jsx(CheckIcon, {
|
|
445
|
+
size: 16,
|
|
446
|
+
color: "green"
|
|
447
|
+
}) : null
|
|
448
|
+
}),
|
|
449
|
+
trailing: /* @__PURE__ */ jsxs(View, {
|
|
450
|
+
style: styles$1.rowActions,
|
|
451
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
452
|
+
variant: "ghost",
|
|
453
|
+
size: "icon",
|
|
454
|
+
accessibilityLabel: `Rename ${group.name}`,
|
|
455
|
+
onPress: () => {
|
|
456
|
+
setDeleting(void 0);
|
|
457
|
+
setRenaming({
|
|
458
|
+
group: group.name,
|
|
459
|
+
draft: group.name
|
|
460
|
+
});
|
|
461
|
+
},
|
|
462
|
+
children: /* @__PURE__ */ jsx(EditIcon, {
|
|
463
|
+
size: 16,
|
|
464
|
+
color: "dim"
|
|
465
|
+
})
|
|
466
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
467
|
+
variant: "ghost",
|
|
468
|
+
size: "icon",
|
|
469
|
+
accessibilityLabel: `Delete ${group.name}`,
|
|
470
|
+
onPress: () => {
|
|
471
|
+
setRenaming(void 0);
|
|
472
|
+
setDeleting(group.name);
|
|
473
|
+
},
|
|
474
|
+
children: /* @__PURE__ */ jsx(TrashIcon, {
|
|
475
|
+
size: 16,
|
|
476
|
+
color: "dim"
|
|
477
|
+
})
|
|
478
|
+
})]
|
|
479
|
+
}),
|
|
480
|
+
disclosure: false,
|
|
481
|
+
onPress: () => toggle(group.name),
|
|
482
|
+
style: edge
|
|
483
|
+
}, group.name);
|
|
484
|
+
}), canCreate ? /* @__PURE__ */ jsx(ListRow, {
|
|
485
|
+
title: /* @__PURE__ */ jsxs(Text, {
|
|
486
|
+
style: styles$1.create(problem === void 0),
|
|
487
|
+
numberOfLines: 1,
|
|
488
|
+
children: [
|
|
489
|
+
"Create group “",
|
|
490
|
+
typed,
|
|
491
|
+
"”"
|
|
492
|
+
]
|
|
493
|
+
}),
|
|
494
|
+
description: problem === void 0 ? void 0 : /* @__PURE__ */ jsx(Text, {
|
|
495
|
+
style: styles$1.error,
|
|
496
|
+
children: problem
|
|
497
|
+
}),
|
|
498
|
+
leading: /* @__PURE__ */ jsx(PlusIcon, {
|
|
499
|
+
size: 16,
|
|
500
|
+
color: problem === void 0 ? "magenta" : "faint"
|
|
501
|
+
}),
|
|
502
|
+
disabled: problem !== void 0,
|
|
503
|
+
disclosure: false,
|
|
504
|
+
onPress: create,
|
|
505
|
+
style: shown.length > 0 && styles$1.divider
|
|
506
|
+
}) : null]
|
|
507
|
+
}) : null,
|
|
508
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
509
|
+
style: styles$1.meta,
|
|
510
|
+
children: [
|
|
511
|
+
value.length,
|
|
512
|
+
" of ",
|
|
513
|
+
8,
|
|
514
|
+
" groups"
|
|
515
|
+
]
|
|
516
|
+
}),
|
|
517
|
+
error ? /* @__PURE__ */ jsx(Text, {
|
|
518
|
+
style: styles$1.error,
|
|
519
|
+
accessibilityRole: "alert",
|
|
520
|
+
children: error
|
|
521
|
+
}) : null,
|
|
522
|
+
/* @__PURE__ */ jsx(Button, {
|
|
523
|
+
variant: "primary",
|
|
524
|
+
size: "lg",
|
|
525
|
+
loading: busy && renaming === void 0 && deleting === void 0,
|
|
526
|
+
loadingLabel: "Saving",
|
|
527
|
+
disabled: busy,
|
|
528
|
+
onPress: () => void run(() => actions.setSessionGroups(session.id, value), onClose),
|
|
529
|
+
children: "Save"
|
|
530
|
+
})
|
|
531
|
+
]
|
|
532
|
+
})] }) })
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
/** A pending setup's ⋮: it has no runtime, so removing it is the only action, as in the cockpit. */
|
|
536
|
+
function SetupMenuSheet({ target, removePendingSetup, onClose }) {
|
|
537
|
+
const [busy, setBusy] = useState(false);
|
|
538
|
+
const [error, setError] = useState("");
|
|
539
|
+
const close = () => {
|
|
540
|
+
if (busy) return;
|
|
541
|
+
setError("");
|
|
542
|
+
onClose();
|
|
543
|
+
};
|
|
544
|
+
const remove = async () => {
|
|
545
|
+
if (target === null) return;
|
|
546
|
+
setBusy(true);
|
|
547
|
+
setError("");
|
|
548
|
+
const result = await removePendingSetup(target.sessionId, target.setup.id);
|
|
549
|
+
setBusy(false);
|
|
550
|
+
if (result === void 0) onClose();
|
|
551
|
+
else setError(result.error);
|
|
552
|
+
};
|
|
553
|
+
return /* @__PURE__ */ jsx(Sheet, {
|
|
554
|
+
open: target !== null,
|
|
555
|
+
onOpenChange: (open) => !open && close(),
|
|
556
|
+
children: /* @__PURE__ */ jsx(SheetContent, { children: target === null ? null : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SheetHeader, { children: /* @__PURE__ */ jsx(SheetTitle, {
|
|
557
|
+
numberOfLines: 1,
|
|
558
|
+
children: target.setup.name
|
|
559
|
+
}) }), /* @__PURE__ */ jsxs(SheetBody, {
|
|
560
|
+
style: styles$1.body,
|
|
561
|
+
children: [/* @__PURE__ */ jsx(Items, { items: [{
|
|
562
|
+
label: busy ? "Removing…" : "Remove setup",
|
|
563
|
+
danger: true,
|
|
564
|
+
disabled: busy,
|
|
565
|
+
onPress: () => void remove()
|
|
566
|
+
}] }), error ? /* @__PURE__ */ jsx(Text, {
|
|
567
|
+
style: styles$1.error,
|
|
568
|
+
accessibilityRole: "alert",
|
|
569
|
+
children: error
|
|
570
|
+
}) : null]
|
|
571
|
+
})] }) })
|
|
572
|
+
});
|
|
573
|
+
}
|
|
242
574
|
const SUGGESTION_DEBOUNCE_MS = 120;
|
|
243
575
|
const TRAILING_SEPARATORS = /\/+$/u;
|
|
244
576
|
function folderName(path) {
|
|
@@ -521,6 +853,24 @@ const styles$1 = StyleSheet.create((theme) => {
|
|
|
521
853
|
paddingBottom: theme.spacing(2),
|
|
522
854
|
uni__dependencies: [0]
|
|
523
855
|
},
|
|
856
|
+
rowEdit: {
|
|
857
|
+
gap: theme.spacing(2),
|
|
858
|
+
paddingHorizontal: theme.spacing(4),
|
|
859
|
+
paddingVertical: theme.spacing(3),
|
|
860
|
+
uni__dependencies: [0]
|
|
861
|
+
},
|
|
862
|
+
rowActions: {
|
|
863
|
+
flexDirection: "row",
|
|
864
|
+
alignItems: "center",
|
|
865
|
+
justifyContent: "flex-end",
|
|
866
|
+
gap: theme.spacing(1),
|
|
867
|
+
uni__dependencies: [0]
|
|
868
|
+
},
|
|
869
|
+
check: {
|
|
870
|
+
width: 16,
|
|
871
|
+
alignItems: "center"
|
|
872
|
+
},
|
|
873
|
+
create: (enabled) => text("base", enabled ? theme.colors.magenta : theme.colors.faint),
|
|
524
874
|
pressed: {
|
|
525
875
|
backgroundColor: theme.colors["tint-green"],
|
|
526
876
|
uni__dependencies: [0]
|
|
@@ -572,7 +922,7 @@ function IconButton({ label, onPress, children }) {
|
|
|
572
922
|
children
|
|
573
923
|
});
|
|
574
924
|
}
|
|
575
|
-
function SessionCard({ session, onOpen, onMenu }) {
|
|
925
|
+
function SessionCard({ session, onOpen, onMenu, onSetupMenu }) {
|
|
576
926
|
const tone = statusTone(session.status);
|
|
577
927
|
const name = session.name || "Untitled";
|
|
578
928
|
const markColor = session.active ? "green" : "faint";
|
|
@@ -690,10 +1040,20 @@ function SessionCard({ session, onOpen, onMenu }) {
|
|
|
690
1040
|
}), session.pendingSetups.map((setup) => /* @__PURE__ */ jsxs(View, {
|
|
691
1041
|
style: styles.setup,
|
|
692
1042
|
children: [
|
|
693
|
-
/* @__PURE__ */
|
|
694
|
-
style: styles.
|
|
695
|
-
|
|
696
|
-
|
|
1043
|
+
/* @__PURE__ */ jsxs(View, {
|
|
1044
|
+
style: styles.setupHead,
|
|
1045
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
1046
|
+
style: [styles.name, styles.setupName],
|
|
1047
|
+
numberOfLines: 1,
|
|
1048
|
+
children: setup.name
|
|
1049
|
+
}), onSetupMenu ? /* @__PURE__ */ jsx(IconButton, {
|
|
1050
|
+
label: `${setup.name} setup actions`,
|
|
1051
|
+
onPress: () => onSetupMenu(setup),
|
|
1052
|
+
children: /* @__PURE__ */ jsx(KebabIcon, {
|
|
1053
|
+
size: 16,
|
|
1054
|
+
color: "dim"
|
|
1055
|
+
})
|
|
1056
|
+
}) : null]
|
|
697
1057
|
}),
|
|
698
1058
|
/* @__PURE__ */ jsx(Text, {
|
|
699
1059
|
style: styles.setupStatus(setup.failed),
|
|
@@ -707,7 +1067,7 @@ function SessionCard({ session, onOpen, onMenu }) {
|
|
|
707
1067
|
]
|
|
708
1068
|
}, setup.id))] });
|
|
709
1069
|
}
|
|
710
|
-
function WorkspaceGroup({ workspace, onOpen, actions, onSessionMenu, onWorkspaceMenu }) {
|
|
1070
|
+
function WorkspaceGroup({ workspace, onOpen, actions, onSessionMenu, onSetupMenu, onWorkspaceMenu }) {
|
|
711
1071
|
return /* @__PURE__ */ jsxs(View, {
|
|
712
1072
|
style: styles.group,
|
|
713
1073
|
children: [
|
|
@@ -759,7 +1119,8 @@ function WorkspaceGroup({ workspace, onOpen, actions, onSessionMenu, onWorkspace
|
|
|
759
1119
|
}) : workspace.sessions.map((session) => /* @__PURE__ */ jsx(SessionCard, {
|
|
760
1120
|
session,
|
|
761
1121
|
onOpen,
|
|
762
|
-
onMenu: onSessionMenu
|
|
1122
|
+
onMenu: onSessionMenu,
|
|
1123
|
+
...onSetupMenu ? { onSetupMenu: (setup) => onSetupMenu(session.id, setup) } : {}
|
|
763
1124
|
}, session.id))
|
|
764
1125
|
]
|
|
765
1126
|
});
|
|
@@ -793,6 +1154,8 @@ function NoWorkspaces({ actions }) {
|
|
|
793
1154
|
function AdvancedSessions({ workspaces, openSession, actions }) {
|
|
794
1155
|
const [sessionMenu, setSessionMenu] = useState(null);
|
|
795
1156
|
const [workspaceMenu, setWorkspaceMenu] = useState(null);
|
|
1157
|
+
const [groupsFor, setGroupsFor] = useState(null);
|
|
1158
|
+
const [setupMenu, setSetupMenu] = useState(null);
|
|
796
1159
|
if (workspaces.length === 0) {
|
|
797
1160
|
const { addWorkspace, searchDirectories, listDirectory } = actions;
|
|
798
1161
|
return addWorkspace && searchDirectories && listDirectory ? /* @__PURE__ */ jsx(NoWorkspaces, { actions: {
|
|
@@ -808,6 +1171,12 @@ function AdvancedSessions({ workspaces, openSession, actions }) {
|
|
|
808
1171
|
});
|
|
809
1172
|
}
|
|
810
1173
|
const sessions = workspaces.flatMap((workspace) => workspace.sessions);
|
|
1174
|
+
const { setSessionGroups, renameGroup, deleteGroup, removePendingSetup } = actions;
|
|
1175
|
+
const groupActions = setSessionGroups && renameGroup && deleteGroup ? {
|
|
1176
|
+
setSessionGroups,
|
|
1177
|
+
renameGroup,
|
|
1178
|
+
deleteGroup
|
|
1179
|
+
} : void 0;
|
|
811
1180
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
812
1181
|
/* @__PURE__ */ jsx(ScrollView, {
|
|
813
1182
|
style: styles.screen,
|
|
@@ -818,19 +1187,35 @@ function AdvancedSessions({ workspaces, openSession, actions }) {
|
|
|
818
1187
|
onOpen: openSession,
|
|
819
1188
|
actions,
|
|
820
1189
|
onSessionMenu: (session) => setSessionMenu(session.id),
|
|
1190
|
+
...removePendingSetup ? { onSetupMenu: (sessionId, setup) => setSetupMenu({
|
|
1191
|
+
sessionId,
|
|
1192
|
+
setup
|
|
1193
|
+
}) } : {},
|
|
821
1194
|
onWorkspaceMenu: (entry) => setWorkspaceMenu(entry.id)
|
|
822
1195
|
}, workspace.id))
|
|
823
1196
|
}),
|
|
824
1197
|
/* @__PURE__ */ jsx(SessionMenuSheet, {
|
|
825
1198
|
session: sessions.find((session) => session.id === sessionMenu) ?? null,
|
|
826
1199
|
actions,
|
|
1200
|
+
...groupActions ? { onGroups: (session) => setGroupsFor(session.id) } : {},
|
|
827
1201
|
onClose: () => setSessionMenu(null)
|
|
828
1202
|
}),
|
|
829
1203
|
/* @__PURE__ */ jsx(WorkspaceMenuSheet, {
|
|
830
1204
|
workspace: workspaces.find((workspace) => workspace.id === workspaceMenu) ?? null,
|
|
831
1205
|
actions,
|
|
832
1206
|
onClose: () => setWorkspaceMenu(null)
|
|
833
|
-
})
|
|
1207
|
+
}),
|
|
1208
|
+
groupActions ? /* @__PURE__ */ jsx(SessionGroupsSheet, {
|
|
1209
|
+
session: sessions.find((session) => session.id === groupsFor) ?? null,
|
|
1210
|
+
sessions,
|
|
1211
|
+
actions: groupActions,
|
|
1212
|
+
onClose: () => setGroupsFor(null)
|
|
1213
|
+
}) : null,
|
|
1214
|
+
removePendingSetup ? /* @__PURE__ */ jsx(SetupMenuSheet, {
|
|
1215
|
+
target: setupMenu,
|
|
1216
|
+
removePendingSetup,
|
|
1217
|
+
onClose: () => setSetupMenu(null)
|
|
1218
|
+
}) : null
|
|
834
1219
|
] });
|
|
835
1220
|
}
|
|
836
1221
|
const styles = StyleSheet.create((theme) => {
|
|
@@ -1027,6 +1412,14 @@ const styles = StyleSheet.create((theme) => {
|
|
|
1027
1412
|
uni__dependencies: [0]
|
|
1028
1413
|
},
|
|
1029
1414
|
setupStatus: (failed) => text("sm", failed ? theme.colors.red : theme.colors.dim),
|
|
1415
|
+
setupHead: {
|
|
1416
|
+
flexDirection: "row",
|
|
1417
|
+
alignItems: "center",
|
|
1418
|
+
gap: theme.spacing(2),
|
|
1419
|
+
marginVertical: -theme.spacing(2),
|
|
1420
|
+
uni__dependencies: [0]
|
|
1421
|
+
},
|
|
1422
|
+
setupName: { flex: 1 },
|
|
1030
1423
|
recovery: text("sm", theme.colors.dim),
|
|
1031
1424
|
error: text("sm", theme.colors.red)
|
|
1032
1425
|
};
|