15856: Merge branch 'master' into 15856-illegal-chars-warning
authorLucas Di Pentima <ldipentima@veritasgenetics.com>
Tue, 26 Nov 2019 21:01:45 +0000 (18:01 -0300)
committerLucas Di Pentima <ldipentima@veritasgenetics.com>
Tue, 26 Nov 2019 21:01:45 +0000 (18:01 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <ldipentima@veritasgenetics.com>

src/components/breadcrumbs/breadcrumbs.tsx
src/components/warning/warning.tsx [new file with mode: 0644]
src/views-components/project-tree/project-tree.test.tsx [deleted file]
src/views-components/project-tree/project-tree.tsx [deleted file]
src/views/collection-panel/collection-panel.tsx

index 444ac75ef51b97c0f1df5ba8cf55b828bbf571c1..207823307c9284b31fa0a4ca969f974b74a9ea23 100644 (file)
@@ -6,6 +6,7 @@ import * as React from 'react';
 import { Button, Grid, StyleRulesCallback, WithStyles, Typography, Tooltip } from '@material-ui/core';
 import ChevronRightIcon from '@material-ui/icons/ChevronRight';
 import { withStyles } from '@material-ui/core';
+import { IllegalNamingWarning } from '../warning/warning';
 
 export interface Breadcrumb {
     label: string;
@@ -37,8 +38,10 @@ export const Breadcrumbs = withStyles(styles)(
     {
         items.map((item, index) => {
             const isLastItem = index === items.length - 1;
+            const isFirstItem = index === 0;
             return (
                 <React.Fragment key={index}>
+                    {isFirstItem ? null : <IllegalNamingWarning name={item.label} />}
                     <Tooltip title={item.label}>
                         <Button
                             color="inherit"
diff --git a/src/components/warning/warning.tsx b/src/components/warning/warning.tsx
new file mode 100644 (file)
index 0000000..1a8f445
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from "react";
+import { WarningIcon } from "~/components/icon/icon";
+import { Tooltip } from "@material-ui/core";
+
+interface WarningComponentProps {
+    text: string;
+    rules: RegExp[];
+    message: string;
+}
+
+export const WarningComponent = ({ text, rules, message }: WarningComponentProps) =>
+    rules.find(aRule => text.match(aRule) !== null)
+    ? message
+        ? <Tooltip title={message}><WarningIcon /></Tooltip>
+        : <WarningIcon />
+    : null;
+
+interface IllegalNamingWarningProps {
+    name: string;
+}
+
+export const IllegalNamingWarning = ({ name }: IllegalNamingWarningProps) =>
+    <WarningComponent
+        text={name} rules={[/\//, /^\.{1,2}$/]}
+        message="Names being '.', '..' or including '/' cause issues with WebDAV, please edit it to something different." />;
\ No newline at end of file
diff --git a/src/views-components/project-tree/project-tree.test.tsx b/src/views-components/project-tree/project-tree.test.tsx
deleted file mode 100644 (file)
index 18efdaf..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import * as React from 'react';
-import * as Enzyme from 'enzyme';
-import { mount } from 'enzyme';
-import * as Adapter from 'enzyme-adapter-react-16';
-import ListItemIcon from '@material-ui/core/ListItemIcon';
-import { Collapse } from '@material-ui/core';
-import CircularProgress from '@material-ui/core/CircularProgress';
-
-import { ProjectTree } from './project-tree';
-import { TreeItem, TreeItemStatus } from '../../components/tree/tree';
-import { ProjectResource } from '../../models/project';
-import { mockProjectResource } from '../../models/test-utils';
-
-Enzyme.configure({ adapter: new Adapter() });
-
-describe("ProjectTree component", () => {
-
-    it("should render ListItemIcon", () => {
-        const project: TreeItem<ProjectResource> = {
-            data: mockProjectResource(),
-            id: "3",
-            open: true,
-            active: true,
-            status: TreeItemStatus.PENDING
-        };
-        const wrapper = mount(<ProjectTree
-            projects={[project]}
-            toggleOpen={jest.fn()}
-            toggleActive={jest.fn()}
-            onContextMenu={jest.fn()} />);
-
-        expect(wrapper.find(ListItemIcon)).toHaveLength(2);
-    });
-
-    it("should render Collapse", () => {
-        const project: Array<TreeItem<ProjectResource>> = [
-            {
-                data: mockProjectResource(),
-                id: "3",
-                open: true,
-                active: true,
-                status: TreeItemStatus.LOADED,
-                items: [
-                    {
-                        data: mockProjectResource(),
-                        id: "3",
-                        open: true,
-                        active: true,
-                        status: TreeItemStatus.PENDING
-                    }
-                ]
-            }
-        ];
-        const wrapper = mount(<ProjectTree
-            projects={project}
-            toggleOpen={jest.fn()}
-            toggleActive={jest.fn()}
-            onContextMenu={jest.fn()} />);
-
-        expect(wrapper.find(Collapse)).toHaveLength(1);
-    });
-
-    it("should render CircularProgress", () => {
-        const project: TreeItem<ProjectResource> = {
-            data: mockProjectResource(),
-            id: "3",
-            open: false,
-            active: true,
-            status: TreeItemStatus.PENDING
-        };
-        const wrapper = mount(<ProjectTree
-            projects={[project]}
-            toggleOpen={jest.fn()}
-            toggleActive={jest.fn()}
-            onContextMenu={jest.fn()} />);
-
-        expect(wrapper.find(CircularProgress)).toHaveLength(1);
-    });
-});
diff --git a/src/views-components/project-tree/project-tree.tsx b/src/views-components/project-tree/project-tree.tsx
deleted file mode 100644 (file)
index b615f5b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import * as React from 'react';
-import { ReactElement } from 'react';
-import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
-import { Tree, TreeItem } from '~/components/tree/tree';
-import { ProjectResource } from '~/models/project';
-import { ProjectIcon } from '~/components/icon/icon';
-import { ArvadosTheme } from '~/common/custom-theme';
-import { ListItemTextIcon } from '~/components/list-item-text-icon/list-item-text-icon';
-
-type CssRules = 'root';
-
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
-    root: {
-        marginLeft: `${theme.spacing.unit * 1.5}px`,
-    }
-});
-
-export interface ProjectTreeProps<T> {
-    projects: Array<TreeItem<ProjectResource>>;
-    toggleOpen: (event: React.MouseEvent<HTMLElement>, item: TreeItem<T>) => void;
-    toggleActive: (event: React.MouseEvent<HTMLElement>, item: TreeItem<T>) => void;
-    onContextMenu: (event: React.MouseEvent<HTMLElement>, item: TreeItem<ProjectResource>) => void;
-}
-
-export const ProjectTree = withStyles(styles)(
-    class ProjectTreeGeneric<T> extends React.Component<ProjectTreeProps<T> & WithStyles<CssRules>> {
-        render(): ReactElement<any> {
-            const { classes, projects, toggleOpen, toggleActive, onContextMenu } = this.props;
-            return (
-                <div className={classes.root}>
-                    <Tree items={projects}
-                        onContextMenu={onContextMenu}
-                        toggleItemOpen={toggleOpen}
-                        toggleItemActive={toggleActive}
-                        render={
-                            (project: TreeItem<ProjectResource>) =>
-                                <ListItemTextIcon
-                                    icon={ProjectIcon}
-                                    name={project.data.name}
-                                    isActive={project.active}
-                                    hasMargin={true} />
-                        } />
-                </div>
-            );
-        }
-    }
-);
index 99edc1a26912e8822d730d7291784b819ec2ab87..b92557f9de35b59557318ea6a4ba8b69f5f3c588 100644 (file)
@@ -24,6 +24,7 @@ import { formatFileSize } from "~/common/formatters";
 import { openDetailsPanel } from '~/store/details-panel/details-panel-action';
 import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
 import { PropertyChipComponent } from '~/views-components/resource-properties-form/property-chip';
+import { IllegalNamingWarning } from '~/components/warning/warning';
 
 type CssRules = 'card' | 'iconHeader' | 'tag' | 'label' | 'value' | 'link';
 
@@ -89,7 +90,7 @@ export const CollectionPanel = withStyles(styles)(
                                         </IconButton>
                                     </Tooltip>
                                 }
-                                title={item && item.name}
+                                title={item && <span><IllegalNamingWarning name={item.name}/>{item.name}</span>}
                                 titleTypographyProps={this.titleProps}
                                 subheader={item && item.description}
                                 subheaderTypographyProps={this.titleProps} />