Fixed No data placeholders for reviewers and related terms (#3359)

* Fixed No data placeholders for reviewers and related terms
This commit is contained in:
darth-coder00 2022-03-10 21:18:12 +05:30 committed by GitHub
parent f03fb1cafa
commit 4d1d25a58b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 146 additions and 85 deletions

View File

@ -29,7 +29,6 @@ import { getTagCategories, getTaglist } from '../../utils/TagsUtils';
import { Button } from '../buttons/Button/Button';
import Avatar from '../common/avatar/Avatar';
import Description from '../common/description/Description';
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
import PopOver from '../common/popover/PopOver';
import TabsPane from '../common/TabsPane/TabsPane';
@ -181,7 +180,7 @@ const GlossaryDetails = ({ isHasAccess, glossary, updateGlossary }: props) => {
}
}, [glossary.reviewers]);
const rightPosButton = () => {
const AddReviewerButton = () => {
return (
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
@ -217,10 +216,10 @@ const GlossaryDetails = ({ isHasAccess, glossary, updateGlossary }: props) => {
))}
</div>
) : (
<ErrorPlaceHolder>
<p className="tw-text-base tw-text-center">No Reviewers.</p>
<p className="tw-text-lg tw-text-center tw-mt-2">{rightPosButton()}</p>
</ErrorPlaceHolder>
<div className="tw-py-3 tw-text-center tw-bg-white tw-border tw-border-main">
<p className="tw-mb-3">No reviewers assigned</p>
<p>{AddReviewerButton()}</p>
</div>
);
};
@ -353,7 +352,7 @@ const GlossaryDetails = ({ isHasAccess, glossary, updateGlossary }: props) => {
glossary.reviewers &&
glossary.reviewers.length > 0 &&
activeTab === 1
? rightPosButton()
? AddReviewerButton()
: undefined
}
setActiveTab={setActiveTabHandler}

View File

@ -13,7 +13,12 @@
import classNames from 'classnames';
import { cloneDeep, includes, isEqual } from 'lodash';
import { EntityTags, FormatedUsersData, GlossaryTermAssets } from 'Models';
import {
EntityTags,
FormatedGlossaryTermData,
FormatedUsersData,
GlossaryTermAssets,
} from 'Models';
import React, { Fragment, useEffect, useState } from 'react';
import {
LIST_SIZE,
@ -29,11 +34,11 @@ import SVGIcons from '../../utils/SvgUtils';
import { getTagCategories, getTaglist } from '../../utils/TagsUtils';
import { Button } from '../buttons/Button/Button';
import Description from '../common/description/Description';
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
import PopOver from '../common/popover/PopOver';
import TabsPane from '../common/TabsPane/TabsPane';
import GlossaryReferenceModal from '../Modals/GlossaryReferenceModal/GlossaryReferenceModal';
import RelatedTermsModal from '../Modals/RelatedTermsModal/RelatedTermsModal';
import ReviewerModal from '../Modals/ReviewerModal/ReviewerModal.component';
import TagsContainer from '../tags-container/tags-container';
import Tags from '../tags/tags';
@ -60,6 +65,7 @@ const GlossaryTermsV1 = ({
const [isDescriptionEditable, setIsDescriptionEditable] = useState(false);
const [activeTab, setActiveTab] = useState(1);
const [showRevieweModal, setShowRevieweModal] = useState(false);
const [showRelatedTermsModal, setShowRelatedTermsModal] = useState(false);
const [isSynonymsEditing, setIsSynonymsEditing] = useState(false);
const [isReferencesEditing, setIsReferencesEditing] = useState(false);
const [synonyms, setSynonyms] = useState(
@ -67,12 +73,9 @@ const GlossaryTermsV1 = ({
);
const [references, setReferences] = useState(glossaryTerm.references || []);
const [reviewer, setReviewer] = useState<Array<FormatedUsersData>>([]);
const [relatedTerms, setRelatedTerms] = useState<
{
relatedTerms: string;
description: string;
}[]
>([]);
const [relatedTerms, setRelatedTerms] = useState<FormatedGlossaryTermData[]>(
[]
);
const tabs = [
{
@ -92,6 +95,32 @@ const GlossaryTermsV1 = ({
},
];
const onRelatedTermsModalCancel = () => {
setShowRelatedTermsModal(false);
};
const handleRelatedTermsSave = (terms: Array<FormatedGlossaryTermData>) => {
if (!isEqual(terms, relatedTerms)) {
let updatedGlossaryTerm = cloneDeep(glossaryTerm);
const oldTerms = terms.filter((d) => includes(relatedTerms, d));
const newTerms = terms
.filter((d) => !includes(relatedTerms, d))
.map((d) => ({
id: d.id,
type: d.type,
displayName: d.displayName,
name: d.name,
}));
updatedGlossaryTerm = {
...updatedGlossaryTerm,
relatedTerms: [...oldTerms, ...newTerms],
};
setRelatedTerms(terms);
handleGlossaryTermUpdate(updatedGlossaryTerm);
}
onRelatedTermsModalCancel();
};
const onReviewerModalCancel = () => {
setShowRevieweModal(false);
};
@ -258,19 +287,12 @@ const GlossaryTermsV1 = ({
}, [glossaryTerm.reviewers]);
useEffect(() => {
if (glossaryTerm.relatedTerms && glossaryTerm.relatedTerms.length) {
setRelatedTerms(
glossaryTerm.relatedTerms.map((term) => {
return {
relatedTerms: (term.displayName || term.name) as string,
description: term.description ?? '',
};
})
);
if (glossaryTerm.relatedTerms?.length) {
setRelatedTerms(glossaryTerm.relatedTerms as FormatedGlossaryTermData[]);
}
}, [glossaryTerm]);
}, [glossaryTerm.relatedTerms]);
const rightPosButton = () => {
const AddReviewerButton = () => {
return (
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
@ -288,6 +310,24 @@ const GlossaryTermsV1 = ({
);
};
const AddRelatedTermButton = () => {
return (
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
className={classNames('tw-h-8 tw-rounded', {
'tw-opacity-40': isHasAccess,
})}
data-testid="add-new-tag-button"
size="small"
theme="primary"
variant="contained"
onClick={() => setShowRelatedTermsModal(true)}>
Add Related Term
</Button>
</NonAdminAction>
);
};
const getReviewerTabData = () => {
return glossaryTerm.reviewers && glossaryTerm.reviewers.length > 0 ? (
<div className="tw-grid xxl:tw-grid-cols-4 lg:tw-grid-cols-3 md:tw-grid-cols-2 tw-gap-4">
@ -306,13 +346,26 @@ const GlossaryTermsV1 = ({
))}
</div>
) : (
<ErrorPlaceHolder>
<p className="tw-text-base tw-text-center">No Reviewers.</p>
<p className="tw-text-lg tw-text-center tw-mt-2">{rightPosButton()}</p>
</ErrorPlaceHolder>
<div className="tw-py-3 tw-text-center tw-bg-white tw-border tw-border-main">
<p className="tw-mb-3">No reviewers assigned</p>
<p>{AddReviewerButton()}</p>
</div>
);
};
const getTabPaneButton = () => {
switch (activeTab) {
case 1: {
return relatedTerms.length ? AddRelatedTermButton() : undefined;
}
case 3: {
return glossaryTerm.reviewers?.length ? AddReviewerButton() : undefined;
}
default:
return;
}
};
return (
<div className="tw-w-full tw-h-full tw-flex tw-flex-col">
<div className="tw-flex tw-gap-5 tw-mb-2">
@ -551,19 +604,18 @@ const GlossaryTermsV1 = ({
<TabsPane
activeTab={activeTab}
className="tw-flex-initial"
rightPosButton={
glossaryTerm.reviewers &&
glossaryTerm.reviewers.length > 0 &&
activeTab === 3
? rightPosButton()
: undefined
}
rightPosButton={getTabPaneButton()}
setActiveTab={activeTabHandler}
tabs={tabs}
/>
<div className="tw-flex-grow tw-py-4">
{activeTab === 1 && <RelationshipTab data={relatedTerms} />}
{activeTab === 1 && (
<RelationshipTab
addButton={<>{AddRelatedTermButton()}</>}
data={relatedTerms}
/>
)}
{activeTab === 2 && (
<AssetsTabs
assetData={assetData}
@ -573,6 +625,14 @@ const GlossaryTermsV1 = ({
{activeTab === 3 && getReviewerTabData()}
</div>
{showRelatedTermsModal && (
<RelatedTermsModal
header="Add Related Terms"
relatedTerms={relatedTerms}
onCancel={onRelatedTermsModalCancel}
onSave={handleRelatedTermsSave}
/>
)}
{showRevieweModal && (
<ReviewerModal
header="Add Reviewer"

View File

@ -12,68 +12,69 @@
*/
import classNames from 'classnames';
import React from 'react';
import ErrorPlaceHolder from '../../common/error-with-placeholder/ErrorPlaceHolder';
import { FormatedGlossaryTermData } from 'Models';
import React, { ReactNode } from 'react';
import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer';
/* eslint-disable max-len */
// need to remove eslint disable once API data comes
type RelationshipTableType = {
relatedTerms: string;
description: string;
};
type Props = {
data?: RelationshipTableType[];
data?: FormatedGlossaryTermData[];
addButton?: ReactNode;
};
const RelationshipTab = ({ data }: Props) => {
return data?.length ? (
const RelationshipTab = ({ data, addButton }: Props) => {
return (
<div className="tw-table-responsive" id="relationship">
<table className="tw-w-full tw-bg-white">
<thead>
<tr className="tableHead-row">
<th className="tableHead-cell">Terms</th>
<th className="tableHead-cell tw-w-2/12">Terms</th>
<th className="tableHead-cell">Description</th>
</tr>
</thead>
<tbody>
{data.map((row, index) => {
return (
<tr className={classNames('tableBody-row')} key={index}>
<td
className={classNames(
'tableBody-cell tw-group tw-relative tw-align-baseline tw-w-2/12'
)}>
{row.relatedTerms}
</td>
<td
className={classNames(
'tableBody-cell tw-group tw-relative tw-align-baseline'
)}>
<div
className="description-text"
data-testid="description-text">
{row.description.trim() ? (
<RichTextEditorPreviewer
enableSeeMoreVariant={false}
markdown={row.description}
/>
) : (
<span className="tw-no-description">No description</span>
)}
</div>
</td>
</tr>
);
})}
{data?.length ? (
data.map((row, index) => {
return (
<tr className={classNames('tableBody-row')} key={index}>
<td
className={classNames(
'tableBody-cell tw-group tw-relative tw-align-baseline'
)}>
{row.displayName || row.name}
</td>
<td
className={classNames(
'tableBody-cell tw-group tw-relative tw-align-baseline'
)}>
<div
className="description-text"
data-testid="description-text">
{row.description?.trim() ? (
<RichTextEditorPreviewer
enableSeeMoreVariant={false}
markdown={row.description}
/>
) : (
<span className="tw-no-description">
No description
</span>
)}
</div>
</td>
</tr>
);
})
) : (
<tr className="tableBody-row">
<td className="tableBody-cell tw-text-center" colSpan={4}>
<p className="tw-mb-3">No related terms available.</p>
{addButton}
</td>
</tr>
)}
</tbody>
</table>
</div>
) : (
<ErrorPlaceHolder>
<p className="tw-text-base tw-text-center">No related terms.</p>
</ErrorPlaceHolder>
);
};

View File

@ -44,7 +44,7 @@ const RelatedTermsModal = ({
>(relatedTerms ?? []);
const getSearchedTerms = (searchedData: FormatedGlossaryTermData[]) => {
const currOptions = selectedOption.map((item) => item.fqdn);
const currOptions = selectedOption.map((item) => item.fqdn || item.name);
const data = searchedData.filter((item: FormatedGlossaryTermData) => {
return !currOptions.includes(item.fqdn);
});

View File

@ -223,6 +223,7 @@ declare module 'Models' {
fqdn: string;
type: string;
id: string;
description?: string;
};
export interface FormatedGlossarySuggestion {