Отображение списков тегов обновлено

This commit is contained in:
goodmice 2022-12-27 19:04:02 +05:00
parent cbbe992966
commit 1e31f2f2c1
No known key found for this signature in database
GPG Key ID: EA4AA16454AC96C8
6 changed files with 56 additions and 32 deletions

View File

@ -1,7 +1,8 @@
import { memo, ReactNode, useCallback, useEffect, useState } from 'react'
import { DefaultOptionType, SelectValue } from 'antd/lib/select'
import { Select, SelectProps, Tag } from 'antd'
import { Select, SelectProps } from 'antd'
import TagList from '@components/TagList'
import type { OmitExtends } from '@utils/types'
import { ColumnProps, DataType, makeColumn } from '.'
@ -67,7 +68,9 @@ export const makeTagColumn = <T extends DataType>(
return makeColumn(title, dataIndex, {
editable: true,
...other,
render: (item: T[] | undefined, dataset, index) => item?.map((elm: T) => <Tag key={elm[label_key]} color={'blue'}>{other?.render?.(elm, dataset, index) ?? elm[label_key]}</Tag>) ?? '-',
render: (item: T[] | undefined, dataset, index) => (
<TagList items={item} render={(elm) => other?.render?.(elm, dataset, index) ?? elm[label_key]} />
),
input: <InputComponent {...tagOther} options={options} />,
})
}

View File

@ -0,0 +1,25 @@
import { memo, ReactNode } from 'react'
import { Tag } from 'antd'
import '@styles/components/tag_list.less'
export type TagListProps<T> = {
items?: T[] | null
render: (item: T) => ReactNode
}
const _TagList = <T,>({ items, render }: TagListProps<T>) => {
if (!items || items.length <= 0) return <>-</>
return (
<div className={'dd-tag-list'}>
{items.map((item, i) => (
<Tag key={`${i}`}>{render(item)}</Tag>
))}
</div>
)
}
export const TagList = memo(_TagList) as typeof _TagList
export default TagList

View File

@ -1,9 +1,10 @@
import { memo } from 'react'
import { Tag, Tooltip } from 'antd'
import { Tooltip } from 'antd'
import { UserRoleDto } from '@api'
import { Grid, GridItem } from '@components/Grid'
import PermissionView from './PermissionView'
import TagList from '../TagList'
export type RoleViewProps = {
role?: UserRoleDto
@ -26,12 +27,8 @@ export const RoleView = memo<RoleViewProps>(({ role }) => {
<GridItem row={2} col={1}>Включённые роли:</GridItem>
{hasIncludedRoles ? (
<GridItem row={3} col={1} colSpan={3}>
{role.roles?.map((role, i) => (
<Tag key={i} color={'blue'}>
<RoleView role={role} />
</Tag>
))}
<GridItem row={3} col={1} colSpan={3} style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
<TagList items={role.roles} render={(role) => <RoleView role={role} />} />
</GridItem>
) : (
<GridItem row={2} col={2}>Отсутствуют</GridItem>
@ -42,12 +39,8 @@ export const RoleView = memo<RoleViewProps>(({ role }) => {
<GridItem row={4 + hasIncludedRoles} col={1}>Разрешения:</GridItem>
{hasPermissions ? (
<GridItem row={5 + hasIncludedRoles} col={1} colSpan={3}>
{role.permissions?.map((permission, i) => (
<Tag key={i} color={'blue'}>
<PermissionView info={permission} />
</Tag>
))}
<GridItem row={5 + hasIncludedRoles} col={1} colSpan={3} style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
<TagList items={role.permissions} render={(permission) => <PermissionView info={permission} />} />
</GridItem>
) : (
<GridItem row={4 + hasIncludedRoles} col={2}>Отсутствуют</GridItem>

View File

@ -18,15 +18,13 @@ export const TelemetryInfo = memo(({ info, danger, ...other }) => (
bordered
column={1}
size={'small'}
style={{ background: 'white' }}
className={'telemetry_merger_info'}
{...other}
>
{Object.keys({ ...lables, ...info }).map(key => (
<Item
key={key}
label={lables[key] ?? key}
style={{ color: danger === true || danger?.includes(key) ? 'red' : 'black' }}
style={{ color: danger === true || danger?.includes(key) ? 'red' : '#ddd' }}
>{info?.[key] ?? '-'}</Item>
))}
</Descriptions>

View File

@ -1,4 +1,4 @@
import { Button, Input, Tag } from 'antd'
import { Button, Input } from 'antd'
import { UserSwitchOutlined } from '@ant-design/icons'
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
import { BehaviorSubject, debounceTime, distinctUntilChanged, filter, map } from 'rxjs'
@ -20,6 +20,7 @@ import { makeTextOnFilter, makeTextFilters, makeArrayOnFilter } from '@utils/fil
import { arrayOrDefault, withPermissions } from '@utils'
import RoleTag from './RoleTag'
import TagList from '@components/TagList'
const SEARCH_TIMEOUT = 400
@ -107,25 +108,20 @@ const UserController = memo(() => {
const filters = makeTextFilters(users, ['surname', 'name', 'patronymic', 'email'])
const roleFilters = [{ text: 'Без роли', value: null }, ...roles.map((role) => ({ text: role.caption, value: role.caption }))]
const rolesRender = (item) => item?.map((elm) => (
<Tag key={elm} color={'blue'}>
const rolesRender = (item) => (
<TagList
items={item}
render={(elm) => (
<RoleView role={roles.find((role) => role.caption === elm)} />
</Tag>
)) ?? '-'
)}
/>
)
setColumns([
makeTextColumn('Логин', 'login', null, null, null, {
formItemRules: [
{ required: true },
...createLoginRules,
// () => ({
// validator(_, value) {
// if (!value || users.findIndex((user) => user.login === value) < 0)
// return Promise.resolve()
// return Promise.reject(new Error('Логин уже занят!'))
// }
// })
// TODO: Для проверки уникальности логина необходимо исключить из выборки логин выбранного пользователя
],
}),
makeTextColumn('Фамилия', 'surname', filters.surname, null, null, {

View File

@ -0,0 +1,9 @@
.dd-tag-list {
display: flex;
flex-wrap: wrap;
gap: 5px;
& > .ant-tag {
margin-right: 0;
}
}