1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { Dispatch } from 'redux';
6 import { RootState } from 'store/store';
7 import { getUserUuid } from 'common/getuser';
8 import { loadDetailsPanel } from 'store/details-panel/details-panel-action';
9 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
13 } from 'store/favorite-panel/favorite-panel-action';
15 getProjectPanelCurrentUuid,
18 setIsProjectPanelTrashed,
19 } from 'store/project-panel/project-panel-action';
21 activateSidePanelTreeItem,
23 loadSidePanelTreeProjects,
24 SidePanelTreeCategory,
25 } from 'store/side-panel-tree/side-panel-tree-actions';
26 import { updateResources } from 'store/resources/resources-actions';
27 import { projectPanelColumns } from 'views/project-panel/project-panel';
28 import { favoritePanelColumns } from 'views/favorite-panel/favorite-panel';
29 import { matchRootRoute } from 'routes/routes';
32 setGroupDetailsBreadcrumbs,
34 setProcessBreadcrumbs,
35 setSharedWithMeBreadcrumbs,
36 setSidePanelBreadcrumbs,
39 setMyAccountBreadcrumbs,
40 setUserProfileBreadcrumbs,
41 } from 'store/breadcrumbs/breadcrumbs-actions';
44 navigateToRootProject,
45 } from 'store/navigation/navigation-action';
46 import { MoveToFormDialogData } from 'store/move-to-dialog/move-to-dialog';
47 import { ServiceRepository } from 'services/services';
48 import { getResource } from 'store/resources/resources';
49 import * as projectCreateActions from 'store/projects/project-create-actions';
50 import * as projectMoveActions from 'store/projects/project-move-actions';
51 import * as projectUpdateActions from 'store/projects/project-update-actions';
52 import * as collectionCreateActions from 'store/collections/collection-create-actions';
53 import * as collectionCopyActions from 'store/collections/collection-copy-actions';
54 import * as collectionMoveActions from 'store/collections/collection-move-actions';
55 import * as processesActions from 'store/processes/processes-actions';
56 import * as processMoveActions from 'store/processes/process-move-actions';
57 import * as processUpdateActions from 'store/processes/process-update-actions';
58 import * as processCopyActions from 'store/processes/process-copy-actions';
59 import { trashPanelColumns } from 'views/trash-panel/trash-panel';
63 } from 'store/trash-panel/trash-panel-action';
64 import { loadProcessPanel } from 'store/process-panel/process-panel-actions';
66 loadSharedWithMePanel,
67 sharedWithMePanelActions,
68 } from 'store/shared-with-me-panel/shared-with-me-panel-actions';
69 import { CopyFormDialogData } from 'store/copy-dialog/copy-dialog';
70 import { workflowPanelActions } from 'store/workflow-panel/workflow-panel-actions';
71 import { loadSshKeysPanel } from 'store/auth/auth-action-ssh';
74 linkAccountPanelActions,
75 } from 'store/link-account-panel/link-account-panel-actions';
76 import { loadSiteManagerPanel } from 'store/auth/auth-action-session';
77 import { workflowPanelColumns } from 'views/workflow-panel/workflow-panel-view';
78 import { progressIndicatorActions } from 'store/progress-indicator/progress-indicator-actions';
79 import { getProgressIndicator } from 'store/progress-indicator/progress-indicator-reducer';
80 import { extractUuidKind, ResourceKind } from 'models/resource';
81 import { FilterBuilder } from 'services/api/filter-builder';
82 import { GroupContentsResource } from 'services/groups-service/groups-service';
83 import { MatchCases, ofType, unionize, UnionOf } from 'common/unionize';
84 import { loadRunProcessPanel } from 'store/run-process-panel/run-process-panel-actions';
86 collectionPanelActions,
88 } from 'store/collection-panel/collection-panel-action';
89 import { CollectionResource } from 'models/collection';
90 import { WorkflowResource } from 'models/workflow';
92 loadSearchResultsPanel,
93 searchResultsPanelActions,
94 } from 'store/search-results-panel/search-results-panel-actions';
95 import { searchResultsPanelColumns } from 'views/search-results-panel/search-results-panel-view';
96 import { loadVirtualMachinesPanel } from 'store/virtual-machines/virtual-machines-actions';
97 import { loadRepositoriesPanel } from 'store/repositories/repositories-actions';
98 import { loadKeepServicesPanel } from 'store/keep-services/keep-services-actions';
99 import { loadUsersPanel, userBindedActions } from 'store/users/users-actions';
100 import * as userProfilePanelActions from 'store/user-profile/user-profile-actions';
104 } from 'store/link-panel/link-panel-actions';
105 import { linkPanelColumns } from 'views/link-panel/link-panel-root';
106 import { userPanelColumns } from 'views/user-panel/user-panel';
108 loadApiClientAuthorizationsPanel,
109 apiClientAuthorizationsActions,
110 } from 'store/api-client-authorizations/api-client-authorizations-actions';
111 import { apiClientAuthorizationPanelColumns } from 'views/api-client-authorization-panel/api-client-authorization-panel-root';
112 import * as groupPanelActions from 'store/groups-panel/groups-panel-actions';
113 import { groupsPanelColumns } from 'views/groups-panel/groups-panel';
114 import * as groupDetailsPanelActions from 'store/group-details-panel/group-details-panel-actions';
116 groupDetailsMembersPanelColumns,
117 groupDetailsPermissionsPanelColumns,
118 } from 'views/group-details-panel/group-details-panel';
119 import { DataTableFetchMode } from 'components/data-table/data-table';
121 loadPublicFavoritePanel,
122 publicFavoritePanelActions,
123 } from 'store/public-favorites-panel/public-favorites-action';
124 import { publicFavoritePanelColumns } from 'views/public-favorites-panel/public-favorites-panel';
126 loadCollectionsContentAddressPanel,
127 collectionsContentAddressActions,
128 } from 'store/collections-content-address-panel/collections-content-address-panel-actions';
129 import { collectionContentAddressPanelColumns } from 'views/collection-content-address-panel/collection-content-address-panel';
130 import { subprocessPanelActions } from 'store/subprocess-panel/subprocess-panel-actions';
131 import { subprocessPanelColumns } from 'views/subprocess-panel/subprocess-panel-root';
133 loadAllProcessesPanel,
134 allProcessesPanelActions,
135 } from '../all-processes-panel/all-processes-panel-action';
136 import { allProcessesPanelColumns } from 'views/all-processes-panel/all-processes-panel';
137 import { AdminMenuIcon } from 'components/icon/icon';
138 import { userProfileGroupsColumns } from 'views/user-profile-panel/user-profile-panel-root';
140 export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen';
142 export const isWorkbenchLoading = (state: RootState) => {
143 const progress = getProgressIndicator(WORKBENCH_LOADING_SCREEN)(
144 state.progressIndicator
146 return progress ? progress.working : false;
149 export const handleFirstTimeLoad =
151 async (dispatch: Dispatch<any>, getState: () => RootState) => {
153 await dispatch(action);
155 if (isWorkbenchLoading(getState())) {
157 progressIndicatorActions.STOP_WORKING(WORKBENCH_LOADING_SCREEN)
163 export const loadWorkbench =
167 getState: () => RootState,
168 services: ServiceRepository
170 dispatch(progressIndicatorActions.START_WORKING(WORKBENCH_LOADING_SCREEN));
171 const { auth, router } = getState();
172 const { user } = auth;
175 projectPanelActions.SET_COLUMNS({ columns: projectPanelColumns })
178 favoritePanelActions.SET_COLUMNS({ columns: favoritePanelColumns })
181 allProcessesPanelActions.SET_COLUMNS({
182 columns: allProcessesPanelColumns,
186 publicFavoritePanelActions.SET_COLUMNS({
187 columns: publicFavoritePanelColumns,
190 dispatch(trashPanelActions.SET_COLUMNS({ columns: trashPanelColumns }));
192 sharedWithMePanelActions.SET_COLUMNS({ columns: projectPanelColumns })
195 workflowPanelActions.SET_COLUMNS({ columns: workflowPanelColumns })
198 searchResultsPanelActions.SET_FETCH_MODE({
199 fetchMode: DataTableFetchMode.INFINITE,
203 searchResultsPanelActions.SET_COLUMNS({
204 columns: searchResultsPanelColumns,
207 dispatch(userBindedActions.SET_COLUMNS({ columns: userPanelColumns }));
209 groupPanelActions.GroupsPanelActions.SET_COLUMNS({
210 columns: groupsPanelColumns,
214 groupDetailsPanelActions.GroupMembersPanelActions.SET_COLUMNS({
215 columns: groupDetailsMembersPanelColumns,
219 groupDetailsPanelActions.GroupPermissionsPanelActions.SET_COLUMNS({
220 columns: groupDetailsPermissionsPanelColumns,
224 userProfilePanelActions.UserProfileGroupsActions.SET_COLUMNS({
225 columns: userProfileGroupsColumns,
228 dispatch(linkPanelActions.SET_COLUMNS({ columns: linkPanelColumns }));
230 apiClientAuthorizationsActions.SET_COLUMNS({
231 columns: apiClientAuthorizationPanelColumns,
235 collectionsContentAddressActions.SET_COLUMNS({
236 columns: collectionContentAddressPanelColumns,
240 subprocessPanelActions.SET_COLUMNS({ columns: subprocessPanelColumns })
243 if (services.linkAccountService.getAccountToLink()) {
244 dispatch(linkAccountPanelActions.HAS_SESSION_DATA());
247 dispatch<any>(initSidePanelTree());
248 if (router.location) {
249 const match = matchRootRoute(router.location.pathname);
251 dispatch<any>(navigateToRootProject);
255 dispatch(userIsNotAuthenticated);
259 export const loadFavorites = () =>
260 handleFirstTimeLoad((dispatch: Dispatch) => {
261 dispatch<any>(activateSidePanelTreeItem(SidePanelTreeCategory.FAVORITES));
262 dispatch<any>(loadFavoritePanel());
263 dispatch<any>(setSidePanelBreadcrumbs(SidePanelTreeCategory.FAVORITES));
266 export const loadCollectionContentAddress = handleFirstTimeLoad(
267 async (dispatch: Dispatch<any>) => {
268 await dispatch(loadCollectionsContentAddressPanel());
272 export const loadTrash = () =>
273 handleFirstTimeLoad((dispatch: Dispatch) => {
274 dispatch<any>(activateSidePanelTreeItem(SidePanelTreeCategory.TRASH));
275 dispatch<any>(loadTrashPanel());
276 dispatch<any>(setSidePanelBreadcrumbs(SidePanelTreeCategory.TRASH));
279 export const loadAllProcesses = () =>
280 handleFirstTimeLoad((dispatch: Dispatch) => {
282 activateSidePanelTreeItem(SidePanelTreeCategory.ALL_PROCESSES)
284 dispatch<any>(loadAllProcessesPanel());
285 dispatch<any>(setSidePanelBreadcrumbs(SidePanelTreeCategory.ALL_PROCESSES));
288 export const loadProject = (uuid: string) =>
291 dispatch: Dispatch<any>,
292 getState: () => RootState,
293 services: ServiceRepository
295 const userUuid = getUserUuid(getState());
296 dispatch(setIsProjectPanelTrashed(false));
300 if (extractUuidKind(uuid) === ResourceKind.USER && userUuid !== uuid) {
301 // Load another users home projects
302 dispatch(finishLoadingProject(uuid));
303 } else if (userUuid !== uuid) {
304 await dispatch(finishLoadingProject(uuid));
305 const match = await loadGroupContentsResource({
312 await dispatch(activateSidePanelTreeItem(uuid));
313 dispatch<any>(setSidePanelBreadcrumbs(uuid));
315 SHARED: async () => {
316 await dispatch(activateSidePanelTreeItem(uuid));
317 dispatch<any>(setSharedWithMeBreadcrumbs(uuid));
319 TRASHED: async () => {
321 activateSidePanelTreeItem(SidePanelTreeCategory.TRASH)
323 dispatch<any>(setTrashBreadcrumbs(uuid));
324 dispatch(setIsProjectPanelTrashed(true));
328 await dispatch(finishLoadingProject(userUuid));
329 await dispatch(activateSidePanelTreeItem(userUuid));
330 dispatch<any>(setSidePanelBreadcrumbs(userUuid));
335 export const createProject =
336 (data: projectCreateActions.ProjectCreateFormDialogData) =>
337 async (dispatch: Dispatch) => {
338 const newProject = await dispatch<any>(
339 projectCreateActions.createProject(data)
343 snackbarActions.OPEN_SNACKBAR({
344 message: 'Project has been successfully created.',
346 kind: SnackbarKind.SUCCESS,
349 await dispatch<any>(loadSidePanelTreeProjects(newProject.ownerUuid));
350 dispatch<any>(navigateTo(newProject.uuid));
354 export const moveProject =
355 (data: MoveToFormDialogData) =>
358 getState: () => RootState,
359 services: ServiceRepository
362 const oldProject = getResource(data.uuid)(getState().resources);
363 const oldOwnerUuid = oldProject ? oldProject.ownerUuid : '';
364 const movedProject = await dispatch<any>(
365 projectMoveActions.moveProject(data)
369 snackbarActions.OPEN_SNACKBAR({
370 message: 'Project has been moved',
372 kind: SnackbarKind.SUCCESS,
376 await dispatch<any>(loadSidePanelTreeProjects(oldProject.ownerUuid));
379 reloadProjectMatchingUuid([
381 movedProject.ownerUuid,
388 snackbarActions.OPEN_SNACKBAR({
391 kind: SnackbarKind.ERROR,
397 export const updateProject =
398 (data: projectUpdateActions.ProjectUpdateFormDialogData) =>
399 async (dispatch: Dispatch) => {
400 const updatedProject = await dispatch<any>(
401 projectUpdateActions.updateProject(data)
403 if (updatedProject) {
405 snackbarActions.OPEN_SNACKBAR({
406 message: 'Project has been successfully updated.',
408 kind: SnackbarKind.SUCCESS,
411 await dispatch<any>(loadSidePanelTreeProjects(updatedProject.ownerUuid));
413 reloadProjectMatchingUuid([
414 updatedProject.ownerUuid,
421 export const updateGroup =
422 (data: projectUpdateActions.ProjectUpdateFormDialogData) =>
423 async (dispatch: Dispatch) => {
424 const updatedGroup = await dispatch<any>(
425 groupPanelActions.updateGroup(data)
429 snackbarActions.OPEN_SNACKBAR({
430 message: 'Group has been successfully updated.',
432 kind: SnackbarKind.SUCCESS,
435 await dispatch<any>(loadSidePanelTreeProjects(updatedGroup.ownerUuid));
437 reloadProjectMatchingUuid([updatedGroup.ownerUuid, updatedGroup.uuid])
442 export const loadCollection = (uuid: string) =>
445 dispatch: Dispatch<any>,
446 getState: () => RootState,
447 services: ServiceRepository
449 const userUuid = getUserUuid(getState());
451 const match = await loadGroupContentsResource({
456 let collection: CollectionResource | undefined;
457 let breadcrumbfunc: ((uuid: string) => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => Promise<void>) | undefined;
458 let sidepanel: string | undefined;
460 OWNED: (thecollection) => {
461 collection = thecollection as CollectionResource;
462 sidepanel = collection.ownerUuid;
463 breadcrumbfunc = setSidePanelBreadcrumbs;
465 SHARED: (thecollection) => {
466 collection = thecollection as CollectionResource;
467 sidepanel = collection.ownerUuid;
468 breadcrumbfunc = setSharedWithMeBreadcrumbs;
470 TRASHED: (thecollection) => {
471 collection = thecollection as CollectionResource;
472 sidepanel = SidePanelTreeCategory.TRASH;
473 breadcrumbfunc = () => setTrashBreadcrumbs('');
476 if (collection && breadcrumbfunc && sidepanel) {
477 dispatch(updateResources([collection]));
478 await dispatch<any>(finishLoadingProject(collection.ownerUuid));
479 dispatch(collectionPanelActions.SET_COLLECTION(collection));
480 await dispatch(activateSidePanelTreeItem(sidepanel));
481 dispatch(breadcrumbfunc(collection.ownerUuid));
482 dispatch(loadCollectionPanel(collection.uuid));
488 export const createCollection =
489 (data: collectionCreateActions.CollectionCreateFormDialogData) =>
490 async (dispatch: Dispatch) => {
491 const collection = await dispatch<any>(
492 collectionCreateActions.createCollection(data)
496 snackbarActions.OPEN_SNACKBAR({
497 message: 'Collection has been successfully created.',
499 kind: SnackbarKind.SUCCESS,
502 dispatch<any>(updateResources([collection]));
503 dispatch<any>(navigateTo(collection.uuid));
507 export const copyCollection =
508 (data: CopyFormDialogData) =>
511 getState: () => RootState,
512 services: ServiceRepository
515 const copyToProject = getResource(data.ownerUuid)(getState().resources);
516 const collection = await dispatch<any>(
517 collectionCopyActions.copyCollection(data)
519 if (copyToProject && collection) {
520 dispatch<any>(reloadProjectMatchingUuid([copyToProject.uuid]));
522 snackbarActions.OPEN_SNACKBAR({
523 message: 'Collection has been copied.',
525 kind: SnackbarKind.SUCCESS,
526 link: collection.ownerUuid,
532 snackbarActions.OPEN_SNACKBAR({
535 kind: SnackbarKind.ERROR,
541 export const moveCollection =
542 (data: MoveToFormDialogData) =>
545 getState: () => RootState,
546 services: ServiceRepository
549 const collection = await dispatch<any>(
550 collectionMoveActions.moveCollection(data)
552 dispatch<any>(updateResources([collection]));
553 dispatch<any>(reloadProjectMatchingUuid([collection.ownerUuid]));
555 snackbarActions.OPEN_SNACKBAR({
556 message: 'Collection has been moved.',
558 kind: SnackbarKind.SUCCESS,
563 snackbarActions.OPEN_SNACKBAR({
566 kind: SnackbarKind.ERROR,
572 export const loadProcess = (uuid: string) =>
573 handleFirstTimeLoad(async (dispatch: Dispatch, getState: () => RootState) => {
574 dispatch<any>(loadProcessPanel(uuid));
575 const process = await dispatch<any>(processesActions.loadProcess(uuid));
577 await dispatch<any>(finishLoadingProject(process.containerRequest.ownerUuid));
579 activateSidePanelTreeItem(process.containerRequest.ownerUuid)
581 dispatch<any>(setProcessBreadcrumbs(uuid));
582 dispatch<any>(loadDetailsPanel(uuid));
586 export const loadRegisteredWorkflow = (uuid: string) =>
587 handleFirstTimeLoad(async (dispatch: Dispatch,
588 getState: () => RootState,
589 services: ServiceRepository) => {
591 const userUuid = getUserUuid(getState());
593 const match = await loadGroupContentsResource({
598 let workflow: WorkflowResource | undefined;
599 let breadcrumbfunc: ((uuid: string) => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => Promise<void>) | undefined;
601 OWNED: async (theworkflow) => {
602 workflow = theworkflow as WorkflowResource;
603 breadcrumbfunc = setSidePanelBreadcrumbs;
605 SHARED: async (theworkflow) => {
606 workflow = theworkflow as WorkflowResource;
607 breadcrumbfunc = setSharedWithMeBreadcrumbs;
611 if (workflow && breadcrumbfunc) {
612 dispatch(updateResources([workflow]));
613 await dispatch<any>(finishLoadingProject(workflow.ownerUuid));
614 await dispatch<any>(activateSidePanelTreeItem(workflow.ownerUuid));
615 dispatch<any>(breadcrumbfunc(workflow.ownerUuid));
620 export const updateProcess =
621 (data: processUpdateActions.ProcessUpdateFormDialogData) =>
622 async (dispatch: Dispatch) => {
624 const process = await dispatch<any>(
625 processUpdateActions.updateProcess(data)
629 snackbarActions.OPEN_SNACKBAR({
630 message: 'Process has been successfully updated.',
632 kind: SnackbarKind.SUCCESS,
635 dispatch<any>(updateResources([process]));
636 dispatch<any>(reloadProjectMatchingUuid([process.ownerUuid]));
640 snackbarActions.OPEN_SNACKBAR({
643 kind: SnackbarKind.ERROR,
649 export const moveProcess =
650 (data: MoveToFormDialogData) =>
653 getState: () => RootState,
654 services: ServiceRepository
657 const process = await dispatch<any>(processMoveActions.moveProcess(data));
658 dispatch<any>(updateResources([process]));
659 dispatch<any>(reloadProjectMatchingUuid([process.ownerUuid]));
661 snackbarActions.OPEN_SNACKBAR({
662 message: 'Process has been moved.',
664 kind: SnackbarKind.SUCCESS,
669 snackbarActions.OPEN_SNACKBAR({
672 kind: SnackbarKind.ERROR,
678 export const copyProcess =
679 (data: CopyFormDialogData) =>
682 getState: () => RootState,
683 services: ServiceRepository
686 const process = await dispatch<any>(processCopyActions.copyProcess(data));
687 dispatch<any>(updateResources([process]));
688 dispatch<any>(reloadProjectMatchingUuid([process.ownerUuid]));
690 snackbarActions.OPEN_SNACKBAR({
691 message: 'Process has been copied.',
693 kind: SnackbarKind.SUCCESS,
696 dispatch<any>(navigateTo(process.uuid));
699 snackbarActions.OPEN_SNACKBAR({
702 kind: SnackbarKind.ERROR,
708 export const resourceIsNotLoaded = (uuid: string) =>
709 snackbarActions.OPEN_SNACKBAR({
710 message: `Resource identified by ${uuid} is not loaded.`,
711 kind: SnackbarKind.ERROR,
714 export const userIsNotAuthenticated = snackbarActions.OPEN_SNACKBAR({
715 message: 'User is not authenticated',
716 kind: SnackbarKind.ERROR,
719 export const couldNotLoadUser = snackbarActions.OPEN_SNACKBAR({
720 message: 'Could not load user',
721 kind: SnackbarKind.ERROR,
724 export const reloadProjectMatchingUuid =
725 (matchingUuids: string[]) =>
728 getState: () => RootState,
729 services: ServiceRepository
731 const currentProjectPanelUuid = getProjectPanelCurrentUuid(getState());
733 currentProjectPanelUuid &&
734 matchingUuids.some((uuid) => uuid === currentProjectPanelUuid)
736 dispatch<any>(loadProject(currentProjectPanelUuid));
740 export const loadSharedWithMe = handleFirstTimeLoad(
741 async (dispatch: Dispatch) => {
742 dispatch<any>(loadSharedWithMePanel());
744 activateSidePanelTreeItem(SidePanelTreeCategory.SHARED_WITH_ME)
747 setSidePanelBreadcrumbs(SidePanelTreeCategory.SHARED_WITH_ME)
752 export const loadRunProcess = handleFirstTimeLoad(
753 async (dispatch: Dispatch) => {
754 await dispatch<any>(loadRunProcessPanel());
758 export const loadPublicFavorites = () =>
759 handleFirstTimeLoad((dispatch: Dispatch) => {
761 activateSidePanelTreeItem(SidePanelTreeCategory.PUBLIC_FAVORITES)
763 dispatch<any>(loadPublicFavoritePanel());
765 setSidePanelBreadcrumbs(SidePanelTreeCategory.PUBLIC_FAVORITES)
769 export const loadSearchResults = handleFirstTimeLoad(
770 async (dispatch: Dispatch<any>) => {
771 await dispatch(loadSearchResultsPanel());
775 export const loadLinks = handleFirstTimeLoad(
776 async (dispatch: Dispatch<any>) => {
777 await dispatch(loadLinkPanel());
781 export const loadVirtualMachines = handleFirstTimeLoad(
782 async (dispatch: Dispatch<any>) => {
783 await dispatch(loadVirtualMachinesPanel());
784 dispatch(setBreadcrumbs([{ label: 'Virtual Machines' }]));
788 export const loadVirtualMachinesAdmin = handleFirstTimeLoad(
789 async (dispatch: Dispatch<any>) => {
790 await dispatch(loadVirtualMachinesPanel());
792 setBreadcrumbs([{ label: 'Virtual Machines Admin', icon: AdminMenuIcon }])
797 export const loadRepositories = handleFirstTimeLoad(
798 async (dispatch: Dispatch<any>) => {
799 await dispatch(loadRepositoriesPanel());
800 dispatch(setBreadcrumbs([{ label: 'Repositories' }]));
804 export const loadSshKeys = handleFirstTimeLoad(
805 async (dispatch: Dispatch<any>) => {
806 await dispatch(loadSshKeysPanel());
810 export const loadSiteManager = handleFirstTimeLoad(
811 async (dispatch: Dispatch<any>) => {
812 await dispatch(loadSiteManagerPanel());
816 export const loadUserProfile = (userUuid?: string) =>
817 handleFirstTimeLoad((dispatch: Dispatch<any>) => {
819 dispatch(setUserProfileBreadcrumbs(userUuid));
820 dispatch(userProfilePanelActions.loadUserProfilePanel(userUuid));
822 dispatch(setMyAccountBreadcrumbs());
823 dispatch(userProfilePanelActions.loadUserProfilePanel());
827 export const loadLinkAccount = handleFirstTimeLoad(
828 (dispatch: Dispatch<any>) => {
829 dispatch(loadLinkAccountPanel());
833 export const loadKeepServices = handleFirstTimeLoad(
834 async (dispatch: Dispatch<any>) => {
835 await dispatch(loadKeepServicesPanel());
839 export const loadUsers = handleFirstTimeLoad(
840 async (dispatch: Dispatch<any>) => {
841 await dispatch(loadUsersPanel());
842 dispatch(setUsersBreadcrumbs());
846 export const loadApiClientAuthorizations = handleFirstTimeLoad(
847 async (dispatch: Dispatch<any>) => {
848 await dispatch(loadApiClientAuthorizationsPanel());
852 export const loadGroupsPanel = handleFirstTimeLoad(
853 (dispatch: Dispatch<any>) => {
854 dispatch(setGroupsBreadcrumbs());
855 dispatch(groupPanelActions.loadGroupsPanel());
859 export const loadGroupDetailsPanel = (groupUuid: string) =>
860 handleFirstTimeLoad((dispatch: Dispatch<any>) => {
861 dispatch(setGroupDetailsBreadcrumbs(groupUuid));
862 dispatch(groupDetailsPanelActions.loadGroupDetailsPanel(groupUuid));
865 const finishLoadingProject =
866 (project: GroupContentsResource | string) =>
867 async (dispatch: Dispatch<any>) => {
868 const uuid = typeof project === 'string' ? project : project.uuid;
869 dispatch(openProjectPanel(uuid));
870 dispatch(loadDetailsPanel(uuid));
871 if (typeof project !== 'string') {
872 dispatch(updateResources([project]));
876 const loadGroupContentsResource = async (params: {
879 services: ServiceRepository;
881 const filters = new FilterBuilder()
882 .addEqual('uuid', params.uuid)
884 const { items } = await params.services.groupsService.contents(
892 const resource = items.shift();
893 let handler: GroupContentsHandler;
896 (resource.kind === ResourceKind.COLLECTION ||
897 resource.kind === ResourceKind.PROJECT) &&
899 ? groupContentsHandlers.TRASHED(resource)
900 : groupContentsHandlers.OWNED(resource);
902 const kind = extractUuidKind(params.uuid);
903 let resource: GroupContentsResource;
904 if (kind === ResourceKind.COLLECTION) {
905 resource = await params.services.collectionService.get(params.uuid);
906 } else if (kind === ResourceKind.PROJECT) {
907 resource = await params.services.projectService.get(params.uuid);
908 } else if (kind === ResourceKind.WORKFLOW) {
909 resource = await params.services.workflowService.get(params.uuid);
910 } else if (kind === ResourceKind.CONTAINER_REQUEST) {
911 resource = await params.services.containerRequestService.get(params.uuid);
913 throw new Error("loadGroupContentsResource unsupported kind " + kind)
915 handler = groupContentsHandlers.SHARED(resource);
919 typeof groupContentsHandlersRecord,
920 GroupContentsHandler,
923 ) => groupContentsHandlers.match(handler, cases);
926 const groupContentsHandlersRecord = {
927 TRASHED: ofType<GroupContentsResource>(),
928 SHARED: ofType<GroupContentsResource>(),
929 OWNED: ofType<GroupContentsResource>(),
932 const groupContentsHandlers = unionize(groupContentsHandlersRecord);
934 type GroupContentsHandler = UnionOf<typeof groupContentsHandlers>;