@codemem/server 0.31.4 → 0.32.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/dist/index.js +123 -7
- package/dist/index.js.map +1 -1
- package/dist/routes/sync.d.ts.map +1 -1
- package/package.json +3 -3
- package/static/app.js +394 -127
package/static/app.js
CHANGED
|
@@ -4122,6 +4122,7 @@
|
|
|
4122
4122
|
groupPreferencesDrafts: /* @__PURE__ */ new Map(),
|
|
4123
4123
|
groupScopeManagementOpen: /* @__PURE__ */ new Set(),
|
|
4124
4124
|
groupScopeManagementDrafts: /* @__PURE__ */ new Map(),
|
|
4125
|
+
teamSetupGuide: null,
|
|
4125
4126
|
availableProjects: []
|
|
4126
4127
|
};
|
|
4127
4128
|
//#endregion
|
|
@@ -7906,6 +7907,42 @@
|
|
|
7906
7907
|
for (const [deviceId, name] of next.entries()) coordinatorAdminState.deviceRenameDrafts.set(deviceId, name);
|
|
7907
7908
|
}
|
|
7908
7909
|
//#endregion
|
|
7910
|
+
//#region src/tabs/coordinator-admin/data/team-card.ts
|
|
7911
|
+
function matchingSetupGuide(groupId, setupGuide) {
|
|
7912
|
+
if (!setupGuide) return null;
|
|
7913
|
+
return setupGuide.groupId === groupId ? setupGuide : null;
|
|
7914
|
+
}
|
|
7915
|
+
function defaultSpaceSummary(preferences, setupGuide) {
|
|
7916
|
+
if (preferences?.loaded && preferences.default_space_scope_id) return "Configured";
|
|
7917
|
+
if (preferences?.loaded) return "Not configured";
|
|
7918
|
+
if (setupGuide?.defaultSpaceLabel) return setupGuide.defaultSpaceLabel;
|
|
7919
|
+
if (setupGuide?.defaultSpaceScopeId) return "Configured";
|
|
7920
|
+
return "Open Team defaults to inspect";
|
|
7921
|
+
}
|
|
7922
|
+
function autoGrantSummary(preferences, setupGuide) {
|
|
7923
|
+
if (preferences?.loaded) return preferences.auto_grant_default_space_on_join ? "On for the default Space" : "Off — Space access stays explicit";
|
|
7924
|
+
if (setupGuide?.autoGrantDefaultSpaceOnJoin === true) return "On for the default Space";
|
|
7925
|
+
if (setupGuide?.autoGrantDefaultSpaceOnJoin === false) return "Off — Space access stays explicit";
|
|
7926
|
+
return "Open Team defaults to inspect";
|
|
7927
|
+
}
|
|
7928
|
+
function activeSpaceCount(scopeManagement) {
|
|
7929
|
+
if (!scopeManagement?.loaded) return null;
|
|
7930
|
+
return scopeManagement.scopes.filter((scope) => String(scope.status || "active") === "active").length;
|
|
7931
|
+
}
|
|
7932
|
+
function spacesSummary(scopeManagement) {
|
|
7933
|
+
const count = activeSpaceCount(scopeManagement);
|
|
7934
|
+
if (count === null) return "Open Spaces to inspect access grants";
|
|
7935
|
+
return `${count} active ${count === 1 ? "Space" : "Spaces"}`;
|
|
7936
|
+
}
|
|
7937
|
+
function teamCardOverview(opts) {
|
|
7938
|
+
const setupGuide = matchingSetupGuide(opts.groupId, opts.setupGuide);
|
|
7939
|
+
return {
|
|
7940
|
+
autoGrant: autoGrantSummary(opts.preferences, setupGuide),
|
|
7941
|
+
defaultSpace: defaultSpaceSummary(opts.preferences, setupGuide),
|
|
7942
|
+
spaces: spacesSummary(opts.scopeManagement)
|
|
7943
|
+
};
|
|
7944
|
+
}
|
|
7945
|
+
//#endregion
|
|
7909
7946
|
//#region ../../node_modules/.pnpm/@radix-ui+react-dialog@1.1.15_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@radix-ui/react-dialog/dist/index.mjs
|
|
7910
7947
|
var DIALOG_NAME = "Dialog";
|
|
7911
7948
|
var [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);
|
|
@@ -10001,7 +10038,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10001
10038
|
//#region src/tabs/coordinator-admin/data/scope-management.ts
|
|
10002
10039
|
function scopeManagementReadinessMessage(summary) {
|
|
10003
10040
|
if (summary.readiness === "ready") return null;
|
|
10004
|
-
return "
|
|
10041
|
+
return "Space management needs the coordinator URL, target Team, and admin secret before it can list Spaces or change memberships.";
|
|
10005
10042
|
}
|
|
10006
10043
|
function scopeStatusLabel(status) {
|
|
10007
10044
|
const value = String(status || "active").trim();
|
|
@@ -10109,7 +10146,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10109
10146
|
...draftFor(groupId),
|
|
10110
10147
|
loaded: true,
|
|
10111
10148
|
loading: false,
|
|
10112
|
-
error: error instanceof Error ? error.message : "Failed to load
|
|
10149
|
+
error: error instanceof Error ? error.message : "Failed to load Spaces."
|
|
10113
10150
|
});
|
|
10114
10151
|
}
|
|
10115
10152
|
renderShell();
|
|
@@ -10132,7 +10169,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10132
10169
|
const label = draft.createLabel.trim();
|
|
10133
10170
|
const kind = draft.createKind.trim() || "team";
|
|
10134
10171
|
if (!scopeId || !label) {
|
|
10135
|
-
showGlobalNotice("Enter a
|
|
10172
|
+
showGlobalNotice("Enter a Space id and label before creating a Space.", "warning");
|
|
10136
10173
|
return;
|
|
10137
10174
|
}
|
|
10138
10175
|
setDraft(groupId, {
|
|
@@ -10157,14 +10194,14 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10157
10194
|
actionPendingKey: "",
|
|
10158
10195
|
actionPendingKind: ""
|
|
10159
10196
|
});
|
|
10160
|
-
showGlobalNotice("
|
|
10197
|
+
showGlobalNotice("Space created. Grant devices explicitly before data can sync.");
|
|
10161
10198
|
await loadGroupScopeManagement(groupId, renderShell, latest.includeInactive);
|
|
10162
10199
|
} catch (error) {
|
|
10163
10200
|
setDraft(groupId, {
|
|
10164
10201
|
...draftFor(groupId),
|
|
10165
10202
|
actionPendingKey: "",
|
|
10166
10203
|
actionPendingKind: "",
|
|
10167
|
-
error: error instanceof Error ? error.message : "Failed to create
|
|
10204
|
+
error: error instanceof Error ? error.message : "Failed to create Space."
|
|
10168
10205
|
});
|
|
10169
10206
|
renderShell();
|
|
10170
10207
|
}
|
|
@@ -10185,14 +10222,14 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10185
10222
|
device_id: deviceId,
|
|
10186
10223
|
role: "member"
|
|
10187
10224
|
});
|
|
10188
|
-
showGlobalNotice("Device granted access to the
|
|
10225
|
+
showGlobalNotice("Device granted access to the Space.");
|
|
10189
10226
|
await loadGroupScopeManagement(groupId, renderShell, draft.includeInactive);
|
|
10190
10227
|
} catch (error) {
|
|
10191
10228
|
setDraft(groupId, {
|
|
10192
10229
|
...draftFor(groupId),
|
|
10193
10230
|
actionPendingKey: "",
|
|
10194
10231
|
actionPendingKind: "",
|
|
10195
|
-
error: error instanceof Error ? error.message : "Failed to grant
|
|
10232
|
+
error: error instanceof Error ? error.message : "Failed to grant Space access."
|
|
10196
10233
|
});
|
|
10197
10234
|
renderShell();
|
|
10198
10235
|
}
|
|
@@ -10202,7 +10239,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10202
10239
|
if (!scopeId) return;
|
|
10203
10240
|
if (!await openSyncConfirmDialog({
|
|
10204
10241
|
title: `Revoke ${displayName || deviceId} from ${scope.label || scopeId}?`,
|
|
10205
|
-
description: "Revocation only blocks future sync for this
|
|
10242
|
+
description: "Revocation only blocks future sync for this Space. Data already copied to that device can remain there.",
|
|
10206
10243
|
confirmLabel: "Revoke membership",
|
|
10207
10244
|
cancelLabel: "Keep membership",
|
|
10208
10245
|
tone: "danger"
|
|
@@ -10219,14 +10256,14 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10219
10256
|
renderShell();
|
|
10220
10257
|
try {
|
|
10221
10258
|
await revokeCoordinatorAdminScopeMember(groupId, scopeId, deviceId);
|
|
10222
|
-
showGlobalNotice("
|
|
10259
|
+
showGlobalNotice("Space access revoked. Future sync is blocked for that device.");
|
|
10223
10260
|
await loadGroupScopeManagement(groupId, renderShell, draft.includeInactive);
|
|
10224
10261
|
} catch (error) {
|
|
10225
10262
|
setDraft(groupId, {
|
|
10226
10263
|
...draftFor(groupId),
|
|
10227
10264
|
actionPendingKey: "",
|
|
10228
10265
|
actionPendingKind: "",
|
|
10229
|
-
error: error instanceof Error ? error.message : "Failed to revoke
|
|
10266
|
+
error: error instanceof Error ? error.message : "Failed to revoke Space access."
|
|
10230
10267
|
});
|
|
10231
10268
|
renderShell();
|
|
10232
10269
|
}
|
|
@@ -10234,7 +10271,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10234
10271
|
function renderMembershipRows(groupId, scope, draft, ready, renderShell) {
|
|
10235
10272
|
const scopeId = String(scope.scope_id || "").trim();
|
|
10236
10273
|
const rows = deriveScopeMembershipDeviceRows(coordinatorAdminDevicesForGroup(draft.devices, state.lastCoordinatorAdminDevices, groupId, draft.devicesLoaded), draft.membersByScope.get(scopeId) ?? []);
|
|
10237
|
-
if (!rows.length) return _$3("div", { class: "peer-submeta coordinator-admin-empty-state" }, "No enrolled devices in this
|
|
10274
|
+
if (!rows.length) return _$3("div", { class: "peer-submeta coordinator-admin-empty-state" }, "No enrolled devices in this Team yet. Enroll a device before granting this Space.");
|
|
10238
10275
|
return _$3("div", { class: "coordinator-admin-scope-member-list" }, rows.map((row) => {
|
|
10239
10276
|
const pendingKey = `${draft.actionPendingKind}:${scopeId}:${row.deviceId}`;
|
|
10240
10277
|
const pending = draft.actionPendingKey === pendingKey;
|
|
@@ -10245,7 +10282,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10245
10282
|
return _$3("div", {
|
|
10246
10283
|
class: "coordinator-admin-scope-member-row",
|
|
10247
10284
|
key: row.deviceId
|
|
10248
|
-
}, _$3("div", { class: "coordinator-admin-scope-member-copy" }, _$3("strong", null, row.displayName), _$3("span", null, `${statusCopy} · ${row.role} · ${epochCopy}`), row.enabled ? null : _$3("span", null, "Device is disabled in this
|
|
10285
|
+
}, _$3("div", { class: "coordinator-admin-scope-member-copy" }, _$3("strong", null, row.displayName), _$3("span", null, `${statusCopy} · ${row.role} · ${epochCopy}`), row.enabled ? null : _$3("span", null, "Device is disabled in this Team.")), _$3("div", { class: "peer-actions" }, canGrant ? _$3("button", {
|
|
10249
10286
|
class: "settings-button",
|
|
10250
10287
|
disabled: !ready || Boolean(draft.actionPendingKey),
|
|
10251
10288
|
onClick: () => void grantMember(groupId, scopeId, row.deviceId, renderShell),
|
|
@@ -10260,11 +10297,11 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10260
10297
|
}
|
|
10261
10298
|
function renderScopeCard(groupId, scope, draft, ready, renderShell) {
|
|
10262
10299
|
const scopeId = String(scope.scope_id || "").trim();
|
|
10263
|
-
const label = String(scope.label || scopeId || "Untitled
|
|
10300
|
+
const label = String(scope.label || scopeId || "Untitled Space");
|
|
10264
10301
|
return _$3("div", {
|
|
10265
10302
|
class: "peer-card peer-card--padded coordinator-admin-scope-card",
|
|
10266
10303
|
key: scopeId || label
|
|
10267
|
-
}, _$3("div", { class: "peer-title" }, _$3("strong", null, label)), _$3("div", { class: "peer-
|
|
10304
|
+
}, _$3("div", { class: "peer-title" }, _$3("strong", null, label)), _$3("div", { class: "peer-submeta" }, `Status: ${scopeStatusLabel(scope.status)} · Kind: ${scope.kind || "user"}`), _$3("div", { class: "peer-meta" }, `Advanced: Space ID ${scopeId || "unknown"} · Membership epoch ${scope.membership_epoch ?? 0}`), _$3("div", { class: "peer-submeta" }, "Devices below are enrolled in the Team; only active Space members can sync this data boundary."), renderMembershipRows(groupId, scope, draft, ready, renderShell));
|
|
10268
10305
|
}
|
|
10269
10306
|
function renderGroupScopeManagementPanel(deps) {
|
|
10270
10307
|
const { groupId, ready, summary, renderShell } = deps;
|
|
@@ -10272,12 +10309,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10272
10309
|
if (!draft) return null;
|
|
10273
10310
|
const readinessMessage = scopeManagementReadinessMessage(summary);
|
|
10274
10311
|
if (readinessMessage) return _$3("div", { class: "peer-meta coordinator-admin-inline-warning" }, readinessMessage);
|
|
10275
|
-
if (!draft.loaded) return _$3("div", { class: "peer-submeta" }, "Loading
|
|
10312
|
+
if (!draft.loaded) return _$3("div", { class: "peer-submeta" }, "Loading Spaces…");
|
|
10276
10313
|
const disabled = !ready || Boolean(draft.actionPendingKey) || draft.loading;
|
|
10277
|
-
return _$3(k$3, null, _$3("h4", { class: "coordinator-admin-drawer-title" }, "
|
|
10314
|
+
return _$3(k$3, null, _$3("h4", { class: "coordinator-admin-drawer-title" }, "Spaces"), _$3("div", { class: "peer-submeta" }, "Teams discover and enroll devices. Spaces grant data access. Granting a device here is explicit; Team membership alone does not share memories."), _$3("label", { class: "coordinator-admin-inline-filter" }, _$3("span", {
|
|
10278
10315
|
class: "section-meta",
|
|
10279
10316
|
id: `coord-admin-domain-inactive-${groupId}`
|
|
10280
|
-
}, "Show inactive
|
|
10317
|
+
}, "Show inactive Spaces"), _$3(RadixSwitch, {
|
|
10281
10318
|
"aria-labelledby": `coord-admin-domain-inactive-${groupId}`,
|
|
10282
10319
|
checked: draft.includeInactive,
|
|
10283
10320
|
className: "coordinator-admin-switch",
|
|
@@ -10286,7 +10323,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10286
10323
|
loadGroupScopeManagement(groupId, renderShell, checked);
|
|
10287
10324
|
},
|
|
10288
10325
|
thumbClassName: "coordinator-admin-switch-thumb"
|
|
10289
|
-
})), _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "New
|
|
10326
|
+
})), _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "New Space id"), _$3(TextInput, {
|
|
10290
10327
|
class: "peer-scope-input",
|
|
10291
10328
|
disabled,
|
|
10292
10329
|
onInput: (event) => {
|
|
@@ -10327,12 +10364,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10327
10364
|
disabled,
|
|
10328
10365
|
onClick: () => void createScope(groupId, renderShell),
|
|
10329
10366
|
type: "button"
|
|
10330
|
-
}, draft.actionPendingKind === "create" ? "Creating…" : "Create
|
|
10367
|
+
}, draft.actionPendingKind === "create" ? "Creating…" : "Create Space"), _$3("button", {
|
|
10331
10368
|
class: "settings-button",
|
|
10332
10369
|
disabled,
|
|
10333
10370
|
onClick: () => void loadGroupScopeManagement(groupId, renderShell, draft.includeInactive),
|
|
10334
10371
|
type: "button"
|
|
10335
|
-
}, draft.loading ? "Refreshing…" : "Refresh")), draft.error ? _$3("div", { class: "peer-submeta coordinator-admin-error" }, draft.error) : null, draft.scopes.length ? _$3("div", { class: "coordinator-admin-scope-card-list" }, draft.scopes.map((scope) => renderScopeCard(groupId, scope, draft, ready, renderShell))) : _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, "No
|
|
10372
|
+
}, draft.loading ? "Refreshing…" : "Refresh")), draft.error ? _$3("div", { class: "peer-submeta coordinator-admin-error" }, draft.error) : null, draft.scopes.length ? _$3("div", { class: "coordinator-admin-scope-card-list" }, draft.scopes.map((scope) => renderScopeCard(groupId, scope, draft, ready, renderShell))) : _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, "No Spaces are defined for this Team yet. Create a Space, then grant specific devices. Projects stay local-only until assigned to a Space."));
|
|
10336
10373
|
}
|
|
10337
10374
|
//#endregion
|
|
10338
10375
|
//#region src/tabs/coordinator-admin/components/groups-panel.ts
|
|
@@ -10353,6 +10390,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10353
10390
|
projects_include: [],
|
|
10354
10391
|
projects_exclude: [],
|
|
10355
10392
|
auto_seed_scope: true,
|
|
10393
|
+
default_space_scope_id: "",
|
|
10394
|
+
auto_grant_default_space_on_join: false,
|
|
10356
10395
|
loaded: false,
|
|
10357
10396
|
saving: false,
|
|
10358
10397
|
error: ""
|
|
@@ -10369,6 +10408,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10369
10408
|
projects_include: Array.isArray(prefs.projects_include) ? [...prefs.projects_include] : [],
|
|
10370
10409
|
projects_exclude: Array.isArray(prefs.projects_exclude) ? [...prefs.projects_exclude] : [],
|
|
10371
10410
|
auto_seed_scope: prefs.auto_seed_scope,
|
|
10411
|
+
default_space_scope_id: prefs.default_space_scope_id || "",
|
|
10412
|
+
auto_grant_default_space_on_join: prefs.auto_grant_default_space_on_join === true,
|
|
10372
10413
|
loaded: true,
|
|
10373
10414
|
saving: false,
|
|
10374
10415
|
error: ""
|
|
@@ -10394,7 +10435,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10394
10435
|
const payload = {
|
|
10395
10436
|
projects_include: initial.projects_include.length > 0 ? [...initial.projects_include] : null,
|
|
10396
10437
|
projects_exclude: initial.projects_exclude.length > 0 ? [...initial.projects_exclude] : null,
|
|
10397
|
-
auto_seed_scope: initial.auto_seed_scope
|
|
10438
|
+
auto_seed_scope: initial.auto_seed_scope,
|
|
10439
|
+
default_space_scope_id: initial.default_space_scope_id || null,
|
|
10440
|
+
auto_grant_default_space_on_join: initial.auto_grant_default_space_on_join
|
|
10398
10441
|
};
|
|
10399
10442
|
coordinatorAdminState.groupPreferencesDrafts.set(groupId, {
|
|
10400
10443
|
...initial,
|
|
@@ -10404,7 +10447,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10404
10447
|
renderShell();
|
|
10405
10448
|
try {
|
|
10406
10449
|
await saveCoordinatorGroupPreferences(groupId, payload);
|
|
10407
|
-
showGlobalNotice("
|
|
10450
|
+
showGlobalNotice("Team defaults saved. New devices use these filters and Space settings.");
|
|
10408
10451
|
closeGroupPreferences(groupId, renderShell);
|
|
10409
10452
|
} catch (error) {
|
|
10410
10453
|
const latest = coordinatorAdminState.groupPreferencesDrafts.get(groupId);
|
|
@@ -10422,10 +10465,11 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10422
10465
|
if (!draft) return null;
|
|
10423
10466
|
if (!draft.loaded) return _$3("div", { class: "peer-submeta" }, "Loading project defaults…");
|
|
10424
10467
|
const autoSeedLabelId = `coord-admin-scope-autoseed-${groupId}`;
|
|
10468
|
+
const autoGrantLabelId = `coord-admin-default-space-autogrant-${groupId}`;
|
|
10425
10469
|
const includeLabelId = `coord-admin-scope-include-${groupId}`;
|
|
10426
10470
|
const excludeLabelId = `coord-admin-scope-exclude-${groupId}`;
|
|
10427
10471
|
const fieldsDisabled = !ready || draft.saving || !draft.auto_seed_scope;
|
|
10428
|
-
return _$3(k$3, null, _$3("h4", { class: "coordinator-admin-drawer-title" }, "
|
|
10472
|
+
return _$3(k$3, null, _$3("h4", { class: "coordinator-admin-drawer-title" }, "Team defaults"), _$3("div", { class: "peer-submeta" }, "Project filters only narrow what future writes sync; they never grant Space access by themselves. Use the default Space toggle to control whether newly joined devices receive the Team's default Space."), _$3("label", { class: "coordinator-admin-inline-filter" }, _$3("span", {
|
|
10429
10473
|
class: "section-meta",
|
|
10430
10474
|
id: autoSeedLabelId
|
|
10431
10475
|
}, "Auto-seed project filters"), _$3(RadixSwitch, {
|
|
@@ -10442,7 +10486,24 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10442
10486
|
renderShell();
|
|
10443
10487
|
},
|
|
10444
10488
|
thumbClassName: "coordinator-admin-switch-thumb"
|
|
10445
|
-
})), _$3("
|
|
10489
|
+
})), _$3("label", { class: "coordinator-admin-inline-filter" }, _$3("span", {
|
|
10490
|
+
class: "section-meta",
|
|
10491
|
+
id: autoGrantLabelId
|
|
10492
|
+
}, "Auto-grant default Space on join"), _$3(RadixSwitch, {
|
|
10493
|
+
"aria-labelledby": autoGrantLabelId,
|
|
10494
|
+
checked: draft.auto_grant_default_space_on_join,
|
|
10495
|
+
className: "coordinator-admin-switch",
|
|
10496
|
+
disabled: !ready || draft.saving || !draft.default_space_scope_id,
|
|
10497
|
+
onCheckedChange: (checked) => {
|
|
10498
|
+
const current = coordinatorAdminState.groupPreferencesDrafts.get(groupId) ?? draft;
|
|
10499
|
+
coordinatorAdminState.groupPreferencesDrafts.set(groupId, {
|
|
10500
|
+
...current,
|
|
10501
|
+
auto_grant_default_space_on_join: checked
|
|
10502
|
+
});
|
|
10503
|
+
renderShell();
|
|
10504
|
+
},
|
|
10505
|
+
thumbClassName: "coordinator-admin-switch-thumb"
|
|
10506
|
+
})), draft.default_space_scope_id ? _$3("div", { class: "peer-submeta" }, "Default Space configured.") : _$3("div", { class: "peer-submeta" }, "No default Space has been created yet."), _$3("div", { class: "coordinator-admin-field" }, _$3("span", { id: includeLabelId }, "Include projects"), _$3(ProjectScopePicker, {
|
|
10446
10507
|
"aria-labelledby": includeLabelId,
|
|
10447
10508
|
availableProjects: coordinatorAdminState.availableProjects,
|
|
10448
10509
|
disabled: fieldsDisabled,
|
|
@@ -10484,6 +10545,54 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10484
10545
|
type: "button"
|
|
10485
10546
|
}, "Cancel")));
|
|
10486
10547
|
}
|
|
10548
|
+
function renderTeamSetupGuide(renderShell) {
|
|
10549
|
+
const guide = coordinatorAdminState.teamSetupGuide;
|
|
10550
|
+
if (!guide) return null;
|
|
10551
|
+
const title = guide.displayName || guide.groupId;
|
|
10552
|
+
const warningStep = {
|
|
10553
|
+
default_space: "default Space setup",
|
|
10554
|
+
default_space_grant: "default Space access grant"
|
|
10555
|
+
}[guide.setupWarning?.step || ""] || "default Space setup";
|
|
10556
|
+
return _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, _$3("h4", { class: "coordinator-admin-drawer-title" }, `Set up ${title}`), _$3("div", { class: "peer-submeta" }, "A Team organizes people and devices. The default Space is the memory boundary; Team membership only grants data access when default Space auto-grant is enabled."), guide.setupWarning ? _$3("div", { class: "peer-meta coordinator-admin-inline-warning" }, `Team created, but ${warningStep} failed. Automatic repair is not available yet; use Spaces to inspect or create access manually before inviting teammates.`) : _$3("div", { class: "peer-submeta" }, guide.defaultSpaceScopeId ? guide.defaultSpaceLabel ? `Default Space ready: ${guide.defaultSpaceLabel}. New devices can receive this Space when auto-grant is enabled.` : "Default Space ready. New devices can receive this Space when auto-grant is enabled." : "Default Space status is unknown. Check Spaces before inviting teammates."), _$3("ol", { class: "peer-submeta" }, _$3("li", null, "Review Team defaults and the auto-grant default Space setting."), _$3("li", null, "Invite teammates or other devices."), _$3("li", null, "Assign projects to Spaces from the Projects tab.")), _$3("div", { class: "peer-actions" }, _$3("button", {
|
|
10557
|
+
class: "settings-button",
|
|
10558
|
+
onClick: () => {
|
|
10559
|
+
coordinatorAdminState.groupPreferencesOpen.add(guide.groupId);
|
|
10560
|
+
openGroupPreferences(guide.groupId, renderShell);
|
|
10561
|
+
},
|
|
10562
|
+
type: "button"
|
|
10563
|
+
}, "Review Team defaults"), _$3("button", {
|
|
10564
|
+
class: "settings-button",
|
|
10565
|
+
onClick: () => {
|
|
10566
|
+
openGroupScopeManagement(guide.groupId, renderShell);
|
|
10567
|
+
},
|
|
10568
|
+
type: "button"
|
|
10569
|
+
}, "Check Spaces"), _$3("button", {
|
|
10570
|
+
class: "settings-button",
|
|
10571
|
+
onClick: () => {
|
|
10572
|
+
coordinatorAdminState.inviteGroup = guide.groupId;
|
|
10573
|
+
coordinatorAdminState.activeSection = "invites";
|
|
10574
|
+
renderShell();
|
|
10575
|
+
},
|
|
10576
|
+
type: "button"
|
|
10577
|
+
}, "Invite devices"), _$3("button", {
|
|
10578
|
+
class: "settings-button",
|
|
10579
|
+
onClick: () => {
|
|
10580
|
+
window.location.hash = "projects";
|
|
10581
|
+
},
|
|
10582
|
+
type: "button"
|
|
10583
|
+
}, "Assign projects"), _$3("button", {
|
|
10584
|
+
class: "settings-button",
|
|
10585
|
+
onClick: () => {
|
|
10586
|
+
coordinatorAdminState.teamSetupGuide = null;
|
|
10587
|
+
renderShell();
|
|
10588
|
+
},
|
|
10589
|
+
type: "button"
|
|
10590
|
+
}, "Dismiss")));
|
|
10591
|
+
}
|
|
10592
|
+
function archiveButtonLabel(archived, pending) {
|
|
10593
|
+
if (pending) return archived ? "Restoring…" : "Archiving…";
|
|
10594
|
+
return archived ? "Unarchive" : "Archive";
|
|
10595
|
+
}
|
|
10487
10596
|
function renderGroupsPanel(deps) {
|
|
10488
10597
|
const { summary, createGroup, runGroup, renderShell, reloadData } = deps;
|
|
10489
10598
|
const configuredGroup = String(state.lastCoordinatorAdminStatus?.active_group || "").trim();
|
|
@@ -10498,7 +10607,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10498
10607
|
return _$3(RadixTabsContent, {
|
|
10499
10608
|
className: "coordinator-admin-panel",
|
|
10500
10609
|
value: "groups"
|
|
10501
|
-
}, _$3("h3", null, "
|
|
10610
|
+
}, _$3("h3", null, "Teams"), _$3("p", { class: "peer-submeta" }, selectedGroup ? `Managing ${selectedGroup}${configuredGroup && configuredGroup !== selectedGroup ? ` · this node uses ${configuredGroup} for discovery` : ""}` : configuredGroup ? `This node uses ${configuredGroup} for discovery. Select a Team below to manage it.` : "No Team selected yet. Create one or select an existing Team to manage."), groups.length ? _$3("p", { class: "peer-submeta" }, countParts.join(" · ")) : null, !targetExists && selectedGroup ? _$3("div", { class: "peer-meta coordinator-admin-inline-warning" }, `The selected Team (${selectedGroup}) is configured locally but does not exist in the coordinator yet. Create it below or switch to another Team once one exists.`) : null, renderTeamSetupGuide(renderShell), _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "New Team id"), _$3(TextInput, {
|
|
10502
10611
|
class: "peer-scope-input",
|
|
10503
10612
|
disabled: summary.readiness !== "ready" || coordinatorAdminState.groupActionPendingKind === "create",
|
|
10504
10613
|
onInput: (event) => {
|
|
@@ -10521,7 +10630,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10521
10630
|
disabled: summary.readiness !== "ready" || coordinatorAdminState.groupActionPendingKind === "create",
|
|
10522
10631
|
onClick: () => createGroup(),
|
|
10523
10632
|
type: "button"
|
|
10524
|
-
}, coordinatorAdminState.groupActionPendingKind === "create" ? "Creating…" : "Create
|
|
10633
|
+
}, coordinatorAdminState.groupActionPendingKind === "create" ? "Creating…" : "Create Team")), _$3("div", { class: "coordinator-admin-secondary-actions" }, _$3("label", { class: "coordinator-admin-inline-filter" }, _$3("span", {
|
|
10525
10634
|
class: "section-meta",
|
|
10526
10635
|
id: "coordinatorAdminShowArchivedLabel"
|
|
10527
10636
|
}, "Show archived"), _$3(RadixSwitch, {
|
|
@@ -10534,17 +10643,25 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10534
10643
|
renderShell();
|
|
10535
10644
|
},
|
|
10536
10645
|
thumbClassName: "coordinator-admin-switch-thumb"
|
|
10537
|
-
})))), !visibleGroups.length ? _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, summary.readiness === "ready" ? coordinatorAdminState.showArchivedGroups ? "No
|
|
10646
|
+
})))), !visibleGroups.length ? _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, summary.readiness === "ready" ? coordinatorAdminState.showArchivedGroups ? "No Teams are available yet." : "No active Teams yet. Create one to get started." : "Team browsing will appear here once setup is complete.") : _$3("div", { class: "peer-list" }, visibleGroups.map((group) => {
|
|
10538
10647
|
const selected = group.group_id === selectedGroup;
|
|
10539
10648
|
const pending = coordinatorAdminState.groupActionPendingId === group.group_id;
|
|
10540
10649
|
const archived = Boolean(group.archived_at);
|
|
10541
10650
|
const draftName = coordinatorAdminState.groupRenameDrafts.get(group.group_id) ?? group.display_name ?? group.group_id;
|
|
10542
10651
|
const scopeOpen = coordinatorAdminState.groupPreferencesOpen.has(group.group_id);
|
|
10543
10652
|
const domainsOpen = coordinatorAdminState.groupScopeManagementOpen.has(group.group_id);
|
|
10653
|
+
const archiveActionKind = archived ? "unarchive" : "archive";
|
|
10654
|
+
const archiveActionLabel = archiveButtonLabel(archived, pending && coordinatorAdminState.groupActionPendingKind === archiveActionKind);
|
|
10655
|
+
const overview = teamCardOverview({
|
|
10656
|
+
groupId: group.group_id,
|
|
10657
|
+
preferences: coordinatorAdminState.groupPreferencesDrafts.get(group.group_id),
|
|
10658
|
+
scopeManagement: coordinatorAdminState.groupScopeManagementDrafts.get(group.group_id),
|
|
10659
|
+
setupGuide: coordinatorAdminState.teamSetupGuide
|
|
10660
|
+
});
|
|
10544
10661
|
return _$3("div", {
|
|
10545
10662
|
class: "peer-card peer-card--padded",
|
|
10546
10663
|
key: group.group_id
|
|
10547
|
-
}, _$3("div", { class: "peer-title" }, _$3("strong", null, draftName)), _$3("div", { class: "peer-meta" }, `
|
|
10664
|
+
}, _$3("div", { class: "peer-title" }, _$3("strong", null, draftName)), _$3("div", { class: "peer-submeta" }, archived ? "Archived Team" : "Active Team"), _$3("div", { class: "peer-meta" }, `Advanced: Team ID ${group.group_id}`), _$3("div", { class: "coordinator-admin-summary-grid" }, _$3("div", { class: "coordinator-admin-summary-card" }, _$3("span", { class: "section-meta" }, "Default Space"), _$3("strong", null, overview.defaultSpace)), _$3("div", { class: "coordinator-admin-summary-card" }, _$3("span", { class: "section-meta" }, "Auto-grant"), _$3("strong", null, overview.autoGrant)), _$3("div", { class: "coordinator-admin-summary-card" }, _$3("span", { class: "section-meta" }, "Spaces"), _$3("strong", null, overview.spaces))), configuredGroup === group.group_id ? _$3("div", { class: "peer-submeta" }, "This node uses this Team for coordinator-backed discovery.") : null, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Display name"), _$3(TextInput, {
|
|
10548
10665
|
class: "peer-scope-input",
|
|
10549
10666
|
disabled: summary.readiness !== "ready" || pending,
|
|
10550
10667
|
onInput: (event) => {
|
|
@@ -10560,7 +10677,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10560
10677
|
reloadData();
|
|
10561
10678
|
},
|
|
10562
10679
|
type: "button"
|
|
10563
|
-
}, selected ? "Managing" : "Manage"), _$3("button", {
|
|
10680
|
+
}, selected ? "Managing" : "Manage Team"), _$3("button", {
|
|
10564
10681
|
class: "settings-button",
|
|
10565
10682
|
disabled: summary.readiness !== "ready" || pending,
|
|
10566
10683
|
onClick: () => runGroup(group.group_id, draftName, "rename"),
|
|
@@ -10576,12 +10693,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10576
10693
|
else openGroupPreferences(group.group_id, renderShell);
|
|
10577
10694
|
},
|
|
10578
10695
|
type: "button"
|
|
10579
|
-
}, _$3("span", null, "
|
|
10696
|
+
}, _$3("span", null, "Team defaults"), _$3("span", {
|
|
10580
10697
|
"aria-hidden": "true",
|
|
10581
10698
|
class: "device-row-chevron"
|
|
10582
10699
|
}, _$3(ChevronRightIcon$1, null))), _$3("button", {
|
|
10583
10700
|
"aria-expanded": domainsOpen,
|
|
10584
|
-
"aria-controls": `coord-admin-
|
|
10701
|
+
"aria-controls": `coord-admin-spaces-drawer-${group.group_id}`,
|
|
10585
10702
|
class: "settings-button coordinator-admin-scope-trigger",
|
|
10586
10703
|
"data-state": domainsOpen ? "open" : "closed",
|
|
10587
10704
|
disabled: summary.readiness !== "ready" || pending,
|
|
@@ -10590,15 +10707,15 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10590
10707
|
else openGroupScopeManagement(group.group_id, renderShell);
|
|
10591
10708
|
},
|
|
10592
10709
|
type: "button"
|
|
10593
|
-
}, _$3("span", null, "
|
|
10710
|
+
}, _$3("span", null, "Spaces & access"), _$3("span", {
|
|
10594
10711
|
"aria-hidden": "true",
|
|
10595
10712
|
class: "device-row-chevron"
|
|
10596
10713
|
}, _$3(ChevronRightIcon$1, null))), _$3("button", {
|
|
10597
10714
|
class: archived ? "settings-button" : "settings-button danger",
|
|
10598
10715
|
disabled: summary.readiness !== "ready" || pending,
|
|
10599
|
-
onClick: () => runGroup(group.group_id, group.display_name || group.group_id,
|
|
10716
|
+
onClick: () => runGroup(group.group_id, group.display_name || group.group_id, archiveActionKind),
|
|
10600
10717
|
type: "button"
|
|
10601
|
-
},
|
|
10718
|
+
}, archiveActionLabel)), _$3(Root$3, {
|
|
10602
10719
|
open: scopeOpen,
|
|
10603
10720
|
onOpenChange: (open) => {
|
|
10604
10721
|
if (open) openGroupPreferences(group.group_id, renderShell);
|
|
@@ -10615,9 +10732,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10615
10732
|
else closeGroupScopeManagement(group.group_id, renderShell);
|
|
10616
10733
|
}
|
|
10617
10734
|
}, _$3(Content$2, {
|
|
10618
|
-
"aria-label": `
|
|
10735
|
+
"aria-label": `Spaces for ${draftName}`,
|
|
10619
10736
|
class: "coordinator-admin-group-preferences coordinator-admin-domain-management",
|
|
10620
|
-
id: `coord-admin-
|
|
10737
|
+
id: `coord-admin-spaces-drawer-${group.group_id}`
|
|
10621
10738
|
}, domainsOpen ? renderGroupScopeManagementPanel({
|
|
10622
10739
|
groupId: group.group_id,
|
|
10623
10740
|
ready: summary.readiness === "ready",
|
|
@@ -10643,11 +10760,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10643
10760
|
return _$3(RadixTabsContent, {
|
|
10644
10761
|
className: "coordinator-admin-panel",
|
|
10645
10762
|
value: "invites"
|
|
10646
|
-
}, _$3("h3", null, "Create teammate invite"), _$3("p", { class: "peer-submeta" }, summary.readiness === "ready" ? "Generate
|
|
10763
|
+
}, _$3("h3", null, "Create teammate invite"), _$3("p", { class: "peer-submeta" }, summary.readiness === "ready" ? "Generate an invite for the selected Team. Default Space access is controlled by that Team's auto-grant setting." : "Finish setup first. Invite creation stays disabled until the local coordinator admin configuration is ready."), _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Team"), _$3(TextInput, {
|
|
10647
10764
|
class: "peer-scope-input",
|
|
10648
10765
|
disabled: summary.readiness !== "ready",
|
|
10649
10766
|
onInput: (event) => {
|
|
10650
10767
|
coordinatorAdminState.inviteGroup = String(event.currentTarget.value || "");
|
|
10768
|
+
renderShell();
|
|
10651
10769
|
},
|
|
10652
10770
|
placeholder: activeGroup || "team-alpha",
|
|
10653
10771
|
type: "text",
|
|
@@ -10664,10 +10782,10 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10664
10782
|
},
|
|
10665
10783
|
options: [{
|
|
10666
10784
|
value: "auto_admit",
|
|
10667
|
-
label: "Auto-admit"
|
|
10785
|
+
label: "Auto-admit to Team"
|
|
10668
10786
|
}, {
|
|
10669
10787
|
value: "approval_required",
|
|
10670
|
-
label: "
|
|
10788
|
+
label: "Require approval to join Team"
|
|
10671
10789
|
}],
|
|
10672
10790
|
triggerClassName: "sync-radix-select-trigger sync-actor-select",
|
|
10673
10791
|
value: coordinatorAdminState.invitePolicy,
|
|
@@ -10688,7 +10806,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10688
10806
|
createInvite();
|
|
10689
10807
|
},
|
|
10690
10808
|
type: "button"
|
|
10691
|
-
}, coordinatorAdminState.invitePending ? "Creating…" : "Create invite"), effectiveGroup ? _$3("span", { class: "peer-submeta" }, `Using
|
|
10809
|
+
}, coordinatorAdminState.invitePending ? "Creating…" : "Create invite"), effectiveGroup ? _$3("span", { class: "peer-submeta" }, `Using Team ${effectiveGroup}`) : null), output ? _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Generated invite"), _$3(TextArea, {
|
|
10692
10810
|
class: "feed-search coordinator-admin-output",
|
|
10693
10811
|
readOnly: true,
|
|
10694
10812
|
value: output
|
|
@@ -10735,22 +10853,39 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10735
10853
|
if (coordinatorAdminState.groupActionPendingKind) return;
|
|
10736
10854
|
const groupId = coordinatorAdminState.createGroupId.trim();
|
|
10737
10855
|
if (!groupId) {
|
|
10738
|
-
showGlobalNotice("Enter a
|
|
10856
|
+
showGlobalNotice("Enter a Team id before creating a Team.", "warning");
|
|
10739
10857
|
return;
|
|
10740
10858
|
}
|
|
10859
|
+
const requestedDisplayName = coordinatorAdminState.createGroupDisplayName.trim();
|
|
10741
10860
|
coordinatorAdminState.groupActionPendingKind = "create";
|
|
10742
10861
|
renderShell();
|
|
10743
10862
|
try {
|
|
10744
|
-
await createCoordinatorAdminGroup({
|
|
10863
|
+
const result = await createCoordinatorAdminGroup({
|
|
10745
10864
|
group_id: groupId,
|
|
10746
|
-
display_name:
|
|
10865
|
+
display_name: requestedDisplayName || null
|
|
10747
10866
|
});
|
|
10867
|
+
const defaultSpaceContainer = result.default_space;
|
|
10868
|
+
const defaultSpace = (defaultSpaceContainer && "scope" in defaultSpaceContainer ? defaultSpaceContainer.scope : defaultSpaceContainer) ?? {};
|
|
10869
|
+
const defaultSpacePreferences = defaultSpaceContainer && "preferences" in defaultSpaceContainer ? defaultSpaceContainer.preferences : null;
|
|
10870
|
+
const defaultSpaceScopeId = String(defaultSpace?.scope_id || "");
|
|
10748
10871
|
coordinatorAdminState.createGroupId = "";
|
|
10749
10872
|
coordinatorAdminState.createGroupDisplayName = "";
|
|
10750
|
-
|
|
10873
|
+
coordinatorAdminState.teamSetupGuide = {
|
|
10874
|
+
groupId,
|
|
10875
|
+
displayName: String(result.group?.display_name || requestedDisplayName || groupId),
|
|
10876
|
+
defaultSpaceScopeId,
|
|
10877
|
+
defaultSpaceLabel: String(defaultSpace?.label || ""),
|
|
10878
|
+
autoGrantDefaultSpaceOnJoin: typeof defaultSpacePreferences?.auto_grant_default_space_on_join === "boolean" ? defaultSpacePreferences.auto_grant_default_space_on_join : null,
|
|
10879
|
+
setupWarning: result.setup_warning || null
|
|
10880
|
+
};
|
|
10751
10881
|
await reloadData();
|
|
10882
|
+
setAdminTargetGroup(groupId);
|
|
10883
|
+
await reloadData();
|
|
10884
|
+
if (result.setup_warning) showGlobalNotice("Team created, but default Space setup needs repair.", "warning");
|
|
10885
|
+
else if (defaultSpaceScopeId) showGlobalNotice("Team created with a default Space.", "success");
|
|
10886
|
+
else showGlobalNotice("Team created, but default Space status is unknown.", "warning");
|
|
10752
10887
|
} catch (error) {
|
|
10753
|
-
showGlobalNotice(error instanceof Error ? error.message : "Failed to create
|
|
10888
|
+
showGlobalNotice(error instanceof Error ? error.message : "Failed to create Team.", "warning");
|
|
10754
10889
|
} finally {
|
|
10755
10890
|
coordinatorAdminState.groupActionPendingKind = "";
|
|
10756
10891
|
renderShell();
|
|
@@ -10760,9 +10895,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10760
10895
|
if (!groupId || coordinatorAdminState.groupActionPendingId) return;
|
|
10761
10896
|
if ((kind === "archive" || kind === "unarchive") && !await openSyncConfirmDialog({
|
|
10762
10897
|
title: `${kind === "archive" ? "Archive" : "Unarchive"} ${displayName || groupId}?`,
|
|
10763
|
-
description: kind === "archive" ? "Archived
|
|
10764
|
-
confirmLabel: kind === "archive" ? "Archive
|
|
10765
|
-
cancelLabel: kind === "archive" ? "Keep
|
|
10898
|
+
description: kind === "archive" ? "Archived Teams stay visible and restorable, but they stop being operational for new invites and joins." : "This Team will become operational again for invites and coordinator-backed joins.",
|
|
10899
|
+
confirmLabel: kind === "archive" ? "Archive Team" : "Unarchive Team",
|
|
10900
|
+
cancelLabel: kind === "archive" ? "Keep Team active" : "Keep Team archived",
|
|
10766
10901
|
tone: "danger"
|
|
10767
10902
|
})) return;
|
|
10768
10903
|
coordinatorAdminState.groupActionPendingId = groupId;
|
|
@@ -10771,19 +10906,19 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10771
10906
|
try {
|
|
10772
10907
|
if (kind === "rename") {
|
|
10773
10908
|
await renameCoordinatorAdminGroup(groupId, displayName);
|
|
10774
|
-
showGlobalNotice("
|
|
10909
|
+
showGlobalNotice("Team renamed.", "success");
|
|
10775
10910
|
}
|
|
10776
10911
|
if (kind === "archive") {
|
|
10777
10912
|
await archiveCoordinatorAdminGroup(groupId);
|
|
10778
|
-
showGlobalNotice("
|
|
10913
|
+
showGlobalNotice("Team archived.", "success");
|
|
10779
10914
|
}
|
|
10780
10915
|
if (kind === "unarchive") {
|
|
10781
10916
|
await unarchiveCoordinatorAdminGroup(groupId);
|
|
10782
|
-
showGlobalNotice("
|
|
10917
|
+
showGlobalNotice("Team unarchived.", "success");
|
|
10783
10918
|
}
|
|
10784
10919
|
await reloadData();
|
|
10785
10920
|
} catch (error) {
|
|
10786
|
-
showGlobalNotice(error instanceof Error ? error.message : `Failed to ${kind}
|
|
10921
|
+
showGlobalNotice(error instanceof Error ? error.message : `Failed to ${kind} Team.`, "warning");
|
|
10787
10922
|
} finally {
|
|
10788
10923
|
coordinatorAdminState.groupActionPendingId = "";
|
|
10789
10924
|
coordinatorAdminState.groupActionPendingKind = "";
|
|
@@ -10797,7 +10932,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10797
10932
|
const groupId = coordinatorAdminState.inviteGroup.trim() || defaultGroup;
|
|
10798
10933
|
const ttlHours = Number(coordinatorAdminState.inviteTtlHours);
|
|
10799
10934
|
if (!groupId) {
|
|
10800
|
-
showGlobalNotice("Choose a
|
|
10935
|
+
showGlobalNotice("Choose a Team before creating an invite.", "warning");
|
|
10801
10936
|
return;
|
|
10802
10937
|
}
|
|
10803
10938
|
if (!Number.isFinite(ttlHours) || ttlHours < 1) {
|
|
@@ -10829,8 +10964,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10829
10964
|
coordinatorAdminState.joinReviewPendingAction = action;
|
|
10830
10965
|
renderShell();
|
|
10831
10966
|
try {
|
|
10832
|
-
await reviewCoordinatorAdminJoinRequest(requestId, action);
|
|
10833
|
-
|
|
10967
|
+
const result = await reviewCoordinatorAdminJoinRequest(requestId, action);
|
|
10968
|
+
if (action === "approve" && result.setup_warning) showGlobalNotice("Join request approved, but default Space access needs repair.", "warning");
|
|
10969
|
+
else showGlobalNotice(action === "approve" ? "Join request approved." : "Join request denied.", "success");
|
|
10834
10970
|
await reloadData();
|
|
10835
10971
|
} catch (error) {
|
|
10836
10972
|
showGlobalNotice(error instanceof Error ? error.message : "Failed to review join request.", "warning");
|
|
@@ -10940,9 +11076,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10940
11076
|
const archivedGroupCount = availableCoordinatorGroups().filter((group) => group.archived_at).length;
|
|
10941
11077
|
const joinRequestCount = Array.isArray(state.lastCoordinatorAdminJoinRequests) ? state.lastCoordinatorAdminJoinRequests.length : 0;
|
|
10942
11078
|
const deviceCount = Array.isArray(state.lastCoordinatorAdminDevices) ? state.lastCoordinatorAdminDevices.length : 0;
|
|
10943
|
-
const headerMessage = summary.readiness !== "ready" ? summary.detail : targetArchived ? "The selected
|
|
11079
|
+
const headerMessage = summary.readiness !== "ready" ? summary.detail : targetArchived ? "The selected Team is archived. Restore it or switch Teams before creating invites." : "";
|
|
10944
11080
|
if (coordinatorAdminState.activeSection === "invites" && !invitesEnabled || coordinatorAdminState.activeSection === "groups" && !groupsEnabled || coordinatorAdminState.activeSection === "join-requests" && !joinRequestsEnabled || coordinatorAdminState.activeSection === "devices" && !devicesEnabled) coordinatorAdminState.activeSection = summary.readiness === "ready" ? "groups" : "invites";
|
|
10945
|
-
J$1(_$3("div", { class: "coordinator-admin-shell" }, _$3("div", { class: "card coordinator-admin-header" }, _$3("div", { class: "section-header" }, _$3("h2", null, "
|
|
11081
|
+
J$1(_$3("div", { class: "coordinator-admin-shell" }, _$3("div", { class: "card coordinator-admin-header" }, _$3("div", { class: "section-header" }, _$3("h2", null, "Teams")), _$3("div", { class: "coordinator-admin-summary-grid" }, _$3("div", { class: "coordinator-admin-summary-card" }, _$3("span", { class: "section-meta" }, "Team admin target"), _$3("strong", null, targetGroup || "None selected")), _$3("div", { class: "coordinator-admin-summary-card" }, _$3("span", { class: "section-meta" }, "Node discovery Team"), _$3("strong", null, activeGroup || "None")), _$3("div", { class: "coordinator-admin-summary-card" }, _$3("span", { class: "section-meta" }, "Teams"), _$3("strong", null, `${activeGroupCount} active${archivedGroupCount ? ` · ${archivedGroupCount} archived` : ""}`)), _$3("div", { class: "coordinator-admin-summary-card" }, _$3("span", { class: "section-meta" }, "Selected Team activity"), _$3("strong", null, `${joinRequestCount} join requests · ${deviceCount} devices`))), headerMessage ? _$3("div", { class: "peer-meta coordinator-admin-inline-warning" }, headerMessage) : null, coordinatorUrl ? _$3("div", { class: "section-meta coordinator-admin-inline-meta" }, `Coordinator: ${coordinatorUrl}`) : null), _$3("div", { class: "card coordinator-admin-sections" }, _$3(RadixTabs, {
|
|
10946
11082
|
ariaLabel: "Coordinator admin sections",
|
|
10947
11083
|
listClassName: "coordinator-admin-tabs-list",
|
|
10948
11084
|
onValueChange: (value) => {
|
|
@@ -10952,7 +11088,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10952
11088
|
tabs: [
|
|
10953
11089
|
{
|
|
10954
11090
|
value: "groups",
|
|
10955
|
-
label: "
|
|
11091
|
+
label: "Teams",
|
|
10956
11092
|
disabled: !groupsEnabled
|
|
10957
11093
|
},
|
|
10958
11094
|
{
|
|
@@ -10989,7 +11125,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10989
11125
|
}), renderDevicesPanel({
|
|
10990
11126
|
summary,
|
|
10991
11127
|
runDevice: (deviceId, groupId, displayName, kind) => void runDeviceAction(deviceId, groupId, displayName, kind)
|
|
10992
|
-
})), _$3("div", { class: "section-meta coordinator-admin-context-line" }, targetArchived ? `Selected
|
|
11128
|
+
})), _$3("div", { class: "section-meta coordinator-admin-context-line" }, targetArchived ? `Selected Team ${targetGroup || "—"} is archived. Switch or restore it to enable invite operations.` : targetGroup ? `Actions below apply to ${targetGroup}.` : "Select a Team to start managing people, Spaces, and access."))), mount);
|
|
10993
11129
|
}
|
|
10994
11130
|
function initCoordinatorAdminTab() {
|
|
10995
11131
|
renderShell();
|
|
@@ -14449,6 +14585,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14449
14585
|
var draftDomainSelections = /* @__PURE__ */ new Map();
|
|
14450
14586
|
var pendingConfirmations = /* @__PURE__ */ new Map();
|
|
14451
14587
|
var pendingForgetConfirmations = /* @__PURE__ */ new Map();
|
|
14588
|
+
var skippedProjectRefreshForActiveSelect = false;
|
|
14589
|
+
var coordinatorGroupNamesCurrent = false;
|
|
14452
14590
|
function el(id) {
|
|
14453
14591
|
return document.getElementById(id);
|
|
14454
14592
|
}
|
|
@@ -14457,7 +14595,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14457
14595
|
}
|
|
14458
14596
|
function formatResolution(reason) {
|
|
14459
14597
|
switch (reason) {
|
|
14460
|
-
case "exact_mapping": return "assigned to a
|
|
14598
|
+
case "exact_mapping": return "assigned to a Space";
|
|
14461
14599
|
case "pattern_mapping": return "assigned by matching rule";
|
|
14462
14600
|
case "explicit_override": return "manually assigned";
|
|
14463
14601
|
default: return "stays on this device";
|
|
@@ -14482,13 +14620,127 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14482
14620
|
function projectClusterLabel(project) {
|
|
14483
14621
|
return project.project || project.display_project || strongestSignal(project);
|
|
14484
14622
|
}
|
|
14485
|
-
function
|
|
14623
|
+
function teamName(groupId) {
|
|
14624
|
+
const normalized = String(groupId || "").trim();
|
|
14625
|
+
if (!normalized) return null;
|
|
14626
|
+
return state.lastCoordinatorAdminGroups.find((item) => String(item.group_id || "").trim() === normalized && !item.archived_at)?.display_name || "Team details unavailable";
|
|
14627
|
+
}
|
|
14628
|
+
function knownActiveCoordinatorGroupIds() {
|
|
14629
|
+
return new Set(state.lastCoordinatorAdminGroups.filter((item) => !item.archived_at).map((item) => String(item.group_id || "").trim()).filter(Boolean));
|
|
14630
|
+
}
|
|
14631
|
+
function isFromKnownInactiveCoordinatorGroup(scope) {
|
|
14632
|
+
if (!coordinatorGroupNamesCurrent || scope.authority_type !== "coordinator" || !scope.group_id) return false;
|
|
14633
|
+
return !knownActiveCoordinatorGroupIds().has(String(scope.group_id).trim());
|
|
14634
|
+
}
|
|
14635
|
+
function isProjectSpaceSelectActive() {
|
|
14636
|
+
const active = document.activeElement;
|
|
14637
|
+
return active instanceof HTMLSelectElement && active.classList.contains("project-domain-select");
|
|
14638
|
+
}
|
|
14639
|
+
function refreshSkippedProjectDataAfterSelectBlur() {
|
|
14640
|
+
if (!skippedProjectRefreshForActiveSelect) return;
|
|
14641
|
+
skippedProjectRefreshForActiveSelect = false;
|
|
14642
|
+
refreshProjects?.();
|
|
14643
|
+
}
|
|
14644
|
+
async function refreshProjectCoordinatorGroupNames() {
|
|
14645
|
+
try {
|
|
14646
|
+
const status = await loadCoordinatorAdminStatus();
|
|
14647
|
+
state.lastCoordinatorAdminStatus = status && typeof status === "object" ? status : null;
|
|
14648
|
+
} catch {
|
|
14649
|
+
state.lastCoordinatorAdminStatus = null;
|
|
14650
|
+
state.lastCoordinatorAdminGroups = [];
|
|
14651
|
+
coordinatorGroupNamesCurrent = false;
|
|
14652
|
+
return;
|
|
14653
|
+
}
|
|
14654
|
+
if (state.lastCoordinatorAdminStatus?.readiness !== "ready" || !state.lastCoordinatorAdminStatus.has_admin_secret) {
|
|
14655
|
+
state.lastCoordinatorAdminGroups = [];
|
|
14656
|
+
coordinatorGroupNamesCurrent = false;
|
|
14657
|
+
return;
|
|
14658
|
+
}
|
|
14659
|
+
try {
|
|
14660
|
+
const payload = await loadCoordinatorAdminGroupsFiltered(false);
|
|
14661
|
+
state.lastCoordinatorAdminGroups = Array.isArray(payload?.items) ? payload.items : [];
|
|
14662
|
+
coordinatorGroupNamesCurrent = true;
|
|
14663
|
+
} catch {
|
|
14664
|
+
state.lastCoordinatorAdminGroups = [];
|
|
14665
|
+
coordinatorGroupNamesCurrent = false;
|
|
14666
|
+
}
|
|
14667
|
+
}
|
|
14668
|
+
function isDefaultTeamSpace(scope) {
|
|
14669
|
+
return scope.kind === "team_default";
|
|
14670
|
+
}
|
|
14671
|
+
function spaceName(scope) {
|
|
14672
|
+
const label = scope.label || "Untitled Space";
|
|
14673
|
+
return isDefaultTeamSpace(scope) ? `${label} (default)` : label;
|
|
14674
|
+
}
|
|
14675
|
+
function spaceOptionName(scope, siblingScopes) {
|
|
14676
|
+
const label = spaceName(scope);
|
|
14677
|
+
return siblingScopes.some((sibling) => sibling.scope_id !== scope.scope_id && spaceName(sibling) === label) ? `${label} · Space ID ${scope.scope_id}` : label;
|
|
14678
|
+
}
|
|
14679
|
+
function spaceOwner(scope) {
|
|
14680
|
+
const team = teamName(scope.group_id);
|
|
14681
|
+
if (team) return `Team: ${team}`;
|
|
14682
|
+
if (scope.authority_type === "local") return "Local device";
|
|
14683
|
+
if (scope.authority_type === "coordinator") return "Coordinator Space";
|
|
14684
|
+
return `${scope.authority_type || "Other"} Space`;
|
|
14685
|
+
}
|
|
14686
|
+
function scopeById(scopeId) {
|
|
14687
|
+
if (!scopeId) return null;
|
|
14688
|
+
return scopes.find((item) => item.scope_id === scopeId) ?? null;
|
|
14689
|
+
}
|
|
14690
|
+
function scopeSummary(scopeId) {
|
|
14691
|
+
const scope = scopeById(scopeId);
|
|
14486
14692
|
if (!scopeId) return "—";
|
|
14487
|
-
|
|
14488
|
-
return scope?.label ? `${scope.label} (${scope.scope_id})` : scopeId;
|
|
14693
|
+
return scope ? `${spaceName(scope)} · ${spaceOwner(scope)}` : "Unknown Space";
|
|
14489
14694
|
}
|
|
14490
14695
|
function assignableScopes() {
|
|
14491
|
-
return scopes.filter((scope) => scope.scope_id !== "legacy-shared-review");
|
|
14696
|
+
return scopes.filter((scope) => scope.scope_id !== "legacy-shared-review" && !isFromKnownInactiveCoordinatorGroup(scope));
|
|
14697
|
+
}
|
|
14698
|
+
function isAssignableScopeId(scopeId) {
|
|
14699
|
+
return assignableScopes().some((scope) => scope.scope_id === scopeId);
|
|
14700
|
+
}
|
|
14701
|
+
function firstSafeSelection(...scopeIds) {
|
|
14702
|
+
for (const scopeId of scopeIds) if (scopeId && isAssignableScopeId(scopeId)) return scopeId;
|
|
14703
|
+
return scopeIds.find((scopeId) => Boolean(scopeId)) ?? "";
|
|
14704
|
+
}
|
|
14705
|
+
function scopeGroupLabel(scope) {
|
|
14706
|
+
const team = teamName(scope.group_id);
|
|
14707
|
+
if (team) return `Team: ${team}`;
|
|
14708
|
+
if (scope.authority_type === "local") return "Local device";
|
|
14709
|
+
if (scope.authority_type === "coordinator") return "Coordinator Spaces";
|
|
14710
|
+
return "Other Spaces";
|
|
14711
|
+
}
|
|
14712
|
+
function scopeGroupKey(scope) {
|
|
14713
|
+
if (scope.group_id) return `team:${scope.group_id}`;
|
|
14714
|
+
return `${scope.authority_type || "other"}:${scope.kind || "space"}`;
|
|
14715
|
+
}
|
|
14716
|
+
function groupedAssignableScopes() {
|
|
14717
|
+
const groups = /* @__PURE__ */ new Map();
|
|
14718
|
+
for (const scope of assignableScopes()) {
|
|
14719
|
+
const key = scopeGroupKey(scope);
|
|
14720
|
+
const label = scopeGroupLabel(scope);
|
|
14721
|
+
const current = groups.get(key) ?? {
|
|
14722
|
+
label,
|
|
14723
|
+
scopes: []
|
|
14724
|
+
};
|
|
14725
|
+
groups.set(key, {
|
|
14726
|
+
label: current.label,
|
|
14727
|
+
scopes: [...current.scopes, scope]
|
|
14728
|
+
});
|
|
14729
|
+
}
|
|
14730
|
+
return [...groups.values()];
|
|
14731
|
+
}
|
|
14732
|
+
function appendAssignableScopeOptions(select) {
|
|
14733
|
+
for (const group of groupedAssignableScopes()) {
|
|
14734
|
+
const optgroup = document.createElement("optgroup");
|
|
14735
|
+
optgroup.label = group.label;
|
|
14736
|
+
for (const scope of group.scopes) {
|
|
14737
|
+
const option = document.createElement("option");
|
|
14738
|
+
option.value = scope.scope_id;
|
|
14739
|
+
option.textContent = spaceOptionName(scope, group.scopes);
|
|
14740
|
+
optgroup.appendChild(option);
|
|
14741
|
+
}
|
|
14742
|
+
select.appendChild(optgroup);
|
|
14743
|
+
}
|
|
14492
14744
|
}
|
|
14493
14745
|
function guardrailHeading(warning) {
|
|
14494
14746
|
switch (warning.code) {
|
|
@@ -14511,7 +14763,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14511
14763
|
});
|
|
14512
14764
|
pendingConfirmations.delete(project.workspace_identity);
|
|
14513
14765
|
draftDomainSelections.delete(project.workspace_identity);
|
|
14514
|
-
showGlobalNotice("Project
|
|
14766
|
+
showGlobalNotice("Project Space assignment updated. Device access grants are unchanged.");
|
|
14515
14767
|
refreshProjects?.();
|
|
14516
14768
|
} catch (error) {
|
|
14517
14769
|
if (error instanceof SharingDomainGuardrailConfirmationError) {
|
|
@@ -14523,7 +14775,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14523
14775
|
refreshProjects?.();
|
|
14524
14776
|
return;
|
|
14525
14777
|
}
|
|
14526
|
-
showGlobalNotice(error instanceof Error ? error.message : "Unable to update project
|
|
14778
|
+
showGlobalNotice(error instanceof Error ? error.message : "Unable to update project Space.", "warning");
|
|
14527
14779
|
}
|
|
14528
14780
|
}
|
|
14529
14781
|
async function saveProjectClusterMapping(projects, scopeId) {
|
|
@@ -14539,7 +14791,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14539
14791
|
showGlobalNotice(`Updated ${assignable.length} project identit${assignable.length === 1 ? "y" : "ies"}. Device access grants are unchanged.`);
|
|
14540
14792
|
refreshProjects?.();
|
|
14541
14793
|
} catch (error) {
|
|
14542
|
-
showGlobalNotice(error instanceof SharingDomainGuardrailConfirmationError ? "One or more identities in this group need review before bulk assignment. Expand the group and save those identities directly." : error instanceof Error ? error.message : "Unable to update project
|
|
14794
|
+
showGlobalNotice(error instanceof SharingDomainGuardrailConfirmationError ? "One or more identities in this group need review before bulk assignment. Expand the group and save those identities directly." : error instanceof Error ? error.message : "Unable to update project Spaces.", "warning");
|
|
14543
14795
|
}
|
|
14544
14796
|
}
|
|
14545
14797
|
async function removeProjectMapping(project) {
|
|
@@ -14548,10 +14800,10 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14548
14800
|
await deleteSharingDomainProjectMapping(project.mapping_id);
|
|
14549
14801
|
pendingConfirmations.delete(project.workspace_identity);
|
|
14550
14802
|
draftDomainSelections.delete(project.workspace_identity);
|
|
14551
|
-
showGlobalNotice("Project
|
|
14803
|
+
showGlobalNotice("Project Space assignment removed. The next fallback now applies.");
|
|
14552
14804
|
refreshProjects?.();
|
|
14553
14805
|
} catch (error) {
|
|
14554
|
-
showGlobalNotice(error instanceof Error ? error.message : "Unable to remove project
|
|
14806
|
+
showGlobalNotice(error instanceof Error ? error.message : "Unable to remove project Space assignment.", "warning");
|
|
14555
14807
|
}
|
|
14556
14808
|
}
|
|
14557
14809
|
async function forgetProjectMemories(project, confirmed = false) {
|
|
@@ -14588,7 +14840,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14588
14840
|
const nextProject = await openSyncInputDialog({
|
|
14589
14841
|
cancelLabel: "Cancel",
|
|
14590
14842
|
confirmLabel: "Change project",
|
|
14591
|
-
description: `This will update ${project.session_count} session${project.session_count === 1 ? "" : "s"} and ${project.memory_count ?? 0} memor${project.memory_count === 1 ? "y" : "ies"} by changing the stored project.
|
|
14843
|
+
description: `This will update ${project.session_count} session${project.session_count === 1 ? "" : "s"} and ${project.memory_count ?? 0} memor${project.memory_count === 1 ? "y" : "ies"} by changing the stored project. Space assignment stays unchanged.`,
|
|
14592
14844
|
initialValue: currentProject,
|
|
14593
14845
|
placeholder: "Project name",
|
|
14594
14846
|
suggestions,
|
|
@@ -14626,7 +14878,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14626
14878
|
label.className = "sr-only";
|
|
14627
14879
|
const selectId = `project-domain-${project.workspace_identity.replace(/[^a-z0-9_-]/gi, "-")}`;
|
|
14628
14880
|
label.htmlFor = selectId;
|
|
14629
|
-
label.textContent = `
|
|
14881
|
+
label.textContent = `Space for ${project.display_project}`;
|
|
14630
14882
|
const select = document.createElement("select");
|
|
14631
14883
|
select.id = selectId;
|
|
14632
14884
|
select.className = "project-domain-select";
|
|
@@ -14634,30 +14886,27 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14634
14886
|
if (!currentAssignable && project.resolved_scope_id) {
|
|
14635
14887
|
const current = document.createElement("option");
|
|
14636
14888
|
current.value = project.resolved_scope_id;
|
|
14637
|
-
current.textContent = `${
|
|
14889
|
+
current.textContent = `${scopeSummary(project.resolved_scope_id)} — not assignable`;
|
|
14638
14890
|
current.disabled = true;
|
|
14639
14891
|
select.appendChild(current);
|
|
14640
14892
|
}
|
|
14641
|
-
|
|
14642
|
-
|
|
14643
|
-
option.value = scope.scope_id;
|
|
14644
|
-
option.textContent = scope.label ? `${scope.label} · ${scope.scope_id}` : scope.scope_id;
|
|
14645
|
-
select.appendChild(option);
|
|
14646
|
-
}
|
|
14647
|
-
select.value = draftDomainSelections.get(project.workspace_identity) ?? project.suggested_scope_id ?? project.resolved_scope_id;
|
|
14893
|
+
appendAssignableScopeOptions(select);
|
|
14894
|
+
select.value = firstSafeSelection(draftDomainSelections.get(project.workspace_identity), project.suggested_scope_id, project.resolved_scope_id);
|
|
14648
14895
|
const save = document.createElement("button");
|
|
14649
14896
|
save.className = "settings-button";
|
|
14650
14897
|
save.type = "button";
|
|
14651
|
-
save.textContent = project.suggested_scope_id && select.value === project.suggested_scope_id ? "Confirm suggestion" : "Save
|
|
14652
|
-
save.disabled = select.value === project.resolved_scope_id && !currentAssignable;
|
|
14898
|
+
save.textContent = project.suggested_scope_id && select.value === project.suggested_scope_id ? "Confirm suggestion" : "Save Space";
|
|
14899
|
+
save.disabled = !select.value || select.value === project.resolved_scope_id && !currentAssignable;
|
|
14653
14900
|
save.addEventListener("click", () => void saveProjectMapping(project, select.value));
|
|
14654
14901
|
select.addEventListener("change", () => {
|
|
14655
14902
|
draftDomainSelections.set(project.workspace_identity, select.value);
|
|
14656
14903
|
pendingConfirmations.delete(project.workspace_identity);
|
|
14657
|
-
|
|
14658
|
-
save.
|
|
14904
|
+
actions.querySelector(".project-space-guardrail-confirmation")?.remove();
|
|
14905
|
+
save.textContent = "Save Space";
|
|
14906
|
+
save.disabled = !select.value;
|
|
14659
14907
|
refreshProjects?.();
|
|
14660
14908
|
});
|
|
14909
|
+
select.addEventListener("blur", refreshSkippedProjectDataAfterSelectBlur);
|
|
14661
14910
|
const keepLocal = document.createElement("button");
|
|
14662
14911
|
keepLocal.className = "settings-button";
|
|
14663
14912
|
keepLocal.type = "button";
|
|
@@ -14686,10 +14935,10 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14686
14935
|
const pending = pendingConfirmations.get(project.workspace_identity);
|
|
14687
14936
|
if (pending) {
|
|
14688
14937
|
const warningBox = document.createElement("div");
|
|
14689
|
-
warningBox.className = "settings-note project-guardrail-confirmation";
|
|
14938
|
+
warningBox.className = "settings-note project-guardrail-confirmation project-space-guardrail-confirmation";
|
|
14690
14939
|
warningBox.setAttribute("role", "alert");
|
|
14691
14940
|
const title = document.createElement("strong");
|
|
14692
|
-
title.textContent = "Confirmation required before saving this
|
|
14941
|
+
title.textContent = "Confirmation required before saving this Space.";
|
|
14693
14942
|
const intro = document.createElement("p");
|
|
14694
14943
|
intro.textContent = "Codemem can save this change after you acknowledge the checks below. Verify the workspace details, then confirm to complete the save.";
|
|
14695
14944
|
const list = document.createElement("ul");
|
|
@@ -14705,7 +14954,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14705
14954
|
const confirm = document.createElement("button");
|
|
14706
14955
|
confirm.className = "settings-button";
|
|
14707
14956
|
confirm.type = "button";
|
|
14708
|
-
confirm.textContent = "I understand, save
|
|
14957
|
+
confirm.textContent = "I understand, save Space";
|
|
14709
14958
|
confirm.addEventListener("click", () => {
|
|
14710
14959
|
const currentPending = pendingConfirmations.get(project.workspace_identity);
|
|
14711
14960
|
if (!currentPending || currentPending.scopeId !== select.value) return;
|
|
@@ -14762,7 +15011,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14762
15011
|
header.appendChild(title);
|
|
14763
15012
|
const domain = document.createElement("div");
|
|
14764
15013
|
domain.className = "project-inventory-domain";
|
|
14765
|
-
domain.textContent =
|
|
15014
|
+
domain.textContent = scopeSummary(project.resolved_scope_id);
|
|
14766
15015
|
header.appendChild(domain);
|
|
14767
15016
|
row.appendChild(header);
|
|
14768
15017
|
const meta = document.createElement("div");
|
|
@@ -14776,7 +15025,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14776
15025
|
if (project.suggested_scope_id && project.suggested_scope_id !== project.resolved_scope_id) {
|
|
14777
15026
|
const suggestion = document.createElement("div");
|
|
14778
15027
|
suggestion.className = "settings-note project-suggestion-note";
|
|
14779
|
-
suggestion.textContent = project.suggestion_reason ? `Suggestion: ${project.suggestion_reason}` : `Suggestion:
|
|
15028
|
+
suggestion.textContent = project.suggestion_reason ? `Suggestion: ${project.suggestion_reason}` : `Suggestion: assign this project to ${scopeSummary(project.suggested_scope_id)}.`;
|
|
14780
15029
|
row.appendChild(suggestion);
|
|
14781
15030
|
}
|
|
14782
15031
|
const warnings = project.guardrail_warnings.filter((warning) => warning.severity === "warning");
|
|
@@ -14815,7 +15064,10 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14815
15064
|
["CWD", project.cwd],
|
|
14816
15065
|
["Git remote", project.git_remote],
|
|
14817
15066
|
["Git branch", project.git_branch],
|
|
14818
|
-
["
|
|
15067
|
+
["Current Space", scopeSummary(project.resolved_scope_id)],
|
|
15068
|
+
["Suggested Space", project.suggested_scope_id ? scopeSummary(project.suggested_scope_id) : null],
|
|
15069
|
+
["Advanced: current Space ID", project.resolved_scope_id],
|
|
15070
|
+
["Advanced: suggested Space ID", project.suggested_scope_id],
|
|
14819
15071
|
["Suggestion reason", project.suggestion_reason],
|
|
14820
15072
|
["Sessions", project.session_count],
|
|
14821
15073
|
["Memories", project.memory_count ?? "count unavailable"]
|
|
@@ -14834,7 +15086,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14834
15086
|
}
|
|
14835
15087
|
function clusterDomainLabel(projects) {
|
|
14836
15088
|
const uniqueScopes = [...new Set(projects.map((project) => project.resolved_scope_id))];
|
|
14837
|
-
return uniqueScopes.length === 1 ?
|
|
15089
|
+
return uniqueScopes.length === 1 ? scopeSummary(uniqueScopes[0]) : "Mixed Spaces";
|
|
14838
15090
|
}
|
|
14839
15091
|
function renderProjectCluster(projects) {
|
|
14840
15092
|
if (projects.length === 1) return renderProjectRow(projects[0]);
|
|
@@ -14865,32 +15117,28 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14865
15117
|
const resolvedScopes = new Set(projects.map((project) => project.resolved_scope_id));
|
|
14866
15118
|
const select = document.createElement("select");
|
|
14867
15119
|
select.className = "project-domain-select";
|
|
14868
|
-
select.setAttribute("aria-label", `
|
|
15120
|
+
select.setAttribute("aria-label", `Space for ${projectClusterLabel(projects[0])} group`);
|
|
14869
15121
|
const placeholder = document.createElement("option");
|
|
14870
15122
|
placeholder.value = "";
|
|
14871
|
-
placeholder.textContent = "Choose
|
|
15123
|
+
placeholder.textContent = "Choose Space…";
|
|
14872
15124
|
select.appendChild(placeholder);
|
|
14873
|
-
|
|
14874
|
-
const option = document.createElement("option");
|
|
14875
|
-
option.value = scope.scope_id;
|
|
14876
|
-
option.textContent = scope.label ? `${scope.label} · ${scope.scope_id}` : scope.scope_id;
|
|
14877
|
-
select.appendChild(option);
|
|
14878
|
-
}
|
|
15125
|
+
appendAssignableScopeOptions(select);
|
|
14879
15126
|
select.value = "";
|
|
14880
15127
|
const save = document.createElement("button");
|
|
14881
15128
|
save.className = "settings-button";
|
|
14882
15129
|
save.type = "button";
|
|
14883
|
-
save.textContent = `Save
|
|
15130
|
+
save.textContent = `Save Space for ${projects.length} identities`;
|
|
14884
15131
|
save.disabled = true;
|
|
14885
15132
|
save.addEventListener("click", () => void saveProjectClusterMapping(projects, select.value));
|
|
14886
15133
|
select.addEventListener("change", () => {
|
|
14887
15134
|
save.disabled = !select.value || hasGuardrailWarnings;
|
|
14888
15135
|
});
|
|
15136
|
+
select.addEventListener("blur", refreshSkippedProjectDataAfterSelectBlur);
|
|
14889
15137
|
actions.append(select, save);
|
|
14890
15138
|
if (suggestedScopes.size > 1 || resolvedScopes.size > 1 || hasGuardrailWarnings) {
|
|
14891
15139
|
const note = document.createElement("div");
|
|
14892
15140
|
note.className = "settings-note project-attention-note";
|
|
14893
|
-
note.textContent = hasGuardrailWarnings ? "One or more identities in this group need individual review before bulk assignment." : "This group has mixed suggestions or current
|
|
15141
|
+
note.textContent = hasGuardrailWarnings ? "One or more identities in this group need individual review before bulk assignment." : "This group has mixed suggestions or current Spaces. Choose a Space explicitly before bulk assignment.";
|
|
14894
15142
|
actions.appendChild(note);
|
|
14895
15143
|
}
|
|
14896
15144
|
row.appendChild(actions);
|
|
@@ -14925,10 +15173,34 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14925
15173
|
empty.textContent = message;
|
|
14926
15174
|
list.appendChild(empty);
|
|
14927
15175
|
}
|
|
15176
|
+
function renderProjectInventory(result) {
|
|
15177
|
+
const meta = el("projectsInventoryMeta");
|
|
15178
|
+
const list = el("projectsInventoryList");
|
|
15179
|
+
if (!meta || !list) return;
|
|
15180
|
+
list.textContent = "";
|
|
15181
|
+
if (result.projects.length === 0) renderEmpty("No projects match those filters.");
|
|
15182
|
+
else for (const cluster of projectClusters(result.projects)) list.appendChild(renderProjectCluster(cluster));
|
|
15183
|
+
meta.textContent = result.total === 0 ? "0 project identities found" : `${result.total} project identit${result.total === 1 ? "y" : "ies"} found · showing ${result.offset + 1}-${Math.min(result.offset + result.projects.length, result.total)}`;
|
|
15184
|
+
const prev = el("projectsPrevPage");
|
|
15185
|
+
const next = el("projectsNextPage");
|
|
15186
|
+
if (prev) prev.disabled = result.offset === 0;
|
|
15187
|
+
if (next) next.disabled = !result.has_more;
|
|
15188
|
+
}
|
|
15189
|
+
function refreshProjectCoordinatorGroupNamesInBackground(result) {
|
|
15190
|
+
refreshProjectCoordinatorGroupNames().then(() => {
|
|
15191
|
+
if (isProjectSpaceSelectActive()) return;
|
|
15192
|
+
renderProjectInventory(result);
|
|
15193
|
+
});
|
|
15194
|
+
}
|
|
14928
15195
|
async function loadProjectsData() {
|
|
14929
15196
|
const meta = el("projectsInventoryMeta");
|
|
14930
15197
|
const list = el("projectsInventoryList");
|
|
14931
15198
|
if (!meta || !list) return;
|
|
15199
|
+
if (isProjectSpaceSelectActive()) {
|
|
15200
|
+
skippedProjectRefreshForActiveSelect = true;
|
|
15201
|
+
return;
|
|
15202
|
+
}
|
|
15203
|
+
skippedProjectRefreshForActiveSelect = false;
|
|
14932
15204
|
meta.textContent = "Loading project inventory…";
|
|
14933
15205
|
try {
|
|
14934
15206
|
const [result, settings] = await Promise.all([loadProjectScopeInventory({
|
|
@@ -14938,14 +15210,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14938
15210
|
status: el("projectsStatusFilter")?.value || void 0
|
|
14939
15211
|
}), loadSharingDomainSettings()]);
|
|
14940
15212
|
scopes = settings.scopes;
|
|
14941
|
-
|
|
14942
|
-
|
|
14943
|
-
else for (const cluster of projectClusters(result.projects)) list.appendChild(renderProjectCluster(cluster));
|
|
14944
|
-
meta.textContent = result.total === 0 ? "0 project identities found" : `${result.total} project identit${result.total === 1 ? "y" : "ies"} found · showing ${result.offset + 1}-${Math.min(result.offset + result.projects.length, result.total)}`;
|
|
14945
|
-
const prev = el("projectsPrevPage");
|
|
14946
|
-
const next = el("projectsNextPage");
|
|
14947
|
-
if (prev) prev.disabled = result.offset === 0;
|
|
14948
|
-
if (next) next.disabled = !result.has_more;
|
|
15213
|
+
renderProjectInventory(result);
|
|
15214
|
+
refreshProjectCoordinatorGroupNamesInBackground(result);
|
|
14949
15215
|
} catch (error) {
|
|
14950
15216
|
meta.textContent = "Project inventory failed to load.";
|
|
14951
15217
|
renderEmpty(error instanceof Error ? error.message : "Unable to load project inventory.");
|
|
@@ -16576,8 +16842,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16576
16842
|
//#endregion
|
|
16577
16843
|
//#region src/tabs/settings/components/SharingDomainsPanel.tsx
|
|
16578
16844
|
function domainLabel(scope) {
|
|
16845
|
+
const team = scope.group_id ? `Team ${scope.group_id}` : scope.authority_type;
|
|
16579
16846
|
const qualifier = scope.authority_type === "local" ? "local" : scope.authority_type;
|
|
16580
|
-
return `${scope.label || scope.scope_id} · ${qualifier}`;
|
|
16847
|
+
return `${scope.label || scope.scope_id} · ${team || qualifier}`;
|
|
16581
16848
|
}
|
|
16582
16849
|
function projectSubtitle(project) {
|
|
16583
16850
|
if (project.git_remote) return `Matched by git remote · ${project.git_remote}`;
|
|
@@ -16618,7 +16885,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16618
16885
|
function settingsMappingWarnings(settings) {
|
|
16619
16886
|
return settings.mappings.flatMap((mapping) => mapping.guardrail_warnings ?? []);
|
|
16620
16887
|
}
|
|
16621
|
-
function GuardrailMessages({ label = "
|
|
16888
|
+
function GuardrailMessages({ label = "Space assignment guardrail", warnings }) {
|
|
16622
16889
|
if (warnings.length === 0) return null;
|
|
16623
16890
|
return /* @__PURE__ */ u("div", {
|
|
16624
16891
|
"aria-label": label,
|
|
@@ -16642,7 +16909,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16642
16909
|
setSettings(next);
|
|
16643
16910
|
setDrafts(resetDrafts(next));
|
|
16644
16911
|
} catch (err) {
|
|
16645
|
-
setError(err instanceof Error ? err.message : "Unable to load
|
|
16912
|
+
setError(err instanceof Error ? err.message : "Unable to load Spaces");
|
|
16646
16913
|
} finally {
|
|
16647
16914
|
setLoading(false);
|
|
16648
16915
|
}
|
|
@@ -16674,7 +16941,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16674
16941
|
scope_id: scopeId
|
|
16675
16942
|
});
|
|
16676
16943
|
setConfirmation(null);
|
|
16677
|
-
showGlobalNotice("Project
|
|
16944
|
+
showGlobalNotice("Project Space assignment updated. Device access grants are unchanged.");
|
|
16678
16945
|
await reload();
|
|
16679
16946
|
} catch (err) {
|
|
16680
16947
|
if (err instanceof SharingDomainGuardrailConfirmationError) {
|
|
@@ -16685,7 +16952,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16685
16952
|
});
|
|
16686
16953
|
return;
|
|
16687
16954
|
}
|
|
16688
|
-
setError(err instanceof Error ? err.message : "Unable to save
|
|
16955
|
+
setError(err instanceof Error ? err.message : "Unable to save Space assignment");
|
|
16689
16956
|
} finally {
|
|
16690
16957
|
setSavingKey(null);
|
|
16691
16958
|
}
|
|
@@ -16697,10 +16964,10 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16697
16964
|
try {
|
|
16698
16965
|
await deleteSharingDomainProjectMapping(project.mapping_id);
|
|
16699
16966
|
setConfirmation(null);
|
|
16700
|
-
showGlobalNotice("Project
|
|
16967
|
+
showGlobalNotice("Project Space assignment removed. The next fallback now applies.");
|
|
16701
16968
|
await reload();
|
|
16702
16969
|
} catch (err) {
|
|
16703
|
-
setError(err instanceof Error ? err.message : "Unable to reset
|
|
16970
|
+
setError(err instanceof Error ? err.message : "Unable to reset Space assignment");
|
|
16704
16971
|
} finally {
|
|
16705
16972
|
setSavingKey(null);
|
|
16706
16973
|
}
|
|
@@ -16713,15 +16980,15 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16713
16980
|
children: [
|
|
16714
16981
|
/* @__PURE__ */ u("h3", {
|
|
16715
16982
|
className: "settings-group-title",
|
|
16716
|
-
children: "Advanced
|
|
16983
|
+
children: "Advanced Space assignments"
|
|
16717
16984
|
}),
|
|
16718
16985
|
/* @__PURE__ */ u("div", {
|
|
16719
16986
|
className: "small",
|
|
16720
|
-
children: "Use Projects for day-to-day project/
|
|
16987
|
+
children: "Use Projects for day-to-day project/Space review. This fallback panel exposes the same assignment controls for troubleshooting and recovery."
|
|
16721
16988
|
}),
|
|
16722
16989
|
/* @__PURE__ */ u("div", {
|
|
16723
16990
|
className: "small",
|
|
16724
|
-
children: "Saving
|
|
16991
|
+
children: "Saving an assignment changes local Space resolution for future writes; it does not grant any device or Team member access by itself."
|
|
16725
16992
|
}),
|
|
16726
16993
|
/* @__PURE__ */ u("div", {
|
|
16727
16994
|
className: "section-actions",
|
|
@@ -16733,12 +17000,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16733
17000
|
})
|
|
16734
17001
|
}),
|
|
16735
17002
|
settings ? /* @__PURE__ */ u(GuardrailMessages, {
|
|
16736
|
-
label: "
|
|
17003
|
+
label: "Space assignment warnings",
|
|
16737
17004
|
warnings: settingsMappingWarnings(settings)
|
|
16738
17005
|
}) : null,
|
|
16739
17006
|
loading && !settings ? /* @__PURE__ */ u("div", {
|
|
16740
17007
|
className: "small",
|
|
16741
|
-
children: "Loading
|
|
17008
|
+
children: "Loading Spaces…"
|
|
16742
17009
|
}) : null,
|
|
16743
17010
|
error ? /* @__PURE__ */ u("div", {
|
|
16744
17011
|
className: "settings-note",
|
|
@@ -16772,7 +17039,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16772
17039
|
children: projectSubtitle(project)
|
|
16773
17040
|
}),
|
|
16774
17041
|
/* @__PURE__ */ u(RadixSelect, {
|
|
16775
|
-
ariaLabel: `
|
|
17042
|
+
ariaLabel: `Space for ${project.display_project}`,
|
|
16776
17043
|
contentClassName: "settings-select-content",
|
|
16777
17044
|
disabled: !assignable || saving || scopeOptions.length === 0,
|
|
16778
17045
|
id: fieldId,
|
|
@@ -16785,7 +17052,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16785
17052
|
if (confirmation?.workspaceIdentity === project.workspace_identity) setConfirmation(null);
|
|
16786
17053
|
},
|
|
16787
17054
|
options: scopeOptions,
|
|
16788
|
-
placeholder: "Choose
|
|
17055
|
+
placeholder: "Choose Space",
|
|
16789
17056
|
triggerClassName: "settings-select-trigger",
|
|
16790
17057
|
value: currentValue,
|
|
16791
17058
|
viewportClassName: "settings-select-viewport"
|
|
@@ -16793,7 +17060,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16793
17060
|
/* @__PURE__ */ u("div", {
|
|
16794
17061
|
className: "small",
|
|
16795
17062
|
children: [
|
|
16796
|
-
"Current
|
|
17063
|
+
"Current Space: ",
|
|
16797
17064
|
currentScopeName,
|
|
16798
17065
|
" · ",
|
|
16799
17066
|
resolutionLabel(project.resolution_reason)
|
|
@@ -16811,13 +17078,13 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16811
17078
|
/* @__PURE__ */ u(GuardrailMessages, { warnings: visibleProjectWarnings(project) }),
|
|
16812
17079
|
!assignable ? /* @__PURE__ */ u("div", {
|
|
16813
17080
|
className: "settings-note",
|
|
16814
|
-
children: "This project is missing a stable identity, so
|
|
17081
|
+
children: "This project is missing a stable identity, so Space assignment is disabled. Add a path, git remote, or workspace id first; until then it remains Local only."
|
|
16815
17082
|
}) : null,
|
|
16816
17083
|
pendingConfirmation ? /* @__PURE__ */ u("div", {
|
|
16817
17084
|
className: "settings-note",
|
|
16818
17085
|
role: "alert",
|
|
16819
17086
|
children: [
|
|
16820
|
-
/* @__PURE__ */ u("strong", { children: "Review before saving this
|
|
17087
|
+
/* @__PURE__ */ u("strong", { children: "Review before saving this Space assignment." }),
|
|
16821
17088
|
/* @__PURE__ */ u("ul", { children: pendingConfirmation.warnings.map((warning, warningIndex) => /* @__PURE__ */ u("li", { children: warning.message }, warningKey(warning, warningIndex))) }),
|
|
16822
17089
|
/* @__PURE__ */ u("div", {
|
|
16823
17090
|
className: "section-actions",
|
|
@@ -16844,7 +17111,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16844
17111
|
disabled: !assignable || saving || unchanged,
|
|
16845
17112
|
onClick: () => void saveProject(project),
|
|
16846
17113
|
type: "button",
|
|
16847
|
-
children: saving ? "Saving…" : usingSuggestion ? "Confirm suggested mapping" : "Save
|
|
17114
|
+
children: saving ? "Saving…" : usingSuggestion ? "Confirm suggested mapping" : "Save Space"
|
|
16848
17115
|
}), /* @__PURE__ */ u("button", {
|
|
16849
17116
|
className: "settings-button",
|
|
16850
17117
|
disabled: saving || !canRemoveProjectMapping,
|
|
@@ -21936,7 +22203,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
21936
22203
|
try {
|
|
21937
22204
|
const runtime = await loadRuntimeInfo();
|
|
21938
22205
|
if (!runtime?.version) return;
|
|
21939
|
-
setRuntimeLabel(runtime.version, "
|
|
22206
|
+
setRuntimeLabel(runtime.version, "1a8e247");
|
|
21940
22207
|
} catch {}
|
|
21941
22208
|
}
|
|
21942
22209
|
var lastAnnouncedRefreshState = null;
|