mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-09 01:53:21 +08:00
Use table layout for access-grant people lists (4.9.1-ops.15).
Nickname, phone, permission, and actions sit in aligned columns with headers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
a59a09e0d2
commit
a10d900a7b
6 changed files with 268 additions and 141 deletions
|
|
@ -204,44 +204,53 @@ function MemberRows({
|
|||
...(nested ? {} : { disabled }),
|
||||
},
|
||||
nested ? h('h4', { className: 'dim-accessSubblockTitle' }, title) : h('legend', null, title),
|
||||
h('ul', { className: 'dim-accessCompactList' }, members.map((member, index) =>
|
||||
h('li', {
|
||||
key: `member-${index}`,
|
||||
className: 'dim-accessCompactRow',
|
||||
'data-kind': 'member',
|
||||
},
|
||||
h('div', { className: 'dim-accessCompactIdentity' },
|
||||
h(PhoneTypeahead, {
|
||||
value: member.phone,
|
||||
contacts,
|
||||
disabled,
|
||||
placeholder: '8613800000000',
|
||||
onChange: (phone) => onChange(members.map((entry, i) => (
|
||||
i === index ? { ...entry, phone } : entry
|
||||
))),
|
||||
}),
|
||||
h(NicknameHint, { contacts, phone: member.phone, shortEmpty: true })),
|
||||
h('select', {
|
||||
className: 'dim-accessCompactSelect',
|
||||
title: '命令权限',
|
||||
'aria-label': '命令权限',
|
||||
value: member.canExecuteCommands ? 'allow' : 'deny',
|
||||
disabled,
|
||||
onChange: (event) => onChange(members.map((entry, i) => (
|
||||
i === index
|
||||
? { ...entry, canExecuteCommands: event.target.value === 'allow' }
|
||||
: entry
|
||||
))),
|
||||
},
|
||||
h('option', { value: 'allow' }, '可执行命令'),
|
||||
h('option', { value: 'deny' }, '不可执行命令')),
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dim-deliveryButton dim-accessCompactDelete',
|
||||
'data-kind': 'danger',
|
||||
disabled,
|
||||
onClick: () => onChange(members.filter((_, i) => i !== index)),
|
||||
}, '删除')))),
|
||||
h('div', { className: 'dim-accessTableWrap' },
|
||||
h('table', { className: 'dim-accessTable', 'data-kind': 'member' },
|
||||
h('thead', null,
|
||||
h('tr', null,
|
||||
h('th', { scope: 'col' }, '昵称'),
|
||||
h('th', { scope: 'col' }, '电话'),
|
||||
h('th', { scope: 'col' }, '命令权限'),
|
||||
h('th', { scope: 'col', className: 'dim-accessTableActions' }, '操作'))),
|
||||
h('tbody', null, members.length === 0
|
||||
? h('tr', null, h('td', { colSpan: 4, className: 'dim-accessTableEmpty' }, '暂无用户,可点下方新增。'))
|
||||
: members.map((member, index) =>
|
||||
h('tr', { key: `member-${index}` },
|
||||
h('td', { className: 'dim-accessTableNick' },
|
||||
h(NicknameHint, { contacts, phone: member.phone, shortEmpty: true })),
|
||||
h('td', { className: 'dim-accessTablePhone' },
|
||||
h(PhoneTypeahead, {
|
||||
value: member.phone,
|
||||
contacts,
|
||||
disabled,
|
||||
placeholder: '8613800000000',
|
||||
onChange: (phone) => onChange(members.map((entry, i) => (
|
||||
i === index ? { ...entry, phone } : entry
|
||||
))),
|
||||
})),
|
||||
h('td', { className: 'dim-accessTablePerm' },
|
||||
h('select', {
|
||||
className: 'dim-accessCompactSelect',
|
||||
title: '命令权限',
|
||||
'aria-label': '命令权限',
|
||||
value: member.canExecuteCommands ? 'allow' : 'deny',
|
||||
disabled,
|
||||
onChange: (event) => onChange(members.map((entry, i) => (
|
||||
i === index
|
||||
? { ...entry, canExecuteCommands: event.target.value === 'allow' }
|
||||
: entry
|
||||
))),
|
||||
},
|
||||
h('option', { value: 'allow' }, '可执行命令'),
|
||||
h('option', { value: 'deny' }, '不可执行命令'))),
|
||||
h('td', { className: 'dim-accessTableActions' },
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dim-deliveryButton dim-accessCompactDelete',
|
||||
'data-kind': 'danger',
|
||||
disabled,
|
||||
onClick: () => onChange(members.filter((_, i) => i !== index)),
|
||||
}, '删除'))))))),
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dim-deliveryButton',
|
||||
|
|
@ -266,36 +275,44 @@ function AdminPhones({
|
|||
},
|
||||
nested ? h('h4', { className: 'dim-accessSubblockTitle' }, title) : h('legend', null, title),
|
||||
help ? h('p', { className: 'dim-accessHint' }, help) : null,
|
||||
h('ul', { className: 'dim-accessCompactList' }, phones.map((phone, index) => {
|
||||
const locked = lockedPhone && phone === lockedPhone;
|
||||
return h('li', {
|
||||
key: `admin-${index}`,
|
||||
className: 'dim-accessCompactRow',
|
||||
'data-kind': 'admin',
|
||||
...(locked ? { 'data-locked': 'true' } : {}),
|
||||
},
|
||||
h('div', { className: 'dim-accessCompactIdentity' },
|
||||
h(PhoneTypeahead, {
|
||||
value: phone,
|
||||
contacts,
|
||||
disabled: disabled || locked,
|
||||
placeholder: '8613800000000',
|
||||
onChange: (next) => onChange(phones.map((entry, i) => (i === index ? next : entry))),
|
||||
}),
|
||||
locked
|
||||
? h('span', { className: 'dim-accessNickname' }, '绑定账号(全局管理员)')
|
||||
: h(NicknameHint, { contacts, phone, shortEmpty: true })),
|
||||
h('span', { className: 'dim-accessCompactSelectSlot', 'aria-hidden': 'true' }),
|
||||
locked
|
||||
? h('span', { className: 'dim-accessCompactDeleteSlot', 'aria-hidden': 'true' })
|
||||
: h('button', {
|
||||
type: 'button',
|
||||
className: 'dim-deliveryButton dim-accessCompactDelete',
|
||||
'data-kind': 'danger',
|
||||
disabled,
|
||||
onClick: () => onChange(phones.filter((_, i) => i !== index)),
|
||||
}, '删除'));
|
||||
})),
|
||||
h('div', { className: 'dim-accessTableWrap' },
|
||||
h('table', { className: 'dim-accessTable', 'data-kind': 'admin' },
|
||||
h('thead', null,
|
||||
h('tr', null,
|
||||
h('th', { scope: 'col' }, '昵称'),
|
||||
h('th', { scope: 'col' }, '电话'),
|
||||
h('th', { scope: 'col', className: 'dim-accessTableActions' }, '操作'))),
|
||||
h('tbody', null, phones.length === 0
|
||||
? h('tr', null, h('td', { colSpan: 3, className: 'dim-accessTableEmpty' }, '暂无管理员,可点下方新增。'))
|
||||
: phones.map((phone, index) => {
|
||||
const locked = lockedPhone && phone === lockedPhone;
|
||||
return h('tr', {
|
||||
key: `admin-${index}`,
|
||||
...(locked ? { 'data-locked': 'true' } : {}),
|
||||
},
|
||||
h('td', { className: 'dim-accessTableNick' },
|
||||
locked
|
||||
? h('span', { className: 'dim-accessNickname' }, '绑定账号')
|
||||
: h(NicknameHint, { contacts, phone, shortEmpty: true })),
|
||||
h('td', { className: 'dim-accessTablePhone' },
|
||||
h(PhoneTypeahead, {
|
||||
value: phone,
|
||||
contacts,
|
||||
disabled: disabled || locked,
|
||||
placeholder: '8613800000000',
|
||||
onChange: (next) => onChange(phones.map((entry, i) => (i === index ? next : entry))),
|
||||
})),
|
||||
h('td', { className: 'dim-accessTableActions' },
|
||||
locked
|
||||
? h('span', { className: 'dim-accessTableLocked' }, '不可删除')
|
||||
: h('button', {
|
||||
type: 'button',
|
||||
className: 'dim-deliveryButton dim-accessCompactDelete',
|
||||
'data-kind': 'danger',
|
||||
disabled,
|
||||
onClick: () => onChange(phones.filter((_, i) => i !== index)),
|
||||
}, '删除')));
|
||||
})))),
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dim-deliveryButton',
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@ const EN = Object.freeze({
|
|||
'机器人设置页签': 'Bot settings tabs',
|
||||
'投递设置': 'Delivery settings',
|
||||
'访问设置': 'Access settings',
|
||||
"暂无管理员,可点下方新增。": "No admins yet. Add one below.",
|
||||
"暂无用户,可点下方新增。": "No users yet. Add one below.",
|
||||
"不可删除": "Locked",
|
||||
"绑定账号": "Linked account",
|
||||
"操作": "Actions",
|
||||
"昵称": "Nickname",
|
||||
"请提交有效的群名同步请求。": "Submit a valid group-name sync request.",
|
||||
"同步群名失败,请稍后重试。": "Could not sync the group name. Try again later.",
|
||||
"未能从 WhatsApp 读取群名,请确认机器人在线且仍在该群。": "Could not read the group name from WhatsApp. Confirm the bot is online and still in the group.",
|
||||
|
|
|
|||
|
|
@ -471,6 +471,29 @@ body[data-ds-dark-theme] .dim-page select option, body[data-ds-dark-theme] .dim-
|
|||
.dim-accessCompactDelete, .dim-accessCompactDeleteSlot { width: 100%; min-height: 32px; justify-self: stretch; }
|
||||
.dim-accessCompactDelete { padding-inline: 8px; }
|
||||
.dim-accessCompactDeleteSlot { display: block; }
|
||||
.dim-accessTableWrap { min-width: 0; margin-top: 8px; overflow: auto; border: 1px solid var(--dsw-alias-border-l1, #eef0f3); border-radius: 8px; background: var(--dsw-alias-bg-layer-1, #fff); }
|
||||
.dim-accessTable { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
||||
.dim-accessTable th, .dim-accessTable td { padding: 8px 10px; border-bottom: 1px solid var(--dsw-alias-border-l1, #eef0f3); text-align: left; vertical-align: middle; }
|
||||
.dim-accessTable th { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 16px; font-weight: 600; background: color-mix(in srgb, var(--dsw-alias-bg-module-platform, #f7f8fa) 80%, transparent); }
|
||||
.dim-accessTable tbody tr:last-child td { border-bottom: 0; }
|
||||
.dim-accessTable tbody tr:focus-within { background: color-mix(in srgb, var(--dsw-alias-bg-module-platform, #f7f8fa) 70%, transparent); }
|
||||
.dim-accessTable[data-kind="admin"] th:nth-child(1), .dim-accessTable[data-kind="admin"] td:nth-child(1) { width: 28%; }
|
||||
.dim-accessTable[data-kind="admin"] th:nth-child(2), .dim-accessTable[data-kind="admin"] td:nth-child(2) { width: 52%; }
|
||||
.dim-accessTable[data-kind="admin"] th:nth-child(3), .dim-accessTable[data-kind="admin"] td:nth-child(3) { width: 20%; }
|
||||
.dim-accessTable[data-kind="member"] th:nth-child(1), .dim-accessTable[data-kind="member"] td:nth-child(1) { width: 20%; }
|
||||
.dim-accessTable[data-kind="member"] th:nth-child(2), .dim-accessTable[data-kind="member"] td:nth-child(2) { width: 36%; }
|
||||
.dim-accessTable[data-kind="member"] th:nth-child(3), .dim-accessTable[data-kind="member"] td:nth-child(3) { width: 28%; }
|
||||
.dim-accessTable[data-kind="member"] th:nth-child(4), .dim-accessTable[data-kind="member"] td:nth-child(4) { width: 16%; }
|
||||
.dim-accessTableNick { min-width: 0; }
|
||||
.dim-accessTableNick .dim-accessNickname { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.dim-accessTablePhone { min-width: 0; position: relative; z-index: 0; }
|
||||
.dim-accessTablePhone:focus-within { z-index: 6; }
|
||||
.dim-accessTablePhone .dim-accessTypeahead > input { height: 32px; }
|
||||
.dim-accessTablePerm { min-width: 0; }
|
||||
.dim-accessTableActions { width: 72px; white-space: nowrap; text-align: right; }
|
||||
.dim-accessTableActions .dim-accessCompactDelete { width: auto; min-width: 52px; }
|
||||
.dim-accessTableEmpty { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; text-align: center; }
|
||||
.dim-accessTableLocked { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; }
|
||||
.dim-accessDeleteUser { margin-bottom: 1px; }
|
||||
.dim-accessUnsupported { padding: 18px 14px; border: 1px dashed var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f7f8fa); text-align: center; }
|
||||
.dim-accessUnsupported strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 13px; line-height: 20px; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue