[ARVADOS-WORKBENCH2] updated: 1.2.0-915-gcab8fbe
Git user
git at public.curoverse.com
Tue Nov 20 06:22:23 EST 2018
Summary of changes:
src/store/advanced-tab/advanced-tab.ts | 70 +++++++++++++------
src/store/context-menu/context-menu-actions.ts | 19 +++---
src/store/repositories/repositories-actions.ts | 10 ++-
.../advanced-tab-dialog/advanced-tab-dialog.tsx | 2 +-
.../action-sets/repository-action-set.ts | 6 +-
.../repositories-sample-git-dialog.tsx | 78 ++++++++++++++++++++++
.../rich-text-editor-dialog.tsx | 4 +-
.../repositories-panel/repositories-panel.tsx | 18 ++---
src/views/workbench/workbench.tsx | 2 +
9 files changed, 164 insertions(+), 45 deletions(-)
create mode 100644 src/views-components/repositories-sample-git-dialog/repositories-sample-git-dialog.tsx
via cab8fbece33e9c6188b911552790f459c740f4cd (commit)
from a0aedfcf68e7b3d4caeee3e36d776ca0b34780bf (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit cab8fbece33e9c6188b911552790f459c740f4cd
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Tue Nov 20 12:22:04 2018 +0100
advanced-tab-and-sample-git-start-for-repositories
Feature #13865
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --git a/src/store/advanced-tab/advanced-tab.ts b/src/store/advanced-tab/advanced-tab.ts
index ba0cf77..d845c46 100644
--- a/src/store/advanced-tab/advanced-tab.ts
+++ b/src/store/advanced-tab/advanced-tab.ts
@@ -14,6 +14,7 @@ import { CollectionResource } from '~/models/collection';
import { ProjectResource } from '~/models/project';
import { ServiceRepository } from '~/services/services';
import { FilterBuilder } from '~/services/api/filter-builder';
+import { RepositoriesResource } from '~/models/repositories';
export const ADVANCED_TAB_DIALOG = 'advancedTabDialog';
@@ -46,34 +47,46 @@ enum ProjectData {
DELETE_AT = 'delete_at'
}
-export const openAdvancedTabDialog = (uuid: string) =>
+enum RepositoryData {
+ REPOSITORY = 'repository',
+ CREATED_AT = 'created_at'
+}
+
+export const openAdvancedTabDialog = (uuid: string, index?: number) =>
async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
const { resources } = getState();
const kind = extractUuidKind(uuid);
const data = getResource<any>(uuid)(resources);
- const user = await services.userService.get(data.ownerUuid);
- const metadata = await services.linkService.list({
- filters: new FilterBuilder()
- .addEqual('headUuid', uuid)
- .getFilters()
- });
- if (data) {
- if (kind === ResourceKind.COLLECTION) {
- const dataCollection: AdvancedTabDialogData = advancedTabData(uuid, metadata, user, collectionApiResponse, data, CollectionData.COLLECTION, GroupContentsResourcePrefix.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED, data.storageClassesConfirmed);
- dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataCollection }));
- } else if (kind === ResourceKind.PROCESS) {
- const dataProcess: AdvancedTabDialogData = advancedTabData(uuid, metadata, user, containerRequestApiResponse, data, ProcessData.CONTAINER_REQUEST, GroupContentsResourcePrefix.PROCESS, ProcessData.OUTPUT_NAME, data.outputName);
- dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProcess }));
- } else if (kind === ResourceKind.PROJECT) {
- const dataProject: AdvancedTabDialogData = advancedTabData(uuid, metadata, user, groupRequestApiResponse, data, ProjectData.GROUP, GroupContentsResourcePrefix.PROJECT, ProjectData.DELETE_AT, data.deleteAt);
- dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProject }));
+ const repositoryData = getState().repositories.items[index!];
+ if (data || repositoryData) {
+ if (data) {
+ const user = await services.userService.get(data.ownerUuid);
+ const metadata = await services.linkService.list({
+ filters: new FilterBuilder()
+ .addEqual('headUuid', uuid)
+ .getFilters()
+ });
+ if (kind === ResourceKind.COLLECTION) {
+ const dataCollection: AdvancedTabDialogData = advancedTabData(uuid, metadata, user, collectionApiResponse, data, CollectionData.COLLECTION, GroupContentsResourcePrefix.COLLECTION, CollectionData.STORAGE_CLASSES_CONFIRMED, data.storageClassesConfirmed);
+ dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataCollection }));
+ } else if (kind === ResourceKind.PROCESS) {
+ const dataProcess: AdvancedTabDialogData = advancedTabData(uuid, metadata, user, containerRequestApiResponse, data, ProcessData.CONTAINER_REQUEST, GroupContentsResourcePrefix.PROCESS, ProcessData.OUTPUT_NAME, data.outputName);
+ dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProcess }));
+ } else if (kind === ResourceKind.PROJECT) {
+ const dataProject: AdvancedTabDialogData = advancedTabData(uuid, metadata, user, groupRequestApiResponse, data, ProjectData.GROUP, GroupContentsResourcePrefix.PROJECT, ProjectData.DELETE_AT, data.deleteAt);
+ dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataProject }));
+ }
+
+ } else if (kind === ResourceKind.REPOSITORY) {
+ const dataRepository: AdvancedTabDialogData = advancedTabData(uuid, '', '', repositoryApiResponse, repositoryData, RepositoryData.REPOSITORY, 'repositories', RepositoryData.CREATED_AT, repositoryData.createdAt);
+ dispatch(dialogActions.OPEN_DIALOG({ id: ADVANCED_TAB_DIALOG, data: dataRepository }));
}
} else {
dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Could not open advanced tab for this resource.", hideDuration: 2000, kind: SnackbarKind.ERROR }));
}
};
-const advancedTabData = (uuid: string, metadata: any, user: any, apiResponseKind: any, data: any, resourceKind: CollectionData | ProcessData | ProjectData, resourcePrefix: GroupContentsResourcePrefix, resourceKindProperty: CollectionData | ProcessData | ProjectData, property: any) => {
+const advancedTabData = (uuid: string, metadata: any, user: any, apiResponseKind: any, data: any, resourceKind: CollectionData | ProcessData | ProjectData | RepositoryData, resourcePrefix: GroupContentsResourcePrefix | 'repositories', resourceKindProperty: CollectionData | ProcessData | ProjectData | RepositoryData, property: any) => {
return {
uuid,
user,
@@ -82,9 +95,9 @@ const advancedTabData = (uuid: string, metadata: any, user: any, apiResponseKind
pythonHeader: pythonHeader(resourceKind),
pythonExample: pythonExample(uuid, resourcePrefix),
cliGetHeader: cliGetHeader(resourceKind),
- cliGetExample: cliGetExample(uuid, resourcePrefix),
+ cliGetExample: cliGetExample(uuid, resourceKind),
cliUpdateHeader: cliUpdateHeader(resourceKind, resourceKindProperty),
- cliUpdateExample: cliUpdateExample(uuid, resourceKind, property, resourceKind),
+ cliUpdateExample: cliUpdateExample(uuid, resourceKind, property, resourceKindProperty),
curlHeader: curlHeader(resourceKind, resourceKindProperty),
curlExample: curlExample(uuid, resourcePrefix, property, resourceKind, resourceKindProperty),
};
@@ -104,8 +117,8 @@ const pythonExample = (uuid: string, resourcePrefix: string) => {
const cliGetHeader = (resourceKind: string) =>
`An example arv command to get a ${resourceKind} using its uuid:`;
-const cliGetExample = (uuid: string, resourcePrefix: string) => {
- const cliGetExample = `arv ${resourcePrefix} get \\
+const cliGetExample = (uuid: string, resourceKind: string) => {
+ const cliGetExample = `arv ${resourceKind} get \\
--uuid ${uuid}`;
return cliGetExample;
@@ -228,4 +241,17 @@ const groupRequestApiResponse = (apiResponse: ProjectResource) => {
"properties": ${stringifyObject(properties)}`;
return response;
+};
+
+const repositoryApiResponse = (apiResponse: RepositoriesResource) => {
+ const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid, name } = apiResponse;
+ const response = `"uuid": "${uuid}",
+"owner_uuid": "${ownerUuid}",
+"modified_by_client_uuid": ${stringify(modifiedByClientUuid)},
+"modified_by_user_uuid": ${stringify(modifiedByUserUuid)},
+"modified_at": ${stringify(modifiedAt)},
+"name": ${stringify(name)},
+"created_at": "${createdAt}"`;
+
+ return response;
};
\ No newline at end of file
diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts
index a59f376..5a7a601 100644
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@ -13,6 +13,7 @@ import { UserResource } from '~/models/user';
import { isSidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
import { extractUuidKind, ResourceKind } from '~/models/resource';
import { Process } from '~/store/processes/process';
+import { RepositoriesResource } from '~/models/repositories';
export const contextMenuActions = unionize({
OPEN_CONTEXT_MENU: ofType<{ position: ContextMenuPosition, resource: ContextMenuResource }>(),
@@ -29,6 +30,7 @@ export type ContextMenuResource = {
kind: ResourceKind,
menuKind: ContextMenuKind;
isTrashed?: boolean;
+ index?: number
};
export const isKeyboardClick = (event: React.MouseEvent<HTMLElement>) =>
event.nativeEvent.detail === 0;
@@ -59,15 +61,16 @@ export const openCollectionFilesContextMenu = (event: React.MouseEvent<HTMLEleme
}));
};
-export const openRepositoryContextMenu = (event: React.MouseEvent<HTMLElement>) =>
+export const openRepositoryContextMenu = (event: React.MouseEvent<HTMLElement>, index: number, repository: RepositoriesResource) =>
(dispatch: Dispatch, getState: () => RootState) => {
- dispatch<any>(openContextMenu(event, {
- name: '',
- uuid: '',
- ownerUuid: '',
- kind: ResourceKind.REPOSITORY,
- menuKind: ContextMenuKind.REPOSITORY
- }));
+ dispatch<any>(openContextMenu(event, {
+ name: '',
+ uuid: repository.uuid,
+ ownerUuid: repository.ownerUuid,
+ kind: ResourceKind.REPOSITORY,
+ menuKind: ContextMenuKind.REPOSITORY,
+ index
+ }));
};
export const openRootProjectContextMenu = (event: React.MouseEvent<HTMLElement>, projectUuid: string) =>
diff --git a/src/store/repositories/repositories-actions.ts b/src/store/repositories/repositories-actions.ts
index 7f953b8..2660f7a 100644
--- a/src/store/repositories/repositories-actions.ts
+++ b/src/store/repositories/repositories-actions.ts
@@ -8,14 +8,22 @@ import { RootState } from '~/store/store';
import { ServiceRepository } from "~/services/services";
import { navigateToRepositories } from "~/store/navigation/navigation-action";
import { unionize, ofType, UnionOf } from "~/common/unionize";
+import { dialogActions } from '~/store/dialog/dialog-actions';
export const repositoriesActions = unionize({
SET_REPOSITORIES: ofType<any>(),
});
- export type RepositoriesActions = UnionOf<typeof repositoriesActions>;
+export type RepositoriesActions = UnionOf<typeof repositoriesActions>;
export const REPOSITORIES_PANEL = 'repositoriesPanel';
+export const REPOSITORIES_SAMPLE_GIT_NAME = 'repositoriesSampleGit';
+
+export const openRepositoriesSampleGitDialog = () =>
+ (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ const uuidPrefix = getState().properties.uuidPrefix;
+ dispatch(dialogActions.OPEN_DIALOG({ id: REPOSITORIES_SAMPLE_GIT_NAME, data: { uuidPrefix } }));
+ };
const repositoriesBindedActions = bindDataExplorerActions(REPOSITORIES_PANEL);
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 9a31a69..8bce416 100644
--- a/src/views-components/advanced-tab-dialog/advanced-tab-dialog.tsx
+++ b/src/views-components/advanced-tab-dialog/advanced-tab-dialog.tsx
@@ -78,7 +78,7 @@ export const AdvancedTabDialog = compose(
</Tabs>
<DialogContent className={classes.content}>
{value === 0 && <div>{dialogContentExample(apiResponse, classes)}</div>}
- {value === 1 && <div>{metadata.items.length > 0 ? <MetadataTab items={metadata.items} uuid={uuid} user={user} /> : dialogContentHeader('(No metadata links found)')}</div>}
+ {value === 1 && <div>{metadata !== '' && metadata.items.length > 0 ? <MetadataTab items={metadata.items} uuid={uuid} user={user} /> : dialogContentHeader('(No metadata links found)')}</div>}
{value === 2 && dialogContent(pythonHeader, pythonExample, classes)}
{value === 3 && <div>
{dialogContent(cliGetHeader, cliGetExample, classes)}
diff --git a/src/views-components/context-menu/action-sets/repository-action-set.ts b/src/views-components/context-menu/action-sets/repository-action-set.ts
index 2f3a985..1332a67 100644
--- a/src/views-components/context-menu/action-sets/repository-action-set.ts
+++ b/src/views-components/context-menu/action-sets/repository-action-set.ts
@@ -5,6 +5,7 @@
import { ContextMenuActionSet } from "~/views-components/context-menu/context-menu-action-set";
import { AdvancedIcon, RemoveIcon, ShareIcon } from "~/components/icon/icon";
import { openFileRemoveDialog, openRenameFileDialog } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
+import { openAdvancedTabDialog } from "~/store/advanced-tab/advanced-tab";
export const repositoryActionSet: ContextMenuActionSet = [[{
name: "Attributes",
@@ -22,10 +23,9 @@ export const repositoryActionSet: ContextMenuActionSet = [[{
name: "Advanced",
icon: AdvancedIcon,
execute: (dispatch, resource) => {
- dispatch<any>(openFileRemoveDialog(resource.uuid));
+ dispatch<any>(openAdvancedTabDialog(resource.uuid, resource.index));
}
-},
-{
+}, {
name: "Remove",
icon: RemoveIcon,
execute: (dispatch, resource) => {
diff --git a/src/views-components/repositories-sample-git-dialog/repositories-sample-git-dialog.tsx b/src/views-components/repositories-sample-git-dialog/repositories-sample-git-dialog.tsx
new file mode 100644
index 0000000..0941b53
--- /dev/null
+++ b/src/views-components/repositories-sample-git-dialog/repositories-sample-git-dialog.tsx
@@ -0,0 +1,78 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from "react";
+import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Typography } from "@material-ui/core";
+import { WithDialogProps } from "~/store/dialog/with-dialog";
+import { withDialog } from '~/store/dialog/with-dialog';
+import { REPOSITORIES_SAMPLE_GIT_NAME } from "~/store/repositories/repositories-actions";
+import { DefaultCodeSnippet } from '~/components/default-code-snippet/default-code-snippet';
+import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
+import { ArvadosTheme } from '~/common/custom-theme';
+import { compose } from "redux";
+
+type CssRules = 'codeSnippet' | 'link' | 'spacing';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ codeSnippet: {
+ borderRadius: theme.spacing.unit * 0.5,
+ border: '1px solid',
+ borderColor: theme.palette.grey["400"],
+ },
+ link: {
+ textDecoration: 'none',
+ color: theme.palette.primary.main,
+ "&:hover": {
+ color: theme.palette.primary.dark,
+ transition: 'all 0.5s ease'
+ }
+ },
+ spacing: {
+ paddingTop: theme.spacing.unit * 2
+ }
+});
+
+interface RepositoriesSampleGitDataProps {
+ uuidPrefix: string;
+}
+
+type RepositoriesSampleGitProps = RepositoriesSampleGitDataProps & WithStyles<CssRules>;
+
+export const RepositoriesSampleGitDialog = compose(
+ withDialog(REPOSITORIES_SAMPLE_GIT_NAME),
+ withStyles(styles))(
+ (props: WithDialogProps<RepositoriesSampleGitProps> & RepositoriesSampleGitProps) =>
+ <Dialog open={props.open}
+ onClose={props.closeDialog}
+ fullWidth
+ maxWidth='sm'>
+ <DialogTitle>Sample git quick start:</DialogTitle>
+ <DialogContent>
+ <DefaultCodeSnippet
+ className={props.classes.codeSnippet}
+ lines={[snippetText(props.data.uuidPrefix)]} />
+ <Typography variant="body2" className={props.classes.spacing}>
+ See also:
+ <div><a href="https://doc.arvados.org/user/getting_started/ssh-access-unix.html" className={props.classes.link} target="_blank">SSH access</a></div>
+ <div><a href="https://doc.arvados.org/user/tutorials/tutorial-firstscript.html" className={props.classes.link} target="_blank">Writing a Crunch Script</a></div>
+ </Typography>
+ </DialogContent>
+ <DialogActions>
+ <Button
+ variant='flat'
+ color='primary'
+ onClick={props.closeDialog}>
+ Close
+ </Button>
+ </DialogActions>
+ </Dialog>
+ );
+
+const snippetText = (uuidPrefix: string) => `git clone git at git.${uuidPrefix}.arvadosapi.com:arvados.git
+cd arvados
+# edit files
+git add the/files/you/changed
+git commit
+git push
+`;
diff --git a/src/views-components/rich-text-editor-dialog/rich-text-editor-dialog.tsx b/src/views-components/rich-text-editor-dialog/rich-text-editor-dialog.tsx
index a997355..86422ba 100644
--- a/src/views-components/rich-text-editor-dialog/rich-text-editor-dialog.tsx
+++ b/src/views-components/rich-text-editor-dialog/rich-text-editor-dialog.tsx
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: AGPL-3.0
import * as React from "react";
-import { Dialog, DialogTitle, DialogContent, DialogActions, Button, DialogContentText } from "@material-ui/core";
-import { WithDialogProps } from "../../store/dialog/with-dialog";
+import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from "@material-ui/core";
+import { WithDialogProps } from "~/store/dialog/with-dialog";
import { withDialog } from '~/store/dialog/with-dialog';
import { RICH_TEXT_EDITOR_DIALOG_NAME } from "~/store/rich-text-editor-dialog/rich-text-editor-dialog-actions";
import RichTextEditor from 'react-rte';
diff --git a/src/views/repositories-panel/repositories-panel.tsx b/src/views/repositories-panel/repositories-panel.tsx
index 3d2d32c..cafbefd 100644
--- a/src/views/repositories-panel/repositories-panel.tsx
+++ b/src/views/repositories-panel/repositories-panel.tsx
@@ -11,7 +11,7 @@ import { Link } from 'react-router-dom';
import { Dispatch, compose } from 'redux';
import { RootState } from '~/store/store';
import { HelpIcon, AddIcon, MoreOptionsIcon } from '~/components/icon/icon';
-import { loadRepositoriesData } from '~/store/repositories/repositories-actions';
+import { loadRepositoriesData, openRepositoriesSampleGitDialog } from '~/store/repositories/repositories-actions';
import { RepositoriesResource } from '~/models/repositories';
import { openRepositoryContextMenu } from '~/store/context-menu/context-menu-actions';
@@ -63,16 +63,18 @@ const mapStateToProps = (state: RootState) => {
};
};
-const mapDispatchToProps = (dispatch: Dispatch): Pick<RepositoriesActionProps, 'onOptionsMenuOpen' | 'loadRepositories'> => ({
+const mapDispatchToProps = (dispatch: Dispatch): Pick<RepositoriesActionProps, 'onOptionsMenuOpen' | 'loadRepositories' | 'openRepositoriesSampleGitDialog'> => ({
loadRepositories: () => dispatch<any>(loadRepositoriesData()),
- onOptionsMenuOpen: (event) => {
- dispatch<any>(openRepositoryContextMenu(event));
+ onOptionsMenuOpen: (event, index, repository) => {
+ dispatch<any>(openRepositoryContextMenu(event, index, repository));
},
+ openRepositoriesSampleGitDialog: () => dispatch<any>(openRepositoriesSampleGitDialog())
});
interface RepositoriesActionProps {
loadRepositories: () => void;
- onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>) => void;
+ onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, index: number, repository: RepositoriesResource) => void;
+ openRepositoriesSampleGitDialog: () => void;
}
interface RepositoriesDataProps {
@@ -90,7 +92,7 @@ export const RepositoriesPanel = compose(
this.props.loadRepositories();
}
render() {
- const { classes, repositories, onOptionsMenuOpen } = this.props;
+ const { classes, repositories, onOptionsMenuOpen, openRepositoriesSampleGitDialog } = this.props;
console.log(repositories);
return (
<Card>
@@ -111,7 +113,7 @@ export const RepositoriesPanel = compose(
<Grid item xs={12}>
<div className={classes.iconRow}>
<Tooltip title="Sample git quick start">
- <IconButton className={classes.moreOptionsButton}>
+ <IconButton className={classes.moreOptionsButton} onClick={openRepositoriesSampleGitDialog}>
<HelpIcon className={classes.icon} />
</IconButton>
</Tooltip>
@@ -133,7 +135,7 @@ export const RepositoriesPanel = compose(
<TableCell className={classes.cloneUrls}>{repository.cloneUrls.join("\n")}</TableCell>
<TableCell className={classes.moreOptions}>
<Tooltip title="More options" disableFocusListener>
- <IconButton onClick={onOptionsMenuOpen} className={classes.moreOptionsButton}>
+ <IconButton onClick={event => onOptionsMenuOpen(event, index, repository)} className={classes.moreOptionsButton}>
<MoreOptionsIcon />
</IconButton>
</Tooltip>
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index d0509d0..c9bcd91 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -49,6 +49,7 @@ import { AdvancedTabDialog } from '~/views-components/advanced-tab-dialog/advanc
import { ProcessInputDialog } from '~/views-components/process-input-dialog/process-input-dialog';
import { ProjectPropertiesDialog } from '~/views-components/project-properties-dialog/project-properties-dialog';
import { RepositoriesPanel } from '~/views/repositories-panel/repositories-panel';
+import { RepositoriesSampleGitDialog } from '~/views-components/repositories-sample-git-dialog/repositories-sample-git-dialog';
type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content';
@@ -147,6 +148,7 @@ export const WorkbenchPanel =
<ProjectPropertiesDialog />
<RemoveProcessDialog />
<RenameFileDialog />
+ <RepositoriesSampleGitDialog />
<RichTextEditorDialog />
<SharingDialog />
<Snackbar />
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list