feat: select users in file access explanations
This commit is contained in:
@@ -10,11 +10,15 @@ import {
|
||||
type FilesManagedFileLinkTarget,
|
||||
type ReferenceOptionProvider
|
||||
} from "@govoplan/core-webui";
|
||||
export { fetchResourceAccessExplanation } from "@govoplan/core-webui";
|
||||
export {
|
||||
fetchResourceAccessExplanation,
|
||||
fetchResourceAccessExplanationSubjects
|
||||
} from "@govoplan/core-webui";
|
||||
export type {
|
||||
AccessDecisionProvenanceItem,
|
||||
ResourceAccessExplanationUser as AccessExplanationUser,
|
||||
ResourceAccessExplanationResponse
|
||||
ResourceAccessExplanationResponse,
|
||||
ResourceAccessExplanationSubjectsResponse
|
||||
} from "@govoplan/core-webui";
|
||||
|
||||
export type FileSpace = {
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
downloadFile,
|
||||
downloadFilesAsZip,
|
||||
fetchResourceAccessExplanation,
|
||||
fetchResourceAccessExplanationSubjects,
|
||||
listFilesDelta,
|
||||
listFilesByProperties,
|
||||
listFileConnectorProfiles,
|
||||
@@ -52,7 +53,8 @@ import {
|
||||
type FileSpace,
|
||||
type ManagedFile,
|
||||
type RenameResponse,
|
||||
type ResourceAccessExplanationResponse } from
|
||||
type ResourceAccessExplanationResponse,
|
||||
type ResourceAccessExplanationSubjectsResponse } from
|
||||
"../../api/files";
|
||||
import { EMPTY_FILES, EMPTY_FOLDERS, EMPTY_SPACES, INTERNAL_DRAG_TYPE } from "./constants";
|
||||
import { FileConflictDialog, FileContextMenu, FileDialog, FolderTree, RenamePreviewList, TransferFolderSelector } from "./components/FileManagerComponents";
|
||||
@@ -176,6 +178,8 @@ export default function FilesPage({ settings, auth }: {settings: ApiSettings;aut
|
||||
const [error, setError] = useState("");
|
||||
const [accessExplanationTarget, setAccessExplanationTarget] = useState<FileAccessExplanationTarget | null>(null);
|
||||
const [resourceAccessExplanation, setResourceAccessExplanation] = useState<ResourceAccessExplanationResponse | null>(null);
|
||||
const [resourceAccessSubjects, setResourceAccessSubjects] = useState<ResourceAccessExplanationSubjectsResponse | null>(null);
|
||||
const [resourceAccessSubjectId, setResourceAccessSubjectId] = useState("");
|
||||
const [resourceAccessLoading, setResourceAccessLoading] = useState(false);
|
||||
const [shareDialogFile, setShareDialogFile] = useState<ManagedFile | null>(null);
|
||||
const { setDragActive, internalDrag, setInternalDrag, dropTargetKey, setDropTargetKey, clearDropState: clearDragDropState } = useFileDragDropState();
|
||||
@@ -1911,14 +1915,25 @@ export default function FilesPage({ settings, auth }: {settings: ApiSettings;aut
|
||||
}
|
||||
|
||||
async function openAccessExplanation(target: FileAccessExplanationTarget): Promise<void> {
|
||||
if (!auth.user?.id) return;
|
||||
const currentUserId = auth.principal?.membership_id || auth.user?.id;
|
||||
if (!currentUserId) return;
|
||||
setAccessExplanationTarget(target);
|
||||
setResourceAccessExplanation(null);
|
||||
setResourceAccessSubjects(null);
|
||||
setResourceAccessLoading(true);
|
||||
setError("");
|
||||
try {
|
||||
const subjects = await fetchResourceAccessExplanationSubjects(settings, {
|
||||
tenantId: (auth.active_tenant ?? auth.tenant)?.id
|
||||
});
|
||||
const initialSubjectId = subjects.users.some((user) => user.id === currentUserId)
|
||||
? currentUserId
|
||||
: subjects.users[0]?.id;
|
||||
if (!initialSubjectId) throw new Error("No permitted access-explanation subject is available.");
|
||||
setResourceAccessSubjects(subjects);
|
||||
setResourceAccessSubjectId(initialSubjectId);
|
||||
setResourceAccessExplanation(await fetchResourceAccessExplanation(settings, {
|
||||
userId: auth.user.id,
|
||||
userId: initialSubjectId,
|
||||
resourceType: target.resourceType,
|
||||
resourceId: target.resourceId,
|
||||
action: target.action,
|
||||
@@ -1932,6 +1947,27 @@ export default function FilesPage({ settings, auth }: {settings: ApiSettings;aut
|
||||
}
|
||||
}
|
||||
|
||||
async function selectAccessExplanationSubject(userId: string): Promise<void> {
|
||||
if (!accessExplanationTarget || userId === resourceAccessSubjectId) return;
|
||||
setResourceAccessLoading(true);
|
||||
setError("");
|
||||
try {
|
||||
const explanation = await fetchResourceAccessExplanation(settings, {
|
||||
userId,
|
||||
resourceType: accessExplanationTarget.resourceType,
|
||||
resourceId: accessExplanationTarget.resourceId,
|
||||
action: accessExplanationTarget.action,
|
||||
tenantId: (auth.active_tenant ?? auth.tenant)?.id
|
||||
});
|
||||
setResourceAccessExplanation(explanation);
|
||||
setResourceAccessSubjectId(userId);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : String(err));
|
||||
} finally {
|
||||
setResourceAccessLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
function openTransferDialogForContext(menu: ContextMenuState | null, mode: TransferMode) {
|
||||
const sets = selectedSetsForContext(menu);
|
||||
const space = spaceForContext(menu);
|
||||
@@ -2595,13 +2631,16 @@ export default function FilesPage({ settings, auth }: {settings: ApiSettings;aut
|
||||
}
|
||||
|
||||
{accessExplanationTarget &&
|
||||
<FileDialog title="i18n:govoplan-core.access_explanation.75ee7f62" onClose={() => {if (!resourceAccessLoading) {setAccessExplanationTarget(null);setResourceAccessExplanation(null);}}}>
|
||||
<FileDialog title="i18n:govoplan-core.access_explanation.75ee7f62" onClose={() => {if (!resourceAccessLoading) {setAccessExplanationTarget(null);setResourceAccessExplanation(null);setResourceAccessSubjects(null);setResourceAccessSubjectId("");}}}>
|
||||
<ResourceAccessExplanation
|
||||
loading={resourceAccessLoading}
|
||||
explanation={resourceAccessExplanation}
|
||||
subjects={resourceAccessSubjects}
|
||||
selectedUserId={resourceAccessSubjectId}
|
||||
onSelectedUserIdChange={(userId) => void selectAccessExplanationSubject(userId)}
|
||||
fallbackResourceLabel={accessExplanationTarget.label} />
|
||||
<div className="button-row compact-actions align-end">
|
||||
<Button onClick={() => {setAccessExplanationTarget(null);setResourceAccessExplanation(null);}} disabled={resourceAccessLoading}>i18n:govoplan-files.close.bbfa773e</Button>
|
||||
<Button onClick={() => {setAccessExplanationTarget(null);setResourceAccessExplanation(null);setResourceAccessSubjects(null);setResourceAccessSubjectId("");}} disabled={resourceAccessLoading}>i18n:govoplan-files.close.bbfa773e</Button>
|
||||
</div>
|
||||
</FileDialog>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user