Skip to content

Commit

Permalink
feat(Navigation/NavigationError): add copy button and impove error de…
Browse files Browse the repository at this point in the history
…tails [YTFRONT-4049]
  • Loading branch information
KostyaAvtushko committed Feb 4, 2025
1 parent 93722c7 commit 4a500f0
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 8 deletions.
4 changes: 4 additions & 0 deletions packages/ui/src/ui/components/ErrorDetails/ErrorDetails.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {ClipboardButton} from '@gravity-ui/uikit';
import Link from '../../components/Link/Link';
import block from 'bem-cn-lite';
import ypath from '../../common/thor/ypath';
Expand Down Expand Up @@ -107,13 +108,16 @@ export default class ErrorDetails extends Component {
}

renderTabs() {
const {error} = this.props;
const {currentTab} = this.state;

const items = this.prepareTabs();
const text = unipika.formatFromYSON(error.attributes, {asHTML: false});

return (
<div className={b('tabs')}>
<Tabs onTabChange={this.changeCurrentTab} active={currentTab} items={items} />
<ClipboardButton title='Copy error' view='flat-secondary' size='s' text={text}/>
</div>
);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/ui/components/ErrorDetails/ErrorDetails.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
}

&__tabs {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;

span {
color: var(--g-color-text-complementary);
font-weight: 700;
Expand Down
11 changes: 8 additions & 3 deletions packages/ui/src/ui/pages/navigation/Navigation/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {StickyContainer} from 'react-sticky';
import {connect, useSelector} from 'react-redux';
import PropTypes from 'prop-types';
import hammer from '../../../common/hammer';
import unipika from '../../../common/thor/unipika';
import cn from 'bem-cn-lite';

import map_ from 'lodash/map';
Expand All @@ -22,13 +23,15 @@ import ContentViewer from './ContentViewer/ContentViewer';
import {checkContentIsSupported} from './ContentViewer/helpers';
import Tabs from '../../../components/Tabs/Tabs';
import {NavigationError} from './NavigationError';
import { getNavigationPathAttributes } from '../../../store/selectors/navigation/navigation';

import {Tab} from '../../../constants/navigation';
import {LOADING_STATUS} from '../../../constants/index';

import {onTransactionChange, setMode, updateView} from '../../../store/actions/navigation';

import {
getAttributes,
getError,
getIdmSupport,
getLoadState,
Expand Down Expand Up @@ -247,15 +250,15 @@ class Navigation extends Component {
cluster,
path,
} = this.props;

console.log(message, details)
return (
<NavigationError cluster={cluster} path={path} details={details} message={message} />
);
}

render() {
const {loaded, hasError} = this.props;

const {attributes, loaded, hasError, pathAttributes} = this.props;
console.log(attributes, pathAttributes, "hello")
return (
<ErrorBoundary>
<div className={block({error: hasError}, 'elements-main-section')}>
Expand Down Expand Up @@ -286,6 +289,8 @@ function mapStateToProps(state) {
const hasError = loadState === LOADING_STATUS.ERROR;
const loaded = loadState === LOADING_STATUS.LOADED;
return {
attributes: getAttributes(state),
pathAttributes: getNavigationPathAttributes(state),
path: getPath(state),
mode: getEffectiveMode(state),
type: getType(state),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React from 'react';
import cn from 'bem-cn-lite';
import {Flex, Text} from '@gravity-ui/uikit';
import {ClipboardButton, Flex, Text} from '@gravity-ui/uikit';

import Error from '../../../../components/Error/Error';
import {NavigationErrorImage} from './NavigationErrorImage';
import ErrorDetails from '../../../../components/ErrorDetails/ErrorDetails';
import {RequestPermission} from './RequestPermission';
import {getPermissionDeniedError} from '../../../../utils/errors';
import {YTError} from '../../../../../@types/types';
import {getErrorTitle, getLeadingErrorCode} from './helpers';
import {getErrorTitle, getLeadingErrorCode, formatForCopy} from './helpers';

import './NavigationError.scss';

Expand All @@ -26,8 +26,8 @@ function PrettyError(props: Props) {

const code = getLeadingErrorCode(details);
const error = code == 901 ? getPermissionDeniedError(details)! : details;

const title = getErrorTitle(error, path);
const errorInfo = formatForCopy(details);

return (
<Flex className={block()} justifyContent="center" alignItems="center" gap={7}>
Expand All @@ -37,7 +37,16 @@ function PrettyError(props: Props) {
<Flex direction="column" className={block('info')} gap={4}>
<Text className={block('title')}>{title}</Text>
<ErrorDetails error={details} />
{code === 901 && <RequestPermission cluster={cluster} path={path} error={error} />}
<Flex direction="row" gap={3}>
{code === 901 && <RequestPermission cluster={cluster} path={path} error={error} />}
<ClipboardButton
className={block('copy')}
view="outlined"
text={errorInfo}
>
Copy error details
</ClipboardButton>
</Flex>
</Flex>
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
@import '../NavigationError.scss';

.request-permission {
&__request-permissions-button {
--_--height: auto;
width: fit-content;

padding: 5px 12px;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import unipika from '../../../../../common/thor/unipika';

import {getYtErrorCode} from '../../../../../utils/errors';
import {YTError} from '../../../../../../@types/types';
import {UnipikaValue} from '../../../../../components/Yson/StructuredYson/StructuredYsonTypes';
Expand Down Expand Up @@ -85,3 +87,36 @@ export function getLeadingErrorCode(error: YTError): ErrorCode | undefined {

return;
}

export function formatForCopy(error: YTError) {
const formatSettings = {asHTML: false};
let res = '';

const errorTraversal = (e: YTError) => {
if (e.message) {
// replace needed to truncate extra \
// for situations like: Access denied for user \"username\": \"role\"
res += `${unipika.formatFromYSON(e.message, formatSettings)}`.replace(/\\"/g, '"');
}

if (e.code) {
res += `[${unipika.formatFromYSON(e.code, formatSettings)}]`
}

res += '\n'

if (e.attributes) {
res += `${unipika.formatFromYSON(e.attributes, formatSettings)}\n`;
}

if (e.inner_errors) {
for (let err of e.inner_errors) {
errorTraversal(err);
}
}
}

errorTraversal(error);

return res;
}

0 comments on commit 4a500f0

Please sign in to comment.