@ant-design/icons#ToolOutlined TypeScript Examples

The following examples show how to use @ant-design/icons#ToolOutlined. 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: CurrentPlan.tsx    From posthog-foss with MIT License 5 votes vote down vote up
export function CurrentPlan({ plan }: { plan: PlanInterface }): JSX.Element {
    const { billing } = useValues(billingLogic)

    return (
        <>
            <div className="space-top" />
            {billing?.should_setup_billing ? (
                <Alert
                    type="warning"
                    message={
                        <>
                            Your plan is <b>currently inactive</b> as you haven't finished setting up your billing
                            information.
                        </>
                    }
                    action={
                        billing.subscription_url && (
                            <Button href={billing.subscription_url} icon={<ToolOutlined />}>
                                Finish setup
                            </Button>
                        )
                    }
                    showIcon
                    icon={<WarningOutlined />}
                />
            ) : (
                <Card title="Organization billing plan">
                    <div style={{ display: 'flex', alignItems: 'center' }}>
                        <div>
                            <img src={plan.image_url || defaultImg} alt="" height={100} width={100} />
                        </div>
                        <div style={{ flexGrow: 1, paddingLeft: 16 }}>
                            <h3 className="l3" style={{ marginBottom: 8 }}>
                                {plan.name}
                            </h3>
                            <Link target="_blank" to={`https://posthog.com/pricing#plan-${plan.key}?${UTM_TAGS}`}>
                                More plan details <IconOpenInNew />
                            </Link>
                            <div style={{ marginTop: 4 }}>{plan.price_string}</div>
                            <div className="text-muted mt">
                                Click on <b>manage subscription</b> to cancel your billing agreement,{' '}
                                <b>update your card</b> or other billing information,
                            </div>
                        </div>
                        <div>
                            <Button type="primary" href="/billing/manage" icon={<ToolOutlined />}>
                                Manage subscription
                            </Button>
                            <div className="text-muted text-center">Get past invoices too</div>
                        </div>
                    </div>
                </Card>
            )}
        </>
    )
}
Example #2
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 #3
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 #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: YakLocalProcess.tsx    From yakit with GNU Affero General Public License v3.0 4 votes vote down vote up
YakLocalProcess: React.FC<YakLocalProcessProp> = (props) => {
    const [process, setProcess] = useState<yakProcess[]>([]);
    const [shouldAutoStart, setShouldAutoStart] = useState(false);
    const [installed, setInstalled] = useState(false);
    const [psIng, setPsIng] = useState(false);
    const [notified, setNotified] = useState(false);

    // 检查是不是 windows
    const [isWindows, setIsWindows] = useState(false);
    const notWindows = !isWindows;

    // 检查默认数据库是不是又问题?
    const [databaseError, setDatabaseError] = useState("");

    let databaseErrorVerbose: React.ReactNode = databaseError;
    switch (databaseError) {
        case "not allow to write":
            databaseErrorVerbose = "数据库无权限写入"
            break
        case "no such file or directory":
            databaseErrorVerbose = <div>
                <Tooltip title={"直接启动引擎即可"}>
                    无本地数据库
                </Tooltip>
            </div>
    }

    const update = useMemoizedFn(() => {
        let noProcess = true;
        ipcRenderer.invoke("is-yak-engine-installed").then(ok => {
            setInstalled(ok)
        });

        if (psIng) {
            return
        }
        setPsIng(true)
        ipcRenderer.invoke("ps-yak-grpc").then((i: yakProcess[]) => {
            setNotified(false)
            setProcess(i.map((element: yakProcess) => {
                noProcess = false;
                return {
                    port: element.port,
                    pid: element.pid,
                    cmd: element.cmd,
                    origin: element.origin,
                }
            }).filter(i => true))
        }).catch(e => {
            if (!notified) {
                failed(`PS | GREP yak failed ${e}`)
                setNotified(true)
            }
        }).finally(() => {
            if (noProcess) {
                setShouldAutoStart(true)
            }
            setPsIng(false)
        })

        ipcRenderer.invoke("is-windows").then((i: boolean) => {
            setIsWindows(i)
        })

        ipcRenderer.invoke("check-local-database").then(e => {
            setDatabaseError(e)
        })
    })

    useEffect(() => {
        update()

        let id = setInterval(update, 1000);
        return () => {
            clearInterval(id);
        }
    }, [])

    useEffect(() => {
        props.onProcess && props.onProcess([...process])
    }, [process])

    const promptInstallYakEngine = () => {
        let m = showModal({
            keyboard: false,
            title: "引擎安装与升级",
            width: "50%",
            content: <>
                <YakUpgrade onFinished={() => {
                    m.destroy()
                }}/>
            </>
        })
    }

    const startYakGRPCServer = (sudo: boolean) => {
        ipcRenderer.invoke("start-local-yak-grpc-server", {
            sudo,
        }).then(() => {
            info("启动 yak grpc 进程成功")
        }).catch((e: Error) => {
            const flag = `${e.message}`;
            if (flag.includes(`uninstall yak engine`)) {
                failed("未安装 Yak 引擎")
                promptInstallYakEngine()
                return
            }
            failed(`${e.message}`)
        }).finally(() => {
            update()
        })
    }

    const databaseMeetError = notWindows && installed && databaseError !== "";

    return <>
        <Form.Item label={" "} colon={false}>
            <div style={{width: "100%"}}>
                <Row>
                    <Col span={5}/>
                    <Col span={14}>
                        <Card
                            title={<Space>
                                <div>本地 Yak 进程管理</div>
                                {!installed && <Tag color={"red"}>引擎未安装</Tag>}
                                {notWindows && installed && databaseError !== "" &&
                                <Space size={0}>
                                    <Tag color={"red"}>{databaseErrorVerbose}</Tag>
                                    <Popconfirm
                                        title={"尝试修复数据库写权限(可能要求 ROOT 权限)"}
                                        onConfirm={e => {
                                            ipcRenderer.invoke("fix-local-database").then(e => {
                                                info("修复成功")
                                            }).catch(e => {
                                                failed(`修复数据库权限错误:${e}`)
                                            })
                                        }}
                                    >
                                        <Button type={"link"} size={"small"}
                                                icon={<>
                                                    <ToolOutlined/>
                                                </>}/>
                                    </Popconfirm>
                                </Space>}
                            </Space>}
                            size={"small"}
                            extra={
                                process.length > 0 && <Space>
                                    <Button size={"small"} onClick={() => {
                                        startYakGRPCServer(false)
                                    }} disabled={databaseMeetError}>普通权限启动</Button>
                                    <Popconfirm title={"以管理员权限启动"} onConfirm={() => {
                                        startYakGRPCServer(true)
                                    }} disabled={databaseMeetError}>
                                        <Button
                                            size={"small"} type={"primary"}
                                            disabled={databaseMeetError}
                                        >管理员(sudo)启动</Button>
                                    </Popconfirm>
                                </Space>
                            }
                        >
                            {process.length > 0 ? <List
                                dataSource={process}
                                renderItem={(i: yakProcess) => {
                                    return <List.Item
                                        key={i.pid}
                                    >
                                        <Card
                                            size={"small"} style={{width: "100%"}} bordered={false} hoverable={true}
                                        >
                                            <Row>
                                                <Col span={12} style={{textAlign: "left"}}>
                                                    <Space>
                                                        <Tag color={"green"}>PID: {i.pid}</Tag>
                                                        <CopyableField
                                                            text={`yak grpc --port ${i.port === 0 ? "获取中" : i.port}`}
                                                            width={300}
                                                        />
                                                    </Space>
                                                </Col>
                                                <Col span={12}>
                                                    <div style={{width: "100%", textAlign: "right"}}>
                                                        <Space>
                                                            <Button
                                                                size={"small"} type={"primary"}
                                                                disabled={!props.onConnected}
                                                                loading={i.port <= 0}
                                                                onClick={() => {
                                                                    props.onConnected && props.onConnected(
                                                                        i.port, "localhost")
                                                                }}
                                                            >连接引擎</Button>
                                                            <Popconfirm
                                                                title={"将会强制关闭该进程"}
                                                                onConfirm={() => {
                                                                    ipcRenderer.invoke("kill-yak-grpc", i.pid).catch((e: any) => {

                                                                    }).finally(update)
                                                                }}
                                                            >
                                                                <Button
                                                                    size={"small"} danger={true}
                                                                >关闭引擎</Button>
                                                            </Popconfirm>
                                                            <Button
                                                                type={"link"} size={"small"}
                                                                onClick={() => {
                                                                    showModal({
                                                                        title: "YakProcess 详情",
                                                                        content: <>
                                                                            <ReactJson src={i}/>
                                                                        </>
                                                                    })
                                                                }}
                                                            >
                                                                details
                                                            </Button>
                                                        </Space>
                                                    </div>
                                                </Col>
                                            </Row>
                                        </Card>
                                    </List.Item>
                                }}
                            >

                            </List> : <Space>
                                <Button onClick={() => {
                                    startYakGRPCServer(false)
                                }} disabled={databaseMeetError}>普通权限启动</Button>
                                <Popconfirm title={"以管理员权限启动,解锁全部 yak 引擎功能"} onConfirm={() => {
                                    startYakGRPCServer(true)
                                }} disabled={databaseMeetError}>
                                    <Button disabled={databaseMeetError} type={"primary"}>管理员(sudo)启动</Button>
                                </Popconfirm>
                            </Space>}
                        </Card>
                    </Col>
                    <Col span={5}/>
                </Row>
            </div>

        </Form.Item>
    </>
}