refine Semi UI alert and access workspaces
This commit is contained in:
@@ -132,11 +132,16 @@ test('renders mobile access vehicles as selectable Semi cards', async () => {
|
||||
prepareBaseData();
|
||||
mocks.accessVehicles.mockResolvedValue({ items: [accessRow('VIN001', '粤A00001')], total: 1, limit: 50, offset: 0 });
|
||||
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||
render(<QueryClientProvider client={client}><MemoryRouter future={ROUTER_FUTURE} initialEntries={['/access']}><AccessPage /></MemoryRouter></QueryClientProvider>);
|
||||
const view = render(<QueryClientProvider client={client}><MemoryRouter future={ROUTER_FUTURE} initialEntries={['/access']}><AccessPage /></MemoryRouter></QueryClientProvider>);
|
||||
|
||||
const action = await screen.findByRole('button', { name: '查看 粤A00001 接入详情' });
|
||||
expect(action).toHaveClass('semi-button', 'v2-access-mobile-action');
|
||||
expect(action.closest('.semi-card')).toHaveClass('v2-access-mobile-card');
|
||||
expect(view.container.querySelector('.v2-access-table-scroll-v3.is-mobile-scroll')).toHaveAttribute('tabindex', '0');
|
||||
expect(view.container.querySelector('.v2-access-table-scroll-v3.is-mobile-scroll')).toHaveAttribute('aria-label', '车辆接入列表,可上下滚动');
|
||||
expect(within(action).getByText('GB32960')).toBeInTheDocument();
|
||||
expect(within(action).getByText('JT808')).toBeInTheDocument();
|
||||
expect(within(action).getByText('YUTONG_MQTT')).toBeInTheDocument();
|
||||
expect(action).toHaveAttribute('aria-pressed', 'false');
|
||||
expect(action).toHaveAttribute('aria-expanded', 'false');
|
||||
fireEvent.click(action);
|
||||
|
||||
@@ -40,7 +40,7 @@ function compactTime(value: string) {
|
||||
return compactAccessTimeFormatter.format(parsed).replace(/\//g, '-');
|
||||
}
|
||||
|
||||
function ProtocolState({ status, detailed = false }: { status?: AccessProtocolStatus; detailed?: boolean }) {
|
||||
function ProtocolState({ status, detailed = false, protocolLabel }: { status?: AccessProtocolStatus; detailed?: boolean; protocolLabel?: string }) {
|
||||
const state = !status?.connected ? 'missing' : status.onlineState;
|
||||
const label = state === 'missing' ? '无来源' : state === 'online' ? '在线' : state === 'offline' ? '离线' : state === 'unknown' ? '未知' : '从未上报';
|
||||
const color = state === 'online' ? 'green' : state === 'offline' || state === 'unknown' ? 'orange' : 'grey';
|
||||
@@ -66,6 +66,7 @@ function ProtocolState({ status, detailed = false }: { status?: AccessProtocolSt
|
||||
</Card>;
|
||||
}
|
||||
return <div className={`v2-access-protocol-cell is-${state}`} title={status?.latestReceivedAt ? `最新上报:${formatAccessTime(status.latestReceivedAt)}` : '当前未发现该协议来源'}>
|
||||
{protocolLabel ? <b className="v2-access-protocol-label">{protocolLabel}</b> : null}
|
||||
<span><i />{label}</span>
|
||||
<strong>{status?.connected ? compactTime(status.latestReceivedAt) : '—'}</strong>
|
||||
<small>{status?.provider || (status?.connected ? '接入方未维护' : '未发现来源')}</small>
|
||||
@@ -246,9 +247,13 @@ export default function AccessPage() {
|
||||
actionsClassName="v2-access-table-actions"
|
||||
actions={<><ProtocolCoverage summary={summary} /><Button theme="light" icon={<IconDownload />} onClick={() => downloadRows(rows)} disabled={!rows.length}>导出当前页</Button></>}
|
||||
/>
|
||||
<div className="v2-access-table-scroll-v3">
|
||||
<div
|
||||
className={`v2-access-table-scroll-v3${mobileLayout ? ' is-mobile-scroll' : ''}`}
|
||||
tabIndex={mobileLayout ? 0 : undefined}
|
||||
aria-label={mobileLayout ? '车辆接入列表,可上下滚动' : undefined}
|
||||
>
|
||||
{mobileLayout
|
||||
? <div className="v2-access-mobile-list">{rows.map((row) => <Card key={row.vin} className={`v2-access-mobile-card${selected?.vin === row.vin ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" aria-pressed={selected?.vin === row.vin} aria-expanded={selected?.vin === row.vin} aria-label={`查看 ${row.plate || row.vin} 接入详情`} className="v2-access-mobile-action" onClick={() => setSelectedVIN(row.vin)}><span className="v2-access-mobile-card-content"><header><span><strong>{row.plate || '未绑定车牌'}</strong><small>{row.vin}</small></span><ConnectionState row={row} /></header><p>{row.oem || '品牌未维护'} · {row.model || row.company || '车型未维护'}</p><span className="v2-access-mobile-protocols">{PROTOCOLS.map((protocol) => <ProtocolState key={protocol} status={statusByProtocol(row, protocol)} />)}</span><footer>查看接入详情<IconChevronRight /></footer></span></Button></Card>)}</div>
|
||||
? <div className="v2-access-mobile-list">{rows.map((row) => <Card key={row.vin} className={`v2-access-mobile-card${selected?.vin === row.vin ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" aria-pressed={selected?.vin === row.vin} aria-expanded={selected?.vin === row.vin} aria-label={`查看 ${row.plate || row.vin} 接入详情`} className="v2-access-mobile-action" onClick={() => setSelectedVIN(row.vin)}><span className="v2-access-mobile-card-content"><header><span><strong>{row.plate || '未绑定车牌'}</strong><small>{row.vin}</small></span><ConnectionState row={row} /></header><p>{row.oem || '品牌未维护'} · {row.model || row.company || '车型未维护'}</p><span className="v2-access-mobile-protocols">{PROTOCOLS.map((protocol) => <ProtocolState key={protocol} protocolLabel={protocol} status={statusByProtocol(row, protocol)} />)}</span><footer>查看接入详情<IconChevronRight /></footer></span></Button></Card>)}</div>
|
||||
: <AccessVehicleTable rows={rows} selectedVIN={selectedVIN} onSelect={setSelectedVIN} />}
|
||||
{vehiclesQuery.isFetching ? <PanelLoading className="v2-access-loading" title="正在更新车辆接入状态…" description="当前列表返回后会自动替换。" compact={Boolean(rows.length)} /> : null}
|
||||
{!vehiclesQuery.isFetching && !rows.length ? <PanelEmpty className="v2-access-empty" title="没有匹配车辆" description="调整车牌、协议或接入状态筛选后重试。" /> : null}
|
||||
|
||||
@@ -188,6 +188,8 @@ test('renders only selectable Semi alert cards on mobile', async () => {
|
||||
const action = await screen.findByRole('button', { name: '查看 粤A移动01 粤A移动01速度告警 告警详情' });
|
||||
expect(action).toHaveClass('semi-button', 'v2-alert-mobile-action');
|
||||
expect(action.closest('.semi-card')).toHaveClass('v2-alert-mobile-card');
|
||||
expect(view.container.querySelector('.v2-alert-table-scroll.is-mobile-scroll')).toHaveAttribute('tabindex', '0');
|
||||
expect(view.container.querySelector('.v2-alert-table-scroll.is-mobile-scroll')).toHaveAttribute('aria-label', '告警事件列表,可上下滚动');
|
||||
expect(view.container.querySelector('.v2-alert-event-table')).not.toBeInTheDocument();
|
||||
expect(action).toHaveAttribute('aria-expanded', 'false');
|
||||
fireEvent.click(action);
|
||||
|
||||
@@ -223,7 +223,11 @@ function EventWorkspace({ filters, draft, setDraft, setFilters, rules, unread, e
|
||||
meta={`共 ${(events.data?.total ?? 0).toLocaleString('zh-CN')} 条`}
|
||||
actions={<Button theme="borderless" icon={<IconRefresh />} loading={events.isFetching} onClick={() => Promise.all([events.refetch(), summary.refetch(), ...(selectedID ? [detail.refetch()] : [])])}>刷新</Button>}
|
||||
/>
|
||||
<div className="v2-alert-table-scroll">
|
||||
<div
|
||||
className={`v2-alert-table-scroll${mobileLayout ? ' is-mobile-scroll' : ''}`}
|
||||
tabIndex={mobileLayout ? 0 : undefined}
|
||||
aria-label={mobileLayout ? '告警事件列表,可上下滚动' : undefined}
|
||||
>
|
||||
{mobileLayout
|
||||
? <div className="v2-alert-mobile-list">{rows.map((event) => <Card key={event.id} className={`v2-alert-mobile-card${selectedID === event.id ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" className="v2-alert-mobile-action" aria-pressed={selectedID === event.id} aria-expanded={selectedID === event.id} aria-label={`查看 ${event.plate || event.vin} ${event.ruleName} 告警详情`} onClick={() => setSelection({ scope: eventScope, id: event.id })}><span className="v2-alert-mobile-card-content"><header><strong>{event.plate || '未绑定车牌'}</strong><span><SeverityTag severity={event.severity} /><StatusTag status={event.status} /></span></header><p>{event.ruleName}</p><dl><div><dt>触发时间</dt><dd>{formatAlertTime(event.triggeredAt)}</dd></div><div><dt>数据来源</dt><dd>{event.protocol || '—'}</dd></div><div><dt>触发值</dt><dd>{alertValue(event)}</dd></div><div><dt>阈值</dt><dd>{thresholdText(event)}</dd></div></dl><footer>查看处置详情<IconChevronRight /></footer></span></Button></Card>)}</div>
|
||||
: <AlertEventTable rows={rows} selectedID={selectedID} onSelect={(id) => setSelection({ scope: eventScope, id })} />}
|
||||
@@ -410,5 +414,5 @@ export default function AlertsPage() {
|
||||
const setTab = (next: Tab) => { setTabState(next); const copy = new URLSearchParams(params); copy.set('tab', next); setParams(copy, { replace: true }); };
|
||||
const setFilters = (next: Filters) => { setFilterState(next); const copy = new URLSearchParams(); if (tab !== 'events') copy.set('tab', tab); Object.entries(next).forEach(([key, value]) => { if (value) copy.set(key, value); }); setParams(copy, { replace: true }); };
|
||||
const tabs = [{ key: 'events' as const, label: '告警事件', icon: <IconAlarm /> }, ...(admin ? [{ key: 'rules' as const, label: '规则配置' }] : []), { key: 'notifications' as const, label: '站内通知', icon: <IconBell />, count: unread || undefined }];
|
||||
return <div className="v2-alert-page"><div className="v2-alert-navigation"><SegmentedTabs className="v2-alert-tabs" variant="filled" ariaLabel="告警中心分类" value={activeTab} items={tabs} onChange={setTab} /><div className="v2-alert-navigation-meta"><Typography.Text type="tertiary">{operator ? '可处置事件' : '只读查看'}</Typography.Text><Tag color={unread ? 'orange' : 'green'} type="light" size="small">{unread ? `${unread.toLocaleString('zh-CN')} 条未读` : '通知已读'}</Tag></div></div>{activeTab !== 'notifications' && rules.isError ? <InlineError message={rules.error.message} onRetry={() => rules.refetch()} /> : null}{activeTab === 'rules' && metrics.isError ? <InlineError message={metrics.error.message} onRetry={() => metrics.refetch()} /> : null}{activeTab === 'events' ? <EventWorkspace filters={filters} draft={eventDraft} setDraft={setEventDraft} setFilters={setFilters} rules={rules.data ?? []} unread={unread} editable={operator} onTab={setTab} /> : activeTab === 'rules' ? <RulesWorkspace rules={rules.data ?? []} metrics={metrics.data?.metrics ?? []} /> : <NotificationsWorkspace editable={operator} notifications={notifications} />}</div>;
|
||||
return <div className={`v2-alert-page is-${activeTab}`}><div className="v2-alert-navigation"><SegmentedTabs className="v2-alert-tabs" variant="filled" ariaLabel="告警中心分类" value={activeTab} items={tabs} onChange={setTab} /><div className="v2-alert-navigation-meta"><Typography.Text type="tertiary">{operator ? '可处置事件' : '只读查看'}</Typography.Text><Tag color={unread ? 'orange' : 'green'} type="light" size="small">{unread ? `${unread.toLocaleString('zh-CN')} 条未读` : '通知已读'}</Tag></div></div>{activeTab !== 'notifications' && rules.isError ? <InlineError message={rules.error.message} onRetry={() => rules.refetch()} /> : null}{activeTab === 'rules' && metrics.isError ? <InlineError message={metrics.error.message} onRetry={() => metrics.refetch()} /> : null}{activeTab === 'events' ? <EventWorkspace filters={filters} draft={eventDraft} setDraft={setEventDraft} setFilters={setFilters} rules={rules.data ?? []} unread={unread} editable={operator} onTab={setTab} /> : activeTab === 'rules' ? <RulesWorkspace rules={rules.data ?? []} metrics={metrics.data?.metrics ?? []} /> : <NotificationsWorkspace editable={operator} notifications={notifications} />}</div>;
|
||||
}
|
||||
|
||||
@@ -6409,6 +6409,13 @@
|
||||
padding: 8px 7px 16px;
|
||||
}
|
||||
|
||||
.v2-alert-page.is-events {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.v2-alert-navigation {
|
||||
position: sticky;
|
||||
z-index: 8;
|
||||
@@ -6460,7 +6467,7 @@
|
||||
}
|
||||
|
||||
.v2-alert-context-card.semi-card {
|
||||
min-height: 0;
|
||||
min-height: 94px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card > .semi-card-body {
|
||||
@@ -6468,78 +6475,208 @@
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-kpis {
|
||||
min-height: 88px;
|
||||
height: 58px;
|
||||
min-height: 58px;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-kpis .v2-metric-action,
|
||||
.v2-alert-context-card .v2-alert-kpis .v2-metric-action-content {
|
||||
min-height: 44px;
|
||||
min-height: 58px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-kpis .v2-metric-action {
|
||||
padding: 7px 5px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-kpis .v2-metric-action.is-notice {
|
||||
grid-column: auto;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-kpis .v2-metric-action-content {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-kpis small {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-kpis strong {
|
||||
margin-top: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-secondary-states {
|
||||
min-height: 34px;
|
||||
border-top: 1px solid #e4e9f0;
|
||||
border-left: 0;
|
||||
padding: 4px;
|
||||
padding: 3px 4px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-secondary-states > .semi-button {
|
||||
min-height: 40px;
|
||||
padding: 3px 5px;
|
||||
min-height: 30px;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-secondary-states span {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-alert-secondary-states b {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.v2-alert-page.is-events .v2-alert-workspace {
|
||||
min-height: 0;
|
||||
flex: 1 1 0;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.v2-alert-table-card {
|
||||
min-height: 460px;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.v2-alert-table-card > .semi-card-body > .v2-workspace-panel-header {
|
||||
min-height: 58px;
|
||||
align-items: flex-start;
|
||||
padding: 8px;
|
||||
min-height: 50px;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.v2-alert-table-card .v2-workspace-panel-copy > .semi-typography {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-alert-table-scroll.is-mobile-scroll {
|
||||
min-height: 0;
|
||||
flex: 1 1 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-gutter: stable;
|
||||
scrollbar-width: auto;
|
||||
touch-action: pan-y;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.v2-alert-table-scroll.is-mobile-scroll:focus-visible {
|
||||
outline: 2px solid rgba(18, 104, 243, .34);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.v2-alert-table-scroll.is-mobile-scroll::-webkit-scrollbar {
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
.v2-alert-table-scroll.is-mobile-scroll::-webkit-scrollbar-thumb {
|
||||
border: 3px solid transparent;
|
||||
border-radius: 999px;
|
||||
background: #9cacc0;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-list {
|
||||
gap: 7px;
|
||||
padding: 7px;
|
||||
gap: 6px;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-list > .v2-alert-mobile-card.semi-card {
|
||||
border-radius: 9px;
|
||||
contain-intrinsic-size: auto 110px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content {
|
||||
padding: 11px;
|
||||
padding: 8px 9px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content header > strong {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content header > span {
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content .v2-alert-severity.semi-tag,
|
||||
.v2-alert-mobile-card-content .v2-alert-status.semi-tag {
|
||||
height: 20px;
|
||||
min-height: 20px;
|
||||
border-radius: 5px;
|
||||
padding-inline: 5px;
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content p {
|
||||
margin: 6px 0;
|
||||
margin: 4px 0 5px;
|
||||
overflow: hidden;
|
||||
color: #405168;
|
||||
font-size: 11px;
|
||||
line-height: 14px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dl {
|
||||
gap: 6px 10px;
|
||||
padding-top: 7px;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dl > div {
|
||||
display: grid;
|
||||
display: block;
|
||||
min-width: 0;
|
||||
min-height: 24px;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-height: 28px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dl > div:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dl > div + div {
|
||||
border-left: 1px solid #edf1f5;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dt {
|
||||
overflow: hidden;
|
||||
font-size: 8px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dd {
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
margin: 3px 0 0;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
font-size: 9px;
|
||||
line-height: 12px;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content footer {
|
||||
margin-top: 6px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-alert-table-card > .semi-card-body > footer:has(.v2-table-pagination-controls) {
|
||||
min-height: 50px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 5px 6px;
|
||||
}
|
||||
|
||||
.v2-alert-table-card > .semi-card-body > footer .v2-table-pagination-info {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-alert-table-card > .semi-card-body > footer .v2-table-pagination-button.semi-button,
|
||||
.v2-alert-table-card > .semi-card-body > footer .v2-table-pagination-current,
|
||||
.v2-alert-table-card > .semi-card-body > footer .v2-table-pagination-size.semi-select {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.v2-alert-rules {
|
||||
@@ -7456,11 +7593,11 @@
|
||||
|
||||
@media (max-width: 680px) {
|
||||
.v2-access-page-v3 {
|
||||
height: auto;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
gap: 7px;
|
||||
overflow: auto;
|
||||
padding: 7px 7px 14px;
|
||||
overflow: hidden;
|
||||
padding: 7px 7px 8px;
|
||||
}
|
||||
|
||||
.v2-access-filter-card-v3 > .semi-card-body > .v2-workspace-filter-heading {
|
||||
@@ -7482,9 +7619,195 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.v2-access-kpis-card-v3.semi-card,
|
||||
.v2-access-kpis-v3 {
|
||||
min-height: 62px;
|
||||
}
|
||||
|
||||
.v2-access-kpis-v3 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.v2-access-kpis-v3 .v2-metric-action {
|
||||
min-height: 62px;
|
||||
padding: 7px 6px;
|
||||
}
|
||||
|
||||
.v2-access-kpis-v3 .v2-metric-action-content {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.v2-access-kpis-v3 small {
|
||||
overflow: hidden;
|
||||
font-size: 8px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-access-kpis-v3 strong {
|
||||
margin-left: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.v2-access-kpis-v3 em {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-access-workspace-v3 {
|
||||
min-height: 540px;
|
||||
flex: none;
|
||||
min-height: 0;
|
||||
flex: 1 1 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.v2-access-table-v3 > .semi-card-body > .v2-workspace-panel-header {
|
||||
min-height: 50px;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.v2-access-table-v3 .v2-workspace-panel-copy > .semi-typography {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-access-table-scroll-v3.is-mobile-scroll {
|
||||
min-height: 0;
|
||||
flex: 1 1 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-gutter: stable;
|
||||
scrollbar-width: auto;
|
||||
touch-action: pan-y;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.v2-access-table-scroll-v3.is-mobile-scroll:focus-visible {
|
||||
outline: 2px solid rgba(18, 104, 243, .34);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.v2-access-table-scroll-v3.is-mobile-scroll::-webkit-scrollbar {
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
.v2-access-table-scroll-v3.is-mobile-scroll::-webkit-scrollbar-thumb {
|
||||
border: 3px solid transparent;
|
||||
border-radius: 999px;
|
||||
background: #9cacc0;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.v2-access-mobile-list {
|
||||
gap: 6px;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card.semi-card {
|
||||
border-radius: 9px;
|
||||
contain-intrinsic-size: auto 126px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content {
|
||||
gap: 5px;
|
||||
padding: 8px 9px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > header {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > header strong {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > header small {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > header .v2-access-connection {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > header .v2-access-connection > span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > header .v2-access-connection-tag.semi-tag {
|
||||
min-height: 20px;
|
||||
border-radius: 5px;
|
||||
padding-inline: 5px;
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > p {
|
||||
overflow: hidden;
|
||||
font-size: 9px;
|
||||
line-height: 12px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-access-mobile-protocols {
|
||||
gap: 4px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-list .v2-access-protocol-cell {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: 2px 4px;
|
||||
border-radius: 6px;
|
||||
padding: 5px 6px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-list .v2-access-protocol-label {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: #50627a;
|
||||
font-size: 8px;
|
||||
line-height: 11px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-access-mobile-list .v2-access-protocol-cell > span {
|
||||
justify-self: end;
|
||||
gap: 3px;
|
||||
font-size: 8px;
|
||||
line-height: 11px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-list .v2-access-protocol-cell > span i {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-list .v2-access-protocol-cell > strong {
|
||||
grid-column: 1 / -1;
|
||||
font-size: 8px;
|
||||
line-height: 11px;
|
||||
}
|
||||
|
||||
.v2-access-mobile-card-content > footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-access-table-v3 > .semi-card-body > footer:has(.v2-table-pagination-controls) {
|
||||
min-height: 50px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 5px 6px;
|
||||
}
|
||||
|
||||
.v2-access-table-v3 > .semi-card-body > footer .v2-table-pagination-info {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-access-table-v3 > .semi-card-body > footer .v2-table-pagination-button.semi-button,
|
||||
.v2-access-table-v3 > .semi-card-body > footer .v2-table-pagination-current,
|
||||
.v2-access-table-v3 > .semi-card-body > footer .v2-table-pagination-size.semi-select {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.v2-ops-page {
|
||||
|
||||
Reference in New Issue
Block a user