refine Semi UI account workspace
This commit is contained in:
@@ -57,13 +57,14 @@ test('deduplicates vehicle candidates by VIN and renders granted vehicles plate
|
|||||||
expect(customer.closest('.semi-list-item')).toHaveClass('v2-user-list-row');
|
expect(customer.closest('.semi-list-item')).toHaveClass('v2-user-list-row');
|
||||||
expect(customer).toHaveAttribute('aria-pressed', 'false');
|
expect(customer).toHaveAttribute('aria-pressed', 'false');
|
||||||
expect(customer).toHaveAttribute('aria-expanded', 'false');
|
expect(customer).toHaveAttribute('aria-expanded', 'false');
|
||||||
expect(view.container.querySelector('.v2-user-editor.semi-card')).not.toBeInTheDocument();
|
expect(document.querySelector('.v2-user-editor-sidesheet')).not.toBeInTheDocument();
|
||||||
fireEvent.click(customer);
|
fireEvent.click(customer);
|
||||||
await waitFor(() => expect(customer).toHaveAttribute('aria-expanded', 'true'));
|
await waitFor(() => expect(customer).toHaveAttribute('aria-expanded', 'true'));
|
||||||
expect(view.container.querySelector('.v2-user-editor.semi-card')).toBeInTheDocument();
|
expect(document.querySelector('.v2-user-editor-sidesheet .semi-sidesheet-inner')).toHaveAttribute('aria-label', '客户账号详情');
|
||||||
expect(view.container.querySelector('.v2-user-editor-tabs.semi-tabs')).toBeInTheDocument();
|
expect(document.querySelector('.v2-user-editor-sidesheet .v2-user-editor-tabs.semi-tabs')).toBeInTheDocument();
|
||||||
|
expect(document.querySelector('.v2-user-editor-form')).toHaveAttribute('id', 'v2-user-editor-form');
|
||||||
expect(screen.getAllByRole('tab')).toHaveLength(3);
|
expect(screen.getAllByRole('tab')).toHaveLength(3);
|
||||||
expect(view.container.querySelector('.v2-user-vehicle-section.semi-card')).toBeInTheDocument();
|
expect(document.querySelector('.v2-user-vehicle-section.semi-card')).toBeInTheDocument();
|
||||||
fireEvent.click(screen.getByRole('tab', { name: /菜单权限/ }));
|
fireEvent.click(screen.getByRole('tab', { name: /菜单权限/ }));
|
||||||
expect(screen.getByText('客户开放菜单').closest('.semi-tag')).toBeInTheDocument();
|
expect(screen.getByText('客户开放菜单').closest('.semi-tag')).toBeInTheDocument();
|
||||||
fireEvent.click(screen.getByRole('tab', { name: /车辆权限/ }));
|
fireEvent.click(screen.getByRole('tab', { name: /车辆权限/ }));
|
||||||
@@ -126,7 +127,7 @@ test('pages and filters large vehicle grants without nesting a vehicle-list scro
|
|||||||
|
|
||||||
expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(10);
|
expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(10);
|
||||||
expect(screen.getByText('第 1–10 条,共 12 辆')).toBeInTheDocument();
|
expect(screen.getByText('第 1–10 条,共 12 辆')).toBeInTheDocument();
|
||||||
expect(view.container.querySelector('.v2-assigned-pagination')).toBeInTheDocument();
|
expect(document.querySelector('.v2-assigned-pagination')).toBeInTheDocument();
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Next' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Next' }));
|
||||||
expect(await screen.findByRole('button', { name: '移除 粤A00012' })).toBeInTheDocument();
|
expect(await screen.findByRole('button', { name: '移除 粤A00012' })).toBeInTheDocument();
|
||||||
expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(2);
|
expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(2);
|
||||||
@@ -156,12 +157,12 @@ test('keeps the customer directory visible on mobile and opens details on demand
|
|||||||
expect(filterToggle).toHaveAttribute('aria-expanded', 'false');
|
expect(filterToggle).toHaveAttribute('aria-expanded', 'false');
|
||||||
fireEvent.click(filterToggle);
|
fireEvent.click(filterToggle);
|
||||||
expect(screen.getByRole('button', { name: '收起账号范围:全部状态' })).toHaveAttribute('aria-expanded', 'true');
|
expect(screen.getByRole('button', { name: '收起账号范围:全部状态' })).toHaveAttribute('aria-expanded', 'true');
|
||||||
expect(view.container.querySelector('.v2-user-editor')).not.toBeInTheDocument();
|
expect(document.querySelector('.v2-user-editor-sidesheet')).not.toBeInTheDocument();
|
||||||
fireEvent.click(customer);
|
fireEvent.click(customer);
|
||||||
expect(await screen.findByRole('button', { name: '关闭账号详情' })).toBeInTheDocument();
|
expect(await screen.findByRole('button', { name: '关闭账号详情' })).toBeInTheDocument();
|
||||||
expect(customer).toHaveAttribute('aria-expanded', 'true');
|
expect(customer).toHaveAttribute('aria-expanded', 'true');
|
||||||
fireEvent.click(screen.getByRole('button', { name: '关闭账号详情' }));
|
fireEvent.click(screen.getByRole('button', { name: '关闭账号详情' }));
|
||||||
expect(view.container.querySelector('.v2-user-editor')).not.toBeInTheDocument();
|
await waitFor(() => expect(document.querySelector('.v2-user-editor-form')).not.toBeInTheDocument());
|
||||||
expect(customer).toHaveAttribute('aria-expanded', 'false');
|
expect(customer).toHaveAttribute('aria-expanded', 'false');
|
||||||
expect(screen.getAllByRole('button', { name: '新建客户账号' })).toHaveLength(1);
|
expect(screen.getAllByRole('button', { name: '新建客户账号' })).toHaveLength(1);
|
||||||
});
|
});
|
||||||
@@ -210,7 +211,7 @@ test('uses a standard Semi empty state when no customer account exists', async (
|
|||||||
|
|
||||||
expect(await screen.findByText('还没有客户账号')).toBeInTheDocument();
|
expect(await screen.findByText('还没有客户账号')).toBeInTheDocument();
|
||||||
expect(view.container.querySelector('.v2-user-list-empty.semi-empty')).toBeInTheDocument();
|
expect(view.container.querySelector('.v2-user-list-empty.semi-empty')).toBeInTheDocument();
|
||||||
expect(view.container.querySelector('.v2-user-editor')).not.toBeInTheDocument();
|
expect(document.querySelector('.v2-user-editor-sidesheet')).not.toBeInTheDocument();
|
||||||
expect(screen.getAllByRole('button', { name: '创建第一个客户账号' })).toHaveLength(1);
|
expect(screen.getAllByRole('button', { name: '创建第一个客户账号' })).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { IconChevronRight, IconClose, IconDelete, IconPlus, IconRefresh, IconSearch } from '@douyinfe/semi-icons';
|
import { IconChevronRight, IconDelete, IconPlus, IconRefresh, IconSearch } from '@douyinfe/semi-icons';
|
||||||
import { Avatar, Button, Card, Checkbox, Collapse, Empty, Input, List, Select, SideSheet, Spin, Switch, Tabs, Tag, Typography } from '@douyinfe/semi-ui';
|
import { Avatar, Button, Card, Checkbox, Collapse, Empty, Input, List, Select, SideSheet, Spin, Switch, Tabs, Tag, Typography } from '@douyinfe/semi-ui';
|
||||||
import { FormEvent, useDeferredValue, useEffect, useMemo, useState } from 'react';
|
import { FormEvent, useDeferredValue, useEffect, useMemo, useState } from 'react';
|
||||||
import { api } from '../../api/client';
|
import { api } from '../../api/client';
|
||||||
@@ -102,6 +102,8 @@ export default function UsersPage() {
|
|||||||
const editingGrant = useMemo(() => draft.vehicleGrants.find((grant) => grant.vin === editingGrantVIN), [draft.vehicleGrants, editingGrantVIN]);
|
const editingGrant = useMemo(() => draft.vehicleGrants.find((grant) => grant.vin === editingGrantVIN), [draft.vehicleGrants, editingGrantVIN]);
|
||||||
const editingGrantPlate = editingGrant ? vehicleLabels[editingGrant.vin] : '';
|
const editingGrantPlate = editingGrant ? vehicleLabels[editingGrant.vin] : '';
|
||||||
const grantWindowInvalid = Boolean(editingGrant && (!editingGrant.validFrom || (editingGrant.validTo && editingGrant.validTo <= editingGrant.validFrom)));
|
const grantWindowInvalid = Boolean(editingGrant && (!editingGrant.validFrom || (editingGrant.validTo && editingGrant.validTo <= editingGrant.validFrom)));
|
||||||
|
const editorVisible = creating || Boolean(selected);
|
||||||
|
useSideSheetA11y(editorVisible, '.v2-user-editor-sidesheet', 'v2-user-editor-sheet', '客户账号详情', '关闭账号详情');
|
||||||
useSideSheetA11y(Boolean(editingGrant), '.v2-user-grant-sidesheet', 'v2-user-grant-window', '车辆授权有效期', '关闭车辆授权有效期');
|
useSideSheetA11y(Boolean(editingGrant), '.v2-user-grant-sidesheet', 'v2-user-grant-window', '车辆授权有效期', '关闭车辆授权有效期');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -226,8 +228,8 @@ export default function UsersPage() {
|
|||||||
setAssignedPage(1);
|
setAssignedPage(1);
|
||||||
setBulkVINs('');
|
setBulkVINs('');
|
||||||
};
|
};
|
||||||
const submit = (event: FormEvent) => {
|
const persistDraft = () => {
|
||||||
event.preventDefault();
|
if (save.isPending) return;
|
||||||
setFeedback('');
|
setFeedback('');
|
||||||
if (!draft.displayName.trim() || (creating && (!draft.username.trim() || !draft.password))) {
|
if (!draft.displayName.trim() || (creating && (!draft.username.trim() || !draft.password))) {
|
||||||
setActiveSection('identity');
|
setActiveSection('identity');
|
||||||
@@ -243,6 +245,10 @@ export default function UsersPage() {
|
|||||||
}
|
}
|
||||||
save.mutate();
|
save.mutate();
|
||||||
};
|
};
|
||||||
|
const submit = (event: FormEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
persistDraft();
|
||||||
|
};
|
||||||
|
|
||||||
return <div className="v2-user-admin">
|
return <div className="v2-user-admin">
|
||||||
<WorkspaceCommandBar
|
<WorkspaceCommandBar
|
||||||
@@ -314,6 +320,7 @@ export default function UsersPage() {
|
|||||||
<span><small>车辆授权</small><strong>{grantedVehicles}</strong></span>
|
<span><small>车辆授权</small><strong>{grantedVehicles}</strong></span>
|
||||||
</div>
|
</div>
|
||||||
{users.isPending ? <PanelLoading className="v2-user-list-loading" title="正在加载客户账号" description="账号目录和授权摘要就绪后会自动显示。" /> : customers.length === 0 ? <PanelEmpty className="v2-user-list-empty" title="还没有客户账号" description="创建客户账号后,可在这里配置菜单和车辆范围。" action={<Button theme="solid" onClick={startCreate}>创建第一个客户账号</Button>} /> : <>
|
{users.isPending ? <PanelLoading className="v2-user-list-loading" title="正在加载客户账号" description="账号目录和授权摘要就绪后会自动显示。" /> : customers.length === 0 ? <PanelEmpty className="v2-user-list-empty" title="还没有客户账号" description="创建客户账号后,可在这里配置菜单和车辆范围。" action={<Button theme="solid" onClick={startCreate}>创建第一个客户账号</Button>} /> : <>
|
||||||
|
<div className="v2-customer-list-scroll" role="region" aria-label="客户账号目录,可上下滚动" tabIndex={0}>
|
||||||
<List
|
<List
|
||||||
className="v2-customer-list"
|
className="v2-customer-list"
|
||||||
dataSource={visibleCustomers}
|
dataSource={visibleCustomers}
|
||||||
@@ -337,12 +344,27 @@ export default function UsersPage() {
|
|||||||
</Button>
|
</Button>
|
||||||
</List.Item>}
|
</List.Item>}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</>}
|
</>}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
{creating || selected ? <Card className="v2-user-editor" bodyStyle={{ padding: 0 }} aria-label="客户账号详情">
|
</div>
|
||||||
<form onSubmit={submit}>
|
<SideSheet
|
||||||
<div className="v2-user-editor-title"><div><h3>{creating ? '创建客户账号' : selected?.displayName}</h3><p>{creating ? '设置登录身份和最小必要权限' : `@${selected?.username} · ${draft.menuKeys.length} 个菜单 · ${draft.vehicleGrants.length} 辆车 · 最近登录 ${formatTime(selected?.lastLoginAt)}`}</p></div><label className="v2-user-status"><Switch aria-label={draft.status === 'enabled' ? '账号启用' : '账号停用'} checked={draft.status === 'enabled'} onChange={(checked) => setDraft((value) => ({ ...value, status: checked ? 'enabled' : 'disabled' }))} /><span>{draft.status === 'enabled' ? '账号启用' : '账号停用'}</span></label><Button className="v2-user-editor-close" theme="borderless" type="tertiary" icon={<IconClose />} aria-label="关闭账号详情" onClick={closeEditor} /></div>
|
className="v2-user-editor-sidesheet"
|
||||||
|
visible={editorVisible}
|
||||||
|
width={mobileLayout ? '100%' : 840}
|
||||||
|
aria-label="客户账号详情"
|
||||||
|
title={<div className="v2-user-editor-sheet-title">
|
||||||
|
<span><strong>{creating ? '创建客户账号' : selected?.displayName}</strong><small>{creating ? '设置登录身份和最小必要权限' : `@${selected?.username} · ${draft.menuKeys.length} 个菜单 · ${draft.vehicleGrants.length} 辆车 · 最近登录 ${formatTime(selected?.lastLoginAt)}`}</small></span>
|
||||||
|
<label className="v2-user-status"><Switch aria-label={draft.status === 'enabled' ? '账号启用' : '账号停用'} checked={draft.status === 'enabled'} onChange={(checked) => setDraft((value) => ({ ...value, status: checked ? 'enabled' : 'disabled' }))} /><span>{draft.status === 'enabled' ? '账号启用' : '账号停用'}</span></label>
|
||||||
|
</div>}
|
||||||
|
onCancel={closeEditor}
|
||||||
|
footer={<div className="v2-user-editor-sheet-footer">
|
||||||
|
<Typography.Text className={`v2-user-feedback${save.isError ? ' is-error' : ''}`} role="status" type={save.isError ? 'danger' : 'tertiary'}>{feedback || '权限变更最多 30 秒生效,保存前请核对车辆有效期'}</Typography.Text>
|
||||||
|
<Button theme="solid" htmlType="submit" form="v2-user-editor-form" disabled={save.isPending}>{save.isPending ? '正在保存…' : creating ? '创建账号' : '保存权限'}</Button>
|
||||||
|
</div>}
|
||||||
|
>
|
||||||
|
{editorVisible ? <form id="v2-user-editor-form" className="v2-user-editor-form" onSubmit={submit}>
|
||||||
<Tabs className="v2-user-editor-tabs" activeKey={activeSection} onChange={(key) => setActiveSection(String(key) as EditorSection)}>
|
<Tabs className="v2-user-editor-tabs" activeKey={activeSection} onChange={(key) => setActiveSection(String(key) as EditorSection)}>
|
||||||
<Tabs.TabPane tab="登录身份" itemKey="identity">
|
<Tabs.TabPane tab="登录身份" itemKey="identity">
|
||||||
<Card className="v2-user-editor-section v2-user-identity-section" title="登录身份" headerLine>
|
<Card className="v2-user-editor-section v2-user-identity-section" title="登录身份" headerLine>
|
||||||
@@ -413,11 +435,8 @@ export default function UsersPage() {
|
|||||||
</Card>
|
</Card>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
{feedback ? <p className={`v2-user-feedback${save.isError ? ' is-error' : ''}`} role="status">{feedback}</p> : null}
|
</form> : null}
|
||||||
<footer><Button theme="solid" htmlType="submit" disabled={save.isPending}>{save.isPending ? '正在保存…' : creating ? '创建账号' : '保存权限'}</Button></footer>
|
</SideSheet>
|
||||||
</form>
|
|
||||||
</Card> : null}
|
|
||||||
</div>
|
|
||||||
<SideSheet
|
<SideSheet
|
||||||
className="v2-user-grant-sidesheet"
|
className="v2-user-grant-sidesheet"
|
||||||
visible={Boolean(editingGrant)}
|
visible={Boolean(editingGrant)}
|
||||||
|
|||||||
@@ -221,7 +221,8 @@ describe('V2 production entry', () => {
|
|||||||
expect(corePageSources.UsersPage).toContain('<Avatar');
|
expect(corePageSources.UsersPage).toContain('<Avatar');
|
||||||
expect(corePageSources.UsersPage).toContain('<Card');
|
expect(corePageSources.UsersPage).toContain('<Card');
|
||||||
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-list"');
|
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-list"');
|
||||||
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-editor"');
|
expect(corePageSources.UsersPage).toContain('className="v2-user-editor-sidesheet"');
|
||||||
|
expect(corePageSources.UsersPage).toContain('useSideSheetA11y(editorVisible');
|
||||||
expect(corePageSources.UsersPage).toContain('<List');
|
expect(corePageSources.UsersPage).toContain('<List');
|
||||||
expect(corePageSources.UsersPage).toContain('<List.Item');
|
expect(corePageSources.UsersPage).toContain('<List.Item');
|
||||||
expect(corePageSources.UsersPage).toContain('className="v2-user-command-bar"');
|
expect(corePageSources.UsersPage).toContain('className="v2-user-command-bar"');
|
||||||
@@ -229,7 +230,7 @@ describe('V2 production entry', () => {
|
|||||||
expect(corePageSources.UsersPage).toContain('aria-expanded={selectedID === user.id && !creating}');
|
expect(corePageSources.UsersPage).toContain('aria-expanded={selectedID === user.id && !creating}');
|
||||||
expect(corePageSources.UsersPage).toContain('<Tabs className="v2-user-editor-tabs"');
|
expect(corePageSources.UsersPage).toContain('<Tabs className="v2-user-editor-tabs"');
|
||||||
expect(corePageSources.UsersPage).toContain('<Tabs.TabPane');
|
expect(corePageSources.UsersPage).toContain('<Tabs.TabPane');
|
||||||
expect(corePageSources.UsersPage).toContain('aria-label="关闭账号详情"');
|
expect(corePageSources.UsersPage).toContain("'关闭账号详情'");
|
||||||
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-editor-section v2-user-identity-section"');
|
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-editor-section v2-user-identity-section"');
|
||||||
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-editor-section v2-user-menu-section"');
|
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-editor-section v2-user-menu-section"');
|
||||||
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-editor-section v2-user-vehicle-section"');
|
expect(corePageSources.UsersPage).toContain('<Card className="v2-user-editor-section v2-user-vehicle-section"');
|
||||||
|
|||||||
@@ -8210,3 +8210,292 @@
|
|||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Semi UI account inspector: keep the directory stable and edit in a native SideSheet. */
|
||||||
|
.v2-customer-list-scroll {
|
||||||
|
min-height: 0;
|
||||||
|
flex: 1 1 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-customer-list-scroll > .v2-customer-list.semi-list {
|
||||||
|
min-height: auto;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-customer-list-scroll:focus-visible {
|
||||||
|
outline: 2px solid rgba(18, 104, 243, .35);
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .semi-sidesheet-inner {
|
||||||
|
overflow: hidden;
|
||||||
|
border-left: 1px solid #d8e2ee;
|
||||||
|
background: #f6f8fb;
|
||||||
|
box-shadow: -20px 0 58px rgba(27, 47, 73, .16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .semi-sidesheet-header {
|
||||||
|
min-height: 76px;
|
||||||
|
border-bottom: 1px solid #e2e9f1;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 18px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title > span {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title strong {
|
||||||
|
overflow: hidden;
|
||||||
|
color: #20364e;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 750;
|
||||||
|
letter-spacing: -.025em;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title small {
|
||||||
|
overflow: hidden;
|
||||||
|
color: #7b899a;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.4;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title .v2-user-status {
|
||||||
|
display: flex;
|
||||||
|
min-width: 92px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 7px;
|
||||||
|
color: #53667c;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 650;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .semi-sidesheet-body {
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #f6f8fb;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-form {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs.semi-tabs {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
flex: 1 1 0;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
background: #f6f8fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-bar {
|
||||||
|
min-height: 52px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
border-bottom: 1px solid #e2e9f1;
|
||||||
|
background: #fff;
|
||||||
|
padding-inline: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-bar .semi-tabs-tab {
|
||||||
|
min-height: 51px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 650;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-content {
|
||||||
|
min-height: 0;
|
||||||
|
flex: 1 1 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
background: #f6f8fb;
|
||||||
|
padding: 12px;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-content:focus-visible {
|
||||||
|
outline: 2px solid rgba(18, 104, 243, .35);
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-section.semi-card {
|
||||||
|
margin: 0;
|
||||||
|
border: 1px solid #dce5ef;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 6px 22px rgba(31, 53, 80, .05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .semi-sidesheet-footer {
|
||||||
|
min-height: 64px;
|
||||||
|
border-top: 1px solid #e2e9f1;
|
||||||
|
background: #fff;
|
||||||
|
padding: 10px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-footer {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-footer .v2-user-feedback.semi-typography {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 1.45;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-footer > .semi-button {
|
||||||
|
min-width: 132px;
|
||||||
|
min-height: 40px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
border-radius: 9px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 680px) {
|
||||||
|
.v2-customer-list-scroll {
|
||||||
|
scrollbar-width: auto;
|
||||||
|
touch-action: pan-y;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-customer-list-scroll::-webkit-scrollbar {
|
||||||
|
width: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-customer-list-scroll::-webkit-scrollbar-thumb {
|
||||||
|
border: 3px solid transparent;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #9cacc0;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .semi-sidesheet-inner {
|
||||||
|
width: 100% !important;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .semi-sidesheet-header {
|
||||||
|
min-height: 66px;
|
||||||
|
padding: 9px 10px 9px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title {
|
||||||
|
gap: 8px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title strong {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title small {
|
||||||
|
max-width: 226px;
|
||||||
|
font-size: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title .v2-user-status {
|
||||||
|
min-width: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-title .v2-user-status > span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-bar {
|
||||||
|
min-height: 48px;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding-inline: 10px;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-bar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-bar .semi-tabs-tab {
|
||||||
|
min-height: 47px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-right: 14px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-content {
|
||||||
|
padding: 7px;
|
||||||
|
scrollbar-width: auto;
|
||||||
|
touch-action: pan-y;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-content::-webkit-scrollbar {
|
||||||
|
width: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .v2-user-editor-tabs > .semi-tabs-content::-webkit-scrollbar-thumb {
|
||||||
|
border: 3px solid transparent;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #9cacc0;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sidesheet .semi-sidesheet-footer {
|
||||||
|
min-height: 62px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-footer {
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-footer .v2-user-feedback.semi-typography {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-user-editor-sheet-footer > .semi-button {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 44px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user