Skip to content

Commit

Permalink
feat(Acl): improve view (#955)
Browse files Browse the repository at this point in the history
  • Loading branch information
Raubzeug authored Jul 3, 2024
1 parent 6fbd52c commit 46aff45
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 92 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@bem-react/classname": "^1.6.0",
"@gravity-ui/axios-wrapper": "^1.4.1",
"@gravity-ui/chartkit": "^5.5.0",
"@gravity-ui/components": "^3.6.2",
"@gravity-ui/components": "^3.7.0",
"@gravity-ui/date-utils": "^2.4.0",
"@gravity-ui/i18n": "^1.5.0",
"@gravity-ui/icons": "^2.9.1",
Expand Down
23 changes: 14 additions & 9 deletions src/containers/Tenant/Acl/Acl.scss
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
@import '../../../styles/mixins.scss';

.ydb-acl {
&__result {
align-self: flex-start;
}

width: 100%;
&__owner-container {
position: sticky;
z-index: 2;
top: 0;

padding-bottom: 25px;
}
&__result {
padding-bottom: 16px;
}

background-color: var(--g-color-base-background);
&__owner {
font-weight: 600;
}
&__definition-content {
display: flex;
flex-direction: column;
}
&__group-label {
@include subheader-2-typography();
}
}
192 changes: 116 additions & 76 deletions src/containers/Tenant/Acl/Acl.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
import React from 'react';

import type {Column} from '@gravity-ui/react-data-table';
import type {DefinitionListItem} from '@gravity-ui/components';
import {DefinitionList} from '@gravity-ui/components';
//TODO: fix import
import type {DefinitionListSingleItem} from '@gravity-ui/components/build/esm/components/DefinitionList/types';

import {ResponseError} from '../../../components/Errors/ResponseError';
import {Loader} from '../../../components/Loader';
import {ResizeableDataTable} from '../../../components/ResizeableDataTable/ResizeableDataTable';
import {schemaAclApi} from '../../../store/reducers/schemaAcl/schemaAcl';
import type {TACE} from '../../../types/api/acl';
import {cn} from '../../../utils/cn';
import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
import i18n from '../i18n';

import './Acl.scss';

const b = cn('ydb-acl');

const ACL_COLUMNS_WIDTH_LS_KEY = 'aclTableColumnsWidth';

const TABLE_SETTINGS = {
...DEFAULT_TABLE_SETTINGS,
dynamicRender: false,
stickyTop: 36,
};

const prepareLogin = (value: string | undefined) => {
if (value && value.endsWith('@staff') && !value.startsWith('svc_')) {
const login = value.split('@')[0];
Expand All @@ -32,76 +25,117 @@ const prepareLogin = (value: string | undefined) => {
return value;
};

const columns: Column<TACE>[] = [
{
name: 'AccessType',
header: 'Access Type',
sortable: false,
render: ({row}) => row.AccessType,
},
{
name: 'AccessRights',
header: 'Access Rights',
render: ({row}) => {
return row.AccessRights?.map((item, index) => {
return <div key={index}>{item}</div>;
});
},
sortable: false,
},
{
name: 'Subject',
sortable: false,
render: ({row}) => {
return prepareLogin(row.Subject);
},
width: 140,
},
{
name: 'InheritanceType',
header: 'Inheritance Type',
render: ({row}) => {
return row.InheritanceType?.map((item, index) => {
return <div key={index}>{item}</div>;
});
const aclParams = ['access', 'type', 'inheritance'] as const;

type AclParameter = (typeof aclParams)[number];

const aclParamToName: Record<AclParameter, string> = {
access: 'Access',
type: 'Access type',
inheritance: 'Inheritance type',
};

const defaultInheritanceType = ['Object', 'Container'];
const defaultAccessType = 'Allow';

const defaultInheritanceTypeSet = new Set(defaultInheritanceType);

function normalizeAcl(acl: TACE[]) {
return acl.map((ace) => {
const {AccessRules = [], AccessRights = [], AccessType, InheritanceType, Subject} = ace;
const access = AccessRules.concat(AccessRights);
//"Allow" is default access type. We want to show it only if it isn't default
const type = AccessType === defaultAccessType ? undefined : AccessType;
let inheritance;
// ['Object', 'Container'] - is default inheritance type. We want to show it only if it isn't default
if (
InheritanceType?.length !== defaultInheritanceTypeSet.size ||
InheritanceType.some((t) => !defaultInheritanceTypeSet.has(t))
) {
inheritance = InheritanceType;
}
return {
access: access.length ? access : undefined,
type,
inheritance,
Subject,
};
});
}

interface DefinitionValueProps {
value: string | string[];
}

function DefinitionValue({value}: DefinitionValueProps) {
const normalizedValue = typeof value === 'string' ? [value] : value;
return (
<div className={b('definition-content')}>
{normalizedValue.map((el) => (
<span key={el}>{el}</span>
))}
</div>
);
}

function getAclListItems(acl?: TACE[]): DefinitionListItem[] {
if (!acl || !acl.length) {
return [];
}

const normalizedAcl = normalizeAcl(acl);

return normalizedAcl.map(({Subject, ...data}) => {
const definedDataEntries = Object.entries(data).filter(([_key, value]) =>
Boolean(value),
) as [AclParameter, string | string[]][];

if (definedDataEntries.length === 1 && definedDataEntries[0][0] === 'access') {
return {
name: Subject,
content: <DefinitionValue value={definedDataEntries[0][1]} />,
};
}
return {
label: <span className={b('group-label')}>{Subject}</span>,
items: aclParams
.map((key) => {
const value = data[key];
if (value) {
return {
name: aclParamToName[key],
content: <DefinitionValue value={value} />,
};
}
return undefined;
})
.filter(Boolean) as DefinitionListSingleItem[],
};
});
}

function getOwnerItem(owner?: string) {
const preparedOwner = prepareLogin(owner);
if (!preparedOwner) {
return [];
}
return [
{
name: <span className={b('owner')}>{preparedOwner}</span>,
content: <span className={b('owner')}>{i18n('acl.owner')}</span>,
},
sortable: false,
},
];
] as DefinitionListItem[];
}

export const Acl = ({path}: {path: string}) => {
const {currentData, isFetching, error} = schemaAclApi.useGetSchemaAclQuery({path});

const loading = isFetching && !currentData;
const {acl, owner} = currentData || {};

const renderTable = () => {
if (!acl || !acl.length) {
return null;
}

return (
<ResizeableDataTable
columnsWidthLSKey={ACL_COLUMNS_WIDTH_LS_KEY}
columns={columns}
data={acl}
settings={TABLE_SETTINGS}
/>
);
};

const renderOwner = () => {
if (!owner) {
return null;
}
const aclListItems = getAclListItems(acl);

return (
<div className={b('owner-container')}>
<span className={b('owner-label')}>{`${i18n('acl.owner')}: `}</span>
{prepareLogin(owner)}
</div>
);
};
const ownerItem = getOwnerItem(owner);

if (loading) {
return <Loader />;
Expand All @@ -117,10 +151,16 @@ export const Acl = ({path}: {path: string}) => {

return (
<div className={b()}>
<div className={b('result')}>
{renderOwner()}
{renderTable()}
</div>
{ownerItem.length ? (
<DefinitionList
items={ownerItem}
nameMaxWidth={200}
className={b('owner-container')}
/>
) : null}
{aclListItems.length ? (
<DefinitionList items={aclListItems} nameMaxWidth={200} className={b('result')} />
) : null}
</div>
);
};
1 change: 1 addition & 0 deletions src/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
this.getPath('/viewer/json/acl'),
{
path,
merge_rules: true,
},
{concurrentId: concurrentId || `getSchemaAcl`, requestConfig: {signal}},
);
Expand Down
5 changes: 5 additions & 0 deletions src/styles/mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
line-height: var(--g-text-subheader-3-line-height);
}

@mixin subheader-2-typography() {
font-size: var(--g-text-subheader-2-font-size);
line-height: var(--g-text-subheader-2-line-height);
}

@mixin header-1-typography() {
font-size: var(--g-text-header-1-font-size);
line-height: var(--g-text-header-1-line-height);
Expand Down
2 changes: 1 addition & 1 deletion src/styles/themes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

.g-root {
--g-text-header-font-weight: 500;
--g-text-subheader-font-weight: 500;
--g-text-subheader-font-weight: 600;
--g-text-display-font-weight: 500;
--g-text-accent-font-weight: 500;

Expand Down
3 changes: 2 additions & 1 deletion src/types/api/acl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export interface TMetaCommonInfo {
export interface TACE {
AccessType: string;
AccessRights?: string[];
AccessRules?: string[];
Subject: string;
InheritanceType?: string[];
AccessRule: string;
AccessRule?: string;
}

0 comments on commit 46aff45

Please sign in to comment.