antd#Popconfirm TypeScript Examples

The following examples show how to use antd#Popconfirm. 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: PersonalAPIKeys.tsx    From posthog-foss with MIT License 6 votes vote down vote up
function RowActionsCreator(
    deleteKey: (key: PersonalAPIKeyType) => void
): (personalAPIKey: PersonalAPIKeyType) => JSX.Element {
    return function RowActions(personalAPIKey: PersonalAPIKeyType) {
        return (
            <Popconfirm
                title={`Permanently delete key "${personalAPIKey.label}"?`}
                okText="Delete Key"
                okType="danger"
                icon={<ExclamationCircleOutlined style={{ color: red.primary }} />}
                placement="left"
                onConfirm={() => {
                    deleteKey(personalAPIKey)
                }}
            >
                <a className="text-danger">Delete</a>
            </Popconfirm>
        )
    }
}
Example #2
Source File: utils.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
OperationAction = (props: IOperationAction) => {
  const { operation, children, onClick, tipProps, operations, tip } = props;
  if (!operation && !operations)
    return tip ? (
      <Tooltip
        title={
          <div>
            {tip.split('\n').map((item) => (
              <React.Fragment key={item}>
                {item}
                <br />
              </React.Fragment>
            ))}
          </div>
        }
      >
        {children}
      </Tooltip>
    ) : (
      children
    );
  let curOp: CP_COMMON.Operation = operation;
  if (operations) {
    const clickOp = map(filterClickOperations(operations));
    if (clickOp[0]) {
      curOp = clickOp[0];
    }
  }
  const curTip = (curOp.tip || tip) && (
    <div>
      {(curOp.tip || tip).split('\n').map((item: string) => (
        <React.Fragment key={item}>
          {item}
          <br />
        </React.Fragment>
      ))}
    </div>
  );
  if (curOp.disabled === true) {
    // 无权限操作
    return (
      <WithAuth noAuthTip={curOp.disabledTip || curTip} key={curOp.key} pass={false} tipProps={tipProps}>
        {children}
      </WithAuth>
    );
  } else if (curOp.confirm) {
    // 需要确认的操作
    return (
      <Popconfirm
        title={curOp.confirm}
        arrowPointAtCenter
        placement="topRight"
        onConfirm={(e) => {
          e && e.stopPropagation();
          onClick(e);
        }}
        key={curOp.key}
        onCancel={(e) => e && e.stopPropagation()}
      >
        {React.cloneElement(children, {
          onClick: (e: MouseEvent) => e.stopPropagation(),
        })}
      </Popconfirm>
    );
  } else {
    // 普通的操作
    return (
      <Tooltip title={curTip}>
        {React.cloneElement(children, {
          key: curOp.key,
          onClick: (e: MouseEvent) => {
            e.stopPropagation();
            onClick(e);
          },
        })}
      </Tooltip>
    );
  }
}
Example #3
Source File: FormList.tsx    From condo with MIT License 6 votes vote down vote up
function ExtraDropdownActionsMenu ({ actions }) {
    const actionsLine = actions.filter(identity)
    const [popConfirmProps, setPopConfirmProps] = useState({ visible: false, title: null, icon: null })

    function handleAction ({ key }) {
        const action = actionsLine[key]
        if (action.confirm) {
            setPopConfirmProps({
                visible: true,
                onConfirm: action.action,
                onCancel: () => setPopConfirmProps({ visible: false, title: null, icon: null }),
                ...action.confirm,
            })
        } else {
            setPopConfirmProps({ visible: false, title: null, icon: null })
            action.action()
        }
    }

    return <Popconfirm {...popConfirmProps}>
        <Dropdown overlay={<Menu onClick={handleAction}>
            {actionsLine.map((action, i) => <Menu.Item key={i}>{action.label}</Menu.Item>)}
        </Menu>}>
            <a> ... <DownOutlined /></a>
        </Dropdown>
    </Popconfirm>
}
Example #4
Source File: StudentBanner.tsx    From office-hours with GNU General Public License v3.0 6 votes vote down vote up
function LeaveQueueButton({ leaveQueue }: { leaveQueue: () => void }) {
  return (
    <Popconfirm
      title={`Are you sure you want to leave the queue?`}
      okText="Yes"
      cancelText="No"
      onConfirm={leaveQueue}
    >
      <Tooltip title="Leave Queue">
        <BannerDangerButton
          data-cy="leave-queue"
          icon={<DeleteRowOutlined />}
        />
      </Tooltip>
    </Popconfirm>
  );
}
Example #5
Source File: CodeSnippet.tsx    From posthog-foss with MIT License 5 votes vote down vote up
export function CodeSnippet({
    children,
    language = Language.Text,
    wrap = false,
    style = {},
    actions,
    copyDescription = 'code snippet',
    hideCopyButton = false,
}: CodeSnippetProps): JSX.Element {
    return (
        <div className="code-container" style={style}>
            <div className="action-icon-container">
                {actions &&
                    actions.map(({ Icon, callback, popconfirmProps, title }, index) =>
                        !popconfirmProps ? (
                            <Icon
                                key={`snippet-action-${index}`}
                                className="action-icon"
                                onClick={callback}
                                title={title}
                            />
                        ) : (
                            <Popconfirm key={`snippet-action-${index}`} {...popconfirmProps} onConfirm={callback}>
                                <Icon className="action-icon" title={title} />
                            </Popconfirm>
                        )
                    )}
                {!hideCopyButton && (
                    <CopyOutlined
                        className="action-icon"
                        onClick={() => {
                            children && copyToClipboard(children, copyDescription)
                        }}
                        title="Copy"
                    />
                )}
            </div>
            <SyntaxHighlighter
                style={okaidia}
                language={language}
                customStyle={{ borderRadius: 2 }}
                wrapLines={wrap}
                lineProps={{ style: { whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' } }}
            >
                {children}
            </SyntaxHighlighter>
        </div>
    )
}
Example #6
Source File: Editor.tsx    From dnde with GNU General Public License v3.0 5 votes vote down vote up
Delete = ({ style, deleteConfirm }: DeleteProps) => {
  return (
    <Popconfirm placement="right" title="Are you sure ?" okText="Delete" cancelText="Cancel" onConfirm={deleteConfirm}>
      <Button style={style} type="primary" icon={<DeleteFilled />} />
    </Popconfirm>
  );
}
Example #7
Source File: Operation.tsx    From antdp with MIT License 5 votes vote down vote up
operation = ({
  optConfig,
  isEditing,
  isAddEdit,
  save,
  isOptDelete,
  cancel,
  onDelete,
  edit,
  newAdd,
  editingKey,
  rowKey,
  multiple,
}: OperationProps): ColumnsProps[] => [
    {
      title: '操作',
      align: 'center',
      width: 120,
      ...optConfig,
      render: (item: any, record: any, index: number) => {
        const editable = isEditing(record);
        const isNewAdd = isAddEdit(record);
        if (optConfig && optConfig.render) {
          return optConfig.render(item, record, index, {
            editable,
            isNewAdd,
            save,
            cancel,
            onDelete,
            edit,
            newAdd,
            editingKey,
          });
        }
        return editable ? (
          <span>
            <Typography.Link
              onClick={() => save(record[rowKey], record, index)}
              style={{ marginRight: 8 }}
            >
              保存
            </Typography.Link>
            <Popconfirm
              title="是否取消当前行编辑?"
              okText="是"
              cancelText="否"
              onConfirm={
                // 如果是新增操作的数据,进行判断 取消时使用删除方法
                isNewAdd
                  ? onDelete.bind(this, record[rowKey], record, index)
                  : cancel.bind(this, record[rowKey])
              }
            >
              <Typography.Link>取消</Typography.Link>
            </Popconfirm>
          </span>
        ) : (
          <Space>
            <Typography.Link
              disabled={!!editingKey.length && !multiple}
              onClick={() => edit(record)}
            >
              编辑
            </Typography.Link>
            {isOptDelete && (
              <Popconfirm
                title="是否删除当前行数据?"
                okText="是"
                cancelText="否"
                onConfirm={() => onDelete(record[rowKey], record, index)}
              >
                <Typography.Link>删除</Typography.Link>
              </Popconfirm>
            )}
          </Space>
        );
      },
    },
  ]
Example #8
Source File: Relation.tsx    From XFlow with MIT License 5 votes vote down vote up
Relation = (props: Props) => {
  const relation: RelationCanvasModel = props?.data

  const renderRelationOperationItem = (relation: RelationCanvasModel) => {
    const sourcePropertyName = relation?.source
    const targetPropertyName = relation?.target
    return (
      <div className="relation-operation-item" key={relation.id}>
        <div className="relation-operation-item-content">
          <Tooltip placement="top" title={sourcePropertyName}>
            <span className="relation-property-source">{sourcePropertyName}</span>
          </Tooltip>
          (N:1)
          <Tooltip placement="top" title={targetPropertyName}>
            <span className="relation-property-target">{targetPropertyName}</span>
          </Tooltip>
        </div>
        <Popconfirm
          placement="leftTop"
          title="你确定要删除该关系吗"
          okText="确定"
          cancelText="取消"
          onConfirm={() => {
            props?.deleteRelation(relation.id)
          }}
        >
          <ScissorOutlined />
        </Popconfirm>
      </div>
    )
  }

  const renderPopoverContent = () => {
    return (
      <div className="relation-operation-container">{renderRelationOperationItem(relation)}</div>
    )
  }

  return (
    <Popover
      trigger={'hover'}
      content={renderPopoverContent()}
      overlayClassName="relation-operation-popover"
    >
      <div className="relation-count-container">{1}</div>
    </Popover>
  )
}
Example #9
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
TagItem = (props: IItemProps) => {
  const {
    label: _label,
    size = 'default',
    maxWidth,
    onDelete,
    deleteConfirm = true,
    colorMap,
    checked,
    readOnly,
    style: styleProps,
  } = props;
  const { label, color = 'blue' } = _label;
  const [isChecked, setIsChecked] = React.useState(checked);
  // TODO: compatible with gray which color is removed now
  const curColor = color === 'gray' ? 'blue' : color;
  const style = {
    maxWidth,
    ...styleProps,
  };

  React.useEffect(() => {
    if (readOnly) {
      setIsChecked(checked);
    }
  }, [checked, readOnly]);

  const cls = isChecked
    ? `text-${curColor}-light bg-${curColor}-deep border-0 border-solid border-l-2 border-${curColor}-mid`
    : `text-${curColor}-deep bg-${curColor}-light border-0 border-solid border-l-2 border-${curColor}-mid`;

  return (
    <span style={style} className={`tag-default twt-tag-item ${size} ${cls}`}>
      <div className="flex items-center">
        <Ellipsis
          title={label}
          zIndex={2010} // popconfirm zIndex is bigger than tooltip
        />
        {onDelete ? (
          deleteConfirm ? (
            <Popconfirm
              title={`${i18n.t('common:confirm to delete')}?`}
              arrowPointAtCenter
              zIndex={2000} //  popconfirm default zIndex=1030, is smaller than tooltip zIndex=1070
              onConfirm={(e) => {
                e?.stopPropagation();
                onDelete(_label);
              }}
              onCancel={(e) => e && e.stopPropagation()}
            >
              <ErdaIcon size="16" className="cursor-pointer text-default-2 ml-0.5" type="close" />
            </Popconfirm>
          ) : (
            <ErdaIcon
              size="16"
              className="cursor-pointer text-default-2 ml-0.5"
              type="close"
              onClick={(e) => {
                e?.stopPropagation();
                onDelete(_label);
              }}
            />
          )
        ) : null}
        {isChecked && !readOnly && (
          <ErdaIcon
            size="16"
            className={`cursor-pointer text-default-2 ml-0.5 text-${color}-light`}
            type="check"
            onClick={() => setIsChecked(!isChecked)}
          />
        )}
        {checked && readOnly && <CustomIcon className={`text-default-2 ml-0.5 text-${color}-light`} type="tg" />}
      </div>
    </span>
  );
}
Example #10
Source File: EditableTable.tsx    From jetlinks-ui-antd with MIT License 5 votes vote down vote up
columns = [
        {
            title: '源字段',
            dataIndex: 'source',
            editable: true,
        },
        {
            title: '目标字段',
            dataIndex: 'target',
            editable: true,
        },
        {
            title: '类型',
            dataIndex: 'type',
            editable: true,
        },
        {
            title: '操作',
            dataIndex: 'operation',
            render: (text: any, record: any) => {
                const { editingKey } = this.state;
                const editable = this.isEditing(record);
                return editable ? (
                    <span>
                        <EditableContext.Consumer>
                            {form => (
                                <a
                                    href="javascript:;"
                                    onClick={() => this.save(form, record.key)}
                                    style={{ marginRight: 8 }}
                                >
                                    保存
                  </a>
                            )}
                        </EditableContext.Consumer>
                        <Popconfirm title="确认取消?" onConfirm={() => this.cancel()}>
                            <a>取消</a>
                        </Popconfirm>
                    </span>
                ) : (
                        <span>
                            <a disabled={editingKey !== ''} onClick={() => this.edit(record.key)}>
                                编辑
                                </a>
                            <Divider type="vertical" />
                            <a disabled={editingKey !== ''} onClick={() => this.delete(record.key)}>
                                删除
                                </a>
                        </span>
                    );
            },
        },
    ];
Example #11
Source File: SourceEditorOauthButtons.tsx    From jitsu with MIT License 5 votes vote down vote up
SourceEditorOauthButtons: React.FC<Props> = ({
  sourceDataFromCatalog,
  disabled,
  isSignedIn,
  onIsOauthSupportedCheckSuccess,
  onFillAuthDataManuallyChange,
  setOauthSecretsToForms,
}) => {
  const [fillAuthDataManually, setFillAuthDataManually] = useState<boolean>(true)
  const [isOauthSupported, setIsOauthSupported] = useState<boolean>(false)

  const handleFillAuthDataManuallyToggle = useCallback<() => void>(() => {
    setFillAuthDataManually(value => {
      const newValue = !value
      onFillAuthDataManuallyChange?.(value)
      return newValue
    })
  }, [])

  const handleOauthSupportCheckStatus = useCallback<(supported: boolean) => void>(
    supported => {
      onIsOauthSupportedCheckSuccess(supported)
      setIsOauthSupported(supported)
    },
    [onIsOauthSupportedCheckSuccess]
  )

  return (
    <Row key="oauth-button" className="h-8 mb-5">
      <Col span={4} />
      <Col span={20} className="flex items-center pl-2">
        <div>
          <OauthButton
            key="oauth-button"
            service={sourceDataFromCatalog.id}
            forceNotSupported={sourceDataFromCatalog.expertMode}
            disabled={disabled}
            icon={<span className="align-middle h-5 w-7 pr-3 ">{sourceDataFromCatalog.pic}</span>}
            isGoogle={
              sourceDataFromCatalog.id.toLowerCase().includes("google") ||
              sourceDataFromCatalog.id.toLowerCase().includes("firebase")
            }
            setAuthSecrets={setOauthSecretsToForms}
            onIsOauthSuppotedStatusChecked={handleOauthSupportCheckStatus}
          >
            <span className="align-top">{`${
              isSignedIn ? "Re-Sign In" : `Grant Jitsu Access to ${sourceDataFromCatalog.displayName}`
            }`}</span>
          </OauthButton>
        </div>
        {isOauthSupported && (
          <>
            <Popconfirm
              title="This will reset all manual inputs. Are you sure you want to exit?"
              onConfirm={handleFillAuthDataManuallyToggle}
              disabled={fillAuthDataManually}
            >
              <Button type="link" onClick={fillAuthDataManually ? handleFillAuthDataManuallyToggle : undefined}>
                {fillAuthDataManually ? "Fill Auth Credentials Manually" : "Exit Manual Mode"}
              </Button>
            </Popconfirm>
          </>
        )}
      </Col>
    </Row>
  )
}
Example #12
Source File: index.tsx    From visual-layout with MIT License 5 votes vote down vote up
Header: React.FC<{
  projectService: ProjectService;
  options: Options;
  setOptions: (options: Options) => void;
}> = ({ projectService, options, setOptions }) => {
  return (
    <div className={styles.header}>
      <div className={styles.pagesWarper}>
        <div className={styles.pages}>
          {Object.values(projectService.getPages()).map(({ name, id }) => {
            const style = {
              border: `1px solid ${
                id === projectService.currentId ? '#1890ff' : ''
              }`,
            };
            return (
              <div key={id} className={styles.page} style={style}>
                <span onClick={() => projectService.setPages(id)}>{name}</span>
                <Popconfirm
                  title="确定删除?"
                  onConfirm={() => projectService.delete(id)}
                  onCancel={() => {}}
                  okText="是"
                  cancelText="否"
                >
                  <div className={styles.close}>
                    <CloseCircleOutlined />
                  </div>
                </Popconfirm>
              </div>
            );
          })}
        </div>
        <div className={styles.new}>
          <Button
            onClick={() => {
              openNewBuildModal({
                projectService,
              });
            }}
          >
            新建
          </Button>
        </div>
      </div>
      <div className={styles.opr}>
        <Operation
          options={options}
          setOptions={setOptions}
          projectService={projectService}
        />
      </div>
    </div>
  );
}
Example #13
Source File: ChartTypeSelector.tsx    From datart with Apache License 2.0 5 votes vote down vote up
ChartTypeSelector: FC<{
  type;
  translate: (title: string) => string;
  onChange: (value) => void;
  onCreateDownloadDataTask?: () => void;
}> = memo(({ type, onChange, onCreateDownloadDataTask }) => {
  const t = useI18NPrefix(`viz.action.common`);
  const typeChange = useCallback(
    type => () => {
      onChange(type);
    },
    [onChange],
  );

  return (
    <StyledChartTypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.GRAPH })}
        onClick={typeChange(ChartPresentType.GRAPH)}
      >
        <AreaChartOutlined />
      </TypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.RAW })}
        onClick={typeChange(ChartPresentType.RAW)}
      >
        <TableOutlined />
      </TypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.SQL })}
        onClick={typeChange(ChartPresentType.SQL)}
      >
        <ConsoleSqlOutlined />
      </TypeSelector>
      <TypeSelector
        fontSize={FONT_SIZE_HEADING}
        className={classnames({ active: type === ChartPresentType.DOWNLOAD })}
      >
        <Popconfirm
          placement="left"
          title={t('downloadForExcel')}
          onConfirm={onCreateDownloadDataTask}
        >
          <CloudDownloadOutlined />
        </Popconfirm>
      </TypeSelector>
    </StyledChartTypeSelector>
  );
})
Example #14
Source File: FileList.tsx    From nebula-studio with Apache License 2.0 5 votes vote down vote up
FileList = (props: IProps) => {
  const { onDelete, fileList, onUpload, loading } = props;
  const columns = [
    {
      title: intl.get('import.fileName'),
      dataIndex: 'name',
    },
    {
      title: intl.get('import.withHeader'),
      key: 'withHeader',
      render: () => <Checkbox disabled={true} />,
    },
    {
      title: intl.get('import.fileSize'),
      key: 'size',
      dataIndex: 'size',
      render: size => getFileSize(size),
    },
    {
      title: intl.get('common.operation'),
      key: 'operation',
      render: (_, file, index) => {
        if(!file.content) {
          return null;
        }
        return (
          <div className={styles.operation}>
            <CSVPreviewLink file={file} btnType="default">
              <Icon type="icon-studio-btn-detail" />
            </CSVPreviewLink>
            <Popconfirm
              onConfirm={() => onDelete(index)}
              title={intl.get('common.ask')}
              okText={intl.get('common.ok')}
              cancelText={intl.get('common.cancel')}
            >
              <Button className="warningBtn" type="link">
                <Icon type="icon-studio-btn-delete" />
              </Button>
            </Popconfirm>
          </div>
        );
      },
    },
  ];
  return (
    <div className={styles.fileUpload}>
      <Upload
        multiple={true}
        accept=".csv"
        showUploadList={false}
        fileList={fileList}
        customRequest={() => {}}
        beforeUpload={onUpload}
      >
        <Button className={cls('studioAddBtn', styles.uploadBtn)} type="primary">
          <Icon className="studioAddBtnIcon" type="icon-studio-btn-add" />{intl.get('import.uploadFile')}
        </Button>
      </Upload>

      <div className={styles.fileList}>
        <h3>{intl.get('import.fileTitle')}</h3>
        <Table
          loading={!!loading}
          dataSource={fileList}
          columns={columns}
          rowKey="name"
          pagination={false}
        />
      </div>
    </div>
  );
}
Example #15
Source File: FuzzableParamList.tsx    From yakit with GNU Affero General Public License v3.0 5 votes vote down vote up
FuzzableParamList: React.FC<FuzzableParamListProp> = (props) => {
    return <Table<FuzzableParams>
        pagination={false}
        dataSource={props.data}
        rowKey={row => row.ParamName}
        columns={[
            {title: "参数名", render: (i: FuzzableParams) => <Tag>{i.ParamName}</Tag>},
            {title: "参数位置", render: (i: FuzzableParams) => <Tag>{i.Position}</Tag>},
            {
                title: "参数原值", render: (i: FuzzableParams) => <Tag><Text style={{maxWidth: 500}} ellipsis={{
                    tooltip: true,
                }} copyable={true}>
                    {i.OriginValue ? new Buffer(i.OriginValue).toString() : ""}
                </Text></Tag>
            },
            {title: "IsHTTPS", render: (i: FuzzableParams) => <Tag>{i.IsHTTPS}</Tag>},
            {
                title: "操作", render: (i: FuzzableParams) => <Space>
                    <Popconfirm title={"测试该参数将会暂时进入 Web Fuzzer"}
                                onConfirm={(e) => {
                                    ipcRenderer.invoke("send-to-tab", {
                                        type: "fuzzer",
                                        data:{
                                            isHttps: i.IsHTTPS,
                                            request: new Buffer(i.AutoTemplate).toString("utf8")
                                        }
                                    })
                                    if (props.sendToWebFuzzer) props.sendToWebFuzzer()
                                }}
                    >
                        <Button
                            type={"primary"} size={"small"}
                        >模糊测试该参数</Button>
                    </Popconfirm>
                </Space>
            },
        ]}
    >

    </Table>
}
Example #16
Source File: table.tsx    From generator-earth with MIT License 4 votes vote down vote up
useTableEffect = () => {
    // 控制modal显示隐藏
    const [visible, setVisible] = useState<boolean>(false)

    // get history by hooks, useHistory可以完全替代withRouter
    // const history = useHistory()

    // 路由根路径
    const CONTAINER_ROUTE_PREFIX = useBaseContext();

    // handle delete
    function onDelete() {
        console.log('onDelete', arguments)
    }

    // handle close modal
    function closeModal() {
        setVisible(false);
    }

    const columns: ColumnProps<ITableRecord>[] = useMemo(() => ([
        {
            title: '资产方编号',
            dataIndex: 'assetCode',
            key: 'assetCode'
        }, {
            title: '资产方名称',
            dataIndex: 'assetName',
            key: 'assetName'
        }, {
            title: '签约主体',
            dataIndex: 'contract',
            key: 'contract'
        }, {
            title: '签约时间',
            dataIndex: 'contractDate',
            key: 'contractDate'
        }, {
            title: '联系人',
            dataIndex: 'contacts',
            key: 'contacts'
        }, {
            title: '联系电话',
            dataIndex: 'contactsPhone',
            key: 'contactsPhone'
        }, {
            title: '创建时间',
            dataIndex: 'createDate',
            key: 'createDate'
        }, {
            title: '操作人',
            dataIndex: 'operator',
            key: 'operator'
        }
        , {
            title: '操作',
            key: 'action',
            fixed: 'right',
            render: (text, record) => (
                <Link to={`${CONTAINER_ROUTE_PREFIX}/item/edit/${record.id}`}>查看/修改</Link>
            )
        }, {
            title: '操作',
            key: 'action',
            fixed: 'right',
            render: (text, record) => {
                return (
                    <Popconfirm
                        title="Are you sure to delete this task?"
                        onConfirm={onDelete.bind(null, record.id)}
                    >
                        <a>删除</a>
                    </Popconfirm>
                )
            }
        }, {
            title: '操作',
            key: 'action',
            fixed: 'right',
            render: (text, record) => {
                return (
                    <a onClick={() => setVisible(true)}>新增</a>
                )
            }
        }
    ]), [CONTAINER_ROUTE_PREFIX])

    return {
        columns,
        onDelete,
        visible,
        closeModal,
    }
}
Example #17
Source File: PropertiesTable.tsx    From posthog-foss with MIT License 4 votes vote down vote up
export function PropertiesTable({
    properties,
    rootKey,
    onEdit,
    sortProperties = false,
    nestingLevel = 0,
    onDelete,
    className,
}: PropertiesTableType): JSX.Element {
    const objectProperties = useMemo(() => {
        if (!(properties instanceof Object)) {
            return []
        }
        const entries = Object.entries(properties)
        if (!sortProperties) {
            return entries
        }
        return entries.sort((a, b) => {
            if (a[0][0] === '$' && b[0][0] !== '$') {
                return 1
            } else if (a[0][0] !== '$' && b[0][0] === '$') {
                return -1
            }
            return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : 1
        })
    }, [properties, sortProperties])

    if (Array.isArray(properties)) {
        return (
            <div>
                {properties.length ? (
                    properties.map((item, index) => (
                        <PropertiesTable key={index} properties={item} nestingLevel={nestingLevel + 1} />
                    ))
                ) : (
                    <div className="property-value-type">ARRAY (EMPTY)</div>
                )}
            </div>
        )
    }

    const columns: LemonTableColumns<Record<string, any>> = [
        {
            title: 'key',
            width: '15rem',
            render: function Key(_, item: any): JSX.Element {
                return (
                    <div className="properties-table-key">
                        {onDelete && nestingLevel <= 1 && !keyMappingKeys.includes(item[0]) && (
                            <Popconfirm
                                onConfirm={() => onDelete(item[0])}
                                title={
                                    <>
                                        Are you sure you want to delete this property? <b>This cannot be undone.</b>
                                    </>
                                }
                            >
                                <DeleteOutlined className="cursor-pointer" />
                            </Popconfirm>
                        )}
                        <PropertyKeyInfo value={item[0]} />
                    </div>
                )
            },
        },
        {
            title: 'value',
            render: function Value(_, item: any): JSX.Element {
                return (
                    <PropertiesTable
                        properties={item[1]}
                        rootKey={item[0]}
                        onEdit={onEdit}
                        nestingLevel={nestingLevel + 1}
                    />
                )
            },
        },
    ]

    if (properties instanceof Object) {
        return (
            <LemonTable
                columns={columns}
                showHeader={false}
                size="small"
                rowKey="0"
                embedded
                dataSource={objectProperties}
                className={className}
                emptyState="This property contains an empty object."
            />
        )
    }
    // if none of above, it's a value
    return <ValueDisplay value={properties} rootKey={rootKey} onEdit={onEdit} nestingLevel={nestingLevel} />
}
Example #18
Source File: DevicesPage.tsx    From iot-center-v2 with MIT License 4 votes vote down vote up
DevicesPage: FunctionComponent<Props> = ({helpCollapsed}) => {
  const [loading, setLoading] = useState(true)
  const [message, setMessage] = useState<Message | undefined>(undefined)
  const [data, setData] = useState(NO_DEVICES)
  const [dataStamp, setDataStamp] = useState(0)
  const [lastEntries, setLastEntries] = useState(NO_ENTRIES)

  useEffect(() => {
    setLoading(true)
    const fetchDevices = async () => {
      try {
        const response = await fetch('/api/devices')
        if (response.status >= 300) {
          const text = await response.text()
          throw new Error(`${response.status} ${text}`)
        }
        const data = (await response.json()) as Array<DeviceInfo>
        setData(data)

        setLastEntries(
          await Promise.all(
            data.map(({deviceId}) => fetchLastEntryTime(deviceId))
          )
        )
      } catch (e) {
        setMessage({
          title: 'Cannot fetch data',
          description: String(e),
          type: 'error',
        })
      } finally {
        setLoading(false)
      }
    }
    fetchDevices()
  }, [dataStamp])

  const removeAuthorization = async (device: DeviceInfo) => {
    try {
      setLoading(true)
      const response = await fetch(`/api/devices/${device.deviceId}`, {
        method: 'DELETE',
      })
      if (response.status >= 300) {
        const text = await response.text()
        throw new Error(`${response.status} ${text}`)
      }
      setLoading(false)
      antdMessage.success(`Device ${device.deviceId} was unregistered`, 2)
    } catch (e) {
      setLoading(false)
      setMessage({
        title: 'Cannot remove device',
        description: String(e),
        type: 'error',
      })
    } finally {
      setDataStamp(dataStamp + 1)
    }
  }

  const addAuthorization = async (deviceId: string, deviceType: string) => {
    try {
      setLoading(true)
      const response = await fetch(`/api/env/${deviceId}`)
      if (response.status >= 300) {
        const text = await response.text()
        throw new Error(`${response.status} ${text}`)
      }
      const {newlyRegistered} = await response.json()

      if (newlyRegistered && deviceType !== '') {
        const setTypeResponse = await fetch(
          `/api/devices/${deviceId}/type/${deviceType}`,
          {
            method: 'POST',
          }
        )
        if (setTypeResponse.status >= 300) {
          const text = await setTypeResponse.text()
          throw new Error(`${setTypeResponse.status} ${text}`)
        }
      }

      setLoading(false)
      if (newlyRegistered) {
        antdMessage.success(`Device '${deviceId}' was registered`, 2)
      } else {
        antdMessage.success(`Device '${deviceId}' is already registered`, 2)
      }
    } catch (e) {
      setLoading(false)
      setMessage({
        title: 'Cannot register device',
        description: String(e),
        type: 'error',
      })
    } finally {
      setDataStamp(dataStamp + 1)
    }
  }

  // define table columns
  const columnDefinitions: ColumnsType<DeviceInfo> = [
    {
      title: 'Device ID',
      dataIndex: 'deviceId',
      defaultSortOrder: 'ascend',
      render: (deviceId: string) => (
        <Link to={`/devices/${deviceId}`}>{deviceId}</Link>
      ),
    },
    {
      title: 'Registration Time',
      dataIndex: 'createdAt',
      responsive: helpCollapsed ? ['lg'] : ['xxl'],
    },
    {
      title: 'Last Entry',
      dataIndex: 'deviceId',
      render: (id: string) => {
        const lastEntry = lastEntries.find(
          ({deviceId}) => deviceId === id
        )?.lastEntry
        if (lastEntry != null && lastEntry !== 0)
          return timeFormatter({
            timeZone: 'UTC',
            format: 'YYYY-MM-DD HH:mm:ss ZZ',
          })(lastEntry)
      },
      responsive: helpCollapsed ? ['xl'] : [],
    },
    {
      title: '',
      key: 'action',
      align: 'right',
      render: (_: string, device: DeviceInfo) => (
        <>
          <Tooltip title="Go to device settings" placement="topRight">
            <Button
              type="text"
              icon={<IconSettings />}
              href={`/devices/${device.deviceId}`}
            />
          </Tooltip>
          <Tooltip title="Go to device dashboard" placement="topRight">
            <Button
              type="text"
              icon={<IconDashboard />}
              href={`/dashboard/${device.deviceId}`}
            />
          </Tooltip>
          <Popconfirm
            icon={<ExclamationCircleFilled style={{color: 'red'}} />}
            title={`Are you sure to remove '${device.deviceId}' ?`}
            onConfirm={() => removeAuthorization(device)}
            okText="Yes"
            okType="danger"
            cancelText="No"
          >
            <Tooltip title="Remove device" placement="topRight" color="red">
              <Button type="text" icon={<IconDelete />} />
            </Tooltip>
          </Popconfirm>
        </>
      ),
    },
  ]

  return (
    <PageContent
      title="Device Registrations"
      spin={loading}
      message={message}
      titleExtra={
        <>
          <Tooltip title="Register a new Device">
            <Button
              onClick={() => {
                let deviceId = ''
                let deviceType = ''
                Modal.confirm({
                  title: 'Register Device',
                  icon: '',
                  content: (
                    <Form
                      name="registerDevice"
                      initialValues={{deviceId, deviceType}}
                    >
                      <Form.Item
                        name="deviceId"
                        rules={[
                          {required: true, message: 'Please input device ID !'},
                        ]}
                      >
                        <Input
                          placeholder="Device ID"
                          onChange={(e) => {
                            deviceId = e.target.value
                          }}
                        />
                        <Input
                          placeholder="Device type"
                          onChange={(e) => {
                            deviceType = e.target.value
                          }}
                        />
                      </Form.Item>
                    </Form>
                  ),
                  onOk: () => {
                    addAuthorization(deviceId, deviceType)
                  },
                  okText: 'Register',
                })
              }}
            >
              Register
            </Button>
          </Tooltip>
          <Tooltip title="Reload Table">
            <Button
              type="primary"
              onClick={() => setDataStamp(dataStamp + 1)}
              style={{marginRight: '8px'}}
            >
              Reload
            </Button>
          </Tooltip>
        </>
      }
    >
      <Table
        dataSource={data}
        columns={columnDefinitions}
        rowKey={deviceTableRowKey}
      />
    </PageContent>
  )
}
Example #19
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {
    const { dataSource, pagination } = this.state;
    const {
      form,
      title = '',
      className = '',
      addBtnText = i18n.t('common:Add'),
      disableAdd = false,
      disableDelete = false,
      editDisabled,
      existKeys = [],
      keyDisabled = false,
      isTextArea,
      validate,
      maxLength,
    } = this.props;
    const showPagination = dataSource.length >= pagination.pageSize;

    const deleteBtnClass = classNames({
      'delete-row-btn': true,
      'table-operations': true,
      disabled: editDisabled,
    });

    const columns: Array<ColumnProps<IItemData>> = [
      {
        title: 'KEY',
        dataIndex: 'key',
        width: 280,
        ellipsis: false,
        render: (text: string, record: IItemData) => (
          <InputItem
            form={form}
            name={ROW_KEY}
            value={text}
            nameId={record.uniKey}
            dataSource={dataSource}
            existKeys={existKeys}
            onChange={this.handleItemChange}
            initialValue={record[ROW_KEY]}
            editDisabled={editDisabled || keyDisabled}
            validate={validate && validate.key}
            maxLength={maxLength}
          />
        ),
      },
      {
        title: 'VALUE',
        dataIndex: 'value',
        ellipsis: false,
        render: (text: string, record: IItemData) => (
          <InputItem
            form={form}
            name={ROW_VALUE}
            value={text}
            nameId={record.uniKey}
            onChange={this.handleItemChange}
            initialValue={record[ROW_VALUE]}
            editDisabled={editDisabled}
            isTextArea={isTextArea}
            validate={validate && validate.value}
            maxLength={maxLength}
          />
        ),
      },
    ];

    if (!disableDelete) {
      columns.push({
        title: i18n.t('Operations'),
        width: 160,
        dataIndex: 'operation',
        className: 'operation',
        render: (_text, record) => {
          return (
            <Popconfirm
              title={`${i18n.t('common:confirm to delete')}?`}
              onConfirm={() => this.handleDelete(record.uniKey)}
            >
              <span className={deleteBtnClass}>
                <span className="table-operations-btn">{i18n.t('Delete')}</span>
              </span>
            </Popconfirm>
          );
        },
      });
    }

    return (
      <div className="key-value-table-wrap">
        <div className="add-row-btn-wrap">
          {!disableAdd && (
            <Button size="small" type="primary" ghost disabled={editDisabled} onClick={this.handleAdd}>
              {addBtnText}
            </Button>
          )}
          <span>{title}</span>
        </div>
        <Table
          dataSource={dataSource}
          columns={columns}
          rowKey="uniKey"
          pagination={showPagination ? pagination : false}
          className={`key-value-table ${className}`}
          scroll={undefined}
          onChange={this.handleTableChange}
        />
      </div>
    );
  }
Example #20
Source File: index.tsx    From react-resume-site with GNU General Public License v3.0 4 votes vote down vote up
History = () => {
  const localData = localStorage.getItem(LOCAL_STORE.MD_HISTORY);
  const data: HistoryLocalInfo[] = JSON.parse(localData || "[]").reverse() || [];
  const { templateStore } = useStores();
  const { setPreview, setTheme, setMdContent, setColor } = templateStore;
  const handleSelect = (md: string, theme: string, color: string) => {
    // 设置主题
    setTheme(theme);
    localStorage.setItem(LOCAL_STORE.MD_THEME, theme);
    // 设置颜色 
    setColor(color);
    localStorage.setItem(LOCAL_STORE.MD_COLOR, color);
    // 设置内容
    setMdContent(md)
    // 持久化设置
    localStorage.setItem(LOCAL_STORE.MD_RESUME, md);
    // 临时设置
    setTimeout(async () => {
      // 设置编辑器内容
      mdEditorRef && (mdEditorRef.setValue(md));
      // 拉取主题
      await getTheme(theme);
      document.body.style.setProperty("--bg", color);
      // 设置 html 渲染
      renderViewStyle(color)
    }, 300);

    setPreview(false);
  }
  const [ visible, setVisible ] = useState(false);
  return (
    <>
      <a
        className="ant-dropdown-link rs-link"
        onClick={(e) => {
          e.preventDefault();
          setVisible(true);
        }}
      >
        历史记录
      </a>
      <Modal
        title="历史记录"
        visible={visible}
        onCancel={() => {
          setVisible(false);
        }}
        footer={null}
        width={1100}
        >
        <List
          className="history-list"
          itemLayout="horizontal"
          dataSource={data}
          renderItem={item => (
            <List.Item
              actions={[
                <Popconfirm
                  title="确定使用此版本替换你当前编辑器中的内容吗?"
                  onConfirm={() => {
                    const { md, theme, color } = item;
                    handleSelect(md, theme, color);
                    setVisible(false);
                  }}
                  okText="决定了"
                  cancelText="再想想"
                >
                  <span className="btn btn-normal mr20">选择</span>
                </Popconfirm>
              ]}
            >
              <List.Item.Meta
                avatar={""}
                title={dayjs(item.time).format('YYYY-MM-DD HH:mm:ss')}
                description={item.md.slice(0, 800) + '...'}
              />
              <span className="hist">{ item.theme }</span>
              <Tag color={item.color}>{item.color}</Tag>
            </List.Item>
          )}
          ></List>
      </Modal>
    </>
  )
}
Example #21
Source File: index.tsx    From jetlinks-ui-antd with MIT License 4 votes vote down vote up
NotificationView = () => {
    const service = new Service('notifications/subscriptions');
    const [result, setResult] = useState<any>([]);
    const [loading, setLoading] = useState<boolean>(true);
    const [searchParam, setSearchParam] = useState<any>({
        pageSize: 10,
        sorts: {
            field: 'createTime',
            order: 'desc',
        },
    });

    const [saveVisible, setSaveVisible] = useState<boolean>(false);

    const [current, setCurrent] = useState<any>();
    const handleSearch = (params: any) => {
        setSearchParam(params);
        service.query(encodeQueryParam(params)).subscribe(resp => {
            setResult(resp);
            setLoading(false)
        });
    }

    useEffect(() => {
        handleSearch(searchParam);
    }, []);

    const remove = (id: string) => {
        setLoading(true);
        service.notification.remove(id).subscribe(() => {
            message.success('删除成功');
        }, () => {
            message.error('删除失败');
        }, () => {
            setLoading(false);
            handleSearch(searchParam);
        })
    }

    const columns: ColumnProps<Notification>[] = [
        {
            title: '订阅类型',
            dataIndex: 'subscriberType'
        }, {
            title: '订阅主题',
            dataIndex: 'topicProvider'
        }, {
            title: '订阅名称',
            dataIndex: 'subscribeName'
        }, {
            title: '状态',
            dataIndex: 'state.text'
        }, {
            title: '操作',
            render: (_, record) => {
                return (
                    <>
                        <a onClick={() => {
                            setSaveVisible(true);
                            setCurrent(record);
                        }}>配置</a>
                        <Divider type="vertical" />
                        {record.state?.value !== 'enabled' ?
                            (
                                <>
                                    <a onClick={
                                        () => {
                                            setLoading(true);
                                            service.notification.open(record.id).subscribe(() => {
                                                message.success('开启订阅成功');
                                            }, () => {
                                                message.error('操作失败');
                                            }, () => {
                                                setLoading(false);
                                                handleSearch(searchParam);
                                            })
                                        }
                                    }>
                                        开启
                                    </a>
                                    <Divider type="vertical" />
                                </>
                            ) :
                            <>
                                <a onClick={
                                    () => {
                                        setLoading(true);
                                        service.notification.close(record.id).subscribe(() => {
                                            message.success('关闭订阅成功');
                                        }, () => {
                                            message.error('操作失败');
                                        }, () => {
                                            setLoading(false);
                                            handleSearch(searchParam);
                                        })
                                    }}>关闭</a>
                                <Divider type="vertical" />
                            </>
                        }
                        <Popconfirm title="删除此订阅?" onConfirm={() => remove(record.id)}>
                            <a>删除</a>
                        </Popconfirm>
                    </>
                )
            }
        }
    ];

    const onTableChange = (
        pagination: any,
        filters: any,
        sorter: any,
    ) => {
        handleSearch({
            pageIndex: Number(pagination.current) - 1,
            pageSize: pagination.pageSize,
            terms: searchParam.terms,
            sorts: sorter.field ? sorter : searchParam.sorter,
        });
    };


    return (
        <div>
            <SearchForm
                search={(params: any) => {
                }}
                formItems={[{
                    label: '订阅名称',
                    key: 'subscribeName$LIKE',
                    type: 'string',
                }]}
            />
            <div style={{ margin: 10 }}>
                <Button
                    type="primary"
                    onClick={() => {
                        setCurrent({})
                        setSaveVisible(true);
                    }}
                >
                    添加订阅
                </Button>
            </div>
            <Table
                loading={loading}
                dataSource={result.data}
                columns={columns}
                rowKey="id"
                onChange={onTableChange}
                pagination={{
                    current: result.pageIndex + 1,
                    total: result.total,
                    pageSize: result.pageSize,
                    showQuickJumper: true,
                    showSizeChanger: true,
                    pageSizeOptions: ['10', '20', '50', '100'],
                    showTotal: (total: number) =>
                        `共 ${total} 条记录 第  ${result.pageIndex + 1}/${Math.ceil(
                            result.total / result.pageSize,
                        )}页`,
                }}
            />
            {
                saveVisible && (
                    <Save
                        data={current}
                        close={() => {
                            setSaveVisible(false);
                            handleSearch(searchParam);
                        }} />
                )
            }
        </div>
    )
}