@ant-design/icons#RollbackOutlined TypeScript Examples
The following examples show how to use
@ant-design/icons#RollbackOutlined.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx From web-pdm with Apache License 2.0 | 6 votes |
IconRenders = {
undo: <RollbackOutlined />,
redo: <RollbackOutlined style={{ transform: 'scaleX(-1)' }} />,
min: <ZoomOutOutlined />,
max: <ZoomInOutlined />,
full: <BorderOutlined />,
miniMap: <PictureFilled />,
miniMapNo: <PictureOutlined />,
dagreLayout: <PartitionOutlined />,
relationLayout: <UngroupOutlined />,
reload: <ReloadOutlined />,
image: <DownloadOutlined />,
darkness: <SnippetsFilled />,
light: <SnippetsOutlined />,
colorClose: <BgColorsOutlined />,
colorOpen: <BgColorsOutlined />
}
Example #2
Source File: out.tsx From web-pdm with Apache License 2.0 | 6 votes |
IconRenders = {
undo: <RollbackOutlined />,
redo: <RollbackOutlined style={{ transform: 'scaleX(-1)' }} />,
min: <ZoomOutOutlined />,
max: <ZoomInOutlined />,
full: <BorderOutlined />,
miniMap: <PictureFilled />,
miniMapNo: <PictureOutlined />,
dagreLayout: <PartitionOutlined />,
relationLayout: <UngroupOutlined />,
reload: <ReloadOutlined />,
image: <DownloadOutlined />,
darkness: <SnippetsFilled />,
light: <SnippetsOutlined />,
colorClose: <BgColorsOutlined />,
colorOpen: <BgColorsOutlined />
}
Example #3
Source File: add.tsx From fe-v5 with Apache License 2.0 | 5 votes |
Add = (props: any) => {
const history = useHistory();
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const { t } = useTranslation();
const handleSubmit = (values: any) => {
request(`${api.tasktpls(curBusiItem.id)}`, {
method: 'POST',
body: JSON.stringify(values),
}).then(() => {
message.success(t('msg.create.success'));
props.history.push({
pathname: `/job-tpls`,
});
});
};
return (
<PageLayout hideCluster title={
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tpls')} />
自愈脚本
</>
}>
<div style={{ padding: 10 }}>
<Card
title="创建自愈脚本"
>
<TplForm
onSubmit={handleSubmit}
footer={
<div>
<Button type="primary" htmlType="submit" style={{ marginRight: 8 }}>
{t('form.submit')}
</Button>
</div>
}
/>
</Card>
</div>
</PageLayout>
)
}
Example #4
Source File: clone.tsx From fe-v5 with Apache License 2.0 | 5 votes |
Add = (props: any) => {
const history = useHistory();
const id = _.get(props, 'match.params.id');
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const [data, setData] = useState({} as Tpl);
const handleSubmit = (values: any) => {
request(`${api.tasktpls(curBusiItem.id)}`, {
method: 'POST',
body: JSON.stringify(values),
}).then(() => {
message.success(t('msg.create.success'));
props.history.push({
pathname: `/job-tpls`,
});
});
};
useEffect(() => {
if (id) {
setLoading(true);
request(`${api.tasktpl(curBusiItem.id)}/${id}`).then((data) => {
const { dat } = data;
setData({
...dat.tpl,
hosts: dat.hosts,
grp: dat.grp,
});
}).finally(() => {
setLoading(false);
});
}
}, [id, curBusiItem.id]);
return (
<PageLayout hideCluster title={
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tpls')} />
自愈脚本
</>
}>
<div style={{ padding: 10 }}>
<Card
title="克隆自愈脚本"
>
<Spin spinning={loading}>
{
data.title ?
<TplForm
onSubmit={handleSubmit}
initialValues={data}
footer={
<div>
<Button type="primary" htmlType="submit" style={{ marginRight: 8 }}>
{t('form.submit')}
</Button>
</div>
}
/> : null
}
</Spin>
</Card>
</div>
</PageLayout>
)
}
Example #5
Source File: modify.tsx From fe-v5 with Apache License 2.0 | 5 votes |
Modify = (props: any) => {
const history = useHistory();
const id = _.get(props, 'match.params.id');
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const [data, setData] = useState<any>({});
const handleSubmit = (values: any) => {
request(`${api.tasktpl(curBusiItem.id)}/${id}`, {
method: 'PUT',
body: JSON.stringify(values),
}).then(() => {
message.success(t('msg.modify.success'));
props.history.push({
pathname: `/job-tpls`,
});
});
};
useEffect(() => {
if (id) {
setLoading(true);
request(`${api.tasktpl(curBusiItem.id)}/${id}`).then((data) => {
const { dat } = data;
setData({
...dat.tpl,
hosts: dat.hosts,
grp: dat.grp,
});
}).finally(() => {
setLoading(false);
});
}
}, [id, curBusiItem.id]);
return (
<PageLayout hideCluster title={
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tpls')} />
自愈脚本
</>
}>
<div style={{ padding: 10 }}>
<Card
title="修改自愈脚本"
>
<Spin spinning={loading}>
{
data.title ?
<TplForm
onSubmit={handleSubmit}
initialValues={data}
footer={
<Button type="primary" htmlType="submit">
{t('form.submit')}
</Button>
}
/> : null
}
</Spin>
</Card>
</div>
</PageLayout>
)
}
Example #6
Source File: PluginDrawer.tsx From posthog-foss with MIT License | 4 votes |
export function PluginDrawer(): JSX.Element {
const { user } = useValues(userLogic)
const { preflight } = useValues(preflightLogic)
const { editingPlugin, loading, editingSource, editingPluginInitialChanges } = useValues(pluginsLogic)
const { editPlugin, savePluginConfig, uninstallPlugin, setEditingSource, generateApiKeysIfNeeded, patchPlugin } =
useActions(pluginsLogic)
const [form] = Form.useForm()
const [invisibleFields, setInvisibleFields] = useState<string[]>([])
const [requiredFields, setRequiredFields] = useState<string[]>([])
useEffect(() => {
if (editingPlugin) {
form.setFieldsValue({
...(editingPlugin.pluginConfig.config || defaultConfigForPlugin(editingPlugin)),
__enabled: editingPlugin.pluginConfig.enabled,
...editingPluginInitialChanges,
})
generateApiKeysIfNeeded(form)
} else {
form.resetFields()
}
updateInvisibleAndRequiredFields()
}, [editingPlugin?.id, editingPlugin?.config_schema])
const updateInvisibleAndRequiredFields = (): void => {
determineAndSetInvisibleFields()
determineAndSetRequiredFields()
}
const determineAndSetInvisibleFields = (): void => {
const fieldsToSetAsInvisible = []
for (const field of Object.values(getConfigSchemaArray(editingPlugin?.config_schema || {}))) {
if (!field.visible_if || !field.key) {
continue
}
const shouldBeVisible = field.visible_if.every(
([targetFieldName, targetFieldValue]: Array<string | undefined>) =>
doFieldRequirementsMatch(form, targetFieldName, targetFieldValue)
)
if (!shouldBeVisible) {
fieldsToSetAsInvisible.push(field.key)
}
}
setInvisibleFields(fieldsToSetAsInvisible)
}
const determineAndSetRequiredFields = (): void => {
const fieldsToSetAsRequired = []
for (const field of Object.values(getConfigSchemaArray(editingPlugin?.config_schema || {}))) {
if (!field.required_if || !Array.isArray(field.required_if) || !field.key) {
continue
}
const shouldBeRequired = field.required_if.every(
([targetFieldName, targetFieldValue]: Array<string | undefined>) =>
doFieldRequirementsMatch(form, targetFieldName, targetFieldValue)
)
if (shouldBeRequired) {
fieldsToSetAsRequired.push(field.key)
}
}
setRequiredFields(fieldsToSetAsRequired)
}
const isValidChoiceConfig = (fieldConfig: PluginConfigChoice): boolean => {
return (
Array.isArray(fieldConfig.choices) &&
!!fieldConfig.choices.length &&
!fieldConfig.choices.find((c) => typeof c !== 'string') &&
!fieldConfig.secret
)
}
const isValidField = (fieldConfig: PluginConfigSchema): boolean =>
fieldConfig.type !== 'choice' || isValidChoiceConfig(fieldConfig)
return (
<>
<Drawer
forceRender={true}
visible={!!editingPlugin}
onClose={() => editPlugin(null)}
width="min(90vw, 500px)"
title={editingPlugin?.name}
data-attr="plugin-drawer"
footer={
<div style={{ display: 'flex' }}>
<Space style={{ flexGrow: 1 }}>
{editingPlugin &&
!editingPlugin.is_global &&
canInstallPlugins(user?.organization, editingPlugin.organization_id) && (
<Popconfirm
placement="topLeft"
title="Are you sure you wish to uninstall this plugin completely?"
onConfirm={() => uninstallPlugin(editingPlugin.name)}
okText="Uninstall"
cancelText="Cancel"
className="plugins-popconfirm"
>
<Button
style={{ color: 'var(--danger)', padding: 4 }}
type="text"
icon={<DeleteOutlined />}
data-attr="plugin-uninstall"
>
Uninstall
</Button>
</Popconfirm>
)}
{preflight?.cloud &&
editingPlugin &&
canGloballyManagePlugins(user?.organization) &&
(editingPlugin.is_global ? (
<Tooltip
title={
<>
This plugin can currently be used by other organizations in this
instance of PostHog. This action will <b>disable and hide it</b> for all
organizations other than yours.
</>
}
>
<Button
type="text"
icon={<RollbackOutlined />}
onClick={() => patchPlugin(editingPlugin.id, { is_global: false })}
style={{ padding: 4 }}
>
Make local
</Button>
</Tooltip>
) : (
<Tooltip
title={
<>
This action will mark this plugin as installed for{' '}
<b>all organizations</b> in this instance of PostHog.
</>
}
>
<Button
type="text"
icon={<GlobalOutlined />}
onClick={() => patchPlugin(editingPlugin.id, { is_global: true })}
style={{ padding: 4 }}
>
Make global
</Button>
</Tooltip>
))}
</Space>
<Space>
<Button onClick={() => editPlugin(null)} data-attr="plugin-drawer-cancel">
Cancel
</Button>
<Button
type="primary"
loading={loading}
onClick={form.submit}
data-attr="plugin-drawer-save"
>
Save
</Button>
</Space>
</div>
}
>
<Form form={form} layout="vertical" name="basic" onFinish={savePluginConfig}>
{editingPlugin ? (
<div>
<div style={{ display: 'flex', marginBottom: 16 }}>
<PluginImage
pluginType={editingPlugin.plugin_type}
url={editingPlugin.url}
size="large"
/>
<div style={{ flexGrow: 1, paddingLeft: 16 }}>
{endWithPunctation(editingPlugin.description)}
<div style={{ marginTop: 5 }}>
{editingPlugin?.plugin_type === 'local' && editingPlugin.url ? (
<LocalPluginTag url={editingPlugin.url} title="Installed Locally" />
) : editingPlugin.plugin_type === 'source' ? (
<SourcePluginTag />
) : null}
{editingPlugin.url && (
<a href={editingPlugin.url}>
<i>⤷ Learn more</i>
</a>
)}
</div>
<div style={{ display: 'flex', alignItems: 'center', marginTop: 5 }}>
<Form.Item
fieldKey="__enabled"
name="__enabled"
style={{ display: 'inline-block', marginBottom: 0 }}
data-attr="plugin-enabled-switch"
>
<EnabledDisabledSwitch />
</Form.Item>
</div>
</div>
</div>
{editingPlugin.plugin_type === 'source' ? (
<div>
<Button
type={editingSource ? 'default' : 'primary'}
icon={<CodeOutlined />}
onClick={() => setEditingSource(!editingSource)}
data-attr="plugin-edit-source"
>
Edit Source
</Button>
</div>
) : null}
{editingPlugin.capabilities && Object.keys(editingPlugin.capabilities).length > 0 ? (
<>
<h3 className="l3" style={{ marginTop: 32 }}>
Capabilities
</h3>
<div style={{ marginTop: 5 }}>
{[
...editingPlugin.capabilities.methods,
...editingPlugin.capabilities.scheduled_tasks,
]
.filter(
(capability) => !['setupPlugin', 'teardownPlugin'].includes(capability)
)
.map((capability) => (
<Tooltip title={capabilitiesInfo[capability] || ''} key={capability}>
<Tag className="plugin-capabilities-tag">{capability}</Tag>
</Tooltip>
))}
{editingPlugin.capabilities.jobs.map((jobName) => (
<Tooltip title="Custom job" key={jobName}>
<Tag className="plugin-capabilities-tag">{jobName}</Tag>
</Tooltip>
))}
</div>
</>
) : null}
{editingPlugin.pluginConfig.id && (
<PluginJobOptions
plugin={editingPlugin}
pluginConfigId={editingPlugin.pluginConfig.id}
/>
)}
<h3 className="l3" style={{ marginTop: 32 }}>
Configuration
</h3>
{getConfigSchemaArray(editingPlugin.config_schema).length === 0 ? (
<div>This plugin is not configurable.</div>
) : null}
{getConfigSchemaArray(editingPlugin.config_schema).map((fieldConfig, index) => (
<React.Fragment key={fieldConfig.key || `__key__${index}`}>
{fieldConfig.markdown && (
<ReactMarkdown source={fieldConfig.markdown} linkTarget="_blank" />
)}
{fieldConfig.type && isValidField(fieldConfig) ? (
<Form.Item
hidden={!!fieldConfig.key && invisibleFields.includes(fieldConfig.key)}
label={
<>
{fieldConfig.secret && <SecretFieldIcon />}
{fieldConfig.name || fieldConfig.key}
</>
}
extra={
fieldConfig.hint && (
<small>
<div style={{ height: 2 }} />
<ReactMarkdown source={fieldConfig.hint} linkTarget="_blank" />
</small>
)
}
name={fieldConfig.key}
required={
fieldConfig.required ||
(!!fieldConfig.key && requiredFields.includes(fieldConfig.key))
}
rules={[
{
required:
fieldConfig.required ||
(!!fieldConfig.key && requiredFields.includes(fieldConfig.key)),
message: 'Please enter a value!',
},
]}
>
<PluginField
fieldConfig={fieldConfig}
onChange={updateInvisibleAndRequiredFields}
/>
</Form.Item>
) : (
<>
{fieldConfig.type ? (
<p style={{ color: 'var(--danger)' }}>
Invalid config field <i>{fieldConfig.name || fieldConfig.key}</i>.
</p>
) : null}
</>
)}
</React.Fragment>
))}
</div>
) : null}
</Form>
</Drawer>
{editingPlugin?.plugin_type === 'source' ? <PluginSource /> : null}
</>
)
}
Example #7
Source File: Icon.tsx From html2sketch with MIT License | 4 votes |
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 #8
Source File: Stats.tsx From leek with Apache License 2.0 | 4 votes |
function Stats(stats: any) {
return [
{
number: stats.SEEN_TASKS,
text: "Total Tasks",
icon: <UnorderedListOutlined />,
tooltip: "Seen tasks names",
},
{
number: stats.SEEN_WORKERS,
text: "Total Workers",
icon: <RobotFilled />,
tooltip: "The total offline/online and beat workers",
},
{
number: stats.PROCESSED_EVENTS,
text: "Events Processed",
icon: <ThunderboltOutlined />,
tooltip: "The total processed events",
},
{
number: stats.PROCESSED_TASKS,
text: "Tasks Processed",
icon: <SyncOutlined />,
tooltip: "The total processed tasks",
},
{
number: stats.QUEUED,
text: "Tasks Queued",
icon: <EllipsisOutlined />,
tooltip: "The total tasks in the queues",
},
{
number: stats.RETRY,
text: "To Retry",
icon: <RetweetOutlined style={{ color: STATES_COLORS.RETRY }} />,
tooltip: "Tasks that are failed and waiting for retry",
},
{
number: stats.RECEIVED,
text: "Received",
icon: <SendOutlined style={{ color: STATES_COLORS.RECEIVED }} />,
tooltip: "Tasks were received by a worker. but not yet started",
},
{
number: stats.STARTED,
text: "Started",
icon: <LoadingOutlined style={{ color: STATES_COLORS.STARTED }} />,
tooltip:
"Tasks that were started by a worker and still active, set (task_track_started) to True on worker level to report started tasks",
},
{
number: stats.SUCCEEDED,
text: "Succeeded",
icon: <CheckCircleOutlined style={{ color: STATES_COLORS.SUCCEEDED }} />,
tooltip: "Tasks that were succeeded",
},
{
number: stats.RECOVERED,
text: "Recovered",
icon: <IssuesCloseOutlined style={{ color: STATES_COLORS.RECOVERED }} />,
tooltip: "Tasks that were succeeded after retries.",
},
{
number: stats.FAILED,
text: "Failed",
icon: <WarningOutlined style={{ color: STATES_COLORS.FAILED }} />,
tooltip: "Tasks that were failed",
},
{
number: stats.CRITICAL,
text: "Critical",
icon: <CloseCircleOutlined style={{ color: STATES_COLORS.CRITICAL }} />,
tooltip: "Tasks that were failed after max retries.",
},
{
number: stats.REJECTED,
text: "Rejected",
icon: <RollbackOutlined style={{ color: STATES_COLORS.REJECTED }} />,
tooltip:
"Tasks that were rejected by workers and requeued, or moved to a dead letter queue",
},
{
number: stats.REVOKED,
text: "Revoked",
icon: <StopOutlined style={{ color: STATES_COLORS.REVOKED }} />,
tooltip: "Tasks that were revoked by workers, but still in the queue.",
},
];
}
Example #9
Source File: index.tsx From fe-v5 with Apache License 2.0 | 4 votes |
PageLayout: React.FC<IPageLayoutProps> = ({ icon, title, rightArea, children, customArea, showBack, onChangeCluster, hideCluster = true }) => {
const { t, i18n } = useTranslation();
const history = useHistory();
const dispatch = useDispatch();
let { profile } = useSelector<AccountRootState, accountStoreState>((state) => state.account);
const { clusters } = useSelector<CommonRootState, CommonStoreState>((state) => state.common);
const localCluster = localStorage.getItem('curCluster');
const [curCluster, setCurCluster] = useState<string>(localCluster || clusters[0]);
if (!localCluster && clusters.length > 0) {
setCurCluster(clusters[0]);
localStorage.setItem('curCluster', clusters[0]);
dispatch({
type: 'common/saveData',
prop: 'curCluster',
data: clusters[0],
});
}
const menu = (
<Menu>
<Menu.Item
onClick={() => {
history.push('/account/profile/info');
}}
>
{t('个人信息')}
</Menu.Item>
<Menu.Item
onClick={() => {
Logout().then((res) => {
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
dispatch({
type: 'common/saveData',
prop: 'clusters',
data: [],
});
dispatch({
type: 'common/saveData',
prop: 'busiGroups',
data: [],
});
history.push('/login');
});
}}
>
{t('退出')}
</Menu.Item>
</Menu>
);
const clusterMenu = (
<Menu selectedKeys={[curCluster]}>
{clusters.map((cluster) => (
<Menu.Item
key={cluster}
onClick={(_) => {
setCurCluster(cluster);
onChangeCluster && onChangeCluster(cluster);
localStorage.setItem('curCluster', cluster);
dispatch({
type: 'common/saveData',
prop: 'curCluster',
data: cluster,
});
}}
>
{cluster}
</Menu.Item>
))}
</Menu>
);
return (
<div className={'page-wrapper'}>
{customArea ? (
<div className={'page-top-header'}>{customArea}</div>
) : (
<div className={'page-top-header'}>
<div className={'page-header-content'}>
<div className={'page-header-title'}>
{showBack && (
<RollbackOutlined
onClick={() => history.goBack()}
style={{
marginRight: '5px',
}}
/>
)}
{icon}
{title}
</div>
{/* <div className={'page-header-right-area'}>{rightArea}</div> */}
<div className={'page-header-right-area'}>
{import.meta.env.VITE_DOC_LINK && (
<a href={import.meta.env.VITE_DOC_LINK as string} target='_blank' style={{ marginRight: 20 }}>
文档
</a>
)}
{!hideCluster && (
<div style={{ marginRight: 20 }}>
集群:
<Dropdown overlay={clusterMenu}>
<Button>
{curCluster} <DownOutlined />
</Button>
</Dropdown>
</div>
)}
{/* 文案完善了再打开 */}
{/* <span
className='language'
onClick={() => {
let language = i18n.language == 'en' ? 'zh' : 'en';
i18n.changeLanguage(language);
localStorage.setItem('language', language);
}}
>
{i18n.language == 'zh' ? 'En' : '中'}
</span> */}
<Dropdown overlay={menu} trigger={['click']}>
<span className='avator'>
<img src={profile.portrait || '/image/avatar1.png'} alt='' />
<span className='display-name'>{profile.nickname || profile.username}</span>
<DownOutlined />
</span>
</Dropdown>
</div>
</div>
</div>
)}
{children && children}
</div>
);
}
Example #10
Source File: Title.tsx From fe-v5 with Apache License 2.0 | 4 votes |
export default function Title(props: IProps) {
const { curCluster, clusters, setCurCluster, dashboard, setDashboard, refresh, range, setRange, step, setStep, refreshFlag, setRefreshFlag, refreshRef, onAddPanel } = props;
const { id, name } = dashboard;
const history = useHistory();
const [titleEditing, setTitleEditing] = useState(false);
const titleRef = useRef<any>(null);
const handleModifyTitle = async (newName) => {
updateDashboard(id, { ...dashboard, name: newName }).then(() => {
setDashboard({ ...dashboard, name: newName });
setTitleEditing(false);
});
};
const { run } = useThrottleFn(
() => {
if ('start' in range && range.start && range.end) {
const diff = range.end - range.start;
const now = moment().unix();
setRange({
end: now,
start: now - diff,
});
} else if ('unit' in range && range.unit) {
const newRefreshFlag = _.uniqueId('refreshFlag_');
setRange({
...range,
refreshFlag: newRefreshFlag,
});
setRefreshFlag(newRefreshFlag);
}
refresh(false);
},
{ wait: 1000 },
);
return (
<div className='dashboard-detail-header'>
<div className='dashboard-detail-header-left'>
<RollbackOutlined className='back' onClick={() => history.push('/dashboards')} />
{titleEditing ? (
<Input
ref={titleRef}
defaultValue={name}
onPressEnter={(e: any) => {
handleModifyTitle(e.target.value);
}}
/>
) : (
<div className='title'>{dashboard.name}</div>
)}
{!titleEditing ? (
<EditOutlined
className='edit'
onClick={() => {
setTitleEditing(!titleEditing);
}}
/>
) : (
<>
<Button size='small' style={{ marginRight: 5, marginLeft: 5 }} onClick={() => setTitleEditing(false)}>
取消
</Button>
<Button
size='small'
type='primary'
onClick={() => {
handleModifyTitle(titleRef.current.state.value);
}}
>
保存
</Button>
</>
)}
</div>
<div className='dashboard-detail-header-right'>
<Space>
<div>
<Dropdown
trigger={['click']}
overlay={
<Menu>
{_.map([{ type: 'row', name: '分组' }, ...visualizations], (item) => {
return (
<Menu.Item
key={item.type}
onClick={() => {
onAddPanel(item.type);
}}
>
{item.name}
</Menu.Item>
);
})}
</Menu>
}
>
<Button type='primary' icon={<AddPanelIcon />}>
添加图表
</Button>
</Dropdown>
</div>
<div style={{ display: 'flex', alignItems: 'center' }}>
集群:
<Dropdown
overlay={
<Menu selectedKeys={[curCluster]}>
{clusters.map((cluster) => (
<Menu.Item
key={cluster}
onClick={(_) => {
setCurCluster(cluster);
localStorage.setItem('curCluster', cluster);
refresh();
}}
>
{cluster}
</Menu.Item>
))}
</Menu>
}
>
<Button>
{curCluster} <DownOutlined />
</Button>
</Dropdown>
</div>
<DateRangePicker value={range} onChange={setRange} />
<Resolution onChange={(v) => setStep(v)} initialValue={step} />
<Refresh onRefresh={run} ref={refreshRef} />
</Space>
</div>
</div>
);
}
Example #11
Source File: detail.tsx From fe-v5 with Apache License 2.0 | 4 votes |
export default function DashboardDetail() {
const refreshRef = useRef<{ closeRefresh: Function }>();
const { t } = useTranslation();
const { id, busiId } = useParams<URLParam>();
const [groupForm] = Form.useForm();
const history = useHistory();
const Ref = useRef<any>(null);
const { clusters } = useSelector<CommonRootState, CommonStoreState>((state) => state.common);
const localCluster = localStorage.getItem('curCluster');
const [curCluster, setCurCluster] = useState<string>(localCluster || clusters[0]);
if (!localCluster && clusters.length > 0) {
setCurCluster(clusters[0]);
localStorage.setItem('curCluster', clusters[0]);
}
const [dashboard, setDashboard] = useState<Dashboard>({
create_by: '',
favorite: 0,
id: 0,
name: '',
tags: '',
update_at: 0,
update_by: '',
});
const [step, setStep] = useState<number | null>(null);
const [titleEditing, setTitleEditing] = useState(false);
const [chartGroup, setChartGroup] = useState<Group[]>([]);
const [variableConfig, setVariableConfig] = useState<VariableType>();
const [variableConfigWithOptions, setVariableConfigWithOptions] = useState<VariableType>();
const [dashboardLinks, setDashboardLinks] = useState<ILink[]>();
const [groupModalVisible, setGroupModalVisible] = useState(false);
const [chartModalVisible, setChartModalVisible] = useState(false);
const [chartModalInitValue, setChartModalInitValue] = useState<Chart | null>();
const [range, setRange] = useState<Range>({
start: 0,
end: 0,
});
const [refreshFlag, setRefreshFlag] = useState(_.uniqueId('refreshFlag_'));
const { run } = useThrottleFn(
() => {
if ('start' in range && range.start && range.end) {
const diff = range.end - range.start;
const now = moment().unix();
setRange({
end: now,
start: now - diff,
});
} else if ('unit' in range && range.unit) {
const newRefreshFlag = _.uniqueId('refreshFlag_');
setRange({
...range,
refreshFlag: newRefreshFlag,
});
setRefreshFlag(newRefreshFlag);
}
init(false);
},
{ wait: 1000 },
);
useEffect(() => {
init();
}, []);
const init = (needUpdateVariable = true) => {
getSingleDashboard(busiId, id).then((res) => {
setDashboard(res.dat);
if (res.dat.configs) {
const configs = JSON.parse(res.dat.configs);
setVariableConfig(configs);
setVariableConfigWithOptions(configs);
setDashboardLinks(configs.links);
}
});
getChartGroup(busiId, id).then((res) => {
let arr = res.dat || [];
setChartGroup(
arr
.sort((a, b) => a - b)
.map((item) => {
item.updateTime = Date.now(); // 前端拓展一个更新时间字段,用来主动刷新ChartGroup
return item;
}),
);
});
};
const handleDateChange = (e) => {
setRange(e);
};
const handleEdit = () => {
setTitleEditing(!titleEditing);
};
const handleModifyTitle = async (e) => {
await updateSingleDashboard(busiId, id, { ...dashboard, name: e.target.value });
// await init();
setDashboard({ ...dashboard, name: e.target.value });
setTitleEditing(false);
};
const handleAddChart = (gid: number) => {
groupId = gid;
editor({
visible: true,
variableConfig: variableConfigWithOptions,
cluster: curCluster,
busiId,
groupId,
id,
initialValues: {
type: 'timeseries',
targets: [
{
refId: 'A',
expr: '',
},
],
},
onOK: () => {
handleChartConfigVisibleChange(true);
},
});
// setChartModalVisible(true);
}; //group是为了让detail组件知道当前需要刷新的是哪个chartGroup,item是为了获取待编辑的信息
const handleUpdateChart = (group: Group, item: Chart) => {
groupId = group.id;
setChartModalInitValue(item);
if (semver.valid(item.configs.version)) {
editor({
visible: true,
variableConfig,
cluster: curCluster,
busiId,
groupId,
id,
initialValues: {
...item.configs,
id: item.id,
},
onOK: () => {
handleChartConfigVisibleChange(true);
},
});
} else {
setChartModalVisible(true);
}
};
const handleDelChart = async (group: Group, item: Chart) => {
groupId = group.id;
await removeChart(busiId, item.id as any);
refreshUpdateTimeByChartGroupId();
};
const handleCloneChart = async (group: Group, item: Chart) => {
groupId = group.id;
const configsClone = _.cloneDeep(item.configs);
configsClone.layout = {
w: configsClone.layout.w,
h: configsClone.layout.h,
};
await createChart(busiId, {
configs: JSON.stringify(configsClone),
weight: 0,
group_id: groupId,
});
refreshUpdateTimeByChartGroupId();
};
const handleShareChart = async (group: Group, item: any) => {
const serielData = {
dataProps: {
...item.configs,
targets: _.map(item.configs.targets, (target) => {
const realExpr = variableConfigWithOptions ? replaceExpressionVars(target.expr, variableConfigWithOptions, variableConfigWithOptions.var.length, id) : target.expr;
return {
...target,
expr: realExpr,
};
}),
step,
range,
},
curCluster: localStorage.getItem('curCluster'),
};
SetTmpChartData([
{
configs: JSON.stringify(serielData),
},
]).then((res) => {
const ids = res.dat;
window.open('/chart/' + ids);
});
};
const handleAddOrUpdateChartGroup = async () => {
await groupForm.validateFields();
let obj = groupForm.getFieldsValue();
if (isAddGroup) {
let weightArr = chartGroup.map((item) => item.weight);
let weight = Math.max(...weightArr) + 1;
await createChartGroup(busiId, { ...obj, weight, dashboard_id: Number(id) });
} else {
let group = chartGroup.find((item) => item.id === groupId);
await updateChartGroup(busiId, [{ dashboard_id: Number(id), ...group, ...obj }]);
}
init();
isAddGroup = true;
setGroupModalVisible(false);
};
const handleUpdateChartGroup = (group: Group) => {
groupId = group.id;
isAddGroup = false;
groupForm.setFieldsValue({ name: group.name });
setGroupModalVisible(true);
};
const handleMoveUpChartGroup = async (group: Group) => {
const { weight } = group;
let lessWeightGroup = chartGroup.find((item) => item.weight === weight - 1);
if (!lessWeightGroup) return;
lessWeightGroup.weight = weight;
group.weight = weight - 1;
await updateChartGroup(busiId, [lessWeightGroup, group]);
init();
};
const handleMoveDownChartGroup = async (group: Group) => {
const { weight } = group;
let lessWeightGroup = chartGroup.find((item) => item.weight === weight + 1);
if (!lessWeightGroup) return;
lessWeightGroup.weight = weight;
group.weight = weight + 1;
await updateChartGroup(busiId, [lessWeightGroup, group]);
init();
};
const handleDelChartGroup = async (id: number) => {
await delChartGroup(busiId, id);
message.success(t('删除分组成功'));
init();
setGroupModalVisible(false);
};
const refreshUpdateTimeByChartGroupId = () => {
let groupIndex = chartGroup.findIndex((item) => item.id === groupId);
if (groupIndex < 0) return;
let newChartGroup = [...chartGroup];
newChartGroup[groupIndex].updateTime = Date.now();
setChartGroup(newChartGroup);
};
const handleChartConfigVisibleChange = (b) => {
setChartModalVisible(false);
setChartModalInitValue(null);
b && refreshUpdateTimeByChartGroupId();
};
const handleVariableChange = (value, b, valueWithOptions) => {
let dashboardConfigs: any = {};
try {
if (dashboard.configs) {
dashboardConfigs = JSON.parse(dashboard.configs);
}
} catch (e) {
console.error(e);
}
dashboardConfigs.var = value.var;
b && updateSingleDashboard(busiId, id, { ...dashboard, configs: JSON.stringify(dashboardConfigs) });
setVariableConfig(dashboardConfigs);
valueWithOptions && setVariableConfigWithOptions(valueWithOptions);
};
const stopAutoRefresh = () => {
refreshRef.current?.closeRefresh();
};
const clusterMenu = (
<Menu selectedKeys={[curCluster]}>
{clusters.map((cluster) => (
<Menu.Item
key={cluster}
onClick={(_) => {
setCurCluster(cluster);
localStorage.setItem('curCluster', cluster);
init();
}}
>
{cluster}
</Menu.Item>
))}
</Menu>
);
return (
<PageLayout
customArea={
<div className='dashboard-detail-header'>
<div className='dashboard-detail-header-left'>
<RollbackOutlined className='back' onClick={() => history.push('/dashboards')} />
{titleEditing ? <Input ref={Ref} defaultValue={dashboard.name} onPressEnter={handleModifyTitle} /> : <div className='title'>{dashboard.name}</div>}
{!titleEditing ? (
<EditOutlined className='edit' onClick={handleEdit} />
) : (
<>
<Button size='small' style={{ marginRight: 5, marginLeft: 5 }} onClick={() => setTitleEditing(false)}>
取消
</Button>
<Button
size='small'
type='primary'
onClick={() => {
handleModifyTitle({ target: { value: Ref.current.state.value } });
}}
>
保存
</Button>
</>
)}
</div>
<div className='dashboard-detail-header-right'>
<Space>
<div style={{ display: 'flex', alignItems: 'center' }}>
集群:
<Dropdown overlay={clusterMenu}>
<Button>
{curCluster} <DownOutlined />
</Button>
</Dropdown>
</div>
<DateRangePicker onChange={handleDateChange} />
<Resolution onChange={(v) => setStep(v)} initialValue={step} />
<Refresh onRefresh={run} ref={refreshRef} />
</Space>
</div>
</div>
}
>
<div className='dashboard-detail-content'>
<div className='dashboard-detail-content-header'>
<div className='variable-area'>
<VariableConfig onChange={handleVariableChange} value={variableConfig} cluster={curCluster} range={range} id={id} onOpenFire={stopAutoRefresh} />
</div>
<DashboardLinks
value={dashboardLinks}
onChange={(v) => {
let dashboardConfigs: any = {};
try {
if (dashboard.configs) {
dashboardConfigs = JSON.parse(dashboard.configs);
}
} catch (e) {
console.error(e);
}
dashboardConfigs.links = v;
updateSingleDashboard(busiId, id, {
...dashboard,
configs: JSON.stringify(dashboardConfigs),
});
setDashboardLinks(v);
}}
/>
</div>
<div className='charts'>
{chartGroup.map((item, i) => (
<ChartGroup
id={id}
cluster={curCluster}
busiId={busiId}
key={i}
step={step}
groupInfo={item}
onAddChart={handleAddChart}
onUpdateChart={handleUpdateChart}
onCloneChart={handleCloneChart}
onShareChart={handleShareChart}
onUpdateChartGroup={handleUpdateChartGroup}
onMoveUpChartGroup={handleMoveUpChartGroup}
onMoveDownChartGroup={handleMoveDownChartGroup}
onDelChart={handleDelChart}
onDelChartGroup={handleDelChartGroup}
range={range}
refreshFlag={refreshFlag}
variableConfig={variableConfigWithOptions!}
moveUpEnable={i > 0}
moveDownEnable={i < chartGroup.length - 1}
/>
))}
<Button
block
icon={<PlusOutlined />}
style={{
paddingRight: 0,
}}
onClick={() => {
groupForm.setFieldsValue({ name: '' });
setGroupModalVisible(true);
}}
>
{t('新增图表分组')}
</Button>
</div>
</div>
<Modal
title={isAddGroup ? t('新建分组') : t('更新分组名称')}
visible={groupModalVisible}
onOk={handleAddOrUpdateChartGroup}
onCancel={() => {
setGroupModalVisible(false);
}}
>
<Form {...layout} form={groupForm}>
<Form.Item
label={t('分组名称')}
name='name'
rules={[
{
required: true,
message: t('请输入名称'),
},
]}
>
<Input />
</Form.Item>
</Form>
</Modal>
{chartModalVisible && (
<ChartConfigModal
id={id}
cluster={curCluster}
busiId={busiId}
initialValue={chartModalInitValue}
groupId={groupId}
show={chartModalVisible}
onVisibleChange={handleChartConfigVisibleChange}
variableConfig={variableConfigWithOptions}
/>
)}
</PageLayout>
);
}
Example #12
Source File: add.tsx From fe-v5 with Apache License 2.0 | 4 votes |
Add = (props: any) => {
const history = useHistory();
const query = queryString.parse(_.get(props, 'location.search'));
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const [data, setData] = useState();
const [action, setAction] = useState('');
const handleSubmit = (values: any) => {
if (action) {
request(api.tasks(curBusiItem.id), {
method: 'POST',
body: JSON.stringify({
...values,
action,
}),
}).then((res) => {
message.success(t('msg.create.success'));
props.history.push({
pathname: `/job-tasks/${res.dat}/result`,
});
});
}
};
useEffect(() => {
if (_.isPlainObject(query)) {
if (query.tpl !== undefined) {
setLoading(true);
request(`${api.tasktpl(curBusiItem.id)}/${query.tpl}`, {
}).then((data) => {
setData({
...data.dat.tpl,
hosts: data.dat.hosts,
});
}).finally(() => {
setLoading(false);
});
} else if (query.task !== undefined) {
setLoading(true);
request(`${api.task(curBusiItem.id)}/${query.task}`, {
}).then((data) => {
setData({
...data.dat.meta,
hosts: _.map(data.dat.hosts, (host) => {
return host.host;
}),
});
}).finally(() => {
setLoading(false);
});
}
}
}, []);
return (
<PageLayout hideCluster title={
query.tpl ?
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tpls')} />
自愈脚本
</> :
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tasks')} />
执行历史
</>
}>
<div style={{ padding: 10 }}>
<div style={{ background: 'none' }}>
<Row gutter={20}>
<Col span={18}>
<Card
title={
query.tpl ? '创建任务' : query.task ? '克隆任务' : '创建临时任务'
}
>
<Spin spinning={loading}>
{
data || (!query.tpl && !query.task) ?
<TplForm
type="task"
initialValues={data}
onSubmit={handleSubmit}
footer={
<div>
<Button type="primary" htmlType="submit" style={{ marginRight: 10 }}
onClick={() => {
setAction('pause');
}}
>
保存暂不执行
</Button>
<Button type="primary" htmlType="submit"
onClick={() => {
setAction('start');
}}
>
保存立刻执行
</Button>
</div>
}
/> : null
}
</Spin>
</Card>
</Col>
<Col span={6}>
<Alert
showIcon
message="提示信息"
description="如果你的角色是管理员,则可以在任意机器执行脚本;否则,只能对有管理权限的业务组下的机器执行脚本"
type="warning"
/>
</Col>
</Row>
</div>
</div>
</PageLayout>
);
}
Example #13
Source File: detail.tsx From fe-v5 with Apache License 2.0 | 4 votes |
Detail = (props: any) => {
const history = useHistory();
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const { t } = useTranslation();
const taskId = _.get(props, 'match.params.id');
const [loading, setLoading] = useState(false);
const [data, setData] = useState({} as any);
useEffect(() => {
if (taskId !== undefined) {
setLoading(true);
request(`${api.task(curBusiItem.id)}/${taskId}`).then((data) => {
setData({
...data.dat.meta,
hosts: _.map(data.dat.hosts, (host) => {
return host.host;
}),
});
}).finally(() => {
setLoading(false);
});
}
}, [taskId]);
return (
<PageLayout hideCluster title={
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tasks')} />
执行历史
</>
}>
<div style={{ padding: 10 }}>
<Card
title={data.title}
>
<Spin spinning={loading}>
<div className="job-task-table">
<div className="ant-table ant-table-default ant-table-bordered">
<div className="ant-table-content">
<div className="ant-table-body">
<table>
<colgroup>
<col style={{ width: 100, minWidth: 100 }} />
<col />
</colgroup>
<tbody className="ant-table-tbody">
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.title')}</td>
<td>{data.title}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.creator')}</td>
<td>{data.creator} @ {moment(data.created).format('YYYY-MM-DD HH:mm:ss')}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.control.params')}</td>
<td>
{t('task.account')}:{data.account}
<Divider type="vertical" />
{t('task.batch')}:{data.batch}
<Divider type="vertical" />
{t('task.tolerance')}:{data.tolerance}
<Divider type="vertical" />
{t('task.timeout')}:{data.timeout}
</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.script')}</td>
<td>
<Editor value={data.script} readOnly height="200px" />
</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.script.args')}</td>
<td>{data.args}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.pause')}</td>
<td>{data.pause}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.host.list')}</td>
<td>
{
_.map(data.hosts, (host) => {
return <div key={host}>{host}</div>;
})
}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div style={{ marginTop: 10 }}>
<Link to={{ pathname: '/job-tasks/add', search: `task=${taskId}` }}>
<Button type="primary">{t('task.clone.new')}</Button>
</Link>
<Link style={{ marginLeft: 8 }} to={{ pathname: `/job-tasks` }}>
<Button>返回</Button>
</Link>
</div>
</Spin>
</Card>
</div>
</PageLayout>
);
}
Example #14
Source File: result.tsx From fe-v5 with Apache License 2.0 | 4 votes |
index = (props: any) => {
const taskResultCls = 'job-task-result';
const history = useHistory();
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const { params } = props.match;
const taskId = params.id;
const { t, i18n } = useTranslation();
const [activeStatus, setActiveStatus] = useState<string[]>();
const [data, setData] = useState({} as any);
const [hosts, setHosts] = useState<HostItem[]>([]);
const [loading, setLoading] = useState(false);
const getTableData = () => {
setLoading(true)
return request(`${api.task(curBusiItem.id)}/${params.id}`).then((data) => {
setData({
...data.dat.meta,
action: data.dat.action,
});
setHosts(data.dat.hosts);
}).finally(() => {
setLoading(false);
});
};
useEffect(() => {
getTableData();
}, []);
let filteredHosts = _.cloneDeep(hosts);
if (activeStatus) {
filteredHosts = _.filter(filteredHosts, (item: any) => {
return _.includes(activeStatus, item.status);
});
}
const handleHostAction = (host: string, action: string) => {
request(`${api.task(curBusiItem.id)}/${taskId}/host/${host}/action`, {
method: 'PUT',
body: JSON.stringify({
action,
}),
}).then(() => {
getTableData();
});
};
const handleTaskAction = (action: string) => {
request(`${api.task(curBusiItem.id)}/${taskId}/action`, {
method: 'PUT',
body: JSON.stringify({
action,
}),
}).then(() => {
getTableData();
});
};
const renderHostStatusFilter = () => {
const groupedHosts = _.groupBy(hosts, 'status');
return _.map(groupedHosts, (chosts, status) => {
return {
text: `${status} (${chosts.length})`,
value: status
}
});
}
const columns: ColumnProps<HostItem>[] = [
{
title: (
<FieldCopy
dataIndex="host"
hasSelected={false}
data={filteredHosts}
/>
),
dataIndex: 'host',
}, {
title: t('task.status'),
dataIndex: 'status',
filters: renderHostStatusFilter(),
onFilter: (value: string, record) => {
return record.status === value;
},
render: (text) => {
if (text === 'success') {
return <Tag color="#87d068">{text}</Tag>;
} else if (text === 'cancelled' || text === 'ignored') {
return <Tag color="#ec971f">{text}</Tag>;
} else if (text === 'failed' || text === 'killfailed' || text === 'timeout') {
return <Tag color="#f50">{text}</Tag>;
}
return <Tag>{text}</Tag>;
},
}, {
title: t('task.output'),
render: (_text, record) => {
return (
<span>
<Link
to={`/job-task/${curBusiItem.id}/output/${params.id}/${record.host}/stdout`}
target="_blank"
>
stdout
</Link>
<Divider type="vertical" />
<a
href={`/job-task/${curBusiItem.id}/output/${params.id}/${record.host}/stderr`}
target="_blank"
>
stderr
</a>
</span>
);
},
},
];
if (!data.done) {
columns.push({
title: t('table.operations'),
render: (_text, record) => {
return (
<span>
<a onClick={() => handleHostAction(record.host, 'ignore')}>ignore</a>
<Divider type="vertical" />
<a onClick={() => handleHostAction(record.host, 'redo')}>redo</a>
<Divider type="vertical" />
<a onClick={() => handleHostAction(record.host, 'kill')}>kill</a>
</span>
);
},
});
}
return (
<PageLayout hideCluster title={
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tasks')} />
执行历史
</>
}>
<div style={{ padding: 10 }} className={taskResultCls}>
<Card
title={data.title}
extra={<a onClick={() => { getTableData(); }}>{t('task.refresh')}</a>}
>
<Row style={{ marginBottom: 20 }}>
<Col span={18}>
<div>
<a href={`/job-task/${curBusiItem.id}/output/${taskId}/stdout`} target="_blank">stdouts</a>
<Divider type="vertical" />
<a href={`/job-task/${curBusiItem.id}/output/${taskId}/stderr`} target="_blank">stderrs</a>
<Divider type="vertical" />
<Link to={{ pathname: `/job-tasks/${taskId}/detail` }}>{t('task.meta')}</Link>
<Divider type="vertical" />
<Link to={{ pathname: '/job-tasks/add', search: `task=${taskId}` }}>{t('task.clone')}</Link>
</div>
</Col>
<Col span={6} className="textAlignRight">
{
!data.done ?
<span>
{
data.action === 'start' ?
<Button className="success-btn" onClick={() => handleTaskAction('pause')}>Pause</Button> :
<Button className="success-btn" onClick={() => handleTaskAction('start')}>Start</Button>
}
<Button className="ml10 warning-btn" onClick={() => handleTaskAction('cancel')}>Cancel</Button>
<Button className="ml10 danger-btn" onClick={() => handleTaskAction('kill')}>Kill</Button>
</span> : null
}
</Col>
</Row>
<Table
rowKey="host"
columns={columns as any}
dataSource={hosts}
loading={loading}
pagination={{
showSizeChanger: true,
pageSizeOptions: ['10', '50', '100', '500', '1000'],
showTotal: (total) => {
return i18n.language == 'en' ?
`Total ${total} items` :
`共 ${total} 条`
},
} as any}
onChange={(pagination, filters, sorter, extra) => {
setActiveStatus(filters.status as string[]);
}}
/>
</Card>
</div>
</PageLayout>
)
}
Example #15
Source File: detail.tsx From fe-v5 with Apache License 2.0 | 4 votes |
Detail = (props: any) => {
const history = useHistory();
const id = _.get(props, 'match.params.id');
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const [data, setData] = useState({} as Tpl);
useEffect(() => {
if (id) {
setLoading(true);
request(`${api.tasktpl(curBusiItem.id)}/${id}`).then((data) => {
const { dat } = data;
setData({
...dat.tpl,
hosts: dat.hosts,
grp: dat.grp,
});
}).finally(() => {
setLoading(false);
});
}
}, [id, curBusiItem.id]);
return (
<PageLayout hideCluster title={
<>
<RollbackOutlined className='back' onClick={() => history.push('/job-tpls')} />
自愈脚本
</>
}>
<div style={{ padding: 10 }}>
<Card
title="自愈脚本详情"
>
<Spin spinning={loading}>
<div className="job-task-table">
<div className="ant-table ant-table-default ant-table-bordered">
<div className="ant-table-content">
<div className="ant-table-body">
<table>
<colgroup>
<col style={{ width: 100, minWidth: 100 }} />
<col />
</colgroup>
<tbody className="ant-table-tbody">
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.title')}</td>
<td>{data.title}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('tpl.creator')}</td>
<td>{data.create_by}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('tpl.last_updated')}</td>
<td>{moment.unix(data.update_at).format('YYYY-MM-DD HH:mm:ss')}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.control.params')}</td>
<td>
{t('task.account')}:{data.account}
<Divider type="vertical" />
{t('task.batch')}:{data.batch}
<Divider type="vertical" />
{t('task.tolerance')}:{data.tolerance}
<Divider type="vertical" />
{t('task.timeout')}:{data.timeout}
</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.script')}</td>
<td>
<Editor value={data.script} readOnly height="200px" />
</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.script.args')}</td>
<td>{data.args}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.pause')}</td>
<td>{data.pause}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>{t('task.host.list')}</td>
<td>
{
_.map(data.hosts, (host) => {
return <div key={host}>{host}</div>;
})
}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div style={{ marginTop: 10 }}>
<Link to={{ pathname: `/job-tpls/${id}/modify` }}>
<Button type="primary" style={{ marginRight: 10 }}>{t('tpl.modify')}</Button>
</Link>
<Link to={{ pathname: `/job-tpls/add/task`, search: `tpl=${id}` }}>
<Button type="primary">{t('tpl.create.task')}</Button>
</Link>
</div>
</Spin>
</Card>
</div>
</PageLayout>
)
}
Example #16
Source File: Columns.tsx From wildduck-ui with MIT License | 4 votes |
getArchiveColumns = ({
dataSource,
restoreMessage,
}: {
dataSource: any;
restoreMessage({ message, params }: any): void;
}): any => {
const columns = [
{
title: 'From',
dataIndex: 'from',
key: 'from',
width: 350,
customDataIndex: 'from.address',
filter: true,
children: [
{
title: 'Name',
dataIndex: 'fromName',
key: 'fromName',
width: 100,
fixed: 'left',
render: (text: any, record: any) => _.get(record, 'from.name'),
},
{
title: 'Address',
dataIndex: 'fromAddress',
key: 'fromAddress',
fixed: 'left',
width: 230,
render: (text: any, record: any) => _.get(record, 'from.address'),
},
],
},
{
title: 'To',
dataIndex: 'to',
key: 'to',
width: 350,
children: [
{
title: 'Name',
dataIndex: 'toName',
key: 'toName',
width: 100,
render: (text: any, record: any) => createRecordDisplayList(record, 'to', 'name'),
},
{
title: 'Address',
dataIndex: 'toAddress',
key: 'toAddress',
width: 230,
render: (text: any, record: any) => createRecordDisplayList(record, 'to', 'address'),
},
],
},
{
title: 'Cc',
dataIndex: 'cc',
key: 'cc',
widht: 350,
children: [
{
title: 'Name',
dataIndex: 'ccName',
key: 'ccName',
width: 100,
render: (text: any, record: any) => createRecordDisplayList(record, 'cc', 'name'),
},
{
title: 'Address',
dataIndex: 'ccAddress',
key: 'ccAddress',
width: 230,
render: (text: any, record: any) => createRecordDisplayList(record, 'cc', 'address'),
},
],
},
{
title: 'Bcc',
dataIndex: 'bcc',
key: 'bcc',
width: 350,
children: [
{
title: 'Name',
dataIndex: 'bccName',
key: 'bccName',
width: 100,
render: (text: any, record: any) => createRecordDisplayList(record, 'bcc', 'name'),
},
{
title: 'Address',
dataIndex: 'bccAddress',
key: 'bccAddress',
width: 230,
render: (text: any, record: any) => createRecordDisplayList(record, 'bcc', 'address'),
},
],
},
{
title: 'Subject',
dataIndex: 'subject',
key: 'subject',
width: 100,
},
{
title: 'Date',
dataIndex: 'date',
key: 'date',
sortable: 'date',
width: 100,
render: (date: string) => moment(date).format(DATE_TIME_FORMAT_AP),
},
{
title: 'Intro',
dataIndex: 'intro',
key: 'intro',
width: 100,
},
{
title: 'Attachments',
dataIndex: 'attachments',
key: 'attachments',
filter: true,
width: 110,
align: 'center',
render: (text: string) => _.toString(text),
},
{
title: 'Seen',
dataIndex: 'seen',
key: 'seen',
filter: true,
width: 70,
align: 'center',
render: (text: string) => _.toString(text),
},
{
title: 'Deleted',
dataIndex: 'deleted',
key: 'deleted',
filter: true,
width: 90,
align: 'center',
render: (text: string) => _.toString(text),
},
{
title: 'Flagged',
dataIndex: 'flagged',
key: 'flagged',
filter: true,
width: 90,
align: 'center',
render: (text: string) => _.toString(text),
},
{
title: 'Content type',
dataIndex: 'contentType',
key: 'contentType',
customDataIndex: 'contentType.value',
filter: true,
width: 350,
children: [
{
title: 'Value',
dataIndex: 'value',
key: 'value',
width: 100,
render: (text: any, record: any) => _.get(record, 'contentType.value'),
},
{
title: 'Params',
dataIndex: 'params',
key: 'params',
width: 230,
render: (text: any, record: any) =>
_.map(_.get(record, 'contentType.params'), (params, key) => (
<Space key={key + params}>
{key} : {params}
</Space>
)),
},
],
},
{
title: 'Action',
key: 'action',
fixed: 'right' as const,
width: 100,
align: 'center',
render: (text: string, record: any) => (
<Space size={'middle'}>
<Tooltip title={'Restore Message'}>
<Button
onClick={() => {
showConfirm(
() =>
restoreMessage({
message: _.get(record, 'id'),
params: { mailbox: _.get(record, 'mailbox') },
}),
'Are you sure you want to restore this message?',
);
}}
className='ant-btn-icon'
shape='circle'
>
<RollbackOutlined className='green-color' />
</Button>
</Tooltip>
</Space>
),
},
];
return getColumnsWithFilterAndSort(columns, dataSource);
}