[ARVADOS-WORKBENCH2] updated: 1.2.0-930-gaed25c0

Git user git at public.curoverse.com
Wed Nov 21 06:38:07 EST 2018


Summary of changes:
 src/models/ssh-key.ts                              | 17 ++++++
 src/routes/route-change-handlers.ts                |  7 ++-
 src/routes/routes.ts                               |  8 ++-
 .../authorized-keys-service.ts                     | 34 ++++++++++++
 src/services/services.ts                           |  3 ++
 src/store/auth/auth-action.ts                      | 63 ++++++++++++++++++++--
 src/store/auth/auth-reducer.ts                     | 16 +++++-
 src/store/navigation/navigation-action.ts          |  2 +
 .../run-process-panel/run-process-panel-actions.ts |  2 +-
 src/store/workbench/workbench-actions.ts           |  6 +++
 src/validators/is-rsa-key.tsx                      | 10 ++++
 src/validators/validators.tsx                      |  6 ++-
 .../dialog-create/dialog-ssh-key-create.tsx        | 25 +++++++++
 .../dialog-forms/create-ssh-key-dialog.ts          | 19 +++++++
 .../form-fields/ssh-key-form-fields.tsx            | 25 +++++++++
 src/views-components/main-app-bar/account-menu.tsx |  4 +-
 .../repositories-panel/repositories-panel.tsx      |  3 +-
 src/views/ssh-key-panel/ssh-key-panel-root.tsx     | 55 +++++++++++++++++++
 src/views/ssh-key-panel/ssh-key-panel.tsx          | 23 ++++++++
 src/views/workbench/workbench.tsx                  |  4 ++
 20 files changed, 320 insertions(+), 12 deletions(-)
 create mode 100644 src/models/ssh-key.ts
 create mode 100644 src/services/authorized-keys-service/authorized-keys-service.ts
 create mode 100644 src/validators/is-rsa-key.tsx
 create mode 100644 src/views-components/dialog-create/dialog-ssh-key-create.tsx
 create mode 100644 src/views-components/dialog-forms/create-ssh-key-dialog.ts
 create mode 100644 src/views-components/form-fields/ssh-key-form-fields.tsx
 create mode 100644 src/views/ssh-key-panel/ssh-key-panel-root.tsx
 create mode 100644 src/views/ssh-key-panel/ssh-key-panel.tsx

       via  aed25c0fef7e65b307d702e8ee515567d6c2a7c1 (commit)
       via  b56fac763b24e34c5c2ba42cf9e183ffcc2014fc (commit)
       via  3bb5a602028d5ace55da8af3637a7f9d4eb48c00 (commit)
       via  9eaee66663fa21962f46e301ba6257ab63a9b10c (commit)
       via  65bdf250e5a09633e482bacd968666861643c150 (commit)
       via  13bf073c77ca9fcf75ebd31098a9bf538e96c9c9 (commit)
       via  42db83a0075f9704dcbfb2cd29821c97ff0fe34b (commit)
       via  62ff5a943865229c1630c66366f824511048ce63 (commit)
      from  c27efd822acfd3bd93fc3e2e3e24a24146811eb7 (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 aed25c0fef7e65b307d702e8ee515567d6c2a7c1
Merge: c27efd8 b56fac7
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date:   Wed Nov 21 12:37:51 2018 +0100

    fixed conflicts + link to ssh-keys panel
    
    Feature #13865
    
    Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>

diff --cc src/routes/route-change-handlers.ts
index a4a53d7,fb6f5e2..c7f3555
--- a/src/routes/route-change-handlers.ts
+++ b/src/routes/route-change-handlers.ts
@@@ -4,8 -4,8 +4,8 @@@
  
  import { History, Location } from 'history';
  import { RootStore } from '~/store/store';
- import { matchProcessRoute, matchProcessLogRoute, matchProjectRoute, matchCollectionRoute, matchFavoritesRoute, matchTrashRoute, matchRootRoute, matchSharedWithMeRoute, matchRunProcessRoute, matchWorkflowRoute, matchSearchResultsRoute, matchRepositoriesRoute } from './routes';
- import { loadProject, loadCollection, loadFavorites, loadTrash, loadProcess, loadProcessLog, loadRepositories } from '~/store/workbench/workbench-actions';
 -import { matchProcessRoute, matchProcessLogRoute, matchProjectRoute, matchCollectionRoute, matchFavoritesRoute, matchTrashRoute, matchRootRoute, matchSharedWithMeRoute, matchRunProcessRoute, matchWorkflowRoute, matchSearchResultsRoute, matchSshKeysRoute } from './routes';
 -import { loadProject, loadCollection, loadFavorites, loadTrash, loadProcess, loadProcessLog, loadSshKeys } from '~/store/workbench/workbench-actions';
++import { matchProcessRoute, matchProcessLogRoute, matchProjectRoute, matchCollectionRoute, matchFavoritesRoute, matchTrashRoute, matchRootRoute, matchSharedWithMeRoute, matchRunProcessRoute, matchWorkflowRoute, matchSearchResultsRoute, matchSshKeysRoute, matchRepositoriesRoute } from './routes';
++import { loadProject, loadCollection, loadFavorites, loadTrash, loadProcess, loadProcessLog, loadSshKeys, loadRepositories } from '~/store/workbench/workbench-actions';
  import { navigateToRootProject } from '~/store/navigation/navigation-action';
  import { loadSharedWithMe, loadRunProcess, loadWorkflow, loadSearchResults } from '~//store/workbench/workbench-actions';
  
@@@ -51,7 -51,7 +52,9 @@@ const handleLocationChange = (store: Ro
          store.dispatch(loadWorkflow);
      } else if (searchResultsMatch) {
          store.dispatch(loadSearchResults);
 +    } else if(repositoryMatch) {
 +        store.dispatch(loadRepositories);
+     } else if (sshKeysMatch) {
+         store.dispatch(loadSshKeys);
      }
  };
diff --cc src/routes/routes.ts
index 5dbecb4,b00b9fe..c9c2ae2
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@@ -78,5 -78,5 +79,8 @@@ export const matchWorkflowRoute = (rout
  export const matchSearchResultsRoute = (route: string) =>
      matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
  
 +export const matchRepositoriesRoute = (route: string) =>
-     matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
++    matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
++    
+ export const matchSshKeysRoute = (route: string) =>
 -    matchPath(route, { path: Routes.SSH_KEYS });
++    matchPath(route, { path: Routes.SSH_KEYS });
diff --cc src/services/services.ts
index 2bc955f,aeeb955..308505c
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@@ -24,7 -24,7 +24,8 @@@ import { ApiActions } from "~/services/
  import { WorkflowService } from "~/services/workflow-service/workflow-service";
  import { SearchService } from '~/services/search-service/search-service';
  import { PermissionService } from "~/services/permission-service/permission-service";
 +import { RepositoriesService } from '~/services/repositories-service/repositories-service';
+ import { AuthorizedKeysService } from '~/services/authorized-keys-service/authorized-keys-service';
  
  export type ServiceRepository = ReturnType<typeof createServices>;
  
diff --cc src/store/navigation/navigation-action.ts
index ce59969,57967c7..fc08f3a
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@@ -62,4 -62,4 +62,6 @@@ export const navigateToRunProcess = pus
  
  export const navigateToSearchResults = push(Routes.SEARCH_RESULTS);
  
 -export const navigateToSshKeys= push(Routes.SSH_KEYS);
 +export const navigateToRepositories = push(Routes.REPOSITORIES);
++
++export const navigateToSshKeys= push(Routes.SSH_KEYS);
diff --cc src/store/workbench/workbench-actions.ts
index c6440fd,5cc9ea3..5e33661
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@@ -33,15 -33,16 +33,16 @@@ import * as processUpdateActions from '
  import * as processCopyActions from '~/store/processes/process-copy-actions';
  import { trashPanelColumns } from "~/views/trash-panel/trash-panel";
  import { loadTrashPanel, trashPanelActions } from "~/store/trash-panel/trash-panel-action";
 -import { initProcessLogsPanel } from '../process-logs-panel/process-logs-panel-actions';
 +import { initProcessLogsPanel } from '~/store/process-logs-panel/process-logs-panel-actions';
  import { loadProcessPanel } from '~/store/process-panel/process-panel-actions';
  import { sharedWithMePanelActions } from '~/store/shared-with-me-panel/shared-with-me-panel-actions';
 -import { loadSharedWithMePanel } from '../shared-with-me-panel/shared-with-me-panel-actions';
 +import { loadSharedWithMePanel } from '~/store/shared-with-me-panel/shared-with-me-panel-actions';
  import { CopyFormDialogData } from '~/store/copy-dialog/copy-dialog';
  import { loadWorkflowPanel, workflowPanelActions } from '~/store/workflow-panel/workflow-panel-actions';
+ import { loadSshKeysPanel } from '~/store/auth/auth-action';
  import { workflowPanelColumns } from '~/views/workflow-panel/workflow-panel-view';
  import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions';
 -import { getProgressIndicator } from '../progress-indicator/progress-indicator-reducer';
 +import { getProgressIndicator } from '~/store/progress-indicator/progress-indicator-reducer';
  import { ResourceKind, extractUuidKind } from '~/models/resource';
  import { FilterBuilder } from '~/services/api/filter-builder';
  import { GroupContentsResource } from '~/services/groups-service/groups-service';
@@@ -391,12 -391,11 +392,17 @@@ export const loadSearchResults = handle
          await dispatch(loadSearchResultsPanel());
      });
  
 +export const loadRepositories = handleFirstTimeLoad(
 +    async (dispatch: Dispatch<any>) => {
 +        await dispatch(loadRepositoriesPanel());
 +        dispatch(setBreadcrumbs([{ label: 'Repositories' }]));
 +    });
 +
+ export const loadSshKeys = handleFirstTimeLoad(
+     async (dispatch: Dispatch<any>) => {
+         await dispatch(loadSshKeysPanel());
+     });
+ 
  const finishLoadingProject = (project: GroupContentsResource | string) =>
      async (dispatch: Dispatch<any>) => {
          const uuid = typeof project === 'string' ? project : project.uuid;
diff --cc src/validators/validators.tsx
index 37c1bd3,1980ed8..c601df1
--- a/src/validators/validators.tsx
+++ b/src/validators/validators.tsx
@@@ -21,4 -22,5 +22,7 @@@ export const MOVE_TO_VALIDATION = [requ
  
  export const PROCESS_NAME_VALIDATION = [require, maxLength(255)];
  
- export const REPOSITORY_NAME_VALIDATION = [require, maxLength(255)];
++export const REPOSITORY_NAME_VALIDATION = [require, maxLength(255)];
++
+ export const SSH_KEY_PUBLIC_VALIDATION = [require, isRsaKey, maxLength(1024)];
 -export const SSH_KEY_NAME_VALIDATION = [require, maxLength(255)];
++export const SSH_KEY_NAME_VALIDATION = [require, maxLength(255)];
diff --cc src/views-components/main-app-bar/account-menu.tsx
index c643fef,ee863a2..f00c678
--- a/src/views-components/main-app-bar/account-menu.tsx
+++ b/src/views-components/main-app-bar/account-menu.tsx
@@@ -8,10 -8,10 +8,11 @@@ import { User, getUserFullname } from "
  import { DropdownMenu } from "~/components/dropdown-menu/dropdown-menu";
  import { UserPanelIcon } from "~/components/icon/icon";
  import { DispatchProp, connect } from 'react-redux';
- import { logout } from "~/store/auth/auth-action";
+ import { logout } from '~/store/auth/auth-action';
  import { RootState } from "~/store/store";
 -import { openCurrentTokenDialog } from '../../store/current-token-dialog/current-token-dialog-actions';
 +import { openCurrentTokenDialog } from '~/store/current-token-dialog/current-token-dialog-actions';
 +import { openRepositoriesPanel } from "~/store/repositories/repositories-actions";
+ import { navigateToSshKeys } from '~/store/navigation/navigation-action';
  
  interface AccountMenuProps {
      user?: User;
@@@ -31,8 -31,8 +32,9 @@@ export const AccountMenu = connect(mapS
                  <MenuItem>
                      {getUserFullname(user)}
                  </MenuItem>
 +                <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</MenuItem>
                  <MenuItem onClick={() => dispatch(openCurrentTokenDialog)}>Current token</MenuItem>
+                 <MenuItem onClick={() => dispatch(navigateToSshKeys)}>Ssh Keys</MenuItem>
                  <MenuItem>My account</MenuItem>
                  <MenuItem onClick={() => dispatch(logout())}>Logout</MenuItem>
              </DropdownMenu>
diff --cc src/views/repositories-panel/repositories-panel.tsx
index 262f3cc,0000000..cfe59f0
mode 100644,000000..100644
--- a/src/views/repositories-panel/repositories-panel.tsx
+++ b/src/views/repositories-panel/repositories-panel.tsx
@@@ -1,153 -1,0 +1,154 @@@
 +// Copyright (C) The Arvados Authors. All rights reserved.
 +//
 +// SPDX-License-Identifier: AGPL-3.0
 +
 +import * as React from 'react';
 +import { connect } from 'react-redux';
 +import { Grid, Typography, Button, Card, CardContent, TableBody, TableCell, TableHead, TableRow, Table, Tooltip, IconButton } from '@material-ui/core';
 +import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
 +import { ArvadosTheme } from '~/common/custom-theme';
 +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, openRepositoriesSampleGitDialog, openRepositoryCreateDialog } from '~/store/repositories/repositories-actions';
 +import { RepositoryResource } from '~/models/repositories';
 +import { openRepositoryContextMenu } from '~/store/context-menu/context-menu-actions';
++import { Routes } from '~/routes/routes';
 +
 +
 +type CssRules = 'link' | 'button' | 'icon' | 'iconRow' | 'moreOptionsButton' | 'moreOptions' | 'cloneUrls';
 +
 +const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
 +    link: {
 +        textDecoration: 'none',
 +        color: theme.palette.primary.main,
 +        "&:hover": {
 +            color: theme.palette.primary.dark,
 +            transition: 'all 0.5s ease'
 +        }
 +    },
 +    button: {
 +        textAlign: 'right',
 +        alignSelf: 'center'
 +    },
 +    icon: {
 +        cursor: 'pointer',
 +        color: theme.palette.grey["500"],
 +        "&:hover": {
 +            color: theme.palette.common.black,
 +            transition: 'all 0.5s ease'
 +        }
 +    },
 +    iconRow: {
 +        paddingTop: theme.spacing.unit * 2,
 +        textAlign: 'right'
 +    },
 +    moreOptionsButton: {
 +        padding: 0
 +    },
 +    moreOptions: {
 +        textAlign: 'right',
 +        '&:last-child': {
 +            paddingRight: 0
 +        }
 +    },
 +    cloneUrls: {
 +        whiteSpace: 'pre-wrap'
 +    }
 +});
 +
 +const mapStateToProps = (state: RootState) => {
 +    return {
 +        repositories: state.repositories.items
 +    };
 +};
 +
 +const mapDispatchToProps = (dispatch: Dispatch): Pick<RepositoriesActionProps, 'onOptionsMenuOpen' | 'loadRepositories' | 'openRepositoriesSampleGitDialog' | 'openRepositoryCreateDialog'> => ({
 +    loadRepositories: () => dispatch<any>(loadRepositoriesData()),
 +    onOptionsMenuOpen: (event, index, repository) => {
 +        dispatch<any>(openRepositoryContextMenu(event, index, repository));
 +    },
 +    openRepositoriesSampleGitDialog: () => dispatch<any>(openRepositoriesSampleGitDialog()),
 +    openRepositoryCreateDialog: () => dispatch<any>(openRepositoryCreateDialog())
 +});
 +
 +interface RepositoriesActionProps {
 +    loadRepositories: () => void;
 +    onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, index: number, repository: RepositoryResource) => void;
 +    openRepositoriesSampleGitDialog: () => void;
 +    openRepositoryCreateDialog: () => void;
 +}
 +
 +interface RepositoriesDataProps {
 +    repositories: RepositoryResource[];
 +}
 +
 +
 +type RepositoriesProps = RepositoriesDataProps & RepositoriesActionProps & WithStyles<CssRules>;
 +
 +export const RepositoriesPanel = compose(
 +    withStyles(styles),
 +    connect(mapStateToProps, mapDispatchToProps))(
 +        class extends React.Component<RepositoriesProps> {
 +            componentDidMount() {
 +                this.props.loadRepositories();
 +            }
 +            render() {
 +                const { classes, repositories, onOptionsMenuOpen, openRepositoriesSampleGitDialog, openRepositoryCreateDialog } = this.props;
 +                return (
 +                    <Card>
 +                        <CardContent>
 +                            <Grid container direction="row">
 +                                <Grid item xs={8}>
 +                                    <Typography variant="body2">
 +                                        When you are using an Arvados virtual machine, you should clone the https:// URLs. This will authenticate automatically using your API token. <br />
-                                         In order to clone git repositories using SSH, <Link to='' className={classes.link}>add an SSH key to your account</Link> and clone the git@ URLs.
++                                        In order to clone git repositories using SSH, <Link to={Routes.SSH_KEYS} className={classes.link}>add an SSH key to your account</Link> and clone the git@ URLs.
 +                                    </Typography>
 +                                </Grid>
 +                                <Grid item xs={4} className={classes.button}>
 +                                    <Button variant="contained" color="primary" onClick={openRepositoryCreateDialog}>
 +                                        <AddIcon /> NEW REPOSITORY
 +                                    </Button>
 +                                </Grid>
 +                            </Grid>
 +                            <Grid item xs={12}>
 +                                <div className={classes.iconRow}>
 +                                    <Tooltip title="Sample git quick start">
 +                                        <IconButton className={classes.moreOptionsButton} onClick={openRepositoriesSampleGitDialog}>
 +                                            <HelpIcon className={classes.icon} />
 +                                        </IconButton>
 +                                    </Tooltip>
 +                                </div>
 +                            </Grid>
 +                            <Grid item xs={12}>
 +                                {repositories && <Table>
 +                                    <TableHead>
 +                                        <TableRow>
 +                                            <TableCell>Name</TableCell>
 +                                            <TableCell>URL</TableCell>
 +                                            <TableCell />
 +                                        </TableRow>
 +                                    </TableHead>
 +                                    <TableBody>
 +                                        {repositories.map((repository, index) =>
 +                                            <TableRow key={index}>
 +                                                <TableCell>{repository.name}</TableCell>
 +                                                <TableCell className={classes.cloneUrls}>{repository.cloneUrls.join("\n")}</TableCell>
 +                                                <TableCell className={classes.moreOptions}>
 +                                                    <Tooltip title="More options" disableFocusListener>
 +                                                        <IconButton onClick={event => onOptionsMenuOpen(event, index, repository)} className={classes.moreOptionsButton}>
 +                                                            <MoreOptionsIcon />
 +                                                        </IconButton>
 +                                                    </Tooltip>
 +                                                </TableCell>
 +                                            </TableRow>)}
 +                                    </TableBody>
 +                                </Table>}
 +                            </Grid>
 +                        </CardContent>
 +                    </Card>
 +                );
 +            }
 +        }
 +    );
diff --cc src/views/workbench/workbench.tsx
index eee9911,3a63ea3..ebdf57c
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@@ -48,11 -49,7 +49,12 @@@ import { SharingDialog } from '~/views-
  import { AdvancedTabDialog } from '~/views-components/advanced-tab-dialog/advanced-tab-dialog';
  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';
 +import { RepositoryAttributesDialog } from '~/views-components/repository-attributes-dialog/repository-attributes-dialog';
 +import { CreateRepositoryDialog } from '~/views-components/dialog-forms/create-repository-dialog';
 +import { RemoveRepositoryDialog } from '~/views-components/repository-remove-dialog/repository-remove-dialog';
+ import { CreateSshKeyDialog } from '~/views-components/dialog-forms/create-ssh-key-dialog';
  
  type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content';
  
@@@ -122,7 -119,7 +124,8 @@@ export const WorkbenchPanel 
                                  <Route path={Routes.RUN_PROCESS} component={RunProcessPanel} />
                                  <Route path={Routes.WORKFLOWS} component={WorkflowPanel} />
                                  <Route path={Routes.SEARCH_RESULTS} component={SearchResultsPanel} />
 +                                <Route path={Routes.REPOSITORIES} component={RepositoriesPanel} />
+                                 <Route path={Routes.SSH_KEYS} component={SshKeyPanel} />
                              </Switch>
                          </Grid>
                      </Grid>
@@@ -138,7 -135,7 +141,8 @@@
              <CopyProcessDialog />
              <CreateCollectionDialog />
              <CreateProjectDialog />
 +            <CreateRepositoryDialog />
+             <CreateSshKeyDialog />
              <CurrentTokenDialog />
              <FileRemoveDialog />
              <FilesUploadCollectionDialog />

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list