mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2026-01-07 21:16:45 +00:00
UI: Revamp Manage Tab UI (#4380)
This commit is contained in:
parent
d84e2c2a8d
commit
b5b42e1ca9
@ -670,6 +670,7 @@ const DashboardDetails = ({
|
||||
entityName={dashboardDetails.name}
|
||||
entityType={EntityType.DASHBOARD}
|
||||
hasEditAccess={hasEditAccess()}
|
||||
manageSectionType={EntityType.DASHBOARD}
|
||||
onSave={onSettingsUpdate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -741,6 +741,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
||||
entityName={tableDetails.name}
|
||||
entityType={EntityType.TABLE}
|
||||
hasEditAccess={hasEditAccess()}
|
||||
manageSectionType={EntityType.TABLE}
|
||||
onSave={onSettingsUpdate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -26,8 +26,8 @@ import { useAuth } from '../../hooks/authHooks';
|
||||
import jsonData from '../../jsons/en';
|
||||
import { getOwnerList } from '../../utils/ManageUtils';
|
||||
import { showErrorToast } from '../../utils/ToastUtils';
|
||||
import CardListItem from '../card-list/CardListItem/CardWithListItems';
|
||||
import { CardWithListItems } from '../card-list/CardListItem/CardWithListItems.interface';
|
||||
import CardListItem from '../cardlist/CardListItem/CardWithListItem';
|
||||
import { CardWithListItems } from '../cardlist/CardListItem/CardWithListItem.interface';
|
||||
import DeleteWidget from '../common/DeleteWidget/DeleteWidget';
|
||||
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
|
||||
import OwnerWidget from '../common/OwnerWidget/OwnerWidget';
|
||||
@ -167,37 +167,48 @@ const ManageTab: FunctionComponent<ManageProps> = ({
|
||||
};
|
||||
|
||||
const getTierCards = () => {
|
||||
if (!hideTier) {
|
||||
return isLoadingTierData ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<div className="tw-flex tw-flex-col" data-testid="cards">
|
||||
{tierData.map((card, i) => (
|
||||
<NonAdminAction
|
||||
html={
|
||||
<Fragment>
|
||||
<p>You need to be owner to perform this action</p>
|
||||
<p>Claim ownership from above </p>
|
||||
</Fragment>
|
||||
}
|
||||
isOwner={hasEditAccess || Boolean(owner && !currentUser)}
|
||||
key={i}
|
||||
permission={Operation.UpdateTags}
|
||||
position="left">
|
||||
<CardListItem
|
||||
card={card}
|
||||
isActive={activeTier === card.id}
|
||||
isSelected={card.id === currentTier}
|
||||
tierStatus={statusTier}
|
||||
onSave={handleTierSave}
|
||||
onSelect={handleCardSelection}
|
||||
/>
|
||||
</NonAdminAction>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="tw-flex tw-flex-col tw-mb-7" data-testid="cards">
|
||||
{tierData.map((card, i) => (
|
||||
<NonAdminAction
|
||||
html={
|
||||
<Fragment>
|
||||
<p>You need to be owner to perform this action</p>
|
||||
<p>Claim ownership from above </p>
|
||||
</Fragment>
|
||||
}
|
||||
isOwner={hasEditAccess || Boolean(owner && !currentUser)}
|
||||
key={i}
|
||||
permission={Operation.UpdateTags}
|
||||
position="left">
|
||||
<CardListItem
|
||||
card={card}
|
||||
className={classNames(
|
||||
'tw-mb-0 tw-shadow',
|
||||
{
|
||||
'tw-rounded-t-md': i === 0,
|
||||
},
|
||||
{
|
||||
'tw-rounded-b-md ': i === tierData.length - 1,
|
||||
}
|
||||
)}
|
||||
isActive={activeTier === card.id}
|
||||
isSelected={card.id === currentTier}
|
||||
tierStatus={statusTier}
|
||||
onCardSelect={handleCardSelection}
|
||||
onSave={handleTierSave}
|
||||
/>
|
||||
</NonAdminAction>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getTierWidget = () => {
|
||||
if (hideTier) {
|
||||
return null;
|
||||
} else {
|
||||
return isLoadingTierData ? <Loader /> : getTierCards();
|
||||
}
|
||||
};
|
||||
|
||||
@ -291,12 +302,12 @@ const ManageTab: FunctionComponent<ManageProps> = ({
|
||||
className="tw-max-w-3xl tw-mx-auto"
|
||||
data-testid="manage-tab"
|
||||
id="manageTabDetails">
|
||||
<p className="tw-text-base tw-font-medium">
|
||||
<p className="tw-text-base tw-font-medium tw-mt-2">
|
||||
Manage {manageSectionType ? manageSectionType : 'Section'}
|
||||
</p>
|
||||
<div
|
||||
className={classNames('tw-mt-2 tw-pb-4', {
|
||||
'tw-border-b tw-border-separator tw-mb-4': !hideTier,
|
||||
'tw-mb-3': !hideTier,
|
||||
})}>
|
||||
<OwnerWidget
|
||||
allowTeamOwner={allowTeamOwner}
|
||||
@ -316,7 +327,7 @@ const ManageTab: FunctionComponent<ManageProps> = ({
|
||||
teamJoinable={teamJoinable}
|
||||
/>
|
||||
</div>
|
||||
{getTierCards()}
|
||||
{getTierWidget()}
|
||||
{getDeleteEntityWidget()}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -68,7 +68,7 @@ const mockTierData = {
|
||||
|
||||
const mockFunction = jest.fn().mockImplementation(() => Promise.resolve());
|
||||
|
||||
jest.mock('../card-list/CardListItem/CardWithListItems', () => {
|
||||
jest.mock('../cardlist/CardListItem/CardWithListItem', () => {
|
||||
return jest.fn().mockReturnValue(<p data-testid="card">CardWithListItems</p>);
|
||||
});
|
||||
|
||||
|
||||
@ -601,6 +601,7 @@ const PipelineDetails = ({
|
||||
entityName={pipelineDetails.name}
|
||||
entityType={EntityType.PIPELINE}
|
||||
hasEditAccess={hasEditAccess()}
|
||||
manageSectionType={EntityType.PIPELINE}
|
||||
onSave={onSettingsUpdate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -440,6 +440,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
|
||||
entityName={topicDetails.name}
|
||||
entityType={EntityType.TOPIC}
|
||||
hasEditAccess={hasEditAccess()}
|
||||
manageSectionType={EntityType.TOPIC}
|
||||
onSave={onSettingsUpdate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HTMLAttributes } from 'react';
|
||||
import { Status } from '../../ManageTab/ManageTab.interface';
|
||||
|
||||
export type CardWithListItems = {
|
||||
@ -20,11 +21,11 @@ export type CardWithListItems = {
|
||||
title: string;
|
||||
};
|
||||
|
||||
export type Props = {
|
||||
export interface Props extends HTMLAttributes<HTMLDivElement> {
|
||||
card: CardWithListItems;
|
||||
isActive: boolean;
|
||||
isSelected: boolean;
|
||||
tierStatus: Status;
|
||||
onSave: (updatedTier: string) => void;
|
||||
onSelect: (cardId: string) => void;
|
||||
};
|
||||
onCardSelect: (cardId: string) => void;
|
||||
}
|
||||
@ -12,15 +12,15 @@
|
||||
*/
|
||||
|
||||
export const cardStyle = {
|
||||
base: 'tw-flex tw-flex-col tw-rounded-md tw-border tw-mb-4',
|
||||
default: 'tw-border-main',
|
||||
active: 'tw-border-primary-lite',
|
||||
base: 'tw-flex tw-flex-col tw-border tw-bg-white',
|
||||
default: 'tw-border-main tw-border-b-0',
|
||||
active: 'tw-border-primary',
|
||||
selected: 'tw-border-primary',
|
||||
header: {
|
||||
base: 'tw-flex tw-px-5 tw-py-3 tw-cursor-pointer tw-justify-between tw-items-center',
|
||||
default: 'tw-bg-badge',
|
||||
active: 'tw-bg-primary-lite tw-rounded-t-md',
|
||||
selected: 'tw-bg-primary tw-rounded-t-md tw-text-white',
|
||||
default: '',
|
||||
active: 'tw-bg-primary-lite tw-border-b tw-border-primary',
|
||||
selected: 'tw-bg-primary tw-text-white',
|
||||
title: 'tw-text-base tw-mb-0',
|
||||
description: 'tw-font-medium tw-pr-2',
|
||||
},
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import CardListItem from './CardWithListItems';
|
||||
import CardListItem from './CardWithListItem';
|
||||
|
||||
const mockSelectFunction = jest.fn();
|
||||
const mockSaveFuntion = jest.fn();
|
||||
@ -36,8 +36,8 @@ describe('Test CardWithListing Component', () => {
|
||||
isActive={false}
|
||||
isSelected={false}
|
||||
tierStatus="initial"
|
||||
onCardSelect={mockSelectFunction}
|
||||
onSave={mockSaveFuntion}
|
||||
onSelect={mockSelectFunction}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -55,8 +55,8 @@ describe('Test CardWithListing Component', () => {
|
||||
isActive={false}
|
||||
isSelected={false}
|
||||
tierStatus="initial"
|
||||
onCardSelect={mockSelectFunction}
|
||||
onSave={mockSaveFuntion}
|
||||
onSelect={mockSelectFunction}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -79,8 +79,8 @@ describe('Test CardWithListing Component', () => {
|
||||
card={mockCard}
|
||||
isSelected={false}
|
||||
tierStatus="initial"
|
||||
onCardSelect={mockSelectFunction}
|
||||
onSave={mockSaveFuntion}
|
||||
onSelect={mockSelectFunction}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -107,8 +107,8 @@ describe('Test CardWithListing Component', () => {
|
||||
card={mockCard}
|
||||
isSelected={false}
|
||||
tierStatus="initial"
|
||||
onCardSelect={mockSelectFunction}
|
||||
onSave={mockSaveFuntion}
|
||||
onSelect={mockSelectFunction}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -17,52 +17,58 @@ import React, { FunctionComponent } from 'react';
|
||||
import { Button } from '../../buttons/Button/Button';
|
||||
import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer';
|
||||
import Loader from '../../Loader/Loader';
|
||||
import { Props } from './CardWithListItems.interface';
|
||||
import { cardStyle } from './CardWithListItems.style';
|
||||
import { Props } from './CardWithListItem.interface';
|
||||
import { cardStyle } from './CardWithListItem.style';
|
||||
|
||||
const CardListItem: FunctionComponent<Props> = ({
|
||||
card,
|
||||
isActive,
|
||||
isSelected,
|
||||
onSelect,
|
||||
onCardSelect,
|
||||
onSave,
|
||||
tierStatus,
|
||||
className,
|
||||
}: Props) => {
|
||||
const getCardBodyStyle = () => {
|
||||
return isSelected
|
||||
? cardStyle.selected
|
||||
: isActive
|
||||
? cardStyle.active
|
||||
: cardStyle.default;
|
||||
const activeStyle = isActive ? cardStyle.active : cardStyle.default;
|
||||
|
||||
return isSelected ? cardStyle.selected : activeStyle;
|
||||
};
|
||||
|
||||
const getCardHeaderStyle = () => {
|
||||
return isSelected
|
||||
? cardStyle.header.selected
|
||||
: isActive
|
||||
const activeHeaderStyle = isActive
|
||||
? cardStyle.header.active
|
||||
: cardStyle.header.default;
|
||||
|
||||
return isSelected ? cardStyle.header.selected : activeHeaderStyle;
|
||||
};
|
||||
|
||||
const getTierSelectButton = (tier: string) => {
|
||||
return tierStatus === 'waiting' ? (
|
||||
<Loader
|
||||
className="tw-inline-block"
|
||||
size="small"
|
||||
style={{ marginBottom: '-4px' }}
|
||||
type="default"
|
||||
/>
|
||||
) : tierStatus === 'success' ? (
|
||||
<FontAwesomeIcon icon="check" />
|
||||
) : (
|
||||
<Button
|
||||
data-testid="select-tier-buuton"
|
||||
size="small"
|
||||
theme="primary"
|
||||
onClick={() => onSave(tier)}>
|
||||
Select
|
||||
</Button>
|
||||
);
|
||||
switch (tierStatus) {
|
||||
case 'waiting':
|
||||
return (
|
||||
<Loader
|
||||
className="tw-inline-block"
|
||||
size="small"
|
||||
style={{ marginBottom: '-4px' }}
|
||||
type="default"
|
||||
/>
|
||||
);
|
||||
|
||||
case 'success':
|
||||
return <FontAwesomeIcon icon="check" />;
|
||||
|
||||
default:
|
||||
return (
|
||||
<Button
|
||||
data-testid="select-tier-buuton"
|
||||
size="small"
|
||||
theme="primary"
|
||||
onClick={() => onSave(tier)}>
|
||||
Select
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getCardIcon = (cardId: string) => {
|
||||
@ -77,11 +83,15 @@ const CardListItem: FunctionComponent<Props> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const handleCardSelect = () => {
|
||||
onCardSelect(card.id);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(cardStyle.base, getCardBodyStyle())}
|
||||
className={classNames(cardStyle.base, getCardBodyStyle(), className)}
|
||||
data-testid="card-list"
|
||||
onClick={() => onSelect(card.id)}>
|
||||
onClick={handleCardSelect}>
|
||||
<div className={classNames(cardStyle.header.base, getCardHeaderStyle())}>
|
||||
<div className="tw-flex">
|
||||
<div className="tw-self-start tw-mr-2">
|
||||
@ -693,6 +693,7 @@ const DatabaseSchemaPage: FunctionComponent = () => {
|
||||
databaseSchema?.owner?.type || '',
|
||||
databaseSchema?.owner?.id || ''
|
||||
)}
|
||||
manageSectionType={EntityType.DATABASE_SCHEMA}
|
||||
onSave={handleUpdateOwner}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -802,6 +802,7 @@ const DatabaseDetails: FunctionComponent = () => {
|
||||
database?.owner?.type || '',
|
||||
database?.owner?.id || ''
|
||||
)}
|
||||
manageSectionType={EntityType.DATABASE}
|
||||
onSave={handleUpdateOwner}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -1000,6 +1000,7 @@ const ServicePage: FunctionComponent = () => {
|
||||
serviceDetails?.owner?.type || '',
|
||||
serviceDetails?.owner?.id || ''
|
||||
)}
|
||||
manageSectionType={serviceCategory.slice(0, -1)}
|
||||
onSave={handleUpdateOwner}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user