Skip to content

Commit

Permalink
Add empty data dialog (#360)
Browse files Browse the repository at this point in the history
* add empty dialog client

Signed-off-by: ryjiang <[email protected]>

* support empty data

Signed-off-by: ryjiang <[email protected]>

---------

Signed-off-by: ryjiang <[email protected]>
  • Loading branch information
shanghaikid authored Jan 11, 2024
1 parent c645a4a commit c9863ed
Show file tree
Hide file tree
Showing 20 changed files with 175 additions and 25 deletions.
24 changes: 17 additions & 7 deletions client/src/components/customDialog/DeleteDialogTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const useStyles = makeStyles((theme: Theme) => ({
maxWidth: '480px',
backgroundColor: '#fff',
},
info: {
marginBottom: theme.spacing(0.5),
},
mb: {
marginBottom: theme.spacing(2.5),
},
Expand All @@ -42,8 +45,15 @@ const useStyles = makeStyles((theme: Theme) => ({
}));

const DeleteTemplate: FC<DeleteDialogContentType> = props => {
const { title, text, label, handleDelete, handleCancel, forceDelLabel } =
props;
const {
title,
text,
label,
compare,
handleDelete,
handleCancel,
forceDelLabel,
} = props;
const { handleCloseDialog } = useContext(rootContext);
const classes = useStyles();
const { t: dialogTrans } = useTranslation('dialog');
Expand All @@ -67,7 +77,7 @@ const DeleteTemplate: FC<DeleteDialogContentType> = props => {
const value = event.target.value;
setValue(value);

setDeleteReady(value.toLowerCase() === label.toLowerCase());
setDeleteReady(value.toLowerCase() === (compare || label).toLowerCase());
};

return (
Expand All @@ -81,12 +91,12 @@ const DeleteTemplate: FC<DeleteDialogContentType> = props => {
</CustomDialogTitle>

<DialogContent>
<Typography variant="body1">{text}</Typography>
<Typography variant="body1" className={classes.info}>{text}</Typography>
<Typography variant="body1" className={classes.mb}>
{dialogTrans('deleteTipAction')}
<strong
className={classes.btnLabel}
>{` ${label.toLowerCase()} `}</strong>
<strong className={classes.btnLabel}>{` ${(
compare || label
).toLowerCase()} `}</strong>
{dialogTrans('deleteTipPurpose')}
</Typography>
<TextField
Expand Down
1 change: 1 addition & 0 deletions client/src/components/customDialog/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type DeleteDialogContentType = {
title: string;
text: string;
label: string;
compare?: string;
handleCancel?: () => void;
handleDelete: (force?: boolean) => void;
forceDelLabel?: string;
Expand Down
5 changes: 2 additions & 3 deletions client/src/components/grid/ToolBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ const useStyles = makeStyles((theme: Theme) =>
opacity: 0.4,
},
btn: {
// marginLeft: theme.spacing(1),
marginRight: '12px',
marginRight: theme.spacing(.5),
},
gridEnd: {
display: 'flex',
Expand Down Expand Up @@ -83,7 +82,7 @@ const CustomToolBar: FC<ToolBarType> = props => {
size="small"
onClick={c.onClick}
startIcon={Icon}
color="primary"
color={c.btnColor || 'primary'}
disabled={disabled}
// use contained variant as default
variant={c.btnVariant || 'contained'}
Expand Down
1 change: 1 addition & 0 deletions client/src/components/grid/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export type ToolBarConfig = Partial<TableSwitchType> &
position?: 'right' | 'left';
component?: ReactElement;
btnVariant?: 'contained' | 'outlined' | 'text';
btnColor?: 'primary' | 'secondary'
};

export type TableHeadType = {
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/icons/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SearchIcon from '@material-ui/icons/Search';
import AddIcon from '@material-ui/icons/Add';
import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutlineOutlined';
import DeleteIcon from '@material-ui/icons/Delete';
import DeleteOutlineIcon from '@material-ui/icons/DeleteOutline';
import FileCopyIcon from '@material-ui/icons/FileCopy';
import Visibility from '@material-ui/icons/Visibility';
import VisibilityOff from '@material-ui/icons/VisibilityOff';
Expand Down Expand Up @@ -49,6 +50,7 @@ const icons: { [x in IconsType]: (props?: any) => React.ReactElement } = {
add: (props = {}) => <AddIcon {...props} />,
addOutline: (props = {}) => <AddCircleOutlineIcon {...props} />,
delete: (props = {}) => <DeleteIcon {...props} />,
deleteOutline: (props = {}) => <DeleteOutlineIcon {...props} />,
list: (props = {}) => <ReorderIcon {...props} />,
copy: (props = {}) => <FileCopyIcon {...props} />,
visible: (props = {}) => <Visibility {...props} />,
Expand Down
1 change: 1 addition & 0 deletions client/src/components/icons/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export type IconsType =
| 'add'
| 'addOutline'
| 'delete'
| 'deleteOutline'
| 'list'
| 'copy'
| 'visible'
Expand Down
6 changes: 6 additions & 0 deletions client/src/http/Data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,10 @@ export class DataService extends BaseModel {
},
});
}

static emptyData(collectionName: string) {
return super.update({
path: `${this.COLLECTIONS_URL}/${collectionName}/empty`,
});
}
}
1 change: 1 addition & 0 deletions client/src/i18n/cn/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const btnTrans = {
rename: '重命名',
duplicate: '复制',
export: '导出',
empty: '清空数据'
};

export default btnTrans;
7 changes: 6 additions & 1 deletion client/src/i18n/cn/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const collectionTrans = {
download: '下载',
downloadTooltip: '将所有查询结果导出到CSV文件',
downloadDisabledTooltip: '请在导出前查询数据',
empty: '清空数据',
emptyDataDisableTooltip: '请选择一个已加载的Collection进行清空数据操作',

collection: 'Collection',
entities: 'Entities',
Expand All @@ -37,7 +39,8 @@ const collectionTrans = {
aliasInfo: '别名可以在向量搜索中用作Collection名称。',
consistencyLevelInfo:
'一致性是指确保每个节点或副本在给定时间写入或读取数据时具有相同数据视图的属性。',
entityCountInfo: '大约的Entity数量。',
entityCountInfo:
'这个计数是一个近似值,并可能因为Milvus的独特机制而稍有延迟。实际的计数可能会有所变化,并会定期更新。请注意,这个数字应该被用作参考,而不是精确的计数。',
duplicateCollectionInfo:
'复制Collection不会复制Collection中的数据。它只会使用现有的Schema创建一个新的Collection。',

Expand Down Expand Up @@ -147,6 +150,8 @@ const collectionTrans = {
// flush dialog
flush: '落盘',
flushDialogInfo: `落盘是一个在数据被插入到Milvus后,封闭和索引任何剩余段的过程。这避免了在未封闭的段上进行暴力搜索。 <br /><br />最好在插入会话结束时使用落盘,以防止数据碎片化。 <br /><br /><strong>注意:对于大型数据集,此操作可能需要一些时间。</strong>`,

emptyDataDialogInfo: `您正在尝试清空数据。此操作无法撤销,请谨慎操作。`,
};

export default collectionTrans;
1 change: 1 addition & 0 deletions client/src/i18n/cn/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const dialogTrans = {
releaseContent: `您正在尝试发布带有数据的 {{type}}。请注意,数据将不再可用于搜索。`,

createTitle: `在 "{{name}}" 上创建 {{type}}`,
emptyTitle: `清空{{type}}的数据`,
};

export default dialogTrans;
1 change: 1 addition & 0 deletions client/src/i18n/cn/success.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const successTrans = {
update: `{{name}}更新成功。`,
rename: `{{name}}重命名成功。`,
duplicate: `{{name}}复制成功.`,
empty: `{{name}}清空已经开始.`,
};

export default successTrans;
3 changes: 2 additions & 1 deletion client/src/i18n/en/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ const btnTrans = {
example: 'Generate Random Vector',
rename: 'Rename',
duplicate: 'Duplicate',
export: 'Export'
export: 'Export',
empty: 'Empty'
};

export default btnTrans;
8 changes: 7 additions & 1 deletion client/src/i18n/en/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const collectionTrans = {
download: 'Download',
downloadTooltip: 'Export all query results to CSV file',
downloadDisabledTooltip: 'Please query data before exporting',
empty: 'empty data',
emptyDataDisableTooltip: 'Please select one loaded collection to empty data',

collection: 'Collection',
entities: 'entities',
Expand All @@ -37,7 +39,8 @@ const collectionTrans = {
aliasInfo: 'Alias can be used as collection name in vector search.',
consistencyLevelInfo:
'Consistency refers to the property that ensures every node or replica has the same view of data when writing or reading data at a given time.',
entityCountInfo: 'Approximately entity count.',
entityCountInfo:
'This count is an approximation and may be slightly delayed due to the unique mechanisms of Milvus. The actual count may vary and is updated periodically. Please note that this number should be used as a reference and not as an exact count.',
duplicateCollectionInfo:
'Duplicating a collection does not copy the data within the collection. It only creates a new collection using the existing schema.',

Expand Down Expand Up @@ -146,6 +149,9 @@ const collectionTrans = {
// flush dialog
flush: 'Flush',
flushDialogInfo: `Flush is a process that seals and indexes any remaining segments after data is upserted into Milvus. This avoids brute force searches on unsealed segments. <br /><br />It's best to use flush at the end of an upsert session to prevent data fragmentation. <br /><br /><strong>Note: that this operation may take some time for large datasets.</strong>`,

// empty dialog
emptyDataDialogInfo: `You are attempting to empty the data. This action cannot be undone, please proceed with caution.`,
};

export default collectionTrans;
1 change: 1 addition & 0 deletions client/src/i18n/en/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const dialogTrans = {
releaseContent: `You are trying to release {{type}} with data. Please be aware that the data will no longer be available for search.`,

createTitle: `Create {{type}} on "{{name}}"`,
emptyTitle: `Empty data for {{type}}`,
};

export default dialogTrans;
1 change: 1 addition & 0 deletions client/src/i18n/en/success.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const successTrans = {
update: `{{name}} has been updated.`,
rename: `{{name}} has been renamed.`,
duplicate: `{{name}} has been duplicated.`,
empty: `Emptying data for {{name}} has started.`,
};

export default successTrans;
68 changes: 56 additions & 12 deletions client/src/pages/collections/Collections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import ReleaseCollectionDialog from '../dialogs/ReleaseCollectionDialog';
import DropCollectionDialog from '../dialogs/DropCollectionDialog';
import RenameCollectionDialog from '../dialogs/RenameCollectionDialog';
import DuplicateCollectionDialog from '../dialogs/DuplicateCollectionDailog';
import EmptyDataDialog from '../dialogs/EmptyDataDialog';
import InsertDialog from '../dialogs/insert/Dialog';
import ImportSampleDialog from '../dialogs/ImportSampleDialog';
import { LOADING_STATE } from '@/consts';
Expand Down Expand Up @@ -299,7 +300,9 @@ const Collections = () => {
},
{
icon: 'uploadFile',
type: 'iconBtn',
type: 'button',
btnVariant: 'text',
btnColor: 'secondary',
label: btnTrans('insert'),
onClick: () => {
setDialog({
Expand Down Expand Up @@ -355,7 +358,9 @@ const Collections = () => {
},
{
icon: 'edit',
type: 'iconBtn',
type: 'button',
btnColor: 'secondary',
btnVariant: 'text',
onClick: () => {
setDialog({
open: true,
Expand All @@ -378,14 +383,15 @@ const Collections = () => {
},
});
},
label: collectionTrans('rename'),
label: btnTrans('rename'),
// tooltip: collectionTrans('deleteTooltip'),
disabledTooltip: collectionTrans('renameTooltip'),
disabled: data => data.length !== 1,
},
{
icon: 'copy',
type: 'iconBtn',
type: 'button',
btnVariant: 'text',
onClick: () => {
setDialog({
open: true,
Expand All @@ -409,13 +415,51 @@ const Collections = () => {
},
});
},
label: collectionTrans('duplicate'),
label: btnTrans('duplicate'),
// tooltip: collectionTrans('deleteTooltip'),
disabledTooltip: collectionTrans('duplicateTooltip'),
disabled: data => data.length !== 1,
},
{
type: 'iconBtn',
icon: 'deleteOutline',
type: 'button',
btnVariant: 'text',
onClick: () => {
setDialog({
open: true,
type: 'custom',
params: {
component: (
<EmptyDataDialog
cb={async () => {
openSnackBar(
successTrans('empty', {
name: collectionTrans('collection'),
})
);
setSelectedCollections([]);
await fetchData();
}}
collectionName={selectedCollections[0].collectionName}
/>
),
},
});
},
label: btnTrans('empty'),
disabledTooltip: collectionTrans('emptyDataDisableTooltip'),
disabled: (data: any) => {
if (data.length === 0 || data.length > 1) {
return true;
} else {
return Number(data[0].loadedPercentage) !== 100;
}
},
},
{
icon: 'delete',
type: 'button',
btnVariant: 'text',
onClick: () => {
setDialog({
open: true,
Expand All @@ -438,21 +482,21 @@ const Collections = () => {
},
});
},
label: collectionTrans('delete'),
icon: 'delete',
label: btnTrans('drop'),
// tooltip: collectionTrans('deleteTooltip'),
disabledTooltip: collectionTrans('deleteTooltip'),
disabled: data => data.length === 0,
disabled: data => data.length !== 1,
},

{
type: 'iconBtn',
icon: 'refresh',
type: 'button',
btnVariant: 'text',
onClick: () => {
clearIndexCache();
fetchData();
},
label: collectionTrans('delete'),
icon: 'refresh',
label: btnTrans('refresh'),
},

{
Expand Down
37 changes: 37 additions & 0 deletions client/src/pages/dialogs/EmptyDataDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { FC, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { rootContext } from '@/context';
import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
import { DataService } from '@/http';
import { EmptyDataProps } from './Types';

const EmptyDataDialog: FC<EmptyDataProps> = props => {
const { cb, collectionName } = props;

const { handleCloseDialog } = useContext(rootContext);
const { t: dialogTrans } = useTranslation('dialog');
const { t: collectionTrans } = useTranslation('collection');
const { t: btnTrans } = useTranslation('btn');

const handleDelete = async () => {
// duplicate
DataService.emptyData(collectionName);
// close dialog
handleCloseDialog();
cb && cb();
};

return (
<DeleteTemplate
label={btnTrans('empty')}
title={dialogTrans('emptyTitle', {
type: collectionTrans('collection'),
})}
compare={collectionName}
text={collectionTrans('emptyDataDialogInfo')}
handleDelete={handleDelete}
/>
);
};

export default EmptyDataDialog;
Loading

0 comments on commit c9863ed

Please sign in to comment.