From: Janicki Artur Date: Mon, 30 Jul 2018 11:28:09 +0000 (+0200) Subject: Merge branch 'master' into 13853-collection-view-info-card X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/7ae86efd9905582df4191910528c3803a68ba81b?hp=3ee31ce16470660d90fb870e048c2de9fcde6e47 Merge branch 'master' into 13853-collection-view-info-card refs #13853 Arvados-DCO-1.1-Signed-off-by: Janicki Artur --- diff --git a/.env b/.env index a523865a6a..ed397c5cc0 100644 --- a/.env +++ b/.env @@ -3,4 +3,5 @@ # SPDX-License-Identifier: AGPL-3.0 REACT_APP_ARVADOS_CONFIG_URL=/config.json -REACT_APP_ARVADOS_API_HOST=https://qr1hi.arvadosapi.com \ No newline at end of file +REACT_APP_ARVADOS_API_HOST=qr1hi.arvadosapi.com +HTTPS=true \ No newline at end of file diff --git a/src/common/api/server-api.ts b/src/common/api/server-api.ts index 5beecd48ee..bcd2f65985 100644 --- a/src/common/api/server-api.ts +++ b/src/common/api/server-api.ts @@ -6,19 +6,24 @@ import Axios, { AxiosInstance } from "axios"; export const API_HOST = process.env.REACT_APP_ARVADOS_API_HOST; -export const serverApi: AxiosInstance = Axios.create({ - baseURL: API_HOST + '/arvados/v1' -}); +export const authClient: AxiosInstance = Axios.create(); +export const apiClient: AxiosInstance = Axios.create(); export function setServerApiAuthorizationHeader(token: string) { - serverApi.defaults.headers.common = { - 'Authorization': `OAuth2 ${token}` - };} + [authClient, apiClient].forEach(client => { + client.defaults.headers.common = { + Authorization: `OAuth2 ${token}` + }; + }); +} export function removeServerApiAuthorizationHeader() { - delete serverApi.defaults.headers.common.Authorization; + [authClient, apiClient].forEach(client => { + delete client.defaults.headers.common.Authorization; + }); } export const setBaseUrl = (url: string) => { - serverApi.defaults.baseURL = url + "/arvados/v1"; + authClient.defaults.baseURL = url; + apiClient.defaults.baseURL = url + "/arvados/v1"; }; diff --git a/src/common/config.ts b/src/common/config.ts index 4b4a52a3ea..775b11452a 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -10,14 +10,21 @@ export interface Config { API_HOST: string; } -const defaultConfig: Config = { - API_HOST: process.env.REACT_APP_ARVADOS_API_HOST || "" -}; - export const fetchConfig = () => { return Axios .get(CONFIG_URL + "?nocache=" + (new Date()).getTime()) .then(response => response.data) - .catch(() => Promise.resolve(defaultConfig)); + .catch(() => Promise.resolve(getDefaultConfig())) + .then(mapConfig); }; +const mapConfig = (config: Config): Config => ({ + ...config, + API_HOST: addProtocol(config.API_HOST) +}); + +const getDefaultConfig = (): Config => ({ + API_HOST: process.env.REACT_APP_ARVADOS_API_HOST || "" +}); + +const addProtocol = (url: string) => `${window.location.protocol}//${url}`; diff --git a/src/common/labels.ts b/src/common/labels.ts index 9567ce1493..ed3a43d142 100644 --- a/src/common/labels.ts +++ b/src/common/labels.ts @@ -6,11 +6,11 @@ import { ResourceKind } from "../models/resource"; export const resourceLabel = (type: string) => { switch (type) { - case ResourceKind.Collection: + case ResourceKind.COLLECTION: return "Data collection"; - case ResourceKind.Project: + case ResourceKind.PROJECT: return "Project"; - case ResourceKind.Process: + case ResourceKind.PROCESS: return "Process"; default: return "Unknown"; diff --git a/src/components/data-table/data-column.ts b/src/components/data-table/data-column.ts index 06744c3a21..96ef952493 100644 --- a/src/components/data-table/data-column.ts +++ b/src/components/data-table/data-column.ts @@ -17,9 +17,9 @@ export interface DataColumn(column: DataColumn) => { @@ -28,12 +28,12 @@ export const isColumnConfigurable = (column: DataColumn) => { export const toggleSortDirection = (column: DataColumn): DataColumn => { return column.sortDirection - ? column.sortDirection === SortDirection.Asc - ? { ...column, sortDirection: SortDirection.Desc } - : { ...column, sortDirection: SortDirection.Asc } + ? column.sortDirection === SortDirection.ASC + ? { ...column, sortDirection: SortDirection.DESC } + : { ...column, sortDirection: SortDirection.ASC } : column; }; export const resetSortDirection = (column: DataColumn): DataColumn => { - return column.sortDirection ? { ...column, sortDirection: SortDirection.None } : column; + return column.sortDirection ? { ...column, sortDirection: SortDirection.NONE } : column; }; diff --git a/src/components/data-table/data-table.test.tsx b/src/components/data-table/data-table.test.tsx index 7e460c892f..99ed2daffb 100644 --- a/src/components/data-table/data-table.test.tsx +++ b/src/components/data-table/data-table.test.tsx @@ -130,7 +130,7 @@ describe("", () => { it("passes sorting props to ", () => { const columns: DataColumns = [{ name: "Column 1", - sortDirection: SortDirection.Asc, + sortDirection: SortDirection.ASC, selected: true, render: (item) => {item} }]; @@ -151,7 +151,7 @@ describe("", () => { it("passes filter props to ", () => { const columns: DataColumns = [{ name: "Column 1", - sortDirection: SortDirection.Asc, + sortDirection: SortDirection.ASC, selected: true, filters: [{ name: "Filter 1", selected: true }], render: (item) => {item} diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx index 829bc84ebe..f92f97b72f 100644 --- a/src/components/data-table/data-table.tsx +++ b/src/components/data-table/data-table.tsx @@ -74,8 +74,8 @@ export const DataTable = withStyles(styles)( : sortDirection ? onSortToggle && onSortToggle(column)}> diff --git a/src/components/tree/tree.tsx b/src/components/tree/tree.tsx index 799e821704..20526005a1 100644 --- a/src/components/tree/tree.tsx +++ b/src/components/tree/tree.tsx @@ -44,9 +44,9 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ }); export enum TreeItemStatus { - Initial, - Pending, - Loaded + INITIAL, + PENDING, + LOADED } export interface TreeItem { @@ -55,7 +55,6 @@ export interface TreeItem { open: boolean; active: boolean; status: TreeItemStatus; - toggled?: boolean; items?: Array>; } @@ -80,12 +79,12 @@ export const Tree = withStyles(styles)( toggleItemActive(it.id, it.status)} onContextMenu={this.handleRowContextMenu(it)}> - {it.status === TreeItemStatus.Pending ? + {it.status === TreeItemStatus.PENDING ? : null} this.props.toggleItemOpen(it.id, it.status)} className={toggableIconContainer}> - {it.toggled && it.items && it.items.length === 0 ? : } + {it.status !== TreeItemStatus.INITIAL && it.items && it.items.length === 0 ? : } {render(it, level)} diff --git a/src/models/collection.ts b/src/models/collection.ts index 8ab319991c..0e96f7fd3d 100644 --- a/src/models/collection.ts +++ b/src/models/collection.ts @@ -5,7 +5,7 @@ import { Resource, ResourceKind } from "./resource"; export interface CollectionResource extends Resource { - kind: ResourceKind.Collection; + kind: ResourceKind.COLLECTION; name: string; description: string; properties: any; diff --git a/src/models/container-request.ts b/src/models/container-request.ts index 4e5481570e..d1bcc36c81 100644 --- a/src/models/container-request.ts +++ b/src/models/container-request.ts @@ -5,13 +5,13 @@ import { Resource, ResourceKind } from "./resource"; export enum ContainerRequestState { - Uncommitted = "Uncommitted", - Committed = "Committed", - Final = "Final" + UNCOMMITTED = "Uncommitted", + COMMITTED = "Committed", + FINAL = "Final" } export interface ContainerRequestResource extends Resource { - kind: ResourceKind.ContainerRequest; + kind: ResourceKind.CONTAINER_REQUEST; name: string; description: string; properties: any; diff --git a/src/models/group.ts b/src/models/group.ts index d8efae2671..5e8d7a1e0b 100644 --- a/src/models/group.ts +++ b/src/models/group.ts @@ -5,7 +5,7 @@ import { Resource, ResourceKind } from "./resource"; export interface GroupResource extends Resource { - kind: ResourceKind.Group; + kind: ResourceKind.GROUP; name: string; groupClass: GroupClass | null; description: string; @@ -17,5 +17,5 @@ export interface GroupResource extends Resource { } export enum GroupClass { - Project = "project" + PROJECT = "project" } \ No newline at end of file diff --git a/src/models/project.ts b/src/models/project.ts index d3626d3be9..b919450774 100644 --- a/src/models/project.ts +++ b/src/models/project.ts @@ -5,7 +5,7 @@ import { GroupResource, GroupClass } from "./group"; export interface ProjectResource extends GroupResource { - groupClass: GroupClass.Project; + groupClass: GroupClass.PROJECT; } export const getProjectUrl = (uuid: string) => { diff --git a/src/models/resource.ts b/src/models/resource.ts index 2d72fbcd82..6a76b07045 100644 --- a/src/models/resource.ts +++ b/src/models/resource.ts @@ -15,10 +15,10 @@ export interface Resource { } export enum ResourceKind { - Collection = "arvados#collection", - ContainerRequest = "arvados#containerRequest", - Group = "arvados#group", - Process = "arvados#containerRequest", - Project = "arvados#group", - Workflow = "arvados#workflow" + COLLECTION = "arvados#collection", + CONTAINER_REQUEST = "arvados#containerRequest", + GROUP = "arvados#group", + PROCESS = "arvados#containerRequest", + PROJECT = "arvados#group", + WORKFLOW = "arvados#workflow" } diff --git a/src/models/test-utils.ts b/src/models/test-utils.ts index 3f49dba6a3..6723430c34 100644 --- a/src/models/test-utils.ts +++ b/src/models/test-utils.ts @@ -14,7 +14,7 @@ export const mockGroupResource = (data: Partial = {}): GroupResou groupClass: null, href: "", isTrashed: false, - kind: ResourceKind.Group, + kind: ResourceKind.GROUP, modifiedAt: "", modifiedByClientUuid: "", modifiedByUserUuid: "", @@ -28,7 +28,7 @@ export const mockGroupResource = (data: Partial = {}): GroupResou }); export const mockProjectResource = (data: Partial = {}): ProjectResource => - mockGroupResource({ ...data, groupClass: GroupClass.Project }) as ProjectResource; + mockGroupResource({ ...data, groupClass: GroupClass.PROJECT }) as ProjectResource; export const mockCommonResource = (data: Partial): Resource => ({ createdAt: "", diff --git a/src/models/workflow.ts b/src/models/workflow.ts index e0a5df4381..d644b79090 100644 --- a/src/models/workflow.ts +++ b/src/models/workflow.ts @@ -5,7 +5,7 @@ import { Resource, ResourceKind } from "./resource"; export interface WorkflowResource extends Resource { - kind: ResourceKind.Workflow; + kind: ResourceKind.WORKFLOW; name: string; description: string; definition: string; diff --git a/src/services/auth-service/auth-service.ts b/src/services/auth-service/auth-service.ts index 1879e6a0ab..551d435f25 100644 --- a/src/services/auth-service/auth-service.ts +++ b/src/services/auth-service/auth-service.ts @@ -24,7 +24,9 @@ export interface UserDetailsResponse { export class AuthService { - constructor(protected serverApi: AxiosInstance) { } + constructor( + protected authClient: AxiosInstance, + protected apiClient: AxiosInstance) { } public saveApiToken(token: string) { localStorage.setItem(API_TOKEN_KEY, token); @@ -76,16 +78,16 @@ export class AuthService { public login() { const currentUrl = `${window.location.protocol}//${window.location.host}/token`; - window.location.assign(`${API_HOST}/login?return_to=${currentUrl}`); + window.location.assign(`${this.authClient.defaults.baseURL || ""}/login?return_to=${currentUrl}`); } public logout() { const currentUrl = `${window.location.protocol}//${window.location.host}`; - window.location.assign(`${API_HOST}/logout?return_to=${currentUrl}`); + window.location.assign(`${this.authClient.defaults.baseURL || ""}/logout?return_to=${currentUrl}`); } public getUserDetails = (): Promise => { - return this.serverApi + return this.apiClient .get('/users/current') .then(resp => ({ email: resp.data.email, diff --git a/src/services/favorite-service/favorite-order-builder.ts b/src/services/favorite-service/favorite-order-builder.ts index 33214a0dc8..0d9a75eb48 100644 --- a/src/services/favorite-service/favorite-order-builder.ts +++ b/src/services/favorite-service/favorite-order-builder.ts @@ -22,18 +22,18 @@ export class FavoriteOrderBuilder { addAsc(attribute: "name") { const linkOrder = this.linkOrder.addAsc(attribute); const contentOrder = this.contentOrder - .concat(OrderBuilder.create(GroupContentsResourcePrefix.Collection).addAsc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.Process).addAsc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.Project).addAsc(attribute)); + .concat(OrderBuilder.create(GroupContentsResourcePrefix.COLLECTION).addAsc(attribute)) + .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROCESS).addAsc(attribute)) + .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROJECT).addAsc(attribute)); return FavoriteOrderBuilder.create(linkOrder, contentOrder); } addDesc(attribute: "name") { const linkOrder = this.linkOrder.addDesc(attribute); const contentOrder = this.contentOrder - .concat(OrderBuilder.create(GroupContentsResourcePrefix.Collection).addDesc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.Process).addDesc(attribute)) - .concat(OrderBuilder.create(GroupContentsResourcePrefix.Project).addDesc(attribute)); + .concat(OrderBuilder.create(GroupContentsResourcePrefix.COLLECTION).addDesc(attribute)) + .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROCESS).addDesc(attribute)) + .concat(OrderBuilder.create(GroupContentsResourcePrefix.PROJECT).addDesc(attribute)); return FavoriteOrderBuilder.create(linkOrder, contentOrder); } diff --git a/src/services/groups-service/groups-service.ts b/src/services/groups-service/groups-service.ts index dfaf11d6e8..a0f27a4abb 100644 --- a/src/services/groups-service/groups-service.ts +++ b/src/services/groups-service/groups-service.ts @@ -47,7 +47,7 @@ export class GroupsService extends Comm } export enum GroupContentsResourcePrefix { - Collection = "collections", - Project = "groups", - Process = "container_requests" + COLLECTION = "collections", + PROJECT = "groups", + PROCESS = "container_requests" } diff --git a/src/services/project-service/project-service.ts b/src/services/project-service/project-service.ts index 7b1640ee02..31a2ddd29c 100644 --- a/src/services/project-service/project-service.ts +++ b/src/services/project-service/project-service.ts @@ -11,7 +11,7 @@ import { FilterBuilder } from "../../common/api/filter-builder"; export class ProjectService extends GroupsService { create(data: Partial) { - const projectData = { ...data, groupClass: GroupClass.Project }; + const projectData = { ...data, groupClass: GroupClass.PROJECT }; return super.create(projectData); } @@ -30,6 +30,6 @@ export class ProjectService extends GroupsService { : FilterBuilder.create()) .concat(FilterBuilder .create() - .addEqual("groupClass", GroupClass.Project)); + .addEqual("groupClass", GroupClass.PROJECT)); } } diff --git a/src/services/services.ts b/src/services/services.ts index f0afd76fc8..e0d15cc40a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4,13 +4,13 @@ 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); \ No newline at end of file diff --git a/src/store/auth/auth-reducer.test.ts b/src/store/auth/auth-reducer.test.ts index ea08e58983..778b500d36 100644 --- a/src/store/auth/auth-reducer.test.ts +++ b/src/store/auth/auth-reducer.test.ts @@ -12,7 +12,6 @@ import { USER_OWNER_UUID_KEY, USER_UUID_KEY } from "../../services/auth-service/auth-service"; -import { API_HOST } from "../../common/api/server-api"; import 'jest-localstorage-mock'; @@ -96,7 +95,7 @@ describe('auth-reducer', () => { window.location.assign = jest.fn(); authReducer(initialState, authActions.LOGIN()); expect(window.location.assign).toBeCalledWith( - `${API_HOST}/login?return_to=${window.location.protocol}//${window.location.host}/token` + `/login?return_to=${window.location.protocol}//${window.location.host}/token` ); }); @@ -105,7 +104,7 @@ describe('auth-reducer', () => { window.location.assign = jest.fn(); authReducer(initialState, authActions.LOGOUT()); expect(window.location.assign).toBeCalledWith( - `${API_HOST}/logout?return_to=${location.protocol}//${location.host}` + `/logout?return_to=${location.protocol}//${location.host}` ); }); }); diff --git a/src/store/collection-panel/collection-panel-action.ts b/src/store/collection-panel/collection-panel-action.ts index c2684e055b..3c66016570 100644 --- a/src/store/collection-panel/collection-panel-action.ts +++ b/src/store/collection-panel/collection-panel-action.ts @@ -4,8 +4,8 @@ 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"; -import { serverApi } from "../../common/api/server-api"; import { ResourceKind } from "../../models/resource"; import { CollectionResource } from "../../models/collection"; @@ -19,7 +19,7 @@ export type CollectionPanelAction = UnionOf; export const loadCollection = (uuid: string, kind: ResourceKind) => (dispatch: Dispatch) => { dispatch(collectionPanelActions.LOAD_COLLECTION({ uuid, kind })); - return new CommonResourceService(serverApi, "collections") + return new CommonResourceService(apiClient, "collections") .get(uuid) .then(item => { dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: item as CollectionResource })); diff --git a/src/store/data-explorer/data-explorer-reducer.test.tsx b/src/store/data-explorer/data-explorer-reducer.test.tsx index 5b9f68ffbe..c54a86af4a 100644 --- a/src/store/data-explorer/data-explorer-reducer.test.tsx +++ b/src/store/data-explorer/data-explorer-reducer.test.tsx @@ -25,12 +25,12 @@ describe('data-explorer-reducer', () => { name: "Column 1", render: jest.fn(), selected: true, - sortDirection: SortDirection.Asc + sortDirection: SortDirection.ASC }, { name: "Column 2", render: jest.fn(), selected: true, - sortDirection: SortDirection.None, + sortDirection: SortDirection.NONE, }]; const state = dataExplorerReducer({ "Data explorer": { ...initialDataExplorer, columns } }, dataExplorerActions.TOGGLE_SORT({ id: "Data explorer", columnName: "Column 2" })); diff --git a/src/store/details-panel/details-panel-action.ts b/src/store/details-panel/details-panel-action.ts index ba330f2e41..03212b9fc9 100644 --- a/src/store/details-panel/details-panel-action.ts +++ b/src/store/details-panel/details-panel-action.ts @@ -5,7 +5,7 @@ import { unionize, ofType, UnionOf } from "unionize"; import { CommonResourceService } from "../../common/api/common-resource-service"; import { Dispatch } from "redux"; -import { serverApi } from "../../common/api/server-api"; +import { apiClient } from "../../common/api/server-api"; import { Resource, ResourceKind } from "../../models/resource"; export const detailsPanelActions = unionize({ @@ -28,12 +28,12 @@ export const loadDetails = (uuid: string, kind: ResourceKind) => const getService = (kind: ResourceKind) => { switch (kind) { - case ResourceKind.Project: - return new CommonResourceService(serverApi, "groups"); - case ResourceKind.Collection: - return new CommonResourceService(serverApi, "collections"); + case ResourceKind.PROJECT: + return new CommonResourceService(apiClient, "groups"); + case ResourceKind.COLLECTION: + return new CommonResourceService(apiClient, "collections"); default: - return new CommonResourceService(serverApi, ""); + return new CommonResourceService(apiClient, ""); } }; diff --git a/src/store/favorite-panel/favorite-panel-middleware.ts b/src/store/favorite-panel/favorite-panel-middleware.ts index 0ce13b461c..548a117814 100644 --- a/src/store/favorite-panel/favorite-panel-middleware.ts +++ b/src/store/favorite-panel/favorite-panel-middleware.ts @@ -67,7 +67,7 @@ export const favoritePanelMiddleware: Middleware = store => next => { limit: dataExplorer.rowsPerPage, offset: dataExplorer.page * dataExplorer.rowsPerPage, order: sortColumn!.name === FavoritePanelColumnNames.NAME - ? sortColumn!.sortDirection === SortDirection.Asc + ? sortColumn!.sortDirection === SortDirection.ASC ? order.addDesc("name") : order.addAsc("name") : order, @@ -104,14 +104,14 @@ export const favoritePanelMiddleware: Middleware = store => next => { const getOrder = (direction: SortDirection) => { const order = OrderBuilder.create(); const addRule = (builder: OrderBuilder, direction: SortDirection) => - direction === SortDirection.Asc + direction === SortDirection.ASC ? builder.addAsc("name") : builder.addDesc("name"); return [ - OrderBuilder.create(GroupContentsResourcePrefix.Collection), - OrderBuilder.create(GroupContentsResourcePrefix.Process), - OrderBuilder.create(GroupContentsResourcePrefix.Project) + OrderBuilder.create(GroupContentsResourcePrefix.COLLECTION), + OrderBuilder.create(GroupContentsResourcePrefix.PROCESS), + OrderBuilder.create(GroupContentsResourcePrefix.PROJECT) ].reduce((acc, b) => acc.concat(addRule(b, direction)), addRule(OrderBuilder.create(), direction)); }; diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts index d65685d296..f8687ed754 100644 --- a/src/store/navigation/navigation-action.ts +++ b/src/store/navigation/navigation-action.ts @@ -16,8 +16,8 @@ import { getProjectUrl } from "../../models/project"; export const getResourceUrl = (resource: T): string => { switch (resource.kind) { - case ResourceKind.Project: return getProjectUrl(resource.uuid); - case ResourceKind.Collection: return getCollectionUrl(resource.uuid); + case ResourceKind.PROJECT: return getProjectUrl(resource.uuid); + case ResourceKind.COLLECTION: return getCollectionUrl(resource.uuid); default: return resource.href; } }; @@ -35,10 +35,6 @@ export const setProjectItem = (itemId: string, itemMode: ItemMode) => 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) { @@ -48,12 +44,15 @@ export const setProjectItem = (itemId: string, itemMode: ItemMode) => 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(getProjectList(itemId)); promise .then(() => dispatch(() => { + 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})); })); diff --git a/src/store/project-panel/project-panel-middleware.ts b/src/store/project-panel/project-panel-middleware.ts index faa22f0b85..b7ab03ceca 100644 --- a/src/store/project-panel/project-panel-middleware.ts +++ b/src/store/project-panel/project-panel-middleware.ts @@ -55,7 +55,7 @@ export const projectPanelMiddleware: Middleware = store => next => { const typeFilters = getColumnFilters(columns, ProjectPanelColumnNames.TYPE); const statusFilters = getColumnFilters(columns, ProjectPanelColumnNames.STATUS); const sortColumn = dataExplorer.columns.find(({ sortDirection }) => Boolean(sortDirection && sortDirection !== "none")); - const sortDirection = sortColumn && sortColumn.sortDirection === SortDirection.Asc ? SortDirection.Asc : SortDirection.Desc; + const sortDirection = sortColumn && sortColumn.sortDirection === SortDirection.ASC ? SortDirection.ASC : SortDirection.DESC; if (typeFilters.length > 0) { groupsService .contents(state.projects.currentItemId, { @@ -72,7 +72,7 @@ export const projectPanelMiddleware: Middleware = store => next => { .create() .addIsA("uuid", typeFilters.map(f => f.type))) .concat(FilterBuilder - .create(GroupContentsResourcePrefix.Process) + .create(GroupContentsResourcePrefix.PROCESS) .addIn("state", statusFilters.map(f => f.type))) .concat(getSearchFilter(dataExplorer.searchValue)) }) @@ -108,20 +108,20 @@ const getColumnFilters = (columns: DataColumns [ - OrderBuilder.create(GroupContentsResourcePrefix.Collection), - OrderBuilder.create(GroupContentsResourcePrefix.Process), - OrderBuilder.create(GroupContentsResourcePrefix.Project) + OrderBuilder.create(GroupContentsResourcePrefix.COLLECTION), + OrderBuilder.create(GroupContentsResourcePrefix.PROCESS), + OrderBuilder.create(GroupContentsResourcePrefix.PROJECT) ].reduce((acc, b) => - acc.concat(direction === SortDirection.Asc + acc.concat(direction === SortDirection.ASC ? b.addAsc(attribute) : b.addDesc(attribute)), OrderBuilder.create()); const getSearchFilter = (searchValue: string) => searchValue ? [ - FilterBuilder.create(GroupContentsResourcePrefix.Collection), - FilterBuilder.create(GroupContentsResourcePrefix.Process), - FilterBuilder.create(GroupContentsResourcePrefix.Project)] + FilterBuilder.create(GroupContentsResourcePrefix.COLLECTION), + FilterBuilder.create(GroupContentsResourcePrefix.PROCESS), + FilterBuilder.create(GroupContentsResourcePrefix.PROJECT)] .reduce((acc, b) => acc.concat(b.addILike("name", searchValue)), FilterBuilder.create()) : FilterBuilder.create(); diff --git a/src/store/project/project-reducer.test.ts b/src/store/project/project-reducer.test.ts index c8eed87c71..0fc28960b6 100644 --- a/src/store/project/project-reducer.test.ts +++ b/src/store/project/project-reducer.test.ts @@ -28,7 +28,7 @@ describe('project-reducer', () => { id: "2", items: [], data: mockProjectResource({ uuid: "2" }), - status: 0 + status: TreeItemStatus.INITIAL } ], currentItemId: "", @@ -47,7 +47,7 @@ describe('project-reducer', () => { id: "1", open: true, active: true, - status: 1 + status: TreeItemStatus.PENDING }], currentItemId: "1", creator: { opened: false, pending: false, ownerUuid: "" }, @@ -58,7 +58,7 @@ describe('project-reducer', () => { id: "1", open: true, active: false, - status: 1 + status: TreeItemStatus.PENDING }], currentItemId: "", creator: { opened: false, pending: false, ownerUuid: "" }, @@ -75,7 +75,7 @@ describe('project-reducer', () => { id: "1", open: true, active: false, - status: 1 + status: TreeItemStatus.PENDING }], currentItemId: "1", creator: { opened: false, pending: false, ownerUuid: "" } @@ -86,8 +86,7 @@ describe('project-reducer', () => { id: "1", open: true, active: true, - status: 1, - toggled: true + status: TreeItemStatus.PENDING, }], currentItemId: "1", creator: { opened: false, pending: false, ownerUuid: "" }, @@ -105,8 +104,7 @@ describe('project-reducer', () => { id: "1", open: true, active: false, - status: 1, - toggled: false, + status: TreeItemStatus.PENDING, }], currentItemId: "1", creator: { opened: false, pending: false, ownerUuid: "" } @@ -117,8 +115,7 @@ describe('project-reducer', () => { id: "1", open: false, active: false, - status: 1, - toggled: true + status: TreeItemStatus.PENDING, }], currentItemId: "1", creator: { opened: false, pending: false, ownerUuid: "" }, @@ -136,7 +133,7 @@ describe("findTreeBranch", () => { active: false, data: "", open: false, - status: TreeItemStatus.Initial + status: TreeItemStatus.INITIAL }); it("should return an array that matches path to the given item", () => { diff --git a/src/store/project/project-reducer.ts b/src/store/project/project-reducer.ts index 94a451a865..45e0e19527 100644 --- a/src/store/project/project-reducer.ts +++ b/src/store/project/project-reducer.ts @@ -73,14 +73,14 @@ function updateProjectTree(tree: Array>, projects: Pro if (parentItemId) { treeItem = findTreeItem(tree, parentItemId); if (treeItem) { - treeItem.status = TreeItemStatus.Loaded; + treeItem.status = TreeItemStatus.LOADED; } } const items = projects.map(p => ({ id: p.uuid, open: false, active: false, - status: TreeItemStatus.Initial, + status: TreeItemStatus.INITIAL, data: p, items: [] } as TreeItem)); @@ -123,7 +123,7 @@ export const projectsReducer = (state: ProjectState = initialState, action: Proj const items = _.cloneDeep(state.items); const item = findTreeItem(items, itemId); if (item) { - item.status = TreeItemStatus.Pending; + item.status = TreeItemStatus.PENDING; state.items = items; } return { ...state, items }; @@ -139,7 +139,6 @@ export const projectsReducer = (state: ProjectState = initialState, action: Proj const items = _.cloneDeep(state.items); const item = findTreeItem(items, itemId); if (item) { - item.toggled = true; item.open = !item.open; } return { @@ -153,7 +152,6 @@ export const projectsReducer = (state: ProjectState = initialState, action: Proj resetTreeActivity(items); const item = findTreeItem(items, itemId); if (item) { - item.toggled = true; item.active = true; } return { diff --git a/src/store/side-panel/side-panel-reducer.ts b/src/store/side-panel/side-panel-reducer.ts index 263ecbdad0..9d56102b14 100644 --- a/src/store/side-panel/side-panel-reducer.ts +++ b/src/store/side-panel/side-panel-reducer.ts @@ -41,17 +41,17 @@ export const sidePanelReducer = (state: SidePanelState = sidePanelData, action: }; export enum SidePanelIdentifiers { - Projects = "Projects", - SharedWithMe = "SharedWithMe", - Workflows = "Workflows", - RecentOpen = "RecentOpen", - Favourites = "Favourites", - Trash = "Trash" + PROJECTS = "Projects", + SHARED_WITH_ME = "SharedWithMe", + WORKFLOWS = "Workflows", + RECENT_OPEN = "RecentOpen", + FAVORITES = "Favourites", + TRASH = "Trash" } export const sidePanelData = [ { - id: SidePanelIdentifiers.Projects, + id: SidePanelIdentifiers.PROJECTS, name: "Projects", icon: ProjectsIcon, open: false, @@ -60,25 +60,25 @@ export const sidePanelData = [ openAble: true }, { - id: SidePanelIdentifiers.SharedWithMe, + id: SidePanelIdentifiers.SHARED_WITH_ME, name: "Shared with me", icon: ShareMeIcon, active: false, }, { - id: SidePanelIdentifiers.Workflows, + id: SidePanelIdentifiers.WORKFLOWS, name: "Workflows", icon: WorkflowIcon, active: false, }, { - id: SidePanelIdentifiers.RecentOpen, + id: SidePanelIdentifiers.RECENT_OPEN, name: "Recent open", icon: RecentIcon, active: false, }, { - id: SidePanelIdentifiers.Favourites, + id: SidePanelIdentifiers.FAVORITES, name: "Favorites", icon: FavoriteIcon, active: false, @@ -89,7 +89,7 @@ export const sidePanelData = [ } }, { - id: SidePanelIdentifiers.Trash, + id: SidePanelIdentifiers.TRASH, name: "Trash", icon: TrashIcon, active: false, diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx index 288177663f..f0be4497ec 100644 --- a/src/views-components/details-panel/collection-details.tsx +++ b/src/views-components/details-panel/collection-details.tsx @@ -19,7 +19,7 @@ export class CollectionDetails extends DetailsData { getDetails() { return
- + diff --git a/src/views-components/details-panel/details-panel.tsx b/src/views-components/details-panel/details-panel.tsx index ea8f2e40f6..20d3843f77 100644 --- a/src/views-components/details-panel/details-panel.tsx +++ b/src/views-components/details-panel/details-panel.tsx @@ -55,11 +55,11 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ const getItem = (resource: DetailsResource): DetailsData => { const res = resource || { kind: undefined, name: 'Projects' }; switch (res.kind) { - case ResourceKind.Project: + case ResourceKind.PROJECT: return new ProjectDetails(res); - case ResourceKind.Collection: + case ResourceKind.COLLECTION: return new CollectionDetails(res); - case ResourceKind.Process: + case ResourceKind.PROCESS: return new ProcessDetails(res); default: return new EmptyDetails(res as EmptyResource); diff --git a/src/views-components/details-panel/process-details.tsx b/src/views-components/details-panel/process-details.tsx index 931ff7ed92..e195d05f34 100644 --- a/src/views-components/details-panel/process-details.tsx +++ b/src/views-components/details-panel/process-details.tsx @@ -19,7 +19,7 @@ export class ProcessDetails extends DetailsData { getDetails() { return
- + diff --git a/src/views-components/details-panel/project-details.tsx b/src/views-components/details-panel/project-details.tsx index 84b3706633..b46bdcdbe8 100644 --- a/src/views-components/details-panel/project-details.tsx +++ b/src/views-components/details-panel/project-details.tsx @@ -19,7 +19,7 @@ export class ProjectDetails extends DetailsData { getDetails() { return
- + {/* Missing attr */} diff --git a/src/views/favorite-panel/favorite-panel-item.ts b/src/views/favorite-panel/favorite-panel-item.ts index 28f7f882f3..da48298aa7 100644 --- a/src/views/favorite-panel/favorite-panel-item.ts +++ b/src/views/favorite-panel/favorite-panel-item.ts @@ -25,7 +25,7 @@ export function resourceToDataItem(r: GroupContentsResource): FavoritePanelItem url: "", owner: r.ownerUuid, lastModified: r.modifiedAt, - status: r.kind === ResourceKind.Process ? r.state : undefined + status: r.kind === ResourceKind.PROCESS ? r.state : undefined }; } diff --git a/src/views/favorite-panel/favorite-panel.tsx b/src/views/favorite-panel/favorite-panel.tsx index 8f49450517..36a3410763 100644 --- a/src/views/favorite-panel/favorite-panel.tsx +++ b/src/views/favorite-panel/favorite-panel.tsx @@ -52,11 +52,11 @@ const renderName = (item: FavoritePanelItem) => const renderIcon = (item: FavoritePanelItem) => { switch (item.kind) { - case ResourceKind.Project: + case ResourceKind.PROJECT: return ; - case ResourceKind.Collection: + case ResourceKind.COLLECTION: return ; - case ResourceKind.Process: + case ResourceKind.PROCESS: return ; default: return ; @@ -104,7 +104,7 @@ export const columns: DataColumns = [ { name: FavoritePanelColumnNames.NAME, selected: true, - sortDirection: SortDirection.Asc, + sortDirection: SortDirection.ASC, render: renderName, width: "450px" }, @@ -113,19 +113,19 @@ export const columns: DataColumns = [ 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, @@ -136,19 +136,19 @@ export const columns: DataColumns = [ 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), @@ -169,7 +169,7 @@ export const columns: DataColumns = [ { name: FavoritePanelColumnNames.LAST_MODIFIED, selected: true, - sortDirection: SortDirection.None, + sortDirection: SortDirection.NONE, render: item => renderDate(item.lastModified), width: "150px" } diff --git a/src/views/project-panel/project-panel-item.ts b/src/views/project-panel/project-panel-item.ts index 1d665a6601..d0609d6df7 100644 --- a/src/views/project-panel/project-panel-item.ts +++ b/src/views/project-panel/project-panel-item.ts @@ -25,7 +25,7 @@ export function resourceToDataItem(r: GroupContentsResource): ProjectPanelItem { url: "", owner: r.ownerUuid, lastModified: r.modifiedAt, - status: r.kind === ResourceKind.Process ? r.state : undefined + status: r.kind === ResourceKind.PROCESS ? r.state : undefined }; } diff --git a/src/views/project-panel/project-panel.tsx b/src/views/project-panel/project-panel.tsx index 2ddc1b05f7..81d84990a4 100644 --- a/src/views/project-panel/project-panel.tsx +++ b/src/views/project-panel/project-panel.tsx @@ -52,11 +52,11 @@ const renderName = (item: ProjectPanelItem) => const renderIcon = (item: ProjectPanelItem) => { switch (item.kind) { - case ResourceKind.Project: + case ResourceKind.PROJECT: return ; - case ResourceKind.Collection: + case ResourceKind.COLLECTION: return ; - case ResourceKind.Process: + case ResourceKind.PROCESS: return ; default: return ; @@ -104,7 +104,7 @@ export const columns: DataColumns = [ { name: ProjectPanelColumnNames.NAME, selected: true, - sortDirection: SortDirection.Asc, + sortDirection: SortDirection.ASC, render: renderName, width: "450px" }, @@ -113,19 +113,19 @@ export const columns: DataColumns = [ 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, @@ -136,19 +136,19 @@ export const columns: DataColumns = [ 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), @@ -169,7 +169,7 @@ export const columns: DataColumns = [ { name: ProjectPanelColumnNames.LAST_MODIFIED, selected: true, - sortDirection: SortDirection.None, + sortDirection: SortDirection.NONE, render: item => renderDate(item.lastModified), width: "150px" } diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx index 6c7f85d87f..e25244018c 100644 --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@ -205,8 +205,8 @@ export const Workbench = withStyles(styles)( })} toggleActive={itemId => { this.props.dispatch(setProjectItem(itemId, ItemMode.ACTIVE)); - this.props.dispatch(loadDetails(itemId, ResourceKind.Project)); - this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects)); + this.props.dispatch(loadDetails(itemId, ResourceKind.PROJECT)); + this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS)); }} /> } @@ -232,7 +232,7 @@ export const Workbench = withStyles(styles)( } renderCollectionPanel = (props: RouteComponentProps<{ id: string }>) => this.props.dispatch(loadCollection(collectionId, ResourceKind.Collection))} + onItemRouteChange={(collectionId) => this.props.dispatch(loadCollection(collectionId, ResourceKind.COLLECTION))} onContextMenu={(event, item) => { this.openContextMenu(event, { uuid: item.uuid, @@ -245,7 +245,8 @@ export const Workbench = withStyles(styles)( renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => this.props.dispatch(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, @@ -258,20 +259,21 @@ export const Workbench = withStyles(styles)( }} onItemDoubleClick={item => { switch (item.kind) { - case ResourceKind.Collection: + case ResourceKind.COLLECTION: this.props.dispatch(loadCollection(item.uuid, item.kind as ResourceKind)); this.props.dispatch(push(getCollectionUrl(item.uuid))); default: this.props.dispatch(setProjectItem(item.uuid, ItemMode.ACTIVE)); this.props.dispatch(loadDetails(item.uuid, item.kind as ResourceKind)); } + }} {...props} /> renderFavoritePanel = (props: RouteComponentProps<{ id: string }>) => this.props.dispatch(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, @@ -284,21 +286,22 @@ export const Workbench = withStyles(styles)( }} onItemDoubleClick={item => { switch (item.kind) { - case ResourceKind.Collection: + case ResourceKind.COLLECTION: this.props.dispatch(loadCollection(item.uuid, item.kind as ResourceKind)); this.props.dispatch(push(getCollectionUrl(item.uuid))); default: - this.props.dispatch(loadDetails(item.uuid, ResourceKind.Project)); + this.props.dispatch(loadDetails(item.uuid, ResourceKind.PROJECT)); this.props.dispatch(setProjectItem(item.uuid, ItemMode.ACTIVE)); - this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects)); + this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS)); } + }} {...props} /> mainAppBarActions: MainAppBarActionProps = { onBreadcrumbClick: ({ itemId }: NavBreadcrumb) => { this.props.dispatch(setProjectItem(itemId, ItemMode.BOTH)); - this.props.dispatch(loadDetails(itemId, ResourceKind.Project)); + this.props.dispatch(loadDetails(itemId, ResourceKind.PROJECT)); }, onSearch: searchText => { this.setState({ searchText });