瀏覽代碼

Merge pull request #1 from zilliztech/uxd-622

[UXD-622] add connect page
nameczz 4 年之前
父節點
當前提交
efb650de72
共有 89 個文件被更改,包括 416 次插入1618 次删除
  1. 5 0
      client/src/assets/icons/milvus.svg
  2. 二進制
      client/src/assets/imgs/connectContainer/background.png
  3. 二進制
      client/src/assets/imgs/logo.png
  4. 0 49
      client/src/components/__test__/filter/Filter.spec.tsx
  5. 1 2
      client/src/components/__test__/grid/Toolbar.spec.tsx
  6. 2 2
      client/src/components/__test__/textField/customInput.spec.tsx
  7. 2 1
      client/src/components/copy/Copy.tsx
  8. 0 179
      client/src/components/customCard/CustomCard.tsx
  9. 0 19
      client/src/components/customCard/Types.ts
  10. 1 1
      client/src/components/customDialog/CustomDialog.tsx
  11. 3 9
      client/src/components/customInput/CustomInput.tsx
  12. 2 2
      client/src/components/customInput/SearchInput.tsx
  13. 0 0
      client/src/components/customInput/Types.ts
  14. 1 1
      client/src/components/customSelector/CustomGroupedSelect.tsx
  15. 2 2
      client/src/components/customSnackBar/CustomSnackBar.tsx
  16. 1 1
      client/src/components/customTabList/CustomTabList.tsx
  17. 0 162
      client/src/components/filter/Filter.tsx
  18. 0 5
      client/src/components/filter/Types.ts
  19. 1 1
      client/src/components/grid/ActionBar.tsx
  20. 2 2
      client/src/components/grid/Table.tsx
  21. 2 1
      client/src/components/grid/TableHead.tsx
  22. 1 1
      client/src/components/grid/TableSwitch.tsx
  23. 3 17
      client/src/components/grid/ToolBar.tsx
  24. 2 3
      client/src/components/grid/Types.ts
  25. 2 7
      client/src/components/grid/index.tsx
  26. 6 2
      client/src/components/icons/Icons.tsx
  27. 2 2
      client/src/components/icons/Types.ts
  28. 2 1
      client/src/components/layout/GlobalEffect.tsx
  29. 2 2
      client/src/components/layout/GlobalToolbar.tsx
  30. 2 49
      client/src/components/layout/Header.tsx
  31. 10 10
      client/src/components/layout/Layout.tsx
  32. 15 13
      client/src/components/menu/NavMenu.tsx
  33. 2 1
      client/src/components/menu/SimpleMenu.tsx
  34. 1 1
      client/src/components/status/Status.tsx
  35. 1 1
      client/src/components/status/StatusIcon.tsx
  36. 0 6
      client/src/consts/Polling.ts
  37. 0 6
      client/src/consts/Reducer.ts
  38. 0 1
      client/src/consts/WebSocket.ts
  39. 5 150
      client/src/context/Root.tsx
  40. 0 1
      client/src/context/Types.ts
  41. 0 37
      client/src/hooks/CommonStyle.ts
  42. 1 3
      client/src/hooks/Form.ts
  43. 0 29
      client/src/hooks/Polling.ts
  44. 0 29
      client/src/hooks/__test__/CommonStyle.spec.tsx
  45. 6 1
      client/src/hooks/__test__/Form.spec.tsx
  46. 3 15
      client/src/i18n/cn/button.ts
  47. 0 13
      client/src/i18n/cn/card.ts
  48. 0 31
      client/src/i18n/cn/collection.ts
  49. 7 59
      client/src/i18n/cn/common.ts
  50. 0 12
      client/src/i18n/cn/connect.ts
  51. 0 5
      client/src/i18n/cn/data.ts
  52. 0 43
      client/src/i18n/cn/database.ts
  53. 0 8
      client/src/i18n/cn/dialog.ts
  54. 0 15
      client/src/i18n/cn/help.ts
  55. 0 24
      client/src/i18n/cn/index.ts
  56. 0 29
      client/src/i18n/cn/partition.ts
  57. 0 20
      client/src/i18n/cn/password.ts
  58. 0 47
      client/src/i18n/cn/query.ts
  59. 0 6
      client/src/i18n/cn/signUp.ts
  60. 0 6
      client/src/i18n/cn/verify.ts
  61. 3 17
      client/src/i18n/cn/warning.ts
  62. 3 16
      client/src/i18n/en/button.ts
  63. 0 13
      client/src/i18n/en/card.ts
  64. 0 31
      client/src/i18n/en/collection.ts
  65. 7 60
      client/src/i18n/en/common.ts
  66. 0 12
      client/src/i18n/en/connect.ts
  67. 0 5
      client/src/i18n/en/data.ts
  68. 0 42
      client/src/i18n/en/database.ts
  69. 0 8
      client/src/i18n/en/dialog.ts
  70. 0 15
      client/src/i18n/en/help.ts
  71. 0 24
      client/src/i18n/en/index.ts
  72. 0 29
      client/src/i18n/en/partition.ts
  73. 0 21
      client/src/i18n/en/password.ts
  74. 0 47
      client/src/i18n/en/query.ts
  75. 0 6
      client/src/i18n/en/signUp.ts
  76. 0 6
      client/src/i18n/en/verify.ts
  77. 3 18
      client/src/i18n/en/warning.ts
  78. 0 52
      client/src/i18n/index.ts
  79. 4 3
      client/src/index.tsx
  80. 111 0
      client/src/pages/connect/Connect.tsx
  81. 8 8
      client/src/pages/connect/ConnectContainer.tsx
  82. 0 0
      client/src/pages/overview/Overview.tsx
  83. 8 2
      client/src/router/Config.ts
  84. 1 1
      client/src/router/Router.tsx
  85. 136 0
      client/src/styles/theme.ts
  86. 17 0
      client/src/utils/Form.ts
  87. 0 27
      client/src/utils/Time.ts
  88. 0 10
      client/src/utils/User.ts
  89. 17 0
      client/src/utils/__test__/Form.spec.ts

+ 5 - 0
client/src/assets/icons/milvus.svg

@@ -0,0 +1,5 @@
+<svg width="44" height="31" viewBox="0 0 44 31" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M30.4251 5.17564C24.7152 -0.554964 15.4562 -0.554964 9.74634 5.17564L0.41376 14.5419C-0.13792 15.0962 -0.13792 15.9886 0.41376 16.5429L9.74634 25.9091C15.4562 31.6397 24.7152 31.6397 30.4251 25.9185C36.1442 20.1973 36.1442 10.9062 30.4251 5.17564ZM28.2184 23.166C24.0256 27.3747 17.2216 27.3747 13.0288 23.166L6.16042 16.2798C5.75586 15.8759 5.75586 15.2183 6.16042 14.8049L13.0196 7.9282C17.2124 3.7195 24.0165 3.7195 28.2092 7.9282C32.4112 12.1369 32.4112 18.9573 28.2184 23.166Z" fill="#4FC4F9"/>
+<path d="M42.6532 14.5515L38.5431 10.3522C38.2949 10.0986 37.8811 10.3334 37.9639 10.681C38.6719 13.8845 38.6719 17.2289 37.9639 20.4324C37.8903 20.78 38.3041 21.0055 38.5431 20.7612L42.6532 16.5619C43.1956 15.9983 43.1956 15.1058 42.6532 14.5515Z" fill="#4FC4F9"/>
+<path d="M20.6691 22.9126C24.6453 22.9126 27.8686 19.6193 27.8686 15.5568C27.8686 11.4942 24.6453 8.20093 20.6691 8.20093C16.693 8.20093 13.4697 11.4942 13.4697 15.5568C13.4697 19.6193 16.693 22.9126 20.6691 22.9126Z" fill="#4FC4F9"/>
+</svg>

二進制
client/src/assets/imgs/connectContainer/background.png


二進制
client/src/assets/imgs/logo.png


+ 0 - 49
client/src/components/__test__/filter/Filter.spec.tsx

@@ -1,49 +0,0 @@
-import { render, unmountComponentAtNode } from 'react-dom';
-import { act } from 'react-dom/test-utils';
-import Filter from '../../filter/Filter';
-import { fireEvent } from '@testing-library/react';
-
-let container: any = null;
-
-// jest.mock('../../customButton/CustomButton', () => {
-//   return props => {
-//     <button>{props.children}</button>;
-//   };
-// });
-
-jest.mock('@material-ui/core/styles/makeStyles', () => {
-  return () => () => ({});
-});
-
-describe('Test Filter', () => {
-  beforeEach(() => {
-    container = document.createElement('div');
-    document.body.appendChild(container);
-  });
-
-  afterEach(() => {
-    unmountComponentAtNode(container);
-    container.remove();
-    container = null;
-  });
-
-  test('test filter props', () => {
-    const options = [
-      { label: 'a', value: 1 },
-      { label: 'b', value: 2 },
-    ];
-    const filterSpy = jest.fn();
-    act(() => {
-      render(
-        <Filter
-          filterOptions={options}
-          filterTitle="test"
-          onFilter={filterSpy}
-        />,
-        container
-      );
-    });
-    fireEvent.click(container.querySelector('button'));
-    expect(container.querySelector('p').textContent).toEqual('test');
-  });
-});

+ 1 - 2
client/src/components/__test__/grid/Toolbar.spec.tsx

@@ -15,14 +15,13 @@ jest.mock('../../customButton/CustomButton', () => {
   };
 });
 
-jest.mock('../../textField/SearchInput', () => {
+jest.mock('../../customInput/SearchInput', () => {
   return props => {
     return <div>{props.children}</div>;
   };
 });
 
 jest.mock('@material-ui/core/TextField', () => {
-  console.log('test enter');
   return props => {
     return <input {...props} className="input" />;
   };

+ 2 - 2
client/src/components/__test__/textField/customInput.spec.tsx

@@ -1,12 +1,12 @@
 import { fireEvent } from '@testing-library/react';
 import { render, unmountComponentAtNode } from 'react-dom';
 import { act } from 'react-dom/test-utils';
-import CustomInput from '../../textField/CustomInput';
+import CustomInput from '../../customInput/CustomInput';
 import {
   IAdornmentConfig,
   IIconConfig,
   ITextfieldConfig,
-} from '../../textField/Types';
+} from '../../customInput/Types';
 
 let container: any = null;
 

+ 2 - 1
client/src/components/copy/Copy.tsx

@@ -1,5 +1,6 @@
 import { IconButton, makeStyles } from '@material-ui/core';
-import React, { useState } from 'react';
+import { useState } from 'react';
+import React from 'react';
 import { useTranslation } from 'react-i18next';
 import { copyToCommand } from '../../utils/Common';
 import CustomToolTip from '../customToolTip/CustomToolTip';

+ 0 - 179
client/src/components/customCard/CustomCard.tsx

@@ -1,179 +0,0 @@
-import {
-  Card,
-  CardActions,
-  CardContent,
-  CardHeader,
-  IconButton,
-  makeStyles,
-  Menu,
-  MenuItem,
-  Theme,
-  Tooltip,
-} from '@material-ui/core';
-import React, { FC } from 'react';
-import icons from '../icons/Icons';
-import { ICustomCardProps, IMenu } from './Types';
-
-const getStyles = makeStyles((theme: Theme) => ({
-  root: {
-    boxShadow: 'none',
-    filter: 'drop-shadow(0px 8px 24px rgba(0, 0, 0, 0.1))',
-    width: '100%',
-
-    position: 'relative',
-  },
-  menuItem: {
-    minWidth: '160px',
-    textTransform: 'capitalize',
-
-    '&:hover': {
-      backgroundColor: theme.palette.zilliz.light,
-    },
-  },
-  menuPaper: {
-    boxShadow: '0px 8px 16px rgba(0, 0, 0, 0.15)',
-  },
-  menuContent: {
-    padding: 0,
-
-    '&:last-child': {
-      paddingBottom: 0,
-    },
-  },
-  actions: {
-    '&:hover': {
-      background:
-        'linear-gradient(0deg, rgba(18, 195, 244, 0.05), rgba(18, 195, 244, 0.05)), #fff',
-
-      transition: 'all 0.3s',
-    },
-  },
-
-  actionsDisable: {
-    '&:hover': {
-      backgroundColor: '#fff',
-    },
-  },
-  actionBtn: {
-    color: theme.palette.primary.main,
-  },
-
-  mask: {
-    position: 'absolute',
-    top: 0,
-    right: 0,
-    left: 0,
-    bottom: 0,
-    backgroundColor: 'rgba(196, 196, 196, 0.5)',
-    zIndex: theme.zIndex.modal,
-  },
-}));
-
-const CustomCard: FC<ICustomCardProps> = props => {
-  const {
-    showCardHeaderTitle = true,
-    cardHeaderTitle = '',
-    menu = [],
-    content,
-    actions,
-    wrapperClassName = '',
-    showMask,
-    actionsDisabled = false,
-  } = props;
-  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
-
-  const handleMoreClick = (event: React.MouseEvent<HTMLButtonElement>) => {
-    setAnchorEl(event.currentTarget);
-  };
-
-  const handleMenuClose = () => {
-    setAnchorEl(null);
-  };
-
-  const classes = getStyles();
-
-  const handleClick = (event: any, m: IMenu) => {
-    if (m.onClick) {
-      m.onClick(event);
-    }
-
-    handleMenuClose();
-  };
-
-  return (
-    <Card className={`${classes.root} ${wrapperClassName}`}>
-      {showMask && <div className={classes.mask}></div>}
-      <CardHeader
-        action={
-          menu.length > 0 && (
-            <>
-              <IconButton aria-label="settings" onClick={handleMoreClick}>
-                {icons.more({ classes: { root: classes.actionBtn } })}
-              </IconButton>
-              <Menu
-                anchorEl={anchorEl}
-                disableScrollLock={true}
-                keepMounted
-                open={Boolean(anchorEl)}
-                onClose={handleMenuClose}
-                getContentAnchorEl={null}
-                anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
-                transformOrigin={{ vertical: 'top', horizontal: 'center' }}
-                classes={{ paper: classes.menuPaper }}
-              >
-                {menu.map((m, index) =>
-                  typeof m.label === 'string' ? (
-                    m.tip ? (
-                      <Tooltip
-                        key={m.label}
-                        title={m.tip}
-                        placement="right-end"
-                      >
-                        <span style={{ display: 'block' }}>
-                          <MenuItem
-                            classes={{ root: classes.menuItem }}
-                            onClick={event => handleClick(event, m)}
-                            disabled={m.disabled}
-                          >
-                            {m.label}
-                          </MenuItem>
-                        </span>
-                      </Tooltip>
-                    ) : (
-                      <MenuItem
-                        classes={{ root: classes.menuItem }}
-                        key={m.label}
-                        onClick={event => handleClick(event, m)}
-                        disabled={m.disabled}
-                      >
-                        {m.label}
-                      </MenuItem>
-                    )
-                  ) : (
-                    <span key={index}>{m.label}</span>
-                  )
-                )}
-              </Menu>
-            </>
-          )
-        }
-        title={showCardHeaderTitle ? cardHeaderTitle : null}
-      />
-      <CardContent classes={{ root: classes.menuContent }}>
-        {content}
-      </CardContent>
-      {actions && (
-        <CardActions
-          classes={{
-            root: actionsDisabled ? classes.actionsDisable : classes.actions,
-          }}
-          disableSpacing
-        >
-          {actions}
-        </CardActions>
-      )}
-    </Card>
-  );
-};
-
-export default CustomCard;

+ 0 - 19
client/src/components/customCard/Types.ts

@@ -1,19 +0,0 @@
-import { ReactElement } from 'react';
-
-export interface IMenu {
-  label: string | ReactElement;
-  onClick?: (event: any) => void;
-  disabled?: boolean;
-  tip?: string | null;
-}
-
-export interface ICustomCardProps {
-  showCardHeaderTitle?: boolean;
-  cardHeaderTitle?: string | ReactElement;
-  menu?: IMenu[];
-  content: string | ReactElement;
-  actions?: ReactElement;
-  wrapperClassName?: string;
-  showMask?: boolean;
-  actionsDisabled?: boolean;
-}

+ 1 - 1
client/src/components/customDialog/CustomDialog.tsx

@@ -1,4 +1,4 @@
-import React, { FC } from 'react';
+import { FC } from 'react';
 import {
   DialogActions,
   DialogContent,

+ 3 - 9
client/src/components/textField/CustomInput.tsx → client/src/components/customInput/CustomInput.tsx

@@ -12,7 +12,7 @@ import {
   TextField,
 } from '@material-ui/core';
 import Icons from '../icons/Icons';
-import React, { ReactElement } from 'react';
+import { ReactElement } from 'react';
 import {
   IAdornmentConfig,
   IIconConfig,
@@ -148,14 +148,8 @@ const getIconInput = (
   checkValid: Function,
   validInfo: IValidInfo
 ): ReactElement => {
-  const {
-    icon,
-    inputType,
-    inputConfig,
-    containerClass,
-    spacing,
-    alignItems,
-  } = config;
+  const { icon, inputType, inputConfig, containerClass, spacing, alignItems } =
+    config;
   return (
     <Grid
       classes={{ container: `${containerClass || {}}` }}

+ 2 - 2
client/src/components/textField/SearchInput.tsx → client/src/components/customInput/SearchInput.tsx

@@ -1,5 +1,5 @@
 import { InputAdornment, makeStyles, TextField } from '@material-ui/core';
-import React, { FC, useState } from 'react';
+import { useRef, FC, useState } from 'react';
 import Icons from '../icons/Icons';
 import { SearchType } from './Types';
 
@@ -60,7 +60,7 @@ const SearchInput: FC<SearchType> = props => {
 
   const classes = useSearchStyles({ searched, showInput });
 
-  const inputRef = React.useRef<any>(null);
+  const inputRef = useRef<any>(null);
 
   const onIconClick = () => {
     setShowInput(true);

+ 0 - 0
client/src/components/textField/Types.ts → client/src/components/customInput/Types.ts


+ 1 - 1
client/src/components/customSelector/CustomGroupedSelect.tsx

@@ -7,7 +7,7 @@ import {
   Select,
   Theme,
 } from '@material-ui/core';
-import React, { FC } from 'react';
+import { FC } from 'react';
 import { GroupOption, ICustomGroupSelect } from './Types';
 
 const getStyles = makeStyles((theme: Theme) => ({

+ 2 - 2
client/src/components/customSnackBar/CustomSnackBar.tsx

@@ -1,4 +1,4 @@
-import React, { FC, SyntheticEvent } from 'react';
+import { forwardRef, FC, SyntheticEvent } from 'react';
 import { CustomSnackBarType } from './Types';
 import MuiAlert from '@material-ui/lab/Alert';
 import { Snackbar, makeStyles, Theme, createStyles } from '@material-ui/core';
@@ -7,7 +7,7 @@ import { TransitionProps } from '@material-ui/core/transitions/transition';
 
 // if we need to use slide component
 // snackbar content must use forwardRef to wrapper it
-const Alert = React.forwardRef((props: { [x: string]: any }, ref) => {
+const Alert = forwardRef((props: { [x: string]: any }, ref) => {
   return <MuiAlert ref={ref} elevation={6} variant="filled" {...props} />;
 });
 

+ 1 - 1
client/src/components/customTabList/CustomTabList.tsx

@@ -1,5 +1,5 @@
 import { Box, makeStyles, Tab, Tabs, Theme } from '@material-ui/core';
-import React, { FC, useState } from 'react';
+import { FC, useState } from 'react';
 import { ITabListProps, ITabPanel } from './Types';
 
 const useStyles = makeStyles((theme: Theme) => ({

+ 0 - 162
client/src/components/filter/Filter.tsx

@@ -1,162 +0,0 @@
-import React, { FC, useState, useEffect } from 'react';
-import CustomButton from '../customButton/CustomButton';
-import ICONS from '../icons/Icons';
-import {
-  Typography,
-  makeStyles,
-  Theme,
-  createStyles,
-  Button,
-} from '@material-ui/core';
-import { FilterType } from './Types';
-import Icons from '../icons/Icons';
-import ClickAwayListener from '@material-ui/core/ClickAwayListener';
-import { useTranslation } from 'react-i18next';
-
-const useStyles = makeStyles((theme: Theme) =>
-  createStyles({
-    root: {
-      position: 'relative',
-      display: 'inline-block',
-      margin: theme.spacing(0, 2),
-    },
-    count: {
-      display: 'flex',
-      justifyContent: 'center',
-      alignItems: 'center',
-      width: '16px',
-      height: '16px',
-      marginLeft: theme.spacing(1),
-      fontSize: '12px',
-      borderRadius: '50%',
-      backgroundColor: theme.palette.common.white,
-    },
-    options: {
-      position: 'absolute',
-      top: '120%',
-      width: '360px',
-      padding: theme.spacing(4, 3),
-      backgroundColor: theme.palette.common.white,
-      color: 'rgba(0, 0, 0, 0.33)',
-      border: '2px solid rgba(0, 0, 0, 0.15)',
-      zIndex: theme.zIndex.tooltip,
-    },
-    title: {
-      marginBottom: theme.spacing(1),
-      textTransform: 'uppercase',
-      boxShadow: 'initial',
-    },
-    btnRoot: {
-      color: theme.palette.common.black,
-      marginRight: theme.spacing(3),
-      opacity: 0.33,
-      '&:hover': {
-        color: theme.palette.common.black,
-        opacity: 0.6,
-      },
-    },
-    active: {
-      color: theme.palette.common.black,
-      opacity: 0.6,
-      backgroundColor: theme.palette.zilliz.light,
-    },
-    typoButton: {
-      textTransform: 'none',
-    },
-  })
-);
-
-const Filter: FC<FilterType> = props => {
-  const classes = useStyles();
-  const [selected, setSelected] = useState<string[]>([]);
-  const [show, setShow] = useState<boolean>(false);
-  const { t } = useTranslation('btn');
-
-  const { filterOptions = [], onFilter, filterTitle = '' } = props;
-
-  const handleClick = (e: React.MouseEvent) => {
-    setShow(!show);
-  };
-
-  const handleFilter = (value: string) => {
-    !selected.includes(value) && setSelected([...selected, value]);
-  };
-
-  const handleClose = (e: React.MouseEvent, value: string) => {
-    e.stopPropagation();
-    setSelected(v => v.filter(text => value !== text));
-  };
-
-  const CloseIcon = (props: { value: string }) => (
-    <>
-      {Icons.clear({
-        onClick: (e: React.MouseEvent) => handleClose(e, props.value),
-      })}
-    </>
-  );
-
-  useEffect(() => {
-    onFilter && onFilter(selected);
-  }, [selected, onFilter]);
-
-  const handleClickAway = () => {
-    setShow(false);
-  };
-
-  return (
-    <div className={classes.root}>
-      <CustomButton
-        size="small"
-        onClick={handleClick}
-        startIcon={ICONS.filter()}
-        color="primary"
-      >
-        <Typography variant="button">{t('filter')} </Typography>
-        {selected.length ? (
-          <Typography
-            className={classes.count}
-            variant="button"
-            component="span"
-          >
-            {selected.length}
-          </Typography>
-        ) : null}
-      </CustomButton>
-      {show && (
-        <ClickAwayListener onClickAway={handleClickAway}>
-          <div className={classes.options}>
-            <Typography className={classes.title}>{filterTitle}</Typography>
-            {filterOptions.map(v => (
-              <Button
-                key={v.value}
-                size="small"
-                color="default"
-                classes={{
-                  root: classes.btnRoot,
-                }}
-                className={selected.includes(v.value) ? classes.active : ''}
-                endIcon={
-                  selected.includes(v.value) ? (
-                    <CloseIcon value={v.value} />
-                  ) : null
-                }
-                onClick={() => {
-                  handleFilter(v.value);
-                }}
-              >
-                <Typography
-                  variant="button"
-                  classes={{ button: classes.typoButton }}
-                >
-                  {v.label}
-                </Typography>
-              </Button>
-            ))}
-          </div>
-        </ClickAwayListener>
-      )}
-    </div>
-  );
-};
-
-export default Filter;

+ 0 - 5
client/src/components/filter/Types.ts

@@ -1,5 +0,0 @@
-export type FilterType = {
-  filterOptions?: { label: string; value: any }[];
-  onFilter?: (selected: any[]) => void;
-  filterTitle?: string;
-};

+ 1 - 1
client/src/components/grid/ActionBar.tsx

@@ -1,4 +1,4 @@
-import React, { FC } from 'react';
+import { FC } from 'react';
 import { IconButton, makeStyles, Theme, createStyles } from '@material-ui/core';
 import Icons from '../icons/Icons';
 import { ActionBarType } from './Types';

+ 2 - 2
client/src/components/grid/Table.tsx

@@ -1,4 +1,5 @@
-import React, { FC, useEffect, useRef, useState } from 'react';
+import { FC, useEffect, useRef, useState } from 'react';
+import React from 'react';
 import { makeStyles } from '@material-ui/core/styles';
 import Table from '@material-ui/core/Table';
 import TableBody from '@material-ui/core/TableBody';
@@ -54,7 +55,6 @@ const useStyles = makeStyles(theme => ({
   },
   rowHover: {
     '&:hover': {
-      // backgroundColor: `${theme.palette.zilliz.light} !important`,
       backgroundColor: `#f3fcfe`,
       '& td': {
         background: 'inherit',

+ 2 - 1
client/src/components/grid/TableHead.tsx

@@ -1,4 +1,5 @@
-import React, { FC } from 'react';
+import { FC } from 'react';
+import React from 'react';
 import { TableHeadType } from './Types';
 import {
   TableHead,

+ 1 - 1
client/src/components/grid/TableSwitch.tsx

@@ -1,5 +1,5 @@
 import { makeStyles, Theme, createStyles } from '@material-ui/core';
-import React, { FC, useState } from 'react';
+import { FC, useState } from 'react';
 import Icons from '../icons/Icons';
 import { TableSwitchType } from './Types';
 

+ 3 - 17
client/src/components/grid/ToolBar.tsx

@@ -1,4 +1,4 @@
-import React, { FC, useMemo } from 'react';
+import { FC, useMemo } from 'react';
 import {
   Grid,
   Typography,
@@ -10,8 +10,7 @@ import {
 import CustomButton from '../customButton/CustomButton';
 import Icons from '../icons/Icons';
 import { ToolBarConfig, ToolBarType } from './Types';
-import Filter from '../filter/Filter';
-import SearchInput from '../textField/SearchInput';
+import SearchInput from '../customInput/SearchInput';
 import TableSwitch from './TableSwitch';
 import { throwErrorForDev } from '../../utils/Common';
 import CustomIconButton from '../customButton/CustomIconButton';
@@ -38,13 +37,7 @@ const useStyles = makeStyles((theme: Theme) =>
 );
 
 const CustomToolBar: FC<ToolBarType> = props => {
-  const {
-    toolbarConfigs,
-    filterOptions = [],
-    onFilter,
-    filterTitle,
-    selected = [],
-  } = props;
+  const { toolbarConfigs, selected = [] } = props;
   const classes = useStyles();
 
   // remove hidden button
@@ -107,13 +100,6 @@ const CustomToolBar: FC<ToolBarType> = props => {
 
             return isIcon ? iconBtn : btn;
           })}
-          {filterOptions.length && onFilter ? (
-            <Filter
-              filterOptions={filterOptions}
-              onFilter={onFilter}
-              filterTitle={filterTitle}
-            ></Filter>
-          ) : null}
         </Grid>
 
         {rightConfigs.length > 0 && (

+ 2 - 3
client/src/components/grid/Types.ts

@@ -1,6 +1,5 @@
 import { IconsType } from '../icons/Types';
-import { FilterType } from '../filter/Types';
-import { SearchType } from '../textField/Types';
+import { SearchType } from '../customInput/Types';
 import { ReactElement } from 'react';
 
 export type IconConfigType = {
@@ -12,7 +11,7 @@ export type ColorType = 'default' | 'inherit' | 'primary' | 'secondary';
 /**
  * selected: selected data in table checkbox
  */
-export type ToolBarType = FilterType & {
+export type ToolBarType = {
   toolbarConfigs: ToolBarConfig[];
   selected?: any[];
   setSelected?: (selected: any[]) => void;

+ 2 - 7
client/src/components/grid/index.tsx

@@ -1,4 +1,5 @@
-import React, { FC, MouseEvent } from 'react';
+import { FC, MouseEvent } from 'react';
+import React from 'react';
 import { makeStyles } from '@material-ui/core/styles';
 import Grid from '@material-ui/core/Grid';
 import Breadcrumbs from '@material-ui/core/Breadcrumbs';
@@ -98,9 +99,6 @@ const MilvusGrid: FC<MilvusGridType> = props => {
     openCheckBox = true,
     disableSelect = false,
     noData = t('grid.noData'),
-    filterOptions = [],
-    onFilter,
-    filterTitle,
     showHoverStyle = true,
     selected = [],
     setSelected = () => {},
@@ -189,9 +187,6 @@ const MilvusGrid: FC<MilvusGridType> = props => {
         <Grid item>
           <CustomToolbar
             toolbarConfigs={toolbarConfigs}
-            filterOptions={filterOptions}
-            onFilter={onFilter}
-            filterTitle={filterTitle}
             selected={selected}
           ></CustomToolbar>
         </Grid>

+ 6 - 2
client/src/components/icons/Icons.tsx

@@ -7,13 +7,15 @@ import FileCopyIcon from '@material-ui/icons/FileCopy';
 import Visibility from '@material-ui/icons/Visibility';
 import VisibilityOff from '@material-ui/icons/VisibilityOff';
 import ClearIcon from '@material-ui/icons/Clear';
-import FilterListIcon from '@material-ui/icons/FilterList';
 import ReorderIcon from '@material-ui/icons/Reorder';
 import AppsIcon from '@material-ui/icons/Apps';
 import MoreVertIcon from '@material-ui/icons/MoreVert';
 import CancelIcon from '@material-ui/icons/Cancel';
 import CheckCircleIcon from '@material-ui/icons/CheckCircle';
 
+import { SvgIcon } from '@material-ui/core';
+import { ReactComponent as MilvusIcon } from '../../assets/icons/milvus.svg';
+
 const icons: { [x in IconsType]: (props?: any) => React.ReactElement } = {
   search: (props = {}) => <SearchIcon {...props} />,
   add: (props = {}) => <AddIcon {...props} />,
@@ -24,10 +26,12 @@ const icons: { [x in IconsType]: (props?: any) => React.ReactElement } = {
   invisible: (props = {}) => <VisibilityOff {...props} />,
   error: (props = {}) => <CancelIcon {...props} />,
   clear: (props = {}) => <ClearIcon {...props} />,
-  filter: (props = {}) => <FilterListIcon {...props} />,
   more: (props = {}) => <MoreVertIcon {...props} />,
   app: (props = {}) => <AppsIcon {...props} />,
   success: (props = {}) => <CheckCircleIcon {...props} />,
+  milvus: (props = {}) => (
+    <SvgIcon viewBox="0 0 44 31" component={MilvusIcon} {...props} />
+  ),
 };
 
 export default icons;

+ 2 - 2
client/src/components/icons/Types.ts

@@ -8,7 +8,7 @@ export type IconsType =
   | 'invisible'
   | 'error'
   | 'clear'
-  | 'filter'
   | 'app'
   | 'more'
-  | 'success';
+  | 'success'
+  | 'milvus';

+ 2 - 1
client/src/components/layout/GlobalEffect.tsx

@@ -1,4 +1,5 @@
-import React, { useContext } from 'react';
+import { useContext } from 'react';
+import React from 'react';
 import axiosInstance from '../../http/Axios';
 import { rootContext } from '../../context/Root';
 import { CODE_STATUS } from '../../consts/Http';

+ 2 - 2
client/src/components/layout/GlobalToolbar.tsx

@@ -1,4 +1,4 @@
-import React, { useContext } from 'react';
+import { useContext } from 'react';
 import {
   makeStyles,
   Theme,
@@ -60,7 +60,7 @@ const GlobalToolbar = (props: { width: String }) => {
   const { t } = useTranslation();
   const classes = useStyles(props);
   const { t: btnTrans } = useTranslation('btn');
-  const navTrans: any = t('nav');
+  // const navTrans: any = t('nav');
 
   // const SearchIcon = icons.search;
   const AddIcon = icons.add;

+ 2 - 49
client/src/components/layout/Header.tsx

@@ -1,4 +1,4 @@
-import React, { FC } from 'react';
+import { FC } from 'react';
 import { makeStyles, Theme, createStyles } from '@material-ui/core';
 import { HeaderType } from './Types';
 // import { useTranslation } from 'react-i18next';
@@ -11,60 +11,13 @@ const useStyles = makeStyles((theme: Theme) =>
       color: theme.palette.common.black,
       marginRight: theme.spacing(5),
     },
-    contentWrapper: {
-      display: 'flex',
-      justifyContent: 'space-between',
-      alignItems: 'center',
-      paddingTop: theme.spacing(3),
-      paddingLeft: theme.spacing(6),
-      flex: 1,
-    },
-    navigation: {
-      display: 'flex',
-      alignItems: 'center',
-      fontWeight: 'bold',
-      '& svg': {
-        fontSize: '16px',
-        cursor: 'pointer',
-      },
-    },
-    changePwdTip: {
-      width: '420px',
-      textAlign: 'center',
-      '& span': {
-        fontStyle: 'italic',
-      },
-    },
-    user: {
-      display: 'flex',
-    },
-    menuLabel: {
-      height: '100%',
-      color: '#010e29',
-      fontSize: '14px',
-      lineHeight: '20px',
-
-      '&:hover': {
-        backgroundColor: 'transparent',
-      },
-    },
-    arrow: {
-      color: theme.palette.primary.main,
-    },
-    icon: {
-      color: theme.palette.primary.main,
-    },
   })
 );
 
 const Header: FC<HeaderType> = props => {
   const classes = useStyles();
 
-  return (
-    <header className={classes.header}>
-      <div className={classes.contentWrapper}>header</div>
-    </header>
-  );
+  return <header className={classes.header}>header</header>;
 };
 
 export default Header;

+ 10 - 10
client/src/components/layout/Layout.tsx

@@ -26,29 +26,29 @@ const useStyles = makeStyles((theme: Theme) =>
 );
 
 const Layout = (props: any) => {
-  // const history = useHistory();
   const path = window.location.hash.slice(2);
   const greyPaths = ['', 'billing'];
   const bgColor = greyPaths.includes(path) ? '#f5f5f5' : '#fff';
   const classes = useStyles({ backgroundColor: bgColor });
 
-  // const { t } = useTranslation();
-
   const data: NavMenuItem[] = [];
+  const isAuth = false;
 
   return (
     <div className={classes.root}>
       <GlobalEffect>
         <div className={classes.content}>
-          <NavMenu
-            width="200px"
-            data={data}
-            defaultActive="Lock"
-            defaultOpen={{ security: true }}
-          />
+          {isAuth && (
+            <NavMenu
+              width="200px"
+              data={data}
+              defaultActive="Lock"
+              defaultOpen={{ security: true }}
+            />
+          )}
 
           <div className={classes.body}>
-            <Header />
+            {isAuth && <Header />}
             {props.children}
           </div>
         </div>

+ 15 - 13
client/src/components/menu/NavMenu.tsx

@@ -1,4 +1,4 @@
-import React, { FC, useEffect } from 'react';
+import { useState, FC, useEffect } from 'react';
 import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
 import List from '@material-ui/core/List';
 import ListItem from '@material-ui/core/ListItem';
@@ -8,9 +8,9 @@ import Collapse from '@material-ui/core/Collapse';
 import ExpandLess from '@material-ui/icons/ExpandLess';
 import ExpandMore from '@material-ui/icons/ExpandMore';
 import { NavMenuItem, NavMenuType } from './Types';
-import logoPath from '../../assets/imgs/logo.png';
 import { useTranslation } from 'react-i18next';
 import { useLocation } from 'react-router';
+import icons from '../icons/Icons';
 
 const useStyles = makeStyles((theme: Theme) =>
   createStyles({
@@ -96,8 +96,8 @@ const useStyles = makeStyles((theme: Theme) =>
 const NavMenu: FC<NavMenuType> = props => {
   const { width, data, defaultActive = '', defaultOpen = {} } = props;
   const classes = useStyles({ width });
-  const [open, setOpen] = React.useState<{ [x: string]: boolean }>(defaultOpen);
-  const [active, setActive] = React.useState<string>(defaultActive);
+  const [open, setOpen] = useState<{ [x: string]: boolean }>(defaultOpen);
+  const [active, setActive] = useState<string>(defaultActive);
   const location = useLocation();
 
   const handleClick = (label: string) => {
@@ -108,14 +108,14 @@ const NavMenu: FC<NavMenuType> = props => {
   };
 
   const { t } = useTranslation();
-  const navTrans: { [key in string]: string | object } = t('nav');
+  // const navTrans: { [key in string]: string | object } = t('nav');
 
-  useEffect(() => {
-    const activeLabel = location.pathname.includes('queries')
-      ? (navTrans.query as string)
-      : (navTrans.database as string);
-    setActive(activeLabel);
-  }, [location.pathname, navTrans.query, navTrans.database]);
+  // useEffect(() => {
+  //   const activeLabel = location.pathname.includes('queries')
+  //     ? (navTrans.query as string)
+  //     : (navTrans.database as string);
+  //   setActive(activeLabel);
+  // }, [location.pathname, navTrans.query, navTrans.database]);
 
   const NestList = (props: { data: NavMenuItem[]; className?: string }) => {
     const { className, data } = props;
@@ -170,14 +170,16 @@ const NavMenu: FC<NavMenuType> = props => {
     );
   };
 
+  const Logo = icons.milvus;
+
   return (
     <List component="nav" className={classes.root}>
       <div>
         <div className={classes.logoWrapper}>
-          <img className={classes.logo} src={logoPath} alt="cloud logo" />
+          <Logo classes={{ root: classes.logo }} />
         </div>
 
-        <NestList data={data} />
+        {/* <NestList data={data} /> */}
       </div>
     </List>
   );

+ 2 - 1
client/src/components/menu/SimpleMenu.tsx

@@ -1,4 +1,5 @@
-import React, { FC, useMemo } from 'react';
+import { FC, useMemo } from 'react';
+import React from 'react';
 import Menu from '@material-ui/core/Menu';
 import MenuItem from '@material-ui/core/MenuItem';
 import { generateId } from '../../utils/Common';

+ 1 - 1
client/src/components/status/Status.tsx

@@ -1,4 +1,4 @@
-import React, { FC, useMemo } from 'react';
+import { FC, useMemo } from 'react';
 import { StatusType, StatusEnum } from './Types';
 import { useTranslation } from 'react-i18next';
 import { makeStyles, Theme, createStyles, Typography } from '@material-ui/core';

+ 1 - 1
client/src/components/status/StatusIcon.tsx

@@ -1,5 +1,5 @@
 import { CircularProgress, makeStyles, Theme } from '@material-ui/core';
-import React, { FC, ReactElement } from 'react';
+import { FC, ReactElement } from 'react';
 import { getStatusType } from '../../utils/Status';
 import icons from '../icons/Icons';
 import { StatusEnum, StatusType } from './Types';

+ 0 - 6
client/src/consts/Polling.ts

@@ -1,6 +0,0 @@
-export const POLLING_INTERVAL = 1000 * 30;
-
-export enum PollingTypeEnum {
-  databases = 'DATABASES',
-  queries = 'QUERY_SERVICES',
-}

+ 0 - 6
client/src/consts/Reducer.ts

@@ -1,6 +0,0 @@
-// reducer actions
-export const ADD = 'add';
-export const UPDATE = 'update';
-export const INIT = 'init';
-export const DELETE = 'delete';
-export const RESET = 'reset';

+ 0 - 1
client/src/consts/WebSocket.ts

@@ -1 +0,0 @@
-export const CONNECT = 'connect';

+ 5 - 150
client/src/context/Root.tsx

@@ -1,12 +1,7 @@
-import React, { useState, useCallback } from 'react';
-import {
-  // for strict mode
-  unstable_createMuiStrictModeTheme as createMuiTheme,
-  ThemeProvider,
-  makeStyles,
-} from '@material-ui/core/styles';
-import { Backdrop, CircularProgress, SwipeableDrawer } from '@material-ui/core';
-
+import { useState, useCallback } from 'react';
+import React from 'react';
+import { ThemeProvider, makeStyles } from '@material-ui/core/styles';
+import { SwipeableDrawer } from '@material-ui/core';
 import {
   RootContextType,
   DialogType,
@@ -15,16 +10,7 @@ import {
 } from './Types';
 import CustomSnackBar from '../components/customSnackBar/CustomSnackBar';
 import CustomDialog from '../components/customDialog/CustomDialog';
-import lightBlue from '@material-ui/core/colors/lightBlue';
-
-declare module '@material-ui/core/styles/createPalette' {
-  interface Palette {
-    zilliz: Palette['primary'];
-  }
-  interface PaletteOptions {
-    zilliz: PaletteOptions['primary'];
-  }
-}
+import { theme } from '../styles/theme';
 
 const DefaultDialogConfigs: DialogType = {
   open: false,
@@ -47,135 +33,9 @@ export const rootContext = React.createContext<RootContextType>({
   dialog: DefaultDialogConfigs,
   setDialog: params => {},
   handleCloseDialog: () => {},
-  setGlobalLoading: () => {},
   setDrawer: (params: any) => {},
 });
 
-const otherThemes = {
-  spacing: (factor: any) => `${8 * factor}px`,
-};
-
-const theme = createMuiTheme({
-  palette: {
-    primary: {
-      ...lightBlue,
-      main: '#06AFF2',
-      light: '#65DAF8',
-      dark: '#009BC4',
-    },
-    secondary: {
-      light: '#82D3BA',
-      main: '#31B78D',
-      dark: '#279371',
-    },
-    error: {
-      main: '#FF4605',
-      light: '#FF8F68',
-      dark: '#CD3804',
-    },
-    zilliz: {
-      ...lightBlue,
-      light: lightBlue[50],
-    },
-  },
-  ...otherThemes,
-  overrides: {
-    MuiTypography: {
-      button: {
-        textTransform: 'initial',
-        lineHeight: '16px',
-        fontWeight: 'bold',
-      },
-      h1: {
-        fontSize: '36px',
-        lineHeight: '42px',
-        letterSpacing: '-0.02em',
-      },
-      h2: {
-        lineHeight: '24px',
-        fontSize: '28px',
-      },
-      h3: {
-        lineHeight: '20px',
-        fontSize: '23px',
-        fontWeight: 'bold',
-      },
-      h4: {
-        fontWeight: 500,
-        lineHeight: '23px',
-        fontSize: '20px',
-        letterSpacing: '-0.02em',
-      },
-      h5: {
-        fontWeight: 'bold',
-        fontSize: '16px',
-        lineHeight: '24px',
-      },
-      h6: {
-        fontWeight: 'normal',
-        fontSize: '16px',
-        lineHeight: '24px',
-        letterSpacing: '-0.01em',
-      },
-      body1: {
-        fontSize: '14px',
-        lineHeight: '20px',
-      },
-      body2: {
-        fontSize: '12px',
-        lineHeight: '16px',
-      },
-      caption: {
-        fontSize: '10px',
-        lineHeight: '12px',
-      },
-    },
-    MuiButton: {
-      root: {
-        textTransform: 'initial',
-        fontWeight: 'bold',
-      },
-      text: {
-        '&:hover': {
-          backgroundColor: lightBlue[50],
-        },
-      },
-    },
-    MuiDialogActions: {
-      spacing: {
-        padding: otherThemes.spacing(4),
-      },
-    },
-    MuiDialogContent: {
-      root: {
-        padding: `${otherThemes.spacing(1)} ${otherThemes.spacing(4)}`,
-      },
-    },
-    MuiDialogTitle: {
-      root: {
-        padding: otherThemes.spacing(4),
-        paddingBottom: otherThemes.spacing(1),
-      },
-    },
-    MuiStepIcon: {
-      root: {
-        color: '#c4c4c4',
-        '&$active': {
-          color: '#12C3F4',
-        },
-        '&$completed': {
-          color: '#12C3F4',
-        },
-      },
-    },
-    MuiFormHelperText: {
-      contained: {
-        marginLeft: 0,
-      },
-    },
-  },
-});
-
 const { Provider } = rootContext;
 // Dialog has two type : normal | custom;
 // notice type mean it's a notice dialog you need to set props like title, content, actions
@@ -199,7 +59,6 @@ export const RootProvider = (props: { children: React.ReactNode }) => {
     autoHideDuration: 3000,
   });
   const [dialog, setDialog] = useState<DialogType>(DefaultDialogConfigs);
-  const [globalLoading, setGlobalLoading] = useState<boolean>(false);
   const [drawer, setDrawer]: any = useState({
     anchor: 'right',
     open: false,
@@ -254,7 +113,6 @@ export const RootProvider = (props: { children: React.ReactNode }) => {
         dialog,
         setDialog,
         handleCloseDialog,
-        setGlobalLoading,
         setDrawer,
       }}
     >
@@ -262,9 +120,6 @@ export const RootProvider = (props: { children: React.ReactNode }) => {
         <CustomSnackBar {...snackBar} onClose={handleSnackBarClose} />
         {props.children}
         <CustomDialog {...dialog} onClose={handleCloseDialog} />
-        <Backdrop open={globalLoading} style={{ zIndex: 2000 }}>
-          <CircularProgress color="inherit" />
-        </Backdrop>
 
         <SwipeableDrawer
           anchor={drawer.anchor}

+ 0 - 1
client/src/context/Types.ts

@@ -5,7 +5,6 @@ export type RootContextType = {
   dialog: DialogType;
   setDialog: (params: DialogType) => void;
   handleCloseDialog: () => void;
-  setGlobalLoading: (loading: boolean) => void;
   setDrawer: (params: any) => void;
 };
 

+ 0 - 37
client/src/hooks/CommonStyle.ts

@@ -1,37 +0,0 @@
-import { makeStyles } from '@material-ui/core';
-
-const useStyles = makeStyles(theme => ({
-  root: {
-    padding: `${theme.spacing(4)}px ${theme.spacing(4)}px`,
-    backgroundColor: '#f4f4f4',
-  },
-  titleWrapper: {
-    background: theme.palette.primary.light,
-    color: '#fff',
-    padding: theme.spacing(2),
-    '& h2': {
-      fontSize: '26px',
-    },
-  },
-  paper: {
-    color: theme.palette.text.secondary,
-    padding: theme.spacing(4),
-  },
-  titleContainer: {
-    display: 'flex',
-    padding: theme.spacing(1, 0, 2),
-  },
-  h2: {
-    fontSize: '26px',
-    fontWeight: 'bold',
-    margin: '0 10px 0 0',
-  },
-  tab: {
-    background: theme.palette.primary.main,
-    color: '#fff',
-  },
-}));
-
-export function usePageStyles() {
-  return useStyles();
-}

+ 1 - 3
client/src/hooks/Form.ts

@@ -1,5 +1,5 @@
 import { useState } from 'react';
-import { IValidation } from '../components/textField/Types';
+import { IValidation } from '../components/customInput/Types';
 import { checkIsEmpty, getCheckResult } from '../utils/Validation';
 
 export interface IForm {
@@ -48,8 +48,6 @@ export const useFormValidation = (form: IForm[]): IValidationInfo => {
       {}
     );
 
-  console.log('init validation', initValidation);
-
   // validation detail about form item
   const [validation, setValidation] = useState(initValidation);
   // overall validation result to control following actions

+ 0 - 29
client/src/hooks/Polling.ts

@@ -1,29 +0,0 @@
-import dayjs from 'dayjs';
-import { useEffect, useRef } from 'react';
-import { PollingTypeEnum } from '../consts/Polling';
-
-export const useInterval = (
-  callback: (isInterval?: boolean) => void,
-  delay: number | null,
-  type: PollingTypeEnum
-) => {
-  const savedCallback = useRef<(isInterval?: boolean) => void>(() => {});
-  useEffect(() => {
-    savedCallback.current = callback;
-  }, [callback]);
-
-  useEffect(() => {
-    const cb = () => {
-      console.log(
-        `starting fetch data for ${type}`,
-        dayjs().format('YYYY-MM-DD HH:mm:ss')
-      );
-      savedCallback.current(true);
-    };
-
-    if (delay !== null) {
-      let timer = setInterval(cb, delay);
-      return () => clearInterval(timer);
-    }
-  }, [delay, type]);
-};

+ 0 - 29
client/src/hooks/__test__/CommonStyle.spec.tsx

@@ -1,29 +0,0 @@
-import { render } from '@testing-library/react';
-
-import { usePageStyles } from '../CommonStyle';
-
-const setupUsePageStyles = () => {
-  const returnVal = {};
-
-  const TestComponent = () => {
-    Object.assign(returnVal, usePageStyles());
-    return null;
-  };
-
-  render(<TestComponent />);
-  return returnVal;
-};
-
-test('test usePageStyles', () => {
-  const style = setupUsePageStyles();
-  const expectedStyle = {
-    root: 'makeStyles-root-1',
-    titleWrapper: 'makeStyles-titleWrapper-2',
-    paper: 'makeStyles-paper-3',
-
-    titleContainer: 'makeStyles-titleContainer-4',
-    h2: 'makeStyles-h2-5',
-    tab: 'makeStyles-tab-6',
-  };
-  expect(style).toEqual(expectedStyle);
-});

+ 6 - 1
client/src/hooks/__test__/Form.spec.tsx

@@ -1,6 +1,11 @@
 import { render } from '@testing-library/react';
 import { IForm, useFormValidation } from '../Form';
 
+// jest.mock('react', () => ({
+//   ...jest.requireActual('react'),
+//   useState: jest.fn().mockReturnValue([[], jest.fn]),
+// }));
+
 const mockForm: IForm[] = [
   {
     key: 'username',
@@ -30,7 +35,7 @@ test('test useFormValidation hook', () => {
   const { checkFormValid, checkIsValid, validation } = setupUseFormValidation();
 
   expect(checkFormValid(mockForm)).toBeFalsy();
-  expect(validation).toEqual([]);
+  expect(Object.keys(validation)).toEqual(['username']);
   expect(
     checkIsValid({
       value: '',

+ 3 - 15
client/src/i18n/cn/button.ts

@@ -1,4 +1,4 @@
-export default {
+const btnTrans = {
   cancel: '取消',
   save: '保存',
   reset: '重置',
@@ -8,18 +8,6 @@ export default {
   connect: '连接',
   import: '导入',
   delete: '删除',
-  export: '导出',
-  verify: '验证邮件',
-  login: '登录',
-  resendEmail: '重发邮件',
-  createAccount: '创建账号',
-  signIn: '登录',
-  new: '新增',
-  signOut: '退出',
-  filter: '筛选',
-  print: '打印',
-  downloadCSV: '下载 csv 文件',
-  drop: 'Drop',
-  terminate: '停止',
-  send: '发送',
 };
+
+export default btnTrans;

+ 0 - 13
client/src/i18n/cn/card.ts

@@ -1,13 +0,0 @@
-export default {
-  // base card
-  core: 'cores',
-  memory: 'memory',
-  capacity: 'capacity',
-  count: 'node count',
-
-  // info card
-  dimension: 'Dimension',
-  metric: 'Metric type',
-  createTime: 'Created time',
-  index: 'Index',
-};

+ 0 - 31
client/src/i18n/cn/collection.ts

@@ -1,31 +0,0 @@
-export default {
-  // dialog
-  collection: 'Collection',
-  create: 'Create Collection',
-  edit: 'Edit Collection',
-  deleteMultipleTitle: 'Delete {{number}} Collections',
-  deleteWarning:
-    'You are trying to delete a collection with data. This action cannot be undone.',
-  deleteMultipleWarning:
-    'You are trying to delete multiple collections. This action cannot be undone.',
-
-  // dialog form and table
-  name: 'Name',
-  database: 'Database',
-  dimension: 'Dimension',
-  metric: 'Metric Type',
-  desc: 'Description',
-  time: 'Created Time',
-  partition: 'Partition Count',
-  index: 'Index count',
-  location: 'Location',
-
-  empty: 'No Collection',
-
-  // dialog snackbar
-  createSuccess: `"{{collectionName}}" is created in "{{dbName}}"`,
-  editSuccess: 'Collection is updated',
-
-  deleteMultipleSuccess: '{{number}} collections are deleted',
-  deleteSuccess: `Collection "{{name}}" is deleted`,
-};

+ 7 - 59
client/src/i18n/cn/common.ts

@@ -1,4 +1,8 @@
-export default {
+const commonTrans = {
+  milvus: {
+    admin: 'Milvus Admin',
+    address: 'Milvus Address',
+  },
   status: {
     creating: 'creating',
     running: 'running',
@@ -12,66 +16,10 @@ export default {
     nextLabel: 'next page',
     prevLabel: 'prev page',
   },
-  nav: {
-    database: 'Database',
-    index: 'Index',
-    query: 'Query Service',
-    task: 'Task',
-
-    menu: {
-      database: 'Database',
-      collection: 'Collection',
-      partition: 'Partition',
-      index: 'Index',
-      query: 'Query',
-    },
-  },
   copy: {
     copy: 'Copy',
     copied: 'Copied',
   },
-  header: {
-    navigation: {
-      allDatabases: 'All Databases',
-      allTasks: 'Task',
-      allQueries: 'All Queries',
-    },
-  },
-  oauth: {
-    divider: 'OR',
-    signIn: {
-      google: 'Sign in with Google',
-      success: 'Sign in successfully',
-    },
-    signUp: {
-      google: 'Sign up with Google',
-    },
-  },
-  stepper: {
-    back: 'Back',
-    next: 'Next',
-  },
-  autoComplete: {
-    all: 'View All',
-    searchTitle: 'Search by category',
-    database: 'Database',
-    collection: 'Collection',
-    partition: 'Partition',
-    index: 'Index',
-    query: 'Query',
-  },
-  tabs: {
-    collection: 'Collections',
-    partitions: 'Partitions',
-    schema: 'Schema',
-    index: 'Index',
-    data: 'Data',
-  },
-  schema: {
-    name: 'Field Name',
-    type: 'Type',
-    dimension: 'Dimension',
-    desc: 'Descriptions',
-  },
-  uploadSuccess: 'Upload successfully',
 };
+
+export default commonTrans;

+ 0 - 12
client/src/i18n/cn/connect.ts

@@ -1,12 +0,0 @@
-export default {
-  connect: 'Connect',
-  title: 'Connect Your Service',
-  subtitle: 'Here are the fast way to connect your Zilliz Cloud',
-  download: 'Download Golang SDK',
-  tip: 'More operations, please check the documentation',
-  link: 'Go to Milvus Doc',
-
-  start: 'Quick Start',
-  py: 'Python',
-  go: 'Golang',
-};

+ 0 - 5
client/src/i18n/cn/data.ts

@@ -1,5 +0,0 @@
-export default {
-  id: 'ID',
-  vector: 'Vector',
-  empty: 'No Data',
-};

+ 0 - 43
client/src/i18n/cn/database.ts

@@ -1,43 +0,0 @@
-export default {
-  // dialog
-  db: 'Database',
-  empty: 'No Database',
-
-  create: 'Create Database',
-  editDb: 'Edit Database',
-  deleteDb: 'Delete Database',
-  deleteWarning:
-    'Deleting this database will terminate all related query services, this action can not be undone.',
-
-  // card
-  endpoint: 'Endpoint',
-  token: 'Access Token',
-  query: 'Query Service',
-  addQuery: 'Add Query Service',
-  write: 'Write Node',
-  // view: 'View Collections',
-  connect: 'Connect Your Service',
-  edit: 'edit',
-  delete: 'delete',
-  createCollection: 'Create Collection',
-  createQuery: 'Create Query Service',
-  createQueryTip: 'one database can only has one query service',
-
-  // dialog form
-  name: 'Name',
-  provider: 'Cloud Provider',
-  region: 'Cloud Region',
-  node: 'Node Type',
-  price: 'Price',
-  desc: 'Description',
-  time: 'Create Time',
-  status: 'Status',
-
-  // dialog snackbar
-  createSuccess: `Start creating Database "{{dbName}}"`,
-  editSuccess: `Database "{{name}}" is updated`,
-  deleteSuccess: `Database "{{name}}" is deleted`,
-
-  // tooltip
-  viewCollectionTip: 'Database is creating',
-};

+ 0 - 8
client/src/i18n/cn/dialog.ts

@@ -1,8 +0,0 @@
-export default {
-  deleteTipAction: 'Type',
-  deleteTipPurpose: 'to confirm.',
-  deleteTitle: `Delete {{type}} "{{name}}"`,
-  dropTitle: `Drop {{type}} {{name}}`,
-
-  createTitle: `Create {{type}} in "{{name}}"`,
-};

+ 0 - 15
client/src/i18n/cn/help.ts

@@ -1,15 +0,0 @@
-export default {
-  text: '发送反馈',
-  tip: '',
-  title: '联系我们',
-  content: '有任何意见或问题?',
-  content2: '请告诉我们.',
-  placeholder: '填写你的经历',
-  success: '您的反馈已发送成功',
-
-  // type
-  support: 'Support',
-  bug: 'Bug',
-  suggestion: 'Suggestion',
-  other: 'Other',
-};

+ 0 - 24
client/src/i18n/cn/index.ts

@@ -1,24 +0,0 @@
-export default {
-  index: 'Index',
-  drop: 'Drop Index "{{name}}"',
-  dropWarning: 'This action cannot be undone',
-  create: 'Create Index',
-
-  // form
-  name: 'Name',
-  indexType: 'Index Type',
-  param: 'Parameters',
-
-  // snackbar
-  createSuccess: `"{{indexName}}" is created in "{{collectionName}}"`,
-  editSuccess: 'Index "{{name}}" is updated',
-  deleteSuccess: 'Index "{{name}}" is deleted',
-
-  // table
-  type: 'Type',
-  metric: 'Metric',
-  location: 'Location',
-  empty: 'No Index',
-  edit: 'Edit Index',
-  status: 'Status',
-};

+ 0 - 29
client/src/i18n/cn/partition.ts

@@ -1,29 +0,0 @@
-export default {
-  partition: 'Partition',
-  create: 'Create Partition',
-  edit: 'Edit Partition',
-  deleteMultipleTitle: 'Delete {{number}} Partitions',
-  deleteWarning:
-    'You are trying to delete a partition with data. This action cannot be undone.',
-  deleteMultipleWarning:
-    'You are trying to delete multiple partitions. This action cannot be undone.',
-
-  empty: 'No Parition',
-
-  // form
-  database: 'Database',
-  collection: 'Collection',
-
-  // table
-  name: 'Name',
-  desc: 'Description',
-  time: 'Create Time',
-  location: 'Location',
-
-  // snackbar
-  createSuccess: `"{{partitionName}}" is created in "{{collectionName}}"`,
-  editSuccess: `Partition "{{name}}" is updated`,
-
-  deleteSuccess: `Partition "{{name}}" is deleted`,
-  deleteMultipleSuccess: '{{number}} partitions are deleted',
-};

+ 0 - 20
client/src/i18n/cn/password.ts

@@ -1,20 +0,0 @@
-export default {
-  pwd: '密码',
-  reset: '重置密码',
-  changePwdTip: '一封有修改密码链接的邮件将会发送到',
-
-  recoverPwd: {
-    title: '重置密码',
-    tip: 'No worries, happens to the best of us.',
-    confirm: '发送重置邮件',
-    cancel: '返回登录',
-    success: '发送成功',
-  },
-  changePwd: {
-    title: '修改密码',
-    newPwd: '新密码',
-    confirmNewPwd: '确认新密码',
-    confirm: '修改密码',
-    success: '您的密码已修改成功',
-  },
-};

+ 0 - 47
client/src/i18n/cn/query.ts

@@ -1,47 +0,0 @@
-export default {
-  // dialog
-  createTitle: 'Create Query Service',
-  edit: 'Edit Query Service',
-  terminateTitle: 'Terminate Query',
-  terminateWarning: 'This action can’t be undone.',
-
-  empty: 'No Query Service',
-
-  // dialog form
-  name: 'Name',
-  database: 'Database',
-  type: 'Query Service Type',
-  count: 'Query Node Count',
-  desc: 'Description',
-  noDbs: 'No database available',
-  capacity: 'Capacity',
-
-  // card
-  editQuery: 'edit',
-  deleteQuery: 'delete',
-  terminate: 'terminate',
-  queryLabel: 'Query Service',
-  search: 'Vector Search',
-
-  // query service page
-  token: 'Access Token',
-  endpoint: 'Endpoint',
-  create: 'Create Query',
-  region: 'Cloud Region',
-  time: 'Create Time',
-  status: 'Status',
-  vectorSearchEmpty: 'Start your search',
-  noVectorSearch: 'No result found',
-
-  // vector search
-  rank: 'Rank',
-  id: 'ID',
-  vector: 'Vector',
-  distance: 'Distance',
-  topK: 'TopK',
-
-  // dialog snackbar
-  createSuccess: 'Start creating query node',
-  editSuccess: 'Query node is updated',
-  deleteSuccess: `Query Service "{{name}}" is deleted.`,
-};

+ 0 - 6
client/src/i18n/cn/signUp.ts

@@ -1,6 +0,0 @@
-export default {
-  title: '创建账号',
-  account: '邮箱',
-  password: '密码',
-  confirm: '确认密码',
-};

+ 0 - 6
client/src/i18n/cn/verify.ts

@@ -1,6 +0,0 @@
-export default {
-  thank: '感谢使用 Zilliz 云平台,邮件已发送至',
-  check: '请检查邮箱,验证账号',
-  continue: '重新登录',
-  successMsg: '账号验证成功',
-};

+ 3 - 17
client/src/i18n/cn/warning.ts

@@ -1,24 +1,10 @@
-export default {
-  nameLength: '名称最长 128 字',
-  nameStrength: '名称可包含字母、数字、空格或 + - = . _ : / @ 等特殊字符',
-
-  email: '请输入正确的邮箱地址',
-
-  passwordLength: '请输入 8 字以上的密码',
-  passwordStrength: '密码请使用大写字母、小写字母、数字和特殊符号的组合',
-  passwordConfirm: '两次输入的密码不一致,请重试',
-
+const warningTrans = {
   closeDialog: '已填写的表单会丢失,确认离开?',
 
-  collectionName:
-    'Name should be combined with number, letter or underscore and not begin with number',
-  dimension: 'dimension should be 8 multiple',
-
   required: '{{name}} is required',
   positive: '{{name}} should be positive',
   integer: '{{name}} should be integers',
   range: 'range is {{min}} ~ {{max}}',
-
-  deletePartition: '_default partition cannot be deleted',
-  createIndex: 'You can only create one index',
 };
+
+export default warningTrans;

+ 3 - 16
client/src/i18n/en/button.ts

@@ -1,4 +1,4 @@
-export default {
+const btnTrans = {
   cancel: 'Cancel',
   save: 'Save',
   create: 'Create',
@@ -9,19 +9,6 @@ export default {
   connect: 'Connect',
   import: 'Import',
   delete: 'Delete',
-  export: 'Export',
-  verify: 'Verify email',
-  login: 'Back to sign in',
-  signIn: 'Sign in',
-  resendEmail: 'Resend email',
-  createAccount: 'Create account',
-  forgetPassword: 'Forget password?',
-  new: 'New',
-  signOut: 'Sign out',
-  filter: 'Filter',
-  print: 'Print',
-  downloadCSV: 'Download CSV File',
-  drop: 'Drop',
-  terminate: 'Terminate',
-  send: 'Send',
 };
+
+export default btnTrans;

+ 0 - 13
client/src/i18n/en/card.ts

@@ -1,13 +0,0 @@
-export default {
-  // base card
-  core: 'cores',
-  memory: 'memory',
-  capacity: 'capacity',
-  count: 'node count',
-
-  // info card
-  dimension: 'Dimension',
-  metric: 'Metric type',
-  createTime: 'Created time',
-  index: 'Index',
-};

+ 0 - 31
client/src/i18n/en/collection.ts

@@ -1,31 +0,0 @@
-export default {
-  // dialog
-  collection: 'Collection',
-  create: 'Create Collection',
-  edit: 'Edit Collection',
-  deleteMultipleTitle: 'Delete {{number}} Collections',
-  deleteWarning:
-    'You are trying to delete a collection with data. This action cannot be undone.',
-  deleteMultipleWarning:
-    'You are trying to delete multiple collections. This action cannot be undone.',
-
-  // dialog form and table
-  name: 'Name',
-  database: 'Database',
-  dimension: 'Dimension',
-  metric: 'Metric Type',
-  desc: 'Description',
-  time: 'Created Time',
-  partition: 'Partition Count',
-  index: 'Index count',
-  location: 'Location',
-
-  empty: 'No Collection',
-
-  // dialog snackbar
-  createSuccess: `"{{collectionName}}" is created in "{{dbName}}"`,
-  editSuccess: `Collection "{{name}}" is updated`,
-
-  deleteMultipleSuccess: '{{number}} collections are deleted',
-  deleteSuccess: `Collection "{{name}}" is deleted`,
-};

+ 7 - 60
client/src/i18n/en/common.ts

@@ -1,4 +1,8 @@
-export default {
+const commonTrans = {
+  milvus: {
+    admin: 'Milvus Admin',
+    address: 'Milvus Address',
+  },
   status: {
     creating: 'creating',
     running: 'running',
@@ -12,67 +16,10 @@ export default {
     nextLabel: 'next page',
     prevLabel: 'prev page',
   },
-  nav: {
-    database: 'Database',
-    index: 'Index',
-    query: 'Query Service',
-    task: 'Task',
-
-    menu: {
-      database: 'Database',
-      collection: 'Collection',
-      partition: 'Partition',
-      index: 'Index',
-      query: 'Query',
-    },
-  },
   copy: {
     copy: 'Copy',
     copied: 'Copied',
   },
-  header: {
-    navigation: {
-      allDatabases: 'All Databases',
-      allTasks: 'Task',
-      allQueries: 'All Queries',
-    },
-  },
-  oauth: {
-    divider: 'OR',
-    signIn: {
-      google: 'Sign in with Google',
-      success: 'Sign in successfully',
-    },
-    signUp: {
-      google: 'Sign up with Google',
-    },
-  },
-  stepper: {
-    back: 'Back',
-    next: 'Next',
-  },
-  autoComplete: {
-    all: 'View All',
-    searchTitle: 'Search by category',
-    database: 'Database',
-    collection: 'Collection',
-    partition: 'Partition',
-    index: 'Index',
-    query: 'Query',
-  },
-  tabs: {
-    collection: 'Collections',
-    partitions: 'Partitions',
-    schema: 'Schema',
-    index: 'Index',
-    data: 'Data',
-  },
-  schema: {
-    name: 'Field Name',
-    type: 'Type',
-    dimension: 'Dimension',
-    desc: 'Descriptions',
-  },
-
-  uploadSuccess: 'Upload successfully',
 };
+
+export default commonTrans;

+ 0 - 12
client/src/i18n/en/connect.ts

@@ -1,12 +0,0 @@
-export default {
-  connect: 'Connect',
-  title: 'Connect Your Service',
-  subtitle: 'Here are the fast way to connect your Zilliz Cloud',
-  download: 'Download {{name}} SDK',
-  tip: 'More operations, please check the documentation',
-  link: 'Go to Milvus Doc',
-
-  start: 'Quick Start',
-  py: 'Python',
-  go: 'Golang',
-};

+ 0 - 5
client/src/i18n/en/data.ts

@@ -1,5 +0,0 @@
-export default {
-  id: 'ID',
-  vector: 'Vector',
-  empty: 'No Data',
-};

+ 0 - 42
client/src/i18n/en/database.ts

@@ -1,42 +0,0 @@
-export default {
-  // dialog
-  db: 'Database',
-  empty: 'No Database',
-  create: 'Create Database',
-  editDb: 'Edit Database',
-  deleteDb: 'Delete Database',
-  deleteWarning:
-    'Deleting this database will terminate all related query services, this action can not be undone.',
-
-  // card
-  endpoint: 'Endpoint',
-  token: 'Access Token',
-  query: 'Query Service',
-  addQuery: 'Add Query Service',
-  write: 'Write Node',
-  // view: 'View Collections',
-  connect: 'Connect Your Service',
-  edit: 'edit',
-  delete: 'delete',
-  createCollection: 'Create Collection',
-  createQuery: 'Create Query Service',
-  createQueryTip: 'one database can only has one query service',
-
-  // dialog form
-  name: 'Name',
-  provider: 'Cloud Provider',
-  region: 'Cloud Region',
-  node: 'Node Type',
-  price: 'Price',
-  desc: 'Description',
-  time: 'Create Time',
-  status: 'Status',
-
-  // dialog snackbar
-  createSuccess: `Start creating Database "{{dbName}}"`,
-  editSuccess: `Database "{{name}}" is updated`,
-  deleteSuccess: `Database "{{name}}" is deleted`,
-
-  // tooltip
-  viewCollectionTip: 'Database is creating',
-};

+ 0 - 8
client/src/i18n/en/dialog.ts

@@ -1,8 +0,0 @@
-export default {
-  deleteTipAction: 'Type',
-  deleteTipPurpose: 'to confirm.',
-  deleteTitle: `Delete {{type}} "{{name}}"`,
-  dropTitle: `Drop {{type}} {{name}}`,
-
-  createTitle: `Create {{type}} in "{{name}}"`,
-};

+ 0 - 15
client/src/i18n/en/help.ts

@@ -1,15 +0,0 @@
-export default {
-  text: 'Send feedback',
-  tip: 'Help/feedback',
-  title: 'Send Feedback',
-  content: 'Do you have a suggestion or found some bug?',
-  content2: 'Let us know in the field bellow.',
-  placeholder: 'Describe your experience here...',
-  success: 'Your message has been successfully sent',
-
-  // type
-  support: 'Support',
-  bug: 'Bug',
-  suggestion: 'Suggestion',
-  other: 'Other',
-};

+ 0 - 24
client/src/i18n/en/index.ts

@@ -1,24 +0,0 @@
-export default {
-  index: 'Index',
-  drop: 'Drop Index "{{name}}"',
-  dropWarning: 'This action cannot be undone',
-  create: 'Create Index',
-
-  // form
-  name: 'Name',
-  indexType: 'Index Type',
-  param: 'Parameters',
-
-  // snackbar
-  createSuccess: `"{{indexName}}" is created in "{{collectionName}}"`,
-  editSuccess: 'Index "{{name}}" is updated',
-  deleteSuccess: 'Index "{{name}}" is deleted',
-
-  // table
-  type: 'Type',
-  metric: 'Metric',
-  location: 'Location',
-  empty: 'No Index',
-  edit: 'Edit Index',
-  status: 'Status',
-};

+ 0 - 29
client/src/i18n/en/partition.ts

@@ -1,29 +0,0 @@
-export default {
-  partition: 'Partition',
-  create: 'Create Partition',
-  edit: 'Edit Partition',
-  deleteMultipleTitle: 'Delete {{number}} Partitions',
-  deleteWarning:
-    'You are trying to delete a partition with data. This action cannot be undone.',
-  deleteMultipleWarning:
-    'You are trying to delete multiple partitions. This action cannot be undone.',
-
-  empty: 'No Parition',
-
-  // form
-  database: 'Database',
-  collection: 'Collection',
-
-  // table
-  name: 'Name',
-  desc: 'Description',
-  time: 'Create Time',
-  location: 'Location',
-
-  // snackbar
-  createSuccess: `"{{partitionName}}" is created in "{{collectionName}}"`,
-  editSuccess: `Partition "{{name}}" is updated`,
-
-  deleteSuccess: `Partition "{{name}}" is deleted`,
-  deleteMultipleSuccess: '{{number}} partitions are deleted',
-};

+ 0 - 21
client/src/i18n/en/password.ts

@@ -1,21 +0,0 @@
-export default {
-  pwd: 'Password',
-  reset: 'Reset Password',
-  changePwdTip:
-    ' A verification email with a link to change your password will be sent to',
-
-  recoverPwd: {
-    title: 'Recover password',
-    tip: 'No worries, happens to the best of us.',
-    confirm: 'Email me a recovery link',
-    cancel: 'Back to sign in',
-    success: 'Send recovery password email success, please check your email.',
-  },
-  changePwd: {
-    title: 'Change password',
-    newPwd: 'New password',
-    confirmNewPwd: 'Re-enter your new password',
-    confirm: 'Change password',
-    success: 'Your password has been changed.',
-  },
-};

+ 0 - 47
client/src/i18n/en/query.ts

@@ -1,47 +0,0 @@
-export default {
-  // dialog
-  createTitle: 'Create Query Service',
-  edit: 'Edit Query Service',
-  terminateTitle: 'Terminate Query',
-  terminateWarning: 'This action can’t be undone.',
-
-  empty: 'No Query Service',
-
-  // dialog form
-  name: 'Name',
-  database: 'Database',
-  type: 'Query Service Type',
-  count: 'Query Node Count',
-  desc: 'Description',
-  noDbs: 'No database available',
-  capacity: 'Capacity',
-
-  // card
-  editQuery: 'edit',
-  deleteQuery: 'delete',
-  terminate: 'terminate',
-  queryLabel: 'Query Service',
-  search: 'Vector Search',
-
-  // query service page
-  token: 'Access Token',
-  endpoint: 'Endpoint',
-  create: 'Create Query',
-  region: 'Cloud Region',
-  time: 'Create Time',
-  status: 'Status',
-  vectorSearchEmpty: 'Start your search',
-  noVectorSearch: 'No result found',
-
-  // vector search
-  rank: 'Rank',
-  id: 'ID',
-  vector: 'Vector',
-  distance: 'Distance',
-  topK: 'TopK',
-
-  // dialog snackbar
-  createSuccess: 'Start creating query node',
-  editSuccess: 'Query node is updated',
-  deleteSuccess: `Query Service "{{name}}" is deleted.`,
-};

+ 0 - 6
client/src/i18n/en/signUp.ts

@@ -1,6 +0,0 @@
-export default {
-  title: 'Sign up',
-  account: 'Email Address',
-  password: 'Password',
-  confirm: 'Confirm password',
-};

+ 0 - 6
client/src/i18n/en/verify.ts

@@ -1,6 +0,0 @@
-export default {
-  thank: 'Thank you for using Zilliz Cloud. An Email had been sent to',
-  check: 'Check your mail box to verify your account.',
-  continue: 'Continue to sign in',
-  successMsg: 'Your account had been verified.',
-};

+ 3 - 18
client/src/i18n/en/warning.ts

@@ -1,25 +1,10 @@
-export default {
-  nameLength: 'Contain at most 128 characters',
-  nameStrength: 'Only letters, numbers, spaces and + - = . _ : / @ are allowed',
-
-  email: 'Email address is invalid.',
-
-  passwordLength: 'Contain at least 8 characters',
-  passwordStrength:
-    'Please choose a stronger password. Try a mix of uppercase and lowercase letters, numbers, and symbols.',
-  passwordConfirm: `Those passwords didn't match. Try again.`,
-
+const warningTrans = {
   closeDialog: 'Will lose your data, are you sure to leave?',
 
-  collectionName:
-    'Name should be combined with number, letter or underscore and not begin with number',
-  dimension: 'dimension should be 8 multiple',
-
   required: '{{name}} is required',
   positive: '{{name}} should be positive',
   integer: '{{name}} should be integers',
   range: 'range is {{min}} ~ {{max}}',
-
-  deletePartition: '_default partition cannot be deleted',
-  createIndex: 'You can only create one index',
 };
+
+export default warningTrans;

+ 0 - 52
client/src/i18n/index.ts

@@ -5,71 +5,19 @@ import commonCn from './cn/common';
 import commonEn from './en/common';
 import buttonEn from './en/button';
 import buttonCn from './cn/button';
-import databaseCn from './cn/database';
-import databaseEn from './en/database';
-import signUpCn from './cn/signUp';
-import signUpEn from './en/signUp';
 import warningCn from './cn/warning';
 import warningEn from './en/warning';
-import verifyCn from './cn/verify';
-import verifyEn from './en/verify';
-import helpCn from './cn/help';
-import helpEn from './en/help';
-import queryCn from './cn/query';
-import queryEn from './en/query';
-import collectionCn from './cn/collection';
-import collectionEn from './en/collection';
-import partitionCn from './cn/partition';
-import partitionEn from './en/partition';
-import indexCn from './cn/index';
-import indexEn from './en/index';
-import cardCn from './cn/card';
-import cardEn from './en/card';
-import dataCn from './cn/data';
-import dataEn from './en/data';
-import dialogCn from './cn/dialog';
-import dialogEn from './en/dialog';
-import passwordCn from './cn/password';
-import passwordEn from './en/password';
-import connectCn from './cn/connect';
-import connectEn from './en/connect';
 
 export const resources = {
   cn: {
     translation: commonCn,
-    signUp: signUpCn,
     btn: buttonCn,
     warning: warningCn,
-    verify: verifyCn,
-    help: helpCn,
-    database: databaseCn,
-    query: queryCn,
-    collection: collectionCn,
-    partition: partitionCn,
-    index: indexCn,
-    card: cardCn,
-    data: dataCn,
-    dialog: dialogCn,
-    password: passwordCn,
-    connect: connectCn,
   },
   en: {
     translation: commonEn,
-    signUp: signUpEn,
     btn: buttonEn,
     warning: warningEn,
-    verify: verifyEn,
-    help: helpEn,
-    database: databaseEn,
-    query: queryEn,
-    collection: collectionEn,
-    partition: partitionEn,
-    index: indexEn,
-    card: cardEn,
-    data: dataEn,
-    dialog: dialogEn,
-    password: passwordEn,
-    connect: connectEn,
   },
 };
 

+ 4 - 3
client/src/index.tsx

@@ -1,13 +1,14 @@
-import React from 'react';
+import { StrictMode } from 'react';
 import ReactDOM from 'react-dom';
 import './index.css';
+import './i18n';
 import App from './App';
 import reportWebVitals from './reportWebVitals';
 
 ReactDOM.render(
-  <React.StrictMode>
+  <StrictMode>
     <App />
-  </React.StrictMode>,
+  </StrictMode>,
   document.getElementById('root')
 );
 

+ 111 - 0
client/src/pages/connect/Connect.tsx

@@ -0,0 +1,111 @@
+import { Theme, makeStyles } from '@material-ui/core';
+import { useTranslation } from 'react-i18next';
+import { ITextfieldConfig } from '../../components/customInput/Types';
+import icons from '../../components/icons/Icons';
+import ConnectContainer from './ConnectContainer';
+import CustomInput from '../../components/customInput/CustomInput';
+import { useMemo, useState } from 'react';
+import { formatForm } from '../../utils/Form';
+import { useFormValidation } from '../../hooks/Form';
+import CustomButton from '../../components/customButton/CustomButton';
+import { useHistory } from 'react-router-dom';
+
+const useStyles = makeStyles((theme: Theme) => ({
+  wrapper: {
+    display: 'flex',
+    flexDirection: 'column',
+    alignItems: 'flex-end',
+
+    padding: theme.spacing(0, 3),
+  },
+  titleWrapper: {
+    display: 'flex',
+    padding: theme.spacing(3),
+    margin: '0 auto',
+
+    '& h2': {
+      margin: 0,
+      color: '#323232',
+    },
+  },
+  logo: {
+    width: '42px',
+    height: 'auto',
+    marginRight: theme.spacing(2),
+  },
+  input: {
+    margin: theme.spacing(3, 0, 0.5),
+  },
+}));
+
+const Connect = () => {
+  const history = useHistory();
+
+  const classes = useStyles();
+  const { t } = useTranslation();
+  const { t: warningTrans } = useTranslation('warning');
+  const milvusTrans: { [key in string]: string } = t('milvus');
+  const { t: btnTrans } = useTranslation('btn');
+
+  const [form, setForm] = useState({
+    address: '',
+  });
+  const checkedForm = useMemo(() => {
+    const { address } = form;
+    return formatForm({ address });
+  }, [form]);
+  const { validation, checkIsValid, disabled } = useFormValidation(checkedForm);
+
+  const Logo = icons.milvus;
+
+  const handleInputChange = (value: string) => {
+    setForm({ address: value });
+  };
+
+  const handleConnect = () => {
+    console.log('connect address', form.address);
+    history.push('/');
+  };
+
+  const addressInputConfig: ITextfieldConfig = {
+    label: milvusTrans.address,
+    key: 'address',
+    onChange: handleInputChange,
+    variant: 'filled',
+    className: classes.input,
+    placeholder: milvusTrans.addaress,
+    fullWidth: true,
+    validations: [
+      {
+        rule: 'require',
+        errorText: warningTrans('required', { name: milvusTrans.address }),
+      },
+    ],
+  };
+
+  return (
+    <ConnectContainer>
+      <section className={classes.wrapper}>
+        <div className={classes.titleWrapper}>
+          <Logo classes={{ root: classes.logo }} />
+          <h2>{milvusTrans.admin}</h2>
+        </div>
+        <CustomInput
+          type="text"
+          textConfig={addressInputConfig}
+          checkValid={checkIsValid}
+          validInfo={validation}
+        />
+        <CustomButton
+          variant="contained"
+          disabled={disabled}
+          onClick={handleConnect}
+        >
+          {btnTrans('connect')}
+        </CustomButton>
+      </section>
+    </ConnectContainer>
+  );
+};
+
+export default Connect;

+ 8 - 8
client/src/components/layout/UserContainer.tsx → client/src/pages/connect/ConnectContainer.tsx

@@ -1,6 +1,6 @@
 import { makeStyles, Theme } from '@material-ui/core';
-import React, { ReactElement } from 'react';
-import backgroundPath from '../../assets/imgs/background.png';
+import { ReactElement } from 'react';
+import backgroundPath from '../../assets/imgs/connectContainer/background.png';
 
 const getContainerStyles = makeStyles((theme: Theme) => ({
   wrapper: {
@@ -23,15 +23,15 @@ const getContainerStyles = makeStyles((theme: Theme) => ({
   },
 }));
 
-// used for user login process
-const UserContainer = ({ children }: { children: ReactElement }) => {
+// used for user connect process
+const ConnectContainer = ({ children }: { children: ReactElement }) => {
   const classes = getContainerStyles();
 
   return (
-    <section className={classes.wrapper}>
-      <div className={classes.card}>{children}</div>
-    </section>
+    <main className={classes.wrapper}>
+      <section className={classes.card}>{children}</section>
+    </main>
   );
 };
 
-export default UserContainer;
+export default ConnectContainer;

+ 0 - 0
client/src/pages/dashboard/Dashboard.tsx → client/src/pages/overview/Overview.tsx


+ 8 - 2
client/src/router/Config.ts

@@ -1,11 +1,17 @@
-import Dashboard from '../pages/dashboard/Dashboard';
+import Connect from '../pages/connect/Connect';
+import Overview from '../pages/overview/Overview';
 
 const RouterConfig = [
   {
     path: '/',
-    component: Dashboard,
+    component: Overview,
     auth: true,
   },
+  {
+    path: '/connect',
+    component: Connect,
+    auth: false,
+  },
 ];
 
 export default RouterConfig;

+ 1 - 1
client/src/router/Router.tsx

@@ -20,7 +20,7 @@ const RouterWrapper = () => {
               return (
                 <Redirect
                   to={{
-                    pathname: '/',
+                    pathname: '/connect',
                   }}
                 />
               );

+ 136 - 0
client/src/styles/theme.ts

@@ -0,0 +1,136 @@
+import {
+  // for strict mode
+  unstable_createMuiStrictModeTheme as createMuiTheme,
+} from '@material-ui/core/styles';
+
+const commonThemes = {
+  typography: {
+    fontFamily: [
+      'Roboto',
+      '-apple-system',
+      'BlinkMacSystemFont',
+      '"Segoe UI"',
+      '"Helvetica Neue"',
+      'Arial',
+      'sans-serif',
+      '"Apple Color Emoji"',
+      '"Segoe UI Emoji"',
+      '"Segoe UI Symbol"',
+    ].join(','),
+  },
+  palette: {
+    primary: {
+      main: '#06aff2',
+      light: '#65daf8',
+      dark: '#009bc4',
+    },
+    secondary: {
+      light: '#82d3ba',
+      main: '#31b78d',
+      dark: '#279371',
+    },
+    error: {
+      main: '#ff4605',
+      light: '#ff8f68',
+      dark: '#cd3804',
+    },
+  },
+  breakpoints: {
+    values: {
+      xs: 0,
+      sm: 600,
+      md: 1025,
+      lg: 1200,
+      xl: 1920,
+    },
+  },
+  spacing: (factor: number) => `${8 * factor}px`,
+};
+
+export const theme = createMuiTheme({
+  ...commonThemes,
+  overrides: {
+    MuiTypography: {
+      button: {
+        textTransform: 'initial',
+        lineHeight: '16px',
+        fontWeight: 'bold',
+      },
+      h1: {
+        fontSize: '36px',
+        lineHeight: '42px',
+        letterSpacing: '-0.02em',
+      },
+      h2: {
+        lineHeight: '24px',
+        fontSize: '28px',
+      },
+      h3: {
+        lineHeight: '20px',
+        fontSize: '23px',
+        fontWeight: 'bold',
+      },
+      h4: {
+        fontWeight: 500,
+        lineHeight: '23px',
+        fontSize: '20px',
+        letterSpacing: '-0.02em',
+      },
+      h5: {
+        fontWeight: 'bold',
+        fontSize: '16px',
+        lineHeight: '24px',
+      },
+      h6: {
+        fontWeight: 'normal',
+        fontSize: '16px',
+        lineHeight: '24px',
+        letterSpacing: '-0.01em',
+      },
+      body1: {
+        fontSize: '14px',
+        lineHeight: '20px',
+      },
+      body2: {
+        fontSize: '12px',
+        lineHeight: '16px',
+      },
+      caption: {
+        fontSize: '10px',
+        lineHeight: '12px',
+      },
+    },
+    MuiButton: {
+      root: {
+        textTransform: 'initial',
+        fontWeight: 'bold',
+      },
+      text: {
+        '&:hover': {
+          backgroundColor: commonThemes.palette.primary.light,
+        },
+      },
+    },
+    MuiDialogActions: {
+      spacing: {
+        padding: commonThemes.spacing(4),
+      },
+    },
+    MuiDialogContent: {
+      root: {
+        padding: `${commonThemes.spacing(1)} ${commonThemes.spacing(4)}`,
+      },
+    },
+    MuiDialogTitle: {
+      root: {
+        padding: commonThemes.spacing(4),
+        paddingBottom: commonThemes.spacing(1),
+      },
+    },
+    MuiFormHelperText: {
+      contained: {
+        marginLeft: 0,
+      },
+    },
+  },
+});

+ 17 - 0
client/src/utils/Form.ts

@@ -0,0 +1,17 @@
+import { IForm } from "../hooks/Form";
+
+interface IInfo {
+  [key: string]: any
+}
+
+export const formatForm = (info: IInfo): IForm[] => {
+  const form: IForm[] = Object.entries(info).map(item => {
+    const [key, value] = item;
+    return {
+      key,
+      value,
+      needCheck: true,
+    };
+  });
+  return form;
+}

+ 0 - 27
client/src/utils/Time.ts

@@ -1,27 +0,0 @@
-import dayjs from 'dayjs';
-
-export const getMonthOptions = (
-  start: number
-): { label: string; value: number }[] => {
-  const current = dayjs().endOf('month').valueOf();
-  let options: { label: string; value: number }[] = [];
-  let month = dayjs(start).endOf('month').valueOf();
-
-  while (month <= current) {
-    options = [
-      ...options,
-      {
-        label: dayjs(month).format('MMMM YYYY'),
-        value: dayjs(month).endOf('month').valueOf(),
-      },
-    ];
-
-    month = dayjs(month).add(1, 'M').valueOf();
-  }
-
-  return options;
-};
-
-export const formatDate = (time: number): string => {
-  return dayjs(time * 1000).format('YYYY-MM-DD HH:mm:ss');
-};

+ 0 - 10
client/src/utils/User.ts

@@ -1,10 +0,0 @@
-export const getEmailAndCode = (search: string): { [key: string]: string } => {
-  const s = search.slice(1);
-  const result: { [key: string]: string } = {};
-  s.split('&').forEach(item => {
-    const [key, value] = item.split('=');
-    result[key] = value;
-  });
-
-  return result;
-};

+ 17 - 0
client/src/utils/__test__/Form.spec.ts

@@ -0,0 +1,17 @@
+import { formatForm } from '../Form';
+
+describe('Test form utils', () => {
+  test('test formatForm function', () => {
+    const mockUserInfo = {
+      name: 'user1',
+      age: 20,
+      isMale: true,
+    };
+
+    const form = formatForm(mockUserInfo);
+    const nameInfo = form.find(item => item.key === 'name');
+    expect(form.length).toBe(3);
+    expect(nameInfo?.value).toBe('user1');
+    expect(nameInfo?.needCheck).toBeTruthy();
+  });
+});