@ai-matrx/records-ui 0.93.132 → 0.93.140

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.
@@ -0,0 +1,168 @@
1
+ import { PermissionLevel, Table } from '@ai-matrx/records';
2
+
3
+ /** The six things a person does to a record or a table, as the screens offer them. */
4
+ type Capability = "read" | "comment" | "write" | "remove" | "share" | "structure";
5
+ interface WhatYouMayDo {
6
+ /** The word the store answered, or null when it answered nothing. */
7
+ level: PermissionLevel | null;
8
+ /**
9
+ * Whether the store has ANSWERED yet. `false` is a third state and not a
10
+ * refusal: a screen that drew "you may not" while the answer was in flight
11
+ * would blink every control off on every reload, which is its own lie.
12
+ */
13
+ known: boolean;
14
+ read: boolean;
15
+ comment: boolean;
16
+ write: boolean;
17
+ remove: boolean;
18
+ share: boolean;
19
+ structure: boolean;
20
+ /** Why this person may not do that, in one sentence naming the way in. */
21
+ why: (what: Capability) => string;
22
+ }
23
+ /** What each rung of the ladder is called where a person reads it. */
24
+ declare const LEVEL_WORD: Record<PermissionLevel, string>;
25
+ /** The rung a capability asks for — so a short "Needs Admin access" never re-decides the ladder. */
26
+ declare function levelNeededFor(what: Capability): PermissionLevel;
27
+ /**
28
+ * WHAT ONE LEVEL LETS A PERSON DO. `level` null and `known` true means the
29
+ * store said "nothing" — a real answer. `known` false means it has not said.
30
+ */
31
+ declare function whatYouMayDo(level: PermissionLevel | null, known?: boolean): WhatYouMayDo;
32
+ /** Nothing offered, because nothing is known yet. */
33
+ declare const NOT_ANSWERED_YET: WhatYouMayDo;
34
+ /**
35
+ * REC-27. The nine Tables the platform ships are not administered from a
36
+ * person's screen whatever level they hold on them — so the structure controls
37
+ * are absent for a kernel Table and say why, and everything else follows the
38
+ * level as usual.
39
+ */
40
+ declare const KERNEL_REASON: string;
41
+ declare function whatYouMayDoWithTable(table: Table | null | undefined, level: PermissionLevel | null, known: boolean): WhatYouMayDo;
42
+
43
+ /**
44
+ * A Lucide icon NAME, kebab-case — the same currency `Table.icon` already uses.
45
+ * Closed on purpose: each renderer maps every member to its own component, and a
46
+ * new member fails that renderer's typecheck until it is mapped.
47
+ */
48
+ type ObjectActionIcon = "folder-open" | "external-link" | "link" | "pencil" | "copy" | "folder-input" | "star" | "star-off" | "share-2" | "download" | "upload" | "columns-3" | "settings" | "history" | "blocks" | "file-text" | "calendar-clock" | "list-checks" | "bell" | "door-open" | "inbox" | "layout-dashboard" | "archive-restore" | "archive" | "link-2" | "layout-grid";
49
+ /** The groups, in their one order. Separators fall out of group boundaries. */
50
+ type ObjectActionGroup = "open" | "organize" | "share" | "manage" | "built-on" | "danger";
51
+ interface ObjectActionGroupDef {
52
+ id: ObjectActionGroup;
53
+ /** Present only on a group that renders as a submenu. */
54
+ label?: string;
55
+ icon?: ObjectActionIcon;
56
+ /** Rendered as ONE submenu entry holding the group's actions. */
57
+ submenu: boolean;
58
+ }
59
+ declare const OBJECT_ACTION_GROUPS: readonly ObjectActionGroupDef[];
60
+ /** One thing a person can do to an object, for any renderer. */
61
+ interface ObjectAction {
62
+ /** Stable within the object's list. React key, test handle, future ⌘K id. */
63
+ id: string;
64
+ label: string;
65
+ icon: ObjectActionIcon;
66
+ group: ObjectActionGroup;
67
+ /** Display-only hint ("⌘D"). */
68
+ shortcut?: string;
69
+ destructive?: boolean;
70
+ /** Present = shown disabled with this line (≤ 60 chars). Absent = enabled. */
71
+ disabledReason?: string;
72
+ /** Called only when enabled. The host owns the side effect and its feedback. */
73
+ run: () => void | Promise<void>;
74
+ }
75
+ /** What the list needs to know about the table. A full `Table` satisfies it. */
76
+ type TableActionSubject = Pick<Table, "id" | "name"> & Partial<Pick<Table, "is_kernel">>;
77
+ /** The places built on a table, in their one order. */
78
+ type BuiltOnDestination = "forms" | "bookings" | "checklists" | "notifications" | "portals" | "inbox" | "dashboards" | "archived";
79
+ type Handler = (table: TableActionSubject) => void | Promise<void>;
80
+ /**
81
+ * THE SIDE EFFECTS THIS PACKAGE CANNOT OWN. Every handler is optional: one the
82
+ * host leaves out keeps its action in the list, disabled, saying so.
83
+ */
84
+ interface TableActionHost {
85
+ /** Origin for Copy link and Open in new tab. Default `https://www.aimatrx.com`. */
86
+ origin?: string;
87
+ open?: Handler;
88
+ /** Receives the table's link (`<origin>/data-v2/<id>`). */
89
+ openInNewTab?: (url: string, table: TableActionSubject) => void;
90
+ /** Receives the table's link. Runs inside the click (clipboard needs the gesture). */
91
+ copyText?: (text: string, table: TableActionSubject) => void | Promise<void>;
92
+ rename?: Handler;
93
+ duplicate?: Handler;
94
+ move?: Handler;
95
+ /** Current favorite state; flips the Favorite label. Unknown = "Add to favorites". */
96
+ isFavorite?: boolean;
97
+ toggleFavorite?: Handler;
98
+ share?: Handler;
99
+ export?: Handler;
100
+ import?: Handler;
101
+ addColumn?: Handler;
102
+ settings?: Handler;
103
+ history?: Handler;
104
+ /** The "Built on it" destinations, one handler for all eight. */
105
+ openBuiltOn?: (destination: BuiltOnDestination, table: TableActionSubject) => void;
106
+ archive?: Handler;
107
+ /**
108
+ * ANOTHER LANE'S ENTRIES ("Link a record…", a hub tile's verbs). Return the
109
+ * same ids whatever `rights` say — express rights as `disabledReason`. Each
110
+ * entry lands at the END of its named group, in the order returned; `danger`
111
+ * is refused (Archive is always last) and so is an id already in the list.
112
+ */
113
+ extend?: (table: TableActionSubject, rights: WhatYouMayDo) => readonly ObjectAction[];
114
+ }
115
+ interface TableActionsInput {
116
+ table: TableActionSubject;
117
+ rights: WhatYouMayDo;
118
+ host: TableActionHost;
119
+ }
120
+ declare const DEFAULT_ACTION_ORIGIN = "https://www.aimatrx.com";
121
+ /** The one link to a table: `<origin>/data-v2/<tableId>`. */
122
+ declare function tableLink(tableId: string, origin?: string): string;
123
+ declare const ACTION_NOT_HERE_REASON = "Not available here";
124
+ declare const ACTION_CHECKING_ACCESS_REASON = "Checking your access\u2026";
125
+ declare const ACTION_NO_ACCESS_REASON = "You don't have access";
126
+ declare const ACTION_PLATFORM_TABLE_REASON = "Platform tables can't be changed here";
127
+ /** Why `rights` refuse `what`, in one short line — or null when they allow it. */
128
+ declare function rightsReason(rights: WhatYouMayDo, what: Capability, table?: TableActionSubject): string | null;
129
+ /**
130
+ * THE TABLE'S ACTIONS, in the one order. Same ids, same order, for every seat
131
+ * and every host — only `disabledReason` varies.
132
+ */
133
+ declare function tableActions(input: TableActionsInput): ObjectAction[];
134
+ /**
135
+ * Another lane's entries, placed deterministically: each at the end of its
136
+ * group, in the order given. Loud on the two mistakes that would break the
137
+ * invariants — a `danger` entry (Archive must stay last) and a duplicate id.
138
+ */
139
+ declare function withExtensions(base: readonly ObjectAction[], extra: readonly ObjectAction[]): ObjectAction[];
140
+ /** A run of actions that renders together: a plain section, or one submenu. */
141
+ interface ObjectActionSection {
142
+ group: ObjectActionGroupDef;
143
+ actions: ObjectAction[];
144
+ }
145
+ /**
146
+ * THE ONE GROUPING every adapter uses: the list cut at group boundaries, in
147
+ * group order, empty groups dropped, the order inside a group kept.
148
+ */
149
+ declare function groupObjectActions(actions: readonly ObjectAction[]): ObjectActionSection[];
150
+ /** The header ⋯ dropdown's entries — records-ui's own renderer reads these. */
151
+ type ObjectActionDropdownEntry = {
152
+ kind: "separator";
153
+ id: string;
154
+ } | {
155
+ kind: "item";
156
+ action: ObjectAction;
157
+ } | {
158
+ kind: "submenu";
159
+ id: string;
160
+ label: string;
161
+ icon: ObjectActionIcon | undefined;
162
+ actions: ObjectAction[];
163
+ };
164
+ declare function toDropdownEntries(actions: readonly ObjectAction[]): ObjectActionDropdownEntry[];
165
+ /** The action ids a dropdown draws, in order — what G1 compares. */
166
+ declare function dropdownActionIds(entries: readonly ObjectActionDropdownEntry[]): string[];
167
+
168
+ export { ACTION_CHECKING_ACCESS_REASON as A, type BuiltOnDestination as B, type Capability as C, DEFAULT_ACTION_ORIGIN as D, KERNEL_REASON as K, LEVEL_WORD as L, NOT_ANSWERED_YET as N, type ObjectAction as O, type TableActionHost as T, type WhatYouMayDo as W, ACTION_NOT_HERE_REASON as a, ACTION_NO_ACCESS_REASON as b, ACTION_PLATFORM_TABLE_REASON as c, OBJECT_ACTION_GROUPS as d, type ObjectActionDropdownEntry as e, type ObjectActionGroup as f, type ObjectActionGroupDef as g, type ObjectActionIcon as h, type ObjectActionSection as i, type TableActionSubject as j, type TableActionsInput as k, dropdownActionIds as l, groupObjectActions as m, levelNeededFor as n, tableLink as o, toDropdownEntries as p, whatYouMayDoWithTable as q, rightsReason as r, withExtensions as s, tableActions as t, whatYouMayDo as w };
@@ -0,0 +1,168 @@
1
+ import { PermissionLevel, Table } from '@ai-matrx/records';
2
+
3
+ /** The six things a person does to a record or a table, as the screens offer them. */
4
+ type Capability = "read" | "comment" | "write" | "remove" | "share" | "structure";
5
+ interface WhatYouMayDo {
6
+ /** The word the store answered, or null when it answered nothing. */
7
+ level: PermissionLevel | null;
8
+ /**
9
+ * Whether the store has ANSWERED yet. `false` is a third state and not a
10
+ * refusal: a screen that drew "you may not" while the answer was in flight
11
+ * would blink every control off on every reload, which is its own lie.
12
+ */
13
+ known: boolean;
14
+ read: boolean;
15
+ comment: boolean;
16
+ write: boolean;
17
+ remove: boolean;
18
+ share: boolean;
19
+ structure: boolean;
20
+ /** Why this person may not do that, in one sentence naming the way in. */
21
+ why: (what: Capability) => string;
22
+ }
23
+ /** What each rung of the ladder is called where a person reads it. */
24
+ declare const LEVEL_WORD: Record<PermissionLevel, string>;
25
+ /** The rung a capability asks for — so a short "Needs Admin access" never re-decides the ladder. */
26
+ declare function levelNeededFor(what: Capability): PermissionLevel;
27
+ /**
28
+ * WHAT ONE LEVEL LETS A PERSON DO. `level` null and `known` true means the
29
+ * store said "nothing" — a real answer. `known` false means it has not said.
30
+ */
31
+ declare function whatYouMayDo(level: PermissionLevel | null, known?: boolean): WhatYouMayDo;
32
+ /** Nothing offered, because nothing is known yet. */
33
+ declare const NOT_ANSWERED_YET: WhatYouMayDo;
34
+ /**
35
+ * REC-27. The nine Tables the platform ships are not administered from a
36
+ * person's screen whatever level they hold on them — so the structure controls
37
+ * are absent for a kernel Table and say why, and everything else follows the
38
+ * level as usual.
39
+ */
40
+ declare const KERNEL_REASON: string;
41
+ declare function whatYouMayDoWithTable(table: Table | null | undefined, level: PermissionLevel | null, known: boolean): WhatYouMayDo;
42
+
43
+ /**
44
+ * A Lucide icon NAME, kebab-case — the same currency `Table.icon` already uses.
45
+ * Closed on purpose: each renderer maps every member to its own component, and a
46
+ * new member fails that renderer's typecheck until it is mapped.
47
+ */
48
+ type ObjectActionIcon = "folder-open" | "external-link" | "link" | "pencil" | "copy" | "folder-input" | "star" | "star-off" | "share-2" | "download" | "upload" | "columns-3" | "settings" | "history" | "blocks" | "file-text" | "calendar-clock" | "list-checks" | "bell" | "door-open" | "inbox" | "layout-dashboard" | "archive-restore" | "archive" | "link-2" | "layout-grid";
49
+ /** The groups, in their one order. Separators fall out of group boundaries. */
50
+ type ObjectActionGroup = "open" | "organize" | "share" | "manage" | "built-on" | "danger";
51
+ interface ObjectActionGroupDef {
52
+ id: ObjectActionGroup;
53
+ /** Present only on a group that renders as a submenu. */
54
+ label?: string;
55
+ icon?: ObjectActionIcon;
56
+ /** Rendered as ONE submenu entry holding the group's actions. */
57
+ submenu: boolean;
58
+ }
59
+ declare const OBJECT_ACTION_GROUPS: readonly ObjectActionGroupDef[];
60
+ /** One thing a person can do to an object, for any renderer. */
61
+ interface ObjectAction {
62
+ /** Stable within the object's list. React key, test handle, future ⌘K id. */
63
+ id: string;
64
+ label: string;
65
+ icon: ObjectActionIcon;
66
+ group: ObjectActionGroup;
67
+ /** Display-only hint ("⌘D"). */
68
+ shortcut?: string;
69
+ destructive?: boolean;
70
+ /** Present = shown disabled with this line (≤ 60 chars). Absent = enabled. */
71
+ disabledReason?: string;
72
+ /** Called only when enabled. The host owns the side effect and its feedback. */
73
+ run: () => void | Promise<void>;
74
+ }
75
+ /** What the list needs to know about the table. A full `Table` satisfies it. */
76
+ type TableActionSubject = Pick<Table, "id" | "name"> & Partial<Pick<Table, "is_kernel">>;
77
+ /** The places built on a table, in their one order. */
78
+ type BuiltOnDestination = "forms" | "bookings" | "checklists" | "notifications" | "portals" | "inbox" | "dashboards" | "archived";
79
+ type Handler = (table: TableActionSubject) => void | Promise<void>;
80
+ /**
81
+ * THE SIDE EFFECTS THIS PACKAGE CANNOT OWN. Every handler is optional: one the
82
+ * host leaves out keeps its action in the list, disabled, saying so.
83
+ */
84
+ interface TableActionHost {
85
+ /** Origin for Copy link and Open in new tab. Default `https://www.aimatrx.com`. */
86
+ origin?: string;
87
+ open?: Handler;
88
+ /** Receives the table's link (`<origin>/data-v2/<id>`). */
89
+ openInNewTab?: (url: string, table: TableActionSubject) => void;
90
+ /** Receives the table's link. Runs inside the click (clipboard needs the gesture). */
91
+ copyText?: (text: string, table: TableActionSubject) => void | Promise<void>;
92
+ rename?: Handler;
93
+ duplicate?: Handler;
94
+ move?: Handler;
95
+ /** Current favorite state; flips the Favorite label. Unknown = "Add to favorites". */
96
+ isFavorite?: boolean;
97
+ toggleFavorite?: Handler;
98
+ share?: Handler;
99
+ export?: Handler;
100
+ import?: Handler;
101
+ addColumn?: Handler;
102
+ settings?: Handler;
103
+ history?: Handler;
104
+ /** The "Built on it" destinations, one handler for all eight. */
105
+ openBuiltOn?: (destination: BuiltOnDestination, table: TableActionSubject) => void;
106
+ archive?: Handler;
107
+ /**
108
+ * ANOTHER LANE'S ENTRIES ("Link a record…", a hub tile's verbs). Return the
109
+ * same ids whatever `rights` say — express rights as `disabledReason`. Each
110
+ * entry lands at the END of its named group, in the order returned; `danger`
111
+ * is refused (Archive is always last) and so is an id already in the list.
112
+ */
113
+ extend?: (table: TableActionSubject, rights: WhatYouMayDo) => readonly ObjectAction[];
114
+ }
115
+ interface TableActionsInput {
116
+ table: TableActionSubject;
117
+ rights: WhatYouMayDo;
118
+ host: TableActionHost;
119
+ }
120
+ declare const DEFAULT_ACTION_ORIGIN = "https://www.aimatrx.com";
121
+ /** The one link to a table: `<origin>/data-v2/<tableId>`. */
122
+ declare function tableLink(tableId: string, origin?: string): string;
123
+ declare const ACTION_NOT_HERE_REASON = "Not available here";
124
+ declare const ACTION_CHECKING_ACCESS_REASON = "Checking your access\u2026";
125
+ declare const ACTION_NO_ACCESS_REASON = "You don't have access";
126
+ declare const ACTION_PLATFORM_TABLE_REASON = "Platform tables can't be changed here";
127
+ /** Why `rights` refuse `what`, in one short line — or null when they allow it. */
128
+ declare function rightsReason(rights: WhatYouMayDo, what: Capability, table?: TableActionSubject): string | null;
129
+ /**
130
+ * THE TABLE'S ACTIONS, in the one order. Same ids, same order, for every seat
131
+ * and every host — only `disabledReason` varies.
132
+ */
133
+ declare function tableActions(input: TableActionsInput): ObjectAction[];
134
+ /**
135
+ * Another lane's entries, placed deterministically: each at the end of its
136
+ * group, in the order given. Loud on the two mistakes that would break the
137
+ * invariants — a `danger` entry (Archive must stay last) and a duplicate id.
138
+ */
139
+ declare function withExtensions(base: readonly ObjectAction[], extra: readonly ObjectAction[]): ObjectAction[];
140
+ /** A run of actions that renders together: a plain section, or one submenu. */
141
+ interface ObjectActionSection {
142
+ group: ObjectActionGroupDef;
143
+ actions: ObjectAction[];
144
+ }
145
+ /**
146
+ * THE ONE GROUPING every adapter uses: the list cut at group boundaries, in
147
+ * group order, empty groups dropped, the order inside a group kept.
148
+ */
149
+ declare function groupObjectActions(actions: readonly ObjectAction[]): ObjectActionSection[];
150
+ /** The header ⋯ dropdown's entries — records-ui's own renderer reads these. */
151
+ type ObjectActionDropdownEntry = {
152
+ kind: "separator";
153
+ id: string;
154
+ } | {
155
+ kind: "item";
156
+ action: ObjectAction;
157
+ } | {
158
+ kind: "submenu";
159
+ id: string;
160
+ label: string;
161
+ icon: ObjectActionIcon | undefined;
162
+ actions: ObjectAction[];
163
+ };
164
+ declare function toDropdownEntries(actions: readonly ObjectAction[]): ObjectActionDropdownEntry[];
165
+ /** The action ids a dropdown draws, in order — what G1 compares. */
166
+ declare function dropdownActionIds(entries: readonly ObjectActionDropdownEntry[]): string[];
167
+
168
+ export { ACTION_CHECKING_ACCESS_REASON as A, type BuiltOnDestination as B, type Capability as C, DEFAULT_ACTION_ORIGIN as D, KERNEL_REASON as K, LEVEL_WORD as L, NOT_ANSWERED_YET as N, type ObjectAction as O, type TableActionHost as T, type WhatYouMayDo as W, ACTION_NOT_HERE_REASON as a, ACTION_NO_ACCESS_REASON as b, ACTION_PLATFORM_TABLE_REASON as c, OBJECT_ACTION_GROUPS as d, type ObjectActionDropdownEntry as e, type ObjectActionGroup as f, type ObjectActionGroupDef as g, type ObjectActionIcon as h, type ObjectActionSection as i, type TableActionSubject as j, type TableActionsInput as k, dropdownActionIds as l, groupObjectActions as m, levelNeededFor as n, tableLink as o, toDropdownEntries as p, whatYouMayDoWithTable as q, rightsReason as r, withExtensions as s, tableActions as t, whatYouMayDo as w };