@ant-design/icons#ClusterOutlined TypeScript Examples

The following examples show how to use @ant-design/icons#ClusterOutlined. 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: personalizationOptions.tsx    From posthog-foss with MIT License 5 votes vote down vote up
ROLES: RadioSelectType[] = [
    {
        key: 'engineer',
        label: 'Engineer',
        icon: <CodeOutlined />,
    },
    {
        key: 'product',
        label: 'Product Manager',
        icon: <RocketOutlined />,
    },
    {
        key: 'management',
        label: 'Management',
        icon: <ClusterOutlined />,
    },

    {
        key: 'marketing',
        label: 'Marketing',
        icon: <NotificationOutlined />,
    },
    {
        key: 'sales',
        label: 'Sales',
        icon: <DollarOutlined />,
    },
    {
        key: 'cx',
        label: 'Customer success',
        icon: <SmileOutlined />,
    },
    {
        key: 'ops',
        label: 'Operations',
        icon: <ToolOutlined />,
    },
    {
        key: 'other',
        label: 'Other',
        icon: <BlockOutlined />,
    },
]
Example #2
Source File: Icon.tsx    From html2sketch with MIT License 4 votes vote down vote up
IconSymbol: FC = () => {
  return (
    <Row>
      {/*<CaretUpOutlined*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/1.CaretUpOutlined'}*/}
      {/*/>*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/2.MailOutlined'}*/}
      {/*/>*/}
      {/*<StepBackwardOutlined*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
      {/*/>*/}
      {/*<StepForwardOutlined*/}
      {/*  className="icon"*/}
      {/*  symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
      {/*/>*/}
      <StepForwardOutlined />
      <ShrinkOutlined />
      <ArrowsAltOutlined />
      <DownOutlined />
      <UpOutlined />
      <LeftOutlined />
      <RightOutlined />
      <CaretUpOutlined />
      <CaretDownOutlined />
      <CaretLeftOutlined />
      <CaretRightOutlined />
      <VerticalAlignTopOutlined />
      <RollbackOutlined />
      <FastBackwardOutlined />
      <FastForwardOutlined />
      <DoubleRightOutlined />
      <DoubleLeftOutlined />
      <VerticalLeftOutlined />
      <VerticalRightOutlined />
      <VerticalAlignMiddleOutlined />
      <VerticalAlignBottomOutlined />
      <ForwardOutlined />
      <BackwardOutlined />
      <EnterOutlined />
      <RetweetOutlined />
      <SwapOutlined />
      <SwapLeftOutlined />
      <SwapRightOutlined />
      <ArrowUpOutlined />
      <ArrowDownOutlined />
      <ArrowLeftOutlined />
      <ArrowRightOutlined />
      <LoginOutlined />
      <LogoutOutlined />
      <MenuFoldOutlined />
      <MenuUnfoldOutlined />
      <BorderBottomOutlined />
      <BorderHorizontalOutlined />
      <BorderInnerOutlined />
      <BorderOuterOutlined />
      <BorderLeftOutlined />
      <BorderRightOutlined />
      <BorderTopOutlined />
      <BorderVerticleOutlined />
      <PicCenterOutlined />
      <PicLeftOutlined />
      <PicRightOutlined />
      <RadiusBottomleftOutlined />
      <RadiusBottomrightOutlined />
      <RadiusUpleftOutlined />
      <RadiusUprightOutlined />
      <FullscreenOutlined />
      <FullscreenExitOutlined />
      <QuestionOutlined />
      <PauseOutlined />
      <MinusOutlined />
      <PauseCircleOutlined />
      <InfoOutlined />
      <CloseOutlined />
      <ExclamationOutlined />
      <CheckOutlined />
      <WarningOutlined />
      <IssuesCloseOutlined />
      <StopOutlined />
      <EditOutlined />
      <CopyOutlined />
      <ScissorOutlined />
      <DeleteOutlined />
      <SnippetsOutlined />
      <DiffOutlined />
      <HighlightOutlined />
      <AlignCenterOutlined />
      <AlignLeftOutlined />
      <AlignRightOutlined />
      <BgColorsOutlined />
      <BoldOutlined />
      <ItalicOutlined />
      <UnderlineOutlined />
      <StrikethroughOutlined />
      <RedoOutlined />
      <UndoOutlined />
      <ZoomInOutlined />
      <ZoomOutOutlined />
      <FontColorsOutlined />
      <FontSizeOutlined />
      <LineHeightOutlined />
      <SortAscendingOutlined />
      <SortDescendingOutlined />
      <DragOutlined />
      <OrderedListOutlined />
      <UnorderedListOutlined />
      <RadiusSettingOutlined />
      <ColumnWidthOutlined />
      <ColumnHeightOutlined />
      <AreaChartOutlined />
      <PieChartOutlined />
      <BarChartOutlined />
      <DotChartOutlined />
      <LineChartOutlined />
      <RadarChartOutlined />
      <HeatMapOutlined />
      <FallOutlined />
      <RiseOutlined />
      <StockOutlined />
      <BoxPlotOutlined />
      <FundOutlined />
      <SlidersOutlined />
      <AndroidOutlined />
      <AppleOutlined />
      <WindowsOutlined />
      <IeOutlined />
      <ChromeOutlined />
      <GithubOutlined />
      <AliwangwangOutlined />
      <DingdingOutlined />
      <WeiboSquareOutlined />
      <WeiboCircleOutlined />
      <TaobaoCircleOutlined />
      <Html5Outlined />
      <WeiboOutlined />
      <TwitterOutlined />
      <WechatOutlined />
      <AlipayCircleOutlined />
      <TaobaoOutlined />
      <SkypeOutlined />
      <FacebookOutlined />
      <CodepenOutlined />
      <CodeSandboxOutlined />
      <AmazonOutlined />
      <GoogleOutlined />
      <AlipayOutlined />
      <AntDesignOutlined />
      <AntCloudOutlined />
      <ZhihuOutlined />
      <SlackOutlined />
      <SlackSquareOutlined />
      <BehanceSquareOutlined />
      <DribbbleOutlined />
      <DribbbleSquareOutlined />
      <InstagramOutlined />
      <YuqueOutlined />
      <AlibabaOutlined />
      <YahooOutlined />
      <RedditOutlined />
      <SketchOutlined />
      <AccountBookOutlined />
      <AlertOutlined />
      <ApartmentOutlined />
      <ApiOutlined />
      <QqOutlined />
      <MediumWorkmarkOutlined />
      <GitlabOutlined />
      <MediumOutlined />
      <GooglePlusOutlined />
      <AppstoreAddOutlined />
      <AppstoreOutlined />
      <AudioOutlined />
      <AudioMutedOutlined />
      <AuditOutlined />
      <BankOutlined />
      <BarcodeOutlined />
      <BarsOutlined />
      <BellOutlined />
      <BlockOutlined />
      <BookOutlined />
      <BorderOutlined />
      <BranchesOutlined />
      <BuildOutlined />
      <BulbOutlined />
      <CalculatorOutlined />
      <CalendarOutlined />
      <CameraOutlined />
      <CarOutlined />
      <CarryOutOutlined />
      <CiCircleOutlined />
      <CiOutlined />
      <CloudOutlined />
      <ClearOutlined />
      <ClusterOutlined />
      <CodeOutlined />
      <CoffeeOutlined />
      <CompassOutlined />
      <CompressOutlined />
      <ContactsOutlined />
      <ContainerOutlined />
      <ControlOutlined />
      <CopyrightCircleOutlined />
      <CopyrightOutlined />
      <CreditCardOutlined />
      <CrownOutlined />
      <CustomerServiceOutlined />
      <DashboardOutlined />
      <DatabaseOutlined />
      <DeleteColumnOutlined />
      <DeleteRowOutlined />
      <DisconnectOutlined />
      <DislikeOutlined />
      <DollarCircleOutlined />
      <DollarOutlined />
      <DownloadOutlined />
      <EllipsisOutlined />
      <EnvironmentOutlined />
      <EuroCircleOutlined />
      <EuroOutlined />
      <ExceptionOutlined />
      <ExpandAltOutlined />
      <ExpandOutlined />
      <ExperimentOutlined />
      <ExportOutlined />
      <EyeOutlined />
      <FieldBinaryOutlined />
      <FieldNumberOutlined />
      <FieldStringOutlined />
      <DesktopOutlined />
      <DingtalkOutlined />
      <FileAddOutlined />
      <FileDoneOutlined />
      <FileExcelOutlined />
      <FileExclamationOutlined />
      <FileOutlined />
      <FileImageOutlined />
      <FileJpgOutlined />
      <FileMarkdownOutlined />
      <FilePdfOutlined />
      <FilePptOutlined />
      <FileProtectOutlined />
      <FileSearchOutlined />
      <FileSyncOutlined />
      <FileTextOutlined />
      <FileUnknownOutlined />
      <FileWordOutlined />
      <FilterOutlined />
      <FireOutlined />
      <FlagOutlined />
      <FolderAddOutlined />
      <FolderOutlined />
      <FolderOpenOutlined />
      <ForkOutlined />
      <FormatPainterOutlined />
      <FrownOutlined />
      <FunctionOutlined />
      <FunnelPlotOutlined />
      <GatewayOutlined />
      <GifOutlined />
      <GiftOutlined />
      <GlobalOutlined />
      <GoldOutlined />
      <GroupOutlined />
      <HddOutlined />
      <HeartOutlined />
      <HistoryOutlined />
      <HomeOutlined />
      <HourglassOutlined />
      <IdcardOutlined />
      <ImportOutlined />
      <InboxOutlined />
      <InsertRowAboveOutlined />
      <InsertRowBelowOutlined />
      <InsertRowLeftOutlined />
      <InsertRowRightOutlined />
      <InsuranceOutlined />
      <InteractionOutlined />
      <KeyOutlined />
      <LaptopOutlined />
      <LayoutOutlined />
      <LikeOutlined />
      <LineOutlined />
      <LinkOutlined />
      <Loading3QuartersOutlined />
      <LoadingOutlined />
      <LockOutlined />
      <MailOutlined />
      <ManOutlined />
      <MedicineBoxOutlined />
      <MehOutlined />
      <MenuOutlined />
      <MergeCellsOutlined />
      <MessageOutlined />
      <MobileOutlined />
      <MoneyCollectOutlined />
      <MonitorOutlined />
      <MoreOutlined />
      <NodeCollapseOutlined />
      <NodeExpandOutlined />
      <NodeIndexOutlined />
      <NotificationOutlined />
      <NumberOutlined />
      <PaperClipOutlined />
      <PartitionOutlined />
      <PayCircleOutlined />
      <PercentageOutlined />
      <PhoneOutlined />
      <PictureOutlined />
      <PoundCircleOutlined />
      <PoundOutlined />
      <PoweroffOutlined />
      <PrinterOutlined />
      <ProfileOutlined />
      <ProjectOutlined />
      <PropertySafetyOutlined />
      <PullRequestOutlined />
      <PushpinOutlined />
      <QrcodeOutlined />
      <ReadOutlined />
      <ReconciliationOutlined />
      <RedEnvelopeOutlined />
      <ReloadOutlined />
      <RestOutlined />
      <RobotOutlined />
      <RocketOutlined />
      <SafetyCertificateOutlined />
      <SafetyOutlined />
      <ScanOutlined />
      <ScheduleOutlined />
      <SearchOutlined />
      <SecurityScanOutlined />
      <SelectOutlined />
      <SendOutlined />
      <SettingOutlined />
      <ShakeOutlined />
      <ShareAltOutlined />
      <ShopOutlined />
      <ShoppingCartOutlined />
      <ShoppingOutlined />
      <SisternodeOutlined />
      <SkinOutlined />
      <SmileOutlined />
      <SolutionOutlined />
      <SoundOutlined />
      <SplitCellsOutlined />
      <StarOutlined />
      <SubnodeOutlined />
      <SyncOutlined />
      <TableOutlined />
      <TabletOutlined />
      <TagOutlined />
      <TagsOutlined />
      <TeamOutlined />
      <ThunderboltOutlined />
      <ToTopOutlined />
      <ToolOutlined />
      <TrademarkCircleOutlined />
      <TrademarkOutlined />
      <TransactionOutlined />
      <TrophyOutlined />
      <UngroupOutlined />
      <UnlockOutlined />
      <UploadOutlined />
      <UsbOutlined />
      <UserAddOutlined />
      <UserDeleteOutlined />
      <UserOutlined />
      <UserSwitchOutlined />
      <UsergroupAddOutlined />
      <UsergroupDeleteOutlined />
      <VideoCameraOutlined />
      <WalletOutlined />
      <WifiOutlined />
      <BorderlessTableOutlined />
      <WomanOutlined />
      <BehanceOutlined />
      <DropboxOutlined />
      <DeploymentUnitOutlined />
      <UpCircleOutlined />
      <DownCircleOutlined />
      <LeftCircleOutlined />
      <RightCircleOutlined />
      <UpSquareOutlined />
      <DownSquareOutlined />
      <LeftSquareOutlined />
      <RightSquareOutlined />
      <PlayCircleOutlined />
      <QuestionCircleOutlined />
      <PlusCircleOutlined />
      <PlusSquareOutlined />
      <MinusSquareOutlined />
      <MinusCircleOutlined />
      <InfoCircleOutlined />
      <ExclamationCircleOutlined />
      <CloseCircleOutlined />
      <CloseSquareOutlined />
      <CheckCircleOutlined />
      <CheckSquareOutlined />
      <ClockCircleOutlined />
      <FormOutlined />
      <DashOutlined />
      <SmallDashOutlined />
      <YoutubeOutlined />
      <CodepenCircleOutlined />
      <AliyunOutlined />
      <PlusOutlined />
      <LinkedinOutlined />
      <AimOutlined />
      <BugOutlined />
      <CloudDownloadOutlined />
      <CloudServerOutlined />
      <CloudSyncOutlined />
      <CloudUploadOutlined />
      <CommentOutlined />
      <ConsoleSqlOutlined />
      <EyeInvisibleOutlined />
      <FileGifOutlined />
      <DeliveredProcedureOutlined />
      <FieldTimeOutlined />
      <FileZipOutlined />
      <FolderViewOutlined />
      <FundProjectionScreenOutlined />
      <FundViewOutlined />
      <MacCommandOutlined />
      <PlaySquareOutlined />
      <OneToOneOutlined />
      <RotateLeftOutlined />
      <RotateRightOutlined />
      <SaveOutlined />
      <SwitcherOutlined />
      <TranslationOutlined />
      <VerifiedOutlined />
      <VideoCameraAddOutlined />
      <WhatsAppOutlined />

      {/*</Col>*/}
    </Row>
  );
}
Example #3
Source File: ArgumentsSetting.tsx    From yugong with MIT License 4 votes vote down vote up
ArgumentsSetting: React.FC<Props> = ({
  visible,
  argumentsData,
  initArgumentData,
  onOk,
  onCancel,
  title,
  dataFlexible = false,
  headerFlexible = false,
  forceUpdate,
  visiableRunningTimeIcon = true,
}) => {
  const runningTimes = useSelector((state: RootState) => state.runningTimes);
  const [argumentState, setArgumentState] = useState<ArgumentsItem[]>([]);
  const [showRunningTimes, setShowRunningTimes] = useState(false);
  const forceUpdateByStateTag =
    useDispatch<Dispatch>().controller.forceUpdateByStateTag;
  // 将argument数据接管
  useEffect(() => {
    let data: ArgumentsItem[] = [...(argumentsData || [])];
    // 不可自定义参数且数据为空时,使用组件初始数据
    if (data.length === 0) {
      data = [...(initArgumentData || [])];
    }
    setArgumentState(data);
  }, [argumentsData, headerFlexible, initArgumentData]);

  // 弹窗确定收集编辑完毕的argument数据
  const onModalOk = useCallback(() => {
    if (onOk instanceof Function) {
      // todo 确定页面为何强制更新??
      if (forceUpdate) {
        forceUpdateByStateTag();
      }
      onOk(argumentState);
    }
  }, [onOk, forceUpdateByStateTag, argumentState, forceUpdate]);

  // number
  const onChangeInput = useCallback(
    (index: number, isSelect?: boolean) => (e: any) => {
      const result = cloneDeep(argumentState);
      result[index].data = isSelect ? e : e.target.value;
      setArgumentState(result);
    },
    [argumentState],
  );

  const onChangeRunningTime = useCallback(
    (index: number) => (e: any) => {
      const result = [...argumentState];
      result[index].data = e;
      setArgumentState(result);
    },
    [argumentState],
  );

  const onChangeObjType = useCallback(
    (index: number) => (data: ArgumentsItem) => {
      const result = [...argumentState];
      result[index] = data;
      setArgumentState(result);
    },
    [argumentState],
  );

  const onChangeFieldName = useCallback(
    (index: number) => (e: any) => {
      const result = [...argumentState];
      result[index].fieldName = e.target.value;
      result[index].name = e.target.value;
      setArgumentState(result);
    },
    [argumentState],
  );

  const onChangeDescribe = useCallback(
    (index: number) => (e: any) => {
      const result = [...argumentState];
      result[index].describe = e.target.value;
      setArgumentState(result);
    },
    [argumentState],
  );

  // 移除字段
  const onRemove = useCallback(
    (index: number) => () => {
      let result = [...argumentState];
      result = result.filter((_, i) => i !== index);
      setArgumentState(result);
    },
    [argumentState],
  );

  // 新增字段
  const onAddField = useCallback(() => {
    const result = [...argumentState];
    result.push({
      describe: undefined,
      name: '未命名',
      fieldName: '',
      type: 'string',
      data: '',
    });
    setArgumentState(result);
  }, [argumentState]);

  // 修改字段类型
  const onChangeArgType = useCallback(
    (index: number) => (e: any) => {
      const result = [...argumentState];
      result[index].type = e;
      switch (e) {
        case 'runningTime':
        case 'string':
        case 'number':
          result[index].data = '';
          break;
        case 'array':
          result[index].data = [];
          break;
        case 'object':
          result[index].data = {};
          break;
        case 'boolean':
          result[index].data = {
            comparableAverageA: null,
            comparableAverageB: null,
            method: '===',
          };
          break;

        default:
          break;
      }
      setArgumentState(result);
    },
    [argumentState],
  );

  const onClickShowGloabVar = useCallback(() => {
    console.log(runningTimes);
  }, [runningTimes]);

  const renderNumberString = (
    item: ArgumentsString | ArgumentsNumber,
    index: number,
  ) => {
    // 下拉选择形式
    if (item?.select) {
      const { select } = item;
      const keys = Object.keys(select);
      console.log('select', select);
      console.log('keys', keys);
      return (
        <Select
          onChange={onChangeInput(index, true)}
          value={item.data}
          className={s.select}
          placeholder={`请输入值,${item.describe || ''}`}
        >
          {keys.map((value) => (
            <Select.Option key={value} value={value}>
              {select[value]}
            </Select.Option>
          ))}
        </Select>
      );
    }
    // 输入框形式
    return (
      <Input
        onChange={onChangeInput(index)}
        placeholder={`请输入值,${item.describe || ''}`}
        value={item.data}
        type="text"
        suffix={!!item.html ? <HtmlSuffix /> : null}
      />
    );
  };

  return (
    <>
      <Modal
        title={
          <div className={s.title}>
            <h4>
              {title}{' '}
              {visiableRunningTimeIcon ? <Button
                type="text"
                onClick={onClickShowGloabVar}
                icon={
                  <Tooltip title="查看全局发布变量">
                    <ClusterOutlined
                      onClick={() => setShowRunningTimes(true)}
                    />
                  </Tooltip>
                }
              /> : null}
            </h4>
            <div className={s.right}>
              {headerFlexible ? (
                <Button onClick={onAddField}>新增</Button>
              ) : null}
            </div>
          </div>
        }
        visible={visible}
        onOk={onModalOk}
        onCancel={onCancel}
        bodyStyle={{ padding: '10px' }}
        okText="确定"
        cancelText="取消"
      >
        {argumentState.map((item, index) => {
          const initItem = initArgumentData?.length
            ? initArgumentData[index]
            : undefined;
          return (
            <Card
              className={classNames(s.card, {
                [s.mixedcard]: item.type === 'mixed',
              })}
              key={`${index}`}
              title={
                <div className={s.cardtitle}>
                  <div className={s.cardtitleinfo}>
                    {!headerFlexible ? (
                      <>
                        <span className={s.label}>名称:</span>
                        {item.name || initItem?.name || ''} &nbsp;
                        <Tooltip
                          title={parse(
                            item.describe || initItem?.describe || '',
                          )}
                        >
                          <InfoCircleOutlined
                            style={{
                              color: 'rgba(0,0,0,.45)',
                            }}
                          />
                        </Tooltip>
                      </>
                    ) : (
                      <>
                        <span className={s.label}>字段:</span>
                        <Input
                          className={s.title}
                          value={item.fieldName || initItem?.fieldName || ''}
                          placeholder="限数字或字母"
                          onChange={onChangeFieldName(index)}
                          suffix={
                            <Tooltip
                              title={
                                <Input
                                  className={s.desc}
                                  placeholder="新增字段描述"
                                  value={item.describe}
                                  style={{
                                    width: '200px',
                                  }}
                                  onChange={onChangeDescribe(index)}
                                />
                              }
                            >
                              <InfoCircleOutlined
                                style={{
                                  color: 'rgba(0,0,0,.45)',
                                }}
                              />
                            </Tooltip>
                          }
                        />
                      </>
                    )}
                    <span className={s.divide} />
                    <span className={s.label}>类型:</span>
                    {headerFlexible ? (
                      <Select
                        className={s.type}
                        value={item.type}
                        onChange={onChangeArgType(index)}
                      >
                        <Select.Option value="string">string</Select.Option>
                        <Select.Option value="number">number</Select.Option>
                        <Select.Option value="boolean">boolean</Select.Option>
                        <Select.Option value="object">object</Select.Option>
                        <Select.Option value="array">array</Select.Option>
                        <Select.Option value="mixed">mixed</Select.Option>
                        <Select.Option value="runningTime">
                          runningTime
                        </Select.Option>
                      </Select>
                    ) : (
                      item.type
                    )}
                  </div>
                  <div>
                    {headerFlexible ? (
                      <Button onClick={onRemove(index)}>移除</Button>
                    ) : null}
                  </div>
                </div>
              }
            >
              <div>
                {item.type === 'number' || item.type === 'string'
                  ? renderNumberString(item, index)
                  : null}
                {item.type === 'runningTime' ? (
                  <Select
                    className={s.select}
                    placeholder="请选择"
                    showSearch
                    value={item.data}
                    optionFilterProp="children"
                    filterOption={
                      (input, option) => {
                        const str = option?.children?.join('').toLowerCase();
                        if (str?.indexOf(input) !== -1) {
                          return true;
                        }
                        return false;
                      }
                      // option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                    }
                    onChange={onChangeRunningTime(index)}
                  >
                    {Object.keys(runningTimes)?.map(
                      (optionsIitem, optionsIitemIndex) => (
                        <Select.Option
                          key={optionsIitemIndex}
                          value={optionsIitem}
                        >
                          {optionsIitem}
                        </Select.Option>
                      ),
                    )}
                  </Select>
                ) : null}
                {item.type === 'object' ? (
                  <ObjectArguments
                    describe={item.describe}
                    htmlInput={!!item.html}
                    onChange={onChangeObjType(index)}
                    typeArguments={item}
                    flexible={!!dataFlexible}
                  />
                ) : null}
                {item.type === 'array' ? (
                  <ArrayArguments
                    htmlInput={!!item.html}
                    describe={item.describe}
                    onChange={onChangeObjType(index)}
                    typeArguments={item}
                    flexible={!!dataFlexible}
                  />
                ) : null}
                {item.type === 'boolean' ? (
                  <BooleanArguments
                    onChange={onChangeObjType(index)}
                    typeArguments={item}
                    flexible={!!dataFlexible}
                  />
                ) : null}
                {item.type === 'mixed' ? (
                  <MixedArguments
                    onChange={onChangeObjType(index)}
                    typeArguments={item}
                    flexible={!!dataFlexible}
                  />
                ) : null}
              </div>
            </Card>
          );
        })}
      </Modal>
      <RunningTimesModal
        visible={showRunningTimes}
        data={runningTimes}
        onCancel={() => setShowRunningTimes(false)}
      />
    </>
  );
}
Example #4
Source File: Dashboard.tsx    From yugong with MIT License 4 votes vote down vote up
Dashboard: React.FC<Props> = () => {
  // 复制模块
  const [showCopyedModal, setShowCopyedModal] = useState(false);
  // 复制模块名称
  const [newModalName, setNewModalName] = useState<string>();

  const [showRunningTimes, setShowRunningTimes] = useState(false);
  const runningTimes = useSelector((state: RootState) => state.runningTimes);

  // appdata
  const appData = useSelector((state: RootState) => state.appData);

  const pageData = useSelector((state: RootState) => state.pageData);
  

  // 模板ID
  const moduleId = useSelector(
    (state: RootState) => state.activationItem.moduleId,
  );

  const activationItem = useSelector(
    (state: RootState) => state.activationItem,
  );

  const updateActivationItem =
    useDispatch<Dispatch>().activationItem.updateActivationItem;
  const updateAppData = useDispatch<Dispatch>().appData.updateAppData;
  const removeActivationItem =
    useDispatch<Dispatch>().activationItem.removeActivationItem;

  // 样式与设置菜单面板
  const [mainTag, setMainTag] = useState('config');
  const onSelectMainTag = useCallback((e) => {
    setMainTag(e.key);
  }, []);

  const sendMessage = usePostMessage(() => {});
  // 收发处理,子窗口onload时向子窗口发送信息, 通知当前正处于编辑模式下,

  // 重置当前被选择项
  const onChangeSelect = useCallback(
    (e) => {
      if (activationItem.moduleId === e) return;
      for (let index = 0; index < appData.length; index++) {
        const element = appData[index];
        if (element.moduleId === e) {
          const value = { ...element };
          updateActivationItem(value);
          const win = (
            document.getElementById('wrapiframe') as HTMLIFrameElement
          ).contentWindow;
          if (win) {
            sendMessage({ tag: 'id', value: element.moduleId }, win);
          }
          break;
        }
      }
    },
    [activationItem.moduleId, appData, sendMessage, updateActivationItem],
  );

  // =====================================模块删除=======================================//
  const [isDeleteComp, setIsDeleteComp] = useState(false);

  const delModule = useCallback(() => {
    const optAppData = produce(reject([...appData], { moduleId }), undefined, createDesc('删除',`组件${activationItem.moduleName}`) );
    const win = (document.getElementById('wrapiframe') as HTMLIFrameElement)
      .contentWindow;
    updateAppData(optAppData);
    removeActivationItem();
    sendMessage(
      {
        tag: 'updateAppData',
        value: optAppData,
      },
      win,
    );
    sendMessage(
      {
        tag: 'removeActivationItem',
        value: undefined,
      },
      win,
    );
    setIsDeleteComp(false);
  }, [activationItem.moduleName, appData, moduleId, removeActivationItem, sendMessage, updateAppData]);

  const confirmModal = useCallback(() => {
    if (isDeleteComp) return;
    setIsDeleteComp(true);
    confirm({
      content: (
        <div>
          <h3>确定删除</h3>
          <br />
          模块名称:{activationItem.moduleName}
          <br />
          Id: {activationItem.moduleId}
          <br />
          <span className={s.warn}>
            当前模块将被移除,请手动清除其他模块事件中引用的当前模块方法。
          </span>
        </div>
      ),
      okText: '确定',
      cancelText: '取消',
      onCancel: () => setIsDeleteComp(false),
      onOk: delModule,
    });
  }, [
    isDeleteComp,
    activationItem.moduleName,
    activationItem.moduleId,
    delModule,
  ]);

  // 模块删除快捷键
  // key deletd
  useKeyDown((event) => {
    event.preventDefault();
    confirmModal();
  }, 'Delete');

  // =====================================模块复制=======================================//
  // copyData
  const beforCopyModule = useCallback(() => {
    setNewModalName(`${activationItem.moduleName} 拷贝`);
    setShowCopyedModal(true);
  }, [activationItem.moduleName]);

  // 初始化或,取消复制弹窗
  const initCopyModule = useCallback(() => {
    setShowCopyedModal(false);
    setNewModalName(undefined);
  }, []);

  // 方法,复制当前选中的组件
  const copyModule = useCallback(() => {
    // 准备创建
    const oprateActivationItem = cloneDeep(activationItem);
    const moduleId = nanoid();
    oprateActivationItem.moduleId = moduleId;
    oprateActivationItem.layout!.i = moduleId;
    oprateActivationItem.moduleName =
      newModalName || `${activationItem.moduleName} 拷贝`;

    // 模块垂直位置
    let y = 0;
    // 行高
    let rowHeight = pageData.rowHeight || GRID_DEFAULT_ROWHEIGHT;
    if (typeof rowHeight === 'string') rowHeight = getResult(rowHeight);
    // 滚动条高度
    const iframeNode = document.getElementById(
      'wrapiframe',
    ) as HTMLIFrameElement | null;
    const scrollTop =
      iframeNode?.contentDocument?.documentElement.scrollTop || 0;
    // 通过滚动条定位计算新增元素应该在当前视窗内
    y = (scrollTop + 100) / (rowHeight as number);
    
    oprateActivationItem.layout!.y = y;
    // 复制模块,更新当前模块到全局并设为当前被选择模块
    updateAppData(produce([...appData, oprateActivationItem], undefined, createDesc('复制',`新组件${oprateActivationItem.moduleName}`)));
    updateActivationItem(oprateActivationItem);
    // 初始化复制窗口
    initCopyModule();
  }, [activationItem, appData, newModalName, pageData.rowHeight, updateAppData, updateActivationItem, initCopyModule]);

  // 处理键盘事件
  // 模拟模块复制
  // useKeyDown(
  //   () => {
  //     beforCopyModule();
  //   },
  //   'c',
  //   'ctrlKey',
  // );

  // // 确认复制模块
  useKeyDown((event) => {
    if (showCopyedModal) {
      event.preventDefault();
      copyModule();
    }
  }, 'Enter');

  const CodeEditor = useMemo(
    () => lazy(() => import(`../CodeEditor/index`)),
    [],
  );

  return (
    <>
      <div className={s.headtab}>
        <div className={s.moduleselect}>
          <Select
            onChange={onChangeSelect}
            className={s.select}
            value={moduleId}
            showSearch
            placeholder="请选择编辑模块"
            optionFilterProp="children"
            filterOption={
              (input, option) => {
                const str = option?.children?.join('').toLowerCase();
                if (str?.indexOf(input) !== -1) {
                  return true;
                }
                return false;
              }
              // option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
            }
          >
            {appData.map((item) => (
              <Select.Option value={item.moduleId} key={item.moduleId}>
                {item.moduleName || '(未标题)'}-{item.type}
              </Select.Option>
            ))}
          </Select>
        </div>

        <Menu
          onClick={() => setMainTag('config')}
          onSelect={onSelectMainTag}
          selectedKeys={[mainTag]}
          mode="horizontal"
          className={s.contentmenu}
        >
          <Menu.Item key="config" icon={<ToolOutlined />}>
            设置
          </Menu.Item>
          <Menu.Item key="style" icon={<FormatPainterOutlined />}>
            样式
          </Menu.Item>
          <Menu.Item key="code" icon={<CodeOutlined />}>
            code
          </Menu.Item>
        </Menu>
        <div className={s.info}>
          <Tooltip placement="bottomRight" title="查看全局发布变量">
            <ClusterOutlined
              className={s.delete}
              onClick={() => setShowRunningTimes(true)}
            />
          </Tooltip>
        </div>
        <div className={s.info}>
          <Tooltip
            placement="bottomRight"
            title={
              <div className={s.tips}>
                <h3>复制为新模块</h3>
                当前模块信息
                <br />
                模块:{activationItem.moduleName}
                <br />
                类型:{activationItem.type}
                <br />
                Id:{activationItem.moduleId}
              </div>
            }
          >
            <CopyOutlined alt="复制模块" onClick={beforCopyModule} />
          </Tooltip>
        </div>
        <div>
          <Tooltip
            placement="bottomRight"
            title={`删除 ${
              activationItem.moduleName || activationItem.moduleId
            }`}
          >
            <DeleteOutlined className={s.delete} onClick={confirmModal} />
          </Tooltip>
        </div>
      </div>
      <div
        className={s.root}
        style={{ height: `${window.innerHeight - 80}px` }}
      >
        <div
          className={s.controllerwrap}
          style={{ display: mainTag === 'style' ? 'block' : 'none' }}
        >
          <StyleController />
        </div>
        <div
          className={s.controllerwrap}
          style={{ display: mainTag === 'config' ? 'block' : 'none' }}
        >
          <ConfigurationController />
        </div>
        <div
          className={s.controllerwrap}
          style={{ display: mainTag === 'code' ? 'block' : 'none' }}
        >
          <CodeEditor />
        </div>
      </div>
      <Modal
        title={`复制${activationItem?.moduleName || ''}(${
          activationItem?.type || ''
        })模块`}
        visible={!!showCopyedModal}
        footer={null}
        onCancel={initCopyModule}
      >
        <Row gutter={[16, 16]}>
          <Col span={3}></Col>
          <Col span={15}>
            <Input
              type="text"
              value={newModalName as any}
              onChange={(e) => setNewModalName(e.target.value || undefined)}
              placeholder={`请输入${activationItem?.type || ''}模块的别名`}
            />
          </Col>
          <Col span={6}>
            <Button type="primary" onClick={copyModule}>
              确定
            </Button>
          </Col>
        </Row>
        <br />
      </Modal>
      <RunningTimesModal
        visible={showRunningTimes}
        data={runningTimes}
        onCancel={() => setShowRunningTimes(false)}
      />
    </>
  );
}
Example #5
Source File: PageSetting.tsx    From yugong with MIT License 4 votes vote down vote up
Pagesetting: React.FC<Props> = () => {
  const appData = useSelector((state: RootState) => state.appData);
  const pageData = useSelector((state: RootState) => state.pageData);
  const updatePage = useDispatch<Dispatch>().pageData.updatePage;
  const [showRunningTimes, setShowRunningTimes] = useState(false);
  const runningTimes = useSelector((state: RootState) => state.runningTimes);
  // const ref = useRef();


  // 监听App页面数据,同步到编辑器数据
  const sendMessage = usePostMessage((data) => {
    const { tag, value } = data;
    if (tag === "updatePage") {
      updatePage(value);
    }
  });

  // 本地存储编辑数据
  const [, setPagedataLocalStorage] = useLocalStorage("pageData", null);

  const handleUpdatePage = useCallback(
    (pageData) => {
      // 1、更新redux数据
      updatePage(pageData);
      // 2、将页面数据本地缓存
      setPagedataLocalStorage(pageData);
      // 3、向下游发送数据
      const win = (document.getElementById("wrapiframe") as HTMLIFrameElement)
        .contentWindow;
      if (win) {
        sendMessage(
          {
            tag: "updatePage",
            value: pageData,
          },
          win
        );
      }
    },
    [sendMessage, setPagedataLocalStorage, updatePage]
  );

  const onChangeEnv = useCallback(
    (envinfo, data) => {
      const optPageData = produce(pageData, draft => {
        if (envinfo.name === "mount") {
          draft.mountEnvents = data;
        }
        if (envinfo.name === "unmount") {
          draft.unmountEnvents = data;
        }
      }, createDesc('页面', `修改${envinfo.name}事件`));
      
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChange = useCallback(
    (
      result: any,
      type: StyleType
    ) => {
      if (type === 'backgroundGroup') {
        const optPageData = produce(pageData, draft => {
          draft.style = {
            backgroundGroup: result
          }
        }, createDesc('页面', '修改背景样式'));
        handleUpdatePage(optPageData);
      }
    },
    [handleUpdatePage, pageData]
  );

  const onChangeUnit = useCallback(
    (type: "unit" | "toUnit") => (e: any) => {
      const optPageData = produce(pageData, draft => {
        if (type === "unit") {
          draft.unit = e;
        }
        if (type === "toUnit") {
          draft.toUnit = e;
        }
  
        if (draft.unit !== "rem" && draft.toUnit !== "rem") {
          delete draft.UIWidth;
          delete draft.baseFont;
        } else {
          draft.UIWidth = undefined;
          draft.baseFont = undefined;
        }
      }, createDesc('页面', '修改全局单位'));

      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChangeStatisticsId = useCallback(
    (e) => {
      const optPageData = produce(pageData, draft => {
        draft.statisticsId = e.target.value;
      }, createDesc('页面', '设置百度统计'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChangeUIWidth = useCallback(
    (e) => {
      const optPageData = produce(pageData, draft => {
        draft.UIWidth = e;
      }, createDesc('页面', '设置UI宽度'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChangeBaseFont = useCallback(
    (e) => {
      const optPageData = produce(pageData, draft => {
        draft.baseFont = e;
      }, createDesc('页面', '设置UI基准字体'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChangeApi = useCallback(
    (data) => {
      const optPageData = produce(pageData, draft => {
        draft.onLoadApi = data;
      }, createDesc('页面', '修改Api'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onRemoveApi = useCallback(
    (_, data: ApiType) => {
      const optPageData = produce(pageData, draft => {
        draft.onLoadApi = reject(draft.onLoadApi, {
          apiId: data.apiId,
        });
      }, createDesc('页面', '删除Api'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onPlus = useCallback(() => {
    const optPageData = produce(pageData, draft => {
      draft.onLoadApi?.push({
        name: `ApiBeforMounted`,
        apiId: nanoid(),
      });
    }, createDesc('页面', '新增Api'));
    handleUpdatePage(optPageData);
  }, [handleUpdatePage, pageData]);

  const onChangeRowHeight = useCallback(
    (e) => {
      const optPageData = produce(pageData, draft => {
        draft.rowHeight = e.target.value;
      }, createDesc('页面', '修改删格行高'));
      
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChangeCols = useCallback(
    (e) => {
      const optPageData = produce(pageData, draft => {
        draft.cols = e.target.value;
      }, createDesc('页面', '修改删格列宽'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChangeSpace = useCallback(
    (e) => {
      const optPageData = produce(pageData, draft => {
        draft.space = e.target.value;
      }, createDesc('页面', '修改删格间距'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onChangePageTitle = useCallback(
    (e) => {
      const optPageData = produce(pageData, draft => {
        draft.pageTitle = e.target.value;
      }, createDesc('页面', '修改标题'));
      handleUpdatePage(optPageData);
    },
    [handleUpdatePage, pageData]
  );

  const onShowRunningTimes = useCallback((e) => {
    e.stopPropagation();
    setShowRunningTimes(true);
  }, []);

  const getDefaultData = useCallback(
    (type: StyleType) => pageData.style?.backgroundGroup || {},
    [pageData.style?.backgroundGroup]
  );

  return (
    <>
      <Collapse accordion bordered={false} defaultActiveKey="baseset">
        <Panel
          header="基本信息"
          key="baseset"
          extra={
            <Tooltip title="查看全局发布变量">
              <ClusterOutlined onClick={onShowRunningTimes} />
            </Tooltip>
          }
        >
          <Row gutter={4} className={s.row}>
            <Col className={s.label} span={4}>
              页面名称:
            </Col>
            <Col span={19}>
              <Input
                placeholder="请输入页面名称"
                value={pageData.pageTitle}
                onChange={onChangePageTitle}
                className={s.num}
              />
            </Col>
            <Col span={1} />
          </Row>

          <Row gutter={4} className={s.row}>
            <Col className={s.label} span={4}>
              栅格列数:
            </Col>
            <Col span={7}>
              <Input
                value={pageData.cols}
                onChange={onChangeCols}
                className={s.num}
                placeholder="输入栅格列数"
              />
            </Col>
            <Col className={s.info} span={1}>
              <Tooltip title={<div>屏幕栅格列数&gt;0 (默认12列)</div>}>
                <InfoCircleOutlined />
              </Tooltip>
            </Col>
            <Col className={s.label} span={4}>
              栅格行高:
            </Col>
            <Col span={7}>
              <Input
                value={pageData.rowHeight}
                onChange={onChangeRowHeight}
                placeholder="输入栅格行高"
                className={s.num}
              />
            </Col>
            <Col className={s.info} span={1}>
              <Tooltip
                title={
                  <div>屏幕栅格行高&gt;0(默认20px),可使用运行时window计算高度</div>
                }
              >
                <InfoCircleOutlined />
              </Tooltip>
            </Col>
          </Row>
          <Row gutter={4} className={s.row}>
            <Col className={s.label} span={4}>
              栅格间距:
            </Col>
            <Col span={7}>
              <Input
                value={pageData.space}
                onChange={onChangeSpace}
                className={s.num}
                placeholder="输入栅格间距"
              />
            </Col>
            <Col className={s.info} span={1}>
              <Tooltip title={<div>栅格间距(默认0px)</div>}>
                <InfoCircleOutlined />
              </Tooltip>
            </Col>
          </Row>
          <Row gutter={4} className={s.row}>
            <Col className={s.label} span={4}>
              基准单位:
            </Col>
            <Col span={19}>
              <Select
                placeholder="请选择"
                className={s.select}
                value={pageData.toUnit}
                onChange={onChangeUnit("toUnit")}
              >
                {units.map((item) => (
                  <Option key={item} value={item}>
                    {item}
                  </Option>
                ))}
              </Select>
            </Col>
            <Col className={s.info} span={1}>
              <Tooltip title={<div>页面的基准单位,用于单位换算;设置为rem时需要设置UI宽度和基准像素</div>}>
                <InfoCircleOutlined />
              </Tooltip>
            </Col>
          </Row>

          {pageData.toUnit === "rem" || pageData.unit === "rem" ? (
            <Row gutter={4} className={s.row}>
              <Col className={s.label} span={4}>
                UI宽度:
              </Col>
              <Col span={7}>
                <InputNumber
                  value={pageData.UIWidth}
                  onChange={onChangeUIWidth}
                  placeholder="px"
                  className={s.num}
                />
              </Col>
              <Col className={s.info} span={1}>
                <Tooltip title={<div>UI设计的屏幕宽度(px)</div>}>
                  <InfoCircleOutlined />
                </Tooltip>
              </Col>
              <Col className={s.label} span={4}>
                基准像素:
              </Col>
              <Col span={7}>
                <InputNumber
                  min={5}
                  value={pageData.baseFont}
                  onChange={onChangeBaseFont}
                  placeholder="px"
                  className={s.num}
                />
              </Col>
              <Col className={s.info} span={1}>
                <Tooltip title={<div>UI设计下,1rem=1基准像素</div>}>
                  <InfoCircleOutlined />
                </Tooltip>
              </Col>
            </Row>
          ) : null}
          <StyleContext.Provider
            value={{
              onChange,
              getDefaultData
            }}
          >
          <Row gutter={4} className={s.row}>
            <Col span={24}>
              <div className={s.bg}>
                <BackgroundGroup />
              </div>
            </Col>
            <Col span={1} />
          </Row>
          </StyleContext.Provider>
        </Panel>
        <Panel header="初始化Api" key="pagemount">
          <div className={s.apiwrap}>
            <h4 className={s.apititle}>
              <Button size="small" icon={<PlusOutlined onClick={onPlus} />} />
            </h4>
            <ApiConfig
              sortable
              onRemove={onRemoveApi}
              apiData={pageData.onLoadApi}
              defaultApiData={cloneDeep(pageData.onLoadApi)}
              onChange={onChangeApi}
            />
          </div>
        </Panel>
        <Panel header="页面事件" key="pageevent">
          <div className={s.events}>
            <>
              {Output.exposeEvents?.map((item, index) => (
                <EventGroup
                  key={index}
                  eventName={item.name}
                  value={
                    item.name === "mount"
                      ? pageData.mountEnvents || []
                      : pageData.unmountEnvents || []
                  }
                  curentEventInfomation={item}
                  onPlay={() => {}}
                  onChange={onChangeEnv}
                />
              ))}
            </>
          </div>
        </Panel>
        <Panel header="百度统计" key="pagecounter">
          <Row className={s.row}>
            <Col className={s.label} span={4}>
              统计Id:
            </Col>
            <Col span={20}>
              <Input
                placeholder="请在百度账号下创建站点,获取统计Id"
                className={s.num}
                value={pageData.statisticsId}
                onChange={onChangeStatisticsId}
              />
            </Col>
          </Row>
        </Panel>
        <Panel header="数据视图" key="pagedata">
          <ReactJson src={{pageData, appData}} collapsed={1} name="project" />
        </Panel>
      </Collapse>
      <RunningTimesModal
        visible={showRunningTimes}
        data={runningTimes}
        onCancel={() => setShowRunningTimes(false)}
      />
    </>
  );
}