[ARVADOS-WORKBENCH2] created: 2.1.0-56-gac09b3b5
Git user
git at public.arvados.org
Wed Nov 11 09:21:16 UTC 2020
at ac09b3b5c8ecd122b778bb9c17f2aef1f00f6b05 (commit)
commit ac09b3b5c8ecd122b778bb9c17f2aef1f00f6b05
Author: Daniel Kutyła <daniel.kutyla at contractors.roche.com>
Date: Fri Nov 6 22:15:21 2020 +0100
16005: Open collection and project in new tab feature added
Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła <daniel.kutyla at contractors.roche.com>1~
diff --git a/src/common/array-utils.ts b/src/common/array-utils.ts
new file mode 100644
index 00000000..a92461c8
--- /dev/null
+++ b/src/common/array-utils.ts
@@ -0,0 +1,18 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+export const sortByProperty = (propName: string) => (obj1: any, obj2: any) => {
+ const prop1 = obj1[propName];
+ const prop2 = obj2[propName];
+
+ if (prop1 > prop2) {
+ return 1;
+ }
+
+ if (prop1 < prop2) {
+ return -1;
+ }
+
+ return 0;
+};
diff --git a/src/common/copy-store.ts b/src/common/copy-store.ts
new file mode 100644
index 00000000..9c7f3875
--- /dev/null
+++ b/src/common/copy-store.ts
@@ -0,0 +1,28 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+const STORE_COPY_KEY = 'storeCopy';
+
+export const copyStore = (store: any) => {
+ const { localStorage } = window;
+ const state = store.getState();
+ const storeCopy = JSON.parse(JSON.stringify(state));
+ storeCopy.router.location.pathname = '/';
+
+ if (localStorage) {
+ localStorage.setItem(STORE_COPY_KEY, JSON.stringify(storeCopy));
+ }
+};
+
+export const restoreStore = () => {
+ let storeCopy = null;
+ const { localStorage } = window;
+
+ if (localStorage && localStorage.getItem(STORE_COPY_KEY)) {
+ storeCopy = localStorage.getItem(STORE_COPY_KEY);
+ localStorage.removeItem(STORE_COPY_KEY);
+ }
+
+ return storeCopy;
+};
diff --git a/src/common/redirect-to.ts b/src/common/redirect-to.ts
index f5ece21b..baf44711 100644
--- a/src/common/redirect-to.ts
+++ b/src/common/redirect-to.ts
@@ -5,14 +5,22 @@
import { Config } from './config';
const REDIRECT_TO_KEY = 'redirectTo';
+export const REDIRECT_TO_APPLY_TO_PATH = 'redirectToApplyToPath';
export const storeRedirects = () => {
- if (window.location.href.indexOf(REDIRECT_TO_KEY) > -1) {
- const { location: { href }, localStorage } = window;
- const redirectUrl = href.split(`${REDIRECT_TO_KEY}=`)[1];
+ let redirectUrl;
+ const { location: { href }, localStorage } = window;
+ const applyToPath = href.indexOf(REDIRECT_TO_APPLY_TO_PATH) > -1;
- if (localStorage) {
- localStorage.setItem(REDIRECT_TO_KEY, redirectUrl);
+ if (href.indexOf(REDIRECT_TO_KEY) > -1) {
+ redirectUrl = href.split(`${REDIRECT_TO_KEY}=`)[1];
+ }
+
+ if (localStorage && redirectUrl) {
+ localStorage.setItem(REDIRECT_TO_KEY, redirectUrl);
+
+ if (applyToPath) {
+ localStorage.setItem(REDIRECT_TO_APPLY_TO_PATH, 'true');
}
}
};
@@ -24,9 +32,18 @@ export const handleRedirects = (token: string, config: Config) => {
if (localStorage && localStorage.getItem(REDIRECT_TO_KEY)) {
const redirectUrl = localStorage.getItem(REDIRECT_TO_KEY);
localStorage.removeItem(REDIRECT_TO_KEY);
+ const applyToPath = localStorage.getItem(REDIRECT_TO_APPLY_TO_PATH);
+
if (redirectUrl) {
- const sep = redirectUrl.indexOf("?") > -1 ? "&" : "?";
- window.location.href = `${keepWebServiceUrl}${redirectUrl}${sep}api_token=${token}`;
+ if (applyToPath === 'true') {
+ localStorage.removeItem(REDIRECT_TO_APPLY_TO_PATH);
+ setTimeout(() => {
+ window.location.pathname = redirectUrl;
+ }, 0);
+ } else {
+ const sep = redirectUrl.indexOf("?") > -1 ? "&" : "?";
+ window.location.href = `${keepWebServiceUrl}${redirectUrl}${sep}api_token=${token}`;
+ }
}
}
};
diff --git a/src/store/open-in-new-tab/open-in-new-tab.actions.ts b/src/store/open-in-new-tab/open-in-new-tab.actions.ts
index 17ba7402..c6462ea1 100644
--- a/src/store/open-in-new-tab/open-in-new-tab.actions.ts
+++ b/src/store/open-in-new-tab/open-in-new-tab.actions.ts
@@ -2,24 +2,36 @@
//
// SPDX-License-Identifier: AGPL-3.0
-import { Dispatch } from 'redux';
+import * as copy from 'copy-to-clipboard';
import { ResourceKind } from '~/models/resource';
-import { unionize, ofType } from '~/common/unionize';
+import { getClipboardUrl } from '~/views-components/context-menu/actions/helpers';
-export const openInNewTabActions = unionize({
- COPY_STORE: ofType<{}>(),
- OPEN_COLLECTION_IN_NEW_TAB: ofType<string>(),
- OPEN_PROJECT_IN_NEW_TAB: ofType<string>()
-});
-
-export const openInNewTabAction = (resource: any) => (dispatch: Dispatch) => {
+const getUrl = (resource: any) => {
+ let url = null;
const { uuid, kind } = resource;
- dispatch(openInNewTabActions.COPY_STORE());
-
if (kind === ResourceKind.COLLECTION) {
- dispatch(openInNewTabActions.OPEN_COLLECTION_IN_NEW_TAB(uuid));
- } else if (kind === ResourceKind.PROJECT) {
- dispatch(openInNewTabActions.OPEN_PROJECT_IN_NEW_TAB(uuid));
+ url = `/collections/${uuid}`;
+ }
+ if (kind === ResourceKind.PROJECT) {
+ url = `/projects/${uuid}`;
+ }
+
+ return url;
+};
+
+export const openInNewTabAction = (resource: any) => () => {
+ const url = getUrl(resource);
+
+ if (url) {
+ window.open(`${window.location.origin}${url}`, '_blank');
+ }
+};
+
+export const copyToClipboardAction = (resource: any) => () => {
+ const url = getUrl(resource);
+
+ if (url) {
+ copy(getClipboardUrl(url, false));
}
};
\ No newline at end of file
diff --git a/src/store/store.ts b/src/store/store.ts
index 7beb099c..517368aa 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -163,6 +163,7 @@ export function configureStore(history: History, services: ServiceRepository, co
collectionsContentAddress,
subprocessMiddleware,
];
+
const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
return createStore(rootReducer, enhancer);
}
diff --git a/src/views-components/advanced-tab-dialog/advanced-tab-dialog.tsx b/src/views-components/advanced-tab-dialog/advanced-tab-dialog.tsx
index fdd0bd70..7e90bfd2 100644
--- a/src/views-components/advanced-tab-dialog/advanced-tab-dialog.tsx
+++ b/src/views-components/advanced-tab-dialog/advanced-tab-dialog.tsx
@@ -87,7 +87,7 @@ export const AdvancedTabDialog = compose(
{value === 4 && dialogContent(curlHeader, curlExample, classes)}
</DialogContent>
<DialogActions>
- <Button variant='text' color='primary' onClick={closeDialog}>
+ <Button data-cy="close-advanced-dialog" variant='text' color='primary' onClick={closeDialog}>
Close
</Button>
</DialogActions>
diff --git a/src/views-components/context-menu/action-sets/collection-action-set.ts b/src/views-components/context-menu/action-sets/collection-action-set.ts
index 7fa6f224..4b6b9224 100644
--- a/src/views-components/context-menu/action-sets/collection-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-action-set.ts
@@ -5,7 +5,7 @@
import { ContextMenuActionSet } from "../context-menu-action-set";
import { ToggleFavoriteAction } from "../actions/favorite-action";
import { toggleFavorite } from "~/store/favorites/favorites-actions";
-import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, AdvancedIcon } from "~/components/icon/icon";
+import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, AdvancedIcon, OpenIcon, Link } from "~/components/icon/icon";
import { openCollectionUpdateDialog } from "~/store/collections/collection-update-actions";
import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
import { openMoveCollectionDialog } from '~/store/collections/collection-move-actions';
@@ -15,16 +15,32 @@ import { toggleCollectionTrashed } from "~/store/trash/trash-actions";
import { openSharingDialog } from '~/store/sharing-dialog/sharing-dialog-actions';
import { openAdvancedTabDialog } from "~/store/advanced-tab/advanced-tab";
import { toggleDetailsPanel } from '~/store/details-panel/details-panel-action';
+import { copyToClipboardAction, openInNewTabAction } from "~/store/open-in-new-tab/open-in-new-tab.actions";
export const readOnlyCollectionActionSet: ContextMenuActionSet = [[
{
component: ToggleFavoriteAction,
+ name: 'ToggleFavoriteAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleFavorite(resource)).then(() => {
dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
});
}
},
+ {
+ icon: OpenIcon,
+ name: "Open in new tab",
+ execute: (dispatch, resource) => {
+ dispatch<any>(openInNewTabAction(resource));
+ }
+ },
+ {
+ icon: Link,
+ name: "Copy to clipboard",
+ execute: (dispatch, resource) => {
+ dispatch<any>(copyToClipboardAction(resource));
+ }
+ },
{
icon: CopyIcon,
name: "Make a copy",
@@ -73,6 +89,7 @@ export const collectionActionSet: ContextMenuActionSet = [
},
{
component: ToggleTrashAction,
+ name: 'ToggleTrashAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleCollectionTrashed(resource.uuid, resource.isTrashed!!));
}
diff --git a/src/views-components/context-menu/action-sets/collection-admin-action-set.ts b/src/views-components/context-menu/action-sets/collection-admin-action-set.ts
index 10a839d8..7b39d749 100644
--- a/src/views-components/context-menu/action-sets/collection-admin-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-admin-action-set.ts
@@ -5,7 +5,7 @@
import { ContextMenuActionSet } from "../context-menu-action-set";
import { ToggleFavoriteAction } from "../actions/favorite-action";
import { toggleFavorite } from "~/store/favorites/favorites-actions";
-import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, AdvancedIcon } from "~/components/icon/icon";
+import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, AdvancedIcon, OpenIcon, Link } from "~/components/icon/icon";
import { openCollectionUpdateDialog } from "~/store/collections/collection-update-actions";
import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
import { openMoveCollectionDialog } from '~/store/collections/collection-move-actions';
@@ -18,6 +18,7 @@ import { toggleDetailsPanel } from '~/store/details-panel/details-panel-action';
import { TogglePublicFavoriteAction } from "~/views-components/context-menu/actions/public-favorite-action";
import { publicFavoritePanelActions } from "~/store/public-favorites-panel/public-favorites-action";
import { togglePublicFavorite } from "~/store/public-favorites/public-favorites-actions";
+import { copyToClipboardAction, openInNewTabAction } from "~/store/open-in-new-tab/open-in-new-tab.actions";
export const collectionAdminActionSet: ContextMenuActionSet = [[
{
@@ -27,6 +28,20 @@ export const collectionAdminActionSet: ContextMenuActionSet = [[
dispatch<any>(openCollectionUpdateDialog(resource));
}
},
+ {
+ icon: OpenIcon,
+ name: "Open in new tab",
+ execute: (dispatch, resource) => {
+ dispatch<any>(openInNewTabAction(resource));
+ }
+ },
+ {
+ icon: Link,
+ name: "Copy to clipboard",
+ execute: (dispatch, resource) => {
+ dispatch<any>(copyToClipboardAction(resource));
+ }
+ },
{
icon: ShareIcon,
name: "Share",
@@ -36,6 +51,7 @@ export const collectionAdminActionSet: ContextMenuActionSet = [[
},
{
component: ToggleFavoriteAction,
+ name: 'ToggleFavoriteAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleFavorite(resource)).then(() => {
dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
@@ -44,6 +60,7 @@ export const collectionAdminActionSet: ContextMenuActionSet = [[
},
{
component: TogglePublicFavoriteAction,
+ name: 'TogglePublicFavoriteAction',
execute: (dispatch, resource) => {
dispatch<any>(togglePublicFavorite(resource)).then(() => {
dispatch<any>(publicFavoritePanelActions.REQUEST_ITEMS());
@@ -79,6 +96,7 @@ export const collectionAdminActionSet: ContextMenuActionSet = [[
},
{
component: ToggleTrashAction,
+ name: 'ToggleTrashAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleCollectionTrashed(resource.uuid, resource.isTrashed!!));
}
diff --git a/src/views-components/context-menu/action-sets/collection-admin-action-set.ts b/src/views-components/context-menu/action-sets/collection-resource-action-set.ts
similarity index 70%
copy from src/views-components/context-menu/action-sets/collection-admin-action-set.ts
copy to src/views-components/context-menu/action-sets/collection-resource-action-set.ts
index 10a839d8..5bd362f5 100644
--- a/src/views-components/context-menu/action-sets/collection-admin-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-resource-action-set.ts
@@ -4,22 +4,20 @@
import { ContextMenuActionSet } from "../context-menu-action-set";
import { ToggleFavoriteAction } from "../actions/favorite-action";
+import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
import { toggleFavorite } from "~/store/favorites/favorites-actions";
-import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, AdvancedIcon } from "~/components/icon/icon";
+import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, AdvancedIcon, OpenIcon } from '~/components/icon/icon';
import { openCollectionUpdateDialog } from "~/store/collections/collection-update-actions";
import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
import { openMoveCollectionDialog } from '~/store/collections/collection-move-actions';
-import { openCollectionCopyDialog } from "~/store/collections/collection-copy-actions";
-import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
+import { openCollectionCopyDialog } from '~/store/collections/collection-copy-actions';
import { toggleCollectionTrashed } from "~/store/trash/trash-actions";
-import { openSharingDialog } from '~/store/sharing-dialog/sharing-dialog-actions';
-import { openAdvancedTabDialog } from "~/store/advanced-tab/advanced-tab";
+import { openSharingDialog } from "~/store/sharing-dialog/sharing-dialog-actions";
+import { openAdvancedTabDialog } from '~/store/advanced-tab/advanced-tab';
import { toggleDetailsPanel } from '~/store/details-panel/details-panel-action';
-import { TogglePublicFavoriteAction } from "~/views-components/context-menu/actions/public-favorite-action";
-import { publicFavoritePanelActions } from "~/store/public-favorites-panel/public-favorites-action";
-import { togglePublicFavorite } from "~/store/public-favorites/public-favorites-actions";
+import { openInNewTabAction } from "~/store/open-in-new-tab/open-in-new-tab.actions";
-export const collectionAdminActionSet: ContextMenuActionSet = [[
+export const collectionResourceActionSet: ContextMenuActionSet = [[
{
icon: RenameIcon,
name: "Edit collection",
@@ -43,25 +41,25 @@ export const collectionAdminActionSet: ContextMenuActionSet = [[
}
},
{
- component: TogglePublicFavoriteAction,
+ icon: OpenIcon,
+ name: "Open in new tab",
execute: (dispatch, resource) => {
- dispatch<any>(togglePublicFavorite(resource)).then(() => {
- dispatch<any>(publicFavoritePanelActions.REQUEST_ITEMS());
- });
+ dispatch<any>(openInNewTabAction(resource));
}
},
{
icon: MoveToIcon,
name: "Move to",
- execute: (dispatch, resource) => dispatch<any>(openMoveCollectionDialog(resource))
+ execute: (dispatch, resource) => {
+ dispatch<any>(openMoveCollectionDialog(resource));
+ }
},
{
icon: CopyIcon,
- name: "Make a copy",
+ name: "Copy to project",
execute: (dispatch, resource) => {
dispatch<any>(openCollectionCopyDialog(resource));
}
-
},
{
icon: DetailsIcon,
@@ -83,4 +81,11 @@ export const collectionAdminActionSet: ContextMenuActionSet = [[
dispatch<any>(toggleCollectionTrashed(resource.uuid, resource.isTrashed!!));
}
},
+ // {
+ // icon: RemoveIcon,
+ // name: "Remove",
+ // execute: (dispatch, resource) => {
+ // // add code
+ // }
+ // }
]];
diff --git a/src/views-components/context-menu/action-sets/project-action-set.ts b/src/views-components/context-menu/action-sets/project-action-set.ts
index 4f92aeb8..c0b925c2 100644
--- a/src/views-components/context-menu/action-sets/project-action-set.ts
+++ b/src/views-components/context-menu/action-sets/project-action-set.ts
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0
import { ContextMenuActionSet } from "../context-menu-action-set";
-import { NewProjectIcon, RenameIcon, MoveToIcon, DetailsIcon, AdvancedIcon } from '~/components/icon/icon';
+import { NewProjectIcon, RenameIcon, MoveToIcon, DetailsIcon, AdvancedIcon, OpenIcon, Link } from '~/components/icon/icon';
import { ToggleFavoriteAction } from "../actions/favorite-action";
import { toggleFavorite } from "~/store/favorites/favorites-actions";
import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
@@ -16,16 +16,32 @@ import { ShareIcon } from '~/components/icon/icon';
import { openSharingDialog } from "~/store/sharing-dialog/sharing-dialog-actions";
import { openAdvancedTabDialog } from "~/store/advanced-tab/advanced-tab";
import { toggleDetailsPanel } from '~/store/details-panel/details-panel-action';
+import { copyToClipboardAction, openInNewTabAction } from "~/store/open-in-new-tab/open-in-new-tab.actions";
export const readOnlyProjectActionSet: ContextMenuActionSet = [[
{
component: ToggleFavoriteAction,
+ name: 'ToggleFavoriteAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleFavorite(resource)).then(() => {
dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
});
}
},
+ {
+ icon: OpenIcon,
+ name: "Open in new tab",
+ execute: (dispatch, resource) => {
+ dispatch<any>(openInNewTabAction(resource));
+ }
+ },
+ {
+ icon: Link,
+ name: "Copy to clipboard",
+ execute: (dispatch, resource) => {
+ dispatch<any>(copyToClipboardAction(resource));
+ }
+ },
{
icon: DetailsIcon,
name: "View details",
@@ -75,6 +91,7 @@ export const projectActionSet: ContextMenuActionSet = [
},
{
component: ToggleTrashAction,
+ name: 'ToggleTrashAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleProjectTrashed(resource.uuid, resource.ownerUuid, resource.isTrashed!!));
}
diff --git a/src/views-components/context-menu/action-sets/project-admin-action-set.ts b/src/views-components/context-menu/action-sets/project-admin-action-set.ts
index f6185804..398864dc 100644
--- a/src/views-components/context-menu/action-sets/project-admin-action-set.ts
+++ b/src/views-components/context-menu/action-sets/project-admin-action-set.ts
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0
import { ContextMenuActionSet } from "../context-menu-action-set";
-import { NewProjectIcon, RenameIcon, MoveToIcon, DetailsIcon, AdvancedIcon } from '~/components/icon/icon';
+import { NewProjectIcon, RenameIcon, MoveToIcon, DetailsIcon, AdvancedIcon, OpenIcon, Link } from '~/components/icon/icon';
import { ToggleFavoriteAction } from "../actions/favorite-action";
import { toggleFavorite } from "~/store/favorites/favorites-actions";
import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
@@ -19,6 +19,7 @@ import { toggleDetailsPanel } from '~/store/details-panel/details-panel-action';
import { TogglePublicFavoriteAction } from "~/views-components/context-menu/actions/public-favorite-action";
import { togglePublicFavorite } from "~/store/public-favorites/public-favorites-actions";
import { publicFavoritePanelActions } from "~/store/public-favorites-panel/public-favorites-action";
+import { copyToClipboardAction, openInNewTabAction } from "~/store/open-in-new-tab/open-in-new-tab.actions";
export const projectAdminActionSet: ContextMenuActionSet = [[
{
@@ -28,6 +29,20 @@ export const projectAdminActionSet: ContextMenuActionSet = [[
dispatch<any>(openProjectCreateDialog(resource.uuid));
}
},
+ {
+ icon: OpenIcon,
+ name: "Open in new tab",
+ execute: (dispatch, resource) => {
+ dispatch<any>(openInNewTabAction(resource));
+ }
+ },
+ {
+ icon: Link,
+ name: "Copy to clipboard",
+ execute: (dispatch, resource) => {
+ dispatch<any>(copyToClipboardAction(resource));
+ }
+ },
{
icon: RenameIcon,
name: "Edit project",
@@ -44,6 +59,7 @@ export const projectAdminActionSet: ContextMenuActionSet = [[
},
{
component: ToggleFavoriteAction,
+ name: 'ToggleFavoriteAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleFavorite(resource)).then(() => {
dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
@@ -52,6 +68,7 @@ export const projectAdminActionSet: ContextMenuActionSet = [[
},
{
component: TogglePublicFavoriteAction,
+ name: 'TogglePublicFavoriteAction',
execute: (dispatch, resource) => {
dispatch<any>(togglePublicFavorite(resource)).then(() => {
dispatch<any>(publicFavoritePanelActions.REQUEST_ITEMS());
@@ -88,6 +105,7 @@ export const projectAdminActionSet: ContextMenuActionSet = [[
},
{
component: ToggleTrashAction,
+ name: 'ToggleTrashAction',
execute: (dispatch, resource) => {
dispatch<any>(toggleProjectTrashed(resource.uuid, resource.ownerUuid, resource.isTrashed!!));
}
diff --git a/src/views-components/context-menu/actions/helpers.ts b/src/views-components/context-menu/actions/helpers.ts
index 8dfcaca0..578af205 100644
--- a/src/views-components/context-menu/actions/helpers.ts
+++ b/src/views-components/context-menu/actions/helpers.ts
@@ -2,7 +2,9 @@
//
// SPDX-License-Identifier: AGPL-3.0
-export const sanitizeToken = (href: string, tokenAsQueryParam: boolean = true): string => {
+import { REDIRECT_TO_APPLY_TO_PATH } from "~/common/redirect-to";
+
+export const sanitizeToken = (href: string, tokenAsQueryParam = true): string => {
const [prefix, suffix] = href.split('/t=');
const [token1, token2, token3, ...rest] = suffix.split('/');
const token = `${token1}/${token2}/${token3}`;
@@ -11,9 +13,9 @@ export const sanitizeToken = (href: string, tokenAsQueryParam: boolean = true):
return `${[prefix, ...rest].join('/')}${tokenAsQueryParam ? `${sep}api_token=${token}` : ''}`;
};
-export const getClipboardUrl = (href: string): string => {
+export const getClipboardUrl = (href: string, shouldSanitizeToken = true): string => {
const { origin } = window.location;
- const url = sanitizeToken(href, false);
+ const url = shouldSanitizeToken ? sanitizeToken(href, false) : href;
- return `${origin}?redirectTo=${url}`;
+ return `${origin}${!shouldSanitizeToken ? `?${REDIRECT_TO_APPLY_TO_PATH}=true&` : `?`}redirectTo=${url}`;
};
diff --git a/src/views-components/context-menu/context-menu.tsx b/src/views-components/context-menu/context-menu.tsx
index 43474dd1..b86498a0 100644
--- a/src/views-components/context-menu/context-menu.tsx
+++ b/src/views-components/context-menu/context-menu.tsx
@@ -10,6 +10,7 @@ import { createAnchorAt } from "~/components/popover/helpers";
import { ContextMenuActionSet, ContextMenuAction } from "./context-menu-action-set";
import { Dispatch } from "redux";
import { memoize } from 'lodash';
+import { sortByProperty } from "~/common/array-utils";
type DataProps = Pick<ContextMenuProps, "anchorEl" | "items" | "open"> & { resource?: ContextMenuResource };
const mapStateToProps = (state: RootState): DataProps => {
const { open, position, resource } = state.contextMenu;
@@ -53,7 +54,8 @@ export const ContextMenu = connect(mapStateToProps, mapDispatchToProps, mergePro
const menuActionSets = new Map<string, ContextMenuActionSet>();
export const addMenuActionSet = (name: string, itemSet: ContextMenuActionSet) => {
- menuActionSets.set(name, itemSet);
+ const sorted = itemSet.map(items => items.sort(sortByProperty('name')));
+ menuActionSets.set(name, sorted);
};
const emptyActionSet: ContextMenuActionSet = [];
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list