chore(ui): UI improvements (#10331)

* chore(ui): UI improvements

* fix table css which was causing cypress issue

* fix cypress issue

* remove required from alerts filters
This commit is contained in:
Ashish Gupta 2023-02-28 13:15:51 +05:30 committed by GitHub
parent 2b4bf736af
commit c1c185321c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 90 additions and 111 deletions

View File

@ -991,6 +991,7 @@ describe('Glossary page should work properly', () => {
it('Delete glossary should work properly', () => { it('Delete glossary should work properly', () => {
[NEW_GLOSSARY.name, NEW_GLOSSARY_1.name].forEach((glossary) => { [NEW_GLOSSARY.name, NEW_GLOSSARY_1.name].forEach((glossary) => {
verifyResponseStatusCode('@fetchGlossaries', 200); verifyResponseStatusCode('@fetchGlossaries', 200);
cy.wait(200);
cy.get('[data-testid="header"]') cy.get('[data-testid="header"]')
.should('be.visible') .should('be.visible')
.contains(glossary) .contains(glossary)

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="442" fill="none"><path fill="#7147E8" d="M481.508 175.336 68.414 3.926C51.011-3.296 31.35-.119 17.105 12.213 2.86 24.547-3.098 43.551 1.558 61.808L38.328 206h180.025c8.284 0 15.001 6.716 15.001 15.001 0 8.284-6.716 15.001-15.001 15.001H38.327L1.558 380.193c-4.656 18.258 1.301 37.262 15.547 49.595 14.274 12.357 33.937 15.495 51.31 8.287L481.51 266.666C500.317 258.862 512 241.364 512 221.001s-11.683-37.862-30.492-45.665Z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 442" fill="none"><path fill="#7147E8" d="M481.508 175.336 68.414 3.926C51.011-3.296 31.35-.119 17.105 12.213 2.86 24.547-3.098 43.551 1.558 61.808L38.328 206h180.025c8.284 0 15.001 6.716 15.001 15.001 0 8.284-6.716 15.001-15.001 15.001H38.327L1.558 380.193c-4.656 18.258 1.301 37.262 15.547 49.595 14.274 12.357 33.937 15.495 51.31 8.287L481.51 266.666C500.317 258.862 512 241.364 512 221.001s-11.683-37.862-30.492-45.665Z"/></svg>

Before

Width:  |  Height:  |  Size: 491 B

After

Width:  |  Height:  |  Size: 488 B

View File

@ -11,13 +11,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { Popover } from 'antd'; import { Button } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { FC, Fragment } from 'react'; import React, { FC } from 'react';
import { useTranslation } from 'react-i18next';
import { Transi18next } from '../../../utils/CommonUtils'; import { ReactComponent as IconPaperPlanePrimary } from '../../../assets/svg/paper-plane-primary.svg';
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
import { Button } from '../../buttons/Button/Button';
interface SendButtonProp { interface SendButtonProp {
editorValue: string; editorValue: string;
@ -25,58 +23,22 @@ interface SendButtonProp {
onSaveHandler: () => void; onSaveHandler: () => void;
} }
const getIcon = (editorValue: string) => {
return editorValue.length > 0 ? Icons.PAPER_PLANE_PRIMARY : Icons.PAPER_PLANE;
};
export const SendButton: FC<SendButtonProp> = ({ export const SendButton: FC<SendButtonProp> = ({
editorValue, editorValue,
buttonClass, buttonClass,
onSaveHandler, onSaveHandler,
}) => { }) => (
const { t } = useTranslation(); <div
className="tw-absolute tw-right-2 tw-bottom-2 tw-flex tw-flex-row tw-items-center tw-justify-end"
return ( onClick={(e) => e.stopPropagation()}>
<div <Button
className="tw-absolute tw-right-2 tw-bottom-2 tw-flex tw-flex-row tw-items-center tw-justify-end" className={classNames('p-0', buttonClass)}
onClick={(e) => e.stopPropagation()}> data-testid="send-button"
<Popover disabled={editorValue.length === 0}
content={ size="small"
<Fragment> type="text"
<strong>{t('label.send-now')}</strong> onClick={onSaveHandler}>
<p> <IconPaperPlanePrimary height={18} width={18} />
{t('label.press')} </Button>
<Transi18next </div>
i18nKey="message.tour-step-discover-all-assets-at-one-place" );
renderElement={
<kbd className="tw-bg-white tw-text-grey-body tw-rounded-sm tw-px-1 tw-py-0.5" />
}
values={{
text: t('label.return'),
}}
/>
</p>
</Fragment>
}
placement="top"
trigger="hover">
<Button
className={classNames(
'tw-py-0.5 tw-px-1 tw-rounded tw-bg-none',
buttonClass
)}
data-testid="send-button"
disabled={editorValue.length === 0}
size="custom"
variant="text"
onClick={onSaveHandler}>
<SVGIcons
alt="paper-plane"
icon={getIcon(editorValue)}
width="18px"
/>
</Button>
</Popover>
</div>
);
};

View File

@ -11,8 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { EllipsisOutlined } from '@ant-design/icons'; import { Button, Col, Dropdown, Row, Tooltip, Typography } from 'antd';
import { Col, Dropdown, Row, Tooltip, Typography } from 'antd';
import { ReactComponent as ExportIcon } from 'assets/svg/ic-export.svg'; import { ReactComponent as ExportIcon } from 'assets/svg/ic-export.svg';
import { ReactComponent as ImportIcon } from 'assets/svg/ic-import.svg'; import { ReactComponent as ImportIcon } from 'assets/svg/ic-import.svg';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
@ -20,6 +19,7 @@ import { isEmpty } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useHistory, useParams } from 'react-router-dom'; import { useHistory, useParams } from 'react-router-dom';
import { ReactComponent as IconDropdown } from '../../assets/svg/menu.svg';
import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants'; import { FQN_SEPARATOR_CHAR } from '../../constants/char.constants';
import { NO_PERMISSION_FOR_ACTION } from '../../constants/HelperTextUtil'; import { NO_PERMISSION_FOR_ACTION } from '../../constants/HelperTextUtil';
import { Glossary } from '../../generated/entity/data/glossary'; import { Glossary } from '../../generated/entity/data/glossary';
@ -33,7 +33,7 @@ import {
} from '../../utils/RouterUtils'; } from '../../utils/RouterUtils';
import SVGIcons, { Icons } from '../../utils/SvgUtils'; import SVGIcons, { Icons } from '../../utils/SvgUtils';
import { showErrorToast } from '../../utils/ToastUtils'; import { showErrorToast } from '../../utils/ToastUtils';
import { Button } from '../buttons/Button/Button'; import '../common/entityPageInfo/ManageButton/ManageButton.less';
import TitleBreadcrumb from '../common/title-breadcrumb/title-breadcrumb.component'; import TitleBreadcrumb from '../common/title-breadcrumb/title-breadcrumb.component';
import { TitleBreadcrumbProps } from '../common/title-breadcrumb/title-breadcrumb.interface'; import { TitleBreadcrumbProps } from '../common/title-breadcrumb/title-breadcrumb.interface';
import GlossaryDetails from '../GlossaryDetails/GlossaryDetails.component'; import GlossaryDetails from '../GlossaryDetails/GlossaryDetails.component';
@ -107,6 +107,11 @@ const GlossaryV1 = ({
[action] [action]
); );
const isGlossaryDeletePermission = useMemo(
() => glossaryPermission.Delete || glossaryTermPermission.Delete,
[glossaryPermission, glossaryTermPermission]
);
const fetchGlossaryPermission = async () => { const fetchGlossaryPermission = async () => {
try { try {
const response = await getEntityPermission( const response = await getEntityPermission(
@ -322,8 +327,9 @@ const GlossaryV1 = ({
trigger={['click']} trigger={['click']}
onOpenChange={setShowActions}> onOpenChange={setShowActions}>
<Tooltip <Tooltip
placement="right"
title={ title={
glossaryPermission.Delete || glossaryTermPermission.Delete isGlossaryDeletePermission
? isGlossaryActive ? isGlossaryActive
? t('label.manage-entity', { entity: t('label.glossary') }) ? t('label.manage-entity', { entity: t('label.glossary') })
: t('label.manage-entity', { : t('label.manage-entity', {
@ -332,18 +338,12 @@ const GlossaryV1 = ({
: NO_PERMISSION_FOR_ACTION : NO_PERMISSION_FOR_ACTION
}> }>
<Button <Button
className="tw-rounded tw-justify-center tw-w-8 tw-h-8 glossary-manage-button tw-flex" className="manage-dropdown-button"
data-testid="manage-button" data-testid="manage-button"
disabled={ disabled={!isGlossaryDeletePermission}
!(glossaryPermission.Delete || glossaryTermPermission.Delete)
}
size="small" size="small"
theme="primary"
variant="outlined"
onClick={() => setShowActions(true)}> onClick={() => setShowActions(true)}>
<span> <IconDropdown className="anticon text-primary self-center manage-dropdown-icon" />
<EllipsisOutlined rotate={90} />
</span>
</Button> </Button>
</Tooltip> </Tooltip>
</Dropdown> </Dropdown>

View File

@ -40,11 +40,6 @@
margin-right: 0.3rem; margin-right: 0.3rem;
} }
.glossary-manage-button {
border: none;
background-color: @manage-dropdown-bg-primary;
}
.manage-button { .manage-button {
.ant-space-item:first-child { .ant-space-item:first-child {
width: 40px; width: 40px;

View File

@ -437,7 +437,7 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
: t('message.no-permission-for-action') : t('message.no-permission-for-action')
}> }>
<Button <Button
className="rounded-4 tw-w-8 d-flex justify-center manage-dropdown-button" className="manage-dropdown-button"
data-testid="profiler-setting-btn" data-testid="profiler-setting-btn"
disabled={!editTest} disabled={!editTest}
type="primary" type="primary"

View File

@ -1086,7 +1086,7 @@ const TeamDetailsV1 = ({
trigger={['click']} trigger={['click']}
onOpenChange={setShowActions}> onOpenChange={setShowActions}>
<Button <Button
className="rounded-4 w-6 manage-dropdown-button d-flex justify-center" className="manage-dropdown-button"
data-testid="teams-dropdown" data-testid="teams-dropdown"
icon={ icon={
<IconDropdown className="text-primary self-center manage-dropdown-icon" /> <IconDropdown className="text-primary self-center manage-dropdown-icon" />

View File

@ -18,27 +18,27 @@ import { Combination, ToDisplay } from './CronEditor.interface';
export const getPeriodOptions = () => { export const getPeriodOptions = () => {
return [ return [
{ {
label: i18n.t('label.none-lowercase'), label: i18n.t('label.none'),
value: '', value: '',
prep: '', prep: '',
}, },
{ {
label: i18n.t('label.minute-plural-lowercase'), label: i18n.t('label.minute-plural'),
value: 'minute', value: 'minute',
prep: '', prep: '',
}, },
{ {
label: i18n.t('label.hour-lowercase'), label: i18n.t('label.hour'),
value: 'hour', value: 'hour',
prep: 'at', prep: 'at',
}, },
{ {
label: i18n.t('label.day-lowercase'), label: i18n.t('label.day'),
value: 'day', value: 'day',
prep: 'at', prep: 'at',
}, },
{ {
label: i18n.t('label.week-lowercase'), label: i18n.t('label.week'),
value: 'week', value: 'week',
prep: 'on', prep: 'on',
} /* , } /* ,

View File

@ -26,14 +26,24 @@
border: none; border: none;
background-color: @manage-dropdown-bg-primary; background-color: @manage-dropdown-bg-primary;
padding: 0; padding: 0;
border-radius: 4px;
width: 24px;
display: flex;
justify-content: center;
.ant-btn { .ant-btn {
padding: 0 8px 0 8px; padding: 0 4px;
} }
} }
.manage-dropdown-button:hover, .manage-dropdown-button:hover,
.manage-dropdown-button:focus { .manage-dropdown-button:focus {
.ant-btn {
.manage-dropdown-icon {
color: @manage-button-bg-primary;
opacity: 0.5;
}
}
.manage-dropdown-icon { .manage-dropdown-icon {
color: @white; color: @white;
font-weight: 600; font-weight: 600;

View File

@ -533,3 +533,9 @@ export const ENTITY_PATH: Record<string, string> = {
pipelines: 'pipeline', pipelines: 'pipeline',
mlmodels: 'mlmodel', mlmodels: 'mlmodel',
}; };
export const VALIDATE_MESSAGES = {
required: t('message.field-text-is-required', {
fieldText: '${label}',
}),
};

View File

@ -192,7 +192,6 @@
"date-filter": "Date Filter", "date-filter": "Date Filter",
"day": "Day", "day": "Day",
"day-left": "{{day}} left", "day-left": "{{day}} left",
"day-lowercase": "day",
"days-change-lowercase": "{{days}}-days change", "days-change-lowercase": "{{days}}-days change",
"dbt-bucket-name": "dbt Bucket Name", "dbt-bucket-name": "dbt Bucket Name",
"dbt-catalog-file-path": "dbt Catalog File Path", "dbt-catalog-file-path": "dbt Catalog File Path",
@ -360,7 +359,7 @@
"here-lowercase": "here", "here-lowercase": "here",
"hide": "Hide", "hide": "Hide",
"home": "Home", "home": "Home",
"hour-lowercase": "hour", "hour": "Hour",
"http-config-source": "HTTP Config Source", "http-config-source": "HTTP Config Source",
"hyper-parameter-plural": "Hyper Parameters", "hyper-parameter-plural": "Hyper Parameters",
"idle": "Idle", "idle": "Idle",
@ -455,7 +454,6 @@
"minor": "Minor", "minor": "Minor",
"minute-lowercase": "minute", "minute-lowercase": "minute",
"minute-plural": "Minutes", "minute-plural": "Minutes",
"minute-plural-lowercase": "minutes",
"ml-model": "ML Model", "ml-model": "ML Model",
"ml-model-plural": "ML Models", "ml-model-plural": "ML Models",
"mode": "Mode", "mode": "Mode",
@ -488,7 +486,7 @@
"no-parameter-available": "No Parameter Available", "no-parameter-available": "No Parameter Available",
"no-reviewer": "No reviewer", "no-reviewer": "No reviewer",
"no-tags-added": "No Tags added", "no-tags-added": "No Tags added",
"none-lowercase": "none", "none": "None",
"not-found-lowercase": "not found", "not-found-lowercase": "not found",
"not-null": "Not Null", "not-null": "Not Null",
"not-used": "Not Used", "not-used": "Not Used",
@ -842,7 +840,7 @@
"webhook": "Webhook", "webhook": "Webhook",
"webhook-display-text": "Webhook {{displayText}}", "webhook-display-text": "Webhook {{displayText}}",
"wednesday": "Wednesday", "wednesday": "Wednesday",
"week-lowercase": "week", "week": "Week",
"welcome-to-open-metadata": "Welcome to OpenMetadata!", "welcome-to-open-metadata": "Welcome to OpenMetadata!",
"whats-new": "What's New", "whats-new": "What's New",
"yes": "Yes", "yes": "Yes",

View File

@ -29,6 +29,7 @@ import {
import { useForm } from 'antd/lib/form/Form'; import { useForm } from 'antd/lib/form/Form';
import { DefaultOptionType } from 'antd/lib/select'; import { DefaultOptionType } from 'antd/lib/select';
import { AsyncSelect } from 'components/AsyncSelect/AsyncSelect'; import { AsyncSelect } from 'components/AsyncSelect/AsyncSelect';
import { VALIDATE_MESSAGES } from 'constants/constants';
import { get, intersection, isEmpty, map, pick, startCase, trim } from 'lodash'; import { get, intersection, isEmpty, map, pick, startCase, trim } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -534,9 +535,9 @@ const AddAlertPage = () => {
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
<Col span={24}> <Col span={24}>
<Typography.Title level={5}> <Typography.Title level={5}>
{!isEmpty(fqn) {t(!isEmpty(fqn) ? 'label.edit-entity' : 'label.create-entity', {
? t('label.edit-entity', { entity: t('label.alert-plural') }) entity: t('label.alert-plural'),
: t('label.create-entity', { entity: t('label.alert-plural') })} })}
</Typography.Title> </Typography.Title>
<Typography.Text>{t('message.alerts-description')}</Typography.Text> <Typography.Text>{t('message.alerts-description')}</Typography.Text>
</Col> </Col>
@ -544,6 +545,7 @@ const AddAlertPage = () => {
<Form<Alerts> <Form<Alerts>
className="alerts-notification-form" className="alerts-notification-form"
form={form} form={form}
validateMessages={VALIDATE_MESSAGES}
onFinish={handleSave} onFinish={handleSave}
onValuesChange={handleChange}> onValuesChange={handleChange}>
<Card loading={loadingCount > 0}> <Card loading={loadingCount > 0}>
@ -557,8 +559,7 @@ const AddAlertPage = () => {
<Form.Item <Form.Item
label={t('label.description')} label={t('label.description')}
labelCol={{ span: 24 }} labelCol={{ span: 24 }}
name="description" name="description">
rules={[{ required: true }]}>
<Input.TextArea /> <Input.TextArea />
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
@ -615,16 +616,8 @@ const AddAlertPage = () => {
subHeading={t('message.alerts-filter-description')} subHeading={t('message.alerts-filter-description')}
/> />
<Form.List <Form.List name="filteringRules">
name="filteringRules" {(fields, { add, remove }) => (
rules={[
{
validator: listLengthValidator(
t('label.filter-plural')
),
},
]}>
{(fields, { add, remove }, { errors }) => (
<> <>
<Form.Item> <Form.Item>
<Button <Button
@ -695,7 +688,6 @@ const AddAlertPage = () => {
</div> </div>
</div> </div>
))} ))}
<Form.ErrorList errors={errors} />
</> </>
)} )}
</Form.List> </Form.List>

View File

@ -10,12 +10,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Col, Row, Table, Tooltip } from 'antd'; import { Button, Col, Row, Table, Tooltip, Typography } from 'antd';
import DeleteWidgetModal from 'components/common/DeleteWidget/DeleteWidgetModal'; import DeleteWidgetModal from 'components/common/DeleteWidget/DeleteWidgetModal';
import NextPrevious from 'components/common/next-previous/NextPrevious'; import NextPrevious from 'components/common/next-previous/NextPrevious';
import PageHeader from 'components/header/PageHeader.component'; import PageHeader from 'components/header/PageHeader.component';
import Loader from 'components/Loader/Loader'; import Loader from 'components/Loader/Loader';
import { isNil } from 'lodash'; import { isEmpty, isNil } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -97,6 +97,8 @@ const AlertsPage = () => {
dataIndex: 'description', dataIndex: 'description',
flex: true, flex: true,
key: 'description', key: 'description',
render: (text: string) =>
!isEmpty(text) ? <Typography.Text>{text}</Typography.Text> : '--',
}, },
{ {
title: t('label.action-plural'), title: t('label.action-plural'),

View File

@ -21,8 +21,6 @@
} }
.ant-table-bordered { .ant-table-bordered {
table { table {
border: 1px solid #dde3ea;
tbody { tbody {
tr { tr {
td { td {
@ -52,8 +50,23 @@
} }
} }
} }
.ant-table-container > .ant-table-content > table > tbody > tr > td { .ant-table-container {
border-right: none; border: 1px solid @border-gray-color;
border-radius: 4px;
overflow: hidden;
.ant-table-content > table {
border-top: none;
tbody > tr {
td {
border-right: none;
}
&:last-child td {
border-bottom: none;
}
}
}
} }
} }
} }