@odla-ai/chapter 0.26.1 → 0.27.0
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 +51 -3
- package/dist/{chunk-QBTFQUDL.js → chunk-IOHVFBXH.js} +2 -2
- package/dist/{chunk-OIWCKF2G.js → chunk-JAWTIROV.js} +2 -1
- package/dist/chunk-JAWTIROV.js.map +1 -0
- package/dist/{chunk-4QZEAWQL.js → chunk-L2SA47IO.js} +434 -79
- package/dist/chunk-L2SA47IO.js.map +1 -0
- package/dist/{copy-context-Vof2eTMt.d.ts → copy-context-efEMF_aD.d.ts} +33 -5
- package/dist/index.cjs +90 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -11
- package/dist/index.d.ts +84 -11
- package/dist/index.js +90 -6
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +12 -3
- package/dist/ui/admin/index.js +6 -2
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +7 -3
- package/dist/ui/member/index.d.ts +2 -2
- package/dist/ui/member/index.js +2 -2
- package/dist/worker/index.cjs +424 -16
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +35 -7
- package/dist/worker/index.d.ts +35 -7
- package/dist/worker/index.js +426 -14
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4QZEAWQL.js.map +0 -1
- package/dist/chunk-OIWCKF2G.js.map +0 -1
- /package/dist/{chunk-QBTFQUDL.js.map → chunk-IOHVFBXH.js.map} +0 -0
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
DEFAULT_CHAPTER_COPY,
|
|
5
5
|
formatChapterCopy,
|
|
6
6
|
useChapterCopy
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JAWTIROV.js";
|
|
8
8
|
|
|
9
9
|
// src/ui/admin.tsx
|
|
10
|
-
import { useEffect as
|
|
10
|
+
import { useEffect as useEffect9, useMemo as useMemo2, useRef, useState as useState14 } from "preact/hooks";
|
|
11
11
|
import { ClerkGate, SignedIn, SignedOut, SignIn, useClerkAuth } from "@odla-ai/auth-clerk";
|
|
12
12
|
import { CrmClient } from "@odla-ai/crm";
|
|
13
13
|
|
|
@@ -1255,46 +1255,398 @@ function peopleSection(options) {
|
|
|
1255
1255
|
});
|
|
1256
1256
|
}
|
|
1257
1257
|
|
|
1258
|
+
// src/ui/admin-network-records.tsx
|
|
1259
|
+
import {
|
|
1260
|
+
DataTable as DataTable3,
|
|
1261
|
+
Field as Field6,
|
|
1262
|
+
MasterDetail,
|
|
1263
|
+
Pagination,
|
|
1264
|
+
Select as Select3
|
|
1265
|
+
} from "@odla-ai/ui/components";
|
|
1266
|
+
import { useEffect as useEffect7, useMemo, useState as useState12 } from "preact/hooks";
|
|
1267
|
+
|
|
1268
|
+
// src/ui/admin-network-notes.tsx
|
|
1269
|
+
import { Button as Button6, Field as Field5, Textarea as Textarea2 } from "@odla-ai/ui/components";
|
|
1270
|
+
import { useState as useState11 } from "preact/hooks";
|
|
1271
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "preact/jsx-runtime";
|
|
1272
|
+
function displayValue(value) {
|
|
1273
|
+
if (Array.isArray(value)) return value.join(", ");
|
|
1274
|
+
if (value && typeof value === "object") return JSON.stringify(value);
|
|
1275
|
+
return value == null ? "\u2014" : String(value);
|
|
1276
|
+
}
|
|
1277
|
+
function PrivateNotes(props) {
|
|
1278
|
+
const { ctx, targetId, record, leaderName } = props;
|
|
1279
|
+
const query = new URLSearchParams({
|
|
1280
|
+
targetId,
|
|
1281
|
+
type: record.type,
|
|
1282
|
+
recordId: record.id
|
|
1283
|
+
});
|
|
1284
|
+
const path = `/api/admin/network/notes?${query}`;
|
|
1285
|
+
const notes = useAdminResource(ctx.getToken, path);
|
|
1286
|
+
const [body, setBody] = useState11("");
|
|
1287
|
+
const [busy, setBusy] = useState11(false);
|
|
1288
|
+
const [error, setError] = useState11(null);
|
|
1289
|
+
const submit = async () => {
|
|
1290
|
+
const trimmed = body.trim();
|
|
1291
|
+
if (!trimmed) return;
|
|
1292
|
+
setBusy(true);
|
|
1293
|
+
setError(null);
|
|
1294
|
+
try {
|
|
1295
|
+
await adminFetch(ctx.getToken, path, {
|
|
1296
|
+
method: "POST",
|
|
1297
|
+
body: JSON.stringify({ body: trimmed })
|
|
1298
|
+
});
|
|
1299
|
+
setBody("");
|
|
1300
|
+
notes.refresh();
|
|
1301
|
+
} catch (cause) {
|
|
1302
|
+
setError(cause instanceof Error ? cause.message : "Could not save note.");
|
|
1303
|
+
} finally {
|
|
1304
|
+
setBusy(false);
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
return /* @__PURE__ */ jsxs12("section", { style: { display: "grid", gap: 12 }, children: [
|
|
1308
|
+
/* @__PURE__ */ jsxs12("h3", { style: { margin: "8px 0 0" }, children: [
|
|
1309
|
+
"Private to ",
|
|
1310
|
+
leaderName
|
|
1311
|
+
] }),
|
|
1312
|
+
/* @__PURE__ */ jsx15(
|
|
1313
|
+
Field5,
|
|
1314
|
+
{
|
|
1315
|
+
label: "Add a note",
|
|
1316
|
+
hint: `Visible only to ${leaderName} admins. Nothing is written back to the follower.`,
|
|
1317
|
+
error,
|
|
1318
|
+
children: /* @__PURE__ */ jsx15(
|
|
1319
|
+
Textarea2,
|
|
1320
|
+
{
|
|
1321
|
+
rows: 4,
|
|
1322
|
+
value: body,
|
|
1323
|
+
maxLength: 4e3,
|
|
1324
|
+
onInput: (event) => setBody(event.currentTarget.value)
|
|
1325
|
+
}
|
|
1326
|
+
)
|
|
1327
|
+
}
|
|
1328
|
+
),
|
|
1329
|
+
/* @__PURE__ */ jsx15("div", { children: /* @__PURE__ */ jsx15(Button6, { disabled: busy || !body.trim(), onClick: () => void submit(), children: busy ? "Saving\u2026" : "Save note" }) }),
|
|
1330
|
+
notes.loading ? /* @__PURE__ */ jsx15("p", { className: "muted", children: "Loading notes\u2026" }) : null,
|
|
1331
|
+
notes.error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: notes.error }) : null,
|
|
1332
|
+
!notes.loading && !notes.error && (notes.data?.notes.length ?? 0) === 0 ? /* @__PURE__ */ jsx15("p", { className: "muted", children: "No notes yet." }) : null,
|
|
1333
|
+
(notes.data?.notes ?? []).map((note) => /* @__PURE__ */ jsxs12("article", { className: "panel", style: { padding: 14 }, children: [
|
|
1334
|
+
/* @__PURE__ */ jsx15("p", { style: { margin: 0, whiteSpace: "pre-wrap" }, children: note.body }),
|
|
1335
|
+
/* @__PURE__ */ jsxs12("p", { className: "muted", style: { margin: "8px 0 0", fontSize: 12 }, children: [
|
|
1336
|
+
note.authorEmail ?? note.authorId,
|
|
1337
|
+
" \xB7 ",
|
|
1338
|
+
new Date(note.createdAt).toLocaleString()
|
|
1339
|
+
] })
|
|
1340
|
+
] }, note.id))
|
|
1341
|
+
] });
|
|
1342
|
+
}
|
|
1343
|
+
function SharedNotes(props) {
|
|
1344
|
+
const { ctx, targetId, targetName, record } = props;
|
|
1345
|
+
const query = new URLSearchParams({
|
|
1346
|
+
targetId,
|
|
1347
|
+
type: record.type,
|
|
1348
|
+
recordId: record.id
|
|
1349
|
+
});
|
|
1350
|
+
const path = `/api/admin/network/shared-notes?${query}`;
|
|
1351
|
+
const notes = useAdminResource(ctx.getToken, path);
|
|
1352
|
+
const [body, setBody] = useState11("");
|
|
1353
|
+
const [busy, setBusy] = useState11(false);
|
|
1354
|
+
const [error, setError] = useState11(null);
|
|
1355
|
+
const submit = async () => {
|
|
1356
|
+
const trimmed = body.trim();
|
|
1357
|
+
if (!trimmed) return;
|
|
1358
|
+
setBusy(true);
|
|
1359
|
+
setError(null);
|
|
1360
|
+
try {
|
|
1361
|
+
await adminFetch(ctx.getToken, path, {
|
|
1362
|
+
method: "POST",
|
|
1363
|
+
body: JSON.stringify({ body: trimmed })
|
|
1364
|
+
});
|
|
1365
|
+
setBody("");
|
|
1366
|
+
notes.refresh();
|
|
1367
|
+
} catch (cause) {
|
|
1368
|
+
setError(cause instanceof Error ? cause.message : "Could not share note.");
|
|
1369
|
+
} finally {
|
|
1370
|
+
setBusy(false);
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
return /* @__PURE__ */ jsxs12("section", { style: { display: "grid", gap: 12 }, children: [
|
|
1374
|
+
/* @__PURE__ */ jsxs12("h3", { style: { margin: "8px 0 0" }, children: [
|
|
1375
|
+
"Shared with ",
|
|
1376
|
+
targetName
|
|
1377
|
+
] }),
|
|
1378
|
+
/* @__PURE__ */ jsx15(
|
|
1379
|
+
Field5,
|
|
1380
|
+
{
|
|
1381
|
+
label: "Add a shared note",
|
|
1382
|
+
hint: `This is written to the record's Notes feed for ${targetName} admins.`,
|
|
1383
|
+
error,
|
|
1384
|
+
children: /* @__PURE__ */ jsx15(
|
|
1385
|
+
Textarea2,
|
|
1386
|
+
{
|
|
1387
|
+
rows: 4,
|
|
1388
|
+
value: body,
|
|
1389
|
+
maxLength: 4e3,
|
|
1390
|
+
onInput: (event) => setBody(event.currentTarget.value)
|
|
1391
|
+
}
|
|
1392
|
+
)
|
|
1393
|
+
}
|
|
1394
|
+
),
|
|
1395
|
+
/* @__PURE__ */ jsx15("div", { children: /* @__PURE__ */ jsx15(Button6, { disabled: busy || !body.trim(), onClick: () => void submit(), children: busy ? "Sharing\u2026" : `Share with ${targetName}` }) }),
|
|
1396
|
+
notes.loading ? /* @__PURE__ */ jsx15("p", { className: "muted", children: "Loading shared notes\u2026" }) : null,
|
|
1397
|
+
notes.error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: notes.error }) : null,
|
|
1398
|
+
!notes.loading && !notes.error && (notes.data?.notes.length ?? 0) === 0 ? /* @__PURE__ */ jsx15("p", { className: "muted", children: "No shared notes yet." }) : null,
|
|
1399
|
+
(notes.data?.notes ?? []).map((note) => /* @__PURE__ */ jsxs12("article", { className: "panel", style: { padding: 14 }, children: [
|
|
1400
|
+
/* @__PURE__ */ jsx15("p", { style: { margin: 0, whiteSpace: "pre-wrap" }, children: note.body }),
|
|
1401
|
+
/* @__PURE__ */ jsxs12("p", { className: "muted", style: { margin: "8px 0 0", fontSize: 12 }, children: [
|
|
1402
|
+
"Shared with ",
|
|
1403
|
+
targetName,
|
|
1404
|
+
" \xB7 ",
|
|
1405
|
+
new Date(note.createdAt).toLocaleString()
|
|
1406
|
+
] })
|
|
1407
|
+
] }, note.id))
|
|
1408
|
+
] });
|
|
1409
|
+
}
|
|
1410
|
+
function NetworkRecordDetail(props) {
|
|
1411
|
+
const { ctx, targetId, targetName, leaderName, sharedEnabled, record } = props;
|
|
1412
|
+
return /* @__PURE__ */ jsxs12("div", { style: { display: "grid", gap: 14 }, children: [
|
|
1413
|
+
/* @__PURE__ */ jsxs12("header", { children: [
|
|
1414
|
+
/* @__PURE__ */ jsx15("h2", { style: { margin: 0 }, children: record.name }),
|
|
1415
|
+
record.stage ? /* @__PURE__ */ jsx15("span", { className: "badge", style: { marginTop: 8 }, children: record.stage.replaceAll("_", " ") }) : null
|
|
1416
|
+
] }),
|
|
1417
|
+
/* @__PURE__ */ jsxs12("dl", { style: { display: "grid", gridTemplateColumns: "minmax(8rem, auto) 1fr", gap: "8px 16px", margin: 0 }, children: [
|
|
1418
|
+
Object.entries(record.fields).map(([name, value]) => /* @__PURE__ */ jsxs12("div", { style: { display: "contents" }, children: [
|
|
1419
|
+
/* @__PURE__ */ jsx15("dt", { className: "muted", children: name.replaceAll("_", " ") }),
|
|
1420
|
+
/* @__PURE__ */ jsx15("dd", { style: { margin: 0, overflowWrap: "anywhere" }, children: displayValue(value) })
|
|
1421
|
+
] }, name)),
|
|
1422
|
+
/* @__PURE__ */ jsxs12("div", { style: { display: "contents" }, children: [
|
|
1423
|
+
/* @__PURE__ */ jsx15("dt", { className: "muted", children: "Updated" }),
|
|
1424
|
+
/* @__PURE__ */ jsx15("dd", { style: { margin: 0 }, children: new Date(record.updatedAt).toLocaleString() })
|
|
1425
|
+
] })
|
|
1426
|
+
] }),
|
|
1427
|
+
/* @__PURE__ */ jsxs12("div", { style: { display: "grid", gap: 22 }, children: [
|
|
1428
|
+
/* @__PURE__ */ jsx15(
|
|
1429
|
+
PrivateNotes,
|
|
1430
|
+
{
|
|
1431
|
+
ctx,
|
|
1432
|
+
targetId,
|
|
1433
|
+
record,
|
|
1434
|
+
leaderName
|
|
1435
|
+
}
|
|
1436
|
+
),
|
|
1437
|
+
sharedEnabled ? /* @__PURE__ */ jsx15(
|
|
1438
|
+
SharedNotes,
|
|
1439
|
+
{
|
|
1440
|
+
ctx,
|
|
1441
|
+
targetId,
|
|
1442
|
+
targetName,
|
|
1443
|
+
record
|
|
1444
|
+
}
|
|
1445
|
+
) : null
|
|
1446
|
+
] })
|
|
1447
|
+
] });
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
// src/ui/admin-network-records.tsx
|
|
1451
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "preact/jsx-runtime";
|
|
1452
|
+
function RecordsExplorer(props) {
|
|
1453
|
+
const { ctx, target, type, leaderName } = props;
|
|
1454
|
+
const [offset, setOffset] = useState12(0);
|
|
1455
|
+
const [search, setSearch] = useState12("");
|
|
1456
|
+
const query = new URLSearchParams({
|
|
1457
|
+
targetId: target.id,
|
|
1458
|
+
type,
|
|
1459
|
+
limit: "25",
|
|
1460
|
+
offset: String(offset)
|
|
1461
|
+
});
|
|
1462
|
+
if (search.trim()) query.set("search", search.trim());
|
|
1463
|
+
const page = useAdminResource(
|
|
1464
|
+
ctx.getToken,
|
|
1465
|
+
`/api/admin/network/records?${query}`
|
|
1466
|
+
);
|
|
1467
|
+
const selected = page.data?.records.find((record) => record.id === ctx.route.recordId);
|
|
1468
|
+
const columns2 = useMemo(() => [
|
|
1469
|
+
{
|
|
1470
|
+
key: "name",
|
|
1471
|
+
header: "Name",
|
|
1472
|
+
cell: (record) => /* @__PURE__ */ jsx16("a", { href: ctx.href({ recordId: record.id, detailTab: null }), children: record.name })
|
|
1473
|
+
},
|
|
1474
|
+
{
|
|
1475
|
+
key: "stage",
|
|
1476
|
+
header: "Stage",
|
|
1477
|
+
cell: (record) => record.stage ? /* @__PURE__ */ jsx16("span", { className: "badge", children: record.stage.replaceAll("_", " ") }) : "\u2014"
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
key: "updatedAt",
|
|
1481
|
+
header: "Updated",
|
|
1482
|
+
cell: (record) => new Date(record.updatedAt).toLocaleDateString()
|
|
1483
|
+
}
|
|
1484
|
+
], [ctx]);
|
|
1485
|
+
return /* @__PURE__ */ jsx16(
|
|
1486
|
+
MasterDetail,
|
|
1487
|
+
{
|
|
1488
|
+
collapseClosedDetail: true,
|
|
1489
|
+
masterLabel: `${target.name} records`,
|
|
1490
|
+
detailLabel: "Follower record details, private notes, and shared notes",
|
|
1491
|
+
detailOpen: Boolean(selected),
|
|
1492
|
+
closeHref: ctx.href({ recordId: null, detailTab: null }),
|
|
1493
|
+
master: /* @__PURE__ */ jsxs13(Panel, { title: `${target.name} \xB7 ${type.replaceAll("_", " ")}`, children: [
|
|
1494
|
+
/* @__PURE__ */ jsx16(
|
|
1495
|
+
DataTable3,
|
|
1496
|
+
{
|
|
1497
|
+
manual: true,
|
|
1498
|
+
filterable: true,
|
|
1499
|
+
filter: search,
|
|
1500
|
+
filterPlaceholder: "Search records\u2026",
|
|
1501
|
+
onFilterChange: (value) => {
|
|
1502
|
+
setSearch(value);
|
|
1503
|
+
setOffset(0);
|
|
1504
|
+
ctx.navigate({ recordId: null, detailTab: null });
|
|
1505
|
+
},
|
|
1506
|
+
rows: page.data?.records ?? [],
|
|
1507
|
+
columns: columns2,
|
|
1508
|
+
rowKey: (record) => record.id,
|
|
1509
|
+
loading: page.loading,
|
|
1510
|
+
emptyState: page.error ? `Could not load records: ${page.error}` : "No records found.",
|
|
1511
|
+
ariaLabel: `${target.name} ${type} records`
|
|
1512
|
+
}
|
|
1513
|
+
),
|
|
1514
|
+
/* @__PURE__ */ jsx16(
|
|
1515
|
+
Pagination,
|
|
1516
|
+
{
|
|
1517
|
+
offset: page.data?.offset ?? offset,
|
|
1518
|
+
limit: page.data?.limit ?? 25,
|
|
1519
|
+
total: page.data?.total,
|
|
1520
|
+
count: page.data?.records.length ?? 0,
|
|
1521
|
+
disabled: page.loading,
|
|
1522
|
+
onOffsetChange: (next) => {
|
|
1523
|
+
setOffset(next);
|
|
1524
|
+
ctx.navigate({ recordId: null, detailTab: null });
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
)
|
|
1528
|
+
] }),
|
|
1529
|
+
detail: selected ? /* @__PURE__ */ jsx16(Panel, { children: /* @__PURE__ */ jsx16(
|
|
1530
|
+
NetworkRecordDetail,
|
|
1531
|
+
{
|
|
1532
|
+
ctx,
|
|
1533
|
+
targetId: target.id,
|
|
1534
|
+
targetName: target.name,
|
|
1535
|
+
leaderName,
|
|
1536
|
+
sharedEnabled: target.sharedNotes.includes(type),
|
|
1537
|
+
record: selected
|
|
1538
|
+
}
|
|
1539
|
+
) }) : void 0
|
|
1540
|
+
}
|
|
1541
|
+
);
|
|
1542
|
+
}
|
|
1543
|
+
function NetworkRecordsWorkspace(props) {
|
|
1544
|
+
const { chapter, ctx } = props;
|
|
1545
|
+
const targets = useAdminResource(ctx.getToken, "/api/admin/network/targets");
|
|
1546
|
+
const [targetId, setTargetId] = useState12("");
|
|
1547
|
+
const [type, setType] = useState12("");
|
|
1548
|
+
const target = targets.data?.targets.find((candidate) => candidate.id === targetId) ?? targets.data?.targets[0];
|
|
1549
|
+
useEffect7(() => {
|
|
1550
|
+
if (target && target.id !== targetId) setTargetId(target.id);
|
|
1551
|
+
}, [target, targetId]);
|
|
1552
|
+
useEffect7(() => {
|
|
1553
|
+
const first = target?.types[0] ?? "";
|
|
1554
|
+
if (target && !target.types.includes(type)) setType(first);
|
|
1555
|
+
}, [target, type]);
|
|
1556
|
+
if (targets.loading) return /* @__PURE__ */ jsx16(AdminNote, { children: "Loading follower records\u2026" });
|
|
1557
|
+
if (targets.error || !targets.data) return /* @__PURE__ */ jsxs13(AdminNote, { children: [
|
|
1558
|
+
"Could not load followers",
|
|
1559
|
+
targets.error ? `: ${targets.error}` : "",
|
|
1560
|
+
"."
|
|
1561
|
+
] });
|
|
1562
|
+
if (!target) return /* @__PURE__ */ jsx16(AdminPage, { children: /* @__PURE__ */ jsx16(Panel, { title: "Follower records", children: /* @__PURE__ */ jsx16("p", { className: "muted", children: "No followers are configured." }) }) });
|
|
1563
|
+
return /* @__PURE__ */ jsxs13(AdminPage, { children: [
|
|
1564
|
+
/* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 12, flexWrap: "wrap", alignItems: "end" }, children: [
|
|
1565
|
+
/* @__PURE__ */ jsx16(Field6, { label: "Chapter", style: { minWidth: 240 }, children: /* @__PURE__ */ jsx16(
|
|
1566
|
+
Select3,
|
|
1567
|
+
{
|
|
1568
|
+
value: target.id,
|
|
1569
|
+
options: targets.data.targets.map((item) => ({ value: item.id, label: item.name })),
|
|
1570
|
+
onChange: (event) => {
|
|
1571
|
+
setTargetId(event.currentTarget.value);
|
|
1572
|
+
setType("");
|
|
1573
|
+
ctx.navigate({ recordId: null, detailTab: null });
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
) }),
|
|
1577
|
+
/* @__PURE__ */ jsx16(Field6, { label: "Record type", style: { minWidth: 180 }, children: /* @__PURE__ */ jsx16(
|
|
1578
|
+
Select3,
|
|
1579
|
+
{
|
|
1580
|
+
value: type,
|
|
1581
|
+
options: target.types.map((item) => ({ value: item, label: item.replaceAll("_", " ") })),
|
|
1582
|
+
onChange: (event) => {
|
|
1583
|
+
setType(event.currentTarget.value);
|
|
1584
|
+
ctx.navigate({ recordId: null, detailTab: null });
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
) })
|
|
1588
|
+
] }),
|
|
1589
|
+
type ? /* @__PURE__ */ jsx16(
|
|
1590
|
+
RecordsExplorer,
|
|
1591
|
+
{
|
|
1592
|
+
ctx,
|
|
1593
|
+
target,
|
|
1594
|
+
type,
|
|
1595
|
+
leaderName: chapter.name
|
|
1596
|
+
},
|
|
1597
|
+
`${target.id}:${type}`
|
|
1598
|
+
) : /* @__PURE__ */ jsx16(Panel, { children: /* @__PURE__ */ jsx16("p", { className: "muted", children: "This follower has no browsable record types configured." }) })
|
|
1599
|
+
] });
|
|
1600
|
+
}
|
|
1601
|
+
function networkRecordsWorkspace(chapter) {
|
|
1602
|
+
return {
|
|
1603
|
+
id: "network",
|
|
1604
|
+
label: chapter.copy.admin.workspaces.network,
|
|
1605
|
+
defaultViewId: "records",
|
|
1606
|
+
render: (ctx) => /* @__PURE__ */ jsx16(NetworkRecordsWorkspace, { chapter, ctx })
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1258
1610
|
// src/ui/admin-portfolio.tsx
|
|
1259
1611
|
import { StatBand as StatBand2, StepPipeline as StepPipeline2 } from "@odla-ai/ui/components";
|
|
1260
|
-
import { jsx as
|
|
1612
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "preact/jsx-runtime";
|
|
1261
1613
|
function LeaderNetworkOverview({ ctx }) {
|
|
1262
1614
|
const copy = useChapterCopy().admin.network;
|
|
1263
1615
|
const { data, loading, error } = useAdminResource(
|
|
1264
1616
|
ctx.getToken,
|
|
1265
1617
|
"/api/admin/network/rollup"
|
|
1266
1618
|
);
|
|
1267
|
-
if (loading) return /* @__PURE__ */
|
|
1268
|
-
if (error || !data) return /* @__PURE__ */
|
|
1619
|
+
if (loading) return /* @__PURE__ */ jsx17(AdminNote, { children: copy.loadingRollup });
|
|
1620
|
+
if (error || !data) return /* @__PURE__ */ jsxs14(AdminNote, { children: [
|
|
1269
1621
|
copy.loadRollupFailed,
|
|
1270
1622
|
error ? `: ${error}` : "",
|
|
1271
1623
|
"."
|
|
1272
1624
|
] });
|
|
1273
|
-
if (data.configured === 0) return /* @__PURE__ */
|
|
1625
|
+
if (data.configured === 0) return /* @__PURE__ */ jsx17(AdminPage, { children: /* @__PURE__ */ jsx17(Panel, { title: copy.overview, children: /* @__PURE__ */ jsx17("p", { className: "muted", children: copy.noFollowers }) }) });
|
|
1274
1626
|
const stats = [
|
|
1275
1627
|
{ value: data.configured.toLocaleString(), label: copy.configuredFollowers },
|
|
1276
1628
|
{ value: data.available.toLocaleString(), label: copy.reachableFollowers },
|
|
1277
1629
|
{ value: data.totalRecords.toLocaleString(), label: copy.recordsAcrossFollowers }
|
|
1278
1630
|
];
|
|
1279
1631
|
const steps = data.types.map((type) => ({
|
|
1280
|
-
icon: /* @__PURE__ */
|
|
1632
|
+
icon: /* @__PURE__ */ jsx17("span", { style: { fontSize: 22, fontWeight: 700 }, children: type.total }),
|
|
1281
1633
|
title: type.type.replaceAll("_", " "),
|
|
1282
1634
|
description: Object.entries(type.stages).filter(([, count]) => count > 0).map(([stage, count]) => `${stage.replaceAll("_", " ")} ${count}`).join(" \xB7 ") || copy.noRecordTotals
|
|
1283
1635
|
}));
|
|
1284
|
-
return /* @__PURE__ */
|
|
1285
|
-
/* @__PURE__ */
|
|
1286
|
-
/* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
/* @__PURE__ */
|
|
1289
|
-
target.error ? /* @__PURE__ */
|
|
1290
|
-
/* @__PURE__ */
|
|
1636
|
+
return /* @__PURE__ */ jsxs14(AdminPage, { children: [
|
|
1637
|
+
/* @__PURE__ */ jsx17(StatBand2, { stats }),
|
|
1638
|
+
/* @__PURE__ */ jsx17(Panel, { title: copy.followers, children: /* @__PURE__ */ jsx17("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "grid", gap: 10 }, children: data.targets.map((target) => /* @__PURE__ */ jsxs14("li", { style: { display: "flex", gap: 12, alignItems: "baseline", flexWrap: "wrap" }, children: [
|
|
1639
|
+
/* @__PURE__ */ jsx17("strong", { style: { minWidth: 180 }, children: target.name }),
|
|
1640
|
+
/* @__PURE__ */ jsx17("span", { className: "badge", children: target.available ? copy.available : copy.unavailable }),
|
|
1641
|
+
target.error ? /* @__PURE__ */ jsx17("span", { className: "muted", children: target.error }) : null,
|
|
1642
|
+
/* @__PURE__ */ jsx17("a", { href: target.url, target: "_blank", rel: "noreferrer", style: { marginLeft: "auto" }, children: target.url })
|
|
1291
1643
|
] }, target.id)) }) }),
|
|
1292
|
-
/* @__PURE__ */
|
|
1644
|
+
/* @__PURE__ */ jsx17(Panel, { title: copy.recordTotals, children: steps.length ? /* @__PURE__ */ jsx17(StepPipeline2, { ariaLabel: copy.recordTotals, steps }) : /* @__PURE__ */ jsx17("p", { className: "muted", children: copy.noRecordTotals }) })
|
|
1293
1645
|
] });
|
|
1294
1646
|
}
|
|
1295
1647
|
|
|
1296
1648
|
// src/ui/admin-workspaces.tsx
|
|
1297
|
-
import { jsx as
|
|
1649
|
+
import { jsx as jsx18 } from "preact/jsx-runtime";
|
|
1298
1650
|
var adminViewContext = (ctx, viewId, active) => {
|
|
1299
1651
|
const route = {
|
|
1300
1652
|
workspaceId: ctx.route.workspaceId,
|
|
@@ -1320,7 +1672,7 @@ function DashboardWorkspace({ chapter, ctx }) {
|
|
|
1320
1672
|
const active = ctx.route.viewId === "billing" ? "billing" : "overview";
|
|
1321
1673
|
const overview = dashboardSection({ id: "overview", label: copy.workspaces.overview });
|
|
1322
1674
|
const billing = billingSection({ label: copy.workspaces.billing });
|
|
1323
|
-
return /* @__PURE__ */
|
|
1675
|
+
return /* @__PURE__ */ jsx18(
|
|
1324
1676
|
Tabs2,
|
|
1325
1677
|
{
|
|
1326
1678
|
ariaLabel: copy.workspaces.dashboardViewsLabel,
|
|
@@ -1348,7 +1700,7 @@ function SettingsWorkspace({ chapter, ctx }) {
|
|
|
1348
1700
|
const active = ctx.route.viewId === "email" ? "email" : "calendar";
|
|
1349
1701
|
const calendar = availabilitySection({ id: "calendar", label: copy.workspaces.calendar });
|
|
1350
1702
|
const email = emailSection({ label: copy.workspaces.email });
|
|
1351
|
-
return /* @__PURE__ */
|
|
1703
|
+
return /* @__PURE__ */ jsx18(
|
|
1352
1704
|
Tabs2,
|
|
1353
1705
|
{
|
|
1354
1706
|
ariaLabel: copy.workspaces.settingsViewsLabel,
|
|
@@ -1376,7 +1728,7 @@ function PeopleWorkspace({ chapter, ctx }) {
|
|
|
1376
1728
|
const fallback = types[0]?.[0] ?? "person";
|
|
1377
1729
|
const active = types.some(([type]) => type === ctx.route.viewId) ? ctx.route.viewId : fallback;
|
|
1378
1730
|
const networkSharing = chapter.network.targets.length > 0;
|
|
1379
|
-
return /* @__PURE__ */
|
|
1731
|
+
return /* @__PURE__ */ jsx18(
|
|
1380
1732
|
Tabs2,
|
|
1381
1733
|
{
|
|
1382
1734
|
ariaLabel: chapter.copy.admin.workspaces.collectionsLabel,
|
|
@@ -1406,8 +1758,8 @@ function PortfolioWorkspace({ chapter, ctx }) {
|
|
|
1406
1758
|
const types = Object.entries(chapter.crm.config.types).filter(([, def]) => def.workspace === "portfolio");
|
|
1407
1759
|
const fallback = types[0]?.[0] ?? "";
|
|
1408
1760
|
const active = types.some(([type]) => type === ctx.route.viewId) ? ctx.route.viewId : fallback;
|
|
1409
|
-
if (!active) return /* @__PURE__ */
|
|
1410
|
-
return /* @__PURE__ */
|
|
1761
|
+
if (!active) return /* @__PURE__ */ jsx18(LeaderNetworkOverview, { ctx });
|
|
1762
|
+
return /* @__PURE__ */ jsx18(
|
|
1411
1763
|
Tabs2,
|
|
1412
1764
|
{
|
|
1413
1765
|
ariaLabel: copy.workspaces.portfolioViewsLabel,
|
|
@@ -1431,7 +1783,7 @@ function PortfolioWorkspace({ chapter, ctx }) {
|
|
|
1431
1783
|
);
|
|
1432
1784
|
}
|
|
1433
1785
|
function LeaderDashboardWorkspace({ chapter, ctx }) {
|
|
1434
|
-
return /* @__PURE__ */
|
|
1786
|
+
return /* @__PURE__ */ jsx18(
|
|
1435
1787
|
Tabs2,
|
|
1436
1788
|
{
|
|
1437
1789
|
ariaLabel: chapter.copy.admin.workspaces.dashboardViewsLabel,
|
|
@@ -1441,14 +1793,14 @@ function LeaderDashboardWorkspace({ chapter, ctx }) {
|
|
|
1441
1793
|
value: "overview",
|
|
1442
1794
|
label: chapter.copy.admin.workspaces.overview,
|
|
1443
1795
|
href: ctx.href({ viewId: "overview", recordId: null, detailTab: null }),
|
|
1444
|
-
panel: /* @__PURE__ */
|
|
1796
|
+
panel: /* @__PURE__ */ jsx18(LeaderNetworkOverview, { ctx: adminViewContext(ctx, "overview", true) })
|
|
1445
1797
|
}]
|
|
1446
1798
|
}
|
|
1447
1799
|
);
|
|
1448
1800
|
}
|
|
1449
1801
|
function LeaderSettingsWorkspace({ chapter, ctx }) {
|
|
1450
1802
|
const email = emailSection({ label: chapter.copy.admin.workspaces.email });
|
|
1451
|
-
return /* @__PURE__ */
|
|
1803
|
+
return /* @__PURE__ */ jsx18(
|
|
1452
1804
|
Tabs2,
|
|
1453
1805
|
{
|
|
1454
1806
|
ariaLabel: chapter.copy.admin.workspaces.settingsViewsLabel,
|
|
@@ -1469,7 +1821,7 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1469
1821
|
id: "people",
|
|
1470
1822
|
label: copy.workspaces.people,
|
|
1471
1823
|
defaultViewId: Object.keys(chapter.crm.config.types)[0] ?? "person",
|
|
1472
|
-
render: (ctx) => /* @__PURE__ */
|
|
1824
|
+
render: (ctx) => /* @__PURE__ */ jsx18(PeopleWorkspace, { chapter, ctx })
|
|
1473
1825
|
};
|
|
1474
1826
|
if (chapter.mode === "hub" && chapter.network.targets.length === 0) return [people];
|
|
1475
1827
|
if (chapter.mode === "hub") {
|
|
@@ -1479,20 +1831,21 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1479
1831
|
id: "dashboard",
|
|
1480
1832
|
label: copy.workspaces.dashboard,
|
|
1481
1833
|
defaultViewId: "overview",
|
|
1482
|
-
render: (ctx) => /* @__PURE__ */
|
|
1834
|
+
render: (ctx) => /* @__PURE__ */ jsx18(LeaderDashboardWorkspace, { chapter, ctx })
|
|
1483
1835
|
},
|
|
1836
|
+
networkRecordsWorkspace(chapter),
|
|
1484
1837
|
people,
|
|
1485
1838
|
{
|
|
1486
1839
|
id: "portfolio",
|
|
1487
1840
|
label: copy.workspaces.portfolio,
|
|
1488
1841
|
defaultViewId: portfolioTypes[0]?.[0],
|
|
1489
|
-
render: (ctx) => /* @__PURE__ */
|
|
1842
|
+
render: (ctx) => /* @__PURE__ */ jsx18(PortfolioWorkspace, { chapter, ctx })
|
|
1490
1843
|
},
|
|
1491
1844
|
{
|
|
1492
1845
|
id: "settings",
|
|
1493
1846
|
label: copy.workspaces.settings,
|
|
1494
1847
|
defaultViewId: "email",
|
|
1495
|
-
render: (ctx) => /* @__PURE__ */
|
|
1848
|
+
render: (ctx) => /* @__PURE__ */ jsx18(LeaderSettingsWorkspace, { chapter, ctx })
|
|
1496
1849
|
}
|
|
1497
1850
|
];
|
|
1498
1851
|
}
|
|
@@ -1501,24 +1854,24 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1501
1854
|
id: "dashboard",
|
|
1502
1855
|
label: copy.workspaces.dashboard,
|
|
1503
1856
|
defaultViewId: "overview",
|
|
1504
|
-
render: (ctx) => /* @__PURE__ */
|
|
1857
|
+
render: (ctx) => /* @__PURE__ */ jsx18(DashboardWorkspace, { chapter, ctx })
|
|
1505
1858
|
},
|
|
1506
1859
|
people,
|
|
1507
1860
|
{
|
|
1508
1861
|
id: "settings",
|
|
1509
1862
|
label: copy.workspaces.settings,
|
|
1510
1863
|
defaultViewId: "calendar",
|
|
1511
|
-
render: (ctx) => /* @__PURE__ */
|
|
1864
|
+
render: (ctx) => /* @__PURE__ */ jsx18(SettingsWorkspace, { chapter, ctx })
|
|
1512
1865
|
}
|
|
1513
1866
|
];
|
|
1514
1867
|
}
|
|
1515
1868
|
|
|
1516
1869
|
// src/ui/admin-frame.tsx
|
|
1517
1870
|
import { ThemeScope as ThemeScope2 } from "@odla-ai/ui/components";
|
|
1518
|
-
import { jsx as
|
|
1871
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "preact/jsx-runtime";
|
|
1519
1872
|
function AdminTheme(props) {
|
|
1520
1873
|
const brand = props.chapter?.brand;
|
|
1521
|
-
return /* @__PURE__ */
|
|
1874
|
+
return /* @__PURE__ */ jsx19(ChapterCopyProvider, { copy: props.chapter?.copy, children: /* @__PURE__ */ jsxs15(
|
|
1522
1875
|
ThemeScope2,
|
|
1523
1876
|
{
|
|
1524
1877
|
ref: props.scopeRef,
|
|
@@ -1527,7 +1880,7 @@ function AdminTheme(props) {
|
|
|
1527
1880
|
accent: brand?.accent,
|
|
1528
1881
|
colorScheme: brand?.colorScheme ?? "light",
|
|
1529
1882
|
children: [
|
|
1530
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx19(BrandStyle, { brand, selector: "[data-chapter-admin]" }),
|
|
1531
1884
|
props.children
|
|
1532
1885
|
]
|
|
1533
1886
|
}
|
|
@@ -1547,11 +1900,11 @@ function signInRedirect(basePath, workspaces) {
|
|
|
1547
1900
|
}
|
|
1548
1901
|
|
|
1549
1902
|
// src/ui/admin-appearance.ts
|
|
1550
|
-
import { useEffect as
|
|
1903
|
+
import { useEffect as useEffect8, useState as useState13 } from "preact/hooks";
|
|
1551
1904
|
import { clerkAppearanceFromTokens } from "@odla-ai/auth-clerk";
|
|
1552
1905
|
function useScopedClerkAppearance(scope) {
|
|
1553
|
-
const [appearance, setAppearance] =
|
|
1554
|
-
|
|
1906
|
+
const [appearance, setAppearance] = useState13();
|
|
1907
|
+
useEffect8(() => {
|
|
1555
1908
|
setAppearance(clerkAppearanceFromTokens(scope.current ?? void 0));
|
|
1556
1909
|
}, [scope]);
|
|
1557
1910
|
return appearance;
|
|
@@ -1582,7 +1935,7 @@ async function loadChapterAdminUser(adapter, apiBase, getToken) {
|
|
|
1582
1935
|
}
|
|
1583
1936
|
|
|
1584
1937
|
// src/ui/admin.tsx
|
|
1585
|
-
import { jsx as
|
|
1938
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "preact/jsx-runtime";
|
|
1586
1939
|
function Authed(props) {
|
|
1587
1940
|
const copy = useChapterCopy().admin;
|
|
1588
1941
|
const {
|
|
@@ -1599,7 +1952,7 @@ function Authed(props) {
|
|
|
1599
1952
|
renderWorkspaceNav
|
|
1600
1953
|
} = props;
|
|
1601
1954
|
const { getToken, signOut } = useClerkAuth();
|
|
1602
|
-
const client =
|
|
1955
|
+
const client = useMemo2(
|
|
1603
1956
|
() => new CrmClient({
|
|
1604
1957
|
basePath: crmBasePath,
|
|
1605
1958
|
headers: async () => {
|
|
@@ -1609,8 +1962,8 @@ function Authed(props) {
|
|
|
1609
1962
|
}),
|
|
1610
1963
|
[getToken, crmBasePath]
|
|
1611
1964
|
);
|
|
1612
|
-
const [state, setState] =
|
|
1613
|
-
|
|
1965
|
+
const [state, setState] = useState14({ status: "checking" });
|
|
1966
|
+
useEffect9(() => {
|
|
1614
1967
|
let live = true;
|
|
1615
1968
|
void (async () => {
|
|
1616
1969
|
try {
|
|
@@ -1629,17 +1982,17 @@ function Authed(props) {
|
|
|
1629
1982
|
live = false;
|
|
1630
1983
|
};
|
|
1631
1984
|
}, [getToken, apiBase, auth]);
|
|
1632
|
-
if (state.status === "checking") return /* @__PURE__ */
|
|
1985
|
+
if (state.status === "checking") return /* @__PURE__ */ jsx20(Gate, { brand, children: /* @__PURE__ */ jsx20("p", { style: S.muted, children: copy.auth.checking }) });
|
|
1633
1986
|
if (state.status === "denied") {
|
|
1634
|
-
return /* @__PURE__ */
|
|
1635
|
-
/* @__PURE__ */
|
|
1636
|
-
/* @__PURE__ */
|
|
1987
|
+
return /* @__PURE__ */ jsx20(Gate, { brand, children: /* @__PURE__ */ jsxs16("div", { className: "card", style: S.card, children: [
|
|
1988
|
+
/* @__PURE__ */ jsx20("h2", { style: { marginTop: 0 }, children: copy.auth.notAuthorized }),
|
|
1989
|
+
/* @__PURE__ */ jsx20("p", { style: S.muted, children: formatChapterCopy(copy.auth.accountNotAuthorized, {
|
|
1637
1990
|
account: state.email ?? copy.auth.thisAccount
|
|
1638
1991
|
}) }),
|
|
1639
|
-
/* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsx20("button", { className: "btn secondary", onClick: () => signOut(), children: copy.auth.signOut })
|
|
1640
1993
|
] }) });
|
|
1641
1994
|
}
|
|
1642
|
-
return /* @__PURE__ */
|
|
1995
|
+
return /* @__PURE__ */ jsx20(
|
|
1643
1996
|
AdminShell,
|
|
1644
1997
|
{
|
|
1645
1998
|
workspaces,
|
|
@@ -1660,11 +2013,11 @@ function Authed(props) {
|
|
|
1660
2013
|
}
|
|
1661
2014
|
function ChapterAdmin(props) {
|
|
1662
2015
|
const copy = props.chapter?.copy ?? DEFAULT_CHAPTER_COPY;
|
|
1663
|
-
const defaults =
|
|
2016
|
+
const defaults = useMemo2(
|
|
1664
2017
|
() => props.chapter ? defaultAdminWorkspaces(props.chapter) : [],
|
|
1665
2018
|
[props.chapter]
|
|
1666
2019
|
);
|
|
1667
|
-
const workspaces =
|
|
2020
|
+
const workspaces = useMemo2(() => {
|
|
1668
2021
|
if (typeof props.workspaces === "function") return props.workspaces(defaults);
|
|
1669
2022
|
return props.workspaces ?? props.sections ?? defaults;
|
|
1670
2023
|
}, [props.workspaces, props.sections, defaults]);
|
|
@@ -1680,10 +2033,10 @@ function ChapterAdmin(props) {
|
|
|
1680
2033
|
const chrome = props.chrome ?? "embedded";
|
|
1681
2034
|
const auth = props.auth ?? DEFAULT_ADMIN_AUTH;
|
|
1682
2035
|
const redirect = signInRedirect(basePath, workspaces);
|
|
1683
|
-
const [publishableKey, setPublishableKey] =
|
|
2036
|
+
const [publishableKey, setPublishableKey] = useState14(void 0);
|
|
1684
2037
|
const scopeRef = useRef(null);
|
|
1685
2038
|
const appearance = useScopedClerkAppearance(scopeRef);
|
|
1686
|
-
|
|
2039
|
+
useEffect9(() => {
|
|
1687
2040
|
let live = true;
|
|
1688
2041
|
void loadChapterAdminConfig(auth, apiBase).then((config) => live && setPublishableKey(config.publishableKey ?? null)).catch(() => live && setPublishableKey(null));
|
|
1689
2042
|
return () => {
|
|
@@ -1692,23 +2045,23 @@ function ChapterAdmin(props) {
|
|
|
1692
2045
|
}, [apiBase, auth]);
|
|
1693
2046
|
let content;
|
|
1694
2047
|
if (publishableKey === void 0 || publishableKey && !appearance) {
|
|
1695
|
-
content = /* @__PURE__ */
|
|
2048
|
+
content = /* @__PURE__ */ jsx20(Gate, { brand, children: /* @__PURE__ */ jsx20("p", { style: S.muted, children: copy.admin.auth.loading }) });
|
|
1696
2049
|
} else if (!publishableKey) {
|
|
1697
|
-
content = /* @__PURE__ */
|
|
1698
|
-
/* @__PURE__ */
|
|
1699
|
-
/* @__PURE__ */
|
|
2050
|
+
content = /* @__PURE__ */ jsx20(Gate, { brand, children: /* @__PURE__ */ jsxs16("div", { className: "card", style: S.card, children: [
|
|
2051
|
+
/* @__PURE__ */ jsx20("h2", { style: { marginTop: 0 }, children: copy.admin.auth.signInNotConfigured }),
|
|
2052
|
+
/* @__PURE__ */ jsx20("p", { style: S.muted, children: copy.admin.auth.missingPublishableKey })
|
|
1700
2053
|
] }) });
|
|
1701
2054
|
} else if (workspaces.length === 0) {
|
|
1702
|
-
content = /* @__PURE__ */
|
|
2055
|
+
content = /* @__PURE__ */ jsx20(Gate, { brand, children: /* @__PURE__ */ jsx20("p", { style: S.muted, children: copy.admin.auth.noWorkspaces }) });
|
|
1703
2056
|
} else {
|
|
1704
|
-
content = /* @__PURE__ */
|
|
2057
|
+
content = /* @__PURE__ */ jsxs16(
|
|
1705
2058
|
ClerkGate,
|
|
1706
2059
|
{
|
|
1707
2060
|
publishableKey,
|
|
1708
2061
|
appearance,
|
|
1709
2062
|
afterSignOutUrl: "/",
|
|
1710
2063
|
children: [
|
|
1711
|
-
/* @__PURE__ */
|
|
2064
|
+
/* @__PURE__ */ jsx20(SignedOut, { children: /* @__PURE__ */ jsx20(Gate, { brand, tagline: copy.admin.auth.signInTagline, children: /* @__PURE__ */ jsx20(
|
|
1712
2065
|
SignIn,
|
|
1713
2066
|
{
|
|
1714
2067
|
routing: "hash",
|
|
@@ -1716,7 +2069,7 @@ function ChapterAdmin(props) {
|
|
|
1716
2069
|
signUpForceRedirectUrl: redirect
|
|
1717
2070
|
}
|
|
1718
2071
|
) }) }),
|
|
1719
|
-
/* @__PURE__ */
|
|
2072
|
+
/* @__PURE__ */ jsx20(SignedIn, { children: /* @__PURE__ */ jsx20(
|
|
1720
2073
|
Authed,
|
|
1721
2074
|
{
|
|
1722
2075
|
workspaces,
|
|
@@ -1736,7 +2089,7 @@ function ChapterAdmin(props) {
|
|
|
1736
2089
|
}
|
|
1737
2090
|
);
|
|
1738
2091
|
}
|
|
1739
|
-
return /* @__PURE__ */
|
|
2092
|
+
return /* @__PURE__ */ jsx20(AdminTheme, { chapter: props.chapter, scopeRef, children: content });
|
|
1740
2093
|
}
|
|
1741
2094
|
|
|
1742
2095
|
// src/ui/admin-defaults.ts
|
|
@@ -1745,17 +2098,17 @@ function defaultAdminSections(chapter) {
|
|
|
1745
2098
|
}
|
|
1746
2099
|
|
|
1747
2100
|
// src/ui/admin-meetings.tsx
|
|
1748
|
-
import { useState as
|
|
1749
|
-
import { Button as
|
|
1750
|
-
import { Fragment as Fragment4, jsx as
|
|
2101
|
+
import { useState as useState15 } from "preact/hooks";
|
|
2102
|
+
import { Button as Button7 } from "@odla-ai/ui/components";
|
|
2103
|
+
import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs17 } from "preact/jsx-runtime";
|
|
1751
2104
|
var when2 = (t) => new Date(t).toLocaleString([], { dateStyle: "medium", timeStyle: "short" });
|
|
1752
2105
|
function MeetingsBody({ ctx }) {
|
|
1753
2106
|
const copy = useChapterCopy().admin.meetings;
|
|
1754
2107
|
const { data, loading, error, refresh } = useAdminResource(ctx.getToken, "/api/admin/meetings?all=1");
|
|
1755
|
-
const [busy, setBusy] =
|
|
1756
|
-
const [note, setNote] =
|
|
1757
|
-
if (loading) return /* @__PURE__ */
|
|
1758
|
-
if (error || !data) return /* @__PURE__ */
|
|
2108
|
+
const [busy, setBusy] = useState15(null);
|
|
2109
|
+
const [note, setNote] = useState15(null);
|
|
2110
|
+
if (loading) return /* @__PURE__ */ jsx21(AdminNote, { children: copy.loading });
|
|
2111
|
+
if (error || !data) return /* @__PURE__ */ jsxs17(AdminNote, { children: [
|
|
1759
2112
|
copy.loadFailed,
|
|
1760
2113
|
error ? `: ${error}` : "",
|
|
1761
2114
|
"."
|
|
@@ -1786,32 +2139,32 @@ function MeetingsBody({ ctx }) {
|
|
|
1786
2139
|
}
|
|
1787
2140
|
void run(id, () => adminFetch(ctx.getToken, `/api/admin/meetings/${id}/reschedule`, { method: "POST", body: JSON.stringify({ startAt }) }));
|
|
1788
2141
|
};
|
|
1789
|
-
return /* @__PURE__ */
|
|
2142
|
+
return /* @__PURE__ */ jsx21(AdminPage, { children: /* @__PURE__ */ jsx21(Panel, { title: /* @__PURE__ */ jsxs17(Fragment4, { children: [
|
|
1790
2143
|
copy.agenda,
|
|
1791
2144
|
" ",
|
|
1792
|
-
/* @__PURE__ */
|
|
2145
|
+
/* @__PURE__ */ jsxs17("span", { className: "muted", style: { fontWeight: 400 }, children: [
|
|
1793
2146
|
"\xB7 ",
|
|
1794
2147
|
data.timezone
|
|
1795
2148
|
] })
|
|
1796
|
-
] }), actions: note ? /* @__PURE__ */
|
|
1797
|
-
/* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
1799
|
-
/* @__PURE__ */
|
|
1800
|
-
m.drift && m.drift !== "none" ? /* @__PURE__ */
|
|
2149
|
+
] }), actions: note ? /* @__PURE__ */ jsx21("span", { className: "muted", children: note }) : void 0, children: data.meetings.length === 0 ? /* @__PURE__ */ jsx21("p", { className: "muted", style: { margin: 0 }, children: copy.empty }) : /* @__PURE__ */ jsx21("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 12 }, children: data.meetings.map((m) => /* @__PURE__ */ jsxs17("li", { style: { display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap", opacity: m.status === "cancelled" ? 0.55 : 1 }, children: [
|
|
2150
|
+
/* @__PURE__ */ jsx21("strong", { style: { minWidth: 170 }, children: when2(m.startAt) }),
|
|
2151
|
+
/* @__PURE__ */ jsx21("span", { style: { flex: 1 }, children: m.applicant ? `${m.applicant.name} \xB7 ${m.applicant.email}` : copy.unknown }),
|
|
2152
|
+
/* @__PURE__ */ jsx21("span", { className: "badge", children: m.status }),
|
|
2153
|
+
m.drift && m.drift !== "none" ? /* @__PURE__ */ jsxs17("span", { className: "badge", children: [
|
|
1801
2154
|
copy.drift,
|
|
1802
2155
|
": ",
|
|
1803
2156
|
m.drift
|
|
1804
2157
|
] }) : null,
|
|
1805
|
-
m.meetUrl ? /* @__PURE__ */
|
|
1806
|
-
m.status === "scheduled" ? /* @__PURE__ */
|
|
1807
|
-
/* @__PURE__ */
|
|
1808
|
-
/* @__PURE__ */
|
|
2158
|
+
m.meetUrl ? /* @__PURE__ */ jsx21("a", { href: m.meetUrl, target: "_blank", rel: "noreferrer", children: copy.meet }) : null,
|
|
2159
|
+
m.status === "scheduled" ? /* @__PURE__ */ jsxs17(Fragment4, { children: [
|
|
2160
|
+
/* @__PURE__ */ jsx21(Button7, { variant: "secondary", mini: true, disabled: busy === m.id, onClick: () => reschedule(m.id), children: copy.reschedule }),
|
|
2161
|
+
/* @__PURE__ */ jsx21(Button7, { variant: "danger", mini: true, disabled: busy === m.id, onClick: () => cancel(m.id), children: copy.cancel })
|
|
1809
2162
|
] }) : null
|
|
1810
2163
|
] }, m.id)) }) }) });
|
|
1811
2164
|
}
|
|
1812
2165
|
function meetingsSection(options = {}) {
|
|
1813
2166
|
const { id = "meetings", label = "Meetings" } = options;
|
|
1814
|
-
return { id, label, render: (ctx) => /* @__PURE__ */
|
|
2167
|
+
return { id, label, render: (ctx) => /* @__PURE__ */ jsx21(MeetingsBody, { ctx }) };
|
|
1815
2168
|
}
|
|
1816
2169
|
|
|
1817
2170
|
export {
|
|
@@ -1834,6 +2187,8 @@ export {
|
|
|
1834
2187
|
applicationLifecycleAdapter,
|
|
1835
2188
|
collectionSection,
|
|
1836
2189
|
peopleSection,
|
|
2190
|
+
NetworkRecordsWorkspace,
|
|
2191
|
+
networkRecordsWorkspace,
|
|
1837
2192
|
LeaderNetworkOverview,
|
|
1838
2193
|
defaultAdminWorkspaces,
|
|
1839
2194
|
loadChapterAdminConfig,
|
|
@@ -1842,4 +2197,4 @@ export {
|
|
|
1842
2197
|
defaultAdminSections,
|
|
1843
2198
|
meetingsSection
|
|
1844
2199
|
};
|
|
1845
|
-
//# sourceMappingURL=chunk-
|
|
2200
|
+
//# sourceMappingURL=chunk-L2SA47IO.js.map
|