feat: optimize mobile access filters
This commit is contained in:
@@ -191,7 +191,7 @@ test('renders mobile access vehicles as selectable Semi cards', async () => {
|
|||||||
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||||
const view = 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 接入详情' });
|
let action = await screen.findByRole('button', { name: '查看 粤A00001 接入详情' });
|
||||||
expect(action).toHaveClass('semi-button', 'v2-access-mobile-action');
|
expect(action).toHaveClass('semi-button', 'v2-access-mobile-action');
|
||||||
expect(action.closest('.semi-card')).toHaveClass('v2-access-mobile-card');
|
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('tabindex', '0');
|
||||||
@@ -202,6 +202,25 @@ test('renders mobile access vehicles as selectable Semi cards', async () => {
|
|||||||
expect(screen.queryByLabelText('每页车辆数')).not.toBeInTheDocument();
|
expect(screen.queryByLabelText('每页车辆数')).not.toBeInTheDocument();
|
||||||
expect(screen.getByRole('button', { name: '打开接入治理' })).toHaveTextContent('治理');
|
expect(screen.getByRole('button', { name: '打开接入治理' })).toHaveTextContent('治理');
|
||||||
expect(screen.getByRole('button', { name: '打开接入治理' })).toHaveClass('v2-workspace-mobile-tool-button', 'is-muted');
|
expect(screen.getByRole('button', { name: '打开接入治理' })).toHaveClass('v2-workspace-mobile-tool-button', 'is-muted');
|
||||||
|
const filterTrigger = screen.getByRole('button', { name: /修改接入筛选/ });
|
||||||
|
expect(filterTrigger).toHaveAttribute('aria-expanded', 'false');
|
||||||
|
fireEvent.click(filterTrigger);
|
||||||
|
const filterDialog = await screen.findByRole('dialog', { name: '接入车辆筛选' });
|
||||||
|
expect(document.querySelector('.v2-access-mobile-filter-sidesheet')).toHaveClass('semi-sidesheet-bottom');
|
||||||
|
expect(document.querySelector('.v2-access-mobile-filter-sidesheet .semi-sidesheet-inner')).toHaveStyle({ height: 'min(76dvh, 640px)' });
|
||||||
|
expect(within(filterDialog).getByRole('textbox', { name: '车辆' })).toBeInTheDocument();
|
||||||
|
expect(within(filterDialog).getByRole('combobox', { name: '接入状态' })).toBeInTheDocument();
|
||||||
|
expect(within(filterDialog).getByRole('combobox', { name: '真实协议' })).toBeInTheDocument();
|
||||||
|
expect(within(filterDialog).getByRole('combobox', { name: '车辆品牌' })).toBeInTheDocument();
|
||||||
|
fireEvent.click(within(filterDialog).getByRole('combobox', { name: '接入状态' }));
|
||||||
|
const attentionOption = (await screen.findAllByText('需关注')).find((element) => element.classList.contains('semi-select-option-text'));
|
||||||
|
expect(attentionOption).toBeInTheDocument();
|
||||||
|
fireEvent.click(attentionOption!);
|
||||||
|
fireEvent.click(within(filterDialog).getByRole('button', { name: '应用并查询' }));
|
||||||
|
await waitFor(() => expect(mocks.accessVehicles).toHaveBeenLastCalledWith(expect.objectContaining({ connectionState: 'attention' }), expect.anything()));
|
||||||
|
expect(screen.getByRole('button', { name: /修改接入筛选:已启用 1 项/ })).toHaveAttribute('aria-expanded', 'false');
|
||||||
|
expect(screen.getByRole('dialog', { name: '接入车辆筛选' })).toHaveClass('semi-sidesheet-animation-content_hide_bottom');
|
||||||
|
action = await screen.findByRole('button', { name: '查看 粤A00001 接入详情' });
|
||||||
const toolsButton = screen.getByRole('button', { name: '打开接入管理工具' });
|
const toolsButton = screen.getByRole('button', { name: '打开接入管理工具' });
|
||||||
expect(toolsButton).toHaveTextContent('工具');
|
expect(toolsButton).toHaveTextContent('工具');
|
||||||
expect(toolsButton).toHaveClass('v2-workspace-mobile-tool-button', 'is-muted');
|
expect(toolsButton).toHaveClass('v2-workspace-mobile-tool-button', 'is-muted');
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import type { AccessProtocolStatus, AccessQuery, AccessSummary, AccessThresholdC
|
|||||||
import { accessIssueSummary, accessRowsToCSV, formatAccessTime, formatSeconds, updateProtocolThreshold } from '../domain/access';
|
import { accessIssueSummary, accessRowsToCSV, formatAccessTime, formatSeconds, updateProtocolThreshold } from '../domain/access';
|
||||||
import { InlineError, PanelEmpty, PanelLoading } from '../shared/AsyncState';
|
import { InlineError, PanelEmpty, PanelLoading } from '../shared/AsyncState';
|
||||||
import { MetricActionButton } from '../shared/MetricActionButton';
|
import { MetricActionButton } from '../shared/MetricActionButton';
|
||||||
|
import { MobileFilterToggle } from '../shared/MobileFilterToggle';
|
||||||
import { TablePagination } from '../shared/TablePagination';
|
import { TablePagination } from '../shared/TablePagination';
|
||||||
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||||
import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel';
|
import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel';
|
||||||
@@ -349,12 +350,17 @@ export default function AccessPage() {
|
|||||||
setOffset(0);
|
setOffset(0);
|
||||||
}, [mobileLayout]);
|
}, [mobileLayout]);
|
||||||
const rows = vehiclesQuery.data?.items ?? []; const selected = rows.find((row) => row.vin === selectedVIN);
|
const rows = vehiclesQuery.data?.items ?? []; const selected = rows.find((row) => row.vin === selectedVIN);
|
||||||
|
const mobileFiltersOpen = mobileLayout && !filtersCollapsed;
|
||||||
useSideSheetA11y(Boolean(selected), '.v2-access-detail-sidesheet', 'v2-access-detail', '车辆接入详情', '关闭车辆接入详情');
|
useSideSheetA11y(Boolean(selected), '.v2-access-detail-sidesheet', 'v2-access-detail', '车辆接入详情', '关闭车辆接入详情');
|
||||||
useSideSheetA11y(editable && governanceOpen, '.v2-access-governance-sidesheet', 'v2-access-governance', '接入治理配置', '关闭接入治理配置');
|
useSideSheetA11y(editable && governanceOpen, '.v2-access-governance-sidesheet', 'v2-access-governance', '接入治理配置', '关闭接入治理配置');
|
||||||
|
useSideSheetA11y(mobileFiltersOpen, '.v2-access-mobile-filter-sidesheet', 'v2-access-mobile-filters', '接入车辆筛选', '关闭接入车辆筛选');
|
||||||
const syncURL = (filters: Filters) => { const next = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value) next.set(key, value); }); setSearchParams(next, { replace: true }); };
|
const syncURL = (filters: Filters) => { const next = new URLSearchParams(); Object.entries(filters).forEach(([key, value]) => { if (value) next.set(key, value); }); setSearchParams(next, { replace: true }); };
|
||||||
const apply = (next: Filters) => { setDraft(next); setCriteria(next); setOffset(0); setSelectedVIN(''); syncURL(next); };
|
const apply = (next: Filters) => { setDraft(next); setCriteria(next); setOffset(0); setSelectedVIN(''); syncURL(next); };
|
||||||
const submit = (event: FormEvent) => { event.preventDefault(); apply(draft); setFiltersCollapsed(true); };
|
const applyDraft = () => { apply(draft); setFiltersCollapsed(true); };
|
||||||
|
const resetFilters = () => { apply(EMPTY_FILTERS); setFiltersCollapsed(true); };
|
||||||
|
const submit = (event: FormEvent) => { event.preventDefault(); applyDraft(); };
|
||||||
const page = Math.floor(offset / limit) + 1; const totalPages = Math.max(1, Math.ceil((vehiclesQuery.data?.total ?? 0) / limit)); const summary = summaryQuery.data;
|
const page = Math.floor(offset / limit) + 1; const totalPages = Math.max(1, Math.ceil((vehiclesQuery.data?.total ?? 0) / limit)); const summary = summaryQuery.data;
|
||||||
|
const activeFilterCount = Object.values(criteria).filter(Boolean).length;
|
||||||
const refresh = () => Promise.all([summaryQuery.refetch(), vehiclesQuery.refetch(), ...(editable ? [unresolvedQuery.refetch(), thresholdQuery.refetch()] : [])]);
|
const refresh = () => Promise.all([summaryQuery.refetch(), vehiclesQuery.refetch(), ...(editable ? [unresolvedQuery.refetch(), thresholdQuery.refetch()] : [])]);
|
||||||
const scrollAccessTable = (event: KeyboardEvent<HTMLDivElement>) => {
|
const scrollAccessTable = (event: KeyboardEvent<HTMLDivElement>) => {
|
||||||
if (mobileLayout || event.currentTarget !== event.target || (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')) return;
|
if (mobileLayout || event.currentTarget !== event.target || (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')) return;
|
||||||
@@ -365,6 +371,12 @@ export default function AccessPage() {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
tableScroller.scrollBy({ left: event.key === 'ArrowRight' ? 260 : -260, behavior: 'smooth' });
|
tableScroller.scrollBy({ left: event.key === 'ArrowRight' ? 260 : -260, behavior: 'smooth' });
|
||||||
};
|
};
|
||||||
|
const filterFields = <>
|
||||||
|
<label className="is-search"><span>车辆</span><Input aria-label="车辆" prefix={<IconSearch />} value={draft.keyword} onChange={(value) => setDraft({ ...draft, keyword: value })} placeholder="车牌 / VIN" /></label>
|
||||||
|
<label><span id="access-connection-label">接入状态</span><Select aria-labelledby="access-connection-label" value={draft.connectionState} onChange={(value) => setDraft({ ...draft, connectionState: String(value) })} optionList={[{ value: '', label: '全部状态' }, { value: 'attention', label: '需关注' }, { value: 'healthy', label: '已接来源正常' }, { value: 'master_data', label: '资料待维护' }, { value: 'degraded', label: '部分来源异常' }, { value: 'offline', label: '已接来源离线' }, { value: 'not_connected', label: '尚无来源' }]} /></label>
|
||||||
|
<label><span id="access-protocol-label">真实协议</span><Select aria-labelledby="access-protocol-label" value={draft.protocol} onChange={(value) => setDraft({ ...draft, protocol: String(value) })} optionList={[{ value: '', label: '全部协议' }, ...PROTOCOLS.map((item) => ({ value: item, label: item }))]} /></label>
|
||||||
|
<label><span id="access-oem-label">车辆品牌</span><Select aria-labelledby="access-oem-label" value={draft.oem} onChange={(value) => setDraft({ ...draft, oem: String(value) })} optionList={[{ value: '', label: '全部品牌' }, ...(summary?.oems.map((item) => ({ value: item.name, label: item.name })) ?? [])]} /></label>
|
||||||
|
</>;
|
||||||
|
|
||||||
return <div className="v2-access-page v2-access-page-v3">
|
return <div className="v2-access-page v2-access-page-v3">
|
||||||
<div className="v2-access-discovery-shell">
|
<div className="v2-access-discovery-shell">
|
||||||
@@ -394,27 +406,48 @@ export default function AccessPage() {
|
|||||||
</Dropdown>
|
</Dropdown>
|
||||||
</> : <>{editable ? <Button theme="light" icon={<IconSetting />} aria-haspopup="dialog" aria-controls="v2-access-governance" aria-expanded={governanceOpen} onClick={() => setGovernanceOpen(true)}>接入治理{unresolvedQuery.data?.total ? ` · ${unresolvedQuery.data.total}` : ''}</Button> : null}<Button theme="light" icon={<IconRefresh />} onClick={() => void refresh()}>刷新</Button></>}
|
</> : <>{editable ? <Button theme="light" icon={<IconSetting />} aria-haspopup="dialog" aria-controls="v2-access-governance" aria-expanded={governanceOpen} onClick={() => setGovernanceOpen(true)}>接入治理{unresolvedQuery.data?.total ? ` · ${unresolvedQuery.data.total}` : ''}</Button> : null}<Button theme="light" icon={<IconRefresh />} onClick={() => void refresh()}>刷新</Button></>}
|
||||||
/>
|
/>
|
||||||
<WorkspaceFilterPanel
|
{mobileLayout ? <div className="v2-access-mobile-discovery">
|
||||||
|
<MobileFilterToggle
|
||||||
|
title="接入筛选"
|
||||||
|
summary={activeFilterCount ? `已启用 ${activeFilterCount} 项` : '全部主车辆'}
|
||||||
|
expanded={mobileFiltersOpen}
|
||||||
|
expandedLabel="关闭"
|
||||||
|
collapsedLabel="修改"
|
||||||
|
onToggle={() => setFiltersCollapsed((value) => !value)}
|
||||||
|
/>
|
||||||
|
<SideSheet
|
||||||
|
className="v2-access-mobile-filter-sidesheet"
|
||||||
|
visible={mobileFiltersOpen}
|
||||||
|
placement="bottom"
|
||||||
|
height="min(76dvh, 640px)"
|
||||||
|
aria-label="接入车辆筛选"
|
||||||
|
title={<div className="v2-access-sheet-title"><strong>筛选接入车辆</strong><span>车辆、接入状态、真实协议与品牌</span></div>}
|
||||||
|
onCancel={() => setFiltersCollapsed(true)}
|
||||||
|
footer={<div className="v2-access-mobile-filter-footer"><Button theme="light" onClick={resetFilters}>重置条件</Button><Button theme="solid" onClick={applyDraft}>应用并查询</Button></div>}
|
||||||
|
>
|
||||||
|
<form className="v2-access-mobile-filter-form" onSubmit={submit}>
|
||||||
|
<header><strong>接入范围</strong><span>优先定位异常、离线、尚无来源和资料差异车辆</span></header>
|
||||||
|
<div>{filterFields}</div>
|
||||||
|
</form>
|
||||||
|
</SideSheet>
|
||||||
|
</div> : <WorkspaceFilterPanel
|
||||||
className="v2-access-filter-card-v3"
|
className="v2-access-filter-card-v3"
|
||||||
title="接入筛选"
|
title="接入筛选"
|
||||||
description="车辆、接入状态、真实协议与品牌"
|
description="车辆、接入状态、真实协议与品牌"
|
||||||
mobileSummary={Object.values(criteria).filter(Boolean).length ? `已启用 ${Object.values(criteria).filter(Boolean).length} 项` : '全部主车辆'}
|
mobileSummary={activeFilterCount ? `已启用 ${activeFilterCount} 项` : '全部主车辆'}
|
||||||
expanded={!filtersCollapsed}
|
expanded={!filtersCollapsed}
|
||||||
status={Object.values(criteria).filter(Boolean).length ? `${Object.values(criteria).filter(Boolean).length} 项已启用` : '全部主车辆'}
|
status={activeFilterCount ? `${activeFilterCount} 项已启用` : '全部主车辆'}
|
||||||
statusColor={Object.values(criteria).filter(Boolean).length ? 'blue' : 'grey'}
|
statusColor={activeFilterCount ? 'blue' : 'grey'}
|
||||||
onToggle={() => setFiltersCollapsed((value) => !value)}
|
onToggle={() => setFiltersCollapsed((value) => !value)}
|
||||||
>
|
>
|
||||||
<form className="v2-access-filter-v3" onSubmit={submit}>
|
<form className="v2-access-filter-v3" onSubmit={submit}>
|
||||||
<label className="is-search"><span>车辆</span><Input aria-label="车辆" prefix={<IconSearch />} value={draft.keyword} onChange={(value) => setDraft({ ...draft, keyword: value })} placeholder="车牌 / VIN" /></label>
|
{filterFields}
|
||||||
<label><span id="access-connection-label">接入状态</span><Select aria-labelledby="access-connection-label" value={draft.connectionState} onChange={(value) => setDraft({ ...draft, connectionState: String(value) })} optionList={[{ value: '', label: '全部状态' }, { value: 'attention', label: '需关注' }, { value: 'healthy', label: '已接来源正常' }, { value: 'master_data', label: '资料待维护' }, { value: 'degraded', label: '部分来源异常' }, { value: 'offline', label: '已接来源离线' }, { value: 'not_connected', label: '尚无来源' }]} /></label>
|
|
||||||
<label><span id="access-protocol-label">真实协议</span><Select aria-labelledby="access-protocol-label" value={draft.protocol} onChange={(value) => setDraft({ ...draft, protocol: String(value) })} optionList={[{ value: '', label: '全部协议' }, ...PROTOCOLS.map((item) => ({ value: item, label: item }))]} /></label>
|
|
||||||
<label><span id="access-oem-label">车辆品牌</span><Select aria-labelledby="access-oem-label" value={draft.oem} onChange={(value) => setDraft({ ...draft, oem: String(value) })} optionList={[{ value: '', label: '全部品牌' }, ...(summary?.oems.map((item) => ({ value: item.name, label: item.name })) ?? [])]} /></label>
|
|
||||||
<div className="v2-access-filter-actions">
|
<div className="v2-access-filter-actions">
|
||||||
<Button className="v2-primary-button" theme="solid" htmlType="submit">查询</Button>
|
<Button className="v2-primary-button" theme="solid" htmlType="submit">查询</Button>
|
||||||
<Button className="v2-secondary-button" theme="light" htmlType="button" onClick={() => apply(EMPTY_FILTERS)}>重置</Button>
|
<Button className="v2-secondary-button" theme="light" htmlType="button" onClick={resetFilters}>重置</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</WorkspaceFilterPanel>
|
</WorkspaceFilterPanel>}
|
||||||
</div>
|
</div>
|
||||||
{summaryQuery.isError ? <InlineError message={summaryQuery.error instanceof Error ? summaryQuery.error.message : '接入汇总读取失败'} onRetry={() => summaryQuery.refetch()} /> : null}
|
{summaryQuery.isError ? <InlineError message={summaryQuery.error instanceof Error ? summaryQuery.error.message : '接入汇总读取失败'} onRetry={() => summaryQuery.refetch()} /> : null}
|
||||||
{vehiclesQuery.isError ? <InlineError message={vehiclesQuery.error instanceof Error ? vehiclesQuery.error.message : '接入车辆读取失败'} onRetry={() => vehiclesQuery.refetch()} /> : null}
|
{vehiclesQuery.isError ? <InlineError message={vehiclesQuery.error instanceof Error ? vehiclesQuery.error.message : '接入车辆读取失败'} onRetry={() => vehiclesQuery.refetch()} /> : null}
|
||||||
|
|||||||
@@ -16916,3 +16916,126 @@
|
|||||||
padding: 3px 4px;
|
padding: 3px 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Semi UI access mobile workflow.
|
||||||
|
* Keep the access difference list in the first viewport and move the complete
|
||||||
|
* filter task into the same focused bottom-sheet pattern used by alerts.
|
||||||
|
*/
|
||||||
|
@media (max-width: 680px) {
|
||||||
|
.v2-access-mobile-discovery {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-discovery > .v2-mobile-filter-toggle.semi-button {
|
||||||
|
min-height: 58px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-sidesheet .semi-sidesheet-inner {
|
||||||
|
width: 100vw !important;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 18px 18px 0 0;
|
||||||
|
background: #f4f7fb;
|
||||||
|
box-shadow: 0 -20px 56px rgba(25, 45, 72, .2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-sidesheet.semi-sidesheet-bottom .semi-sidesheet-header {
|
||||||
|
min-height: 68px;
|
||||||
|
border-bottom: 1px solid #dfe7f0;
|
||||||
|
background: rgba(255, 255, 255, .98);
|
||||||
|
padding: 11px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-sidesheet.semi-sidesheet-bottom .semi-sidesheet-body {
|
||||||
|
overflow: auto;
|
||||||
|
background: #f4f7fb;
|
||||||
|
padding: 12px;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-sidesheet.semi-sidesheet-bottom .semi-sidesheet-footer {
|
||||||
|
border-top: 1px solid #dfe7f0;
|
||||||
|
background: rgba(255, 255, 255, .98);
|
||||||
|
padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form {
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
border: 1px solid #dfe7f0;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px;
|
||||||
|
box-shadow: 0 8px 24px rgba(31, 53, 80, .055);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form > header {
|
||||||
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form > header > strong {
|
||||||
|
color: #2b4058;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form > header > span {
|
||||||
|
color: #7c8b9e;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form > div {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 11px 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form > div > label.is-search,
|
||||||
|
.v2-access-mobile-filter-form > div > label:last-child {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form > div > label {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 6px;
|
||||||
|
color: #5f7188;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 650;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form > div > label > .semi-input-wrapper,
|
||||||
|
.v2-access-mobile-filter-form > div > label > .semi-select {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 44px;
|
||||||
|
border-radius: 9px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-form .semi-input,
|
||||||
|
.v2-access-mobile-filter-form .semi-select-selection-text {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-footer {
|
||||||
|
display: grid;
|
||||||
|
width: 100%;
|
||||||
|
grid-template-columns: minmax(0, .72fr) minmax(0, 1.28fr);
|
||||||
|
gap: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-access-mobile-filter-footer > .semi-button {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 42px;
|
||||||
|
border-radius: 9px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user