import { Resource, ResourceKind } from "./resource";
export interface CollectionResource extends Resource {
- kind: ResourceKind.Collection;
+ kind: ResourceKind.COLLECTION;
name: string;
description: string;
properties: any;
deleteAt: string;
isTrashed: boolean;
}
+
+export const getCollectionUrl = (uuid: string) => {
+ return `/collections/${uuid}`;
+};
import { GroupResource, GroupClass } from "./group";
export interface ProjectResource extends GroupResource {
- groupClass: GroupClass.Project;
+ groupClass: GroupClass.PROJECT;
}
+
+export const getProjectUrl = (uuid: string) => {
+ return `/projects/${uuid}`;
+};
import { AuthService } from "./auth-service/auth-service";
import { GroupsService } from "./groups-service/groups-service";
- import { serverApi } from "../common/api/server-api";
+ import { authClient, apiClient } from "../common/api/server-api";
import { ProjectService } from "./project-service/project-service";
import { LinkService } from "./link-service/link-service";
import { FavoriteService } from "./favorite-service/favorite-service";
- export const authService = new AuthService(serverApi);
- export const groupsService = new GroupsService(serverApi);
- export const projectService = new ProjectService(serverApi);
- export const linkService = new LinkService(serverApi);
- export const favoriteService = new FavoriteService(linkService, groupsService);
+ export const authService = new AuthService(authClient, apiClient);
+ export const groupsService = new GroupsService(apiClient);
+ export const projectService = new ProjectService(apiClient);
+ export const linkService = new LinkService(apiClient);
-export const favoriteService = new FavoriteService(linkService, groupsService);
++export const favoriteService = new FavoriteService(linkService, groupsService);
--- /dev/null
- import { serverApi } from "../../common/api/server-api";
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { unionize, ofType, UnionOf } from "unionize";
+import { CommonResourceService } from "../../common/api/common-resource-service";
++import { apiClient } from "../../common/api/server-api";
+import { Dispatch } from "redux";
- return new CommonResourceService(serverApi, "collections")
+import { ResourceKind } from "../../models/resource";
+import { CollectionResource } from "../../models/collection";
+
+export const collectionPanelActions = unionize({
+ LOAD_COLLECTION: ofType<{ uuid: string, kind: ResourceKind }>(),
+ LOAD_COLLECTION_SUCCESS: ofType<{ item: CollectionResource }>(),
+}, { tag: 'type', value: 'payload' });
+
+export type CollectionPanelAction = UnionOf<typeof collectionPanelActions>;
+
+export const loadCollection = (uuid: string, kind: ResourceKind) =>
+ (dispatch: Dispatch) => {
+ dispatch(collectionPanelActions.LOAD_COLLECTION({ uuid, kind }));
++ return new CommonResourceService(apiClient, "collections")
+ .get(uuid)
+ .then(item => {
+ dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: item as CollectionResource }));
+ });
+ };
+
+
+
import { PROJECT_PANEL_ID } from "../../views/project-panel/project-panel";
import { RootState } from "../store";
import { Resource, ResourceKind } from "../../models/resource";
+import { getCollectionUrl } from "../../models/collection";
+import { getProjectUrl } from "../../models/project";
export const getResourceUrl = <T extends Resource>(resource: T): string => {
switch (resource.kind) {
- case ResourceKind.Project: return getProjectUrl(resource.uuid);
- case ResourceKind.Collection: return getCollectionUrl(resource.uuid);
- case ResourceKind.PROJECT: return `/projects/${resource.uuid}`;
- case ResourceKind.COLLECTION: return `/collections/${resource.uuid}`;
++ case ResourceKind.PROJECT: return getProjectUrl(resource.uuid);
++ case ResourceKind.COLLECTION: return getCollectionUrl(resource.uuid);
default: return resource.href;
}
};
if (treeItem) {
- if (itemMode === ItemMode.OPEN || itemMode === ItemMode.BOTH) {
- dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN(treeItem.data.uuid));
- }
-
const resourceUrl = getResourceUrl(treeItem.data);
if (itemMode === ItemMode.ACTIVE || itemMode === ItemMode.BOTH) {
dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_ACTIVE(treeItem.data.uuid));
}
- const promise = treeItem.status === TreeItemStatus.Loaded
+ const promise = treeItem.status === TreeItemStatus.LOADED
? Promise.resolve()
: dispatch<any>(getProjectList(itemId));
promise
.then(() => dispatch<any>(() => {
+ if (itemMode === ItemMode.OPEN || itemMode === ItemMode.BOTH) {
+ dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN(treeItem.data.uuid));
+ }
dispatch(dataExplorerActions.RESET_PAGINATION({id: PROJECT_PANEL_ID}));
dispatch(dataExplorerActions.REQUEST_ITEMS({id: PROJECT_PANEL_ID}));
}));
{renderIcon(item)}
</Grid>
<Grid item>
- <Typography color="primary">
+ <Typography color="default">
{item.name}
</Typography>
</Grid>
const renderIcon = (item: ProjectPanelItem) => {
switch (item.kind) {
- case ResourceKind.Project:
+ case ResourceKind.PROJECT:
return <ProjectIcon />;
- case ResourceKind.Collection:
+ case ResourceKind.COLLECTION:
return <CollectionIcon />;
- case ResourceKind.Process:
+ case ResourceKind.PROCESS:
return <ProcessIcon />;
default:
return <DefaultIcon />;
{
name: ProjectPanelColumnNames.NAME,
selected: true,
- sortDirection: SortDirection.Asc,
+ sortDirection: SortDirection.ASC,
render: renderName,
width: "450px"
},
selected: true,
filters: [
{
- name: ContainerRequestState.Committed,
+ name: ContainerRequestState.COMMITTED,
selected: true,
- type: ContainerRequestState.Committed
+ type: ContainerRequestState.COMMITTED
},
{
- name: ContainerRequestState.Final,
+ name: ContainerRequestState.FINAL,
selected: true,
- type: ContainerRequestState.Final
+ type: ContainerRequestState.FINAL
},
{
- name: ContainerRequestState.Uncommitted,
+ name: ContainerRequestState.UNCOMMITTED,
selected: true,
- type: ContainerRequestState.Uncommitted
+ type: ContainerRequestState.UNCOMMITTED
}
],
render: renderStatus,
selected: true,
filters: [
{
- name: resourceLabel(ResourceKind.Collection),
+ name: resourceLabel(ResourceKind.COLLECTION),
selected: true,
- type: ResourceKind.Collection
+ type: ResourceKind.COLLECTION
},
{
- name: resourceLabel(ResourceKind.Process),
+ name: resourceLabel(ResourceKind.PROCESS),
selected: true,
- type: ResourceKind.Process
+ type: ResourceKind.PROCESS
},
{
- name: resourceLabel(ResourceKind.Project),
+ name: resourceLabel(ResourceKind.PROJECT),
selected: true,
- type: ResourceKind.Project
+ type: ResourceKind.PROJECT
}
],
render: item => renderType(item.kind),
{
name: ProjectPanelColumnNames.LAST_MODIFIED,
selected: true,
- sortDirection: SortDirection.None,
+ sortDirection: SortDirection.NONE,
render: item => renderDate(item.lastModified),
width: "150px"
}
import { detailsPanelActions, loadDetails } from "../../store/details-panel/details-panel-action";
import { contextMenuActions } from "../../store/context-menu/context-menu-actions";
-import { sidePanelData, SidePanelIdentifiers } from '../../store/side-panel/side-panel-reducer';
+import { SidePanelIdentifiers } from '../../store/side-panel/side-panel-reducer';
import { ProjectResource } from '../../models/project';
import { ResourceKind } from '../../models/resource';
import { ContextMenu, ContextMenuKind } from "../../views-components/context-menu/context-menu";
import { CurrentTokenDialog } from '../../views-components/current-token-dialog/current-token-dialog';
import { dataExplorerActions } from '../../store/data-explorer/data-explorer-action';
import { Snackbar } from '../../views-components/snackbar/snackbar';
+import { CollectionPanel } from '../collection-panel/collection-panel';
+import { loadCollection } from '../../store/collection-panel/collection-panel-action';
+import { getCollectionUrl } from '../../models/collection';
const drawerWidth = 240;
const appBarHeight = 100;
})}
toggleActive={itemId => {
this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE));
- this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
- this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects));
+ this.props.dispatch<any>(loadDetails(itemId, ResourceKind.PROJECT));
+ this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
}} />
</SidePanel>
</Drawer>}
<Switch>
<Route path="/projects/:id" render={this.renderProjectPanel} />
<Route path="/favorites" render={this.renderFavoritePanel} />
+ <Route path="/collections/:id" render={this.renderCollectionPanel} />
</Switch>
</div>
{user && <DetailsPanel />}
);
}
- onItemRouteChange={(collectionId) => this.props.dispatch<any>(loadCollection(collectionId, ResourceKind.Collection))}
+ renderCollectionPanel = (props: RouteComponentProps<{ id: string }>) => <CollectionPanel
++ onItemRouteChange={(collectionId) => this.props.dispatch<any>(loadCollection(collectionId, ResourceKind.COLLECTION))}
+ onContextMenu={(event, item) => {
+ this.openContextMenu(event, {
+ uuid: item.uuid,
+ name: item.name,
+ kind: ContextMenuKind.COLLECTION
+ });
+ }}
+ {...props} />
+
renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => <ProjectPanel
onItemRouteChange={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
onContextMenu={(event, item) => {
- const kind = item.kind === ResourceKind.Project ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
++
+ const kind = item.kind === ResourceKind.PROJECT ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
this.openContextMenu(event, {
uuid: item.uuid,
name: item.name,
this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
}}
onItemDoubleClick={item => {
- this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
- this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.PROJECT));
+ switch (item.kind) {
- case ResourceKind.Collection:
++ case ResourceKind.COLLECTION:
+ this.props.dispatch<any>(loadCollection(item.uuid, item.kind as ResourceKind));
+ this.props.dispatch(push(getCollectionUrl(item.uuid)));
+ default:
+ this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
+ this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
+ }
++
}}
{...props} />
renderFavoritePanel = (props: RouteComponentProps<{ id: string }>) => <FavoritePanel
onItemRouteChange={() => this.props.dispatch<any>(dataExplorerActions.REQUEST_ITEMS({ id: FAVORITE_PANEL_ID }))}
onContextMenu={(event, item) => {
- const kind = item.kind === ResourceKind.Project ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
+ const kind = item.kind === ResourceKind.PROJECT ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
this.openContextMenu(event, {
uuid: item.uuid,
name: item.name,
this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
}}
onItemDoubleClick={item => {
- this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.PROJECT));
- this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
- this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
+ switch (item.kind) {
- case ResourceKind.Collection:
++ case ResourceKind.COLLECTION:
+ this.props.dispatch<any>(loadCollection(item.uuid, item.kind as ResourceKind));
+ this.props.dispatch(push(getCollectionUrl(item.uuid)));
+ default:
- this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.Project));
++ this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.PROJECT));
+ this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
- this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects));
++ this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
+ }
++
}}
{...props} />
mainAppBarActions: MainAppBarActionProps = {
onBreadcrumbClick: ({ itemId }: NavBreadcrumb) => {
this.props.dispatch<any>(setProjectItem(itemId, ItemMode.BOTH));
- this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
+ this.props.dispatch<any>(loadDetails(itemId, ResourceKind.PROJECT));
},
onSearch: searchText => {
this.setState({ searchText });