@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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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
    />
  );
}