antd#Badge TypeScript Examples

The following examples show how to use antd#Badge. 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: utils.tsx    From amiya with MIT License 7 votes vote down vote up
renderStatus = (status: string | number, options: Option[], type: 'badge' | 'tag' = 'badge') => {
  const selectOption: Option | undefined = options.find(({ value }: AnyKeyProps) => value === status)

  if (!selectOption || !selectOption.label) {
    return status
  }

  if (!selectOption.color && !selectOption.status) {
    return selectOption.label
  }

  return (
    <div>
      {type === 'badge' ? (
        <Badge color={selectOption.color} status={selectOption.status} text={selectOption.label} />
      ) : (
        <Tag color={selectOption.color}>{selectOption.label}</Tag>
      )}
    </div>
  )
}
Example #2
Source File: FilterToggle.tsx    From ant-extensions with MIT License 6 votes vote down vote up
FilterToggle: React.FC<IProps> = React.memo(({ collapsed = true, onToggle }) => {
  const { t } = useTranslation(I18nKey);
  const { filters } = useContext(Context);

  return (
    <Button
      className="ant-ext-sb__filterToggle"
      icon={<Badge showZero count={filters.length} overflowCount={25} />}
      ghost={!collapsed}
      onClick={onToggle}
      type={collapsed ? "default" : "primary"}
      onFocusCapture={(e) => e.target.blur()}
    >
      <span className="ant-ext-sb__filterToggle--label">{t("label.filters")}&nbsp;</span>
    </Button>
  );
})
Example #3
Source File: table-col.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
getCloudResourceStatusCol = (
  resourceType: IResourceType,
  title = i18n.t('Status'),
  dataIndex = 'status',
) => {
  return {
    title,
    dataIndex,
    width: 90,
    render: (value: string) => {
      return <Badge status={statusMap[resourceType][value]?.status || 'default'} text={value} />;
    },
  };
}
Example #4
Source File: index.tsx    From gant-design with MIT License 6 votes vote down vote up
//渲染menu主体
  renderSubMenu(prefixCls) {
    const { collapsed, mode } = this.state;
    const { selectedKey, menuData } = this.props;
    let selectedKeys = selectedKey ? [selectedKey] : (menuData.length && [menuData[0].key]) || [];
    let inlineCollapsed = mode == 'inline' && collapsed;
    let inlineProperty = mode == 'inline' ? { inlineCollapsed: collapsed } : {};
    return (
      <Menu
        className={prefixCls}
        selectedKeys={selectedKeys}
        mode={mode}
        onClick={this.onClick}
        {...inlineProperty}
      >
        {menuData.map((item: menuItem) => (
          <Menu.Item
            className={inlineCollapsed && `${prefixCls}-collapsed`}
            disabled={item.disabled}
            key={item.key}
          >
            {typeof item.icon == 'string' ? (
              <Icon type={item.icon} wrapperStyle={{ width: 'auto' }} />
            ) : (
              item.icon
            )}
            <span>{item.title}</span>
            {item.count && (
              <span className={`${prefixCls}-item-count`}>
                <Badge count={item.count} />
              </span>
            )}
          </Menu.Item>
        ))}
      </Menu>
    );
  }
Example #5
Source File: index.tsx    From jetlinks-ui-antd with MIT License 6 votes vote down vote up
render(): React.ReactNode {
    const { className, count, popupVisible, bell } = this.props;
    const { visible } = this.state;
    const noticeButtonClass = classNames(className, styles.noticeButton);
    const notificationBox = this.getNotificationBox();
    const NoticeBellIcon = bell || <Icon type="bell" className={styles.icon} />;
    const trigger = (
      <span className={classNames(noticeButtonClass, { opened: visible })}>
        <Badge count={count} style={{ boxShadow: 'none' }} className={styles.badge}>
          {NoticeBellIcon}
        </Badge>
      </span>
    );
    if (!notificationBox) {
      return trigger;
    }
    const popoverProps: {
      visible?: boolean;
    } = {};
    if ('popupVisible' in this.props) {
      popoverProps.visible = popupVisible;
    }

    return (
      <HeaderDropdown
        placement="bottomRight"
        overlay={notificationBox}
        overlayClassName={styles.popover}
        trigger={['click']}
        visible={visible}
        onVisibleChange={this.handleVisibleChange}
        {...popoverProps}
      >
        {trigger}
      </HeaderDropdown>
    );
  }
Example #6
Source File: EventsView.tsx    From jitsu with MIT License 6 votes vote down vote up
TabTitle: React.FC<{ icon: any; error?: boolean }> = ({ icon, error, children }) => {
  const maxLen = 50
  const titleString = children.toString()
  const title = (
    <div className="align-baseline flex items-center">
      <span className="inline-block h-6 w-6 pr-2">{icon}</span>
      <span>{trim(titleString, maxLen)}</span>
    </div>
  )
  const content = titleString.length > maxLen ? <Tooltip title={children}>{title}</Tooltip> : title
  return error ? (
    <Badge count={"!"} size="small">
      {content}
    </Badge>
  ) : (
    content
  )
}
Example #7
Source File: BadgedOption.tsx    From leek with Apache License 2.0 6 votes vote down vote up
badgedOption = (item) => {
  return (
    <Option key={item.key} value={item.key}>
      <Row style={{ width: "100%" }} justify="space-between">
        <Col>{item.key}</Col>
        <Col>
          <Badge
            count={item.doc_count}
            overflowCount={overflowCount}
            size="small"
            style={badgeStyle}
          />
        </Col>
      </Row>
    </Option>
  );
}
Example #8
Source File: GroupPanelItem.tsx    From tailchat with GNU General Public License v3.0 6 votes vote down vote up
GroupPanelItem: React.FC<{
  name: string;
  icon: React.ReactNode;
  to: string;
  badge?: boolean;
}> = React.memo((props) => {
  const { icon, name, to, badge } = props;
  const location = useLocation();
  const isActive = location.pathname.startsWith(to);

  return (
    <Link className="block" to={to}>
      <div
        className={clsx(
          'w-full hover:bg-black hover:bg-opacity-20 dark:hover:bg-white dark:hover:bg-opacity-20 cursor-pointer text-gray-900 dark:text-white rounded px-1 h-8 flex items-center text-base group',
          {
            'bg-black bg-opacity-20 dark:bg-white dark:bg-opacity-20': isActive,
          }
        )}
      >
        <div className="flex items-center justify-center px-1 mr-1">{icon}</div>

        <Typography.Text
          className="flex-1 text-gray-900 dark:text-white"
          ellipsis={true}
        >
          {name}
        </Typography.Text>

        {badge === true ? (
          <Badge status="error" />
        ) : (
          <Badge count={Number(badge) || 0} />
        )}
      </div>
    </Link>
  );
})
Example #9
Source File: index.tsx    From fe-v5 with Apache License 2.0 6 votes vote down vote up
SelectList: React.FC<SelectListProps> = ({ dataSource, fieldNames = {}, allowNotSelect = false, defaultSelect, showBadge = true, badgeInfo = {}, onChange }) => {
  const [active, setActive] = useState<string | number>(defaultSelect && typeof defaultSelect === 'object' ? defaultSelect[fieldNames.key || 'value'] : defaultSelect);

  return (
    <div className='radio-list'>
      {dataSource.map((item: any) => {
        return (
          <Row key={item.id}>
            <Col span={showBadge ? 20 : 24}>
              <div
                className={classNames({
                  'n9e-metric-views-list-content-item': true,
                  active: item.id == active,
                })}
                key={item.id}
                onClick={(e) => {
                  if (item.id !== active) {
                    setActive(item.id);
                    onChange && onChange(item.id, item);
                  }
                }}
              >
                <span className='name'>{item.name}</span>
              </div>
            </Col>
            {showBadge && (
              <Col span={4}>
                <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
                  <Badge count={badgeInfo[item.id] || 0} />
                </div>
              </Col>
            )}
          </Row>
        );
      })}
    </div>
  );
}
Example #10
Source File: Calendar.tsx    From jmix-frontend with Apache License 2.0 5 votes vote down vote up
CalendarEvent = ({ event }: CalendarEventProps) => (
  <div title="">
    <Tooltip title={event.description}>
      <Badge status="default" text={event.title} />
    </Tooltip>
  </div>
)
Example #11
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
ArrayTabs: React.FC<ErdaFormArrayTabsProps> = observer((props) => {
  const field = useField<ArrayField>();
  const schema = useFieldSchema();
  const [activeKey, setActiveKey] = useState('tab-0');
  const value = Array.isArray(field.value) ? field.value : [];
  const dataSource = value?.length ? value : [{}];
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const { tabTitle, onChange, ...restProps } = props;

  const onEdit = (targetKey: any, type: 'add' | 'remove') => {
    if (type === 'add') {
      const id = dataSource.length;
      if (field?.value?.length) {
        field.push(null);
      } else {
        field.push(null, null);
      }
      setActiveKey(`tab-${id}`);
    } else if (type === 'remove') {
      const index = Number(targetKey.match(/-(\d+)/)?.[1]);
      if (index - 1 > -1) {
        setActiveKey(`tab-${index - 1}`);
      }
      field.remove(index);
    }
  };

  const badgedTab = (index: number) => {
    const tab = tabTitle ? tabTitle(value?.[index]) ?? '' : `${field.title || 'Untitled'} ${index + 1}`;
    const errors = field.errors.filter((error) => error.address?.includes(`${field.address}.${index}`));
    if (errors.length) {
      return (
        <Badge size="small" className="errors-badge" count={errors.length}>
          {tab}
        </Badge>
      );
    }
    return tab;
  };

  return (
    <Tabs
      type="editable-card"
      activeKey={activeKey}
      onChange={(key) => {
        setActiveKey(key);
      }}
      onEdit={onEdit}
      {...restProps}
    >
      {dataSource?.map((_item, index) => {
        const items = Array.isArray(schema.items) ? schema.items[index] : schema.items;
        const key = `tab-${index}`;
        return (
          <Tabs.TabPane key={key} forceRender closable={index !== 0} tab={badgedTab(index)}>
            <RecursionField schema={items!} name={index} />
          </Tabs.TabPane>
        );
      })}
    </Tabs>
  );
})
Example #12
Source File: AvatarDropdown.tsx    From ant-design-pro-V4 with MIT License 5 votes vote down vote up
render(): React.ReactNode {
    const { todoList } = this.props?.todo
    // const todoNum = todoList.filter((item: any) => item.status === 0).length
    const todoNum = todoList?.filter((item: any) => {
      if (item != null) {
        return item.status === 0
      }
    }).length
    const {
      currentUser = {
        avatar: '',
        name: '',
      },
      menu,
    } = this.props;
    const menuHeaderDropdown = (
      <Menu className={styles.menu} selectedKeys={[]} onClick={this.onMenuClick}>
        {menu && (
          <Menu.Item key="center">
            <UserOutlined />
            个人中心
          </Menu.Item>
        )}
        {menu && (
          <Menu.Item key="settings">
            <SettingOutlined />
            个人设置
          </Menu.Item>
        )}
        {menu && <Menu.Divider />}
        <Menu.Item key="todo">
          <UnorderedListOutlined />
          待办事项
          <Badge count={todoNum} offset={[10, -5]} />
        </Menu.Item>
        {menu && <Menu.Divider />}
        <Menu.Item key="logout">
          <LogoutOutlined />
          退出登录
        </Menu.Item>
      </Menu>
    );
    return currentUser && currentUser.name ? (
      <HeaderDropdown overlay={menuHeaderDropdown}>
        <span className={`${styles.action} ${styles.account}`}>
          <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
          <span className={`${styles.name} anticon`}>{currentUser.name}
            <Badge count={todoNum} dot={true} /></span>
        </span>
      </HeaderDropdown>
    ) : (
      <span className={`${styles.action} ${styles.account}`}>
        <Spin
          size="small"
          style={{
            marginLeft: 8,
            marginRight: 8,
          }}
        />
      </span>
    );
  }
Example #13
Source File: Process.tsx    From jetlinks-ui-antd with MIT License 5 votes vote down vote up
Process: React.FC<Props> = props => {
  const initState: State = {
    source: {},
  };
  const [eventSource, setSource] = useState<any>(initState.source);
  const [count, setCount] = useState<number>(0);
  const [flag, setFlag] = useState<boolean>(true);
  const [errMessage, setErrMessage] = useState<string>('');
  const { action } = props;

  const getData = () => {
    let dt = 0;

    const source = new EventSourcePolyfill(wrapAPI(props.api));
    setSource(source);
    source.onmessage = (e:any) => {
      const res = JSON.parse(e.data);
      switch (action) {
        case 'active':
          if (res.success) {
            dt += res.total;
            setCount(dt);
          }
          break;
        case 'sync':
          dt += res;
          setCount(dt);
          break;
        case 'import':
          if (res.success) {
            const temp = res.result.total;
            dt += temp;
            setCount(dt);
          } else {
            setErrMessage(res.message);
          }
          break;
        default:
          break;
      }
    };
    source.onerror = () => {
      setFlag(false);
      source.close();
    };
    source.onopen = () => { };
  };
  useEffect(() => {
    getData();
  }, []);
  return (
    <Modal
      title="当前进度"
      visible
      confirmLoading={flag}
      okText="确认"
      onOk={() => {
        props.closeVisible();
        setCount(0);
        eventSource.close();
      }}
      cancelText="关闭"
      onCancel={() => {
        props.closeVisible();
        setCount(0);
        eventSource.close();
      }}
    >
      {flag ? (
        <Badge status="processing" text="进行中" />
      ) : (
          <Badge status="success" text="已完成" />
        )}
      <p>总数量:{count}</p>
      <p style={{ color: 'red' }}>{errMessage}</p>
    </Modal>
  );
}
Example #14
Source File: Notifications.tsx    From jitsu with MIT License 5 votes vote down vote up
makeIconWithBadge = (icon: React.ReactNode, badge: React.ReactNode): React.ReactNode => {
  return (
    <Badge count={badge} size="small">
      <div className="h-5 w-5">{icon}</div>
    </Badge>
  )
}
Example #15
Source File: index.tsx    From tailchat with GNU General Public License v3.0 5 votes vote down vote up
Avatar: React.FC<AvatarProps> = React.memo((_props) => {
  const { isOnline, ...props } = _props;
  const src = isValidStr(props.src) ? props.src : undefined;

  const name = useMemo(() => _upperCase(_head(props.name)), [props.name]);

  const color = useMemo(
    () =>
      // 如果src为空 且 icon为空 则给个固定颜色
      _isEmpty(src) && _isNil(props.icon)
        ? getTextColorHex(props.name)
        : undefined,
    [src, props.icon, props.name]
  );

  const style: React.CSSProperties = useMemo(
    () => ({
      cursor: 'inherit',
      userSelect: 'none',
      ...props.style,
      backgroundColor: color,
    }),
    [props.style, color]
  );

  if (_isNumber(props.size) && typeof style.fontSize === 'undefined') {
    // 如果props.size是数字且没有指定文字大小
    // 则自动增加fontSize大小
    style.fontSize = props.size * 0.4;
  }

  const inner = (
    <AntdAvatar {...props} src={src} style={style}>
      {name}
    </AntdAvatar>
  );

  if (typeof isOnline === 'boolean') {
    const style = {
      bottom: 0,
      top: 'auto',
    };

    if (isOnline === true) {
      return (
        <Badge dot={true} color="green" style={style}>
          {inner}
        </Badge>
      );
    } else {
      return (
        <Badge dot={true} color="#999" style={style}>
          {inner}
        </Badge>
      );
    }
  }

  return inner;
})
Example #16
Source File: index.tsx    From dashboard with Apache License 2.0 5 votes vote down vote up
EditableTag: React.FC<EditableTagProps> = (props) => {
  const { tags, setTags } = props;
  const [inputVisible, setInputVisible] = useState<boolean>(false);
  const [inputValue, setInputValue] = useState<string>('');

  return (
    <>
      <Space direction={'horizontal'} wrap={true} className={styles.tagList}>
        <Button
          icon={<PlusOutlined />}
          onClick={() => {
            setInputVisible(true);
          }}
        >
          添加
        </Button>

        {inputVisible && (
          <Input
            value={inputValue}
            onChange={(e) => setInputValue(e.currentTarget.value)}
            autoFocus={true}
            allowClear={true}
            placeholder="逗号分隔,回车保存"
            onBlur={() => {
              setInputValue('');
              setInputVisible(false);
            }}
            onPressEnter={(e) => {
              e.preventDefault();
              const params = inputValue
                .replace(',', ',')
                .split(',')
                .filter((val: any) => val);
              setTags(_.uniq<string>([...tags, ...params]));
              setInputValue('');
            }}
          />
        )}
        {tags?.map((tag) => (
          <Badge
            key={tag}
            className={styles.tagWrapper}
            count={
              <CloseCircleOutlined
                onClick={() => {
                  setTags(tags.filter((item) => tag !== item));
                }}
                style={{ color: 'rgb(199,199,199)' }}
              />
            }
          >
            <Tag className={styles.tagItem}>{tag}</Tag>
          </Badge>
        ))}
      </Space>
    </>
  );
}
Example #17
Source File: Chronograph.tsx    From datart with Apache License 2.0 5 votes vote down vote up
StyledBadge = styled(Badge)`
  .ant-badge-status-text {
    font-size: ${FONT_SIZE_LABEL};
    color: ${p => p.theme.textColorLight};
  }
`
Example #18
Source File: TAQueueListItem.tsx    From office-hours with GNU General Public License v3.0 5 votes vote down vote up
export default function TAQueueListItem({
  index,
  selected,
  question,
  onClick,
  showCheckbox,
}: {
  index: number | false;
  selected: boolean;
  question: Question;
  onClick: () => void;
  showCheckbox?: boolean;
}): ReactElement {
  const isDrafting = question.status === OpenQuestionStatus.Drafting;

  const metaInfo: [ReactElement, string][] = [
    [<HourglassOutlined key="h" />, getWaitTime(question)],
  ];
  if (!isDrafting) {
    metaInfo.push([<QuestionOutlined key="q" />, question.questionType]);
  }
  return (
    <Container
      selected={selected}
      data-cy={`queue-list-item-${question.id}`}
      onClick={onClick}
    >
      {showCheckbox && <StyledCheckbox checked={selected} />}
      <BodyContainer>
        <AvatarContainer>
          <Badge
            // 0 is not displayed, hide if no index
            count={index ? `#${index}` : 0}
            style={{ backgroundColor: "#3684c6" }}
            offset={[-40, 0]}
          >
            <KOHAvatar
              size={40}
              name={question.creator.name}
              photoURL={question.creator.photoURL}
            />
          </Badge>
        </AvatarContainer>
        <QuestionInfoContainer>
          <Name>{question.creator.name}</Name>
          <QuestionText>
            {isDrafting ? (
              <i>Still Drafting...</i>
            ) : (
              truncate(question.text, 80)
            )}
          </QuestionText>
          <QuestionMetaRow info={metaInfo} />
        </QuestionInfoContainer>
      </BodyContainer>
    </Container>
  );
}
Example #19
Source File: basic.tsx    From yakit with GNU Affero General Public License v3.0 5 votes vote down vote up
YakVersion: React.FC<YakVersionProp> = (props) => {
    const [version, setVersion] = useState<string>("dev")
    const [latestVersion, setLatestVersion] = useState("");


    useEffect(() => {
        ipcRenderer.invoke("query-latest-yak-version").then((data: string) => {
            setLatestVersion(data)
        }).catch(() => {
        }).finally(
        )

        ipcRenderer.on("client-yak-version", async (e: any, data) => {
            setVersion(data)
        })

        ipcRenderer.invoke("yak-version")
        return () => {
            ipcRenderer.removeAllListeners("client-yak-version")
        }
    }, [])

    if (!version) {
        return <Spin tip={"正在加载 yak 版本"}/>
    }
    const isDev = version.toLowerCase().includes("dev");

    const newVersion = latestVersion !== "" && latestVersion !== version

    if (!newVersion) {
        return <Tag color={isDev ? "red" : "geekblue"}>
            Yak-{version}
        </Tag>
    }

    return <div>
        <Badge dot={newVersion}>
            <Button size={"small"} type={"primary"}
                    onClick={() => {
                        if (!newVersion) {
                            return
                        }

                        showModal({
                            title: "有新的 Yak 核心引擎可升级!",
                            content: <>
                                如果你现在不是很忙
                                <br/>
                                我们推荐您退出当前引擎,点击欢迎界面的
                                <br/>
                                "安装/升级 Yak 引擎" 来免费升级
                            </>
                        })
                    }}>
                Yak-{version}
            </Button>
        </Badge>
    </div>
}
Example #20
Source File: palette.tsx    From jmix-frontend with Apache License 2.0 4 votes vote down vote up
palette = () => (
  <Palette>
    <Category name="Text">
      <Component name="Formatted Message">
        <Variant>
          <FormattedMessage />
        </Variant>
      </Component>
      <Component name="Heading">
        <Variant name="h1">
          <Typography.Title></Typography.Title>
        </Variant>
        <Variant name="h2">
          <Typography.Title level={2}></Typography.Title>
        </Variant>
        <Variant name="h3">
          <Typography.Title level={3}></Typography.Title>
        </Variant>
        <Variant name="h4">
          <Typography.Title level={4}></Typography.Title>
        </Variant>
        <Variant name="h5">
          <Typography.Title level={5}></Typography.Title>
        </Variant>
      </Component>
      <Component name="Text">
        <Variant>
          <Typography.Text></Typography.Text>
        </Variant>
        <Variant name="Secondary">
          <Typography.Text type="secondary"></Typography.Text>
        </Variant>
        <Variant name="Success">
          <Typography.Text type="success"></Typography.Text>
        </Variant>
        <Variant name="Warning">
          <Typography.Text type="warning"></Typography.Text>
        </Variant>
        <Variant name="Danger">
          <Typography.Text type="danger"></Typography.Text>
        </Variant>
        <Variant name="Disabled">
          <Typography.Text disabled></Typography.Text>
        </Variant>
      </Component>
    </Category>
    <Category name="Layout">
      <Component name="Divider">
        <Variant>
          <Divider />
        </Variant>
      </Component>

      <Component name="Grid">
        <Variant name="Simple Row">
          <Row></Row>
        </Variant>
        <Variant name="Two columns">
          <Row>
            <Col span={12}></Col>
            <Col span={12}></Col>
          </Row>
        </Variant>
        <Variant name="Three columns">
          <Row>
            <Col span={8}></Col>
            <Col span={8}></Col>
            <Col span={8}></Col>
          </Row>
        </Variant>
      </Component>

      <Component name="Space">
        <Variant>
          <Space />
        </Variant>
        <Variant name="Small">
          <Space size={"small"} />
        </Variant>
        <Variant name="Large">
          <Space size={"large"} />
        </Variant>
      </Component>
    </Category>
    <Category name="Controls">
      <Component name="Autocomplete">
        <Variant>
          <AutoComplete placeholder="input here" />
        </Variant>
      </Component>

      <Component name="Button">
        <Variant>
          <Button></Button>
        </Variant>
        <Variant name="Primary">
          <Button type="primary"></Button>
        </Variant>
        <Variant name="Link">
          <Button type="link"></Button>
        </Variant>
        <Variant name="Dropdown">
          <Dropdown
            trigger={["click"]}
            overlay={
              <Menu>
                <Menu.Item></Menu.Item>
                <Menu.Item></Menu.Item>
                <Menu.Item></Menu.Item>
              </Menu>
            }
          >
            <Button></Button>
          </Dropdown>
        </Variant>
      </Component>

      <Component name="Checkbox">
        <Variant>
          <Checkbox />
        </Variant>
      </Component>

      <Component name="Switch">
        <Variant>
          <Switch />
        </Variant>
      </Component>

      <Component name="Radio Group">
        <Variant>
          <Radio.Group>
            <Radio value={1}>A</Radio>
            <Radio value={2}>B</Radio>
            <Radio value={3}>C</Radio>
            <Radio value={4}>D</Radio>
          </Radio.Group>
        </Variant>
        <Variant name="Button">
          <Radio.Group>
            <Radio.Button value={1}>A</Radio.Button>
            <Radio.Button value={2}>B</Radio.Button>
            <Radio.Button value={3}>C</Radio.Button>
            <Radio.Button value={4}>D</Radio.Button>
          </Radio.Group>
        </Variant>
      </Component>

      <Component name="DatePicker">
        <Variant>
          <DatePicker />
        </Variant>
        <Variant name="Range">
          <DatePicker.RangePicker />
        </Variant>
      </Component>

      <Component name="TimePicker">
        <Variant>
          <TimePicker />
        </Variant>
        <Variant name="Range">
          <TimePicker.RangePicker />
        </Variant>
      </Component>

      <Component name="Input">
        <Variant>
          <Input />
        </Variant>
        <Variant name="Number">
          <InputNumber />
        </Variant>
      </Component>

      <Component name="Select">
        <Variant>
          <Select defaultValue="1">
            <Select.Option value="1">1</Select.Option>
            <Select.Option value="2">2</Select.Option>
          </Select>
        </Variant>
        <Variant name="Multiple">
          <Select defaultValue={["1"]} mode="multiple" allowClear>
            <Select.Option value="1">1</Select.Option>
            <Select.Option value="2">2</Select.Option>
          </Select>
        </Variant>
      </Component>

      <Component name="Link">
        <Variant>
          <Typography.Link href="" target="_blank"></Typography.Link>
        </Variant>
      </Component>

      <Component name="Slider">
        <Variant>
          <Slider defaultValue={30} />
        </Variant>
        <Variant name="Range">
          <Slider range defaultValue={[20, 50]} />
        </Variant>
      </Component>
    </Category>
    <Category name="Data Display">
      <Component name="Field">
        <Variant>
          <Field
            entityName={ENTITY_NAME}
            disabled={readOnlyMode}
            propertyName=""
            formItemProps={{
              style: { marginBottom: "12px" }
            }}
          />
        </Variant>
      </Component>
      <Component name="Card">
        <Variant>
          <Card />
        </Variant>
        <Variant name="With Title">
          <Card>
            <Card title="Card title">
              <p>Card content</p>
            </Card>
          </Card>
        </Variant>
        <Variant name="My custom card">
          <Card>
            <Card title="Card title">
              <p>Card content</p>
              <Avatar />
            </Card>
          </Card>
        </Variant>
      </Component>
      <Component name="Tabs">
        <Variant>
          <Tabs defaultActiveKey="1">
            <Tabs.TabPane tab="Tab 1" key="1">
              Content of Tab Pane 1
            </Tabs.TabPane>
            <Tabs.TabPane tab="Tab 2" key="2">
              Content of Tab Pane 2
            </Tabs.TabPane>
            <Tabs.TabPane tab="Tab 3" key="3">
              Content of Tab Pane 3
            </Tabs.TabPane>
          </Tabs>
        </Variant>
        <Variant name="Tab Pane">
          <Tabs.TabPane></Tabs.TabPane>
        </Variant>
      </Component>
      <Component name="Collapse">
        <Variant>
          <Collapse defaultActiveKey="1">
            <Collapse.Panel
              header="This is panel header 1"
              key="1"
            ></Collapse.Panel>
            <Collapse.Panel
              header="This is panel header 2"
              key="2"
            ></Collapse.Panel>
            <Collapse.Panel
              header="This is panel header 3"
              key="3"
            ></Collapse.Panel>
          </Collapse>
        </Variant>
      </Component>
      <Component name="Image">
        <Variant>
          <Image width={200} src="" />
        </Variant>
      </Component>
      <Component name="Avatar">
        <Variant>
          <Avatar icon={<UserOutlined />} />
        </Variant>
        <Variant name="Image">
          <Avatar src="https://joeschmoe.io/api/v1/random" />
        </Variant>
      </Component>
      <Component name="Badge">
        <Variant>
          <Badge count={1}></Badge>
        </Variant>
      </Component>
      <Component name="Statistic">
        <Variant>
          <Statistic title="Title" value={112893} />
        </Variant>
      </Component>
      <Component name="Alert">
        <Variant name="Success">
          <Alert message="Text" type="success" />
        </Variant>
        <Variant name="Info">
          <Alert message="Text" type="info" />
        </Variant>
        <Variant name="Warning">
          <Alert message="Text" type="warning" />
        </Variant>
        <Variant name="Error">
          <Alert message="Text" type="error" />
        </Variant>
      </Component>
      <Component name="List">
        <Variant>
          <List
            bordered
            dataSource={[]}
            renderItem={item => <List.Item></List.Item>}
          />
        </Variant>
      </Component>
    </Category>
    <Category name="Icons">
      <Component name="Arrow">
        <Variant name="Up">
          <ArrowUpOutlined />
        </Variant>
        <Variant name="Down">
          <ArrowDownOutlined />
        </Variant>
        <Variant name="Left">
          <ArrowLeftOutlined />
        </Variant>
        <Variant name="Right">
          <ArrowRightOutlined />
        </Variant>
      </Component>
      <Component name="Question">
        <Variant>
          <QuestionOutlined />
        </Variant>
        <Variant name="Circle">
          <QuestionCircleOutlined />
        </Variant>
      </Component>
      <Component name="Plus">
        <Variant>
          <PlusOutlined />
        </Variant>
        <Variant name="Circle">
          <PlusCircleOutlined />
        </Variant>
      </Component>
      <Component name="Info">
        <Variant>
          <InfoOutlined />
        </Variant>
        <Variant name="Circle">
          <InfoCircleOutlined />
        </Variant>
      </Component>
      <Component name="Exclamation">
        <Variant>
          <ExclamationOutlined />
        </Variant>
        <Variant name="Circle">
          <ExclamationCircleOutlined />
        </Variant>
      </Component>
      <Component name="Close">
        <Variant>
          <CloseOutlined />
        </Variant>
        <Variant name="Circle">
          <CloseCircleOutlined />
        </Variant>
      </Component>
      <Component name="Check">
        <Variant>
          <CheckOutlined />
        </Variant>
        <Variant name="Circle">
          <CheckCircleOutlined />
        </Variant>
      </Component>
      <Component name="Edit">
        <Variant>
          <EditOutlined />
        </Variant>
      </Component>
      <Component name="Copy">
        <Variant>
          <CopyOutlined />
        </Variant>
      </Component>
      <Component name="Delete">
        <Variant>
          <DeleteOutlined />
        </Variant>
      </Component>
      <Component name="Bars">
        <Variant>
          <BarsOutlined />
        </Variant>
      </Component>
      <Component name="Bell">
        <Variant>
          <BellOutlined />
        </Variant>
      </Component>
      <Component name="Clear">
        <Variant>
          <ClearOutlined />
        </Variant>
      </Component>
      <Component name="Download">
        <Variant>
          <DownloadOutlined />
        </Variant>
      </Component>
      <Component name="Upload">
        <Variant>
          <UploadOutlined />
        </Variant>
      </Component>
      <Component name="Sync">
        <Variant>
          <SyncOutlined />
        </Variant>
      </Component>
      <Component name="Save">
        <Variant>
          <SaveOutlined />
        </Variant>
      </Component>
      <Component name="Search">
        <Variant>
          <SearchOutlined />
        </Variant>
      </Component>
      <Component name="Settings">
        <Variant>
          <SettingOutlined />
        </Variant>
      </Component>
      <Component name="Paperclip">
        <Variant>
          <PaperClipOutlined />
        </Variant>
      </Component>
      <Component name="Phone">
        <Variant>
          <PhoneOutlined />
        </Variant>
      </Component>
      <Component name="Mail">
        <Variant>
          <MailOutlined />
        </Variant>
      </Component>
      <Component name="Home">
        <Variant>
          <HomeOutlined />
        </Variant>
      </Component>
      <Component name="Contacts">
        <Variant>
          <ContactsOutlined />
        </Variant>
      </Component>
      <Component name="User">
        <Variant>
          <UserOutlined />
        </Variant>
        <Variant name="Add">
          <UserAddOutlined />
        </Variant>
        <Variant name="Remove">
          <UserDeleteOutlined />
        </Variant>
      </Component>
      <Component name="Team">
        <Variant>
          <TeamOutlined />
        </Variant>
      </Component>
    </Category>
    <Category name="Screens">
      <Component name="ExampleCustomScreen">
        <Variant>
          <ExampleCustomScreen />
        </Variant>
      </Component>
      <Component name="CustomEntityFilterTest">
        <Variant>
          <CustomEntityFilterTest />
        </Variant>
      </Component>
      <Component name="CustomFormControls">
        <Variant>
          <CustomFormControls />
        </Variant>
      </Component>
      <Component name="CustomDataDisplayComponents">
        <Variant>
          <CustomDataDisplayComponents />
        </Variant>
      </Component>
      <Component name="CustomAppLayouts">
        <Variant>
          <CustomAppLayouts />
        </Variant>
      </Component>
      <Component name="CustomControls">
        <Variant>
          <CustomControls />
        </Variant>
      </Component>
      <Component name="ErrorBoundaryTests">
        <Variant>
          <ErrorBoundaryTests />
        </Variant>
      </Component>
      <Component name="TestBlankScreen">
        <Variant>
          <TestBlankScreen />
        </Variant>
      </Component>
      <Component name="CarEditor">
        <Variant>
          <CarEditor />
        </Variant>
      </Component>
      <Component name="CarBrowserCards">
        <Variant>
          <CarBrowserCards />
        </Variant>
      </Component>
      <Component name="CarBrowserList">
        <Variant>
          <CarBrowserList />
        </Variant>
      </Component>
      <Component name="CarBrowserTable">
        <Variant>
          <CarBrowserTable />
        </Variant>
      </Component>
      <Component name="CarCardsGrid">
        <Variant>
          <CarCardsGrid />
        </Variant>
      </Component>
      <Component name="FavoriteCars">
        <Variant>
          <FavoriteCars />
        </Variant>
      </Component>
      <Component name="CarCardsWithDetails">
        <Variant>
          <CarCardsWithDetails />
        </Variant>
      </Component>
      <Component name="CarTableWithFilters">
        <Variant>
          <CarTableWithFilters />
        </Variant>
      </Component>
      <Component name="CarMasterDetail">
        <Variant>
          <CarMasterDetail />
        </Variant>
      </Component>
      <Component name="FormWizardCompositionO2O">
        <Variant>
          <FormWizardCompositionO2O />
        </Variant>
      </Component>
      <Component name="FormWizardEditor">
        <Variant>
          <FormWizardEditor />
        </Variant>
      </Component>
      <Component name="FormWizardBrowserTable">
        <Variant>
          <FormWizardBrowserTable />
        </Variant>
      </Component>
      <Component name="CarMultiSelectionTable">
        <Variant>
          <CarMultiSelectionTable />
        </Variant>
      </Component>
      <Component name="DatatypesTestEditor">
        <Variant>
          <DatatypesTestEditor />
        </Variant>
      </Component>
      <Component name="DatatypesTestBrowserCards">
        <Variant>
          <DatatypesTestBrowserCards />
        </Variant>
      </Component>
      <Component name="DatatypesTestBrowserList">
        <Variant>
          <DatatypesTestBrowserList />
        </Variant>
      </Component>
      <Component name="DatatypesTestBrowserTable">
        <Variant>
          <DatatypesTestBrowserTable />
        </Variant>
      </Component>
      <Component name="DatatypesTestCards">
        <Variant>
          <DatatypesTestCards />
        </Variant>
      </Component>
      <Component name="AssociationO2OEditor">
        <Variant>
          <AssociationO2OEditor />
        </Variant>
      </Component>
      <Component name="AssociationO2OBrowserTable">
        <Variant>
          <AssociationO2OBrowserTable />
        </Variant>
      </Component>
      <Component name="AssociationO2MEditor">
        <Variant>
          <AssociationO2MEditor />
        </Variant>
      </Component>
      <Component name="AssociationO2MBrowserTable">
        <Variant>
          <AssociationO2MBrowserTable />
        </Variant>
      </Component>
      <Component name="AssociationM2OEditor">
        <Variant>
          <AssociationM2OEditor />
        </Variant>
      </Component>
      <Component name="AssociationM2OBrowserTable">
        <Variant>
          <AssociationM2OBrowserTable />
        </Variant>
      </Component>
      <Component name="AssociationM2MEditor">
        <Variant>
          <AssociationM2MEditor />
        </Variant>
      </Component>
      <Component name="AssociationM2MBrowserTable">
        <Variant>
          <AssociationM2MBrowserTable />
        </Variant>
      </Component>
      <Component name="CompositionO2OEditor">
        <Variant>
          <CompositionO2OEditor />
        </Variant>
      </Component>
      <Component name="CompositionO2OBrowserTable">
        <Variant>
          <CompositionO2OBrowserTable />
        </Variant>
      </Component>
      <Component name="CompositionO2MEditor">
        <Variant>
          <CompositionO2MEditor />
        </Variant>
      </Component>
      <Component name="CompositionO2MBrowserTable">
        <Variant>
          <CompositionO2MBrowserTable />
        </Variant>
      </Component>
      <Component name="DeeplyNestedTestEntityEditor">
        <Variant>
          <DeeplyNestedTestEntityEditor />
        </Variant>
      </Component>
      <Component name="DeeplyNestedO2MTestEntityTable">
        <Variant>
          <DeeplyNestedO2MTestEntityTable />
        </Variant>
      </Component>
      <Component name="DeeplyNestedO2MTestEntityEditor">
        <Variant>
          <DeeplyNestedO2MTestEntityEditor />
        </Variant>
      </Component>
      <Component name="IntIdEditor">
        <Variant>
          <IntIdEditor />
        </Variant>
      </Component>
      <Component name="IntIdBrowserTable">
        <Variant>
          <IntIdBrowserTable />
        </Variant>
      </Component>
      <Component name="IntIdBrowserCards">
        <Variant>
          <IntIdBrowserCards />
        </Variant>
      </Component>
      <Component name="IntIdBrowserList">
        <Variant>
          <IntIdBrowserList />
        </Variant>
      </Component>
      <Component name="IntIdentityIdCards">
        <Variant>
          <IntIdentityIdCards />
        </Variant>
      </Component>
      <Component name="IntIdentityIdEditor">
        <Variant>
          <IntIdentityIdEditor />
        </Variant>
      </Component>
      <Component name="IntIdentityIdBrowserTable">
        <Variant>
          <IntIdentityIdBrowserTable />
        </Variant>
      </Component>
      <Component name="IntIdentityIdBrowserCards">
        <Variant>
          <IntIdentityIdBrowserCards />
        </Variant>
      </Component>
      <Component name="IntIdentityIdBrowserList">
        <Variant>
          <IntIdentityIdBrowserList />
        </Variant>
      </Component>
      <Component name="StringIdCards">
        <Variant>
          <StringIdCards />
        </Variant>
      </Component>
      <Component name="StringIdMgtCardsEdit">
        <Variant>
          <StringIdMgtCardsEdit />
        </Variant>
      </Component>
      <Component name="StringIdBrowserCards">
        <Variant>
          <StringIdBrowserCards />
        </Variant>
      </Component>
      <Component name="StringIdBrowserList">
        <Variant>
          <StringIdBrowserList />
        </Variant>
      </Component>
      <Component name="StringIdBrowserTable">
        <Variant>
          <StringIdBrowserTable />
        </Variant>
      </Component>
      <Component name="WeirdStringIdEditor">
        <Variant>
          <WeirdStringIdEditor />
        </Variant>
      </Component>
      <Component name="WeirdStringIdBrowserCards">
        <Variant>
          <WeirdStringIdBrowserCards />
        </Variant>
      </Component>
      <Component name="WeirdStringIdBrowserList">
        <Variant>
          <WeirdStringIdBrowserList />
        </Variant>
      </Component>
      <Component name="WeirdStringIdBrowserTable">
        <Variant>
          <WeirdStringIdBrowserTable />
        </Variant>
      </Component>
      <Component name="BoringStringIdEditor">
        <Variant>
          <BoringStringIdEditor />
        </Variant>
      </Component>
      <Component name="BoringStringIdBrowserTable">
        <Variant>
          <BoringStringIdBrowserTable />
        </Variant>
      </Component>
      <Component name="TrickyIdEditor">
        <Variant>
          <TrickyIdEditor />
        </Variant>
      </Component>
      <Component name="TrickyIdBrowserTable">
        <Variant>
          <TrickyIdBrowserTable />
        </Variant>
      </Component>
    </Category>
  </Palette>
)
Example #21
Source File: index.tsx    From antdp with MIT License 4 votes vote down vote up
ButtonGroupPro = (props: ButtonGroupProProps) => {
  const { button, className } = props;
  const [menuDropdownLabel, setmenuDropdownLabel] = useState<{
    label: string | React.ReactNode;
    key?: number | undefined;
  }>({ label: '', key: undefined });
  const [ButtonandDropdown, setButtonandDropdown] = useState(false);

  useEffect(() => {
    button &&
      button.length > 0 &&
      button.map((item) => {
        if (item.ButtonandDropdown) {
          setButtonandDropdown(true);
        }
      });
  }, []);

  const handleMenuClick = (
    menus: any,
    idx: number | undefined,
    e: MenuInfo,
  ) => {
    menus.forEach((menu: any, index: number | undefined) => {
      if (String(index) === e?.key && menu.onClick) {
        setmenuDropdownLabel({ label: menu.label, key: idx });
        menu.onClick();
      }
    });
  };

  const renderMenu = (
    menus: Array<MenusProps> | undefined,
    idx: number | undefined,
  ) => {
    return (
      <Menu onClick={(e: any) => handleMenuClick(menus, idx, e)}>
        {menus &&
          menus.length > 0 &&
          menus.map((items: MenusProps, keys: number) => {
            // 权限
            if (items.path) {
              const accessStr = sessionStorage.getItem('authBtn');
              const access = accessStr ? JSON.parse(accessStr) : [];
              if (!access) return null;
              return access.includes(`${items.path}`) ? (
                <Menu.Item key={keys} disabled={items.disabled}>
                  {items.label}
                </Menu.Item>
              ) : null;
            } else {
              return (
                <Menu.Item key={keys} disabled={items.disabled}>
                  {items.label}
                </Menu.Item>
              );
            }
          })}
      </Menu>
    );
  };

  return (
    <div className={classNames('antdp-ButtonGroup', className)}>
      {button &&
        button.length > 0 &&
        button.map((item: MenusOptionProps, idx) => {
          const props = {
            key: idx,
            size: 'middle',
            type: item.type || 'default',
            onClick: item.onClick,
            disabled: item.disabled,
            style: {
              margin: ButtonandDropdown ? '0 0 0 -3px' : '12px 0 12px 12px',
            },
            ...item,
          } as ButtonProps;
          const buttondom = <Button {...props}>{item.label}</Button>;
          const badgeaParams =
            item.badge && item.badge === 'dot'
              ? { dot: true }
              : { count: item.badge };
          // Menu多选菜单
          if (item.menu && item.menu.length > 0) {
            const DropdownButtonDom = (
              <Button
                size="middle"
                type={props.type || 'default'}
                style={{
                  margin: ButtonandDropdown ? '0 0 0 -3px' : '12px 0 12px 12px',
                }}
              >
                {menuDropdownLabel.key === idx
                  ? menuDropdownLabel.label
                  : item.label}{' '}
                <DownOutlined />
              </Button>
            );
            return item.path ? (
              <div key={idx}>
                <Dropdown overlay={() => renderMenu(item.menu, idx)}>
                  {DropdownButtonDom}
                </Dropdown>
              </div>
            ) : (
              <Dropdown overlay={() => renderMenu(item.menu, idx)} key={idx}>
                {DropdownButtonDom}
              </Dropdown>
            );
          }
          // 自定义render
          if (item.render) {
            return item.path ? (
              // <AuthorizedBtn key={idx} path={item.path}>
                item.render(item.label)
              // </AuthorizedBtn>
            ) : (
              <span key={idx}>{item.render(item.label)}</span>
            );
          }
          // 单独Button
          if (item.path) {
            return item.badge ? (
              // <AuthorizedBtn key={idx} path={item.path}>
                <Badge {...badgeaParams} style={{ marginTop: '15px' }}>
                  {buttondom}
                </Badge>
              // </AuthorizedBtn>
            ) : (
              // <AuthorizedBtn key={idx} path={item.path}>
                buttondom
              // </AuthorizedBtn>
            );
          } else {
            return item.badge ? (
              <span key={idx}>
                <Badge {...badgeaParams} style={{ marginTop: '15px' }}>
                  {buttondom}
                </Badge>
              </span>
            ) : (
              <Button {...props}>{item.label}</Button>
            );
          }
        })}
    </div>
  );
}
Example #22
Source File: DendronCalendarPanel.tsx    From dendron with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function DendronCalendarPanel({ ide, engine }: DendronProps) {
  // --- init
  const ctx = "CalendarView";
  const logger = createLogger("calendarView");

  logger.info({
    ctx,
    state: "enter",
  });
  const { getPrefixCls } = React.useContext(ConfigProvider.ConfigContext);

  const [activeMode, setActiveMode] = useState<CalendarProps["mode"]>("month");
  const { notes, config } = engine;
  const { noteActive } = ide;
  const currentVault = noteActive?.vault;

  logger.info({
    activeNoteFname: noteActive ? noteActive.fname : "no active note found",
  });
  const maxDots: number = 5;
  const wordsPerDot: number = 250;

  const defaultConfig = ConfigUtils.genDefaultConfig();
  const journalConfig = ConfigUtils.getJournal(config || defaultConfig);
  const journalDailyDomain = journalConfig.dailyDomain;
  const journalName = journalConfig.name;

  // Load up the full engine state as all notes are needed for the Tree View
  const [workspace] = useWorkspaceProps();
  useEngine({ engineState: engine, opts: workspace });

  // luxon token format lookup https://github.com/moment/luxon/blob/master/docs/formatting.md#table-of-tokens
  let journalDateFormat = journalConfig.dateFormat;
  const journalMonthDateFormat = "y.MM"; // TODO compute format for currentMode="year" from config

  // Currently luxon does not support setting first day of the week (https://github.com/moment/luxon/issues/373)
  // const dayOfWeek = config?.journal.firstDayOfWeek;
  // const locale = "en-us";

  if (journalDateFormat) {
    // correct possible user mistake that very likely is meant to be day of the month, padded to 2 (dd) and not localized date with abbreviated month (DD)
    journalDateFormat = journalDateFormat.replace(/DD/, "dd");
  }

  const groupedDailyNotes = useMemo(() => {
    const vaultNotes = _.values(notes).filter((notes) => {
      if (currentVault) {
        return VaultUtils.isEqualV2(notes.vault, currentVault);
      }
      return true;
    });

    const dailyNotes = vaultNotes.filter((note) =>
      note.fname.startsWith(`${journalDailyDomain}.${journalName}`)
    );
    const result = _.groupBy(dailyNotes, (note) => {
      return journalName ? getMaybeDatePortion(note, journalName) : undefined;
    });
    return result;
  }, [notes, journalName, journalDailyDomain, currentVault?.fsPath]);

  const activeDate = useMemo(() => {
    if (noteActive && journalName && journalDateFormat) {
      const maybeDatePortion = getMaybeDatePortion(noteActive, journalName);

      if (maybeDatePortion && _.first(groupedDailyNotes[maybeDatePortion])) {
        const dailyDate = Time.DateTime.fromFormat(
          maybeDatePortion,
          journalDateFormat
        );

        const monthlyDate = Time.DateTime.fromFormat(
          maybeDatePortion,
          journalMonthDateFormat
        );

        return dailyDate.isValid
          ? dailyDate
          : monthlyDate.isValid
          ? monthlyDate
          : undefined;
      }

      return undefined;
    }
  }, [noteActive, groupedDailyNotes, journalName, journalDateFormat]);

  const getDateKey = useCallback<
    (date: DateTime, mode?: CalendarProps["mode"]) => string | undefined
  >(
    (date, mode) => {
      const format =
        (mode || activeMode) === "month"
          ? journalDateFormat
          : journalMonthDateFormat;
      return format ? date.toFormat(format) : undefined;
    },
    [activeMode, journalDateFormat]
  );

  const onSelect = useCallback<
    (date: DateTime, mode?: CalendarProps["mode"]) => void
  >(
    (date, mode) => {
      logger.info({ ctx: "onSelect", date });
      const dateKey = getDateKey(date, mode);
      const selectedNote = dateKey
        ? _.first(groupedDailyNotes[dateKey])
        : undefined;

      postVSCodeMessage({
        type: CalendarViewMessageType.onSelect,
        data: {
          id: selectedNote?.id,
          fname: `${journalDailyDomain}.${journalName}.${dateKey}`,
        },
        source: DMessageSource.webClient,
      });
    },
    [groupedDailyNotes, getDateKey, journalDailyDomain, journalName]
  );

  const onPanelChange = useCallback<
    Exclude<CalendarProps["onPanelChange"], undefined>
  >((date, mode) => {
    logger.info({ ctx: "onPanelChange", date, mode });
    setActiveMode(mode);
  }, []);

  const onClickToday = useCallback(() => {
    const mode = "month";
    setActiveMode(mode);
    onSelect(Time.now(), mode);
  }, [onSelect]);

  const dateFullCellRender = useCallback<
    Exclude<CalendarProps["dateFullCellRender"], undefined>
  >(
    (date) => {
      const dateKey = getDateKey(date);
      const dailyNote = dateKey
        ? _.first(groupedDailyNotes[dateKey])
        : undefined;
      const dailyNotes = dailyNote ? [dailyNote] : []; // keeping for case of showing all dailyNotes of day in multi-vault

      const dateCell =
        // multiple daily notes can exist for that day in a mulit-vault setup
        // will only show up when `noteActive` is `undefined`. this happens when opening vscode with no document open
        dailyNotes.map((note, index) => {
          const amount = _.clamp(
            wordsPerDot
              ? Math.floor(note.body.split(/\n| /).length / wordsPerDot) // TODO create test
              : 0,
            0,
            maxDots
          );

          return (
            <div
              key={note.id}
              style={{
                position: "relative",
                top: index * 2 - 6, // space between the day and dots boxes
                // left: index * 1,
              }}
            >
              {_.times(amount, (index) => (
                <div
                  key={index}
                  style={{
                    position: "absolute",
                    left: index * 7, // 7 resutls in a nice visible space between the dots
                  }}
                >
                  <Badge
                    className={`${note.fname}`}
                    dot
                    color={
                      "#00adb5" /* color copied from packages/dendron-next-server/assets/themes/dark-theme.less TODO make dependent on active theme */
                    }
                  />
                </div>
              ))}
            </div>
          );
        });

      const prefixCls = getPrefixCls("picker");
      const calendarPrefixCls = `${prefixCls}-calendar`;

      return (
        <div
          className={classNames(
            `${prefixCls}-cell-inner`,
            `${calendarPrefixCls}-date`,
            {
              [`${calendarPrefixCls}-date-today`]: isSameDate(today, date),
            }
          )}
        >
          <div
            className={`${calendarPrefixCls}-date-value`}
            style={{ color: !dailyNote ? "gray" : undefined }}
          >
            {_.padStart(String(luxonGenerateConfig.getDate(date)), 2, "0")}
          </div>
          <div className={`${calendarPrefixCls}-date-content`}>{dateCell}</div>
        </div>
      );
    },
    [getDateKey, groupedDailyNotes]
  );

  return (
    <>
      <div className="calendar">
        <Calendar
          mode={activeMode}
          onSelect={onSelect}
          onPanelChange={onPanelChange}
          /*
          // @ts-ignore -- `null` initializes ant Calendar into a controlled component whereby it does not render an selected/visible date (today) when `activeDate` is `undefined`*/
          value={activeDate || null}
          dateFullCellRender={dateFullCellRender}
          fullscreen={false}
        />
      </div>
      <Divider plain style={{ marginTop: 0 }}>
        <Button type="primary" onClick={onClickToday}>
          Today
        </Button>
      </Divider>
    </>
  );
}
Example #23
Source File: SchemaItem.tsx    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
export function SchemaItem({
  style,
  readonly,
  className,
  itemData,
  traceId,
  hideDeleteBtn,
  hiddenRootNode,
  disabledModelType,
  isModelDefinitionRow,
  parentsModel = [],
}: SchemaItemProps): React.ReactElement {
  const { t } = useTranslation(NS_FLOW_BUILDER);
  const editorContext = useContext(EditorContext);
  const [hover, setHover] = useState(false);
  const [expand, setExpand] = useState(false);
  const {
    modelDefinitionList = [],
    onModal,
    onRemove,
    showModelDefinition,
    hideModelDefinition,
  } = editorContext;

  useEffect(() => {
    setExpand(!isEmpty(itemData.fields));
  }, [itemData.fields]);

  const openEditModal = (): void => {
    onModal?.({ ...itemData }, true, traceId);
  };

  const openCreateModal = (): void => {
    onModal?.({} as SchemaItemProperty, false, traceId);
  };

  const displayName = useMemo(
    () => itemData.name || itemData.ref,
    [itemData.name, itemData.ref]
  );

  const offsetPadding = useMemo(() => {
    return 20 * (traceId.split("-").length - 1);
  }, [traceId]);

  const modelDefinition = useMemo(() => {
    return modelDefinitionList.find(
      (item) => item.name === calcModelDefinition(itemData)
    );
  }, [modelDefinitionList, itemData]);

  const isSelfRef = useMemo(
    () =>
      isModelDefinition(itemData) &&
      parentsModel.includes(calcModelDefinition(itemData)),
    [itemData, parentsModel]
  );

  const handleExpand = (): void => {
    setExpand(true);
    if (itemData.ref) {
      showModelDefinition(
        getModelRefData(itemData.ref, modelDefinition, modelDefinitionList),
        traceId
      );
    } else {
      showModelDefinition(modelDefinition, traceId);
    }
  };

  const handleFold = (): void => {
    setExpand(false);
    hideModelDefinition(traceId);
  };

  const handleClick = (): void => {
    expand ? handleFold() : handleExpand();
  };

  return (
    <div
      className={classNames({ [styles.highlight]: modelDefinition && expand })}
    >
      <div
        style={style}
        className={className}
        hidden={traceId === rootTraceId && hiddenRootNode}
      >
        <div
          title={displayName}
          className={classNames(styles.textEllipsis, {
            [styles.modelDefinitionText]: isModelDefinitionRow,
          })}
          style={{
            paddingLeft: offsetPadding,
            ...(hover ? { color: "var(--color-brand)" } : {}),
          }}
        >
          {modelDefinition && !isSelfRef ? (
            <span onClick={handleClick} style={{ cursor: "pointer" }}>
              {expand ? (
                <DownOutlined className={styles.caret} />
              ) : (
                <RightOutlined className={styles.caret} />
              )}
              {displayName}
            </span>
          ) : (
            displayName
          )}
        </div>
        <div>
          <Checkbox checked={itemData.required} disabled />
        </div>
        <div className={styles.type}>
          <Tooltip
            title={
              itemData.type ? t(K.SCHEMA_ITEM_NORMAL) : t(K.SCHEMA_ITEM_REF)
            }
          >
            <Tag
              className={classNames({
                [styles.typeTag]: itemData.type,
                [styles.refTag]: itemData.ref,
                [styles.modelDefinitionTag]: isModelDefinitionRow,
              })}
            >
              {itemData.type || itemData.ref}
            </Tag>
          </Tooltip>
          {!readonly && modelDefinition?.updated && (
            <Tooltip title={t(K.MODEL_DEFINITION_UPDATE_MESSAGE)}>
              <Badge color="orange" />
            </Tooltip>
          )}
        </div>
        <div
          className={classNames(styles.textEllipsis, {
            [styles.modelDefinitionText]: isModelDefinitionRow,
          })}
          title={itemData.description}
        >
          {itemData.description}
        </div>
        {!readonly && (
          <div hidden={isModelDefinitionRow}>
            <Button
              type="link"
              className={editorStyles.iconBtn}
              style={{ marginRight: 8 }}
              onClick={openEditModal}
            >
              <SettingOutlined />
            </Button>
            {!hideDeleteBtn && (
              <Button
                type="link"
                className={editorStyles.deleteBtn}
                onClick={() => onRemove?.(traceId)}
              >
                <DeleteOutlined />
              </Button>
            )}
          </div>
        )}
      </div>
      {itemData.fields?.map((item, index) => (
        <SchemaItem
          parentsModel={
            isModelDefinition(itemData)
              ? [...parentsModel, calcModelDefinition(itemData)]
              : [...parentsModel]
          }
          className={editorStyles.schemaItem}
          isModelDefinitionRow={isModelDefinitionRow || !!modelDefinition}
          readonly={readonly}
          style={{
            gridTemplateColumns: getGridTemplateColumns(
              filterTitleList(titleList, readonly)
            ),
          }}
          key={index}
          traceId={`${traceId}-${index}`}
          itemData={item}
          disabledModelType={disabledModelType}
        />
      ))}
      {!readonly && allowExpandFields(itemData.type) && (
        <div
          style={{ paddingLeft: 20 + offsetPadding }}
          hidden={isModelDefinitionRow}
        >
          <Button
            className={editorStyles.iconBtn}
            type="link"
            title={t(K.ADD_FIELD_PARAMS_TIPS, { name: displayName })}
            onMouseEnter={() => setHover(true)}
            onMouseLeave={() => setHover(false)}
            onClick={openCreateModal}
          >
            <PlusCircleOutlined />
            {t(K.FIELD_PARAMS)}
          </Button>
        </div>
      )}
    </div>
  );
}
Example #24
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 4 votes vote down vote up
ConfigurableFilter = React.forwardRef(
  (
    {
      fieldsList: propsFieldList,
      configList = emptyArr,
      defaultConfig,
      value,
      onFilter: onFilterProps,
      onDeleteFilter,
      onSaveFilter,
      processField,
      hideSave,
      onClear,
      onClose,
      zIndex,
    }: IProps,
    ref: React.Ref<{ form: FormInstance }>,
  ) => {
    const fieldsList = React.useMemo(() => compact(propsFieldList), [propsFieldList]);

    const { externalValue: _externalValue, formValue } = React.useMemo(
      () => convertValue(value, fieldsList),
      // eslint-disable-next-line react-hooks/exhaustive-deps
      [value],
    );

    const [form] = Form.useForm();
    const [addForm] = Form.useForm();
    const [externalValue, setExternalValue] = React.useState<Obj<string>>(_externalValue);
    const [visible, setVisible] = React.useState(false);
    const [currentConfig, setCurrentConfig] = React.useState<string | number>();
    const [isNew, setIsNew] = React.useState(false);
    const [addVisible, setAddVisible] = React.useState(false);

    React.useImperativeHandle(ref, () => ({
      form,
    }));

    React.useEffect(() => {
      // remove code in else due to formValue always exist
      const config = getItemByValues(formValue, configList, fieldsList);
      config?.id && setCurrentConfig(config?.id);
      setIsNew(!config);
    }, [configList, formValue, fieldsList]);

    React.useEffect(() => {
      if (formValue) {
        form.setFieldsValue(formValue || {});
      }
    }, [formValue, form]);

    useUpdateEffect(() => {
      if (!isEqual(_externalValue, externalValue)) {
        onFilter();
      }
    }, [externalValue]);

    useUpdateEffect(() => {
      if (!isEqual(_externalValue, externalValue)) {
        setExternalValue(_externalValue);
      }
    }, [_externalValue]);

    const onConfigChange = (config: ConfigData) => {
      setCurrentConfig(config.id);
      setIsNew(false);
      form.resetFields();
      form.setFieldsValue(config.values || {});
      onFilter();
    };

    const onValuesChange = (_, allValues: Obj) => {
      const config = getItemByValues(allValues, configList, fieldsList);
      if (config?.id) {
        setCurrentConfig(config?.id);
        setIsNew(false);
      } else {
        setIsNew(true);
      }
    };

    const saveFilter = (label: string) => {
      onSaveFilter?.(label, form.getFieldsValue());
    };

    const formClear = () => {
      const emptyObj = {};
      fieldsList.forEach((item) => {
        emptyObj[item.key] = undefined;
      });

      form.setFieldsValue(emptyObj);
    };

    const setAllOpen = () => {
      formClear();
      const config = getItemByValues(form.getFieldsValue(), configList, fieldsList);
      setCurrentConfig(config?.id);
      setIsNew(false);
      onClear?.();
    };

    const onFilter = () => {
      form.validateFields().then((values) => {
        onFilterProps({ ...values, ...externalValue });
        setVisible(false);
      });
    };

    useUpdateEffect(() => {
      if (visible && formValue) {
        form.resetFields();
        form.setFieldsValue(formValue || {});
        const config = getItemByValues(formValue, configList, fieldsList);
        config?.id && setCurrentConfig(config?.id);
        setIsNew(!config);
      }
    }, [visible, form, configList, formValue]);

    const externalField = fieldsList.filter((item) => item.outside);

    const addConfigContent = (
      <div>
        <Form form={addForm} layout="vertical" className="p-4">
          <Form.Item
            label={<span className="text-default-3">{i18n.t('dop:filter name')}</span>}
            name="label"
            rules={[
              { required: true, message: i18n.t('Please enter the {name}', { name: i18n.t('dop:filter name') }) },
              { max: 10, message: i18n.t('dop:within {num} characters', { num: 10 }) },
            ]}
          >
            <Input
              className="w-52"
              placeholder={firstCharToUpper(i18n.t('dop:please enter, within {num} characters', { num: 10 }))}
            />
          </Form.Item>
          <div className="mt-3 flex-h-center justify-end">
            <Button
              className="mr-3"
              onClick={() => {
                addForm.resetFields();
                setAddVisible(false);
              }}
            >
              {i18n.t('Cancel')}
            </Button>
            <Button
              type="primary"
              onClick={() => {
                addForm.validateFields().then(({ label }) => {
                  saveFilter?.(label);
                  setAddVisible(false);
                });
              }}
            >
              {i18n.t('OK')}
            </Button>
          </div>
        </Form>
      </div>
    );

    const insideFields = fieldsList?.filter((item) => !item.outside);

    const content = (
      <div className="flex-1">
        <div className="h-full flex flex-col overflow-hidden">
          <div className=" h-[48px] flex-h-center justify-between px-2 mb-2">
            <div className="flex-h-center font-medium text-base">
              <span>{i18n.t('common:Filter-machine')}</span>
            </div>
            <ErdaIcon
              type="guanbi"
              size={20}
              className="text-default-6 cursor-pointer"
              onClick={() => {
                setVisible(false);
                onClose?.();
              }}
            />
          </div>
          <div className="flex justify-start flex-1 overflow-hidden">
            {!hideSave ? (
              <ConfigSelector
                className="overflow-auto"
                list={configList}
                value={currentConfig}
                isNew={isNew}
                defaultValue={defaultConfig}
                onChange={onConfigChange}
                onDeleteFilter={onDeleteFilter}
                onSaveFilter={saveFilter}
              />
            ) : null}
            <div className={'erda-configurable-filter-body ml-2 pl-2 pr-2 overflow-auto flex-1'}>
              <Form form={form} layout="vertical" onValuesChange={onValuesChange}>
                <Row>
                  {insideFields?.map((item, index: number) => {
                    return (
                      <Col span={12} key={item.key} className={index % 2 === 1 ? 'pl-2' : 'pr-2'}>
                        <RenderFormItem
                          required={false}
                          {...defaultProcessField(processField ? processField(item) : item, zIndex)}
                        />
                      </Col>
                    );
                  })}
                </Row>
              </Form>
            </div>
          </div>

          <div className="erda-configurable-filter-footer flex justify-end mt-3">
            <Button
              className="mx-1"
              onClick={() => {
                setVisible(false);
                onClose?.();
              }}
            >
              {i18n.t('Cancel')}
            </Button>
            {hideSave ? (
              <Button className="mx-1" onClick={setAllOpen}>
                {i18n.t('Clear')}
              </Button>
            ) : isNew && currentConfig ? (
              <Popover
                content={addConfigContent}
                visible={addVisible}
                onVisibleChange={setAddVisible}
                trigger={['click']}
                overlayClassName="erda-configurable-filter-add"
                getPopupContainer={(triggerNode) => triggerNode.parentElement as HTMLElement}
              >
                <Button
                  className="mx-1 cursor-pointer rounded-sm px-2 py-1 flex-h-center"
                  onClick={() => setAddVisible(true)}
                >
                  <ErdaIcon size={16} type="baocun" className="mr-1 text-default-8" /> {i18n.t('dop:new filter')}
                </Button>
              </Popover>
            ) : null}
            <Button type="primary" className="ml-1 mr-2" onClick={onFilter}>
              {i18n.t('common:Filter')}
            </Button>
          </div>
        </div>
      </div>
    );
    const getFilterName = () => {
      return getItemByValues(formValue, configList, fieldsList)?.label || i18n.t('common:Filter');
    };

    const isAllOpen = !!(
      formValue &&
      !isEmpty(formValue) &&
      Object.keys(formValue).find(
        (key) => formValue[key] && (typeof formValue[key] === 'number' || !isEmpty(formValue[key])),
      )
    );

    return (
      <div className={'flex items-center'}>
        {insideFields.length ? (
          <div className="flex-h-center bg-default-06 rounded-sm mr-2">
            <Popover
              content={content}
              visible={visible}
              forceRender
              trigger={['click']}
              overlayClassName={`erda-configurable-filter ${hideSave ? 'w-[720px]' : 'w-[960px]'}`}
              placement="bottomLeft"
              onVisibleChange={(v: boolean) => {
                setVisible(v);
                !v && onClose?.();
              }}
              zIndex={zIndex}
            >
              <div
                className={`flex-h-center erda-configurable-filter-btn py-1 px-2 rounded-sm leading-none cursor-pointer`}
                onClick={() => setVisible(true)}
              >
                <Badge dot={isAllOpen}>
                  <div className="flex-h-center">
                    <ErdaIcon type="futaishaixuan" className="filter-icon" size={14} />
                    <span className="mx-1 filter-text">{getFilterName()}</span>
                  </div>
                </Badge>
                <ErdaIcon type="caret-down" />
              </div>
            </Popover>
            {isAllOpen ? (
              <div
                className="erda-configurable-filter-clear-btn p-1 rounded-sm leading-none cursor-pointer"
                onClick={() => {
                  setAllOpen();
                  onFilter();
                }}
              >
                <ErdaIcon type="zhongzhi" color="currentColor" size={20} className="relative top-px" />
              </div>
            ) : null}
          </div>
        ) : null}
        <div className="flex-h-center">
          {externalField?.map((item) => {
            return (
              <ExternalItem
                itemData={item}
                value={externalValue?.[item.key]}
                onChange={(v) => {
                  setExternalValue((prev) => ({ ...prev, [item.key]: v }));
                }}
                key={item.key}
              />
            );
          })}
        </div>
      </div>
    );
  },
)
Example #25
Source File: OpticalPathItem.tsx    From slim with Apache License 2.0 4 votes vote down vote up
render (): React.ReactNode {
    const identifier = this.props.opticalPath.identifier
    const description = this.props.opticalPath.description
    const attributes: Array<{ name: string, value: string }> = []
    if (this.props.opticalPath.illuminationWaveLength !== undefined) {
      attributes.push(
        {
          name: 'Illumination wavelength',
          value: `${this.props.opticalPath.illuminationWaveLength} nm`
        }
      )
    }
    if (this.props.opticalPath.illuminationColor !== undefined) {
      attributes.push(
        {
          name: 'Illumination color',
          value: this.props.opticalPath.illuminationColor.CodeMeaning
        }
      )
    }

    // TID 8001 "Specimen Preparation"
    const specimenDescriptions: dmv.metadata.SpecimenDescription[] = (
      this.props.metadata[0].SpecimenDescriptionSequence ?? []
    )
    specimenDescriptions.forEach(description => {
      const specimenPreparationSteps: dmv.metadata.SpecimenPreparation[] = (
        description.SpecimenPreparationSequence ?? []
      )
      specimenPreparationSteps.forEach(
        (step: dmv.metadata.SpecimenPreparation, index: number): void => {
          step.SpecimenPreparationStepContentItemSequence.forEach((
            item: (
              dcmjs.sr.valueTypes.CodeContentItem |
              dcmjs.sr.valueTypes.TextContentItem |
              dcmjs.sr.valueTypes.UIDRefContentItem |
              dcmjs.sr.valueTypes.PNameContentItem |
              dcmjs.sr.valueTypes.DateTimeContentItem
            ),
            index: number
          ) => {
            const name = new dcmjs.sr.coding.CodedConcept({
              value: item.ConceptNameCodeSequence[0].CodeValue,
              schemeDesignator:
                item.ConceptNameCodeSequence[0].CodingSchemeDesignator,
              meaning: item.ConceptNameCodeSequence[0].CodeMeaning
            })
            if (item.ValueType === dcmjs.sr.valueTypes.ValueTypes.CODE) {
              item = item as dcmjs.sr.valueTypes.CodeContentItem
              const value = new dcmjs.sr.coding.CodedConcept({
                value: item.ConceptCodeSequence[0].CodeValue,
                schemeDesignator:
                  item.ConceptCodeSequence[0].CodingSchemeDesignator,
                meaning: item.ConceptCodeSequence[0].CodeMeaning
              })
              if (!name.equals(SpecimenPreparationStepItems.PROCESSING_TYPE)) {
                if (name.equals(SpecimenPreparationStepItems.STAIN)) {
                  attributes.push({
                    name: 'Tissue stain',
                    value: value.CodeMeaning
                  })
                }
              }
            } else if (item.ValueType === dcmjs.sr.valueTypes.ValueTypes.TEXT) {
              item = item as dcmjs.sr.valueTypes.TextContentItem
              if (!name.equals(SpecimenPreparationStepItems.PROCESSING_TYPE)) {
                if (name.equals(SpecimenPreparationStepItems.STAIN)) {
                  attributes.push({
                    name: 'Tissue stain',
                    value: item.TextValue
                  })
                }
              }
            }
          })
        }
      )
    })

    const maxValue = Math.pow(2, this.props.metadata[0].BitsAllocated) - 1

    const title = (
      description != null ? `${identifier}: ${description}` : identifier
    )
    let settings
    let item
    if (this.props.opticalPath.isMonochromatic) {
      // monochrome images that can be pseudo-colored
      let colorSettings
      if (this.state.currentStyle.color != null) {
        colorSettings = (
          <>
            <Divider plain>
              Color
            </Divider>
            <Row justify='center' align='middle' gutter={[8, 8]}>
              <Col span={5}>
                Red
              </Col>
              <Col span={14}>
                <Slider
                  range={false}
                  min={0}
                  max={255}
                  step={1}
                  value={this.state.currentStyle.color[0]}
                  onChange={this.handleColorRChange}
                />
              </Col>
              <Col span={5}>
                <InputNumber
                  min={0}
                  max={255}
                  size='small'
                  style={{ width: '65px' }}
                  value={this.state.currentStyle.color[0]}
                  onChange={this.handleColorRChange}
                />
              </Col>
            </Row>

            <Row justify='center' align='middle' gutter={[8, 8]}>
              <Col span={5}>
                Green
              </Col>
              <Col span={14}>
                <Slider
                  range={false}
                  min={0}
                  max={255}
                  step={1}
                  value={this.state.currentStyle.color[1]}
                  onChange={this.handleColorGChange}
                />
              </Col>
              <Col span={5}>
                <InputNumber
                  min={0}
                  max={255}
                  size='small'
                  style={{ width: '65px' }}
                  value={this.state.currentStyle.color[1]}
                  onChange={this.handleColorGChange}
                />
              </Col>
            </Row>

            <Row justify='center' align='middle' gutter={[8, 8]}>
              <Col span={5}>
                Blue
              </Col>
              <Col span={14}>
                <Slider
                  range={false}
                  min={0}
                  max={255}
                  step={1}
                  value={this.state.currentStyle.color[2]}
                  onChange={this.handleColorBChange}
                />
              </Col>
              <Col span={5}>
                <InputNumber
                  min={0}
                  max={255}
                  size='small'
                  style={{ width: '65px' }}
                  value={this.state.currentStyle.color[2]}
                  onChange={this.handleColorBChange}
                />
              </Col>
            </Row>
          </>
        )
      }

      let windowSettings
      if (this.state.currentStyle.limitValues != null) {
        windowSettings = (
          <>
            <Divider plain>
              Values of interest
            </Divider>
            <Row justify='center' align='middle' gutter={[8, 8]}>
              <Col span={6}>
                <InputNumber
                  min={0}
                  max={this.state.currentStyle.limitValues[1]}
                  size='small'
                  style={{ width: '75px' }}
                  value={this.state.currentStyle.limitValues[0]}
                  onChange={this.handleLowerLimitChange}
                />
              </Col>
              <Col span={12}>
                <Slider
                  range
                  min={0}
                  max={maxValue}
                  step={1}
                  value={[
                    this.state.currentStyle.limitValues[0],
                    this.state.currentStyle.limitValues[1]
                  ]}
                  onChange={this.handleLimitChange}
                />
              </Col>
              <Col span={6}>
                <InputNumber
                  min={this.state.currentStyle.limitValues[0]}
                  max={maxValue}
                  size='small'
                  style={{ width: '75px' }}
                  value={this.state.currentStyle.limitValues[1]}
                  onChange={this.handleUpperLimitChange}
                />
              </Col>
            </Row>
          </>
        )
      }
      settings = (
        <div>
          {windowSettings}
          {colorSettings}
          <Divider plain />
          <Row justify='center' align='middle' gutter={[8, 8]}>
            <Col span={6}>
              Opacity
            </Col>
            <Col span={12}>
              <Slider
                range={false}
                min={0}
                max={1}
                step={0.01}
                value={this.state.currentStyle.opacity}
                onChange={this.handleOpacityChange}
              />
            </Col>
            <Col span={6}>
              <InputNumber
                min={0}
                max={1}
                size='small'
                step={0.1}
                style={{ width: '65px' }}
                value={this.state.currentStyle.opacity}
                onChange={this.handleOpacityChange}
              />
            </Col>
          </Row>
        </div>
      )
      const colors = this.getCurrentColors()
      item = (
        <Badge
          offset={[-20, 20]}
          count={' '}
          style={{
            borderStyle: 'solid',
            borderWidth: '1px',
            borderColor: 'gray',
            visibility: this.state.isVisible ? 'visible' : 'hidden',
            backgroundImage: `linear-gradient(to right, ${colors.toString()})`
          }}
        >
          <Description
            header={title}
            attributes={attributes}
            selectable
            hasLongValues
          />
        </Badge>
      )
    } else {
      // color images
      settings = (
        <div>
          <Row justify='center' align='middle' gutter={[8, 8]}>
            <Col span={6}>
              Opacity
            </Col>
            <Col span={12}>
              <Slider
                range={false}
                min={0}
                max={1}
                step={0.01}
                value={this.state.currentStyle.opacity}
                onChange={this.handleOpacityChange}
              />
            </Col>
            <Col span={6}>
              <InputNumber
                min={0}
                max={1}
                size='small'
                step={0.1}
                style={{ width: '60px' }}
                value={this.state.currentStyle.opacity}
                onChange={this.handleOpacityChange}
              />
            </Col>
          </Row>
        </div>
      )
      item = (
        <Description
          header={title}
          attributes={attributes}
          selectable
          hasLongValues
        />
      )
    }

    const buttons = []
    if (this.props.isRemovable) {
      buttons.push(
        <Tooltip title='Remove Optical Path'>
          <Button
            type='default'
            shape='circle'
            icon={<DeleteOutlined />}
            onClick={this.handleRemoval}
          />
        </Tooltip>
      )
    }

    const {
      defaultStyle,
      isRemovable,
      isVisible,
      metadata,
      onVisibilityChange,
      onStyleChange,
      onRemoval,
      opticalPath,
      ...otherProps
    } = this.props
    return (
      <Menu.Item
        style={{ height: '100%', paddingLeft: '3px' }}
        key={this.props.opticalPath.identifier}
        {...otherProps}
      >
        <Space align='start'>
          <div style={{ paddingLeft: '14px' }}>
            <Space direction='vertical' align='end'>
              <Switch
                size='small'
                checked={this.state.isVisible}
                onChange={this.handleVisibilityChange}
                checkedChildren={<EyeOutlined />}
                unCheckedChildren={<EyeInvisibleOutlined />}
              />
              <Popover
                placement='left'
                content={settings}
                overlayStyle={{ width: '350px' }}
                title='Display Settings'
              >
                <Button
                  type='primary'
                  shape='circle'
                  icon={<SettingOutlined />}
                />
              </Popover>
              {buttons}
            </Space>
          </div>
          {item}
        </Space>
      </Menu.Item>
    )
  }
Example #26
Source File: index.tsx    From ant-design-pro-V4 with MIT License 4 votes vote down vote up
NoticeIcon: React.FC<NoticeIconProps> & {
  Tab: typeof NoticeList;
} = (props) => {
  const getNotificationBox = (): React.ReactNode => {
    const {
      children,
      loading,
      onClear,
      onTabChange,
      onItemClick,
      onViewMore,
      clearText,
      viewMoreText,
    } = props;
    if (!children) {
      return null;
    }
    const panes: React.ReactNode[] = [];
    React.Children.forEach(children, (child: React.ReactElement<NoticeIconTabProps>): void => {
      if (!child) {
        return;
      }
      const { list, title, count, tabKey, showClear, showViewMore } = child.props;
      const len = list && list.length ? list.length : 0;
      const msgCount = count || count === 0 ? count : len;
      const tabTitle: string = msgCount > 0 ? `${title} (${msgCount})` : title;
      panes.push(
        <TabPane tab={tabTitle} key={tabKey}>
          <NoticeList
            {...child.props}
            clearText={clearText}
            viewMoreText={viewMoreText}
            data={list}
            onClear={(): void => {
              onClear?.(title, tabKey);
            }}
            onClick={(item): void => {
              onItemClick?.(item, child.props);
            }}
            onViewMore={(event): void => {
              onViewMore?.(child.props, event);
            }}
            showClear={showClear}
            showViewMore={showViewMore}
            title={title}
          />
        </TabPane>,
      );
    });
    return (
      <Spin spinning={loading} delay={300}>
        <Tabs className={styles.tabs} onChange={onTabChange}>
          {panes}
        </Tabs>
      </Spin>
    );
  };

  const { className, count, bell } = props;

  const [visible, setVisible] = useMergedState<boolean>(false, {
    value: props.popupVisible,
    onChange: props.onPopupVisibleChange,
  });
  const noticeButtonClass = classNames(className, styles.noticeButton);
  const notificationBox = getNotificationBox();
  const NoticeBellIcon = bell || <BellOutlined className={styles.icon} />;
  const trigger = (
    <span className={classNames(noticeButtonClass, { opened: visible })}>
      <Badge count={count} style={{ boxShadow: 'none' }} className={styles.badge}>
        {NoticeBellIcon}
      </Badge>
    </span>
  );
  if (!notificationBox) {
    return trigger;
  }

  return (
    <HeaderDropdown
      placement="bottomRight"
      overlay={notificationBox}
      overlayClassName={styles.popover}
      trigger={['click']}
      visible={visible}
      onVisibleChange={setVisible}
    >
      {trigger}
    </HeaderDropdown>
  );
}
Example #27
Source File: index.tsx    From jetlinks-ui-antd with MIT License 4 votes vote down vote up
DeviceList = (props: Props) => {
  const [searchParam, setSearchParam] = useState({
    pageSize: 10,
    terms: { productId: props.productId },
  });
  const [deviceData, setDeviceData] = useState<any>({});
  const [deviceId, setDeviceId] = useState(props.data);

  const submitData = () => {
    props.save(deviceId);
  };

  const handleSearch = (params?: any) => {
    setSearchParam(params);
    apis.deviceInstance
      .list(encodeQueryParam(params))
      .then(response => {
        if (response.status === 200) {
          setDeviceData(response.result);
        }
      })
      .catch(() => {});
  };

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

  const onTableChange = (pagination: PaginationConfig, filters: any, sorter: SorterResult<any>) => {
    apis.deviceInstance
      .list(
        encodeQueryParam({
          pageIndex: Number(pagination.current) - 1,
          pageSize: pagination.pageSize,
          sorts: sorter,
          terms: { productId: props.productId },
        }),
      )
      .then(response => {
        if (response.status === 200) {
          setDeviceData(response.result);
        }
      })
      .catch(() => {});
  };

  const rowSelection = {
    onChange: (selectedRowKeys: any) => {
      setDeviceId(selectedRowKeys);
    },
  };

  const statusMap = new Map();
  statusMap.set('在线', 'success');
  statusMap.set('离线', 'error');
  statusMap.set('未激活', 'processing');

  const columns: ColumnProps<any>[] = [
    {
      title: 'ID',
      dataIndex: 'id',
      ellipsis: true,
    },
    {
      title: '设备名称',
      dataIndex: 'name',
      ellipsis: true,
    },
    {
      title: '产品名称',
      dataIndex: 'productName',
      ellipsis: true,
    },
    {
      title: '注册时间',
      dataIndex: 'registryTime',
      width: '200px',
      ellipsis: true,
      render: (text: any) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
      sorter: true,
      defaultSortOrder: 'descend',
    },
    {
      title: '状态',
      dataIndex: 'state',
      width: '120px',
      render: record =>
        record ? <Badge status={statusMap.get(record.text)} text={record.text} /> : '',
    },
  ];

  return (
    <Modal
      title="选择设备"
      visible
      okText="确定"
      cancelText="取消"
      onOk={() => {
        submitData();
      }}
      width="60%"
      style={{ marginTop: -30 }}
      onCancel={() => props.close()}
    >
      <div
        className={styles.tableList}
        style={{ maxHeight: 600, overflowY: 'auto', overflowX: 'hidden' }}
      >
        <div className={styles.tableListForm}>
          <SearchForm
            search={(params: any) => {
              handleSearch({ terms: { ...searchParam.terms, ...params }, pageSize: 10 });
            }}
            formItems={[
              {
                label: '设备名称',
                key: 'name$LIKE',
                type: 'string',
              },
              {
                label: '设备ID',
                key: 'deviceId$IN',
                type: 'string',
              },
            ]}
          />
        </div>

        <div className={styles.StandardTable}>
          <Table
            columns={columns}
            dataSource={deviceData.data}
            rowKey="id"
            onChange={onTableChange}
            rowSelection={{
              selectedRowKeys: deviceId,
              type: 'checkbox',
              ...rowSelection,
            }}
            pagination={{
              current: deviceData.pageIndex + 1,
              total: deviceData.total,
              pageSize: deviceData.pageSize,
              showQuickJumper: true,
              showSizeChanger: true,
              pageSizeOptions: ['10', '20', '50', '100'],
              showTotal: (total: number) =>
                `共 ${total} 条记录 第  ${deviceData.pageIndex + 1}/${Math.ceil(
                  deviceData.total / deviceData.pageSize,
                )}页`,
            }}
          />
        </div>
      </div>
    </Modal>
  );
}