@ant-design/icons#CopyFilled TypeScript Examples
The following examples show how to use
@ant-design/icons#CopyFilled.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx From nanolooker with MIT License | 5 votes |
Copy = ({ text }: { text: string }) => {
const { t } = useTranslation();
const { theme } = React.useContext(PreferencesContext);
const [isCopied, setIsCopied] = React.useState<boolean>(false);
return (
<Tooltip title={isCopied ? `${t("common.copied")}!` : t("common.copy")}>
<CopyToClipboard
text={text}
onCopy={() => {
setIsCopied(true);
clearTimeout(copiedTimeout);
copiedTimeout = window.setTimeout(() => {
setIsCopied(false);
}, 2000);
}}
>
{isCopied ? (
theme === Theme.DARK ? (
<CheckCircleFilled
style={{ fontSize: "24px", color: Colors.PENDING_DARK as string }}
/>
) : (
<CheckCircleFilled
style={{ fontSize: "24px", color: Colors.PENDING as string }}
/>
)
) : (
<Button
shape="circle"
size="small"
disabled={isCopied}
style={{
borderColor: isCopied ? (Colors.RECEIVE as string) : undefined,
}}
>
{theme === Theme.DARK ? <CopyFilled /> : <CopyOutlined />}
</Button>
)}
</CopyToClipboard>
</Tooltip>
);
}
Example #2
Source File: BrickItem.spec.tsx From next-basics with GNU General Public License v3.0 | 4 votes |
describe("BrickItem", () => {
afterEach(() => {
jest.clearAllMocks();
});
it("should display a brick", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const mockOnDraggingChange = jest.fn();
const wrapper = mount(
<BrickItem
brick={{
type: "brick",
id: "my.awesome-brick",
title: "awesome-brick",
description: "My awesome brick",
}}
onDraggingChange={mockOnDraggingChange}
/>
);
expect(wrapper.find(".brickItem").hasClass("brick")).toBe(true);
expect(wrapper.find(".brickItem").prop("title")).toBe("My awesome brick");
expect(wrapper.find(BuildFilled).length).toBe(1);
expect(wrapper.find(".brickName").text()).toBe("awesome-brick");
expect(mockUseDrag).toBeCalledWith(
expect.objectContaining({
item: {
type: BuilderDataTransferType.NODE_TO_ADD,
brickType: undefined,
brick: "my.awesome-brick",
},
})
);
expect(mockOnDraggingChange).toBeCalledWith(false);
});
it("should display a provider", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
type: "provider",
id: "my.awesome-provider",
title: "awesome-provider",
}}
/>
);
expect(wrapper.find(".brickItem").hasClass("provider")).toBe(true);
expect(wrapper.find(".brickItem").prop("title")).toBe("awesome-provider");
expect(wrapper.find(DatabaseFilled).length).toBe(1);
expect(wrapper.find(".brickName").text()).toBe("awesome-provider");
expect(mockUseDrag).toBeCalledWith(
expect.objectContaining({
item: {
type: BuilderDataTransferType.NODE_TO_ADD,
brickType: "provider",
brick: "my.awesome-provider",
},
})
);
});
it("should display a legacy template", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
type: "template",
id: "my.awesome-template",
title: "awesome-template",
}}
/>
);
expect(wrapper.find(".brickItem").hasClass("template")).toBe(true);
expect(wrapper.find(GoldenFilled).length).toBe(1);
expect(wrapper.find(".brickName").text()).toBe("awesome-template");
expect(mockUseDrag).toBeCalledWith(
expect.objectContaining({
item: {
type: BuilderDataTransferType.NODE_TO_ADD,
brickType: "template",
brick: "my.awesome-template",
},
})
);
});
it("should display a custom template", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
type: "customTemplate",
id: "my.awesome-custom-template",
title: "awesome-custom-template",
}}
/>
);
expect(wrapper.find(".brickItem").hasClass("customTemplate")).toBe(true);
expect(wrapper.find(CopyFilled).length).toBe(1);
expect(wrapper.find(".brickName").text()).toBe("awesome-custom-template");
expect(mockUseDrag).toBeCalledWith(
expect.objectContaining({
item: {
type: BuilderDataTransferType.NODE_TO_ADD,
brickType: undefined,
brick: "my.awesome-custom-template",
},
})
);
});
it("should display a snippet", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
type: "snippet",
id: "my.snippet",
title: "My Snippet",
bricks: [
{
brick: "easy-view",
},
],
thumbnail: "test.svg",
}}
/>
);
expect(wrapper.find(".brickItem").hasClass("snippet")).toBe(true);
expect(wrapper.find(".brickIcon img").prop("src")).toBe("test.svg");
expect(wrapper.find(NumberOutlined).length).toBe(0);
expect(wrapper.find(".brickName").text()).toBe("My Snippet");
expect(mockUseDrag).toBeCalledWith(
expect.objectContaining({
item: {
type: BuilderDataTransferType.SNIPPET_TO_APPLY,
bricks: [
{
brick: "easy-view",
},
],
},
})
);
});
it("should display a snippet without thumbnail", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
type: "snippet",
id: "my.snippet",
title: "My Snippet",
bricks: [
{
brick: "easy-view",
},
],
}}
/>
);
expect(wrapper.find(".brickItem").hasClass("snippet")).toBe(true);
expect(wrapper.find(NumberOutlined).length).toBe(1);
expect(wrapper.find(".brickIcon img").length).toBe(0);
});
it("should render icon", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
category: "form-input",
icon: {
lib: "fa",
icon: "abacus",
},
type: "brick",
id: "my.awesome-brick",
title: "awesome-brick",
}}
/>
);
expect(wrapper.find(GeneralIcon).prop("icon")).toEqual({
icon: "abacus",
lib: "fa",
});
});
it("should show thumbnail while layerType was widget", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
type: "brick",
id: "widget-project.my-widget",
title: "my-widget",
thumbnail: "xxx.png",
}}
layerType={LayerType.WIDGET}
/>
);
expect(wrapper.find(".brickIcon img").prop("src")).toBe("xxx.png");
});
it("should show BuildFilled while layType was widget and thumbnail was null", () => {
const dragRef = jest.fn();
mockUseDrag.mockReturnValueOnce([{ isDragging: false }, dragRef]);
const wrapper = shallow(
<BrickItem
brick={{
type: "brick",
id: "widget-project.my-widget",
title: "my-widget",
thumbnail: null,
}}
layerType={LayerType.WIDGET}
/>
);
expect(wrapper.find(BuildFilled).length).toBe(1);
});
});
Example #3
Source File: BrickItem.tsx From next-basics with GNU General Public License v3.0 | 4 votes |
export function BrickItem({
brick,
onDraggingChange,
layerType,
}: BrickItemProps): React.ReactElement {
let brickType: string;
switch (brick.type) {
case "provider":
case "template":
brickType = brick.type;
// `customTemplate` will be treated as `brick`.
}
const transferItem =
brick.type === "snippet"
? {
type: BuilderDataTransferType.SNIPPET_TO_APPLY,
bricks: brick.bricks,
}
: {
type: BuilderDataTransferType.NODE_TO_ADD,
brickType,
brick: brick.id,
};
const [{ isDragging }, dragRef] = useDrag({
item: transferItem,
options: {
dropEffect: "copy",
},
collect: /* istanbul ignore next */ (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
useEffect(() => {
onDraggingChange?.(isDragging);
}, [isDragging, onDraggingChange]);
let icon: JSX.Element;
if (brick.icon) {
icon = <GeneralIcon icon={brick.icon} />;
} else if (layerType === "widget") {
icon = brick.thumbnail ? (
<img
style={{
width: "auto",
height: "100%",
}}
src={brick.thumbnail}
/>
) : (
<BuildFilled />
);
} else {
switch (brick.type) {
case "provider":
icon = <DatabaseFilled />;
break;
case "template":
icon = <GoldenFilled />;
break;
case "customTemplate":
icon = (
<CopyFilled
className={classNames({
[styles.thumbnailType]: layerType !== LayerType.BRICK,
})}
/>
);
break;
case "snippet":
icon = brick.thumbnail ? (
<img src={brick.thumbnail} />
) : (
<NumberOutlined
className={classNames({
[styles.thumbnailType]: layerType !== LayerType.BRICK,
})}
/>
);
break;
default:
icon = <BuildFilled />;
}
}
return (
<div
className={`${styles.brickItem} ${styles[brick.type]} ${
styles[`layer-${layerType ?? LayerType.BRICK}`]
}`}
title={brick.description || brick.title}
ref={dragRef}
>
<span className={styles.brickIcon}>{icon}</span>
<span className={styles.brickName}>{brick.title}</span>
</div>
);
}
Example #4
Source File: VizOperationMenu.tsx From datart with Apache License 2.0 | 4 votes |
VizOperationMenu: FC<{
onShareLinkClick?;
onDownloadDataLinkClick?;
onSaveAsVizs?;
onReloadData?;
onAddToDashBoard?;
onPublish?;
onRecycleViz?;
allowDownload?: boolean;
allowShare?: boolean;
allowManage?: boolean;
isArchived?: boolean;
}> = memo(
({
onShareLinkClick,
onDownloadDataLinkClick,
onSaveAsVizs,
onReloadData,
onAddToDashBoard,
onPublish,
allowDownload,
allowShare,
allowManage,
isArchived,
onRecycleViz,
}) => {
const t = useI18NPrefix(`viz.action`);
const tg = useI18NPrefix(`global`);
const moreActionMenu = () => {
const menus: any[] = [];
if (onReloadData) {
menus.push(
<Menu.Item
key="reloadData"
icon={<ReloadOutlined />}
onClick={onReloadData}
>
{t('syncData')}
</Menu.Item>,
<Menu.Divider key={'reloadDataLine'} />,
);
}
if (allowManage && onSaveAsVizs) {
menus.push(
<Menu.Item key="saveAs" icon={<CopyFilled />} onClick={onSaveAsVizs}>
{tg('button.saveAs')}
</Menu.Item>,
);
}
if (allowManage && onSaveAsVizs) {
menus.push(
<Menu.Item
key="addToDash"
icon={<FileAddOutlined />}
onClick={() => onAddToDashBoard(true)}
>
{t('addToDash')}
</Menu.Item>,
<Menu.Divider key="addToDashLine" />,
);
}
if (allowShare && onShareLinkClick) {
menus.push(
<Menu.Item
key="shareLink"
icon={<ShareAltOutlined />}
onClick={onShareLinkClick}
>
{t('share.shareLink')}
</Menu.Item>,
);
}
if (allowDownload && onDownloadDataLinkClick) {
menus.push(
<Menu.Item key="downloadData" icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
onConfirm={() => {
onDownloadDataLinkClick(DownloadFileType.Excel);
}}
okText={t('common.ok')}
cancelText={t('common.cancel')}
>
{t('share.downloadData')}
</Popconfirm>
</Menu.Item>,
<Menu.Item key="downloadPDF" icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
onConfirm={() => {
onDownloadDataLinkClick(DownloadFileType.Pdf);
}}
okText={t('common.ok')}
cancelText={t('common.cancel')}
>
{t('share.downloadPDF')}
</Popconfirm>
</Menu.Item>,
<Menu.Item key="downloadPicture" icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
onConfirm={() => {
onDownloadDataLinkClick(DownloadFileType.Image);
}}
okText={t('common.ok')}
cancelText={t('common.cancel')}
>
{t('share.downloadPicture')}
</Popconfirm>
</Menu.Item>,
<Menu.Divider />,
<Menu.Divider key="downloadDataLine" />,
);
}
if (allowManage && !isArchived && onPublish) {
menus.push(
<Menu.Item
key="publish"
icon={<VerticalAlignBottomOutlined />}
onClick={onPublish}
>
{t('unpublish')}
</Menu.Item>,
);
}
if (allowManage && onRecycleViz) {
menus.push(
<Menu.Item key="delete" icon={<DeleteOutlined />}>
<Popconfirm
title={tg('operation.archiveConfirm')}
onConfirm={onRecycleViz}
>
{tg('button.archive')}
</Popconfirm>
</Menu.Item>,
);
}
return <Menu>{menus}</Menu>;
};
return <StyleVizOperationMenu>{moreActionMenu()}</StyleVizOperationMenu>;
},
)
Example #5
Source File: BoardDropdownList.tsx From datart with Apache License 2.0 | 4 votes |
BoardDropdownList: FC<Props> = memo(
({ onOpenShareLink, openStoryList }) => {
const t = useI18NPrefix(`viz.action`);
const tg = useI18NPrefix(`global`);
const dispatch = useDispatch();
const {
allowDownload,
allowShare,
allowManage,
renderMode,
status,
orgId,
boardId,
} = useContext(BoardContext);
const recycleViz = useRecycleViz(orgId, boardId, 'DASHBOARD');
const saveAsViz = useSaveAsViz();
const reloadData = () => {
dispatch(widgetsQueryAction({ boardId, renderMode }));
};
const { onBoardToDownLoad } = useContext(BoardActionContext);
const { publishBoard } = usePublishBoard(boardId, 'DASHBOARD', status);
return (
<Menu>
<Menu.Item
key="reloadData"
onClick={reloadData}
icon={<ReloadOutlined />}
>
{t('syncData')}
</Menu.Item>
{allowShare && (
<>
<Menu.Divider key={'shareLinkLine'} />
<Menu.Item
key={'shareLink'}
onClick={onOpenShareLink}
icon={<ShareAltOutlined />}
>
{t('share.shareLink')}
</Menu.Item>
</>
)}
{allowDownload && (
<>
<Menu.Divider key={'downloadDataLine'} />
<Menu.Item key={'downloadData'} icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
okText={t('common.ok')}
cancelText={t('common.cancel')}
onConfirm={() => {
onBoardToDownLoad?.(DownloadFileType.Excel);
}}
>
{t('share.downloadData')}
</Popconfirm>
</Menu.Item>
<Menu.Item key={'downloadPDF'} icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
okText={t('common.ok')}
cancelText={t('common.cancel')}
onConfirm={() => {
onBoardToDownLoad?.(DownloadFileType.Pdf);
}}
>
{t('share.downloadPDF')}
</Popconfirm>
</Menu.Item>
<Menu.Item key={'downloadPicture'} icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
okText={t('common.ok')}
cancelText={t('common.cancel')}
onConfirm={() => {
onBoardToDownLoad?.(DownloadFileType.Image);
}}
>
{t('share.downloadPicture')}
</Popconfirm>
</Menu.Item>
</>
)}
{allowManage && (
<>
<Menu.Divider key="unpublishLine" />
{status === 2 && (
<Menu.Item
key={'unpublish'}
onClick={publishBoard}
icon={<FileAddOutlined />}
>
{t('unpublish')}
</Menu.Item>
)}
<Menu.Item
key={'saveAs'}
onClick={() => saveAsViz(boardId, 'DASHBOARD')}
icon={<CopyFilled />}
>
{tg('button.saveAs')}
</Menu.Item>
<Menu.Item
key={'addToStory'}
onClick={openStoryList}
icon={<FileAddOutlined />}
>
{t('addToStory')}
</Menu.Item>
<Menu.Item
key={'archive'}
onClick={recycleViz}
icon={<DeleteOutlined />}
>
{tg('button.archive')}
</Menu.Item>
</>
)}
</Menu>
);
},
)
Example #6
Source File: Toolbar.tsx From datart with Apache License 2.0 | 4 votes |
Toolbar = memo(({ allowManage, allowEnableViz }: ToolbarProps) => {
const { actions } = useViewSlice();
const dispatch = useDispatch();
const { onRun, onSave } = useContext(EditorContext);
const { showSaveForm } = useContext(SaveFormContext);
const sources = useSelector(selectSources);
const history = useHistory();
const histState = history.location.state as any;
const viewsData = useSelector(selectViews);
const t = useI18NPrefix('view.editor');
const saveAsView = useSaveAsView();
const startAnalysis = useStartAnalysis();
const id = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'id' }),
) as string;
const name = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'name' }),
) as string;
const parentId = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'parentId' }),
) as string;
const config = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'config' }),
) as object;
const sourceId = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'sourceId' }),
) as string;
const stage = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'stage' }),
) as ViewViewModelStages;
const status = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'status' }),
) as ViewStatus;
const script = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'script' }),
) as string;
const fragment = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'fragment' }),
) as string;
const size = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'size' }),
) as number;
const error = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'error' }),
) as string;
const ViewIndex = useSelector(state =>
selectCurrentEditingViewAttr(state, { name: 'index' }),
) as number;
const isArchived = status === ViewStatus.Archived;
const formatSQL = useCallback(() => {
dispatch(
actions.changeCurrentEditingView({
script: format(script),
}),
);
}, [dispatch, actions, script]);
const showEdit = useCallback(() => {
showSaveForm({
type: CommonFormTypes.Edit,
visible: true,
initialValues: {
name,
parentId,
config,
},
parentIdLabel: t('folder'),
onSave: (values, onClose) => {
let index = ViewIndex;
if (isParentIdEqual(parentId, values.parentId)) {
index = getInsertedNodeIndex(values, viewsData);
}
dispatch(
actions.changeCurrentEditingView({
...values,
parentId: values.parentId || null,
index,
}),
);
dispatch(saveView({ resolve: onClose }));
},
});
}, [
showSaveForm,
actions,
dispatch,
name,
parentId,
config,
viewsData,
ViewIndex,
t,
]);
const sourceChange = useCallback(
value => {
dispatch(actions.changeCurrentEditingView({ sourceId: value }));
},
[dispatch, actions],
);
const sizeMenuClick = useCallback(
({ key }) => {
dispatch(actions.changeCurrentEditingView({ size: Number(key) }));
},
[dispatch, actions],
);
useEffect(() => {
if (histState?.sourcesId && sources) {
sourceChange(histState.sourcesId);
}
}, [histState?.sourcesId, sourceChange, sources]);
return (
<Container>
<Operates>
<Space split={<Divider type="vertical" className="divider" />}>
{allowManage && (
<Select
placeholder={t('source')}
value={sourceId}
bordered={false}
disabled={isArchived}
onChange={sourceChange}
className="source"
>
{sources.map(({ id, name }) => (
<Select.Option key={id} value={id}>
{name}
</Select.Option>
))}
</Select>
)}
<Space>
<Tooltip
title={
<TipTitle
title={[
`${fragment ? t('runSelection') : t('run')}`,
t('runWinTip'),
t('runMacTip'),
]}
/>
}
placement="bottom"
>
<ToolbarButton
icon={
stage === ViewViewModelStages.Running ? (
<PauseOutlined />
) : (
<CaretRightOutlined />
)
}
color={fragment ? WARNING : INFO}
onClick={onRun}
/>
</Tooltip>
<Tooltip title={t('beautify')} placement="bottom">
<ToolbarButton
icon={<AlignCenterOutlined />}
disabled={isArchived}
onClick={formatSQL}
/>
</Tooltip>
</Space>
<Dropdown
trigger={['click']}
overlay={
<Menu onClick={sizeMenuClick}>
{PREVIEW_SIZE_LIST.map(s => (
<Menu.Item key={s}>{s}</Menu.Item>
))}
</Menu>
}
>
<ToolbarButton size="small">{`Limit: ${size}`}</ToolbarButton>
</Dropdown>
<Chronograph
running={stage === ViewViewModelStages.Running}
status={
error
? 'error'
: stage >= ViewViewModelStages.Running
? stage === ViewViewModelStages.Running
? 'processing'
: 'success'
: 'default'
}
/>
</Space>
</Operates>
<Actions>
<Space>
{allowManage && (
<Tooltip
title={
<TipTitle
title={[t('save'), t('saveWinTip'), t('saveMacTip')]}
/>
}
placement="bottom"
>
<ToolbarButton
icon={<SaveFilled />}
disabled={isArchived || stage !== ViewViewModelStages.Saveable}
color={INFO}
onClick={onSave}
/>
</Tooltip>
)}
{allowManage && (
<Tooltip title={t('info')} placement="bottom">
<ToolbarButton
icon={<SettingFilled />}
disabled={isArchived || isNewView(id)}
color={INFO}
onClick={showEdit}
/>
</Tooltip>
)}
{allowManage && (
<Tooltip title={t('saveAs')} placement="bottom">
<ToolbarButton
icon={<CopyFilled />}
onClick={() => saveAsView(id)}
disabled={isNewView(id)}
color={INFO}
/>
</Tooltip>
)}
{/* <Tooltip title={t('saveFragment')} placement="bottom">
<ToolbarButton icon={<SnippetsFilled />} />
</Tooltip> */}
{allowEnableViz && (
<Tooltip title={t('startAnalysis')} placement="bottom">
<ToolbarButton
disabled={isNewView(id)}
icon={<MonitorOutlined />}
color={INFO}
onClick={() => {
startAnalysis(id);
}}
/>
</Tooltip>
)}
</Space>
</Actions>
</Container>
);
})
Example #7
Source File: FolderTree.tsx From datart with Apache License 2.0 | 4 votes |
FolderTree = memo(({ treeData }: FolderTreeProps) => {
const dispatch = useDispatch();
const history = useHistory();
const { showSaveForm } = useContext(SaveFormContext);
const loading = useSelector(selectViewListLoading);
const currentEditingViewKey = useSelector(selectCurrentEditingViewKey);
const orgId = useSelector(selectOrgId);
const viewsData = useSelector(selectViews);
const isOwner = useSelector(selectIsOrgOwner);
const permissionMap = useSelector(selectPermissionMap);
const t = useI18NPrefix('view');
const tg = useI18NPrefix('global');
const saveAsView = useSaveAsView();
const startAnalysis = useStartAnalysis();
const allowEnableViz = useAccess({
type: 'module',
module: ResourceTypes.Viz,
id: '',
level: PermissionLevels.Enable,
})(true);
useEffect(() => {
dispatch(getViews(orgId));
}, [dispatch, orgId]);
const redirect = useCallback(
currentEditingViewKey => {
if (currentEditingViewKey) {
history.push(`/organizations/${orgId}/views/${currentEditingViewKey}`);
} else {
history.push(`/organizations/${orgId}/views`);
}
},
[history, orgId],
);
const archive = useCallback(
(id, isFolder) => e => {
e.stopPropagation();
dispatch(
deleteView({
id,
archive: !isFolder,
resolve: () => {
dispatch(removeEditingView({ id, resolve: redirect }));
message.success(
isFolder
? tg('operation.deleteSuccess')
: tg('operation.archiveSuccess'),
);
},
}),
);
},
[dispatch, redirect, tg],
);
const moreMenuClick = useCallback(
({ id, name, parentId, index, isFolder }) =>
({ key, domEvent }) => {
domEvent.stopPropagation();
switch (key) {
case 'info':
showSaveForm({
type: CommonFormTypes.Edit,
visible: true,
simple: isFolder,
initialValues: {
id,
name,
parentId,
},
parentIdLabel: t('saveForm.folder'),
onSave: (values, onClose) => {
if (isParentIdEqual(parentId, values.parentId)) {
index = getInsertedNodeIndex(values, viewsData);
}
dispatch(
updateViewBase({
view: {
id,
...values,
parentId: values.parentId || null,
index,
},
resolve: onClose,
}),
);
},
});
break;
case 'delete':
break;
case 'saveAs':
saveAsView(id);
break;
case 'startAnalysis':
startAnalysis(id);
break;
default:
break;
}
},
[dispatch, showSaveForm, viewsData, t, saveAsView, startAnalysis],
);
const renderTreeTitle = useCallback(
node => {
const { title, path, isFolder, id } = node;
const isAuthorized = getCascadeAccess(
isOwner,
permissionMap,
ResourceTypes.View,
path,
PermissionLevels.Manage,
);
return (
<TreeTitle>
<h4>{`${title}`}</h4>
{isAuthorized || allowEnableViz ? (
<Popup
trigger={['click']}
placement="bottom"
content={
<Menu
prefixCls="ant-dropdown-menu"
selectable={false}
onClick={moreMenuClick(node)}
>
{isAuthorized && (
<MenuListItem
key="info"
prefix={<EditOutlined className="icon" />}
>
{tg('button.info')}
</MenuListItem>
)}
{isAuthorized && !isFolder && (
<MenuListItem
key="saveAs"
prefix={<CopyFilled className="icon" />}
>
{tg('button.saveAs')}
</MenuListItem>
)}
{allowEnableViz && !isFolder && (
<MenuListItem
prefix={<MonitorOutlined className="icon" />}
key="startAnalysis"
>
{t('editor.startAnalysis')}
</MenuListItem>
)}
{isAuthorized && (
<MenuListItem
key="delete"
prefix={<DeleteOutlined className="icon" />}
>
<Popconfirm
title={
isFolder
? tg('operation.deleteConfirm')
: tg('operation.archiveConfirm')
}
onConfirm={archive(id, isFolder)}
>
{isFolder ? tg('button.delete') : tg('button.archive')}
</Popconfirm>
</MenuListItem>
)}
</Menu>
}
>
<span className="action" onClick={stopPPG}>
<MoreOutlined />
</span>
</Popup>
) : (
''
)}
</TreeTitle>
);
},
[archive, moreMenuClick, tg, allowEnableViz, t, isOwner, permissionMap],
);
const treeSelect = useCallback(
(_, { node }) => {
if (!node.isFolder && node.id !== currentEditingViewKey) {
history.push(`/organizations/${orgId}/views/${node.id}`);
}
},
[history, orgId, currentEditingViewKey],
);
const onDrop = info => {
onDropTreeFn({
info,
treeData,
callback: (id, parentId, index) => {
dispatch(
updateViewBase({
view: {
id,
parentId,
index: index,
name: info.dragNode.name,
},
resolve: () => {},
}),
);
},
});
};
return (
<Tree
loading={loading}
treeData={treeData}
titleRender={renderTreeTitle}
selectedKeys={[currentEditingViewKey]}
onSelect={treeSelect}
defaultExpandAll
onDrop={onDrop}
draggable
/>
);
})
Example #8
Source File: FolderTree.tsx From datart with Apache License 2.0 | 4 votes |
export function FolderTree({
selectedId,
treeData,
i18nPrefix,
}: FolderTreeProps) {
const tg = useI18NPrefix('global');
const dispatch = useDispatch();
const history = useHistory();
const orgId = useSelector(selectOrgId);
const loading = useSelector(selectVizListLoading);
const vizsData = useSelector(selectVizs);
const { showSaveForm } = useContext(SaveFormContext);
const saveAsViz = useSaveAsViz();
useEffect(() => {
dispatch(getFolders(orgId));
}, [dispatch, orgId]);
const redirect = useCallback(
tabKey => {
if (tabKey) {
history.push(`/organizations/${orgId}/vizs/${tabKey}`);
} else {
history.push(`/organizations/${orgId}/vizs`);
}
},
[history, orgId],
);
const menuSelect = useCallback(
(_, { node }) => {
if (node.relType !== 'FOLDER') {
history.push(`/organizations/${orgId}/vizs/${node.relId}`);
}
},
[history, orgId],
);
const archiveViz = useCallback(
({ id: folderId, relId, relType }) =>
() => {
let id = folderId;
let archive = false;
let msg = tg('operation.deleteSuccess');
if (['DASHBOARD', 'DATACHART'].includes(relType)) {
id = relId;
archive = true;
msg = tg('operation.archiveSuccess');
}
dispatch(
deleteViz({
params: { id, archive },
type: relType,
resolve: () => {
message.success(msg);
dispatch(removeTab({ id, resolve: redirect }));
},
}),
);
},
[dispatch, redirect, tg],
);
const moreMenuClick = useCallback(
node =>
({ key, domEvent }) => {
domEvent.stopPropagation();
switch (key) {
case 'info':
showSaveForm({
vizType: node.relType,
type: CommonFormTypes.Edit,
visible: true,
initialValues: { ...node, parentId: node.parentId || void 0 },
onSave: (values, onClose) => {
let index = node.index;
if (isParentIdEqual(node.parentId, values.parentId)) {
index = getInsertedNodeIndex(values, vizsData);
}
dispatch(
editFolder({
folder: {
...values,
parentId: values.parentId || null,
index,
},
resolve: onClose,
}),
);
},
});
break;
case 'delete':
break;
case 'saveAs':
saveAsViz(node.relId, node.relType);
break;
default:
break;
}
},
[dispatch, showSaveForm, vizsData, saveAsViz],
);
const renderTreeTitle = useCallback(
node => {
const { isFolder, title, path, relType } = node;
return (
<TreeTitle>
<h4>{`${title}`}</h4>
<CascadeAccess
module={ResourceTypes.Viz}
path={path}
level={PermissionLevels.Manage}
>
<Popup
trigger={['click']}
placement="bottom"
content={
<Menu
prefixCls="ant-dropdown-menu"
selectable={false}
onClick={moreMenuClick(node)}
>
<MenuListItem
key="info"
prefix={<EditOutlined className="icon" />}
>
{tg('button.info')}
</MenuListItem>
{!isFolder && (
<MenuListItem
key="saveAs"
prefix={<CopyFilled className="icon" />}
>
{tg('button.saveAs')}
</MenuListItem>
)}
<MenuListItem
key="delete"
prefix={<DeleteOutlined className="icon" />}
>
<Popconfirm
title={`${
relType === 'FOLDER'
? tg('operation.deleteConfirm')
: tg('operation.archiveConfirm')
}`}
onConfirm={archiveViz(node)}
>
{relType === 'FOLDER'
? tg('button.delete')
: tg('button.archive')}
</Popconfirm>
</MenuListItem>
</Menu>
}
>
<span className="action" onClick={stopPPG}>
<MoreOutlined />
</span>
</Popup>
</CascadeAccess>
</TreeTitle>
);
},
[moreMenuClick, archiveViz, tg],
);
const onDrop = info => {
onDropTreeFn({
info,
treeData,
callback: (id, parentId, index) => {
dispatch(
editFolder({
folder: {
id,
parentId,
index: index,
},
resolve: () => {},
}),
);
},
});
};
return (
<Tree
loading={loading}
treeData={treeData}
titleRender={renderTreeTitle}
onSelect={menuSelect}
onDrop={onDrop}
{...(selectedId && { selectedKeys: [selectedId] })}
defaultExpandAll
draggable
/>
);
}