@ai-matrx/sharing 0.0.0 → 0.1.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/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +32 -1
- package/dist/access-react-cant-remove-dialog.cjs +52 -0
- package/dist/access-react-cant-remove-dialog.cjs.map +1 -0
- package/dist/access-react-cant-remove-dialog.d.cts +6 -0
- package/dist/access-react-cant-remove-dialog.d.ts +6 -0
- package/dist/access-react-cant-remove-dialog.js +32 -0
- package/dist/access-react-cant-remove-dialog.js.map +1 -0
- package/dist/access-react.cjs +2808 -0
- package/dist/access-react.cjs.map +1 -0
- package/dist/access-react.d.cts +682 -0
- package/dist/access-react.d.ts +682 -0
- package/dist/access-react.js +2896 -0
- package/dist/access-react.js.map +1 -0
- package/dist/core.cjs +5384 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +4737 -0
- package/dist/core.d.ts +4737 -0
- package/dist/core.js +5360 -0
- package/dist/core.js.map +1 -0
- package/dist/react.cjs +4574 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +779 -0
- package/dist/react.d.ts +779 -0
- package/dist/react.js +4701 -0
- package/dist/react.js.map +1 -0
- package/package.json +135 -1
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,779 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import react__default, { ReactNode, ComponentType } from 'react';
|
|
3
|
+
import { ConfirmOptions } from '@ai-matrx/kit/confirm-opener';
|
|
4
|
+
import { ResourceType, PermissionWithDetails, PermissionLevel, ShareActionResult, SharingCopyContext, AccessSummary, ShownTo, WhoCanSee, LaneChoice, Permission, CheckPermissionOptions } from '@ai-matrx/sharing/core';
|
|
5
|
+
import { EntityTypeToken } from '@ai-matrx/associations';
|
|
6
|
+
|
|
7
|
+
type LooseProps = {
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
};
|
|
10
|
+
interface ShareSheetOrganization {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
interface ShareSheetConnection {
|
|
16
|
+
user_id: string;
|
|
17
|
+
email: string | null;
|
|
18
|
+
display_name: string | null;
|
|
19
|
+
avatar_url: string | null;
|
|
20
|
+
source: "conversation" | "organization" | "invitation";
|
|
21
|
+
sourceDetails?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
interface ShareSheetConnections {
|
|
24
|
+
connections: ShareSheetConnection[];
|
|
25
|
+
isLoading: boolean;
|
|
26
|
+
error: string | null;
|
|
27
|
+
partialFailures: string[];
|
|
28
|
+
refresh: () => Promise<void> | void;
|
|
29
|
+
}
|
|
30
|
+
interface ShareSheetToastOptions {
|
|
31
|
+
title?: ReactNode | undefined;
|
|
32
|
+
description?: ReactNode | undefined;
|
|
33
|
+
variant?: "default" | "destructive" | "success" | string | undefined;
|
|
34
|
+
}
|
|
35
|
+
interface ShareSheetUi {
|
|
36
|
+
/** Messages. Default: `console` + `window.alert` for errors (never swallowed). */
|
|
37
|
+
toast: (options: ShareSheetToastOptions) => void;
|
|
38
|
+
/** The signed-in person's id. Default: read once from the sharing client's session. */
|
|
39
|
+
useCurrentUserId: () => string | null;
|
|
40
|
+
/** The organizations the person belongs to (`{id, name}`). Default: `organizations` read once. */
|
|
41
|
+
useOrganizations: () => ShareSheetOrganization[];
|
|
42
|
+
/** Contacts offered in the People tab. Default: the organization's roster. */
|
|
43
|
+
useUserConnections: (options: {
|
|
44
|
+
organizationId?: string;
|
|
45
|
+
}) => ShareSheetConnections;
|
|
46
|
+
confirm: (options: ConfirmOptions) => Promise<boolean>;
|
|
47
|
+
CopyButtons: ComponentType<LooseProps>;
|
|
48
|
+
csvExportItem: (...args: any[]) => any;
|
|
49
|
+
jsonExportItem: (...args: any[]) => any;
|
|
50
|
+
usePageCapture: (build: () => unknown, options?: {
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
}) => void;
|
|
53
|
+
dialogCapture: (input: any) => unknown;
|
|
54
|
+
PageCaptureButton: ComponentType<LooseProps>;
|
|
55
|
+
ErrorAlchemyMenu: ComponentType<LooseProps>;
|
|
56
|
+
InfoHint: ComponentType<LooseProps>;
|
|
57
|
+
EntityDoorControls: ComponentType<LooseProps>;
|
|
58
|
+
EntityRef: ComponentType<LooseProps>;
|
|
59
|
+
UserAvatarDisplay: ComponentType<LooseProps>;
|
|
60
|
+
ConnectionsReadNotice: ComponentType<LooseProps>;
|
|
61
|
+
UserSearchField: ComponentType<LooseProps>;
|
|
62
|
+
/** The vault identity the secure-link panel seals with (`@ai-matrx/vault`). */
|
|
63
|
+
vaultIdentity: unknown;
|
|
64
|
+
humanLines: (...args: any[]) => string;
|
|
65
|
+
/** Where dialogs portal (the web: its pop-out window container). Default: the document body. */
|
|
66
|
+
usePortalContainer: () => HTMLElement | null | undefined;
|
|
67
|
+
}
|
|
68
|
+
/** Merge host UI over the defaults (boot-time; tests may call it again). */
|
|
69
|
+
declare function configureShareSheetUi(next: Partial<ShareSheetUi>): void;
|
|
70
|
+
declare function shareSheetUi(): ShareSheetUi;
|
|
71
|
+
/** Test seam: forget every cached answer. */
|
|
72
|
+
declare function resetShareSheetCache(): void;
|
|
73
|
+
|
|
74
|
+
interface ShareModalProps {
|
|
75
|
+
/** The level picker's words: "notion" = Full access · Edit · Comment · View. */
|
|
76
|
+
levelWording?: "roles" | "notion" | undefined;
|
|
77
|
+
isOpen: boolean;
|
|
78
|
+
onClose: () => void;
|
|
79
|
+
resourceType: ResourceType;
|
|
80
|
+
resourceId: string;
|
|
81
|
+
resourceName: string;
|
|
82
|
+
/**
|
|
83
|
+
* The organization this resource belongs to. Pass it whenever the caller knows: it scopes
|
|
84
|
+
* the contact picker to that organization's members (FIX-7B), and the share's in-app
|
|
85
|
+
* notification is filed there (ACCESS-FIX-18) — without it, a share from a page with no
|
|
86
|
+
* organization picked raised "Which workspace is this for?". It is NOT used for the grant —
|
|
87
|
+
* the store still resolves a record's organization off the row itself.
|
|
88
|
+
*/
|
|
89
|
+
organizationId?: string | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* What to CALL this thing on screen, when the caller knows better than the
|
|
92
|
+
* registry does. In the unified store a Table IS a `custom.record` row, so
|
|
93
|
+
* `resourceType="record"` is correct and the registry's label — "Record" —
|
|
94
|
+
* is the wrong noun for a table: the seventh-pass verdict read "Share
|
|
95
|
+
* Record" above a table's own name. Omit it and the registry's label stands.
|
|
96
|
+
*/
|
|
97
|
+
resourceNoun?: string | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* OPTIONAL override. Leave it out — the modal resolves ownership itself.
|
|
100
|
+
*
|
|
101
|
+
* Only pass this when the caller already holds an authoritative, resolved
|
|
102
|
+
* answer (e.g. it just created the row). Passing a stale or defaulted
|
|
103
|
+
* `false` is what renders this dialog as a dead, empty shell for a user who
|
|
104
|
+
* owns the record.
|
|
105
|
+
*/
|
|
106
|
+
isOwner?: boolean | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* SHARING WITH SOMEBODY OUTSIDE THE ORGANIZATION (lane SHARE-OUT, 21 September).
|
|
109
|
+
*
|
|
110
|
+
* Pass this when the subject is a TABLE in the unified record store and the
|
|
111
|
+
* caller knows which organization it belongs to. The Users tab then carries
|
|
112
|
+
* the outside lane: invite by email, "invited, not yet joined", resend and
|
|
113
|
+
* revoke. Leave it out and the dialog is exactly what it was — this is not a
|
|
114
|
+
* capability every resource type has, and a panel that could not work is a
|
|
115
|
+
* panel that must not be drawn.
|
|
116
|
+
*
|
|
117
|
+
* It is NOT a second share surface: the grant it produces is an ordinary
|
|
118
|
+
* `iam.permissions` row read by the same ladder, and the pending state is an
|
|
119
|
+
* `iam.invitations` row, the platform's one invitation primitive.
|
|
120
|
+
*/
|
|
121
|
+
outsideShare?: {
|
|
122
|
+
organizationId: string;
|
|
123
|
+
tableId: string;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* ShareModal - Main sharing interface
|
|
128
|
+
*
|
|
129
|
+
* Generic modal that works with ANY resource type.
|
|
130
|
+
* Provides tabs for sharing with people or making public. A share names a PERSON, never an
|
|
131
|
+
* organization (SHARE-PEOPLE-ONLY, 2026-09-25): the old Organizations tab is gone, and "Add
|
|
132
|
+
* everyone in <organization>" inside the People tab names each current member instead.
|
|
133
|
+
*
|
|
134
|
+
* This is the ONE sharing dialog in the app. Do not build a feature-specific
|
|
135
|
+
* variant — extend this one. It self-resolves ownership, so every call site is
|
|
136
|
+
* a three-prop drop-in.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* <ShareModal
|
|
140
|
+
* isOpen={isOpen}
|
|
141
|
+
* onClose={() => setIsOpen(false)}
|
|
142
|
+
* resourceType="workflow"
|
|
143
|
+
* resourceId={workflowId}
|
|
144
|
+
* resourceName="My Workflow"
|
|
145
|
+
* />
|
|
146
|
+
*/
|
|
147
|
+
declare function ShareModal({ levelWording, isOpen, onClose, resourceType, resourceId, resourceName, organizationId, resourceNoun, isOwner: isOwnerOverride, outsideShare, }: ShareModalProps): react__default.JSX.Element;
|
|
148
|
+
|
|
149
|
+
interface PermissionsListProps {
|
|
150
|
+
permissions: PermissionWithDetails[];
|
|
151
|
+
isOwner: boolean;
|
|
152
|
+
onUpdateLevel: (options: {
|
|
153
|
+
userId?: string | undefined;
|
|
154
|
+
organizationId?: string | undefined;
|
|
155
|
+
isPublic?: boolean | undefined;
|
|
156
|
+
}, newLevel: PermissionLevel) => Promise<ShareActionResult>;
|
|
157
|
+
onRevoke: (options: {
|
|
158
|
+
userId?: string | undefined;
|
|
159
|
+
organizationId?: string | undefined;
|
|
160
|
+
isPublic?: boolean | undefined;
|
|
161
|
+
}) => Promise<ShareActionResult>;
|
|
162
|
+
loading?: boolean | undefined;
|
|
163
|
+
/**
|
|
164
|
+
* Identity + the page's leading KPIs, so every copied grant states what it
|
|
165
|
+
* belongs to. Optional: without it the list still copies, falling back to the
|
|
166
|
+
* identity carried on the permission rows themselves — but a page that shows
|
|
167
|
+
* KPIs above this list should pass them so the payloads mirror the screen.
|
|
168
|
+
*/
|
|
169
|
+
copy?: SharingCopyContext | undefined;
|
|
170
|
+
/** Which slice this list renders, e.g. "Users" / "Organizations". */
|
|
171
|
+
listLabel?: string | undefined;
|
|
172
|
+
/**
|
|
173
|
+
* 🚨 WHAT ELSE IS ON THIS SCREEN THAT IS NOT A GRANT (FIX-10C, VERIFIER-10
|
|
174
|
+
* F13, 2026-09-22).
|
|
175
|
+
*
|
|
176
|
+
* This list only ever knew about DIRECT grants, and said so honestly in its
|
|
177
|
+
* scope note. But after an outside invitation lands, the dialog read
|
|
178
|
+
* "Current Access — Not shared with anyone — No one has been granted access
|
|
179
|
+
* here" with the invited person's row drawn directly underneath it. Both
|
|
180
|
+
* halves were true and the screen contradicted itself, which is the one thing
|
|
181
|
+
* a screen may not do.
|
|
182
|
+
*
|
|
183
|
+
* An invitation is not a grant — it confers nothing until it is accepted, and
|
|
184
|
+
* making this list count it would be the same lie pointing the other way. So
|
|
185
|
+
* the empty state stays an empty state and simply stops pretending it is the
|
|
186
|
+
* whole screen: the caller that also draws the pending rows says how many
|
|
187
|
+
* there are, and the sentence names them.
|
|
188
|
+
*/
|
|
189
|
+
alsoPending?: {
|
|
190
|
+
count: number;
|
|
191
|
+
one: string;
|
|
192
|
+
many: string;
|
|
193
|
+
} | undefined;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* PermissionsList - Display and manage current permissions
|
|
197
|
+
*
|
|
198
|
+
* Shows all users, organizations, and public access for a resource.
|
|
199
|
+
* Allows owners to update permission levels or revoke access.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* <PermissionsList
|
|
203
|
+
* permissions={permissions}
|
|
204
|
+
* isOwner={isOwner}
|
|
205
|
+
* onUpdateLevel={updateLevel}
|
|
206
|
+
* onRevoke={revokeAccess}
|
|
207
|
+
* />
|
|
208
|
+
*/
|
|
209
|
+
declare function PermissionsList({ permissions, isOwner, onUpdateLevel, onRevoke, loading, copy, listLabel, alsoPending, }: PermissionsListProps): react__default.JSX.Element;
|
|
210
|
+
|
|
211
|
+
interface PermissionBadgeProps {
|
|
212
|
+
level: PermissionLevel | "owner";
|
|
213
|
+
variant?: "default" | "compact" | undefined;
|
|
214
|
+
showIcon?: boolean | undefined;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* PermissionBadge - Visual indicator for permission levels
|
|
218
|
+
*
|
|
219
|
+
* Displays color-coded badges for different permission levels
|
|
220
|
+
* Used throughout the app to show user permissions
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* <PermissionBadge level="editor" />
|
|
224
|
+
* <PermissionBadge level="owner" showIcon />
|
|
225
|
+
*/
|
|
226
|
+
declare function PermissionBadge({ level, variant, showIcon, }: PermissionBadgeProps): react__default.JSX.Element;
|
|
227
|
+
/**
|
|
228
|
+
* PublicBadge - Badge specifically for public resources
|
|
229
|
+
*/
|
|
230
|
+
declare function PublicBadge({ variant, }: {
|
|
231
|
+
variant?: "default" | "compact" | undefined;
|
|
232
|
+
}): react__default.JSX.Element;
|
|
233
|
+
/**
|
|
234
|
+
* PermissionLevelDescription - Show what each level can do
|
|
235
|
+
*/
|
|
236
|
+
declare function PermissionLevelDescription({ level, }: {
|
|
237
|
+
level: PermissionLevel;
|
|
238
|
+
}): react__default.JSX.Element;
|
|
239
|
+
/**
|
|
240
|
+
* GuestBadge — a person who is not a member of the thing's organization (CLOSE-SHARE, Notion's "Guest").
|
|
241
|
+
* The store decides (`isGuest` from get_resource_permissions; a Space's presence carries its own answer).
|
|
242
|
+
* One marker for every share list and avatar row.
|
|
243
|
+
*/
|
|
244
|
+
declare function GuestBadge(): react__default.JSX.Element;
|
|
245
|
+
|
|
246
|
+
/** What the panel currently knows, for pages that mirror it in their payload. */
|
|
247
|
+
interface AccessSummaryState {
|
|
248
|
+
summary: AccessSummary | null;
|
|
249
|
+
error: string | null;
|
|
250
|
+
loading: boolean;
|
|
251
|
+
}
|
|
252
|
+
interface AccessSummaryPanelProps {
|
|
253
|
+
entityType: EntityTypeToken;
|
|
254
|
+
entityId: string | null;
|
|
255
|
+
/** Load only when the surface is actually visible. */
|
|
256
|
+
enabled?: boolean | undefined;
|
|
257
|
+
/**
|
|
258
|
+
* Change this value to force a refetch. Required on surfaces that mutate
|
|
259
|
+
* grants beside the panel (a Share tab) — pass a signature of the grant
|
|
260
|
+
* state so the summary can never contradict the list next to it.
|
|
261
|
+
*/
|
|
262
|
+
refreshToken?: unknown | undefined;
|
|
263
|
+
className?: string | undefined;
|
|
264
|
+
/**
|
|
265
|
+
* Identity + the page's leading KPIs, mirrored verbatim into this panel's
|
|
266
|
+
* payloads. Optional — without it the panel derives what it can from the
|
|
267
|
+
* summary itself.
|
|
268
|
+
*/
|
|
269
|
+
copy?: SharingCopyContext | undefined;
|
|
270
|
+
/**
|
|
271
|
+
* Lets the page that composes this panel mirror the reachability answer it
|
|
272
|
+
* is rendering, without paying for a second round trip. Pass a stable
|
|
273
|
+
* callback (a `useState` setter is ideal).
|
|
274
|
+
*/
|
|
275
|
+
onSummaryChange?: (state: AccessSummaryState) => void;
|
|
276
|
+
}
|
|
277
|
+
declare function AccessSummaryPanel({ entityType, entityId, enabled, refreshToken, className, copy, onSummaryChange, }: AccessSummaryPanelProps): react.JSX.Element | null;
|
|
278
|
+
|
|
279
|
+
interface RowControlsProps {
|
|
280
|
+
resourceType: ResourceType;
|
|
281
|
+
resourceId: string;
|
|
282
|
+
/** The person may change this thing's sharing. */
|
|
283
|
+
canChange: boolean;
|
|
284
|
+
/** `useSharing().shownTo` — undefined when the type does not carry it. */
|
|
285
|
+
shownTo: ShownTo | null | undefined;
|
|
286
|
+
/** `useSharing().isPublic` — published to the web. */
|
|
287
|
+
isPublic: boolean;
|
|
288
|
+
/** `useSharing().childRecord` — a child follows its parent: nothing is drawn. */
|
|
289
|
+
childRecord?: boolean | undefined;
|
|
290
|
+
/**
|
|
291
|
+
* `false` when this thing is never published to the web although its type is: a whole Table is a
|
|
292
|
+
* `record` too, and only a ROW has a page (/p/e/record/<id>), so a Table draws no publish switch
|
|
293
|
+
* at all (access ladder T-40; the database refuses it too). Omitted → the type decides.
|
|
294
|
+
*/
|
|
295
|
+
publishable?: boolean | undefined;
|
|
296
|
+
onSetShownTo: (next: ShownTo | null) => Promise<ShareActionResult>;
|
|
297
|
+
onPublish: () => Promise<ShareActionResult>;
|
|
298
|
+
onStopPublishing: () => Promise<ShareActionResult>;
|
|
299
|
+
}
|
|
300
|
+
declare function RowControls({ resourceType, resourceId, canChange, shownTo, isPublic, childRecord, publishable, onSetShownTo, onPublish, onStopPublishing, }: RowControlsProps): react__default.JSX.Element | null;
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* features/sharing/components/WhoCanSeeThis.tsx
|
|
304
|
+
*
|
|
305
|
+
* "WHO CAN SEE THIS" — THE LANE CONTROL AT THE TOP OF THE SHARE DIALOG'S PEOPLE TAB
|
|
306
|
+
* (lane SHARE-LANE-CONTROL, VERIFIER-23 item 3). Record-store things only; every other kind gets
|
|
307
|
+
* its row controls ("Shown to", "Published to the web") in the same place through `row`.
|
|
308
|
+
*
|
|
309
|
+
* The record store has had the door since lane SHARE (`custom.share_lane_set`: mine |
|
|
310
|
+
* organization | world). Under the access ladder law (T-36, chair ruling 2026-10-01) "mine" is the
|
|
311
|
+
* hide it is, "Shown to: Only me": the thing leaves coworkers' lists and still opens for members
|
|
312
|
+
* who have the link. It is never a lock; real separation is another organization or a
|
|
313
|
+
* Confidential/Private Table type. The words are `SHOWN_TO_WORDS.only_me`, the ones RowControls uses.
|
|
314
|
+
* Nothing on screen reached it: a door with no control is a dead end. This is that control, ONE
|
|
315
|
+
* primitive every share host renders (ShareModal, ShareModalWindow, AgentSharePanel,
|
|
316
|
+
* SiteAccessWorkspace) from `useSharing().whoCanSee` — it never reads or writes on its own.
|
|
317
|
+
*
|
|
318
|
+
* · Only me — lane mine: hidden from coworkers' lists; opens by link.
|
|
319
|
+
* · Everyone in <organization> — the organization's default, at the level it grants.
|
|
320
|
+
* · Anyone with the link — the world lane, drawn ONLY where it would be accepted
|
|
321
|
+
* (`world_open`) or is already the state. Otherwise absent,
|
|
322
|
+
* never disabled-looking.
|
|
323
|
+
*
|
|
324
|
+
* The current state is always shown. A person who cannot change sharing sees it as one line of
|
|
325
|
+
* text, not as buttons. Hiding takes nobody's access away, so it applies without a confirm.
|
|
326
|
+
* Named people are never touched.
|
|
327
|
+
*/
|
|
328
|
+
|
|
329
|
+
interface WhoCanSeeThisProps {
|
|
330
|
+
/** `useSharing().whoCanSee`. Null → the kind has no lane door, and nothing is drawn. */
|
|
331
|
+
whoCanSee: WhoCanSee | null;
|
|
332
|
+
/** The person may change this thing's sharing (the host's owner/Admin answer). */
|
|
333
|
+
canChange: boolean;
|
|
334
|
+
/** `useSharing().setWhoCanSee`. */
|
|
335
|
+
onChoose: (choice: LaneChoice) => Promise<ShareActionResult>;
|
|
336
|
+
/**
|
|
337
|
+
* Every kind outside the record store: its row controls ("Shown to", "Published to the web"),
|
|
338
|
+
* drawn in this same place. `RowControls` draws nothing for a Private, Confidential or child
|
|
339
|
+
* record (access ladder T-13 phase 5).
|
|
340
|
+
*/
|
|
341
|
+
row?: Omit<RowControlsProps, "canChange">;
|
|
342
|
+
}
|
|
343
|
+
declare function WhoCanSeeThis({ whoCanSee, canChange, onChoose, row, }: WhoCanSeeThisProps): react__default.JSX.Element | null;
|
|
344
|
+
|
|
345
|
+
interface ShareLinkPanelProps {
|
|
346
|
+
resourceType: ResourceType;
|
|
347
|
+
resourceId: string;
|
|
348
|
+
isOwner: boolean;
|
|
349
|
+
/** Whether this resource type offers no-login links (admin policy). Hidden when false. */
|
|
350
|
+
enabled?: boolean | undefined;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* "Anyone with the link" — mint / copy / revoke no-login share links.
|
|
354
|
+
*
|
|
355
|
+
* A share link is an opaque token that lets anyone view the resource with ZERO
|
|
356
|
+
* sign-in (resolved by the anon `resolve_share_token` RPC). This is the canonical
|
|
357
|
+
* link-carries-everything path — distinct from publishing to the web (which
|
|
358
|
+
* needs a public render route). Owner-only.
|
|
359
|
+
*/
|
|
360
|
+
declare function ShareLinkPanel({ resourceType, resourceId, isOwner, enabled, }: ShareLinkPanelProps): react__default.JSX.Element | null;
|
|
361
|
+
|
|
362
|
+
type GrantableLevels = {
|
|
363
|
+
loading: boolean;
|
|
364
|
+
/** Could not be asked (a failure is not a refusal). */
|
|
365
|
+
error: string | null;
|
|
366
|
+
/** level -> null when allowed, else the reason. Absent while loading or on error. */
|
|
367
|
+
levels: Partial<Record<PermissionLevel, string | null>>;
|
|
368
|
+
/** May share outside the organization: null when allowed, else the reason. */
|
|
369
|
+
outside: string | null;
|
|
370
|
+
/** True when at least one level may be given - i.e. the person may share at all. */
|
|
371
|
+
maySharePeople: boolean;
|
|
372
|
+
};
|
|
373
|
+
declare function useGrantableLevels(resourceType: string, resourceId: string, enabled: boolean, refreshKey?: string | undefined): GrantableLevels;
|
|
374
|
+
|
|
375
|
+
/** One current member of the chosen organization, as the dialog shows them. */
|
|
376
|
+
interface OrgMemberPerson {
|
|
377
|
+
userId: string;
|
|
378
|
+
email: string;
|
|
379
|
+
name: string;
|
|
380
|
+
}
|
|
381
|
+
interface AddEveryoneInOrgProps {
|
|
382
|
+
/** Grants ONE person. The same door the single-person share uses. */
|
|
383
|
+
grantPerson: (person: OrgMemberPerson, level: PermissionLevel) => Promise<ShareActionResult>;
|
|
384
|
+
/** The level picked in the People tab: the block's own level starts here, and follows it until the person picks one here. */
|
|
385
|
+
level: PermissionLevel;
|
|
386
|
+
/** Why a level may not be given on this thing (null: may). Those levels are shown disabled with the reason. */
|
|
387
|
+
whyNotLevel?: (level: PermissionLevel) => string | null;
|
|
388
|
+
/** People who already hold a grant on this thing. They are shown, not re-granted. */
|
|
389
|
+
alreadySharedUserIds?: string[] | undefined;
|
|
390
|
+
/** Called once after a run that granted at least one person. */
|
|
391
|
+
onDone?: () => void;
|
|
392
|
+
/**
|
|
393
|
+
* The organization the thing lives in, when the dialog knows it. It is chosen first, so "Add
|
|
394
|
+
* everyone in <that organization>" is one press away; any other organization the person
|
|
395
|
+
* belongs to stays one pick away.
|
|
396
|
+
*/
|
|
397
|
+
defaultOrgId?: string | undefined;
|
|
398
|
+
}
|
|
399
|
+
declare function AddEveryoneInOrg({ grantPerson, level: sectionLevel, whyNotLevel, alreadySharedUserIds, onDone, defaultOrgId, }: AddEveryoneInOrgProps): react__default.JSX.Element | null;
|
|
400
|
+
|
|
401
|
+
interface ShareWithUserTabProps {
|
|
402
|
+
onShare: (userId: string, level: PermissionLevel) => Promise<ShareActionResult>;
|
|
403
|
+
onSuccess: () => void;
|
|
404
|
+
resourceType: ResourceType;
|
|
405
|
+
resourceId: string;
|
|
406
|
+
/**
|
|
407
|
+
* THE ORGANIZATION THIS THING BELONGS TO (FIX-7B). With it, the contact list is that
|
|
408
|
+
* organization's members and nobody else. Without it the list is every organization the
|
|
409
|
+
* viewer belongs to, which is what a brand-new organization's share dialog looked like when
|
|
410
|
+
* the seventh pass found it offering "people from all over the database".
|
|
411
|
+
*/
|
|
412
|
+
organizationId?: string | undefined;
|
|
413
|
+
/** Identity + the page's leading KPIs, mirrored into the failure payload. */
|
|
414
|
+
copy?: SharingCopyContext | undefined;
|
|
415
|
+
/**
|
|
416
|
+
* "ADD EVERYONE IN <ORGANIZATION>" (SHARE-PEOPLE-ONLY). How ONE listed member is granted.
|
|
417
|
+
* Omitted → `onShare(person.userId, level)`, the same door as the form above. A record-store
|
|
418
|
+
* table passes the outside door here, because its members may sit outside the table's own
|
|
419
|
+
* organization.
|
|
420
|
+
*/
|
|
421
|
+
grantEveryonePerson?: (person: OrgMemberPerson, level: PermissionLevel) => Promise<ShareActionResult>;
|
|
422
|
+
/** People who already hold a grant; "Add everyone" shows them and skips them. */
|
|
423
|
+
alreadySharedUserIds?: string[] | undefined;
|
|
424
|
+
/**
|
|
425
|
+
* "notion": the level picker reads the ladder's sentence labels, highest first — Full access · Edit ·
|
|
426
|
+
* Comment · View (Spaces copies Notion's Share menu). Default: the role words.
|
|
427
|
+
*/
|
|
428
|
+
levelWording?: "roles" | "notion" | undefined;
|
|
429
|
+
/**
|
|
430
|
+
* The levels the doors will accept from THIS person (iam.may_grant_as). A level with a reason is shown
|
|
431
|
+
* disabled with that reason; omitted, every level is offered and the door answers (as before).
|
|
432
|
+
*/
|
|
433
|
+
grantable?: GrantableLevels | undefined;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* ShareWithUserTab - Form to share with a specific user.
|
|
437
|
+
* Shows the user's contacts from conversations, organizations, and invitations
|
|
438
|
+
* for quick selection, with a manual email input fallback.
|
|
439
|
+
*/
|
|
440
|
+
declare function ShareWithUserTab({ levelWording, grantable, onShare, onSuccess, resourceType, resourceId, organizationId, copy, grantEveryonePerson, alreadySharedUserIds, }: ShareWithUserTabProps): react__default.JSX.Element;
|
|
441
|
+
|
|
442
|
+
interface PublicAccessTabProps {
|
|
443
|
+
/** The public permission row from the permissions table, if any (kept for hosts' tab dot). */
|
|
444
|
+
publicPermission?: Permission | undefined;
|
|
445
|
+
isOwner: boolean;
|
|
446
|
+
resourceType: ResourceType;
|
|
447
|
+
resourceId: string;
|
|
448
|
+
resourceName: string;
|
|
449
|
+
/**
|
|
450
|
+
* Identity + the page's leading KPIs, mirrored into this tab's payloads so a
|
|
451
|
+
* copied answer is interpretable on its own.
|
|
452
|
+
*/
|
|
453
|
+
copy?: SharingCopyContext | undefined;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* What "Anyone" means for this type, in words that never promise more than the
|
|
457
|
+
* platform delivers. "No sign-in" only where a signed-out page exists
|
|
458
|
+
* (utils/permissions/publicLane.ts); everywhere else public means every signed-in
|
|
459
|
+
* person finds it under Public, and a signed-out visitor reaches it only through a
|
|
460
|
+
* no-login link — when the type has one. Pure — exported for tests.
|
|
461
|
+
*/
|
|
462
|
+
declare function anyoneReachWords(typeLabel: string, reach: {
|
|
463
|
+
publicPage: boolean;
|
|
464
|
+
noLoginLink: boolean;
|
|
465
|
+
}): string;
|
|
466
|
+
/**
|
|
467
|
+
* PublicAccessTab — "Anyone with the link" (access ladder Words table, Link row).
|
|
468
|
+
*
|
|
469
|
+
* An Anyone link opens the record at its permission for whoever holds it, at EVERY level —
|
|
470
|
+
* Private and Confidential records included — and is never indexed. The row controls ("Shown to",
|
|
471
|
+
* "Published to the web") are not here: they sit at the top of the people tab
|
|
472
|
+
* (`RowControls`), and only on Organization and Public records (T-13 phase 5).
|
|
473
|
+
*/
|
|
474
|
+
declare function PublicAccessTab({ isOwner, resourceType, resourceId, resourceName, copy, }: PublicAccessTabProps): react__default.JSX.Element;
|
|
475
|
+
|
|
476
|
+
/** The one sentence a shut lane gets. Exported so the test asserts the words. */
|
|
477
|
+
declare const LANE_CLOSED_SAY = "This organization's administrator has turned off sharing with people outside it.";
|
|
478
|
+
interface OutsideSharePanelProps {
|
|
479
|
+
organizationId: string;
|
|
480
|
+
tableId: string;
|
|
481
|
+
tableName: string;
|
|
482
|
+
/**
|
|
483
|
+
* 🚨 SO THE LIST ABOVE CANNOT CONTRADICT THE ROWS BELOW (FIX-10C, VERIFIER-10
|
|
484
|
+
* F13). The grant list up the page knows only about grants, which is correct
|
|
485
|
+
* and was still how "Not shared with anyone" came to stand directly over an
|
|
486
|
+
* invited person. This panel tells its host how many people are invited and
|
|
487
|
+
* not yet joined; the host passes that to the grant list's empty state.
|
|
488
|
+
*/
|
|
489
|
+
onPendingChange?: ((count: number) => void) | undefined;
|
|
490
|
+
/**
|
|
491
|
+
* An address already inside the organization is GRANTED the table rather than
|
|
492
|
+
* invited (FIX-10C, VERIFIER-10 F7), and that grant belongs in the list at the
|
|
493
|
+
* top of this dialog, not here. So the host is told to re-read it — otherwise
|
|
494
|
+
* the person gets a sentence saying it happened and an unchanged screen.
|
|
495
|
+
*/
|
|
496
|
+
onGranted?: (() => void) | undefined;
|
|
497
|
+
}
|
|
498
|
+
declare function OutsideSharePanel({ organizationId, tableId, tableName, onPendingChange, onGranted, }: OutsideSharePanelProps): react__default.JSX.Element;
|
|
499
|
+
|
|
500
|
+
interface SecureLinkPanelProps {
|
|
501
|
+
resourceType: string;
|
|
502
|
+
resourceId: string;
|
|
503
|
+
resourceName: string;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Sending a password is a reveal: it needs the SAME fresh sign-in the vault asks for, through the
|
|
507
|
+
* vault's ONE "Confirm it's you" (Google, password or an emailed code) — never a second dialog.
|
|
508
|
+
*/
|
|
509
|
+
declare function SecureLinkPanel(props: SecureLinkPanelProps): react.JSX.Element;
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* features/sharing/components/OrgAvailabilityNote.tsx
|
|
513
|
+
*
|
|
514
|
+
* WHAT AN ORGANIZATION ROW IS NOW (SHARE-PEOPLE-ONLY, chair ruling 2026-09-25). A share names a
|
|
515
|
+
* person. An organization grantee is written only as organization AVAILABILITY: an agent bound
|
|
516
|
+
* to an organization's surface, an item contributed to its library, or the HR directory. That is
|
|
517
|
+
* organization configuration, not something this dialog grants. The row still gives access,
|
|
518
|
+
* though, so the dialog says so in one read-only line and never hides it. It is changed where it
|
|
519
|
+
* was set, in the organization.
|
|
520
|
+
*/
|
|
521
|
+
|
|
522
|
+
declare function OrgAvailabilityNote({ permissions, organizationDefault, }: {
|
|
523
|
+
permissions: PermissionWithDetails[];
|
|
524
|
+
/**
|
|
525
|
+
* SHARE-TAILS (chair ruling 2026-09-25): a thing nobody set to "Only me" is the organization's
|
|
526
|
+
* default, and every member reaches it without a share. "Not shared with anyone" above is true
|
|
527
|
+
* of shares; this line says who else really reaches it. Under "Only me" (access ladder T-36,
|
|
528
|
+
* chair ruling 2026-10-01) members still open it by link but no longer find it in lists, so the
|
|
529
|
+
* door sends no default and the lane control's "Only me" hint says the rest.
|
|
530
|
+
*/
|
|
531
|
+
organizationDefault?: {
|
|
532
|
+
level: string;
|
|
533
|
+
organizationName: string;
|
|
534
|
+
organizationId?: string | undefined;
|
|
535
|
+
} | null;
|
|
536
|
+
}): react__default.JSX.Element | null;
|
|
537
|
+
|
|
538
|
+
interface Props {
|
|
539
|
+
resourceType: string;
|
|
540
|
+
resourceId: string;
|
|
541
|
+
/**
|
|
542
|
+
* Re-read whenever this changes — pass the host's own published state so the control
|
|
543
|
+
* appears the moment the record is published (and leaves when it is unpublished).
|
|
544
|
+
*/
|
|
545
|
+
publishedHint?: boolean | undefined;
|
|
546
|
+
className?: string | undefined;
|
|
547
|
+
}
|
|
548
|
+
declare function SearchEngineIndexedSwitch({ resourceType, resourceId, publishedHint, className, }: Props): react.JSX.Element | null;
|
|
549
|
+
|
|
550
|
+
interface ShareOptions {
|
|
551
|
+
title: string;
|
|
552
|
+
text?: string | undefined;
|
|
553
|
+
/** `null` omits a separate URL field when the reviewed text already contains it. */
|
|
554
|
+
url?: string | null | undefined;
|
|
555
|
+
/** Full text to copy when native sharing is unavailable. */
|
|
556
|
+
copyText?: string | undefined;
|
|
557
|
+
fallbackTitle?: string | undefined;
|
|
558
|
+
fallbackDescription?: string | undefined;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Which door actually opened. Callers that announce the result ("Link copied")
|
|
562
|
+
* must not guess: a manual-fallback run copied nothing, and a toast claiming
|
|
563
|
+
* otherwise is a screen that lies.
|
|
564
|
+
*/
|
|
565
|
+
type ShareOutcome = "shared" | "copied" | "manual" | "cancelled";
|
|
566
|
+
interface UseShareResult {
|
|
567
|
+
share: (options: ShareOptions) => Promise<ShareOutcome>;
|
|
568
|
+
copy: (text: string, fallback?: {
|
|
569
|
+
title?: string | undefined;
|
|
570
|
+
description?: string | undefined;
|
|
571
|
+
}) => Promise<"copied" | "manual">;
|
|
572
|
+
copied: boolean;
|
|
573
|
+
fallbackDialog: ReactNode;
|
|
574
|
+
}
|
|
575
|
+
/** Native share-sheet first, clipboard second, accessible manual copy last. */
|
|
576
|
+
declare function useShare(): UseShareResult;
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* features/sharing/hooks/useAccessSummary.ts
|
|
580
|
+
*
|
|
581
|
+
* One-entity-at-a-time effective-access loader. `enabled` exists so callers can
|
|
582
|
+
* mount the panel inside a collapsed tab and only pay for the round trip when
|
|
583
|
+
* the user actually looks — this query is NOT cheap enough to fire per row.
|
|
584
|
+
*/
|
|
585
|
+
|
|
586
|
+
interface UseAccessSummaryArgs {
|
|
587
|
+
entityType: EntityTypeToken;
|
|
588
|
+
entityId: string | null;
|
|
589
|
+
/** Load only while true. Defaults to true. */
|
|
590
|
+
enabled?: boolean | undefined;
|
|
591
|
+
/**
|
|
592
|
+
* Change this value to force a refetch — for surfaces that mutate grants
|
|
593
|
+
* beside the panel (a Share tab), pass a signature of the grant state so
|
|
594
|
+
* the summary can never contradict the freshly-refreshed list next to it.
|
|
595
|
+
*/
|
|
596
|
+
refreshToken?: unknown | undefined;
|
|
597
|
+
}
|
|
598
|
+
interface UseAccessSummaryResult {
|
|
599
|
+
summary: AccessSummary | null;
|
|
600
|
+
loading: boolean;
|
|
601
|
+
error: string | null;
|
|
602
|
+
reload: () => void;
|
|
603
|
+
}
|
|
604
|
+
declare function useAccessSummary({ entityType, entityId, enabled, refreshToken, }: UseAccessSummaryArgs): UseAccessSummaryResult;
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Permission Hooks
|
|
608
|
+
*
|
|
609
|
+
* React hooks for working with permissions in components.
|
|
610
|
+
* These hooks provide reactive state management for permissions.
|
|
611
|
+
*/
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Hook to get all permissions for a resource
|
|
615
|
+
* @param resourceType Resource type
|
|
616
|
+
* @param resourceId Resource ID
|
|
617
|
+
* @returns Permissions, loading state, and refresh function
|
|
618
|
+
*/
|
|
619
|
+
declare function usePermissions(resourceType: ResourceType, resourceId: string, enabled?: boolean): {
|
|
620
|
+
permissions: PermissionWithDetails[];
|
|
621
|
+
loading: boolean;
|
|
622
|
+
error: string | null;
|
|
623
|
+
refresh: () => Promise<void>;
|
|
624
|
+
};
|
|
625
|
+
/**
|
|
626
|
+
* Hook to get permissions with user/org details
|
|
627
|
+
* @param resourceType Resource type
|
|
628
|
+
* @param resourceId Resource ID
|
|
629
|
+
* @returns Permissions with details, loading state, and refresh function
|
|
630
|
+
*/
|
|
631
|
+
declare function useResourcePermissions(resourceType: ResourceType, resourceId: string): {
|
|
632
|
+
permissions: PermissionWithDetails[];
|
|
633
|
+
loading: boolean;
|
|
634
|
+
error: string | null;
|
|
635
|
+
refresh: () => Promise<void>;
|
|
636
|
+
};
|
|
637
|
+
/**
|
|
638
|
+
* Hook to check if current user has permission for a resource
|
|
639
|
+
* @param options Check options
|
|
640
|
+
* @returns Permission check result and loading state
|
|
641
|
+
*/
|
|
642
|
+
declare function usePermissionCheck(options: CheckPermissionOptions): {
|
|
643
|
+
loading: boolean;
|
|
644
|
+
hasAccess: boolean;
|
|
645
|
+
level?: PermissionLevel | undefined;
|
|
646
|
+
isOwner: boolean;
|
|
647
|
+
reason?: string | undefined;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* Hook to check if current user can edit a resource
|
|
651
|
+
* @param resourceType Resource type
|
|
652
|
+
* @param resourceId Resource ID
|
|
653
|
+
* @returns Whether user can edit and loading state
|
|
654
|
+
*/
|
|
655
|
+
declare function useCanEdit(resourceType: ResourceType, resourceId: string): {
|
|
656
|
+
canEdit: boolean;
|
|
657
|
+
loading: boolean;
|
|
658
|
+
};
|
|
659
|
+
/**
|
|
660
|
+
* Hook to check if current user can delete/admin a resource
|
|
661
|
+
* @param resourceType Resource type
|
|
662
|
+
* @param resourceId Resource ID
|
|
663
|
+
* @returns Whether user has admin access and loading state
|
|
664
|
+
*/
|
|
665
|
+
declare function useCanAdmin(resourceType: ResourceType, resourceId: string): {
|
|
666
|
+
canAdmin: boolean;
|
|
667
|
+
loading: boolean;
|
|
668
|
+
};
|
|
669
|
+
/**
|
|
670
|
+
* Hook to check whether the current user MAY DECIDE WHO ELSE SEES a resource.
|
|
671
|
+
*
|
|
672
|
+
* It kept its name because every call site means "may this person manage
|
|
673
|
+
* sharing?" and none of them meant "did this person create the row". Since
|
|
674
|
+
* 2026-09-19 (lane SHARE) it asks the database's own `may_manage_sharing`
|
|
675
|
+
* predicate — the Owner rung OR the `admin` rung of VIS-17's one ladder, the
|
|
676
|
+
* same question the six sharing RPCs enforce — instead of reading `created_by`
|
|
677
|
+
* from the resource table. Before that an `admin` on a thing was shown a
|
|
678
|
+
* read-only dialog and an empty grant list, and any resource whose table
|
|
679
|
+
* carries no client SELECT grant (the whole record store) could not be asked at
|
|
680
|
+
* all.
|
|
681
|
+
*
|
|
682
|
+
* Returns three distinct states — `loading` (still resolving), `error`
|
|
683
|
+
* (could NOT be determined), and `isOwner` — because collapsing them into one
|
|
684
|
+
* boolean is what makes owner-gated UI render as if the user were a stranger
|
|
685
|
+
* to their own record. Never gate a surface on `!isOwner` alone; check
|
|
686
|
+
* `loading` and `error` first.
|
|
687
|
+
*
|
|
688
|
+
* @param resourceType Resource type
|
|
689
|
+
* @param resourceId Resource ID
|
|
690
|
+
*/
|
|
691
|
+
declare function useIsOwner(resourceType: ResourceType, resourceId: string): {
|
|
692
|
+
isOwner: boolean;
|
|
693
|
+
loading: boolean;
|
|
694
|
+
error: string | null;
|
|
695
|
+
};
|
|
696
|
+
/**
|
|
697
|
+
* Hook for sharing operations
|
|
698
|
+
* Provides functions to share, revoke, and update permissions
|
|
699
|
+
* @param resourceType Resource type
|
|
700
|
+
* @param resourceId Resource ID
|
|
701
|
+
* @returns Sharing functions and state
|
|
702
|
+
*/
|
|
703
|
+
declare function useSharing(resourceType: ResourceType, resourceId: string, enabled?: boolean, resourceName?: string | undefined,
|
|
704
|
+
/**
|
|
705
|
+
* The organization the object lives in, from the page that opened the dialog (its own
|
|
706
|
+
* resolver). Carried to the share's in-app notification so no action on an object ever asks
|
|
707
|
+
* which workspace it is for (ACCESS-FIX-18).
|
|
708
|
+
*/
|
|
709
|
+
organizationId?: string | null | undefined): {
|
|
710
|
+
permissions: PermissionWithDetails[];
|
|
711
|
+
/** Published to the web (or the card's own publish). */
|
|
712
|
+
isPublic: boolean;
|
|
713
|
+
/**
|
|
714
|
+
* "Shown to" — undefined when the type does not carry it (Private, Confidential, child, or a
|
|
715
|
+
* table without the column); null when the type's default applies.
|
|
716
|
+
*/
|
|
717
|
+
shownTo: ShownTo | null | undefined;
|
|
718
|
+
/** A child record (a file attached to a chat): no row control of its own. */
|
|
719
|
+
childRecord: boolean;
|
|
720
|
+
/** Membership alone reaches it — said under Current Access. The record store's door names it. */
|
|
721
|
+
organizationDefault: {
|
|
722
|
+
level: string;
|
|
723
|
+
organizationName: string;
|
|
724
|
+
organizationId?: string | undefined;
|
|
725
|
+
} | null;
|
|
726
|
+
whoCanSee: WhoCanSee | null;
|
|
727
|
+
/** The thing's own organization, read off its row; null when unknown. */
|
|
728
|
+
homeOrganizationId: string | null;
|
|
729
|
+
setWhoCanSee: (choice: LaneChoice) => Promise<ShareActionResult>;
|
|
730
|
+
loading: boolean;
|
|
731
|
+
error: string | null;
|
|
732
|
+
shareWithUser: (userId: string, permissionLevel: PermissionLevel) => Promise<ShareActionResult>;
|
|
733
|
+
makePublic: (permissionLevel?: PermissionLevel) => Promise<ShareActionResult>;
|
|
734
|
+
setShownTo: (next: ShownTo | null) => Promise<ShareActionResult>;
|
|
735
|
+
revokeAccess: (options: {
|
|
736
|
+
userId?: string | undefined;
|
|
737
|
+
organizationId?: string | undefined;
|
|
738
|
+
isPublic?: boolean | undefined;
|
|
739
|
+
}) => Promise<ShareActionResult>;
|
|
740
|
+
revokeOrgAccess: (organizationId: string) => Promise<ShareActionResult>;
|
|
741
|
+
updateLevel: (options: {
|
|
742
|
+
userId?: string | undefined;
|
|
743
|
+
organizationId?: string | undefined;
|
|
744
|
+
}, newLevel: PermissionLevel) => Promise<ShareActionResult>;
|
|
745
|
+
refresh: () => Promise<void>;
|
|
746
|
+
refreshRowState: () => Promise<void>;
|
|
747
|
+
};
|
|
748
|
+
/**
|
|
749
|
+
* Hook to get resources shared with current user
|
|
750
|
+
* @param resourceType Optional filter by resource type
|
|
751
|
+
* @returns Shared permissions and loading state
|
|
752
|
+
*/
|
|
753
|
+
declare function useSharedWithMe(resourceType?: ResourceType | undefined): {
|
|
754
|
+
permissions: Permission[];
|
|
755
|
+
loading: boolean;
|
|
756
|
+
error: string | null;
|
|
757
|
+
refresh: () => Promise<void>;
|
|
758
|
+
};
|
|
759
|
+
/**
|
|
760
|
+
* Hook to get sharing status summary for a resource.
|
|
761
|
+
*
|
|
762
|
+
* Intentionally lightweight — only fetches is_public from the resource row.
|
|
763
|
+
* Safe to call from list-item components like ShareButton (single cheap query).
|
|
764
|
+
*
|
|
765
|
+
* Does NOT call get_resource_permissions (the expensive SECURITY DEFINER RPC).
|
|
766
|
+
* Full permission details are loaded inside useSharing() when the modal opens.
|
|
767
|
+
*/
|
|
768
|
+
declare function useSharingStatus(resourceType: ResourceType, resourceId: string, enabled?: boolean): {
|
|
769
|
+
isPublic: any;
|
|
770
|
+
loading: boolean;
|
|
771
|
+
error: string | null;
|
|
772
|
+
refresh: () => Promise<void>;
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
declare function WhoCouldSeeOn({ recordId }: {
|
|
776
|
+
recordId: string;
|
|
777
|
+
}): react.JSX.Element;
|
|
778
|
+
|
|
779
|
+
export { AccessSummaryPanel, type AccessSummaryPanelProps, type AccessSummaryState, AddEveryoneInOrg, type AddEveryoneInOrgProps, type GrantableLevels, GuestBadge, LANE_CLOSED_SAY, OrgAvailabilityNote, type OrgMemberPerson, OutsideSharePanel, type OutsideSharePanelProps, PermissionBadge, PermissionLevelDescription, PermissionsList, PublicAccessTab, PublicBadge, RowControls, type RowControlsProps, SearchEngineIndexedSwitch, SecureLinkPanel, ShareLinkPanel, ShareModal, type ShareOutcome, type ShareSheetConnection, type ShareSheetConnections, type ShareSheetOrganization, type ShareSheetToastOptions, type ShareSheetUi, ShareWithUserTab, type UseAccessSummaryArgs, type UseAccessSummaryResult, type UseShareResult, WhoCanSeeThis, type WhoCanSeeThisProps, WhoCouldSeeOn, anyoneReachWords, configureShareSheetUi, resetShareSheetCache, shareSheetUi, useAccessSummary, useCanAdmin, useCanEdit, useGrantableLevels, useIsOwner, usePermissionCheck, usePermissions, useResourcePermissions, useShare, useSharedWithMe, useSharing, useSharingStatus };
|