@ant-design/icons#ShareAltOutlined TypeScript Examples
The following examples show how to use
@ant-design/icons#ShareAltOutlined.
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 fe-v5 with Apache License 2.0 | 5 votes |
render() {
const { spinning } = this.state;
const { extraRender, data, showHeader = true } = this.props;
const { title, metric } = data;
const graphConfig = this.getGraphConfig(data);
return (
<div className={this.state.legend ? 'graph-container graph-container-hasLegend' : 'graph-container'}>
{showHeader && (
<div
className='graph-header'
style={{
height: this.headerHeight,
lineHeight: `${this.headerHeight}px`,
}}
>
<div>{title || metric}</div>
<div className='graph-extra'>
<span className='graph-operationbar-item' key='info'>
<Popover placement='left' content={this.getContent()} trigger='click' autoAdjustOverflow={false} getPopupContainer={() => document.body}>
<Button className='' type='link' size='small' onClick={(e) => e.preventDefault()}>
<SettingOutlined />
</Button>
</Popover>
</span>
{this.props.isShowRefresh === false ? null : (
<span className='graph-operationbar-item' key='sync'>
<Button type='link' size='small' onClick={(e) => e.preventDefault()}>
<SyncOutlined onClick={this.refresh} />
</Button>
</span>
)}
{this.props.isShowShare === false ? null : (
<span className='graph-operationbar-item' key='share'>
<Button type='link' size='small' onClick={(e) => e.preventDefault()}>
<ShareAltOutlined onClick={this.shareChart} />
</Button>
</span>
)}
{extraRender && _.isFunction(extraRender) ? extraRender(this) : null}
</div>
</div>
)}
{this.props.graphConfigInnerVisible ? (
<GraphConfigInner
data={graphConfig}
onChange={(...args) => {
this.updateGraphConfig(args[2] || {});
}}
/>
) : null}
{/* 这个spin有点难搞,因为要第一时间获取chart容器的offsetheight */}
{/* <Spin spinning={spinning} wrapperClassName='graph-spin'> */}
{this.renderChart()}
{/* </Spin> */}
<Legend
style={{ display: this.state.legend ? 'block' : 'none', overflowY: 'auto', maxHeight: '35%' }}
graphConfig={graphConfig}
series={this.getZoomedSeries()}
onSelectedChange={this.handleLegendRowSelectedChange}
comparisonOptions={graphConfig.comparisonOptions}
/>
</div>
);
}
Example #2
Source File: StoryOverLay.tsx From datart with Apache License 2.0 | 5 votes |
StoryOverLay: React.FC<BoardOverLayProps> = memo(
({ onOpenShareLink, allowShare, allowManage, onPublish, isArchived }) => {
const t = useI18NPrefix(`viz.action`);
const tg = useI18NPrefix(`global`);
const { storyId: stroyId, orgId } = useContext(StoryContext);
const recycleViz = useRecycleViz(orgId, stroyId, 'STORYBOARD');
const renderList = useMemo(
() => [
{
key: 'shareLink',
icon: <ShareAltOutlined />,
onClick: onOpenShareLink,
disabled: false,
render: allowShare,
content: t('share.shareLink'),
className: 'line',
},
{
key: 'publish',
icon: <VerticalAlignBottomOutlined />,
onClick: onPublish,
disabled: false,
render: allowManage && !isArchived && onPublish,
content: t('unpublish'),
},
{
key: 'delete',
icon: <DeleteOutlined />,
disabled: false,
render: allowManage,
content: (
<Popconfirm
title={tg('operation.archiveConfirm')}
onConfirm={recycleViz}
>
{tg('button.archive')}
</Popconfirm>
),
},
],
[
onOpenShareLink,
allowShare,
t,
onPublish,
allowManage,
isArchived,
tg,
recycleViz,
],
);
const actionItems = useMemo(
() =>
renderList
.filter(item => item.render)
.map(item => {
return (
<>
<Menu.Item
key={item.key}
icon={item.icon}
onClick={item.onClick}
>
{item.content}
</Menu.Item>
{item.className && <Menu.Divider />}
</>
);
}),
[renderList],
);
return <Menu>{actionItems}</Menu>;
},
)
Example #3
Source File: DashboardHeader.tsx From posthog-foss with MIT License | 4 votes |
export function DashboardHeader(): JSX.Element {
const { dashboard, dashboardMode, lastDashboardModeSource } = useValues(dashboardLogic)
const { addNewDashboard, triggerDashboardUpdate, setDashboardMode, addGraph, saveNewTag, deleteTag } =
useActions(dashboardLogic)
const { dashboardTags } = useValues(dashboardsLogic)
const { nameSortedDashboards, dashboardsLoading, dashboardLoading } = useValues(dashboardsModel)
const { pinDashboard, unpinDashboard, deleteDashboard, duplicateDashboard } = useActions(dashboardsModel)
const { user } = useValues(userLogic)
const [newName, setNewName] = useState(dashboard?.name || null) // Used to update the input immediately, debouncing API calls
const nameInputRef = useRef<Input | null>(null)
const descriptionInputRef = useRef<HTMLInputElement | null>(null)
if (!dashboard) {
return <div />
}
const actionsDefault = (
<>
<Dropdown
trigger={['click']}
overlay={
<Menu>
{dashboard.created_by && (
<>
<Menu.Item disabled>
Created by {dashboard.created_by.first_name || dashboard.created_by.email || '-'} on{' '}
{dayjs(dashboard.created_at).format(
dayjs(dashboard.created_at).year() === dayjs().year()
? 'MMMM Do'
: 'MMMM Do YYYY'
)}
</Menu.Item>
<Menu.Divider />
</>
)}
<Menu.Item
icon={<EditOutlined />}
onClick={() => setDashboardMode(DashboardMode.Edit, DashboardEventSource.MoreDropdown)}
>
Edit mode (E)
</Menu.Item>
<Menu.Item
icon={<FullscreenOutlined />}
onClick={() =>
setDashboardMode(DashboardMode.Fullscreen, DashboardEventSource.MoreDropdown)
}
>
Full screen mode (F)
</Menu.Item>
{dashboard.pinned ? (
<Menu.Item
icon={<PushpinFilled />}
onClick={() => unpinDashboard(dashboard.id, DashboardEventSource.MoreDropdown)}
>
Unpin dashboard
</Menu.Item>
) : (
<Menu.Item
icon={<PushpinOutlined />}
onClick={() => pinDashboard(dashboard.id, DashboardEventSource.MoreDropdown)}
>
Pin dashboard
</Menu.Item>
)}
<Menu.Divider />
<Menu.Item
icon={<CopyOutlined />}
onClick={() => duplicateDashboard({ id: dashboard.id, name: dashboard.name, show: true })}
>
Duplicate dashboard
</Menu.Item>
<Menu.Item
icon={<DeleteOutlined />}
onClick={() => deleteDashboard({ id: dashboard.id, redirect: true })}
danger
>
Delete dashboard
</Menu.Item>
</Menu>
}
placement="bottomRight"
>
<Button type="link" className="btn-lg-2x" data-attr="dashboard-more" icon={<EllipsisOutlined />} />
</Dropdown>
<Button
type="link"
data-attr="dashboard-edit-mode"
icon={<EditOutlined />}
onClick={() => setDashboardMode(DashboardMode.Edit, DashboardEventSource.DashboardHeader)}
/>
<HotkeyButton
onClick={() => addGraph()}
data-attr="dashboard-add-graph-header"
icon={<PlusOutlined />}
hotkey="n"
className="hide-lte-md"
>
New insight
</HotkeyButton>
<HotkeyButton
type="primary"
onClick={() => setDashboardMode(DashboardMode.Sharing, DashboardEventSource.DashboardHeader)}
data-attr="dashboard-share-button"
icon={<ShareAltOutlined />}
hotkey="k"
>
Send or share
</HotkeyButton>
</>
)
const actionsPresentationMode = (
<Button
onClick={() => setDashboardMode(null, DashboardEventSource.DashboardHeader)}
data-attr="dashboard-exit-presentation-mode"
icon={<FullscreenExitOutlined />}
>
Exit full screen mode
</Button>
)
const actionsEditMode = (
<Button
data-attr="dashboard-edit-mode-save"
type="primary"
onClick={() => setDashboardMode(null, DashboardEventSource.DashboardHeader)}
tabIndex={10}
>
Finish editing
</Button>
)
useEffect(() => {
if (dashboardMode === DashboardMode.Edit) {
if (lastDashboardModeSource === DashboardEventSource.AddDescription) {
setTimeout(() => descriptionInputRef.current?.focus(), 10)
} else if (!isMobile()) {
setTimeout(() => nameInputRef.current?.focus(), 10)
}
}
}, [dashboardMode])
return (
<>
<div className={`dashboard-header${dashboardMode === DashboardMode.Fullscreen ? ' full-screen' : ''}`}>
{dashboardMode === DashboardMode.Fullscreen && (
<FullScreen onExit={() => setDashboardMode(null, DashboardEventSource.Browser)} />
)}
<ShareModal
onCancel={() => setDashboardMode(null, DashboardEventSource.Browser)}
visible={dashboardMode === DashboardMode.Sharing}
/>
{dashboardsLoading ? (
<Loading />
) : (
<>
{dashboardMode === DashboardMode.Edit ? (
<Input
placeholder="Dashboard name (e.g. Weekly KPIs)"
value={newName || ''}
size="large"
style={{ maxWidth: 400 }}
onChange={(e) => {
setNewName(e.target.value) // To update the input immediately
triggerDashboardUpdate({ name: e.target.value }) // This is breakpointed (i.e. debounced) to avoid multiple API calls
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
setDashboardMode(null, DashboardEventSource.InputEnter)
}
}}
ref={nameInputRef}
tabIndex={0}
/>
) : (
<div className="dashboard-select">
<Select
value={(dashboard?.id || undefined) as number | 'new' | undefined}
onChange={(id) => {
if (id === 'new') {
addNewDashboard()
} else {
router.actions.push(urls.dashboard(id))
eventUsageLogic.actions.reportDashboardDropdownNavigation()
}
}}
bordered={false}
dropdownMatchSelectWidth={false}
>
{nameSortedDashboards.map((dash: DashboardType) => (
<Select.Option key={dash.id} value={dash.id}>
{dash.name || <span style={{ color: 'var(--muted)' }}>Untitled</span>}
{dash.is_shared && (
<Tooltip title="This dashboard is publicly shared">
<ShareAltOutlined style={{ marginLeft: 4, float: 'right' }} />
</Tooltip>
)}
</Select.Option>
))}
<Select.Option value="new">+ New Dashboard</Select.Option>
</Select>
</div>
)}
<div className="dashboard-meta">
{dashboardMode === DashboardMode.Edit
? actionsEditMode
: dashboardMode === DashboardMode.Fullscreen
? actionsPresentationMode
: actionsDefault}
</div>
</>
)}
</div>
{user?.organization?.available_features?.includes(AvailableFeature.DASHBOARD_COLLABORATION) && (
<>
<div className="mb" data-attr="dashboard-tags">
<ObjectTags
tags={dashboard.tags}
onTagSave={saveNewTag}
onTagDelete={deleteTag}
saving={dashboardLoading}
tagsAvailable={dashboardTags.filter((tag) => !dashboard.tags.includes(tag))}
/>
</div>
<Description
item={dashboard}
setItemMode={setDashboardMode}
itemMode={dashboardMode}
triggerItemUpdate={triggerDashboardUpdate}
descriptionInputRef={descriptionInputRef}
/>
</>
)}
</>
)
}
Example #4
Source File: Dashboards.tsx From posthog-foss with MIT License | 4 votes |
export function Dashboards(): JSX.Element {
const { dashboardsLoading } = useValues(dashboardsModel)
const { deleteDashboard, unpinDashboard, pinDashboard, addDashboard, duplicateDashboard } =
useActions(dashboardsModel)
const { setNewDashboardDrawer, setSearchTerm, setCurrentTab } = useActions(dashboardsLogic)
const { dashboards, newDashboardDrawer, searchTerm, currentTab } = useValues(dashboardsLogic)
const { hasAvailableFeature } = useValues(userLogic)
const columns: LemonTableColumns<DashboardType> = [
{
width: 0,
dataIndex: 'pinned',
render: function Render(pinned, { id }) {
return pinned ? (
<PushpinFilled
onClick={() => unpinDashboard(id, DashboardEventSource.DashboardsList)}
style={{ cursor: 'pointer' }}
/>
) : (
<PushpinOutlined
onClick={() => pinDashboard(id, DashboardEventSource.DashboardsList)}
style={{ cursor: 'pointer' }}
/>
)
},
},
{
title: 'Name',
dataIndex: 'name',
width: '40%',
render: function Render(name, { id, description, _highlight, is_shared }) {
return (
<div className={_highlight ? 'highlighted' : undefined} style={{ display: 'inline-block' }}>
<div className="row-name">
<Link data-attr="dashboard-name" to={urls.dashboard(id)}>
{name || 'Untitled'}
</Link>
{is_shared && (
<Tooltip title="This dashboard is shared publicly.">
<ShareAltOutlined style={{ marginLeft: 6 }} />
</Tooltip>
)}
</div>
{hasAvailableFeature(AvailableFeature.DASHBOARD_COLLABORATION) && description && (
<span className="row-description">{description}</span>
)}
</div>
)
},
sorter: (a, b) => (a.name ?? 'Untitled').localeCompare(b.name ?? 'Untitled'),
},
...(hasAvailableFeature(AvailableFeature.DASHBOARD_COLLABORATION)
? [
{
title: 'Tags',
dataIndex: 'tags' as keyof DashboardType,
render: function Render(tags: DashboardType['tags']) {
return <ObjectTags tags={tags} staticOnly />
},
} as LemonTableColumn<DashboardType, keyof DashboardType | undefined>,
]
: []),
createdByColumn<DashboardType>() as LemonTableColumn<DashboardType, keyof DashboardType | undefined>,
createdAtColumn<DashboardType>() as LemonTableColumn<DashboardType, keyof DashboardType | undefined>,
{
width: 0,
render: function RenderActions(_, { id, name }: DashboardType) {
return (
<More
overlay={
<>
<LemonButton
type="stealth"
to={urls.dashboard(id)}
onClick={() => {
dashboardLogic({ id }).mount()
dashboardLogic({ id }).actions.setDashboardMode(
null,
DashboardEventSource.DashboardsList
)
}}
fullWidth
>
View
</LemonButton>
<LemonButton
type="stealth"
to={urls.dashboard(id)}
onClick={() => {
dashboardLogic({ id }).mount()
dashboardLogic({ id }).actions.setDashboardMode(
DashboardMode.Edit,
DashboardEventSource.DashboardsList
)
}}
fullWidth
>
Edit
</LemonButton>
<LemonButton type="stealth" onClick={() => duplicateDashboard({ id, name })} fullWidth>
Duplicate
</LemonButton>
<LemonSpacer />
<LemonButton
type="stealth"
style={{ color: 'var(--danger)' }}
onClick={() => deleteDashboard({ id, redirect: false })}
fullWidth
>
Delete dashboard
</LemonButton>
</>
}
/>
)
},
},
]
return (
<div>
<PageHeader
title="Dashboards"
buttons={
<Button
data-attr={'new-dashboard'}
onClick={() => setNewDashboardDrawer(true)}
type="primary"
icon={<PlusOutlined />}
>
New Dashboard
</Button>
}
/>
<Tabs
activeKey={currentTab}
style={{ borderColor: '#D9D9D9' }}
onChange={(tab) => setCurrentTab(tab as DashboardsTab)}
>
<Tabs.TabPane tab="All Dashboards" key={DashboardsTab.All} />
<Tabs.TabPane tab="Pinned" key={DashboardsTab.Pinned} />
<Tabs.TabPane tab="Shared" key={DashboardsTab.Shared} />
</Tabs>
<div>
<Input.Search
allowClear
enterButton
placeholder="Search for dashboards"
style={{ width: 240 }}
value={searchTerm}
onChange={(e) => {
setSearchTerm(e.target.value)
}}
/>
</div>
<LemonSpacer large />
<Drawer
title="New Dashboard"
width={400}
onClose={() => setNewDashboardDrawer(false)}
destroyOnClose={true}
visible={newDashboardDrawer}
>
<NewDashboard />
</Drawer>
{dashboardsLoading ? (
<div className="flex-center" style={{ flexDirection: 'column' }}>
<Spinner />
<div className="mt">
<b>Loading dashboards</b>
</div>
</div>
) : dashboards.length > 0 || searchTerm || currentTab !== DashboardsTab.All ? (
<LemonTable
dataSource={dashboards}
rowKey="id"
columns={columns}
defaultSorting={{ columnKey: 'name', order: 1 }}
emptyState={
searchTerm ? (
`No ${
currentTab === DashboardsTab.Pinned
? 'pinned '
: currentTab === DashboardsTab.Shared
? 'shared '
: ''
}dashboards matching "${searchTerm}"!`
) : currentTab === DashboardsTab.Pinned ? (
<>
No dashboards have been pinned for quick access yet.{' '}
<Link onClick={() => setCurrentTab(DashboardsTab.All)}>
Go to All Dashboards to pin one.
</Link>
</>
) : currentTab === DashboardsTab.Shared ? (
<>
No dashboards have been shared yet.{' '}
<Link onClick={() => setCurrentTab(DashboardsTab.All)}>
Go to All Dashboards to share one.
</Link>
</>
) : undefined
}
nouns={['dashboard', 'dashboards']}
/>
) : (
<div className="mt">
<p>Create your first dashboard:</p>
<Row gutter={[16, 16]}>
<Col xs={24} xl={6}>
<Card
title="Empty"
size="small"
style={{ cursor: 'pointer' }}
onClick={() =>
addDashboard({
name: 'New Dashboard',
show: true,
useTemplate: '',
})
}
>
<div style={{ textAlign: 'center', fontSize: 40 }}>
<AppstoreAddOutlined />
</div>
</Card>
</Col>
<Col xs={24} xl={6}>
<Card
title="App Default"
size="small"
style={{ cursor: 'pointer' }}
onClick={() =>
addDashboard({
name: 'Web App Dashboard',
show: true,
useTemplate: 'DEFAULT_APP',
})
}
>
<div style={{ textAlign: 'center', fontSize: 40 }}>
<AppstoreAddOutlined />
</div>
</Card>
</Col>
</Row>
</div>
)}
</div>
)
}
Example #5
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 #6
Source File: index.tsx From fe-v5 with Apache License 2.0 | 4 votes |
function Chart(props: Props) {
const { t } = useTranslation();
const { options, barControl, rightBar, title } = props;
const [refreshing, setRefreshing] = useState(false);
const chartRef = useRef(null);
const location = useLocation();
const { metric, description = '', tags, range, limit, idents, classpath_id, classpath_prefix, prome_ql, yplotline, xplotline, step } = options;
const [privateTags, setPrivateTags] = useState<TagType[]>([]);
const [multi, setMulti] = useState(false);
const [sort, setSort] = useState<'desc' | 'asc'>('desc');
const [tooltipFormat, setTooltipFormat] = useState<'origin' | 'short'>('origin');
const [instance, setInstance] =
useState<{
destroy: Function;
update: Function;
options: {
yAxis: object;
xAxis: object;
};
} | null>(null); // transfer Param and RangeItem into timestamp
const formatDate = (r?: Range) => {
let newR = r || range;
if (newR) {
if (isAbsoluteRange(newR)) {
const { start, end } = newR;
return {
start,
end,
};
} else {
return generateTimeStampRange(newR);
}
}
return {
start: 0,
end: 0,
};
};
const { start, end } = formatDate(range);
const initChart = (privateTags: TagType[] = []) => {
let newTags = privateTags;
if (tags && tags.length > 0) {
newTags = tags.concat(newTags);
}
let params = Array.isArray(metric)
? metric.map((item) => {
return {
metric: item,
classpath_id,
classpath_prefix: classpath_prefix === undefined ? undefined : classpath_prefix ? 1 : 0,
prome_ql,
tags: newTags && newTags.length > 0 ? newTags : undefined,
idents,
};
})
: Array.isArray(prome_ql)
? prome_ql.map((item) => {
return {
metric,
classpath_id,
classpath_prefix: classpath_prefix === undefined ? undefined : classpath_prefix ? 1 : 0,
prome_ql: item,
tags: newTags && newTags.length > 0 ? newTags : undefined,
idents,
};
})
: [
{
metric,
classpath_id,
classpath_prefix: classpath_prefix ? 1 : 0,
prome_ql,
tags: newTags && newTags.length > 0 ? newTags : undefined,
idents,
},
];
// GetData({
// params,
// start,
// end,
// limit,
// step,
// }).then((data) => {
// const dataY: DataSource[] = [];
// data.dat.forEach((dataItem) => {
// dataY.push({
// name: dataItem.metric,
// data: dataItem.values.map((item) => item.v),
// });
// });
// const series: Array<any> = [];
// data.dat.forEach((dataItem) => {
// const { metric, values, tags } = dataItem;
// const seriesData = values.map((item) => {
// return {
// timestamp: item.t * 1000,
// value: item.v,
// };
// });
// series.push({
// name: (metric ? `【${metric}】` : '') + tags,
// data: seriesData,
// });
// });
// // if (chartRef.current) {
// // // @ts-ignore
// // chartRef.current.innerHTML = '';
// // }
// let graphOption = instance
// ? {
// series: series,
// tooltip: {
// precision: tooltipFormat,
// shared: multi,
// sharedSortDirection: sort,
// },
// // 必须xAxis和yAxis必须将属性返回
// yAxis: {
// ...instance.options.yAxis,
// plotLines: yplotline
// ? [
// {
// value: yplotline,
// color: 'red',
// },
// ]
// : undefined,
// },
// xAxis: {
// ...instance.options.xAxis,
// plotLines: xplotline
// ? [
// {
// value: xplotline * 1000,
// color: 'red',
// },
// ]
// : undefined,
// },
// }
// : {
// timestamp: 'x',
// xkey: 'timestamp',
// ykey: 'value',
// chart: {
// renderTo: chartRef.current,
// },
// yAxis: {
// plotLines: yplotline
// ? [
// {
// value: yplotline,
// color: 'red',
// },
// ]
// : undefined,
// },
// xAxis: {
// plotLines: xplotline
// ? [
// {
// value: xplotline * 1000,
// color: 'red',
// },
// ]
// : undefined,
// },
// series: series,
// tooltip: {
// precision: tooltipFormat,
// shared: multi,
// sharedSortDirection: sort,
// },
// };
// if (instance) {
// instance.update(graphOption);
// } else {
// setInstance(new TsGraph(graphOption));
// }
// });
};
useEffect(() => {
initChart(privateTags);
}, [options, multi, sort, tooltipFormat]);
// each chart is mounted once, when props and state change, the instance will update.
// so below hook only run once.
useEffect(() => {
return () => {
instance && instance.destroy();
};
}, [instance]);
const handleRefresh = (e) => {
if (refreshing) return;
setRefreshing(true);
initChart(privateTags); //需要将选择的过滤器传进去
setTimeout(() => {
setRefreshing(false);
}, 1000);
};
const handleChartTagsChange = (e: TagType[]) => {
setPrivateTags(e);
initChart(e);
};
const handleMultiChange = (e) => {
setMulti(e.target.checked);
};
const handleOrderSortChange = (bool) => {
setSort(bool ? 'desc' : 'asc');
};
const handleTooltipFormat = (e) => {
setTooltipFormat(e.target.checked ? 'short' : 'origin');
};
const renderMultiOrSort = (
<>
<Tooltip title={t('tooltip中展示所有曲线的值')}>
<Checkbox onChange={handleMultiChange}>Multi</Checkbox>
</Tooltip>
<Tooltip
title={
<>
<span>{t('SI格式化:')}</span>
<a type='link' href='https://en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes' target='_blank'>
{t('文档')}
</a>
</>
}
>
<Checkbox onChange={handleTooltipFormat}>Format</Checkbox>
</Tooltip>
<OrderSort onChange={handleOrderSortChange} />
</>
);
return (
<div className='chart-wrapper'>
{(title || rightBar || description || metric) && (
<div className='chart-title'>
{title ? (
<div className='chart-title-label'>{title}</div>
) : (
<div className='chart-title-label'>
{metric} {description}
</div>
)}
<div className='chart-title-right-bar'>
{rightBar}
{!location.pathname.startsWith('/chart/') && (
<Button
type='link'
size='small'
onClick={async (e) => {
e.preventDefault();
let { dat: ids } = await SetTmpChartData([{ configs: JSON.stringify({ title, options, barControl }) }]);
window.open('/chart/' + ids);
}}
>
<ShareAltOutlined />
</Button>
)}
</div>
</div>
)}
{!barControl && (
<div className='chart-filter'>
<ReloadOutlined className='refresh' spin={refreshing} onClick={handleRefresh} />
{renderMultiOrSort}
{!prome_ql && (
<TagFilterForChart
options={{
...options,
start,
end,
idents,
}}
onChange={handleChartTagsChange}
/>
)}
</div>
)}
{barControl === 'multiOrSort' && <div className='chart-filter'>{renderMultiOrSort}</div>}
<div ref={chartRef} className='chart-content'></div>
</div>
);
}
Example #7
Source File: index.tsx From fe-v5 with Apache License 2.0 | 4 votes |
function index(props: IProps) {
const { dashboardId, id, time, refreshFlag, step, type, variableConfig, isPreview, onCloneClick, onShareClick, onEditClick, onDeleteClick } = props;
const values = _.cloneDeep(props.values);
const ref = useRef<HTMLDivElement>(null);
const [inViewPort] = useInViewport(ref);
const { series, loading } = usePrometheus({
id,
dashboardId,
time,
refreshFlag,
step,
targets: values.targets,
variableConfig,
inViewPort: isPreview || inViewPort,
});
const tipsVisible = values.description || !_.isEmpty(values.links);
if (_.isEmpty(values)) return null;
// TODO: 如果 hexbin 的 colorRange 为 string 时转成成 array
if (typeof _.get(values, 'custom.colorRange') === 'string') {
_.set(values, 'custom.colorRange', _.split(_.get(values, 'custom.colorRange'), ','));
}
const subProps = {
values,
series,
};
const RendererCptMap = {
timeseries: () => <Timeseries {...subProps} />,
stat: () => <Stat {...subProps} />,
table: () => <Table {...subProps} />,
pie: () => <Pie {...subProps} />,
hexbin: () => <Hexbin {...subProps} />,
};
return (
<div className='renderer-container' ref={ref}>
<div className='renderer-header graph-header dashboards-panels-item-drag-handle'>
{tipsVisible ? (
<Tooltip
placement='rightTop'
overlayInnerStyle={{
width: 300,
}}
title={
<div>
<Markdown content={values.description} />
<div>
{_.map(values.links, (link, i) => {
return (
<div key={i} style={{ marginTop: 8 }}>
<a href={link.url} target={link.targetBlank ? '_blank' : '_self'}>
{link.title}
</a>
</div>
);
})}
</div>
</div>
}
>
<div className='renderer-header-desc'>
<span className='renderer-header-info-corner-inner' />
{values.description ? <InfoOutlined /> : <LinkOutlined />}
</div>
</Tooltip>
) : null}
<div className='renderer-header-content'>
{!isPreview ? (
<Dropdown
trigger={['click']}
placement='bottomCenter'
overlayStyle={{
minWidth: '100px',
}}
overlay={
<Menu>
{!isPreview ? (
<>
<Menu.Item onClick={onEditClick} key='0'>
<SettingOutlined style={{ marginRight: 8 }} />
编辑
</Menu.Item>
<Menu.Item onClick={onCloneClick} key='1'>
<CopyOutlined style={{ marginRight: 8 }} />
克隆
</Menu.Item>
<Menu.Item onClick={onShareClick} key='2'>
<ShareAltOutlined style={{ marginRight: 8 }} />
分享
</Menu.Item>
<Menu.Item onClick={onDeleteClick} key='3'>
<DeleteOutlined style={{ marginRight: 8 }} />
删除
</Menu.Item>
</>
) : null}
</Menu>
}
>
<div className='renderer-header-title'>
{values.name}
<DownOutlined className='renderer-header-arrow' />
</div>
</Dropdown>
) : (
<div className='renderer-header-title'>{values.name}</div>
)}
</div>
<div className='renderer-header-loading'>{loading && <SyncOutlined spin />}</div>
</div>
<div className='renderer-body' style={{ height: `calc(100% - 36px)` }}>
{RendererCptMap[type] ? RendererCptMap[type]() : `无效的图表类型 ${type}`}
</div>
</div>
);
}
Example #8
Source File: Graph.tsx From fe-v5 with Apache License 2.0 | 4 votes |
export default function Graph(props: IProps) {
const { metric, match, range, step, onClose } = props;
const newGroups = _.map(
_.filter(match.dimensionLabels, (item) => !_.isEmpty(item.value)),
'label',
);
const [refreshFlag, setRefreshFlag] = useState(_.uniqueId('refreshFlag_'));
const [calcFunc, setCalcFunc] = useState('');
const [comparison, setComparison] = useState<string[]>([]);
const [aggrFunc, setAggrFunc] = useState('avg');
const [aggrGroups, setAggrGroups] = useState<string[]>(newGroups);
const [labels, setLabels] = useState<string[]>([]);
const [series, setSeries] = useState<any[]>([]);
const [highLevelConfig, setHighLevelConfig] = useState({
shared: true,
sharedSortDirection: 'desc',
legend: true,
util: 'none',
colorRange: colors[0].value,
reverseColorOrder: false,
colorDomainAuto: true,
colorDomain: [],
chartheight: 300,
});
const [chartType, setChartType] = useState('line');
const [reduceFunc, setReduceFunc] = useState('last');
const lineGraphProps = {
custom: {
drawStyle: 'lines',
fillOpacity: 0,
stack: 'hidden',
lineInterpolation: 'smooth',
},
options: {
legend: {
displayMode: highLevelConfig.legend ? 'list' : 'hidden',
},
tooltip: {
mode: highLevelConfig.shared ? 'all' : 'single',
sort: highLevelConfig.sharedSortDirection,
},
standardOptions: {
util: highLevelConfig.util,
},
},
};
const hexbinGraphProps = {
custom: {
calc: reduceFunc,
colorRange: highLevelConfig.colorRange,
reverseColorOrder: highLevelConfig.reverseColorOrder,
colorDomainAuto: highLevelConfig.colorDomainAuto,
colorDomain: highLevelConfig.colorDomain,
},
options: {
standardOptions: {
util: highLevelConfig.util,
},
},
};
const graphStandardOptions = {
line: <LineGraphStandardOptions highLevelConfig={highLevelConfig} setHighLevelConfig={setHighLevelConfig} />,
hexbin: <HexbinGraphStandardOptions highLevelConfig={highLevelConfig} setHighLevelConfig={setHighLevelConfig} />,
};
useEffect(() => {
setAggrGroups(newGroups);
}, [JSON.stringify(newGroups)]);
useEffect(() => {
const matchStr = getMatchStr(match);
getLabels(`${metric}${matchStr}`, range).then((res) => {
setLabels(res);
});
}, [refreshFlag, JSON.stringify(match), JSON.stringify(range)]);
useEffect(() => {
getQueryRange({
metric,
match: getMatchStr(match),
range,
step,
aggrFunc,
aggrGroups,
calcFunc,
comparison,
}).then((res) => {
setSeries(res);
});
}, [refreshFlag, metric, JSON.stringify(match), JSON.stringify(range), step, calcFunc, comparison, aggrFunc, aggrGroups]);
return (
<Card
size='small'
style={{ marginBottom: 10 }}
title={metric}
className='n9e-metric-views-metrics-graph'
extra={
<Space>
<Space size={0} style={{ marginRight: 10 }}>
<LineChartOutlined
className={classNames({
'button-link-icon': true,
active: chartType === 'line',
})}
onClick={() => {
setChartType('line');
}}
/>
<Divider type='vertical' />
<HexbinIcon
className={classNames({
'button-link-icon': true,
active: chartType === 'hexbin',
})}
onClick={() => {
setChartType('hexbin');
}}
/>
</Space>
<Popover placement='left' content={graphStandardOptions[chartType]} trigger='click' autoAdjustOverflow={false} getPopupContainer={() => document.body}>
<a>
<SettingOutlined />
</a>
</Popover>
<a>
<SyncOutlined
onClick={() => {
setRefreshFlag(_.uniqueId('refreshFlag_'));
}}
/>
</a>
<a>
<ShareAltOutlined
onClick={() => {
const curCluster = localStorage.getItem('curCluster');
const dataProps = {
type: 'timeseries',
version: '2.0.0',
name: metric,
step,
range,
...lineGraphProps,
targets: _.map(
getExprs({
metric,
match: getMatchStr(match),
aggrFunc,
aggrGroups,
calcFunc,
comparison,
}),
(expr) => {
return {
expr,
};
},
),
};
setTmpChartData([
{
configs: JSON.stringify({
curCluster,
dataProps,
}),
},
]).then((res) => {
const ids = res.dat;
window.open('/chart/' + ids);
});
}}
/>
</a>
<a>
<CloseCircleOutlined onClick={onClose} />
</a>
</Space>
}
>
<div>
<Space>
<div>
计算函数:
<Dropdown
overlay={
<Menu onClick={(e) => setCalcFunc(e.key === 'clear' ? '' : e.key)} selectedKeys={[calcFunc]}>
<Menu.Item key='rate_1m'>rate_1m</Menu.Item>
<Menu.Item key='rate_5m'>rate_5m</Menu.Item>
<Menu.Item key='increase_1m'>increase_1m</Menu.Item>
<Menu.Item key='increase_5m'>increase_5m</Menu.Item>
<Menu.Divider></Menu.Divider>
<Menu.Item key='clear'>clear</Menu.Item>
</Menu>
}
>
<a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
{calcFunc || '无'} <DownOutlined />
</a>
</Dropdown>
</div>
<div>
环比:
{comparison.map((ag) => (
<Tag
key={ag}
closable
onClose={() => {
setComparison(_.without(comparison, ag));
}}
>
{ag}
</Tag>
))}
<Dropdown
overlay={
<Menu
onClick={(e) => {
if (comparison.indexOf(e.key) === -1) {
setComparison([...comparison, e.key]);
} else {
setComparison(_.without(comparison, e.key));
}
}}
selectedKeys={comparison}
>
<Menu.Item key='1d'>1d</Menu.Item>
<Menu.Item key='7d'>7d</Menu.Item>
</Menu>
}
overlayStyle={{ maxHeight: 400, overflow: 'auto' }}
>
<a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
<PlusCircleOutlined />
</a>
</Dropdown>
</div>
<div>
聚合函数:
<Dropdown
overlay={
<Menu onClick={(e) => setAggrFunc(e.key)} selectedKeys={[aggrFunc]}>
<Menu.Item key='sum'>sum</Menu.Item>
<Menu.Item key='avg'>avg</Menu.Item>
<Menu.Item key='max'>max</Menu.Item>
<Menu.Item key='min'>min</Menu.Item>
</Menu>
}
>
<a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
{aggrFunc} <DownOutlined />
</a>
</Dropdown>
</div>
{aggrFunc ? (
<div className='graph-config-inner-item'>
聚合维度:
{aggrGroups.map((ag) => (
<Tag
key={ag}
closable
onClose={() => {
setAggrGroups(_.without(aggrGroups, ag));
}}
>
{ag}
</Tag>
))}
<Dropdown
overlay={
<Menu
onClick={(e) => {
if (aggrGroups.indexOf(e.key) === -1) {
setAggrGroups([...aggrGroups, e.key]);
} else {
setAggrGroups(_.without(aggrGroups, e.key));
}
}}
selectedKeys={aggrGroups}
>
{_.map(
_.filter(labels, (n) => n !== '__name__'),
(ag) => (
<Menu.Item key={ag}>{ag}</Menu.Item>
),
)}
</Menu>
}
overlayStyle={{ maxHeight: 400, overflow: 'auto' }}
>
<a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
<PlusCircleOutlined />
</a>
</Dropdown>
</div>
) : null}
{chartType === 'hexbin' && (
<div>
取值计算:
<Dropdown
overlay={
<Menu onClick={(e) => setReduceFunc(e.key)} selectedKeys={[reduceFunc]}>
{_.map(calcsOptions, (val, key) => {
return <Menu.Item key={key}>{val.name}</Menu.Item>;
})}
</Menu>
}
>
<a className='ant-dropdown-link' onClick={(e) => e.preventDefault()}>
{calcsOptions[reduceFunc]?.name} <DownOutlined />
</a>
</Dropdown>
</div>
)}
</Space>
</div>
<div>
{chartType === 'line' && <Timeseries inDashboard={false} values={lineGraphProps as any} series={series} />}
{chartType === 'hexbin' && (
<div style={{ padding: '20px 0 0 0', height: highLevelConfig.chartheight }}>
<Hexbin values={hexbinGraphProps as any} series={series} />
</div>
)}
</div>
</Card>
);
}
Example #9
Source File: index.tsx From fe-v5 with Apache License 2.0 | 4 votes |
function index(props: IProps) {
const { dashboardId, id, time, refreshFlag, step, type, variableConfig, values, isPreview, onCloneClick, onShareClick, onEditClick, onDeleteClick } = props;
const ref = useRef<HTMLDivElement>(null);
const [inViewPort] = useInViewport(ref);
const { series, loading } = usePrometheus({
id,
dashboardId,
time,
refreshFlag,
step,
targets: values.targets,
variableConfig,
inViewPort: isPreview || inViewPort,
});
const subProps = {
values,
series,
};
const tipsVisible = values.description || !_.isEmpty(values.links);
if (_.isEmpty(values)) return null;
const RendererCptMap = {
timeseries: () => <Timeseries {...subProps} />,
stat: () => <Stat {...subProps} />,
table: () => <Table {...subProps} />,
pie: () => <Pie {...subProps} />,
};
return (
<div className='renderer-container' ref={ref}>
<div className='renderer-header graph-header dashboards-panels-item-drag-handle'>
{tipsVisible ? (
<Tooltip
placement='rightTop'
overlayInnerStyle={{
width: 300,
}}
title={
<div>
<Markdown content={values.description} />
<div>
{_.map(values.links, (link) => {
return (
<div style={{ marginTop: 8 }}>
<a href={link.url} target={link.targetBlank ? '_blank' : '_self'}>
{link.title}
</a>
</div>
);
})}
</div>
</div>
}
>
<div className='renderer-header-desc'>
<span className='renderer-header-info-corner-inner' />
{values.description ? <InfoOutlined /> : <LinkOutlined />}
</div>
</Tooltip>
) : null}
<div className='renderer-header-content'>
{!isPreview ? (
<Dropdown
trigger={['click']}
placement='bottomCenter'
overlayStyle={{
minWidth: '100px',
}}
overlay={
<Menu>
{!isPreview ? (
<>
<Menu.Item onClick={onEditClick} key='0'>
<SettingOutlined style={{ marginRight: 8 }} />
编辑
</Menu.Item>
<Menu.Item onClick={onCloneClick} key='1'>
<CopyOutlined style={{ marginRight: 8 }} />
克隆
</Menu.Item>
<Menu.Item onClick={onShareClick} key='2'>
<ShareAltOutlined style={{ marginRight: 8 }} />
分享
</Menu.Item>
<Menu.Item onClick={onDeleteClick} key='3'>
<DeleteOutlined style={{ marginRight: 8 }} />
删除
</Menu.Item>
</>
) : null}
</Menu>
}
>
<div className='renderer-header-title'>
{values.name}
<DownOutlined className='renderer-header-arrow' />
</div>
</Dropdown>
) : (
<div className='renderer-header-title'>{values.name}</div>
)}
</div>
<div className='renderer-header-loading'>{loading && <SyncOutlined spin />}</div>
</div>
<div className='renderer-body' style={{ height: `calc(100% - 36px)` }}>
{RendererCptMap[type] ? RendererCptMap[type]() : `无效的图表类型 ${type}`}
</div>
</div>
);
}
Example #10
Source File: ShareTicketModal.tsx From condo with MIT License | 4 votes |
ShareTicketModal: React.FC<IShareTicketModalProps> = (props) => {
const intl = useIntl()
const SendTicketToEmailMessage = intl.formatMessage({ id: 'SendTicketToEmail' })
const ToEmployeesEmailMessage = intl.formatMessage({ id: 'ToEmployeesEmail' })
const EmployeesNameMessage = intl.formatMessage({ id: 'EmployeesName' })
const ServerErrorMessage = intl.formatMessage({ id: 'ServerError' })
const WhatsappMessage = intl.formatMessage({ id: 'WhatsApp' })
const TelegramMessage = intl.formatMessage({ id: 'Telegram' })
const ShareHeaderMessage = intl.formatMessage({ id: 'ticket.shareHeader' })
const ShareButtonMessage = intl.formatMessage({ id: 'ticket.shareButton' })
const OKMessage = intl.formatMessage({ id: 'OK' })
const ShareSentMessage = intl.formatMessage({ id: 'ticket.shareSent' })
const ShareSentToEmailMessage = intl.formatMessage({ id: 'ticket.shareSentToEmail' })
const { isSmall } = useLayoutContext()
const { date, number, details, id, locale, organization } = props
const cipher = crypto.createCipher(ALGORITHM, SALT)
let cutDetails = details || ''
if (cutDetails.length >= 110) {
cutDetails = `${cutDetails.substr(0, 100)}…`
}
const stringifiedParams = JSON.stringify({ date, number, details: cutDetails, id })
const encryptedText = cipher.update(stringifiedParams, 'utf8', CRYPTOENCODING) + cipher.final(CRYPTOENCODING)
const { query } = useRouter()
const [shareTicket] = useMutation(SHARE_TICKET_MUTATION)
const {
publicRuntimeConfig: { serverUrl: origin },
} = getConfig()
const [chosenEmployees, setChosenEmployees] = useState([])
const [loading, setLoading] = useState(false)
const [shareVisible, setShareVisible] = useState(false)
const [okVisible, setOkVisible] = useState(false)
const [usersWithoutEmail, setUsersWithoutEmail] = useState([])
const parseSelectValue = (selectedEmployees) => {
try {
return selectedEmployees.map(JSON.parse)
} catch (error) {
console.error('Invalid format for employees in multiple select', selectedEmployees)
}
}
function handleSelect (value) {
const withoutEmails = parseSelectValue(value).filter(item => !get(item, 'value.hasEmail')).map(item => item.text)
setUsersWithoutEmail(withoutEmails)
setChosenEmployees(value)
}
async function handleClick () {
setLoading(true)
const sender = getClientSideSenderInfo()
const { data, error } = await shareTicket({
variables: {
data: {
sender,
employees: parseSelectValue(chosenEmployees).filter(employee => get(employee, 'value.hasEmail')).map(employee => employee.id),
ticketId: query.id,
},
},
})
if (data && data.obj) {
setChosenEmployees([])
setShareVisible(false)
setOkVisible(true)
setUsersWithoutEmail([])
}
if (error) {
console.error(error)
notification.error({
message: ServerErrorMessage,
description: error.message,
})
}
setLoading(false)
}
function handleCancel () {
setShareVisible(false)
}
function handleShow () {
setShareVisible(true)
}
function handleClickSecond () {
setOkVisible(false)
}
return (
<>
<Button
type={'sberDefaultGradient'}
icon={<ShareAltOutlined />}
secondary
onClick={handleShow}
css={sendButton}
>
{ShareButtonMessage}
</Button>
<Modal
style={{ top: 30 }}
visible={okVisible}
footer={<Button
type='sberPrimary'
size='large'
onClick={handleClickSecond}
>
{OKMessage}
</Button>}
onCancel={handleCancel}
title={ShareSentMessage}
>
{ShareSentToEmailMessage}
</Modal>
<Modal
style={{ top: 30 }}
visible={shareVisible}
footer={null}
onCancel={handleCancel}
title={<Typography.Title level={isSmall ? 5 : 3}>{ShareHeaderMessage}</Typography.Title>}
>
<Row gutter={[0, 16]}>
<Col span={24}>
<a
target='_blank'
rel='noreferrer'
href={`https://wa.me/?text=${encodeURIComponent(`${origin}/share?q=${encryptedText}&locale=${locale || EN_LOCALE}`)}`}
>
<ShareButton>
{WhatsappMessage}
<RightOutlined />
</ShareButton>
</a>
</Col>
<Col span={24}>
<a
target='_blank'
rel='noreferrer'
href={`https://t.me/share/url?url=${encodeURIComponent(`${origin}/share?q=${encryptedText}&locale=${locale || EN_LOCALE}`)}`}
>
<ShareButton>
{TelegramMessage}
<RightOutlined />
</ShareButton>
</a>
</Col>
<Col span={24}>
<Collapse expandIconPosition='right' css={collapse}>
<Collapse.Panel key='1' header={ToEmployeesEmailMessage}>
<GraphQlSearchInput
search={getEmployeeWithEmail(get(organization, 'id'))}
showArrow={false}
mode='multiple'
css={search}
onChange={handleSelect}
value={chosenEmployees}
placeholder={EmployeesNameMessage}
autoClearSearchValue={true}
/>
{
!isEmpty(usersWithoutEmail) &&
<Warning>
{usersWithoutEmail}
</Warning>
}
{
!isEmpty(chosenEmployees) &&
<Button
type='sberPrimary'
size='large'
onClick={handleClick}
style={{ marginTop: '20px' }}
disabled={loading}
>
{SendTicketToEmailMessage}
</Button>
}
</Collapse.Panel>
</Collapse>
</Col>
</Row>
</Modal>
</>
)
}
Example #11
Source File: VizOperationMenu.tsx From datart with Apache License 2.0 | 4 votes |
VizOperationMenu: FC<{
onShareLinkClick?;
onDownloadDataLinkClick?;
onSaveAsVizs?;
onReloadData?;
onAddToDashBoard?;
onPublish?;
onRecycleViz?;
allowDownload?: boolean;
allowShare?: boolean;
allowManage?: boolean;
isArchived?: boolean;
}> = memo(
({
onShareLinkClick,
onDownloadDataLinkClick,
onSaveAsVizs,
onReloadData,
onAddToDashBoard,
onPublish,
allowDownload,
allowShare,
allowManage,
isArchived,
onRecycleViz,
}) => {
const t = useI18NPrefix(`viz.action`);
const tg = useI18NPrefix(`global`);
const moreActionMenu = () => {
const menus: any[] = [];
if (onReloadData) {
menus.push(
<Menu.Item
key="reloadData"
icon={<ReloadOutlined />}
onClick={onReloadData}
>
{t('syncData')}
</Menu.Item>,
<Menu.Divider key={'reloadDataLine'} />,
);
}
if (allowManage && onSaveAsVizs) {
menus.push(
<Menu.Item key="saveAs" icon={<CopyFilled />} onClick={onSaveAsVizs}>
{tg('button.saveAs')}
</Menu.Item>,
);
}
if (allowManage && onSaveAsVizs) {
menus.push(
<Menu.Item
key="addToDash"
icon={<FileAddOutlined />}
onClick={() => onAddToDashBoard(true)}
>
{t('addToDash')}
</Menu.Item>,
<Menu.Divider key="addToDashLine" />,
);
}
if (allowShare && onShareLinkClick) {
menus.push(
<Menu.Item
key="shareLink"
icon={<ShareAltOutlined />}
onClick={onShareLinkClick}
>
{t('share.shareLink')}
</Menu.Item>,
);
}
if (allowDownload && onDownloadDataLinkClick) {
menus.push(
<Menu.Item key="downloadData" icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
onConfirm={() => {
onDownloadDataLinkClick(DownloadFileType.Excel);
}}
okText={t('common.ok')}
cancelText={t('common.cancel')}
>
{t('share.downloadData')}
</Popconfirm>
</Menu.Item>,
<Menu.Item key="downloadPDF" icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
onConfirm={() => {
onDownloadDataLinkClick(DownloadFileType.Pdf);
}}
okText={t('common.ok')}
cancelText={t('common.cancel')}
>
{t('share.downloadPDF')}
</Popconfirm>
</Menu.Item>,
<Menu.Item key="downloadPicture" icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
onConfirm={() => {
onDownloadDataLinkClick(DownloadFileType.Image);
}}
okText={t('common.ok')}
cancelText={t('common.cancel')}
>
{t('share.downloadPicture')}
</Popconfirm>
</Menu.Item>,
<Menu.Divider />,
<Menu.Divider key="downloadDataLine" />,
);
}
if (allowManage && !isArchived && onPublish) {
menus.push(
<Menu.Item
key="publish"
icon={<VerticalAlignBottomOutlined />}
onClick={onPublish}
>
{t('unpublish')}
</Menu.Item>,
);
}
if (allowManage && onRecycleViz) {
menus.push(
<Menu.Item key="delete" icon={<DeleteOutlined />}>
<Popconfirm
title={tg('operation.archiveConfirm')}
onConfirm={onRecycleViz}
>
{tg('button.archive')}
</Popconfirm>
</Menu.Item>,
);
}
return <Menu>{menus}</Menu>;
};
return <StyleVizOperationMenu>{moreActionMenu()}</StyleVizOperationMenu>;
},
)
Example #12
Source File: BoardDropdownList.tsx From datart with Apache License 2.0 | 4 votes |
BoardDropdownList: FC<Props> = memo(
({ onOpenShareLink, openStoryList }) => {
const t = useI18NPrefix(`viz.action`);
const tg = useI18NPrefix(`global`);
const dispatch = useDispatch();
const {
allowDownload,
allowShare,
allowManage,
renderMode,
status,
orgId,
boardId,
} = useContext(BoardContext);
const recycleViz = useRecycleViz(orgId, boardId, 'DASHBOARD');
const saveAsViz = useSaveAsViz();
const reloadData = () => {
dispatch(widgetsQueryAction({ boardId, renderMode }));
};
const { onBoardToDownLoad } = useContext(BoardActionContext);
const { publishBoard } = usePublishBoard(boardId, 'DASHBOARD', status);
return (
<Menu>
<Menu.Item
key="reloadData"
onClick={reloadData}
icon={<ReloadOutlined />}
>
{t('syncData')}
</Menu.Item>
{allowShare && (
<>
<Menu.Divider key={'shareLinkLine'} />
<Menu.Item
key={'shareLink'}
onClick={onOpenShareLink}
icon={<ShareAltOutlined />}
>
{t('share.shareLink')}
</Menu.Item>
</>
)}
{allowDownload && (
<>
<Menu.Divider key={'downloadDataLine'} />
<Menu.Item key={'downloadData'} icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
okText={t('common.ok')}
cancelText={t('common.cancel')}
onConfirm={() => {
onBoardToDownLoad?.(DownloadFileType.Excel);
}}
>
{t('share.downloadData')}
</Popconfirm>
</Menu.Item>
<Menu.Item key={'downloadPDF'} icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
okText={t('common.ok')}
cancelText={t('common.cancel')}
onConfirm={() => {
onBoardToDownLoad?.(DownloadFileType.Pdf);
}}
>
{t('share.downloadPDF')}
</Popconfirm>
</Menu.Item>
<Menu.Item key={'downloadPicture'} icon={<CloudDownloadOutlined />}>
<Popconfirm
placement="left"
title={t('common.confirm')}
okText={t('common.ok')}
cancelText={t('common.cancel')}
onConfirm={() => {
onBoardToDownLoad?.(DownloadFileType.Image);
}}
>
{t('share.downloadPicture')}
</Popconfirm>
</Menu.Item>
</>
)}
{allowManage && (
<>
<Menu.Divider key="unpublishLine" />
{status === 2 && (
<Menu.Item
key={'unpublish'}
onClick={publishBoard}
icon={<FileAddOutlined />}
>
{t('unpublish')}
</Menu.Item>
)}
<Menu.Item
key={'saveAs'}
onClick={() => saveAsViz(boardId, 'DASHBOARD')}
icon={<CopyFilled />}
>
{tg('button.saveAs')}
</Menu.Item>
<Menu.Item
key={'addToStory'}
onClick={openStoryList}
icon={<FileAddOutlined />}
>
{t('addToStory')}
</Menu.Item>
<Menu.Item
key={'archive'}
onClick={recycleViz}
icon={<DeleteOutlined />}
>
{tg('button.archive')}
</Menu.Item>
</>
)}
</Menu>
);
},
)