对齐规则列表页交互样式
This commit is contained in:
@@ -84,7 +84,7 @@ export function Breadcrumb({ items = [], className = '' }: BreadcrumbProps) {
|
|||||||
<nav className={finalClassName} aria-label="面包屑导航">
|
<nav className={finalClassName} aria-label="面包屑导航">
|
||||||
<ol className="flex items-center space-x-2 text-sm text-gray-500 mb-0">
|
<ol className="flex items-center space-x-2 text-sm text-gray-500 mb-0">
|
||||||
<li>
|
<li>
|
||||||
<Link to="/" className="hover:text-primary-600 flex items-center">
|
<Link to="/" className="hover:text-[--color-primary-hover] flex items-center">
|
||||||
<i className="ri-home-line mr-1" />
|
<i className="ri-home-line mr-1" />
|
||||||
首页
|
首页
|
||||||
</Link>
|
</Link>
|
||||||
@@ -98,7 +98,7 @@ export function Breadcrumb({ items = [], className = '' }: BreadcrumbProps) {
|
|||||||
) : (
|
) : (
|
||||||
<Link
|
<Link
|
||||||
to={item.to || '#'}
|
to={item.to || '#'}
|
||||||
className="hover:text-primary-600"
|
className="hover:text-[--color-primary-hover]"
|
||||||
prefetch="intent"
|
prefetch="intent"
|
||||||
preventScrollReset={false}
|
preventScrollReset={false}
|
||||||
>
|
>
|
||||||
@@ -110,4 +110,4 @@ export function Breadcrumb({ items = [], className = '' }: BreadcrumbProps) {
|
|||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,20 +36,6 @@ type RulesTestDetailData = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type RulesTestListData = {
|
|
||||||
filters?: {
|
|
||||||
documentType?: string;
|
|
||||||
mainType?: string;
|
|
||||||
subtype?: string;
|
|
||||||
ruleGroup?: string;
|
|
||||||
keyword?: string;
|
|
||||||
};
|
|
||||||
options?: {
|
|
||||||
subtypes?: string[];
|
|
||||||
ruleGroups?: string[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Layout({ children, userRole = 'developer' as UserRole, frontendJWT = '', isMobile = false }: LayoutProps) {
|
export function Layout({ children, userRole = 'developer' as UserRole, frontendJWT = '', isMobile = false }: LayoutProps) {
|
||||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
||||||
const [effectiveUserRole, setEffectiveUserRole] = useState<UserRole>(userRole);
|
const [effectiveUserRole, setEffectiveUserRole] = useState<UserRole>(userRole);
|
||||||
@@ -146,13 +132,9 @@ export function Layout({ children, userRole = 'developer' as UserRole, frontendJ
|
|||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isRulesTestList = location.pathname.startsWith('/rulesTest/list');
|
|
||||||
const isRulesTestDetail = location.pathname.startsWith('/rulesTest/detail');
|
const isRulesTestDetail = location.pathname.startsWith('/rulesTest/detail');
|
||||||
const isRulesTestTopbarPage = isRulesTestList || isRulesTestDetail;
|
const isRulesTestTopbarPage = isRulesTestDetail;
|
||||||
const rulesTestListData = matches.find(match => match.pathname.startsWith('/rulesTest/list'))?.data as RulesTestListData | undefined;
|
|
||||||
const rulesTestDetailData = matches.find(match => match.pathname.startsWith('/rulesTest/detail'))?.data as RulesTestDetailData | undefined;
|
const rulesTestDetailData = matches.find(match => match.pathname.startsWith('/rulesTest/detail'))?.data as RulesTestDetailData | undefined;
|
||||||
const listFilters = rulesTestListData?.filters || {};
|
|
||||||
const listOptions = rulesTestListData?.options || {};
|
|
||||||
const detailPack = rulesTestDetailData?.pack;
|
const detailPack = rulesTestDetailData?.pack;
|
||||||
const isContractDetail = !!detailPack?.documentType?.includes('合同');
|
const isContractDetail = !!detailPack?.documentType?.includes('合同');
|
||||||
const isCaseFileDetail = !!detailPack?.documentType?.includes('案卷');
|
const isCaseFileDetail = !!detailPack?.documentType?.includes('案卷');
|
||||||
@@ -162,13 +144,6 @@ export function Layout({ children, userRole = 'developer' as UserRole, frontendJ
|
|||||||
const rulesListHref = detailPack?.documentType
|
const rulesListHref = detailPack?.documentType
|
||||||
? `/rulesTest/list?documentType=${encodeURIComponent(detailPack.documentType)}${detailPack.mainType ? `&mainType=${encodeURIComponent(detailPack.mainType)}` : ''}`
|
? `/rulesTest/list?documentType=${encodeURIComponent(detailPack.documentType)}${detailPack.mainType ? `&mainType=${encodeURIComponent(detailPack.mainType)}` : ''}`
|
||||||
: '/rulesTest/list';
|
: '/rulesTest/list';
|
||||||
const listScopeText = [
|
|
||||||
listFilters.documentType,
|
|
||||||
listFilters.mainType && listFilters.mainType !== listFilters.documentType ? listFilters.mainType : ''
|
|
||||||
].filter(Boolean).join(' / ');
|
|
||||||
const submitTopbarFilter = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
||||||
event.currentTarget.form?.requestSubmit();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="layout-container">
|
<div className="layout-container">
|
||||||
@@ -180,72 +155,6 @@ export function Layout({ children, userRole = 'developer' as UserRole, frontendJ
|
|||||||
frontendJWT={effectiveFrontendJWT}
|
frontendJWT={effectiveFrontendJWT}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 规则列表页顶部栏 */}
|
|
||||||
{isRulesTestList && (
|
|
||||||
<div className={`page-topbar rules-list-topbar ${sidebarCollapsed ? 'sidebar-collapsed' : ''}`}>
|
|
||||||
<div className="topbar-content">
|
|
||||||
<div className="topbar-left">
|
|
||||||
<span className="topbar-icon" aria-hidden="true">
|
|
||||||
<i className="ri-list-settings-line"></i>
|
|
||||||
</span>
|
|
||||||
<div className="topbar-heading">
|
|
||||||
<h2 className="topbar-title">评查规则列表</h2>
|
|
||||||
<span className="topbar-breadcrumb">
|
|
||||||
<span>评查规则库</span>
|
|
||||||
{listScopeText && (
|
|
||||||
<>
|
|
||||||
<span className="separator">/</span>
|
|
||||||
<span>{listScopeText}</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="topbar-right">
|
|
||||||
<a className="topbar-action secondary" href="/rules/list">
|
|
||||||
<i className="ri-history-line"></i>
|
|
||||||
<span>查看旧版本</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form method="get" action="/rulesTest/list" className="topbar-filter-strip">
|
|
||||||
<input type="hidden" name="documentType" defaultValue={listFilters.documentType || ''} />
|
|
||||||
{listFilters.mainType && <input type="hidden" name="mainType" defaultValue={listFilters.mainType} />}
|
|
||||||
<label className="topbar-filter-field">
|
|
||||||
<span>子类型</span>
|
|
||||||
<select name="subtype" value={listFilters.subtype || ''} onChange={submitTopbarFilter}>
|
|
||||||
<option value="">全部子类型</option>
|
|
||||||
{(listOptions.subtypes || []).map(option => (
|
|
||||||
<option key={option} value={option}>{option}</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label className="topbar-filter-field">
|
|
||||||
<span>规则组</span>
|
|
||||||
<select name="ruleGroup" value={listFilters.ruleGroup || ''} onChange={submitTopbarFilter}>
|
|
||||||
<option value="">全部规则组</option>
|
|
||||||
{(listOptions.ruleGroups || []).map(group => (
|
|
||||||
<option key={group} value={group}>{group}</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label className="topbar-filter-field topbar-filter-field-search">
|
|
||||||
<span>搜索</span>
|
|
||||||
<input
|
|
||||||
key={listFilters.keyword || 'empty-keyword'}
|
|
||||||
name="keyword"
|
|
||||||
defaultValue={listFilters.keyword || ''}
|
|
||||||
placeholder="规则名称 / 编码 / 规则组"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
<button className="topbar-action" type="submit">
|
|
||||||
<i className="ri-search-line"></i>
|
|
||||||
<span>筛选</span>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 规则详情页顶部栏 */}
|
{/* 规则详情页顶部栏 */}
|
||||||
{isRulesTestDetail && (
|
{isRulesTestDetail && (
|
||||||
<div className={`page-topbar ${sidebarCollapsed ? 'sidebar-collapsed' : ''}`}>
|
<div className={`page-topbar ${sidebarCollapsed ? 'sidebar-collapsed' : ''}`}>
|
||||||
@@ -283,7 +192,7 @@ export function Layout({ children, userRole = 'developer' as UserRole, frontendJ
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className={`main-content ${sidebarCollapsed ? 'sidebar-collapsed' : ''} ${isRulesTestDetail ? 'rules-detail-main' : ''} ${isRulesTestList ? 'rules-list-main' : ''}`}>
|
<div className={`main-content ${sidebarCollapsed ? 'sidebar-collapsed' : ''} ${isRulesTestDetail ? 'rules-detail-main' : ''}`}>
|
||||||
{/* 应用模块选择器 */}
|
{/* 应用模块选择器 */}
|
||||||
{/* <div className="app-module-selector py-2 px-4 border-b border-gray-100 flex items-center">
|
{/* <div className="app-module-selector py-2 px-4 border-b border-gray-100 flex items-center">
|
||||||
{APP_MODULES.map(app => (
|
{APP_MODULES.map(app => (
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { type LoaderFunctionArgs, type MetaFunction } from '@remix-run/node';
|
import { type LoaderFunctionArgs, type MetaFunction } from '@remix-run/node';
|
||||||
import { Link, useLoaderData } from '@remix-run/react';
|
import { Link, useLoaderData, useSearchParams } from '@remix-run/react';
|
||||||
|
import type React from 'react';
|
||||||
|
import { Button } from '~/components/ui/Button';
|
||||||
import { Card } from '~/components/ui/Card';
|
import { Card } from '~/components/ui/Card';
|
||||||
|
import { FilterPanel, FilterSelect, SearchFilter } from '~/components/ui/FilterPanel';
|
||||||
|
import { Pagination } from '~/components/ui/Pagination';
|
||||||
import { Table } from '~/components/ui/Table';
|
import { Table } from '~/components/ui/Table';
|
||||||
import { Tag, type TagColor } from '~/components/ui/Tag';
|
import { Tag, type TagColor } from '~/components/ui/Tag';
|
||||||
import { loadRuleYamlPacks, type RuleSummary, type RuleYamlPack } from '~/utils/rules-yaml-mock.server';
|
import { loadRuleYamlPacks, type RuleSummary, type RuleYamlPack } from '~/utils/rules-yaml-mock.server';
|
||||||
@@ -14,6 +18,10 @@ export const meta: MetaFunction = () => [
|
|||||||
{ title: '规则 YAML 列表 - 智慧法务' }
|
{ title: '规则 YAML 列表 - 智慧法务' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const handle = {
|
||||||
|
breadcrumb: '评查点列表'
|
||||||
|
};
|
||||||
|
|
||||||
type RuleRow = RuleSummary & {
|
type RuleRow = RuleSummary & {
|
||||||
rowId: string;
|
rowId: string;
|
||||||
packId: string;
|
packId: string;
|
||||||
@@ -34,7 +42,12 @@ type LoaderData = {
|
|||||||
subtype: string;
|
subtype: string;
|
||||||
ruleGroup: string;
|
ruleGroup: string;
|
||||||
keyword: string;
|
keyword: string;
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
};
|
};
|
||||||
|
totalCount: number;
|
||||||
|
currentPage: number;
|
||||||
|
pageSize: number;
|
||||||
options: {
|
options: {
|
||||||
documentTypes: string[];
|
documentTypes: string[];
|
||||||
mainTypes: string[];
|
mainTypes: string[];
|
||||||
@@ -59,12 +72,16 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
const requestedMainType = url.searchParams.get('mainType') || url.searchParams.get('ruleTypeName') || '';
|
const requestedMainType = url.searchParams.get('mainType') || url.searchParams.get('ruleTypeName') || '';
|
||||||
const requestedSubtype = url.searchParams.get('subtype') || url.searchParams.get('documentAttributeType') || '';
|
const requestedSubtype = url.searchParams.get('subtype') || url.searchParams.get('documentAttributeType') || '';
|
||||||
const requestedRuleGroup = url.searchParams.get('ruleGroup') || url.searchParams.getAll('ruleGroups')[0] || '';
|
const requestedRuleGroup = url.searchParams.get('ruleGroup') || url.searchParams.getAll('ruleGroups')[0] || '';
|
||||||
|
const requestedPage = Number(url.searchParams.get('page') || '1');
|
||||||
|
const requestedPageSize = Number(url.searchParams.get('pageSize') || '10');
|
||||||
const requestedFilters = {
|
const requestedFilters = {
|
||||||
documentType: url.searchParams.get('documentType') || '',
|
documentType: url.searchParams.get('documentType') || '',
|
||||||
mainType: requestedMainType,
|
mainType: requestedMainType,
|
||||||
subtype: requestedSubtype,
|
subtype: requestedSubtype,
|
||||||
ruleGroup: requestedRuleGroup,
|
ruleGroup: requestedRuleGroup,
|
||||||
keyword: url.searchParams.get('keyword') || ''
|
keyword: url.searchParams.get('keyword') || '',
|
||||||
|
page: Number.isFinite(requestedPage) && requestedPage > 0 ? requestedPage : 1,
|
||||||
|
pageSize: [10, 20, 30, 50].includes(requestedPageSize) ? requestedPageSize : 10
|
||||||
};
|
};
|
||||||
|
|
||||||
const packs = await loadRuleYamlPacks();
|
const packs = await loadRuleYamlPacks();
|
||||||
@@ -103,7 +120,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
(!filters.subtype || pack.subtype === filters.subtype)
|
(!filters.subtype || pack.subtype === filters.subtype)
|
||||||
);
|
);
|
||||||
|
|
||||||
const rows: RuleRow[] = visiblePacks.flatMap((pack): RuleRow[] => {
|
const filteredRows: RuleRow[] = visiblePacks.flatMap((pack): RuleRow[] => {
|
||||||
if (pack.rules.length === 0) {
|
if (pack.rules.length === 0) {
|
||||||
return [{
|
return [{
|
||||||
rowId: `${pack.id}-empty`,
|
rowId: `${pack.id}-empty`,
|
||||||
@@ -153,11 +170,22 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
return [row.ruleId, row.name, row.group, row.yamlName, row.subtype]
|
return [row.ruleId, row.name, row.group, row.yamlName, row.subtype]
|
||||||
.some(value => value.toLowerCase().includes(filters.keyword.toLowerCase()));
|
.some(value => value.toLowerCase().includes(filters.keyword.toLowerCase()));
|
||||||
});
|
});
|
||||||
|
const totalCount = filteredRows.length;
|
||||||
|
const totalPages = Math.max(1, Math.ceil(totalCount / filters.pageSize));
|
||||||
|
const currentPage = Math.min(filters.page, totalPages);
|
||||||
|
const startIndex = (currentPage - 1) * filters.pageSize;
|
||||||
|
const rows = filteredRows.slice(startIndex, startIndex + filters.pageSize);
|
||||||
|
|
||||||
return Response.json({
|
return Response.json({
|
||||||
rows,
|
rows,
|
||||||
packs,
|
packs,
|
||||||
filters,
|
filters: {
|
||||||
|
...filters,
|
||||||
|
page: currentPage
|
||||||
|
},
|
||||||
|
totalCount,
|
||||||
|
currentPage,
|
||||||
|
pageSize: filters.pageSize,
|
||||||
options: {
|
options: {
|
||||||
documentTypes,
|
documentTypes,
|
||||||
mainTypes: unique(packs.filter(pack => pack.documentType === filters.documentType).map(pack => pack.mainType)),
|
mainTypes: unique(packs.filter(pack => pack.documentType === filters.documentType).map(pack => pack.mainType)),
|
||||||
@@ -171,7 +199,50 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function RulesTestList() {
|
export default function RulesTestList() {
|
||||||
const { rows } = useLoaderData<typeof loader>() as LoaderData;
|
const { rows, filters, options, totalCount, currentPage, pageSize } = useLoaderData<typeof loader>() as LoaderData;
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
|
const updateParams = (updates: Record<string, string | number | undefined>, resetPage = true) => {
|
||||||
|
const nextParams = new URLSearchParams(searchParams);
|
||||||
|
|
||||||
|
Object.entries(updates).forEach(([key, value]) => {
|
||||||
|
if (value === undefined || value === '') {
|
||||||
|
nextParams.delete(key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nextParams.set(key, String(value));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resetPage) {
|
||||||
|
nextParams.set('page', '1');
|
||||||
|
}
|
||||||
|
|
||||||
|
setSearchParams(nextParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFilterChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
const { name, value } = event.target;
|
||||||
|
updateParams({ [name]: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = (keyword: string) => {
|
||||||
|
updateParams({ keyword });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
const nextParams = new URLSearchParams(searchParams);
|
||||||
|
['ruleGroup', 'subtype', 'documentAttributeType', 'keyword', 'page'].forEach(key => nextParams.delete(key));
|
||||||
|
nextParams.set('page', '1');
|
||||||
|
setSearchParams(nextParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
updateParams({ page }, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageSizeChange = (nextPageSize: number) => {
|
||||||
|
updateParams({ pageSize: nextPageSize, page: 1 }, false);
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@@ -244,15 +315,77 @@ export default function RulesTestList() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rules-test-page rules-page">
|
<div className="rules-test-page rules-page">
|
||||||
<div className="page-shell">
|
<div className="rules-test-list-shell">
|
||||||
|
<div className="rules-list-header">
|
||||||
|
<div className="rules-list-title">
|
||||||
|
<h2>评查点管理</h2>
|
||||||
|
<div className="rules-list-total">
|
||||||
|
<i className="ri-file-list-3-line"></i>
|
||||||
|
<span>总评查点数:</span>
|
||||||
|
<strong>{totalCount}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FilterPanel
|
||||||
|
className="rules-test-filter-panel px-3 py-3"
|
||||||
|
noActionDivider={true}
|
||||||
|
actions={
|
||||||
|
<Button type="default" icon="ri-refresh-line" onClick={handleReset} className="mr-2 hover:!border-gray-300">
|
||||||
|
重置
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FilterSelect
|
||||||
|
label="所属规则组"
|
||||||
|
name="ruleGroup"
|
||||||
|
value={filters.ruleGroup}
|
||||||
|
options={options.ruleGroups.map(group => ({ value: group, label: group }))}
|
||||||
|
onChange={handleFilterChange}
|
||||||
|
className="mr-3 w-[22%]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FilterSelect
|
||||||
|
label="子类型"
|
||||||
|
name="subtype"
|
||||||
|
value={filters.subtype}
|
||||||
|
options={options.subtypes.map(subtype => ({ value: subtype, label: subtype }))}
|
||||||
|
onChange={handleFilterChange}
|
||||||
|
className="mr-3 w-[18%]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SearchFilter
|
||||||
|
key={filters.keyword}
|
||||||
|
label="搜索"
|
||||||
|
placeholder="输入评查点名称或编码"
|
||||||
|
value={filters.keyword}
|
||||||
|
buttonText="搜索"
|
||||||
|
onSearch={handleSearch}
|
||||||
|
className="min-w-[200px] flex-1"
|
||||||
|
/>
|
||||||
|
</FilterPanel>
|
||||||
|
|
||||||
<Card className="ant-card">
|
<Card className="ant-card">
|
||||||
<Table
|
<Table
|
||||||
className="rules-test-table rules-table"
|
className="rules-test-table rules-table"
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={rows}
|
dataSource={rows}
|
||||||
rowKey="rowId"
|
rowKey="rowId"
|
||||||
|
scroll={{ y: 700 }}
|
||||||
emptyText={<div className="empty-state">暂无规则。当前类型的规则列表流程已保留,可进入配置页查看空 YAML 模板。</div>}
|
emptyText={<div className="empty-state">暂无规则。当前类型的规则列表流程已保留,可进入配置页查看空 YAML 模板。</div>}
|
||||||
/>
|
/>
|
||||||
|
{totalCount > 0 && (
|
||||||
|
<Pagination
|
||||||
|
currentPage={currentPage}
|
||||||
|
total={totalCount}
|
||||||
|
pageSize={pageSize}
|
||||||
|
onChange={handlePageChange}
|
||||||
|
onPageSizeChange={handlePageSizeChange}
|
||||||
|
showTotal={true}
|
||||||
|
showPageSizeChanger={true}
|
||||||
|
pageSizeOptions={[10, 20, 30, 50]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,6 +30,71 @@
|
|||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-test-list-shell {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-list-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-list-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-list-title h2 {
|
||||||
|
margin: 0;
|
||||||
|
color: #17231f;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-list-total {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
min-height: 28px;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #fff;
|
||||||
|
color: #6b7b73;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-list-total i,
|
||||||
|
.rules-test-page .rules-list-total strong {
|
||||||
|
color: #00684a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-list-total strong {
|
||||||
|
margin-left: 2px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-test-filter-panel {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-test-filter-panel .filter-list {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rules-test-page .rules-test-filter-panel .filter-actions {
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
.rules-test-page .rules-test-hero {
|
.rules-test-page .rules-test-hero {
|
||||||
border: 1px solid #dfe8e3;
|
border: 1px solid #dfe8e3;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|||||||
Reference in New Issue
Block a user