@datalayer/core 1.0.25 → 1.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -134
- package/lib/api/index.d.ts +0 -9
- package/lib/api/index.js +0 -9
- package/lib/cli-login.js +167 -0
- package/lib/client/auth/AuthenticationManager.d.ts +3 -3
- package/lib/client/auth/AuthenticationManager.js +13 -13
- package/lib/client/auth/strategies.d.ts +2 -2
- package/lib/client/auth/strategies.js +6 -6
- package/lib/client/base.d.ts +9 -12
- package/lib/client/base.js +17 -19
- package/lib/client/index.d.ts +10 -98
- package/lib/client/index.js +12 -21
- package/lib/client/mixins/IAMMixin.js +26 -26
- package/lib/components/auth/Login.js +2 -2
- package/lib/components/avatars/UserAvatar.d.ts +16 -0
- package/lib/components/avatars/UserAvatar.js +47 -0
- package/lib/components/avatars/index.d.ts +1 -0
- package/lib/components/avatars/index.js +1 -0
- package/lib/components/billing/BillableAccountSelect.js +4 -0
- package/lib/components/billing/index.js +4 -0
- package/lib/components/context/index.d.ts +0 -1
- package/lib/components/context/index.js +0 -1
- package/lib/components/display/DisplayHandle.d.ts +12 -0
- package/lib/components/display/DisplayHandle.js +11 -0
- package/lib/components/display/LiveRelativeTime.js +4 -0
- package/lib/components/display/index.d.ts +1 -0
- package/lib/components/display/index.js +1 -0
- package/lib/components/flashes/index.d.ts +0 -1
- package/lib/components/flashes/index.js +0 -1
- package/lib/components/index.d.ts +0 -1
- package/lib/components/index.js +0 -1
- package/lib/components/principal/Principal.d.ts +7 -0
- package/lib/components/principal/Principal.js +153 -16
- package/lib/components/principal/PrincipalAvatar.d.ts +1 -1
- package/lib/components/principal/PrincipalAvatar.js +4 -28
- package/lib/components/principal/PrincipalBadge.js +4 -4
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +4 -2
- package/lib/components/principal/PrincipalDetailsOverlay.js +27 -7
- package/lib/components/principal/PrincipalSwitcherMenu.js +79 -42
- package/lib/components/progress/index.d.ts +0 -1
- package/lib/components/progress/index.js +0 -1
- package/lib/components/sharing/ShareAccessComponent.d.ts +3 -2
- package/lib/components/sharing/ShareAccessComponent.js +194 -147
- package/lib/components/sharing/SharingEditor.js +4 -0
- package/lib/components/snippets/index.d.ts +1 -1
- package/lib/components/snippets/index.js +1 -1
- package/lib/components/students/StudentResultCircle.d.ts +21 -0
- package/lib/components/students/StudentResultCircle.js +59 -0
- package/lib/components/students/index.d.ts +1 -1
- package/lib/components/students/index.js +1 -1
- package/lib/components/time/LiveRelativeTime.js +4 -0
- package/lib/components/time/index.js +4 -0
- package/lib/components/timeline/index.js +4 -0
- package/lib/components/tokens/index.d.ts +1 -1
- package/lib/components/tokens/index.js +1 -1
- package/lib/components/toolbars/index.d.ts +1 -3
- package/lib/components/toolbars/index.js +1 -3
- package/lib/config/Configuration.d.ts +13 -13
- package/lib/config/Configuration.js +5 -5
- package/lib/hooks/cacheConverters.d.ts +21 -0
- package/lib/hooks/cacheConverters.js +110 -0
- package/lib/hooks/index.d.ts +0 -2
- package/lib/hooks/index.js +0 -2
- package/lib/hooks/useCache.d.ts +64 -35
- package/lib/hooks/useCache.js +661 -306
- package/lib/hooks/useDatalayer.js +3 -1
- package/lib/hooks/useIAM.js +2 -4
- package/lib/hooks/useLocationHandles.d.ts +3 -1
- package/lib/hooks/useLocationHandles.js +2 -1
- package/lib/hooks/usePrincipalStore.d.ts +2 -2
- package/lib/hooks/usePrincipalStore.js +97 -14
- package/lib/hooks/useSelectedPrincipal.js +1 -1
- package/lib/hooks/useUser.js +19 -2
- package/lib/index.d.ts +1 -6
- package/lib/index.js +1 -13
- package/lib/main.js +3 -3
- package/lib/mocks/index.js +1 -1
- package/lib/mocks/models/index.d.ts +0 -1
- package/lib/mocks/models/index.js +0 -1
- package/lib/models/Datasource.d.ts +2 -2
- package/lib/models/IAM.d.ts +1 -1
- package/lib/models/School.d.ts +12 -3
- package/lib/models/Secret.d.ts +2 -2
- package/lib/models/Student.d.ts +13 -3
- package/lib/models/Usage.d.ts +11 -1
- package/lib/models/UserDTO.d.ts +2 -2
- package/lib/models/UserSettings.d.ts +1 -1
- package/lib/models/UserSettings.js +1 -1
- package/lib/models/index.d.ts +0 -30
- package/lib/models/index.js +0 -30
- package/lib/otel/client/OtelClient.d.ts +2 -2
- package/lib/otel/client/OtelClient.js +2 -2
- package/lib/otel/hooks/index.js +5 -5
- package/lib/otel/types.d.ts +1 -1
- package/lib/otel/views/OtelLive.js +1 -1
- package/lib/routes/index.d.ts +1 -0
- package/lib/routes/index.js +1 -0
- package/lib/routes/publicPaths.d.ts +23 -0
- package/lib/routes/publicPaths.js +74 -0
- package/lib/state/State.d.ts +0 -12
- package/lib/state/State.js +0 -12
- package/lib/state/substates/CoreState.js +13 -13
- package/lib/state/substates/IAMState.d.ts +1 -1
- package/lib/state/substates/IAMState.js +14 -14
- package/lib/state/substates/LayoutState.d.ts +12 -1
- package/lib/state/substates/SurveysState.d.ts +1 -1
- package/lib/state/substates/SurveysState.js +10 -10
- package/lib/state/substates/index.d.ts +0 -7
- package/lib/state/substates/index.js +0 -7
- package/lib/utils/Handles.js +3 -1
- package/lib/utils/index.d.ts +0 -1
- package/lib/utils/index.js +0 -1
- package/lib/views/api-keys/APIKeys.js +12 -3
- package/lib/views/datasources/DatasourceDetail.d.ts +1 -1
- package/lib/views/datasources/DatasourceNew.d.ts +1 -1
- package/lib/views/datasources/Datasources.d.ts +1 -1
- package/lib/views/datasources/Datasources.js +12 -3
- package/lib/views/iam/SignInSimple.d.ts +37 -1
- package/lib/views/iam/SignInSimple.js +111 -13
- package/package.json +5 -3
- package/lib/App.css +0 -47
- package/lib/App.d.ts +0 -3
- package/lib/App.js +0 -21
- package/lib/api/runtimes/checkpoints.d.ts +0 -122
- package/lib/api/runtimes/checkpoints.js +0 -118
- package/lib/api/runtimes/environments.d.ts +0 -9
- package/lib/api/runtimes/environments.js +0 -29
- package/lib/api/runtimes/healthz.d.ts +0 -15
- package/lib/api/runtimes/healthz.js +0 -44
- package/lib/api/runtimes/index.d.ts +0 -12
- package/lib/api/runtimes/index.js +0 -16
- package/lib/api/runtimes/runtimes.d.ts +0 -138
- package/lib/api/runtimes/runtimes.js +0 -230
- package/lib/api/runtimes/snapshots.d.ts +0 -38
- package/lib/api/runtimes/snapshots.js +0 -82
- package/lib/api/scheduler/index.d.ts +0 -6
- package/lib/api/scheduler/index.js +0 -10
- package/lib/api/scheduler/schedules.d.ts +0 -85
- package/lib/api/scheduler/schedules.js +0 -78
- package/lib/api/spacer/documents.d.ts +0 -12
- package/lib/api/spacer/documents.js +0 -43
- package/lib/api/spacer/healthz.d.ts +0 -15
- package/lib/api/spacer/healthz.js +0 -44
- package/lib/api/spacer/index.d.ts +0 -15
- package/lib/api/spacer/index.js +0 -19
- package/lib/api/spacer/items.d.ts +0 -25
- package/lib/api/spacer/items.js +0 -55
- package/lib/api/spacer/lexicals.d.ts +0 -34
- package/lib/api/spacer/lexicals.js +0 -89
- package/lib/api/spacer/notebooks.d.ts +0 -34
- package/lib/api/spacer/notebooks.js +0 -89
- package/lib/api/spacer/spaces.d.ts +0 -84
- package/lib/api/spacer/spaces.js +0 -170
- package/lib/api/spacer/users.d.ts +0 -9
- package/lib/api/spacer/users.js +0 -29
- package/lib/client/mixins/RuntimesMixin.d.ts +0 -93
- package/lib/client/mixins/RuntimesMixin.js +0 -229
- package/lib/client/mixins/SpacerMixin.d.ts +0 -210
- package/lib/client/mixins/SpacerMixin.js +0 -615
- package/lib/client/utils/spacerUtils.d.ts +0 -18
- package/lib/client/utils/spacerUtils.js +0 -32
- package/lib/collaboration/DatalayerCollaboration.d.ts +0 -13
- package/lib/collaboration/DatalayerCollaboration.js +0 -28
- package/lib/collaboration/DatalayerCollaborationProvider.d.ts +0 -60
- package/lib/collaboration/DatalayerCollaborationProvider.js +0 -163
- package/lib/collaboration/index.d.ts +0 -2
- package/lib/collaboration/index.js +0 -6
- package/lib/components/context/SpaceSelect.d.ts +0 -2
- package/lib/components/context/SpaceSelect.js +0 -42
- package/lib/components/flashes/FlashDisclaimer.d.ts +0 -2
- package/lib/components/flashes/FlashDisclaimer.js +0 -17
- package/lib/components/icons/ArtifactIcon.d.ts +0 -10
- package/lib/components/icons/ArtifactIcon.js +0 -58
- package/lib/components/icons/index.d.ts +0 -1
- package/lib/components/icons/index.js +0 -5
- package/lib/components/nbgrader/NbGradesDetails.d.ts +0 -5
- package/lib/components/nbgrader/NbGradesDetails.js +0 -14
- package/lib/components/nbgrader/index.d.ts +0 -1
- package/lib/components/nbgrader/index.js +0 -5
- package/lib/components/progress/CreditsIndicator.d.ts +0 -33
- package/lib/components/progress/CreditsIndicator.js +0 -23
- package/lib/components/runtimes/RuntimeCellVariables.d.ts +0 -39
- package/lib/components/runtimes/RuntimeCellVariables.js +0 -172
- package/lib/components/runtimes/RuntimeCellVariablesDialog.d.ts +0 -37
- package/lib/components/runtimes/RuntimeCellVariablesDialog.js +0 -101
- package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +0 -57
- package/lib/components/runtimes/RuntimeLauncherDialog.js +0 -275
- package/lib/components/runtimes/RuntimePickerBase.d.ts +0 -69
- package/lib/components/runtimes/RuntimePickerBase.js +0 -122
- package/lib/components/runtimes/RuntimePickerCell.d.ts +0 -34
- package/lib/components/runtimes/RuntimePickerCell.js +0 -104
- package/lib/components/runtimes/RuntimePickerNotebook.d.ts +0 -42
- package/lib/components/runtimes/RuntimePickerNotebook.js +0 -232
- package/lib/components/runtimes/RuntimeReservationControl.d.ts +0 -47
- package/lib/components/runtimes/RuntimeReservationControl.js +0 -42
- package/lib/components/runtimes/RuntimeSimplePicker.d.ts +0 -38
- package/lib/components/runtimes/RuntimeSimplePicker.js +0 -155
- package/lib/components/runtimes/RuntimeTransfer.d.ts +0 -16
- package/lib/components/runtimes/RuntimeTransfer.js +0 -5
- package/lib/components/runtimes/RuntimeUtils.d.ts +0 -17
- package/lib/components/runtimes/RuntimeUtils.js +0 -178
- package/lib/components/runtimes/RuntimeVariables.d.ts +0 -38
- package/lib/components/runtimes/RuntimeVariables.js +0 -75
- package/lib/components/runtimes/index.d.ts +0 -11
- package/lib/components/runtimes/index.js +0 -15
- package/lib/components/scheduler/ScheduleMenu.d.ts +0 -54
- package/lib/components/scheduler/ScheduleMenu.js +0 -154
- package/lib/components/scheduler/index.d.ts +0 -1
- package/lib/components/scheduler/index.js +0 -5
- package/lib/components/snapshots/SandboxSnapshotMenu.d.ts +0 -33
- package/lib/components/snapshots/SandboxSnapshotMenu.js +0 -169
- package/lib/components/snapshots/index.d.ts +0 -1
- package/lib/components/snapshots/index.js +0 -5
- package/lib/components/snippets/SnippetDialog.d.ts +0 -42
- package/lib/components/snippets/SnippetDialog.js +0 -42
- package/lib/components/students/StudentItemStatus.d.ts +0 -7
- package/lib/components/students/StudentItemStatus.js +0 -66
- package/lib/components/tokens/SpaceVariantToken.d.ts +0 -5
- package/lib/components/tokens/SpaceVariantToken.js +0 -23
- package/lib/components/toolbars/AssignmentEditorToolbar.d.ts +0 -4
- package/lib/components/toolbars/AssignmentEditorToolbar.js +0 -18
- package/lib/components/toolbars/DocumentEditorToolbar.d.ts +0 -2
- package/lib/components/toolbars/DocumentEditorToolbar.js +0 -12
- package/lib/components/toolbars/NotebookEditorToolbar.d.ts +0 -29
- package/lib/components/toolbars/NotebookEditorToolbar.js +0 -30
- package/lib/examples/CellExample.d.ts +0 -6
- package/lib/examples/CellExample.js +0 -20
- package/lib/examples/NotebookExample.d.ts +0 -6
- package/lib/examples/NotebookExample.js +0 -19
- package/lib/examples/lexical-theme.css +0 -436
- package/lib/examples/notebooks/IPyWidgetsExample.ipynb.json +0 -101
- package/lib/examples/notebooks/IPyWidgetsExampleWithState.ipynb.json +0 -112
- package/lib/examples/notebooks/Lite.ipynb.json +0 -128
- package/lib/examples/notebooks/Matplotlib.ipynb.json +0 -137
- package/lib/examples/notebooks/NotebookExample1.ipynb.json +0 -126
- package/lib/examples/notebooks/NotebookExample2.ipynb.json +0 -48
- package/lib/examples/notebooks/NotebookOutputs.ipynb.json +0 -49
- package/lib/examples/notebooks/NotebookToCExample.ipynb.json +0 -102
- package/lib/examples/notebooks/PyGWalker.ipynb.json +0 -55
- package/lib/hooks/useCellOutputshot.d.ts +0 -4
- package/lib/hooks/useCellOutputshot.js +0 -25
- package/lib/hooks/useProjects.d.ts +0 -628
- package/lib/hooks/useProjects.js +0 -190
- package/lib/hooks/useRuntimes.d.ts +0 -5
- package/lib/hooks/useRuntimes.js +0 -34
- package/lib/mocks/jupyter/index.js +0 -5
- package/lib/mocks/models/CourseMock.d.ts +0 -6
- package/lib/mocks/models/CourseMock.js +0 -29
- package/lib/mocks/models/SpaceMock.d.ts +0 -6
- package/lib/mocks/models/SpaceMock.js +0 -25
- package/lib/models/Assignment.d.ts +0 -7
- package/lib/models/Assignment.js +0 -5
- package/lib/models/Cell.d.ts +0 -8
- package/lib/models/Cell.js +0 -5
- package/lib/models/CodeBlock.d.ts +0 -10
- package/lib/models/CodeBlock.js +0 -5
- package/lib/models/CodeSandboxSnapshot.d.ts +0 -92
- package/lib/models/CodeSandboxSnapshot.js +0 -13
- package/lib/models/CodeSandboxSnapshotDTO.d.ts +0 -173
- package/lib/models/CodeSandboxSnapshotDTO.js +0 -139
- package/lib/models/CodefeedBlocks.d.ts +0 -7
- package/lib/models/CodefeedBlocks.js +0 -5
- package/lib/models/Content.d.ts +0 -5
- package/lib/models/Content.js +0 -5
- package/lib/models/Course.d.ts +0 -17
- package/lib/models/Course.js +0 -5
- package/lib/models/Dataset.d.ts +0 -16
- package/lib/models/Dataset.js +0 -5
- package/lib/models/Document.d.ts +0 -8
- package/lib/models/Document.js +0 -5
- package/lib/models/Environment.d.ts +0 -86
- package/lib/models/Environment.js +0 -5
- package/lib/models/EnvironmentDTO.d.ts +0 -125
- package/lib/models/EnvironmentDTO.js +0 -88
- package/lib/models/Exercise.d.ts +0 -16
- package/lib/models/Exercise.js +0 -5
- package/lib/models/Item.d.ts +0 -20
- package/lib/models/Item.js +0 -5
- package/lib/models/ItemDTO.d.ts +0 -74
- package/lib/models/ItemDTO.js +0 -186
- package/lib/models/ItemType.d.ts +0 -2
- package/lib/models/ItemType.js +0 -5
- package/lib/models/Lesson.d.ts +0 -5
- package/lib/models/Lesson.js +0 -5
- package/lib/models/LexicalDTO.d.ts +0 -155
- package/lib/models/LexicalDTO.js +0 -157
- package/lib/models/Library.d.ts +0 -10
- package/lib/models/Library.js +0 -5
- package/lib/models/Notebook.d.ts +0 -11
- package/lib/models/Notebook.js +0 -5
- package/lib/models/NotebookDTO.d.ts +0 -96
- package/lib/models/NotebookDTO.js +0 -153
- package/lib/models/Page.d.ts +0 -41
- package/lib/models/Page.js +0 -25
- package/lib/models/PageTag.d.ts +0 -19
- package/lib/models/PageTag.js +0 -94
- package/lib/models/ProjectDTO.d.ts +0 -89
- package/lib/models/ProjectDTO.js +0 -131
- package/lib/models/Runtime.d.ts +0 -123
- package/lib/models/Runtime.js +0 -18
- package/lib/models/RuntimeDTO.d.ts +0 -191
- package/lib/models/RuntimeDTO.js +0 -204
- package/lib/models/Space.d.ts +0 -35
- package/lib/models/Space.js +0 -66
- package/lib/models/SpaceDTO.d.ts +0 -334
- package/lib/models/SpaceDTO.js +0 -244
- package/lib/models/SpaceItem.d.ts +0 -10
- package/lib/models/SpaceItem.js +0 -5
- package/lib/models/SpaceMember.d.ts +0 -6
- package/lib/models/SpaceMember.js +0 -5
- package/lib/models/StudentItem.d.ts +0 -21
- package/lib/models/StudentItem.js +0 -5
- package/lib/services/DatalayerServiceManager.d.ts +0 -22
- package/lib/services/DatalayerServiceManager.js +0 -69
- package/lib/services/index.d.ts +0 -4
- package/lib/services/index.js +0 -7
- package/lib/services/reconnectToRuntime.d.ts +0 -32
- package/lib/services/reconnectToRuntime.js +0 -59
- package/lib/state/substates/CellState.d.ts +0 -12
- package/lib/state/substates/CellState.js +0 -22
- package/lib/state/substates/DocumentState.d.ts +0 -10
- package/lib/state/substates/DocumentState.js +0 -14
- package/lib/state/substates/GradeState.d.ts +0 -10
- package/lib/state/substates/GradeState.js +0 -14
- package/lib/state/substates/JupyterLabState.d.ts +0 -16
- package/lib/state/substates/JupyterLabState.js +0 -17
- package/lib/state/substates/NbformatState.d.ts +0 -13
- package/lib/state/substates/NbformatState.js +0 -16
- package/lib/state/substates/RuntimesState.d.ts +0 -79
- package/lib/state/substates/RuntimesState.js +0 -180
- package/lib/state/substates/SpaceState.d.ts +0 -11
- package/lib/state/substates/SpaceState.js +0 -16
- package/lib/stateful/index.d.ts +0 -2
- package/lib/stateful/index.js +0 -6
- package/lib/stateful/jupyter/exec/Python.d.ts +0 -5
- package/lib/stateful/jupyter/exec/Python.js +0 -100
- package/lib/stateful/jupyter/exec/Snippets.d.ts +0 -105
- package/lib/stateful/jupyter/exec/Snippets.js +0 -101
- package/lib/stateful/jupyter/exec/index.d.ts +0 -2
- package/lib/stateful/jupyter/exec/index.js +0 -6
- package/lib/stateful/jupyter/index.d.ts +0 -2
- package/lib/stateful/jupyter/index.js +0 -6
- package/lib/stateful/jupyter/kernelsHandler.d.ts +0 -8
- package/lib/stateful/jupyter/kernelsHandler.js +0 -39
- package/lib/stateful/runtimes/actions.d.ts +0 -102
- package/lib/stateful/runtimes/actions.js +0 -249
- package/lib/stateful/runtimes/apis.d.ts +0 -273
- package/lib/stateful/runtimes/apis.js +0 -5
- package/lib/stateful/runtimes/index.d.ts +0 -5
- package/lib/stateful/runtimes/index.js +0 -9
- package/lib/stateful/runtimes/settings.d.ts +0 -15
- package/lib/stateful/runtimes/settings.js +0 -31
- package/lib/stateful/runtimes/snapshots.d.ts +0 -25
- package/lib/stateful/runtimes/snapshots.js +0 -150
- package/lib/stateful/runtimes/utils.d.ts +0 -7
- package/lib/stateful/runtimes/utils.js +0 -14
- package/lib/utils/Cells.d.ts +0 -2
- package/lib/utils/Cells.js +0 -28
- /package/lib/{mocks/jupyter/index.d.ts → cli-login.d.ts} +0 -0
|
@@ -4,7 +4,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
|
-
import { KeyIcon, PersonIcon, OrganizationIcon, PeopleIcon, } from '@primer/octicons-react';
|
|
7
|
+
import { ChevronDownIcon, ChevronUpIcon, KeyIcon, PersonIcon, OrganizationIcon, PeopleIcon, } from '@primer/octicons-react';
|
|
8
8
|
import { Box } from '@datalayer/primer-addons';
|
|
9
9
|
import { ActionList, ActionMenu, Button, Dialog, Label, Spinner, Text, TextInput, } from '@primer/react';
|
|
10
10
|
import { useToast } from '../../hooks/index.js';
|
|
@@ -16,7 +16,7 @@ import { PrincipalBadge } from '../principal/PrincipalBadge.js';
|
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
const ACCESS_LEVELS = ['view', 'update', 'execute'];
|
|
18
18
|
const DEFAULT_PRINCIPAL_KINDS = [
|
|
19
|
-
'
|
|
19
|
+
'personal',
|
|
20
20
|
'team',
|
|
21
21
|
'organization',
|
|
22
22
|
];
|
|
@@ -44,7 +44,7 @@ function normalizePrincipalKind(kindRaw) {
|
|
|
44
44
|
if (kind === 'organization' || kind === 'org') {
|
|
45
45
|
return 'organization';
|
|
46
46
|
}
|
|
47
|
-
return '
|
|
47
|
+
return 'personal';
|
|
48
48
|
}
|
|
49
49
|
function toTitleCase(value) {
|
|
50
50
|
if (!value) {
|
|
@@ -78,7 +78,30 @@ function ensurePrincipalDisplayName(kind, ...candidates) {
|
|
|
78
78
|
return candidate.trim();
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
if (kind === 'organization') {
|
|
82
|
+
return 'Organization';
|
|
83
|
+
}
|
|
84
|
+
if (kind === 'team') {
|
|
85
|
+
return 'Team';
|
|
86
|
+
}
|
|
87
|
+
return 'Principal';
|
|
88
|
+
}
|
|
89
|
+
function formatPrincipalHandle(kind, handle, accountHandle) {
|
|
90
|
+
const normalizedHandle = String(handle || '').trim();
|
|
91
|
+
const normalizedAccountHandle = String(accountHandle || '').trim();
|
|
92
|
+
if (!normalizedHandle) {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
if (kind === 'team') {
|
|
96
|
+
if (normalizedHandle.includes('/')) {
|
|
97
|
+
return `@${normalizedHandle}`;
|
|
98
|
+
}
|
|
99
|
+
if (normalizedAccountHandle) {
|
|
100
|
+
return `@${normalizedAccountHandle}/${normalizedHandle}`;
|
|
101
|
+
}
|
|
102
|
+
return `@${normalizedHandle}`;
|
|
103
|
+
}
|
|
104
|
+
return `@${normalizedHandle}`;
|
|
82
105
|
}
|
|
83
106
|
function isSharingAuthorizationMessage(message) {
|
|
84
107
|
const normalized = (message || '').trim().toLowerCase();
|
|
@@ -139,7 +162,7 @@ function extractOwnerPrincipals(payload) {
|
|
|
139
162
|
if (typeof entry === 'string') {
|
|
140
163
|
const uid = entry.trim();
|
|
141
164
|
return uid
|
|
142
|
-
? { kind: '
|
|
165
|
+
? { kind: 'personal', uid, handle: uid, displayName: uid }
|
|
143
166
|
: null;
|
|
144
167
|
}
|
|
145
168
|
const uid = pickFirstString(entry?.uid, entry?.owner_uid, entry?.id);
|
|
@@ -169,7 +192,7 @@ function extractOwnerPrincipals(payload) {
|
|
|
169
192
|
}
|
|
170
193
|
const normalizedUid = uid.trim();
|
|
171
194
|
return {
|
|
172
|
-
kind: '
|
|
195
|
+
kind: 'personal',
|
|
173
196
|
uid: normalizedUid,
|
|
174
197
|
handle: normalizedUid,
|
|
175
198
|
displayName: normalizedUid,
|
|
@@ -201,7 +224,7 @@ function emptyAccessByLevel() {
|
|
|
201
224
|
};
|
|
202
225
|
}
|
|
203
226
|
function bucketFor(kind) {
|
|
204
|
-
return kind === '
|
|
227
|
+
return kind === 'personal'
|
|
205
228
|
? 'userUids'
|
|
206
229
|
: kind === 'team'
|
|
207
230
|
? 'teamUids'
|
|
@@ -255,7 +278,7 @@ function buildAclEntries(state, principalKinds) {
|
|
|
255
278
|
}
|
|
256
279
|
};
|
|
257
280
|
for (const level of ACCESS_LEVELS) {
|
|
258
|
-
state[level].userUids.forEach(uid => upsert('
|
|
281
|
+
state[level].userUids.forEach(uid => upsert('personal', uid, level));
|
|
259
282
|
state[level].teamUids.forEach(uid => upsert('team', uid, level));
|
|
260
283
|
state[level].organizationUids.forEach(uid => upsert('organization', uid, level));
|
|
261
284
|
}
|
|
@@ -315,11 +338,11 @@ function OwnerPrincipalRow({ ownerPrincipal, cache, showAvatarSkeleton = false,
|
|
|
315
338
|
: '';
|
|
316
339
|
const resolvedHandle = safeCachedHandle || safeOwnerHandle || ownerPrincipal.accountHandle;
|
|
317
340
|
const resolvedAccountHandle = entry.accountHandle || ownerPrincipal.accountHandle;
|
|
318
|
-
const resolvedDisplayName = ensurePrincipalDisplayName(ownerPrincipal.kind, ownerPrincipal.displayName, entry.displayName, resolvedHandle, ownerPrincipal.handle, ownerPrincipal.accountHandle, ownerPrincipal.uid);
|
|
341
|
+
const resolvedDisplayName = ensurePrincipalDisplayName(ownerPrincipal.kind, ownerPrincipal.displayName, entry.displayName, formatPrincipalHandle(ownerPrincipal.kind, resolvedHandle, resolvedAccountHandle), resolvedHandle, ownerPrincipal.handle, ownerPrincipal.accountHandle, ownerPrincipal.uid);
|
|
319
342
|
const resolvedAvatarUrl = ownerPrincipal.avatarUrl || entry.avatarUrl;
|
|
320
343
|
const resolvedOrigin = ownerPrincipal.origin ||
|
|
321
344
|
entry.origin ||
|
|
322
|
-
(ownerPrincipal.kind === '
|
|
345
|
+
(ownerPrincipal.kind === 'personal' ? 'Datalayer' : undefined);
|
|
323
346
|
return (_jsx(Box, { sx: {
|
|
324
347
|
display: 'inline-flex',
|
|
325
348
|
alignItems: 'center',
|
|
@@ -333,14 +356,14 @@ function OwnerPrincipalRow({ ownerPrincipal, cache, showAvatarSkeleton = false,
|
|
|
333
356
|
accountHandle: resolvedAccountHandle,
|
|
334
357
|
avatarUrl: resolvedAvatarUrl,
|
|
335
358
|
origin: resolvedOrigin,
|
|
336
|
-
}, showPrincipalLabel: false, showApplyingToText: false, showOriginLabel: ownerPrincipal.kind === '
|
|
359
|
+
}, showPrincipalLabel: false, showApplyingToText: false, showOriginLabel: ownerPrincipal.kind === 'personal', isAdmin: isPlatformAdmin, sx: { px: 0, py: 0, border: 'none', bg: 'transparent' } })) }));
|
|
337
360
|
}
|
|
338
361
|
function AccessPrincipalRow({ entry, cache, showAvatarSkeleton = false, isPlatformAdmin, }) {
|
|
339
362
|
const cached = cache[principalKey(entry.kind, entry.uid)] || {};
|
|
340
363
|
const cachedHandle = cached.handle;
|
|
341
364
|
const safeCachedHandle = cachedHandle && cachedHandle !== entry.uid ? cachedHandle : '';
|
|
342
365
|
const resolvedHandle = safeCachedHandle || cached.accountHandle;
|
|
343
|
-
const resolvedDisplayName = ensurePrincipalDisplayName(entry.kind, cached.displayName, resolvedHandle, entry.uid);
|
|
366
|
+
const resolvedDisplayName = ensurePrincipalDisplayName(entry.kind, cached.displayName, formatPrincipalHandle(entry.kind, resolvedHandle, cached.accountHandle), resolvedHandle, entry.uid);
|
|
344
367
|
return (_jsx(Box, { sx: {
|
|
345
368
|
display: 'inline-flex',
|
|
346
369
|
alignItems: 'center',
|
|
@@ -354,12 +377,12 @@ function AccessPrincipalRow({ entry, cache, showAvatarSkeleton = false, isPlatfo
|
|
|
354
377
|
accountHandle: cached.accountHandle,
|
|
355
378
|
avatarUrl: cached.avatarUrl,
|
|
356
379
|
origin: cached.origin || 'Datalayer',
|
|
357
|
-
}, showPrincipalLabel: false, showApplyingToText: false, showOriginLabel: entry.kind === '
|
|
380
|
+
}, showPrincipalLabel: false, showApplyingToText: false, showOriginLabel: entry.kind === 'personal', isAdmin: isPlatformAdmin, sx: { px: 0, py: 0, border: 'none', bg: 'transparent' } })) }));
|
|
358
381
|
}
|
|
359
382
|
// ---------------------------------------------------------------------------
|
|
360
383
|
// Main component.
|
|
361
384
|
// ---------------------------------------------------------------------------
|
|
362
|
-
export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resourceName, resourceDescription: _resourceDescription, onSharingAccessRestrictedChange, defaultAccessLevel = 'view', principalKinds = DEFAULT_PRINCIPAL_KINDS, displayMode = 'dialog', onClose, }) {
|
|
385
|
+
export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resourceName, resourceDescription: _resourceDescription, expanded = false, onSharingAccessRestrictedChange, defaultAccessLevel = 'view', principalKinds = DEFAULT_PRINCIPAL_KINDS, displayMode = 'dialog', onClose, }) {
|
|
363
386
|
void _resourceDescription;
|
|
364
387
|
const { token, user } = useIAMStore();
|
|
365
388
|
const { configuration } = useCoreStore();
|
|
@@ -368,6 +391,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
368
391
|
// ----- State -----
|
|
369
392
|
const [isLoading, setIsLoading] = useState(false);
|
|
370
393
|
const [isSaving, setIsSaving] = useState(false);
|
|
394
|
+
const [isExpanded, setIsExpanded] = useState(expanded);
|
|
371
395
|
const [selectedAccessLevel, setSelectedAccessLevel] = useState(defaultAccessLevel);
|
|
372
396
|
const [access, setAccess] = useState(emptyAccessByLevel());
|
|
373
397
|
const [ownerPrincipals, setOwnerPrincipals] = useState([]);
|
|
@@ -409,8 +433,8 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
409
433
|
]);
|
|
410
434
|
// ----- Derived -----
|
|
411
435
|
const canRequest = Boolean(requestUrl && token);
|
|
412
|
-
const canSearchPrincipals = Boolean(configuration?.
|
|
413
|
-
const
|
|
436
|
+
const canSearchPrincipals = Boolean(configuration?.iamUrl && token);
|
|
437
|
+
const iamUrl = configuration?.iamUrl;
|
|
414
438
|
const principalKindsSet = useMemo(() => new Set(principalKinds), [principalKinds]);
|
|
415
439
|
const principalKindsKey = useMemo(() => [...principalKinds].sort().join('|'), [principalKinds]);
|
|
416
440
|
const aclEntries = useMemo(() => buildAclEntries(access, principalKinds), [access, principalKinds]);
|
|
@@ -530,7 +554,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
530
554
|
handle: owner.handle || owner.uid,
|
|
531
555
|
avatarUrl: owner.avatarUrl,
|
|
532
556
|
accountHandle: owner.accountHandle,
|
|
533
|
-
origin: owner.kind === '
|
|
557
|
+
origin: owner.kind === 'personal' ? owner.origin : undefined,
|
|
534
558
|
});
|
|
535
559
|
});
|
|
536
560
|
setAccess(hydrated);
|
|
@@ -568,14 +592,14 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
568
592
|
]);
|
|
569
593
|
// ----- Fetch shareable principals on open -----
|
|
570
594
|
useEffect(() => {
|
|
571
|
-
if (!isOpen || !canSearchPrincipals || !
|
|
595
|
+
if (!isOpen || !canSearchPrincipals || !iamUrl || !token) {
|
|
572
596
|
return;
|
|
573
597
|
}
|
|
574
598
|
let cancelled = false;
|
|
575
599
|
const run = async () => {
|
|
576
600
|
setIsLoadingShareable(true);
|
|
577
601
|
try {
|
|
578
|
-
const response = await fetch(`${
|
|
602
|
+
const response = await fetch(`${iamUrl}/api/iam/v1/principals/shareable`, {
|
|
579
603
|
method: 'GET',
|
|
580
604
|
headers: {
|
|
581
605
|
'Content-Type': 'application/json',
|
|
@@ -618,11 +642,13 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
618
642
|
setShareablePrincipals(mapped);
|
|
619
643
|
mapped.forEach(principal => {
|
|
620
644
|
mergePrincipalCacheEntry(principal.kind, principal.uid, {
|
|
621
|
-
displayName: principal.name ||
|
|
645
|
+
displayName: principal.name ||
|
|
646
|
+
formatPrincipalHandle(principal.kind, principal.handle, principal.organizationHandle || undefined) ||
|
|
647
|
+
principal.handle,
|
|
622
648
|
handle: principal.handle,
|
|
623
649
|
avatarUrl: principal.avatarUrl || undefined,
|
|
624
650
|
accountHandle: principal.organizationHandle || undefined,
|
|
625
|
-
origin: principal.kind === '
|
|
651
|
+
origin: principal.kind === 'personal' ? 'Datalayer' : undefined,
|
|
626
652
|
});
|
|
627
653
|
});
|
|
628
654
|
}
|
|
@@ -645,7 +671,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
645
671
|
return () => {
|
|
646
672
|
cancelled = true;
|
|
647
673
|
};
|
|
648
|
-
}, [isOpen, canSearchPrincipals,
|
|
674
|
+
}, [isOpen, canSearchPrincipals, iamUrl, token, mergePrincipalCacheEntry]);
|
|
649
675
|
// ----- Debounce search query -----
|
|
650
676
|
useEffect(() => {
|
|
651
677
|
const timeout = window.setTimeout(() => {
|
|
@@ -657,7 +683,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
657
683
|
}, [searchQuery]);
|
|
658
684
|
// ----- Run search against /principals/search -----
|
|
659
685
|
useEffect(() => {
|
|
660
|
-
if (!isOpen || !canSearchPrincipals || !
|
|
686
|
+
if (!isOpen || !canSearchPrincipals || !iamUrl || !token) {
|
|
661
687
|
setSearchResults([]);
|
|
662
688
|
return;
|
|
663
689
|
}
|
|
@@ -678,7 +704,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
678
704
|
let response;
|
|
679
705
|
let payload;
|
|
680
706
|
try {
|
|
681
|
-
response = await fetch(`${
|
|
707
|
+
response = await fetch(`${iamUrl}/api/iam/v1/principals/search`, {
|
|
682
708
|
method: 'POST',
|
|
683
709
|
headers: {
|
|
684
710
|
'Content-Type': 'application/json',
|
|
@@ -726,7 +752,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
726
752
|
const origin = normalizeUserOrigin(pickFirstString(entry?.origin, entry?.origin_s, entry?.origin_t));
|
|
727
753
|
const avatarUrl = pickFirstString(entry?.avatar_url_s, entry?.avatarUrl, entry?.avatar_url);
|
|
728
754
|
return {
|
|
729
|
-
kind: '
|
|
755
|
+
kind: 'personal',
|
|
730
756
|
uid,
|
|
731
757
|
handle: handle || uid,
|
|
732
758
|
displayName: displayName || handle || uid,
|
|
@@ -746,7 +772,10 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
746
772
|
kind: 'team',
|
|
747
773
|
uid,
|
|
748
774
|
handle: handle || uid,
|
|
749
|
-
displayName: pickFirstString(entry?.name_t, entry?.name) ||
|
|
775
|
+
displayName: pickFirstString(entry?.name_t, entry?.name) ||
|
|
776
|
+
formatPrincipalHandle('team', handle || uid, pickFirstString(entry?.organization_handle_s, entry?.organizationHandle, entry?.organization_handle) || undefined) ||
|
|
777
|
+
handle ||
|
|
778
|
+
uid,
|
|
750
779
|
accountHandle: pickFirstString(entry?.organization_handle_s, entry?.organizationHandle, entry?.organization_handle) || undefined,
|
|
751
780
|
};
|
|
752
781
|
})
|
|
@@ -762,7 +791,10 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
762
791
|
kind: 'organization',
|
|
763
792
|
uid,
|
|
764
793
|
handle: handle || uid,
|
|
765
|
-
displayName: pickFirstString(entry?.name_t, entry?.name) ||
|
|
794
|
+
displayName: pickFirstString(entry?.name_t, entry?.name) ||
|
|
795
|
+
formatPrincipalHandle('organization', handle || uid) ||
|
|
796
|
+
handle ||
|
|
797
|
+
uid,
|
|
766
798
|
};
|
|
767
799
|
})
|
|
768
800
|
.filter(Boolean);
|
|
@@ -777,7 +809,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
777
809
|
handle: result.handle,
|
|
778
810
|
avatarUrl: result.avatarUrl,
|
|
779
811
|
accountHandle: result.accountHandle,
|
|
780
|
-
origin: result.kind === '
|
|
812
|
+
origin: result.kind === 'personal' ? result.origin : undefined,
|
|
781
813
|
});
|
|
782
814
|
});
|
|
783
815
|
setSearchResults(filtered);
|
|
@@ -805,7 +837,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
805
837
|
}, [
|
|
806
838
|
isOpen,
|
|
807
839
|
canSearchPrincipals,
|
|
808
|
-
|
|
840
|
+
iamUrl,
|
|
809
841
|
token,
|
|
810
842
|
normalizedDebouncedSearch,
|
|
811
843
|
principalKindsKey,
|
|
@@ -815,16 +847,16 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
815
847
|
]);
|
|
816
848
|
// ----- Hydrate ACL user uids in bulk -----
|
|
817
849
|
useEffect(() => {
|
|
818
|
-
if (!isOpen || !canSearchPrincipals || !
|
|
850
|
+
if (!isOpen || !canSearchPrincipals || !iamUrl || !token) {
|
|
819
851
|
return;
|
|
820
852
|
}
|
|
821
853
|
const userUids = Array.from(new Set([
|
|
822
854
|
...aclEntries
|
|
823
|
-
.filter(e => e.kind === '
|
|
855
|
+
.filter(e => e.kind === 'personal')
|
|
824
856
|
.map(e => e.uid)
|
|
825
857
|
.filter(Boolean),
|
|
826
858
|
...ownerPrincipals
|
|
827
|
-
.filter(o => o.kind === '
|
|
859
|
+
.filter(o => o.kind === 'personal')
|
|
828
860
|
.map(o => o.uid)
|
|
829
861
|
.filter(Boolean),
|
|
830
862
|
]));
|
|
@@ -832,7 +864,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
832
864
|
if (!uid || userHydrationMissesRef.current.has(uid)) {
|
|
833
865
|
return false;
|
|
834
866
|
}
|
|
835
|
-
const cached = principalCache[principalKey('
|
|
867
|
+
const cached = principalCache[principalKey('personal', uid)] || {};
|
|
836
868
|
return (!cached.displayName ||
|
|
837
869
|
!cached.avatarUrl ||
|
|
838
870
|
!cached.origin ||
|
|
@@ -849,7 +881,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
849
881
|
return acc;
|
|
850
882
|
}, {}));
|
|
851
883
|
try {
|
|
852
|
-
const response = await fetch(`${
|
|
884
|
+
const response = await fetch(`${iamUrl}/api/iam/v1/users/bulk`, {
|
|
853
885
|
method: 'POST',
|
|
854
886
|
headers: {
|
|
855
887
|
'Content-Type': 'application/json',
|
|
@@ -881,7 +913,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
881
913
|
handle;
|
|
882
914
|
const avatarUrl = pickFirstString(entry?.avatar_url_s, entry?.avatarUrl, entry?.avatar_url);
|
|
883
915
|
const origin = normalizeUserOrigin(pickFirstString(entry?.origin, entry?.origin_s, entry?.origin_t));
|
|
884
|
-
mergePrincipalCacheEntry('
|
|
916
|
+
mergePrincipalCacheEntry('personal', uid, {
|
|
885
917
|
displayName,
|
|
886
918
|
handle,
|
|
887
919
|
avatarUrl: avatarUrl || undefined,
|
|
@@ -910,7 +942,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
910
942
|
}, [
|
|
911
943
|
isOpen,
|
|
912
944
|
canSearchPrincipals,
|
|
913
|
-
|
|
945
|
+
iamUrl,
|
|
914
946
|
token,
|
|
915
947
|
aclEntries,
|
|
916
948
|
ownerPrincipals,
|
|
@@ -919,7 +951,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
919
951
|
]);
|
|
920
952
|
// ----- Hydrate ACL team uids individually -----
|
|
921
953
|
useEffect(() => {
|
|
922
|
-
if (!isOpen || !canSearchPrincipals || !
|
|
954
|
+
if (!isOpen || !canSearchPrincipals || !iamUrl || !token) {
|
|
923
955
|
return;
|
|
924
956
|
}
|
|
925
957
|
const unknownTeams = aclEntries.filter(entry => {
|
|
@@ -935,7 +967,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
935
967
|
let cancelled = false;
|
|
936
968
|
void Promise.all(unknownTeams.map(async (entry) => {
|
|
937
969
|
try {
|
|
938
|
-
const response = await fetch(`${
|
|
970
|
+
const response = await fetch(`${iamUrl}/api/iam/v1/teams/${encodeURIComponent(entry.uid)}`, {
|
|
939
971
|
method: 'GET',
|
|
940
972
|
headers: {
|
|
941
973
|
'Content-Type': 'application/json',
|
|
@@ -969,7 +1001,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
969
1001
|
}, [
|
|
970
1002
|
isOpen,
|
|
971
1003
|
canSearchPrincipals,
|
|
972
|
-
|
|
1004
|
+
iamUrl,
|
|
973
1005
|
token,
|
|
974
1006
|
aclEntries,
|
|
975
1007
|
principalCache,
|
|
@@ -1125,12 +1157,17 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
1125
1157
|
const groupedShareable = useMemo(() => {
|
|
1126
1158
|
const filtered = shareablePrincipals.filter(p => principalKindsSet.has(p.kind));
|
|
1127
1159
|
const selfUid = pickFirstString(user?.uid);
|
|
1128
|
-
const self = filtered.filter(p => p.kind === '
|
|
1129
|
-
const otherUsers = filtered.filter(p => p.kind === '
|
|
1160
|
+
const self = filtered.filter(p => p.kind === 'personal' && p.uid === selfUid);
|
|
1161
|
+
const otherUsers = filtered.filter(p => p.kind === 'personal' && p.uid !== selfUid);
|
|
1130
1162
|
const orgs = filtered.filter(p => p.kind === 'organization');
|
|
1131
1163
|
const teams = filtered.filter(p => p.kind === 'team');
|
|
1132
1164
|
return { self, otherUsers, orgs, teams };
|
|
1133
1165
|
}, [shareablePrincipals, principalKindsSet, user?.uid]);
|
|
1166
|
+
useEffect(() => {
|
|
1167
|
+
if (isOpen) {
|
|
1168
|
+
setIsExpanded(expanded);
|
|
1169
|
+
}
|
|
1170
|
+
}, [isOpen, expanded]);
|
|
1134
1171
|
if (!isOpen) {
|
|
1135
1172
|
return null;
|
|
1136
1173
|
}
|
|
@@ -1143,7 +1180,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
1143
1180
|
const alreadyAdded = hasPrincipal(access, selectedAccessLevel, principal.kind, principal.uid);
|
|
1144
1181
|
const cached = principalCache[principalKey(principal.kind, principal.uid)] || {};
|
|
1145
1182
|
const displayName = principal.name || cached.displayName || principal.handle || principal.uid;
|
|
1146
|
-
const Icon = principal.kind === '
|
|
1183
|
+
const Icon = principal.kind === 'personal'
|
|
1147
1184
|
? PersonIcon
|
|
1148
1185
|
: principal.kind === 'organization'
|
|
1149
1186
|
? OrganizationIcon
|
|
@@ -1182,7 +1219,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
1182
1219
|
alignItems: 'center',
|
|
1183
1220
|
gap: 1,
|
|
1184
1221
|
flexWrap: 'wrap',
|
|
1185
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: displayName }), principal.kind === '
|
|
1222
|
+
}, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: displayName }), principal.kind === 'personal' &&
|
|
1186
1223
|
user?.uid &&
|
|
1187
1224
|
principal.uid === user.uid && (_jsx(Label, { size: "small", variant: "accent", children: "You" }))] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["@", principal.handle, principal.kind === 'team' && principal.organizationHandle && (_jsxs(Text, { as: "span", sx: { color: 'fg.muted' }, children: [' · ', "org @", principal.organizationHandle] }))] })] })] }), _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(Icon, { size: 14 }), alreadyAdded ? (_jsx(Label, { size: "small", variant: "success", children: "Added" })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Add" }))] })] }, principalKey(principal.kind, principal.uid)));
|
|
1188
1225
|
};
|
|
@@ -1225,7 +1262,7 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
1225
1262
|
alignItems: 'flex-start',
|
|
1226
1263
|
justifyContent: 'space-between',
|
|
1227
1264
|
gap: 2,
|
|
1228
|
-
}, children: [_jsx(Box, { sx: { display: 'grid', gap: 1 }, children: _jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: ["Share ", resourceName || `this ${resourceLabel.toLowerCase()}`, ". Pick a principal below \u2014 they will be granted the selected access level."] }) }), _jsxs(ActionMenu, { children: [_jsx(ActionMenu.Anchor, { children: _jsxs(Button, { variant: "default", size: "small", leadingVisual: KeyIcon, disabled: isSaving || isReadOnly, children: ["Access: ", ACCESS_LEVEL_LABELS[selectedAccessLevel]] }) }), _jsx(ActionMenu.Overlay, { width: "small", children: _jsx(ActionList, { selectionVariant: "single", children: ACCESS_LEVELS.map(level => (_jsx(ActionList.Item, { selected: selectedAccessLevel === level, onSelect: () => setSelectedAccessLevel(level), children: ACCESS_LEVEL_LABELS[level] }, level))) }) })] })] }), _jsxs(Box, { sx: {
|
|
1265
|
+
}, children: [_jsx(Box, { sx: { display: 'grid', gap: 1 }, children: _jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: ["Share ", resourceName || `this ${resourceLabel.toLowerCase()}`, ". Pick a principal below \u2014 they will be granted the selected access level."] }) }), _jsxs(ActionMenu, { children: [_jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(ActionMenu.Anchor, { children: _jsxs(Button, { variant: "default", size: "small", leadingVisual: KeyIcon, disabled: isSaving || isReadOnly, children: ["Access: ", ACCESS_LEVEL_LABELS[selectedAccessLevel]] }) }), _jsx(Button, { variant: "invisible", size: "small", leadingVisual: isExpanded ? ChevronUpIcon : ChevronDownIcon, onClick: () => setIsExpanded(previous => !previous), "aria-label": isExpanded ? 'Shrink sharing details' : 'Expand sharing details', children: isExpanded ? 'Shrink details' : 'Expand details' })] }), _jsx(ActionMenu.Overlay, { width: "small", children: _jsx(ActionList, { selectionVariant: "single", children: ACCESS_LEVELS.map(level => (_jsx(ActionList.Item, { selected: selectedAccessLevel === level, onSelect: () => setSelectedAccessLevel(level), children: ACCESS_LEVEL_LABELS[level] }, level))) }) })] })] }), !isExpanded && (_jsxs(Box, { sx: {
|
|
1229
1266
|
px: 3,
|
|
1230
1267
|
py: 2,
|
|
1231
1268
|
borderRadius: 2,
|
|
@@ -1235,118 +1272,128 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
|
|
|
1235
1272
|
bg: 'canvas.default',
|
|
1236
1273
|
display: 'grid',
|
|
1237
1274
|
gap: 1,
|
|
1238
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
borderColor: 'border.subtle',
|
|
1243
|
-
}, children: _jsx(OwnerPrincipalRow, { ownerPrincipal: ownerPrincipal, cache: principalCache, showAvatarSkeleton: ownerPrincipal.kind === 'user' &&
|
|
1244
|
-
Boolean(hydratingUserUids[ownerPrincipal.uid]), isPlatformAdmin: isPlatformAdmin }) }, principalKey(ownerPrincipal.kind, ownerPrincipal.uid)))) })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Owner information is not available." }))] }), _jsxs(Box, { sx: {
|
|
1245
|
-
px: 3,
|
|
1246
|
-
py: 2,
|
|
1247
|
-
borderRadius: 2,
|
|
1248
|
-
borderWidth: 1,
|
|
1249
|
-
borderStyle: 'solid',
|
|
1250
|
-
borderColor: 'border.default',
|
|
1251
|
-
bg: 'canvas.default',
|
|
1252
|
-
display: 'grid',
|
|
1253
|
-
gap: 2,
|
|
1254
|
-
}, children: [_jsxs(Box, { sx: {
|
|
1255
|
-
display: 'flex',
|
|
1256
|
-
alignItems: 'center',
|
|
1257
|
-
justifyContent: 'space-between',
|
|
1258
|
-
gap: 2,
|
|
1259
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 600 }, children: "Share with\u2026" }), isLoadingShareable && (_jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Loading\u2026" })] }))] }), !isLoadingShareable &&
|
|
1260
|
-
groupedShareable.self.length === 0 &&
|
|
1261
|
-
groupedShareable.otherUsers.length === 0 &&
|
|
1262
|
-
groupedShareable.orgs.length === 0 &&
|
|
1263
|
-
groupedShareable.teams.length === 0 ? (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "No principals available to share with." })) : (_jsxs(Box, { sx: { display: 'grid', gap: 2 }, children: [renderShareableGroup('You', groupedShareable.self), renderShareableGroup('Other users', groupedShareable.otherUsers), renderShareableGroup('Your organizations', groupedShareable.orgs), renderShareableGroup('Your teams', groupedShareable.teams)] }))] }), _jsxs(Box, { sx: {
|
|
1264
|
-
px: 3,
|
|
1265
|
-
py: 2,
|
|
1266
|
-
borderRadius: 2,
|
|
1267
|
-
borderWidth: 1,
|
|
1268
|
-
borderStyle: 'solid',
|
|
1269
|
-
borderColor: 'border.subtle',
|
|
1270
|
-
bg: 'canvas.subtle',
|
|
1271
|
-
display: 'grid',
|
|
1272
|
-
gap: 1,
|
|
1273
|
-
}, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Or search for any user, team, or organization" }), _jsxs(Box, { sx: { position: 'relative' }, ref: searchContainerRef, children: [_jsx(TextInput, { ref: searchInputRef, block: true, value: searchQuery, onChange: e => {
|
|
1274
|
-
const next = e.target.value;
|
|
1275
|
-
setSearchQuery(next);
|
|
1276
|
-
setIsSearchOverlayOpen(next.trim().length > 0);
|
|
1277
|
-
}, onFocus: () => {
|
|
1278
|
-
if (searchQuery.trim().length > 0) {
|
|
1279
|
-
setIsSearchOverlayOpen(true);
|
|
1280
|
-
}
|
|
1281
|
-
}, onKeyDown: e => {
|
|
1282
|
-
if (e.key === 'Escape') {
|
|
1283
|
-
e.preventDefault();
|
|
1284
|
-
setIsSearchOverlayOpen(false);
|
|
1285
|
-
}
|
|
1286
|
-
}, placeholder: "Search by handle, name, or email", "aria-label": "Search principals", disabled: isSaving }), canShowSearchResults && (_jsx(Box, { sx: {
|
|
1287
|
-
position: 'absolute',
|
|
1288
|
-
top: 'calc(100% + 8px)',
|
|
1289
|
-
left: 0,
|
|
1290
|
-
right: 0,
|
|
1291
|
-
zIndex: 100,
|
|
1292
|
-
borderWidth: 1,
|
|
1293
|
-
borderStyle: 'solid',
|
|
1294
|
-
borderColor: 'border.default',
|
|
1295
|
-
borderRadius: 2,
|
|
1296
|
-
maxHeight: '220px',
|
|
1297
|
-
overflowY: 'auto',
|
|
1298
|
-
bg: 'canvas.overlay',
|
|
1299
|
-
boxShadow: 'shadow.medium',
|
|
1300
|
-
}, children: isSearching ? (_jsxs(Box, { sx: {
|
|
1301
|
-
px: 3,
|
|
1302
|
-
py: 2,
|
|
1303
|
-
display: 'inline-flex',
|
|
1304
|
-
alignItems: 'center',
|
|
1305
|
-
gap: 2,
|
|
1306
|
-
}, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Searching\u2026" })] })) : searchResults.length === 0 ? (_jsx(Box, { sx: { px: 3, py: 2 }, children: _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "No principals found." }) })) : (_jsx(ActionList, { children: searchResults.map(result => (_jsxs(ActionList.Item, { onSelect: () => handleSearchResultSelect(result), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(PrincipalAvatar, { kind: result.kind, avatarUrl: result.avatarUrl, alt: result.displayName, size: 18 }) }), _jsxs(Box, { sx: {
|
|
1307
|
-
display: 'inline-flex',
|
|
1308
|
-
alignItems: 'center',
|
|
1309
|
-
gap: 1,
|
|
1310
|
-
flexWrap: 'wrap',
|
|
1311
|
-
}, children: [_jsx(Text, { children: result.displayName }), result.kind === 'user' && (_jsx(Label, { size: "small", variant: "secondary", children: result.origin ||
|
|
1312
|
-
principalCache[principalKey('user', result.uid)]
|
|
1313
|
-
?.origin ||
|
|
1314
|
-
'Datalayer' }))] }), _jsxs(ActionList.Description, { variant: "block", children: ["@", result.handle] })] }, principalKey(result.kind, result.uid)))) })) }))] })] }), _jsxs(Box, { sx: {
|
|
1315
|
-
px: 3,
|
|
1316
|
-
py: 2,
|
|
1317
|
-
borderRadius: 2,
|
|
1318
|
-
borderWidth: 1,
|
|
1319
|
-
borderStyle: 'solid',
|
|
1320
|
-
borderColor: 'border.default',
|
|
1321
|
-
bg: 'canvas.default',
|
|
1322
|
-
display: 'grid',
|
|
1323
|
-
gap: 1,
|
|
1324
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Access Control List (ACL)" }), _jsx(Box, { sx: {
|
|
1275
|
+
}, children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Sharing details are collapsed." }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [aclEntries.length, " principal", aclEntries.length === 1 ? '' : 's', " currently granted access."] })] })), isExpanded && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
|
|
1276
|
+
px: 3,
|
|
1277
|
+
py: 2,
|
|
1278
|
+
borderRadius: 2,
|
|
1325
1279
|
borderWidth: 1,
|
|
1326
1280
|
borderStyle: 'solid',
|
|
1327
1281
|
borderColor: 'border.default',
|
|
1282
|
+
bg: 'canvas.default',
|
|
1283
|
+
display: 'grid',
|
|
1284
|
+
gap: 1,
|
|
1285
|
+
}, children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Owner" }), ownerPrincipals.length > 0 ? (_jsx(Box, { sx: { display: 'grid' }, children: ownerPrincipals.map((ownerPrincipal, index) => (_jsx(Box, { sx: {
|
|
1286
|
+
py: 1,
|
|
1287
|
+
borderTopWidth: index === 0 ? 0 : 1,
|
|
1288
|
+
borderTopStyle: 'solid',
|
|
1289
|
+
borderColor: 'border.subtle',
|
|
1290
|
+
}, children: _jsx(OwnerPrincipalRow, { ownerPrincipal: ownerPrincipal, cache: principalCache, showAvatarSkeleton: ownerPrincipal.kind === 'personal' &&
|
|
1291
|
+
Boolean(hydratingUserUids[ownerPrincipal.uid]), isPlatformAdmin: isPlatformAdmin }) }, principalKey(ownerPrincipal.kind, ownerPrincipal.uid)))) })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Owner information is not available." }))] }), _jsxs(Box, { sx: {
|
|
1292
|
+
px: 3,
|
|
1293
|
+
py: 2,
|
|
1328
1294
|
borderRadius: 2,
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1295
|
+
borderWidth: 1,
|
|
1296
|
+
borderStyle: 'solid',
|
|
1297
|
+
borderColor: 'border.default',
|
|
1298
|
+
bg: 'canvas.default',
|
|
1299
|
+
display: 'grid',
|
|
1300
|
+
gap: 2,
|
|
1301
|
+
}, children: [_jsxs(Box, { sx: {
|
|
1335
1302
|
display: 'flex',
|
|
1336
1303
|
alignItems: 'center',
|
|
1337
1304
|
justifyContent: 'space-between',
|
|
1338
1305
|
gap: 2,
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
}, children:
|
|
1344
|
-
|
|
1306
|
+
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 600 }, children: "Share with\u2026" }), isLoadingShareable && (_jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Loading\u2026" })] }))] }), !isLoadingShareable &&
|
|
1307
|
+
groupedShareable.self.length === 0 &&
|
|
1308
|
+
groupedShareable.otherUsers.length === 0 &&
|
|
1309
|
+
groupedShareable.orgs.length === 0 &&
|
|
1310
|
+
groupedShareable.teams.length === 0 ? (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "No principals available to share with." })) : (_jsxs(Box, { sx: { display: 'grid', gap: 2 }, children: [renderShareableGroup('You', groupedShareable.self), renderShareableGroup('Other users', groupedShareable.otherUsers), renderShareableGroup('Your organizations', groupedShareable.orgs), renderShareableGroup('Your teams', groupedShareable.teams)] }))] }), _jsxs(Box, { sx: {
|
|
1311
|
+
px: 3,
|
|
1312
|
+
py: 2,
|
|
1313
|
+
borderRadius: 2,
|
|
1314
|
+
borderWidth: 1,
|
|
1315
|
+
borderStyle: 'solid',
|
|
1316
|
+
borderColor: 'border.subtle',
|
|
1317
|
+
bg: 'canvas.subtle',
|
|
1318
|
+
display: 'grid',
|
|
1319
|
+
gap: 1,
|
|
1320
|
+
}, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Or search for any user, team, or organization" }), _jsxs(Box, { sx: { position: 'relative' }, ref: searchContainerRef, children: [_jsx(TextInput, { ref: searchInputRef, block: true, value: searchQuery, onChange: e => {
|
|
1321
|
+
const next = e.target.value;
|
|
1322
|
+
setSearchQuery(next);
|
|
1323
|
+
setIsSearchOverlayOpen(next.trim().length > 0);
|
|
1324
|
+
}, onFocus: () => {
|
|
1325
|
+
if (searchQuery.trim().length > 0) {
|
|
1326
|
+
setIsSearchOverlayOpen(true);
|
|
1327
|
+
}
|
|
1328
|
+
}, onKeyDown: e => {
|
|
1329
|
+
if (e.key === 'Escape') {
|
|
1330
|
+
e.preventDefault();
|
|
1331
|
+
setIsSearchOverlayOpen(false);
|
|
1332
|
+
}
|
|
1333
|
+
}, placeholder: "Search by handle, name, or email", "aria-label": "Search principals", disabled: isSaving }), canShowSearchResults && (_jsx(Box, { sx: {
|
|
1334
|
+
position: 'absolute',
|
|
1335
|
+
top: 'calc(100% + 8px)',
|
|
1336
|
+
left: 0,
|
|
1337
|
+
right: 0,
|
|
1338
|
+
zIndex: 100,
|
|
1339
|
+
borderWidth: 1,
|
|
1340
|
+
borderStyle: 'solid',
|
|
1341
|
+
borderColor: 'border.default',
|
|
1342
|
+
borderRadius: 2,
|
|
1343
|
+
maxHeight: '220px',
|
|
1344
|
+
overflowY: 'auto',
|
|
1345
|
+
bg: 'canvas.overlay',
|
|
1346
|
+
boxShadow: 'shadow.medium',
|
|
1347
|
+
}, children: isSearching ? (_jsxs(Box, { sx: {
|
|
1348
|
+
px: 3,
|
|
1349
|
+
py: 2,
|
|
1350
|
+
display: 'inline-flex',
|
|
1351
|
+
alignItems: 'center',
|
|
1352
|
+
gap: 2,
|
|
1353
|
+
}, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Searching\u2026" })] })) : searchResults.length === 0 ? (_jsx(Box, { sx: { px: 3, py: 2 }, children: _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "No principals found." }) })) : (_jsx(ActionList, { children: searchResults.map(result => (_jsxs(ActionList.Item, { onSelect: () => handleSearchResultSelect(result), children: [_jsx(ActionList.LeadingVisual, { children: _jsx(PrincipalAvatar, { kind: result.kind, avatarUrl: result.avatarUrl, alt: result.displayName, size: 18 }) }), _jsxs(Box, { sx: {
|
|
1354
|
+
display: 'inline-flex',
|
|
1355
|
+
alignItems: 'center',
|
|
1356
|
+
gap: 1,
|
|
1357
|
+
flexWrap: 'wrap',
|
|
1358
|
+
}, children: [_jsx(Text, { children: result.displayName }), result.kind === 'personal' && (_jsx(Label, { size: "small", variant: "secondary", children: result.origin ||
|
|
1359
|
+
principalCache[principalKey('personal', result.uid)]
|
|
1360
|
+
?.origin ||
|
|
1361
|
+
'Datalayer' }))] }), _jsxs(ActionList.Description, { variant: "block", children: ["@", result.handle] })] }, principalKey(result.kind, result.uid)))) })) }))] })] }), _jsxs(Box, { sx: {
|
|
1362
|
+
px: 3,
|
|
1363
|
+
py: 2,
|
|
1364
|
+
borderRadius: 2,
|
|
1365
|
+
borderWidth: 1,
|
|
1366
|
+
borderStyle: 'solid',
|
|
1367
|
+
borderColor: 'border.default',
|
|
1368
|
+
bg: 'canvas.default',
|
|
1369
|
+
display: 'grid',
|
|
1370
|
+
gap: 1,
|
|
1371
|
+
}, children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Access Control List (ACL)" }), _jsx(Box, { sx: {
|
|
1372
|
+
borderWidth: 1,
|
|
1373
|
+
borderStyle: 'solid',
|
|
1374
|
+
borderColor: 'border.default',
|
|
1375
|
+
borderRadius: 2,
|
|
1376
|
+
maxHeight: '220px',
|
|
1377
|
+
overflowY: 'auto',
|
|
1378
|
+
bg: 'canvas.subtle',
|
|
1379
|
+
}, children: aclEntries.length === 0 ? (_jsx(Box, { sx: { px: 3, py: 2 }, children: _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "No principals shared yet." }) })) : (_jsx(Box, { sx: { display: 'grid' }, children: aclEntries.map(entry => (_jsxs(Box, { sx: {
|
|
1380
|
+
px: 3,
|
|
1381
|
+
py: 2,
|
|
1345
1382
|
display: 'flex',
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1383
|
+
alignItems: 'center',
|
|
1384
|
+
justifyContent: 'space-between',
|
|
1385
|
+
gap: 2,
|
|
1386
|
+
borderTopWidth: 1,
|
|
1387
|
+
borderTopStyle: 'solid',
|
|
1388
|
+
borderColor: 'border.subtle',
|
|
1389
|
+
'&:first-of-type': { borderTop: 'none' },
|
|
1390
|
+
}, children: [_jsx(AccessPrincipalRow, { entry: entry, cache: principalCache, showAvatarSkeleton: entry.kind === 'personal' &&
|
|
1391
|
+
Boolean(hydratingUserUids[entry.uid]), isPlatformAdmin: isPlatformAdmin }), _jsx(Box, { sx: {
|
|
1392
|
+
display: 'flex',
|
|
1393
|
+
flexWrap: 'wrap',
|
|
1394
|
+
gap: 1,
|
|
1395
|
+
justifyContent: 'flex-end',
|
|
1396
|
+
}, children: entry.levels.map(level => (_jsx(Label, { size: "small", variant: "secondary", children: ACCESS_LEVEL_LABELS[level] }, level))) }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => removePrincipal(entry.kind, entry.uid), disabled: isSaving, children: "Remove" })] }, principalKey(entry.kind, entry.uid)))) })) })] })] }))] }), _jsxs(Box, { sx: {
|
|
1350
1397
|
display: 'flex',
|
|
1351
1398
|
justifyContent: 'flex-end',
|
|
1352
1399
|
alignItems: 'center',
|