@cosmicdrift/kumiko-bundled-features 0.356.0 → 0.357.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.
Files changed (69) hide show
  1. package/dist/auth-mfa/i18n.js +1 -0
  2. package/dist/auth-mfa/schema/user-mfa.d.ts +6 -0
  3. package/dist/auth-mfa/screens.js +8 -1
  4. package/dist/billing-foundation/entities.d.ts +8 -0
  5. package/dist/billing-foundation/projection.d.ts +8 -0
  6. package/dist/cap-counter/entity.d.ts +1 -0
  7. package/dist/cap-counter/feature.js +7 -1
  8. package/dist/cap-overview/screens.js +3 -1
  9. package/dist/config/table.d.ts +6 -0
  10. package/dist/crypto-shredding/handlers/forget-subject.write.js +15 -3
  11. package/dist/custom-fields/entity.d.ts +4 -0
  12. package/dist/data-retention/schema/tenant-retention-override.d.ts +4 -0
  13. package/dist/delivery/chat-webhook-sender.js +1 -1
  14. package/dist/delivery/constants.d.ts +1 -0
  15. package/dist/delivery/constants.js +4 -0
  16. package/dist/delivery/delivery-service.js +62 -25
  17. package/dist/delivery/feature.js +7 -1
  18. package/dist/delivery/jobs.js +25 -1
  19. package/dist/delivery/tables.d.ts +6 -0
  20. package/dist/delivery/testing.d.ts +1 -0
  21. package/dist/document-ingest-foundation/entity.d.ts +4 -0
  22. package/dist/folders/entity.d.ts +8 -0
  23. package/dist/form-draft/entity.d.ts +2 -0
  24. package/dist/inbound-mail-foundation/entities.d.ts +25 -0
  25. package/dist/inbound-mail-foundation/projection.d.ts +20 -0
  26. package/dist/jobs/job-run-table.d.ts +6 -0
  27. package/dist/ledger/entity.d.ts +13 -0
  28. package/dist/managed-pages/table.d.ts +12 -0
  29. package/dist/notes-history/entity.d.ts +12 -0
  30. package/dist/notes-history/entity.js +7 -6
  31. package/dist/notes-history-user-data/hooks.d.ts +10 -1
  32. package/dist/notes-history-user-data/hooks.js +78 -61
  33. package/dist/notes-history-user-data/index.d.ts +1 -0
  34. package/dist/notes-history-user-data/index.js +2 -1
  35. package/dist/personal-access-tokens/schema/api-token.d.ts +6 -0
  36. package/dist/personal-access-tokens/screens.js +2 -0
  37. package/dist/secrets/table.d.ts +1 -0
  38. package/dist/sessions/schema/user-session.d.ts +4 -0
  39. package/dist/sessions/screens.js +2 -0
  40. package/dist/tags/entity.d.ts +9 -0
  41. package/dist/template-resolver/table.d.ts +10 -0
  42. package/dist/template-resolver/user-content-table.d.ts +10 -0
  43. package/dist/tenant/constants.d.ts +1 -0
  44. package/dist/tenant/constants.js +6 -3
  45. package/dist/tenant/feature.js +2 -0
  46. package/dist/tenant/handlers/member-role-availability.query.d.ts +7 -0
  47. package/dist/tenant/handlers/member-role-availability.query.js +18 -0
  48. package/dist/tenant/invitation-table.d.ts +6 -0
  49. package/dist/tenant/member-role-options.d.ts +2 -0
  50. package/dist/tenant/member-role-options.js +4 -0
  51. package/dist/tenant/membership-table.d.ts +4 -0
  52. package/dist/tenant/schema/tenant.d.ts +6 -0
  53. package/dist/tenant/screens.d.ts +4 -2
  54. package/dist/tenant/screens.js +10 -6
  55. package/dist/tier-engine/entity.d.ts +2 -0
  56. package/dist/tier-engine/tier-resolver.d.ts +2 -0
  57. package/dist/user/schema/user.d.ts +12 -0
  58. package/dist/user/screens.js +8 -1
  59. package/dist/user-data-rights/schema/download-attempt.d.ts +14 -0
  60. package/dist/user-data-rights/schema/download-token.d.ts +8 -0
  61. package/dist/user-data-rights/schema/export-job.d.ts +6 -0
  62. package/dist/user-data-rights/screens.js +8 -1
  63. package/dist/waitlist/entity.d.ts +14 -0
  64. package/dist/waitlist/screens.js +8 -1
  65. package/package.json +9 -9
  66. package/src/auth-mfa/changes.json +6 -0
  67. package/src/crypto-shredding/changes.json +6 -0
  68. package/src/delivery/changes.json +6 -0
  69. package/src/tenant/changes.json +6 -0
@@ -5,6 +5,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
5
5
  readonly description?: string;
6
6
  readonly maxLength?: number;
7
7
  readonly minLength?: number;
8
+ readonly autoComplete?: string;
8
9
  readonly required?: boolean;
9
10
  readonly searchable?: boolean;
10
11
  readonly sortable?: boolean;
@@ -53,6 +54,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
53
54
  readonly description?: string;
54
55
  readonly maxLength?: number;
55
56
  readonly minLength?: number;
57
+ readonly autoComplete?: string;
56
58
  readonly required?: boolean;
57
59
  readonly searchable?: boolean;
58
60
  readonly sortable?: boolean;
@@ -75,6 +77,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
75
77
  readonly description?: string;
76
78
  readonly maxLength?: number;
77
79
  readonly minLength?: number;
80
+ readonly autoComplete?: string;
78
81
  readonly required?: boolean;
79
82
  readonly searchable?: boolean;
80
83
  readonly sortable?: boolean;
@@ -97,6 +100,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
97
100
  readonly description?: string;
98
101
  readonly maxLength?: number;
99
102
  readonly minLength?: number;
103
+ readonly autoComplete?: string;
100
104
  readonly required?: boolean;
101
105
  readonly searchable?: boolean;
102
106
  readonly sortable?: boolean;
@@ -213,6 +217,7 @@ export declare const templateResourceEntity: import("@cosmicdrift/kumiko-types/f
213
217
  readonly description?: string;
214
218
  readonly maxLength?: number;
215
219
  readonly minLength?: number;
220
+ readonly autoComplete?: string;
216
221
  readonly required?: boolean;
217
222
  readonly searchable?: boolean;
218
223
  readonly sortable?: boolean;
@@ -260,6 +265,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
260
265
  readonly description?: string;
261
266
  readonly maxLength?: number;
262
267
  readonly minLength?: number;
268
+ readonly autoComplete?: string;
263
269
  readonly required?: boolean;
264
270
  readonly searchable?: boolean;
265
271
  readonly sortable?: boolean;
@@ -308,6 +314,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
308
314
  readonly description?: string;
309
315
  readonly maxLength?: number;
310
316
  readonly minLength?: number;
317
+ readonly autoComplete?: string;
311
318
  readonly required?: boolean;
312
319
  readonly searchable?: boolean;
313
320
  readonly sortable?: boolean;
@@ -330,6 +337,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
330
337
  readonly description?: string;
331
338
  readonly maxLength?: number;
332
339
  readonly minLength?: number;
340
+ readonly autoComplete?: string;
333
341
  readonly required?: boolean;
334
342
  readonly searchable?: boolean;
335
343
  readonly sortable?: boolean;
@@ -352,6 +360,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
352
360
  readonly description?: string;
353
361
  readonly maxLength?: number;
354
362
  readonly minLength?: number;
363
+ readonly autoComplete?: string;
355
364
  readonly required?: boolean;
356
365
  readonly searchable?: boolean;
357
366
  readonly sortable?: boolean;
@@ -468,6 +477,7 @@ export declare const templateResourcesTable: import("@cosmicdrift/kumiko-framewo
468
477
  readonly description?: string;
469
478
  readonly maxLength?: number;
470
479
  readonly minLength?: number;
480
+ readonly autoComplete?: string;
471
481
  readonly required?: boolean;
472
482
  readonly searchable?: boolean;
473
483
  readonly sortable?: boolean;
@@ -5,6 +5,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
5
5
  readonly description?: string;
6
6
  readonly maxLength?: number;
7
7
  readonly minLength?: number;
8
+ readonly autoComplete?: string;
8
9
  readonly required?: boolean;
9
10
  readonly searchable?: boolean;
10
11
  readonly sortable?: boolean;
@@ -27,6 +28,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
27
28
  readonly description?: string;
28
29
  readonly maxLength?: number;
29
30
  readonly minLength?: number;
31
+ readonly autoComplete?: string;
30
32
  readonly required?: boolean;
31
33
  readonly searchable?: boolean;
32
34
  readonly sortable?: boolean;
@@ -75,6 +77,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
75
77
  readonly description?: string;
76
78
  readonly maxLength?: number;
77
79
  readonly minLength?: number;
80
+ readonly autoComplete?: string;
78
81
  readonly required?: boolean;
79
82
  readonly searchable?: boolean;
80
83
  readonly sortable?: boolean;
@@ -97,6 +100,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
97
100
  readonly description?: string;
98
101
  readonly maxLength?: number;
99
102
  readonly minLength?: number;
103
+ readonly autoComplete?: string;
100
104
  readonly required?: boolean;
101
105
  readonly searchable?: boolean;
102
106
  readonly sortable?: boolean;
@@ -119,6 +123,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
119
123
  readonly description?: string;
120
124
  readonly maxLength?: number;
121
125
  readonly minLength?: number;
126
+ readonly autoComplete?: string;
122
127
  readonly required?: boolean;
123
128
  readonly searchable?: boolean;
124
129
  readonly sortable?: boolean;
@@ -183,6 +188,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
183
188
  readonly description?: string;
184
189
  readonly maxLength?: number;
185
190
  readonly minLength?: number;
191
+ readonly autoComplete?: string;
186
192
  readonly required?: boolean;
187
193
  readonly searchable?: boolean;
188
194
  readonly sortable?: boolean;
@@ -205,6 +211,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
205
211
  readonly description?: string;
206
212
  readonly maxLength?: number;
207
213
  readonly minLength?: number;
214
+ readonly autoComplete?: string;
208
215
  readonly required?: boolean;
209
216
  readonly searchable?: boolean;
210
217
  readonly sortable?: boolean;
@@ -253,6 +260,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
253
260
  readonly description?: string;
254
261
  readonly maxLength?: number;
255
262
  readonly minLength?: number;
263
+ readonly autoComplete?: string;
256
264
  readonly required?: boolean;
257
265
  readonly searchable?: boolean;
258
266
  readonly sortable?: boolean;
@@ -275,6 +283,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
275
283
  readonly description?: string;
276
284
  readonly maxLength?: number;
277
285
  readonly minLength?: number;
286
+ readonly autoComplete?: string;
278
287
  readonly required?: boolean;
279
288
  readonly searchable?: boolean;
280
289
  readonly sortable?: boolean;
@@ -297,6 +306,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
297
306
  readonly description?: string;
298
307
  readonly maxLength?: number;
299
308
  readonly minLength?: number;
309
+ readonly autoComplete?: string;
300
310
  readonly required?: boolean;
301
311
  readonly searchable?: boolean;
302
312
  readonly sortable?: boolean;
@@ -33,6 +33,7 @@ export declare const TenantQueries: {
33
33
  readonly resolveUserIds: "tenant:query:resolve-user-ids";
34
34
  readonly invitations: "tenant:query:invitations";
35
35
  readonly teamList: "tenant:query:team:list";
36
+ readonly memberRoleAvailability: "tenant:query:member-role-availability";
36
37
  };
37
38
  export declare const TenantErrors: {
38
39
  readonly membershipNotFound: "membership_not_found";
@@ -19,9 +19,10 @@ export const MEMBER_ROLES_CELL_COMPONENT = "MemberRolesCell";
19
19
  // Admin (rank 2) shares the invite-create screen with TenantAdmin — TenantAdmin
20
20
  // must not appear here or Admin sees an unassignable option (fw#2414).
21
21
  export const DEFAULT_INVITE_ROLE_OPTIONS = ["User", "Editor", "Admin"];
22
- // Full assignable rank list, used by memberRolesEditScreen: that screen is
23
- // prefilled with a member's *current* roles, so it must be able to represent
24
- // every rank a membership can actually hold, including TenantAdmin (fw#2452).
22
+ // Full rank list for memberRolesEditScreen: it is prefilled with a member's
23
+ // *current* roles, so it must represent every rank a membership can hold,
24
+ // including TenantAdmin (fw#2452). The screen hides what the caller may not
25
+ // assign via TenantQueries.memberRoleAvailability.
25
26
  export const OWNER_INVITE_ROLE_OPTIONS = [
26
27
  "User",
27
28
  "Member",
@@ -58,6 +59,8 @@ export const TenantQueries = {
58
59
  invitations: "tenant:query:invitations",
59
60
  // Combined active-members + pending-invitations list backing /members.
60
61
  teamList: "tenant:query:team:list",
62
+ // Per-role assignability for the caller, mirrors the rank rule of updateMemberRoles.
63
+ memberRoleAvailability: "tenant:query:member-role-availability",
61
64
  };
62
65
  // Error codes
63
66
  export const TenantErrors = {
@@ -7,6 +7,7 @@ import { invitationsQuery } from "./handlers/invitations.query.js";
7
7
  import { listQuery } from "./handlers/list.query.js";
8
8
  import { meQuery } from "./handlers/me.query.js";
9
9
  import { memberDirectoryQuery } from "./handlers/member-directory.query.js";
10
+ import { memberRoleAvailabilityQuery } from "./handlers/member-role-availability.query.js";
10
11
  import { membersQuery } from "./handlers/members.query.js";
11
12
  import { membershipsQuery } from "./handlers/memberships.query.js";
12
13
  import { removeMemberWrite } from "./handlers/remove-member.write.js";
@@ -118,6 +119,7 @@ export function createTenantFeature(options) {
118
119
  resolveUserIds: r.queryHandler(resolveUserIdsQuery),
119
120
  invitations: r.queryHandler(invitationsQuery),
120
121
  teamList: r.queryHandler(teamListQuery),
122
+ memberRoleAvailability: r.queryHandler(memberRoleAvailabilityQuery),
121
123
  };
122
124
  // Entity-convention handlers for the SystemAdmin entityList/entityEdit
123
125
  // screens. The feature's original handlers predate the `<entity>:<verb>`
@@ -0,0 +1,7 @@
1
+ import * as z from "zod";
2
+ export declare const memberRoleAvailabilityQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"member-role-availability", z.ZodObject<{}, z.core.$strip>, {
3
+ rows: {
4
+ value: string;
5
+ disabled: boolean;
6
+ }[];
7
+ }, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
@@ -0,0 +1,18 @@
1
+ import { access, assignableAppRolesOf, canActorAssignRole, defineQueryHandler, } from "@cosmicdrift/kumiko-framework/engine";
2
+ import * as z from "zod";
3
+ import { memberRoleOptions } from "../member-role-options.js";
4
+ export const memberRoleAvailabilityQuery = defineQueryHandler({
5
+ name: "member-role-availability",
6
+ schema: z.object({}),
7
+ access: { roles: access.admin },
8
+ description: "Lists every role the member roles form offers and whether the caller's own rank may assign it; the form hides the roles marked disabled.",
9
+ handler: async (query, ctx) => {
10
+ const assignableAppRoles = assignableAppRolesOf(ctx.registry);
11
+ return {
12
+ rows: memberRoleOptions(assignableAppRoles).map((value) => ({
13
+ value,
14
+ disabled: !canActorAssignRole(query.user.roles, value, assignableAppRoles),
15
+ })),
16
+ };
17
+ },
18
+ });
@@ -12,6 +12,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
12
12
  readonly description?: string;
13
13
  readonly maxLength?: number;
14
14
  readonly minLength?: number;
15
+ readonly autoComplete?: string;
15
16
  readonly required?: boolean;
16
17
  readonly searchable?: boolean;
17
18
  readonly sortable?: boolean;
@@ -34,6 +35,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
34
35
  readonly description?: string;
35
36
  readonly maxLength?: number;
36
37
  readonly minLength?: number;
38
+ readonly autoComplete?: string;
37
39
  readonly required?: boolean;
38
40
  readonly searchable?: boolean;
39
41
  readonly sortable?: boolean;
@@ -81,6 +83,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
81
83
  readonly description?: string;
82
84
  readonly maxLength?: number;
83
85
  readonly minLength?: number;
86
+ readonly autoComplete?: string;
84
87
  readonly required?: boolean;
85
88
  readonly searchable?: boolean;
86
89
  readonly sortable?: boolean;
@@ -139,6 +142,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
139
142
  readonly description?: string;
140
143
  readonly maxLength?: number;
141
144
  readonly minLength?: number;
145
+ readonly autoComplete?: string;
142
146
  readonly required?: boolean;
143
147
  readonly searchable?: boolean;
144
148
  readonly sortable?: boolean;
@@ -161,6 +165,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
161
165
  readonly description?: string;
162
166
  readonly maxLength?: number;
163
167
  readonly minLength?: number;
168
+ readonly autoComplete?: string;
164
169
  readonly required?: boolean;
165
170
  readonly searchable?: boolean;
166
171
  readonly sortable?: boolean;
@@ -208,6 +213,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
208
213
  readonly description?: string;
209
214
  readonly maxLength?: number;
210
215
  readonly minLength?: number;
216
+ readonly autoComplete?: string;
211
217
  readonly required?: boolean;
212
218
  readonly searchable?: boolean;
213
219
  readonly sortable?: boolean;
@@ -0,0 +1,2 @@
1
+ import type { AssignableAppRoles } from "@cosmicdrift/kumiko-framework/engine";
2
+ export declare function memberRoleOptions(assignableAppRoles: AssignableAppRoles): readonly string[];
@@ -0,0 +1,4 @@
1
+ import { OWNER_INVITE_ROLE_OPTIONS } from "./constants.js";
2
+ export function memberRoleOptions(assignableAppRoles) {
3
+ return [...OWNER_INVITE_ROLE_OPTIONS, ...assignableAppRoles.keys()];
4
+ }
@@ -4,6 +4,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
4
4
  readonly description?: string;
5
5
  readonly maxLength?: number;
6
6
  readonly minLength?: number;
7
+ readonly autoComplete?: string;
7
8
  readonly required?: boolean;
8
9
  readonly searchable?: boolean;
9
10
  readonly sortable?: boolean;
@@ -26,6 +27,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
26
27
  readonly description?: string;
27
28
  readonly maxLength?: number;
28
29
  readonly minLength?: number;
30
+ readonly autoComplete?: string;
29
31
  readonly required?: boolean;
30
32
  readonly searchable?: boolean;
31
33
  readonly sortable?: boolean;
@@ -50,6 +52,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
50
52
  readonly description?: string;
51
53
  readonly maxLength?: number;
52
54
  readonly minLength?: number;
55
+ readonly autoComplete?: string;
53
56
  readonly required?: boolean;
54
57
  readonly searchable?: boolean;
55
58
  readonly sortable?: boolean;
@@ -72,6 +75,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
72
75
  readonly description?: string;
73
76
  readonly maxLength?: number;
74
77
  readonly minLength?: number;
78
+ readonly autoComplete?: string;
75
79
  readonly required?: boolean;
76
80
  readonly searchable?: boolean;
77
81
  readonly sortable?: boolean;
@@ -6,6 +6,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
6
6
  readonly description?: string;
7
7
  readonly maxLength?: number;
8
8
  readonly minLength?: number;
9
+ readonly autoComplete?: string;
9
10
  readonly required?: boolean;
10
11
  readonly searchable?: boolean;
11
12
  readonly sortable?: boolean;
@@ -28,6 +29,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
28
29
  readonly description?: string;
29
30
  readonly maxLength?: number;
30
31
  readonly minLength?: number;
32
+ readonly autoComplete?: string;
31
33
  readonly required?: boolean;
32
34
  readonly searchable?: boolean;
33
35
  readonly sortable?: boolean;
@@ -93,6 +95,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
93
95
  readonly description?: string;
94
96
  readonly maxLength?: number;
95
97
  readonly minLength?: number;
98
+ readonly autoComplete?: string;
96
99
  readonly required?: boolean;
97
100
  readonly searchable?: boolean;
98
101
  readonly sortable?: boolean;
@@ -162,6 +165,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
162
165
  readonly description?: string;
163
166
  readonly maxLength?: number;
164
167
  readonly minLength?: number;
168
+ readonly autoComplete?: string;
165
169
  readonly required?: boolean;
166
170
  readonly searchable?: boolean;
167
171
  readonly sortable?: boolean;
@@ -184,6 +188,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
184
188
  readonly description?: string;
185
189
  readonly maxLength?: number;
186
190
  readonly minLength?: number;
191
+ readonly autoComplete?: string;
187
192
  readonly required?: boolean;
188
193
  readonly searchable?: boolean;
189
194
  readonly sortable?: boolean;
@@ -249,6 +254,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
249
254
  readonly description?: string;
250
255
  readonly maxLength?: number;
251
256
  readonly minLength?: number;
257
+ readonly autoComplete?: string;
252
258
  readonly required?: boolean;
253
259
  readonly searchable?: boolean;
254
260
  readonly sortable?: boolean;
@@ -69,7 +69,8 @@ export declare function createMemberRolesEditScreen(assignableAppRoles?: Assigna
69
69
  };
70
70
  roles: {
71
71
  type: "multiSelect";
72
- options: string[];
72
+ options: readonly string[];
73
+ optionsAvailabilityQuery: "tenant:query:member-role-availability";
73
74
  required: true;
74
75
  };
75
76
  };
@@ -99,7 +100,8 @@ export declare const memberRolesEditScreen: {
99
100
  };
100
101
  roles: {
101
102
  type: "multiSelect";
102
- options: string[];
103
+ options: readonly string[];
104
+ optionsAvailabilityQuery: "tenant:query:member-role-availability";
103
105
  required: true;
104
106
  };
105
107
  };
@@ -1,6 +1,7 @@
1
1
  import { AuthHandlers } from "@cosmicdrift/kumiko-bundled-features/auth-email-password/constants";
2
2
  import { access, i18nKey, isAssignableByRole, } from "@cosmicdrift/kumiko-framework/engine";
3
- import { DEFAULT_INVITE_ROLE_OPTIONS, INVITE_CREATE_SCREEN_ID, MEMBER_ROLES_CELL_COMPONENT, MEMBER_ROLES_EDIT_SCREEN_ID, MEMBER_STATUS_CELL_COMPONENT, MEMBERS_SCREEN_ID, OWNER_INVITE_ROLE_OPTIONS, TenantHandlers, TenantQueries, } from "./constants.js";
3
+ import { DEFAULT_INVITE_ROLE_OPTIONS, INVITE_CREATE_SCREEN_ID, MEMBER_ROLES_CELL_COMPONENT, MEMBER_ROLES_EDIT_SCREEN_ID, MEMBER_STATUS_CELL_COMPONENT, MEMBERS_SCREEN_ID, TenantHandlers, TenantQueries, } from "./constants.js";
4
+ import { memberRoleOptions } from "./member-role-options.js";
4
5
  // Cross-tenant SystemAdmin platform view of the tenants themselves. The tenant
5
6
  // feature runs with `r.systemScope()`, so the entityList returns every tenant.
6
7
  // Both screens are SystemAdmin-gated and inert until an app navs them.
@@ -83,6 +84,7 @@ export function createMembersScreen(options) {
83
84
  field: "lastSeenAt",
84
85
  label: i18nKey("tenant.members.col.lastActivity"),
85
86
  renderer: { format: "timestamp" },
87
+ hideOnNarrow: true,
86
88
  },
87
89
  ],
88
90
  defaultSort: { field: "createdAt", dir: "desc" },
@@ -172,13 +174,15 @@ export function createMemberRolesEditScreen(assignableAppRoles = new Map()) {
172
174
  cancelTarget: MEMBERS_SCREEN_ID,
173
175
  fields: {
174
176
  userId: { type: "text", required: true },
175
- // Prefilled with the member's current roles, so the option list must be
176
- // able to represent every assignable rank — DEFAULT_INVITE_ROLE_OPTIONS
177
- // omits TenantAdmin and would silently strip it on submit. Escalation
178
- // still stays server-side via findForbiddenRoleAssignment (update-member-roles.write.ts).
177
+ // Prefilled with the member's current roles, so the static options must
178
+ // represent every rank (DEFAULT_INVITE_ROLE_OPTIONS omits TenantAdmin and
179
+ // would silently strip it on submit); the availability query hides what the
180
+ // caller may not assign. Enforcement stays server-side via
181
+ // findForbiddenRoleAssignment (update-member-roles.write.ts).
179
182
  roles: {
180
183
  type: "multiSelect",
181
- options: [...OWNER_INVITE_ROLE_OPTIONS, ...assignableAppRoles.keys()],
184
+ options: memberRoleOptions(assignableAppRoles),
185
+ optionsAvailabilityQuery: TenantQueries.memberRoleAvailability,
182
186
  required: true,
183
187
  },
184
188
  },
@@ -4,6 +4,7 @@ export declare const tierAssignmentEntity: import("@cosmicdrift/kumiko-types/fie
4
4
  readonly description?: string;
5
5
  readonly maxLength?: number;
6
6
  readonly minLength?: number;
7
+ readonly autoComplete?: string;
7
8
  readonly required?: boolean;
8
9
  readonly searchable?: boolean;
9
10
  readonly sortable?: boolean;
@@ -26,6 +27,7 @@ export declare const tierAssignmentEntity: import("@cosmicdrift/kumiko-types/fie
26
27
  readonly description?: string;
27
28
  readonly maxLength?: number;
28
29
  readonly minLength?: number;
30
+ readonly autoComplete?: string;
29
31
  readonly required?: boolean;
30
32
  readonly searchable?: boolean;
31
33
  readonly sortable?: boolean;
@@ -12,6 +12,7 @@ export declare function createTierResolver<TTier extends string, TCaps>(deps: Ti
12
12
  readonly description?: string;
13
13
  readonly maxLength?: number;
14
14
  readonly minLength?: number;
15
+ readonly autoComplete?: string;
15
16
  readonly required?: boolean;
16
17
  readonly searchable?: boolean;
17
18
  readonly sortable?: boolean;
@@ -34,6 +35,7 @@ export declare function createTierResolver<TTier extends string, TCaps>(deps: Ti
34
35
  readonly description?: string;
35
36
  readonly maxLength?: number;
36
37
  readonly minLength?: number;
38
+ readonly autoComplete?: string;
37
39
  readonly required?: boolean;
38
40
  readonly searchable?: boolean;
39
41
  readonly sortable?: boolean;
@@ -33,6 +33,7 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
33
33
  readonly description?: string;
34
34
  readonly maxLength?: number;
35
35
  readonly minLength?: number;
36
+ readonly autoComplete?: string;
36
37
  readonly required?: boolean;
37
38
  readonly searchable?: boolean;
38
39
  readonly sortable?: boolean;
@@ -55,6 +56,7 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
55
56
  readonly description?: string;
56
57
  readonly maxLength?: number;
57
58
  readonly minLength?: number;
59
+ readonly autoComplete?: string;
58
60
  readonly required?: boolean;
59
61
  readonly searchable?: boolean;
60
62
  readonly sortable?: boolean;
@@ -77,6 +79,7 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
77
79
  readonly description?: string;
78
80
  readonly maxLength?: number;
79
81
  readonly minLength?: number;
82
+ readonly autoComplete?: string;
80
83
  readonly required?: boolean;
81
84
  readonly searchable?: boolean;
82
85
  readonly sortable?: boolean;
@@ -99,6 +102,7 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
99
102
  readonly description?: string;
100
103
  readonly maxLength?: number;
101
104
  readonly minLength?: number;
105
+ readonly autoComplete?: string;
102
106
  readonly required?: boolean;
103
107
  readonly searchable?: boolean;
104
108
  readonly sortable?: boolean;
@@ -130,6 +134,7 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
130
134
  readonly description?: string;
131
135
  readonly maxLength?: number;
132
136
  readonly minLength?: number;
137
+ readonly autoComplete?: string;
133
138
  readonly required?: boolean;
134
139
  readonly searchable?: boolean;
135
140
  readonly sortable?: boolean;
@@ -195,6 +200,7 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
195
200
  readonly description?: string;
196
201
  readonly maxLength?: number;
197
202
  readonly minLength?: number;
203
+ readonly autoComplete?: string;
198
204
  readonly required?: boolean;
199
205
  readonly searchable?: boolean;
200
206
  readonly sortable?: boolean;
@@ -219,6 +225,7 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
219
225
  readonly description?: string;
220
226
  readonly maxLength?: number;
221
227
  readonly minLength?: number;
228
+ readonly autoComplete?: string;
222
229
  readonly required?: boolean;
223
230
  readonly searchable?: boolean;
224
231
  readonly sortable?: boolean;
@@ -241,6 +248,7 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
241
248
  readonly description?: string;
242
249
  readonly maxLength?: number;
243
250
  readonly minLength?: number;
251
+ readonly autoComplete?: string;
244
252
  readonly required?: boolean;
245
253
  readonly searchable?: boolean;
246
254
  readonly sortable?: boolean;
@@ -263,6 +271,7 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
263
271
  readonly description?: string;
264
272
  readonly maxLength?: number;
265
273
  readonly minLength?: number;
274
+ readonly autoComplete?: string;
266
275
  readonly required?: boolean;
267
276
  readonly searchable?: boolean;
268
277
  readonly sortable?: boolean;
@@ -285,6 +294,7 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
285
294
  readonly description?: string;
286
295
  readonly maxLength?: number;
287
296
  readonly minLength?: number;
297
+ readonly autoComplete?: string;
288
298
  readonly required?: boolean;
289
299
  readonly searchable?: boolean;
290
300
  readonly sortable?: boolean;
@@ -316,6 +326,7 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
316
326
  readonly description?: string;
317
327
  readonly maxLength?: number;
318
328
  readonly minLength?: number;
329
+ readonly autoComplete?: string;
319
330
  readonly required?: boolean;
320
331
  readonly searchable?: boolean;
321
332
  readonly sortable?: boolean;
@@ -381,6 +392,7 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
381
392
  readonly description?: string;
382
393
  readonly maxLength?: number;
383
394
  readonly minLength?: number;
395
+ readonly autoComplete?: string;
384
396
  readonly required?: boolean;
385
397
  readonly searchable?: boolean;
386
398
  readonly sortable?: boolean;
@@ -11,7 +11,14 @@ export const userListScreen = {
11
11
  id: "user-list",
12
12
  type: "entityList",
13
13
  entity: "user",
14
- columns: ["email", "displayName", "roles", "tenants", "status", "emailVerified"],
14
+ columns: [
15
+ "email",
16
+ "displayName",
17
+ "roles",
18
+ "tenants",
19
+ "status",
20
+ { field: "emailVerified", hideOnNarrow: true },
21
+ ],
15
22
  rowActions: [
16
23
  {
17
24
  kind: "navigate",