fix: glossary route path for add term (#11000)

* fix: glossary route path for add term

* fix: jest test

* fix: improvements on glossary screen

* fix: glossary comments

* fix: update cypress

* fix: cypress tests

* fix: update cypress tests

* fix: update icon

* fix: tag styles

---------

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
karanh37 2023-04-12 16:42:04 +05:30 committed by GitHub
parent 1b930fa6f7
commit 51bf8cd754
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 524 additions and 626 deletions

View File

@ -244,11 +244,13 @@ export const NEW_GLOSSARY_TERMS = {
name: 'Purchase',
description: 'This is the Purchase',
synonyms: 'buy,collect,acquire',
fullyQualifiedName: 'Business Glossary.Purchase',
},
term_2: {
name: 'Sales',
description: 'This is the Sales',
synonyms: 'give,disposal,deal',
fullyQualifiedName: 'Business Glossary.Sales',
},
};
export const GLOSSARY_TERM_WITH_DETAILS = {
@ -259,6 +261,7 @@ export const GLOSSARY_TERM_WITH_DETAILS = {
relatedTerms: 'Sales',
reviewer: 'Colin Ho',
inheritedReviewer: 'Aaron Johnson',
fullyQualifiedName: 'Business Glossary.Accounts',
};
export const NEW_GLOSSARY_1_TERMS = {
@ -266,11 +269,13 @@ export const NEW_GLOSSARY_1_TERMS = {
name: 'Features',
description: 'This is the Features',
synonyms: 'data,collect,time',
fullyQualifiedName: 'Product Glossary.Features',
},
term_2: {
name: 'Uses',
description: 'This is the Uses',
synonyms: 'home,business,adventure',
fullyQualifiedName: 'Product Glossary.Uses',
},
};

View File

@ -21,7 +21,6 @@ import {
} from '../../common/common';
import {
DELETE_TERM,
GLOSSARY_TERM_WITH_DETAILS,
NEW_GLOSSARY,
NEW_GLOSSARY_1,
NEW_GLOSSARY_1_TERMS,
@ -29,19 +28,19 @@ import {
SEARCH_ENTITY_TABLE,
} from '../../constants/constants';
const visitGlossaryTermPage = (termName) => {
cy.get(`[data-row-key="${termName}"]`)
const visitGlossaryTermPage = (termName, fqn) => {
cy.get(`[data-row-key="${fqn}"]`)
.scrollIntoView()
.should('be.visible')
.contains(termName)
.should('be.visible')
.click();
cy.get('.ant-tabs [id*=tab-summary]').should('be.visible').click();
cy.get('.ant-tabs .glossary-overview-tab').should('be.visible').click();
verifyResponseStatusCode('@getGlossaryTerms', 200);
};
const checkDisplayName = (displayName) => {
cy.get('[data-testid="glossary-display-name"]')
cy.get('[data-testid="entity-header-display-name"]')
.scrollIntoView()
.should('exist')
.and('be.visible')
@ -76,7 +75,7 @@ const fillGlossaryTermDetails = (term, glossary, isMutually = false) => {
.should('be.visible')
.click();
}
cy.get('[data-testid="references"] > .ant-space-item > .button-comp')
cy.get('[data-testid="add-reference"]')
.scrollIntoView()
.should('be.visible')
.click();
@ -97,17 +96,15 @@ const createGlossaryTerm = (term, glossary, isMutually = false) => {
.should('be.visible')
.click();
cy.get(`[data-row-key="${term.name}"]`)
cy.get(`[data-row-key="${glossary.name}.${term.name}"]`)
.scrollIntoView()
.should('be.visible')
.contains(term.name)
.should('be.visible');
};
const deleteGlossaryTerm = ({ name }) => {
visitGlossaryTermPage(name);
cy.get('[data-testid="inactive-link"]').contains(name).should('be.visible');
const deleteGlossaryTerm = ({ name, fullyQualifiedName }) => {
visitGlossaryTermPage(name, fullyQualifiedName);
cy.get('[data-testid="manage-button"]').should('be.visible').click();
cy.get('[data-testid="delete-button"]')
@ -140,15 +137,18 @@ const deleteGlossaryTerm = ({ name }) => {
.should('not.contain', name);
};
const goToAssetsTab = (term) => {
visitGlossaryTermPage(term);
const goToAssetsTab = (name, fqn) => {
visitGlossaryTermPage(name, fqn);
cy.get('[data-testid="inactive-link"]').contains(term).should('be.visible');
cy.get('[data-testid="assets"]').should('be.visible').click();
cy.get('.ant-tabs-tab-active').contains('Assets').should('be.visible');
};
describe.skip('Glossary page should work properly', () => {
const selectActiveGlossary = (glossaryName) => {
cy.get('.ant-menu-item').contains(glossaryName).should('be.visible').click();
};
describe('Glossary page should work properly', () => {
beforeEach(() => {
cy.login();
@ -200,13 +200,6 @@ describe.skip('Glossary page should work properly', () => {
.click();
interceptURL('GET', '/api/v1/tags?limit=1000', 'fetchTags');
interceptURL(
'GET',
`/api/v1/search/query?q=*${encodeURI(
NEW_GLOSSARY.reviewer
)}*&from=0&size=15&index=user_search_index`,
'getReviewer'
);
cy.get('[data-testid="tags-container"] .ant-select-selection-overflow')
.scrollIntoView()
.should('be.visible')
@ -223,7 +216,6 @@ describe.skip('Glossary page should work properly', () => {
cy.get('[data-testid="searchbar"]')
.should('be.visible')
.type(NEW_GLOSSARY.reviewer);
verifyResponseStatusCode('@getReviewer', 200);
cy.get(`[title="${NEW_GLOSSARY.reviewer}"]`)
.scrollIntoView()
.should('be.visible')
@ -313,38 +305,42 @@ describe.skip('Glossary page should work properly', () => {
});
it('Verify and Remove Tags from Glossary', () => {
selectActiveGlossary(NEW_GLOSSARY.name);
// Verify Tags which is added at the time of creating glossary
cy.get('[data-testid="tags-card-container"]')
cy.get('[data-testid="tag-container"]')
.contains('Personal')
.should('be.visible');
cy.wait(5000);
// Remove Tag
cy.get('[data-testid="tags-wrapper"] [data-testid="add-tag"]')
.should('be.visible')
cy.get('[data-testid="tags-input-container"] [data-testid="edit-button"]')
.should('exist')
.and('be.visible')
.click();
cy.get('.ant-select-selection-item-remove').should('be.visible').click();
interceptURL('PATCH', '/api/v1/glossaries/*', 'updateGlossary');
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
verifyResponseStatusCode('@updateGlossary', 200);
cy.get('[data-testid="tags-wrapper"]')
.contains('Tags')
.should('be.visible');
cy.get('[data-testid="add-tag"]').should('be.visible');
});
it('Verify added glossary details', () => {
cy.get('[data-testid="glossary-left-panel"]')
.contains(NEW_GLOSSARY.name)
.should('be.visible');
selectActiveGlossary(NEW_GLOSSARY.name);
cy.wait(2000);
checkDisplayName(NEW_GLOSSARY.name);
cy.get('[data-testid="viewer-container"]')
.invoke('text')
.then((text) => {
expect(text).to.contain(NEW_GLOSSARY.description);
});
cy.get('[data-testid="reviewer-card-container"]').should('be.visible');
cy.get(`[data-testid="user-tag"]`)
cy.get(`[data-testid="glossary-reviewer-name"]`)
.invoke('text')
.then((text) => {
expect(text).to.contain(NEW_GLOSSARY.reviewer);
@ -360,6 +356,9 @@ describe.skip('Glossary page should work properly', () => {
.contains(NEW_GLOSSARY_1.name)
.should('be.visible');
selectActiveGlossary(NEW_GLOSSARY_1.name);
cy.wait(2000);
checkDisplayName(NEW_GLOSSARY_1.name);
cy.get('[data-testid="viewer-container"]')
.invoke('text')
@ -368,33 +367,27 @@ describe.skip('Glossary page should work properly', () => {
});
});
it.skip('Create glossary term should work properly', () => {
it('Create glossary term should work properly', () => {
const terms = Object.values(NEW_GLOSSARY_TERMS);
selectActiveGlossary(NEW_GLOSSARY.name);
terms.forEach((term) => createGlossaryTerm(term, NEW_GLOSSARY, true));
// Glossary term for Product glossary
cy.log('One finished');
cy.get('.ant-menu-item')
.contains(NEW_GLOSSARY_1.name)
.should('be.visible')
.click();
selectActiveGlossary(NEW_GLOSSARY_1.name);
const ProductTerms = Object.values(NEW_GLOSSARY_1_TERMS);
ProductTerms.forEach((term) => createGlossaryTerm(term, NEW_GLOSSARY_1));
});
it.skip('Updating data of glossary should work properly', () => {
it('Updating data of glossary should work properly', () => {
selectActiveGlossary(NEW_GLOSSARY.name);
const newDescription = 'Updated description';
// updating tags
cy.get('[data-testid="tag-container"]')
cy.get('[data-testid="tags-input-container"] [data-testid="add-tag"]')
.should('exist')
.and('be.visible')
.within(() => {
cy.get('[data-testid="add-tag"]')
.should('exist')
.and('be.visible')
.click();
});
.click();
cy.get('[data-testid="tag-selector"]')
.scrollIntoView()
@ -431,8 +424,10 @@ describe.skip('Glossary page should work properly', () => {
.should('be.visible');
});
it.skip('Update glossary term synonyms', () => {
it('Update glossary term synonyms', () => {
selectActiveGlossary(NEW_GLOSSARY.name);
const uSynonyms = ['pick up', 'take', 'obtain'];
const { name, fullyQualifiedName } = NEW_GLOSSARY_TERMS.term_1;
interceptURL(
'GET',
`/api/v1/glossaryTerms/name/*.${NEW_GLOSSARY_TERMS.term_1.name}?fields=*`,
@ -443,33 +438,38 @@ describe.skip('Glossary page should work properly', () => {
'/api/v1/permissions/glossaryTerm/*',
'waitForTermPermission'
);
visitGlossaryTermPage(NEW_GLOSSARY_TERMS.term_1.name);
visitGlossaryTermPage(name, fullyQualifiedName);
verifyResponseStatusCode('@getGlossaryTerm', 200);
verifyResponseStatusCode('@waitForTermPermission', 200);
// updating synonyms
cy.get('[data-testid="section-synonyms"]')
cy.get('[data-testid="synonyms-container"]')
.scrollIntoView()
.should('be.visible');
cy.wait(200);
cy.get('[data-testid="section-synonyms"]')
cy.get('[data-testid="synonyms-container"]')
.find('[data-testid="edit-button"]')
.scrollIntoView()
.should('be.visible')
.click();
cy.get('.ant-select-selector').should('be.visible');
cy.get('.ant-select-clear > .anticon > svg')
cy.get('[data-testid="synonyms-container"] .ant-select-selector').should(
'be.visible'
);
cy.get(
'[data-testid="synonyms-container"] .ant-select-selection-item-remove'
)
.should('exist')
.click({ force: true });
.click({ force: true, multiple: true });
cy.get('.ant-select-selection-overflow')
.should('exist')
.type(uSynonyms.join('{enter}'));
interceptURL('PATCH', '/api/v1/glossaryTerms/*', 'saveSynonyms');
cy.get('[data-testid="save-btn"]').should('be.visible').click();
cy.get('[data-testid="save-synonym-btn"]').should('be.visible').click();
verifyResponseStatusCode('@saveSynonyms', 200);
cy.get('[data-testid="synonyms-container"]')
@ -481,13 +481,15 @@ describe.skip('Glossary page should work properly', () => {
});
});
it.skip('Update glossary term reference and related terms', () => {
it('Update glossary term reference', () => {
selectActiveGlossary(NEW_GLOSSARY.name);
const newRef = { name: 'take', url: 'https://take.com' };
const term2 = NEW_GLOSSARY_TERMS.term_2.name;
const { name, fullyQualifiedName } = NEW_GLOSSARY_TERMS.term_1;
// Navigate to glossary term
interceptURL(
'GET',
`/api/v1/glossaryTerms/name/*.${NEW_GLOSSARY_TERMS.term_1.name}?fields=*`,
`/api/v1/glossaryTerms/name/*.${name}?fields=*`,
'getGlossaryTerm'
);
interceptURL(
@ -495,17 +497,19 @@ describe.skip('Glossary page should work properly', () => {
'/api/v1/permissions/glossaryTerm/*',
'waitForTermPermission'
);
visitGlossaryTermPage(NEW_GLOSSARY_TERMS.term_1.name);
visitGlossaryTermPage(name, fullyQualifiedName);
verifyResponseStatusCode('@getGlossaryTerm', 200);
verifyResponseStatusCode('@waitForTermPermission', 200);
cy.get('[data-testid="section-references"]').should('be.visible');
cy.get('[data-testid="section-References"]').should('be.visible');
cy.wait(200);
// updating References
cy.get('[data-testid="section-references"]')
cy.get('[data-testid="section-References"]')
.find('[data-testid="edit-button"]')
.should('exist')
.click();
cy.get('[data-testid="add-button"]').should('be.visible').click();
cy.get('[data-testid="add-references-button"]')
.should('be.visible')
.click();
cy.get('#references_1_name').should('be.visible').type(newRef.name);
cy.get('#references_1_endpoint').should('be.visible').type(newRef.url);
interceptURL('PATCH', '/api/v1/glossaryTerms/*', 'saveGlossaryTermData');
@ -516,12 +520,33 @@ describe.skip('Glossary page should work properly', () => {
.should('be.visible')
.invoke('attr', 'href')
.should('eq', newRef.url);
});
// add relented term
cy.get('[data-testid="section-related-terms"]')
it('Update glossary related terms', () => {
selectActiveGlossary(NEW_GLOSSARY.name);
const term2 = NEW_GLOSSARY_TERMS.term_2.name;
const { name, fullyQualifiedName } = NEW_GLOSSARY_TERMS.term_1;
interceptURL('PATCH', '/api/v1/glossaryTerms/*', 'saveGlossaryTermData');
// Navigate to glossary term
interceptURL(
'GET',
`/api/v1/glossaryTerms/name/*.${name}?fields=*`,
'getGlossaryTerm'
);
interceptURL(
'GET',
'/api/v1/permissions/glossaryTerm/*',
'waitForTermPermission'
);
visitGlossaryTermPage(name, fullyQualifiedName);
verifyResponseStatusCode('@getGlossaryTerm', 200);
verifyResponseStatusCode('@waitForTermPermission', 200);
// add related term
cy.get('[data-testid="related-term-container"]')
.scrollIntoView()
.should('be.visible');
cy.get('[data-testid="section-related-terms"] [data-testid="edit-button"]')
cy.get('[data-testid="related-term-add-button"]')
.scrollIntoView()
.should('be.visible')
.click({ force: true });
@ -537,7 +562,9 @@ describe.skip('Glossary page should work properly', () => {
.should('be.visible')
.click();
cy.get('[data-testid="save-btn"]').should('be.visible').click();
cy.get('[data-testid="save-related-term-btn"]')
.should('be.visible')
.click();
verifyResponseStatusCode('@saveGlossaryTermData', 200);
cy.get('[data-testid="related-term-container"]')
@ -545,17 +572,19 @@ describe.skip('Glossary page should work properly', () => {
.should('be.visible');
});
it.skip('Updating description and tags of glossary term should work properly', () => {
it('Updating description and tags of glossary term should work properly', () => {
selectActiveGlossary(NEW_GLOSSARY.name);
interceptURL('GET', '/api/v1/permissions/*/*', 'permissionApi');
interceptURL('GET', '/api/v1/search/query?*', 'glossaryAPI');
const term = NEW_GLOSSARY_TERMS.term_1.name;
const newDescription = 'Updated description';
visitGlossaryTermPage(term);
const { name, fullyQualifiedName } = NEW_GLOSSARY_TERMS.term_1;
visitGlossaryTermPage(name, fullyQualifiedName);
verifyResponseStatusCode('@permissionApi', 200);
verifyResponseStatusCode('@glossaryAPI', 200);
// updating tags
cy.get('[data-testid="tag-container"]')
cy.get('[data-testid="tag-container"] [data-testid="add-tag"]')
.scrollIntoView()
.should('be.visible')
.click();
@ -591,11 +620,10 @@ describe.skip('Glossary page should work properly', () => {
cy.get('[data-testid="viewer-container"]')
.contains(newDescription)
.should('be.visible');
cy.get('[data-testid="inactive-link"]').contains(term).should('be.visible');
});
it.skip('Assets Tab should work properly', () => {
it('Assets Tab should work properly', () => {
selectActiveGlossary(NEW_GLOSSARY.name);
const glossary = NEW_GLOSSARY.name;
const term1 = NEW_GLOSSARY_TERMS.term_1.name;
const term2 = NEW_GLOSSARY_TERMS.term_2.name;
@ -611,9 +639,13 @@ describe.skip('Glossary page should work properly', () => {
.should('be.visible')
.click();
goToAssetsTab(term3);
cy.contains('No assets available.').should('be.visible');
cy.get('[data-testid="no-data-image"]').should('be.visible');
goToAssetsTab(
NEW_GLOSSARY_1_TERMS.term_1.name,
NEW_GLOSSARY_1_TERMS.term_1.fullyQualifiedName
);
cy.contains('Adding a new Asset is easy, just give it a spin!').should(
'be.visible'
);
visitEntityDetailsPage(entity.term, entity.serviceName, entity.entity);
// Add tag to breadcrumb
@ -733,176 +765,26 @@ describe.skip('Glossary page should work properly', () => {
.contains(NEW_GLOSSARY_1.name)
.should('be.visible')
.click();
goToAssetsTab(term3);
goToAssetsTab(
NEW_GLOSSARY_1_TERMS.term_1.name,
NEW_GLOSSARY_1_TERMS.term_1.fullyQualifiedName
);
cy.get(`[data-testid="${entity.serviceName}-${entity.term}"]`)
.contains(entity.term)
.should('be.visible');
});
it.skip('Create glossaryTerm with tags, related terms, synonyms, references and reviewer & verify API payload', () => {
interceptURL(
'GET',
'/api/v1/search/query?q=*&from=0&size=10&index=glossary_search_index',
'searchGlossaryTerm'
);
interceptURL('GET', '/api/v1/users/*?fields=profile', 'getProfile');
fillGlossaryTermDetails(GLOSSARY_TERM_WITH_DETAILS, NEW_GLOSSARY);
// Add Tags
interceptURL('GET', '/api/v1/tags?limit=1000', 'fetchTags');
cy.get('[data-testid="tags-container"] .ant-select-selection-overflow')
.scrollIntoView()
.should('be.visible')
.type(GLOSSARY_TERM_WITH_DETAILS.tag);
verifyResponseStatusCode('@fetchTags', 200);
cy.get(`[title="${GLOSSARY_TERM_WITH_DETAILS.tag}"]`)
.should('be.visible')
.click();
cy.get('#right-panel').click();
// Add Related terms
cy.get('[data-testid="add-related-terms"]')
.scrollIntoView()
.should('be.visible')
.click();
cy.get('.ant-modal-body').should('be.visible');
cy.get('[data-testid="searchbar"]')
.should('be.visible')
.type(GLOSSARY_TERM_WITH_DETAILS.relatedTerms);
cy.get('[data-testid="searchbar"]').should(
'have.value',
GLOSSARY_TERM_WITH_DETAILS.relatedTerms
);
verifyResponseStatusCode('@searchGlossaryTerm', 200);
cy.get('[data-testid="user-card-container"]')
.contains(GLOSSARY_TERM_WITH_DETAILS.relatedTerms)
.parents('[data-testid="user-card-container"]')
.find('[data-testid="checkboxAddUser"]')
.should('be.visible')
.click();
// cy.get('').should('be.visible').click();
cy.get('[data-testid="saveButton"]').should('be.visible').click();
cy.get('.ant-modal-body').should('not.exist');
interceptURL(
'GET',
`/api/v1/search/query?q=*${encodeURI(
GLOSSARY_TERM_WITH_DETAILS.reviewer
)}*&from=0&size=15&index=user_search_index`,
'searchReviewer'
);
// Add reviewer
cy.get('[data-testid="add-reviewers"]')
.scrollIntoView()
.should('be.visible')
.click();
// cy.get('.ant-modal-body').should('be.visible');
cy.get('[data-testid="searchbar"]')
.should('be.visible')
.type(GLOSSARY_TERM_WITH_DETAILS.reviewer);
verifyResponseStatusCode('@searchReviewer', 200);
cy.get(`[title="${GLOSSARY_TERM_WITH_DETAILS.reviewer}"]`)
.scrollIntoView()
.should('be.visible')
.click();
cy.get('[data-testid="selectable-list-update-btn"]')
.should('be.visible')
.click();
interceptURL('POST', '/api/v1/glossaryTerms', 'createGlossaryTerms');
cy.get('[data-testid="save-glossary-term"]')
.scrollIntoView()
.should('be.visible')
.click();
cy.wait('@createGlossaryTerms').then(({ request }) => {
const synonym = GLOSSARY_TERM_WITH_DETAILS.synonyms.split(',');
expect(request.body).to.have.all.keys(
'description',
'displayName',
'mutuallyExclusive',
'name',
'glossary',
'references',
'relatedTerms',
'reviewers',
'tags',
'synonyms'
);
expect(request.body.displayName).equals(GLOSSARY_TERM_WITH_DETAILS.name);
expect(request.body.name).equals(GLOSSARY_TERM_WITH_DETAILS.name);
expect(request.body.description).equals(
GLOSSARY_TERM_WITH_DETAILS.description
);
expect(request.body.mutuallyExclusive).equals(false);
expect(request.body.glossary).equals(NEW_GLOSSARY.name);
expect(request.body.reviewers).has.length(2);
expect(request.body.references).has.length(1);
expect(request.body.references[0]).to.have.all.keys('name', 'endpoint');
expect(request.body.synonyms).has.length(synonym.length);
expect(request.body.synonyms).to.deep.equal(synonym);
expect(request.body.tags).has.length(1);
expect(request.body.tags[0]).to.deep.equal({
labelType: 'Manual',
state: 'Confirmed',
tagFQN: 'PersonalData.Personal',
source: 'Classification',
});
});
});
it.skip('Verify details of created glossaryTerm', () => {
interceptURL(
'GET',
`/api/v1/glossaryTerms/name/*.${GLOSSARY_TERM_WITH_DETAILS.name}?fields=*`,
'getGlossaryTerm'
);
interceptURL(
'GET',
'/api/v1/permissions/glossaryTerm/*',
'waitForTermPermission'
);
visitGlossaryTermPage(GLOSSARY_TERM_WITH_DETAILS.name);
verifyResponseStatusCode('@getGlossaryTerm', 200);
verifyResponseStatusCode('@waitForTermPermission', 200);
cy.get('[data-testid="glossary-term"] > :nth-child(1)')
.scrollIntoView()
.as('glossaryTermDetailsPanel');
cy.get('@glossaryTermDetailsPanel').contains('admin').should('be.visible');
cy.get('[data-testid="user-tag"]')
.contains(GLOSSARY_TERM_WITH_DETAILS.reviewer)
.should('be.visible');
cy.get('@glossaryTermDetailsPanel')
.find(`[data-testid="user-tag"]`)
.contains(GLOSSARY_TERM_WITH_DETAILS.inheritedReviewer)
.should('be.visible');
cy.get('[data-testid="add-tag"]')
.contains(GLOSSARY_TERM_WITH_DETAILS.tag)
.should('be.visible');
});
it.skip('Remove Glossary term from entity should work properly', () => {
it('Remove Glossary term from entity should work properly', () => {
const glossaryName = NEW_GLOSSARY_1.name;
const term = NEW_GLOSSARY_1_TERMS.term_1.name;
const { name, fullyQualifiedName } = NEW_GLOSSARY_1_TERMS.term_1;
const entity = SEARCH_ENTITY_TABLE.table_3;
cy.get('.ant-menu-item')
.contains(NEW_GLOSSARY_1.name)
.should('be.visible')
.click();
selectActiveGlossary(NEW_GLOSSARY_1.name);
interceptURL('GET', '/api/v1/search/query*', 'assetTab');
// go assets tab
goToAssetsTab(term);
goToAssetsTab(name, fullyQualifiedName);
verifyResponseStatusCode('@assetTab', 200);
interceptURL('GET', '/api/v1/feed*', 'entityDetails');
@ -933,17 +815,17 @@ describe.skip('Glossary page should work properly', () => {
verifyResponseStatusCode('@removeTags', 200);
cy.get('[data-testid="entity-tags"]')
.should('not.contain', term)
.should('not.contain', name)
.and('not.contain', 'Personal');
// Remove the added column tag from entity
interceptURL('PATCH', '/api/v1/tables/*', 'removeSchemaTags');
cy.get(`[data-testid="remove-${glossaryName}.${term}-tag"]`)
cy.get(`[data-testid="remove-${glossaryName}.${name}-tag"]`)
.should('be.visible')
.click();
verifyResponseStatusCode('@removeSchemaTags', 200);
cy.get('[data-testid="tags"]')
.should('not.contain', term)
.should('not.contain', name)
.and('not.contain', 'Personal');
cy.get('[data-testid="governance"]')
@ -957,33 +839,29 @@ describe.skip('Glossary page should work properly', () => {
cy.wait(500);
cy.get('.ant-menu-item')
.contains(NEW_GLOSSARY_1.name)
.should('be.visible')
.click();
selectActiveGlossary(NEW_GLOSSARY_1.name);
goToAssetsTab(term);
cy.contains('No assets available.').should('be.visible');
cy.get('[data-testid="no-data-image"]').should('be.visible');
goToAssetsTab(name, fullyQualifiedName);
cy.contains('Adding a new Asset is easy, just give it a spin!').should(
'be.visible'
);
});
it.skip('Delete glossary term should work properly', () => {
it('Delete glossary term should work properly', () => {
const terms = Object.values(NEW_GLOSSARY_TERMS);
selectActiveGlossary(NEW_GLOSSARY.name);
terms.forEach(deleteGlossaryTerm);
// Glossary term for Product glossary
cy.get('.ant-menu-item')
.contains(NEW_GLOSSARY_1.name)
.should('be.visible')
.click();
selectActiveGlossary(NEW_GLOSSARY_1.name);
Object.values(NEW_GLOSSARY_1_TERMS).forEach(deleteGlossaryTerm);
});
it('Delete glossary should work properly', () => {
[NEW_GLOSSARY.name, NEW_GLOSSARY_1.name].forEach((glossary) => {
verifyResponseStatusCode('@fetchGlossaries', 200);
cy.get('.ant-menu-item').contains(glossary).should('be.visible').click();
cy.wait(200);
cy.get('[data-testid="manage-button"]').should('be.visible').click();
cy.get('[data-testid="delete-button"]')

View File

@ -1,12 +1,12 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_19628_23090)">
<svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_19769_23023)">
<path d="M1.72277 9.91757C1.62289 9.91755 1.52525 9.88791 1.44221 9.83241C1.35916 9.77691 1.29444 9.69803 1.25622 9.60574C1.218 9.51346 1.20799 9.41192 1.22747 9.31395C1.24695 9.21598 1.29504 9.12599 1.36566 9.05535L9.259 1.16202C9.30559 1.11377 9.36133 1.07529 9.42295 1.04882C9.48458 1.02235 9.55086 1.00841 9.61793 1.00783C9.685 1.00725 9.75151 1.02003 9.81358 1.04543C9.87566 1.07082 9.93206 1.10833 9.97948 1.15576C10.0269 1.20318 10.0644 1.25958 10.0898 1.32165C10.1152 1.38373 10.128 1.45024 10.1274 1.51731C10.1268 1.58438 10.1129 1.65066 10.0864 1.71228C10.0599 1.77391 10.0215 1.82965 9.97322 1.87624L2.07989 9.76957C1.98139 9.86807 1.85208 9.91757 1.72277 9.91757Z" fill="currentColor"/>
<path d="M0.943012 13.5649C0.867642 13.565 0.793214 13.5482 0.725184 13.5157C0.657153 13.4833 0.597246 13.436 0.549853 13.3774C0.50246 13.3188 0.468783 13.2503 0.451291 13.177C0.433799 13.1037 0.432935 13.0274 0.448763 12.9537L1.22916 9.31618C1.24289 9.25115 1.26933 9.18947 1.30695 9.13467C1.34457 9.07988 1.39263 9.03305 1.44839 8.99687C1.50414 8.96069 1.56649 8.93586 1.63185 8.92382C1.69722 8.91178 1.76432 8.91276 1.82931 8.9267C1.89429 8.94064 1.95589 8.96727 2.01056 9.00506C2.06524 9.04286 2.11192 9.09107 2.14793 9.14693C2.18393 9.2028 2.20856 9.26523 2.2204 9.33063C2.23223 9.39603 2.23104 9.46313 2.2169 9.52807L1.4365 13.1656C1.4123 13.2786 1.35012 13.3798 1.26032 13.4525C1.17052 13.5251 1.05853 13.5648 0.943012 13.5649ZM4.58005 12.7845C4.48016 12.7845 4.38253 12.7549 4.29948 12.6993C4.21644 12.6438 4.15171 12.565 4.11349 12.4727C4.07527 12.3804 4.06527 12.2789 4.08475 12.1809C4.10423 12.0829 4.15232 11.9929 4.22294 11.9223L12.1163 4.0292C12.1629 3.98096 12.2186 3.94248 12.2802 3.91601C12.3419 3.88954 12.4081 3.8756 12.4752 3.87502C12.5423 3.87444 12.6088 3.88722 12.6709 3.91261C12.7329 3.93801 12.7893 3.97552 12.8368 4.02294C12.8842 4.07037 12.9217 4.12677 12.9471 4.18884C12.9725 4.25092 12.9853 4.31743 12.9847 4.3845C12.9841 4.45157 12.9702 4.51785 12.9437 4.57947C12.9172 4.6411 12.8787 4.69683 12.8305 4.74343L4.93741 12.6365C4.89054 12.6835 4.83484 12.7208 4.77351 12.7462C4.71218 12.7716 4.64643 12.7846 4.58005 12.7845Z" fill="currentColor"/>
<path d="M0.941691 13.5625C0.817227 13.562 0.697335 13.5155 0.604993 13.4321C0.51265 13.3486 0.454354 13.234 0.441275 13.1102C0.428197 12.9865 0.461256 12.8622 0.534118 12.7613C0.606979 12.6604 0.714518 12.5899 0.836124 12.5634L4.47366 11.783C4.60447 11.7554 4.74089 11.7807 4.85303 11.8535C4.96517 11.9263 5.04389 12.0405 5.07193 12.1713C5.09997 12.302 5.07505 12.4385 5.00263 12.5508C4.9302 12.6632 4.81618 12.7423 4.68556 12.7707L1.04802 13.5511C1.01309 13.5588 0.97744 13.5626 0.941691 13.5625ZM11.0444 6.31747C10.978 6.3176 10.9123 6.30458 10.851 6.27918C10.7897 6.25378 10.7341 6.21649 10.6873 6.16947L7.83011 3.31233C7.78187 3.26573 7.74339 3.21 7.71692 3.14837C7.69045 3.08675 7.67651 3.02046 7.67593 2.9534C7.67535 2.88633 7.68813 2.81982 7.71352 2.75774C7.73892 2.69566 7.77643 2.63927 7.82385 2.59184C7.87128 2.54442 7.92768 2.50691 7.98975 2.48151C8.05183 2.45612 8.11834 2.44334 8.18541 2.44392C8.25248 2.4445 8.31876 2.45843 8.38038 2.48491C8.44201 2.51138 8.49774 2.54986 8.54434 2.5981L11.4015 5.45525C11.4721 5.52589 11.5202 5.61588 11.5397 5.71385C11.5592 5.81182 11.5492 5.91336 11.5109 6.00564C11.4727 6.09793 11.408 6.17681 11.3249 6.23231C11.2419 6.28781 11.1443 6.31745 11.0444 6.31747ZM12.4731 4.88902C12.3731 4.8891 12.2754 4.85952 12.1922 4.80402C12.1091 4.74853 12.0443 4.66961 12.006 4.57727C11.9678 4.48492 11.9578 4.3833 11.9773 4.28526C11.9968 4.18723 12.045 4.09719 12.1157 4.02655C12.3968 3.74546 12.5516 3.36486 12.5516 2.95521C12.5516 2.54557 12.3968 2.16497 12.1157 1.88388C11.8344 1.60253 11.4538 1.44772 11.0441 1.44772C10.6345 1.44772 10.2539 1.60253 9.97278 1.88388C9.92587 1.93079 9.87018 1.96801 9.80888 1.99339C9.74759 2.01878 9.68189 2.03185 9.61555 2.03185C9.5492 2.03185 9.48351 2.01878 9.42221 1.99339C9.36092 1.96801 9.30522 1.93079 9.25831 1.88388C9.2114 1.83697 9.17418 1.78127 9.14879 1.71998C9.1234 1.65868 9.11033 1.59299 9.11033 1.52664C9.11033 1.4603 9.1234 1.3946 9.14879 1.3333C9.17418 1.27201 9.2114 1.21632 9.25831 1.1694C9.73008 0.697378 10.3642 0.4375 11.0441 0.4375C11.7237 0.4375 12.3582 0.697378 12.8299 1.1694C13.302 1.64117 13.5618 2.27534 13.5618 2.95521C13.5618 3.63509 13.302 4.26925 12.8299 4.74103C12.7832 4.78802 12.7275 4.82528 12.6663 4.85068C12.605 4.87608 12.5394 4.88911 12.4731 4.88902Z" fill="currentColor"/>
<line x1="6.1875" y1="13.0625" x2="13.0625" y2="13.0625" stroke="#6B7280" stroke-linecap="round"/>
<line x1="8.19043" y1="13.0625" x2="13.0704" y2="13.0625" stroke="#6B7280" stroke-linecap="round"/>
</g>
<defs>
<clipPath id="clip0_19628_23090">
<clipPath id="clip0_19769_23023">
<rect width="14" height="14" fill="white"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,4 @@
<svg width="8" height="16" viewBox="0 0 8 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.00001 10.2004C3.93026 10.2004 3.86044 10.2272 3.80719 10.2809L1.07993 13.0306C0.973358 13.1381 0.973358 13.312 1.07993 13.4194C1.18649 13.5268 1.35906 13.5269 1.46556 13.4194L4.00001 10.8641L6.53446 13.4194C6.64103 13.5269 6.8136 13.5269 6.9201 13.4194C7.0266 13.312 7.02667 13.138 6.9201 13.0306L4.19283 10.2809C4.13958 10.2272 4.06976 10.2004 4.00001 10.2004Z" fill="currentColor" stroke="currentColor" stroke-width="0.8"/>
<path d="M4.00001 5.79963C3.93026 5.79963 3.86044 5.77276 3.80719 5.71907L1.07993 2.96939C0.973358 2.86194 0.973358 2.68796 1.07993 2.58058C1.18649 2.47321 1.35906 2.47314 1.46556 2.58058L4.00001 5.13586L6.53446 2.58058C6.64103 2.47314 6.8136 2.47314 6.9201 2.58058C7.0266 2.68803 7.02667 2.86201 6.9201 2.96939L4.19283 5.71907C4.13958 5.77276 4.06976 5.79963 4.00001 5.79963Z" fill="currentColor" stroke="currentColor" stroke-width="0.8"/>
</svg>

After

Width:  |  Height:  |  Size: 980 B

View File

@ -1,4 +1,4 @@
<svg viewBox="0 0 8 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="8" height="16" viewBox="0 0 8 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.00001 13.7996C3.93026 13.7996 3.86044 13.7728 3.80719 13.7191L1.07993 10.9694C0.973358 10.8619 0.973358 10.688 1.07993 10.5806C1.18649 10.4732 1.35906 10.4731 1.46556 10.5806L4.00001 13.1359L6.53446 10.5806C6.64103 10.4731 6.8136 10.4731 6.9201 10.5806C7.0266 10.688 7.02667 10.862 6.9201 10.9694L4.19283 13.7191C4.13958 13.7728 4.06976 13.7996 4.00001 13.7996Z" fill="currentColor" stroke="currentColor" stroke-width="0.8"/>
<path d="M4.00001 2.20037C3.93026 2.20037 3.86044 2.22724 3.80719 2.28093L1.07993 5.03061C0.973358 5.13806 0.973358 5.31204 1.07993 5.41942C1.18649 5.52679 1.35906 5.52686 1.46556 5.41942L4.00001 2.86414L6.53446 5.41942C6.64103 5.52686 6.8136 5.52686 6.9201 5.41942C7.0266 5.31197 7.02667 5.13799 6.9201 5.03061L4.19283 2.28093C4.13958 2.22724 4.06976 2.20037 4.00001 2.20037Z" fill="currentColor" stroke="currentColor" stroke-width="0.8"/>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 957 B

After

Width:  |  Height:  |  Size: 980 B

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Space, Typography } from 'antd';
import { Col, Row, Typography } from 'antd';
import React from 'react';
interface props {
@ -21,23 +21,24 @@ interface props {
const EntityHeaderTitle = ({ icon, name, displayName }: props) => {
return (
<Space direction="vertical" size={0}>
<Space align="center" size={8}>
{icon}
<div className="d-flex flex-col">
<Row align="middle" gutter={8} wrap={false}>
<Col>{icon}</Col>
<Col>
<div>
<Typography.Text
className="m-b-0 tw-text-xs tw-text-grey-muted"
className="m-b-0 d-block tw-text-xs tw-text-grey-muted"
data-testid="entity-header-name">
{name}
</Typography.Text>
<Typography.Text
className="m-b-0 entity-header-display-name text-lg font-bold"
data-testid="entity-header-display-name">
className="m-b-0 d-block entity-header-display-name text-lg font-bold"
data-testid="entity-header-display-name"
ellipsis={{ tooltip: true }}>
{displayName}
</Typography.Text>
</div>
</Space>
</Space>
</Col>
</Row>
);
};

View File

@ -12,6 +12,7 @@
*/
import { DownOutlined } from '@ant-design/icons';
import { Button, Col, Dropdown, Row, Space, Tooltip, Typography } from 'antd';
import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import { ReactComponent as ExportIcon } from 'assets/svg/ic-export.svg';
import { ReactComponent as ImportIcon } from 'assets/svg/ic-import.svg';
import { ReactComponent as IconDropdown } from 'assets/svg/menu.svg';
@ -21,6 +22,7 @@ import EntityNameModal from 'components/Modals/EntityNameModal/EntityNameModal.c
import { OperationPermission } from 'components/PermissionProvider/PermissionProvider.interface';
import VersionButton from 'components/VersionButton/VersionButton.component';
import { FQN_SEPARATOR_CHAR } from 'constants/char.constants';
import { DE_ACTIVE_COLOR } from 'constants/constants';
import { EntityReference, Glossary } from 'generated/entity/data/glossary';
import { GlossaryTerm } from 'generated/entity/data/glossaryTerm';
import { cloneDeep, toString } from 'lodash';
@ -177,7 +179,7 @@ const GlossaryHeaderButtons = ({
setShowActions(false);
}}>
<Col className="self-center" span={3}>
<ExportIcon width="20px" />
<ExportIcon width="18px" />
</Col>
<Col span={21}>
<Row>
@ -245,8 +247,8 @@ const GlossaryHeaderButtons = ({
setIsNameEditing(true);
setShowActions(false);
}}>
<Col span={3}>
<SVGIcons alt="Edit" icon={Icons.EDIT} />
<Col className="self-center" span={3}>
<EditIcon color={DE_ACTIVE_COLOR} width="18px" />
</Col>
<Col
className="tw-text-left"
@ -278,7 +280,7 @@ const GlossaryHeaderButtons = ({
setIsDelete(true);
setShowActions(false);
}}>
<Col span={3}>
<Col className="self-center" span={3}>
<SVGIcons alt="Delete" icon={Icons.DELETE} />
</Col>
<Col className="tw-text-left" data-testid="delete-button" span={21}>
@ -303,7 +305,7 @@ const GlossaryHeaderButtons = ({
if (permission.Create) {
return isGlossary ? (
<Button
className="m-r-xs"
className="m-l-xs"
data-testid="add-new-tag-button-header"
size="middle"
type="primary"
@ -312,7 +314,7 @@ const GlossaryHeaderButtons = ({
</Button>
) : (
<Dropdown
className="m-r-xs"
className="m-l-xs"
menu={{
items: addButtonContent,
}}
@ -337,7 +339,7 @@ const GlossaryHeaderButtons = ({
{createButtons}
{selectedData && selectedData.version && (
<VersionButton
className="m-r-xs tw-px-1.5"
className="m-l-xs tw-px-1.5"
selected={Boolean(version)}
version={toString(selectedData.version)}
onClick={handleVersionClick}
@ -347,6 +349,7 @@ const GlossaryHeaderButtons = ({
{permission.Delete && (
<Dropdown
align={{ targetOffset: [-12, 0] }}
className="m-l-xs"
menu={{
items: manageButtonContent,
}}

View File

@ -23,8 +23,10 @@ import {
} from 'antd';
import { ColumnsType, ExpandableConfig } from 'antd/lib/table/interface';
import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import { ReactComponent as DownUpArrowIcon } from 'assets/svg/ic-down-up-arrow.svg';
import { ReactComponent as UpDownArrowIcon } from 'assets/svg/ic-up-down-arrow.svg';
import { ReactComponent as PlusOutlinedIcon } from 'assets/svg/plus-outlined.svg';
import { ReactComponent as PlusIcon } from 'assets/svg/plus-primary.svg';
import { AxiosError } from 'axios';
import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder';
import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer';
@ -32,7 +34,6 @@ import Loader from 'components/Loader/Loader';
import { FQN_SEPARATOR_CHAR } from 'constants/char.constants';
import { DE_ACTIVE_COLOR } from 'constants/constants';
import { GLOSSARIES_DOCS } from 'constants/docs.constants';
import { NO_PERMISSION_FOR_ACTION } from 'constants/HelperTextUtil';
import { TABLE_CONSTANTS } from 'constants/Teams.constants';
import { ERROR_PLACEHOLDER_TYPE } from 'enums/common.enum';
import { compare } from 'fast-json-patch';
@ -261,24 +262,18 @@ const GlossaryTermTab = ({
<ErrorPlaceHolder
buttons={
<div className="tw-text-lg tw-text-center">
<Tooltip
title={
permissions.Create
? t('label.add-entity', {
entity: t('label.term-lowercase'),
})
: NO_PERMISSION_FOR_ACTION
}>
{permissions.Create && (
<Button
ghost
data-testid="add-new-tag-button"
type="primary"
onClick={() => handleAddGlossaryTermClick(glossaryName)}>
{t('label.add-entity', {
entity: t('label.glossary-term'),
})}
<div className="d-flex items-center">
<PlusIcon className="anticon" />
<span className="m-l-0">{t('label.add')}</span>
</div>
</Button>
</Tooltip>
)}
</div>
}
doc={GLOSSARIES_DOCS}
@ -299,7 +294,12 @@ const GlossaryTermTab = ({
type="text"
onClick={toggleExpandAll}>
<Space align="center" size={4}>
<UpDownArrowIcon color={DE_ACTIVE_COLOR} height="14px" />
{expandedRowKeys.length === childGlossaryTerms.length ? (
<DownUpArrowIcon color={DE_ACTIVE_COLOR} height="14px" />
) : (
<UpDownArrowIcon color={DE_ACTIVE_COLOR} height="14px" />
)}
{expandedRowKeys.length === childGlossaryTerms.length
? t('label.collapse-all')
: t('label.expand-all')}
@ -319,6 +319,7 @@ const GlossaryTermTab = ({
loading={isTableLoading}
pagination={false}
rowKey="fullyQualifiedName"
scroll={{ x: true }}
size="small"
tableLayout="auto"
onRow={onTableRow}

View File

@ -65,6 +65,7 @@ const GlossaryV1 = ({
useState<OperationPermission>(DEFAULT_ENTITY_PERMISSION);
const [glossaryTerms, setGlossaryTerms] = useState<GlossaryTerm[]>([]);
const { id } = selectedData ?? {};
const handleCancelGlossaryExport = () =>
history.push(getGlossaryPath(selectedData.name));
@ -129,15 +130,11 @@ const GlossaryV1 = ({
};
const loadGlossaryTerms = useCallback(() => {
fetchGlossaryTerm(
isGlossaryActive
? { glossary: selectedData.id }
: { parent: selectedData.id }
);
}, [selectedData, isGlossaryActive]);
fetchGlossaryTerm(isGlossaryActive ? { glossary: id } : { parent: id });
}, [id, isGlossaryActive]);
useEffect(() => {
if (selectedData) {
if (id) {
loadGlossaryTerms();
if (isGlossaryActive) {
isVersionsView
@ -149,7 +146,7 @@ const GlossaryV1 = ({
: fetchGlossaryTermPermission();
}
}
}, [selectedData, isGlossaryActive, isVersionsView]);
}, [id, isGlossaryActive, isVersionsView]);
return isImportAction ? (
<ImportGlossary glossaryName={selectedData.name} />

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Button, Card, Space, Typography } from 'antd';
import { Button, Card, Col, Row, Space, Typography } from 'antd';
import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import { ReactComponent as PlusIcon } from 'assets/svg/plus-primary.svg';
import ProfilePicture from 'components/common/ProfilePicture/ProfilePicture';
@ -86,11 +86,11 @@ const GlossaryDetailsRightPanel = ({
return (
<Card>
<Space direction="vertical" size={40}>
<Space className="d-flex" direction="vertical">
<Space size={0}>
<Row gutter={[0, 40]}>
<Col span="24">
<div className="d-flex items-center m-b-xs">
<Typography.Text
className="m-b-xs tw-text-base font-medium"
className=" tw-text-base font-medium"
data-testid="glossary-owner-name">
{t('label.owner')}
</Typography.Text>
@ -108,35 +108,34 @@ const GlossaryDetailsRightPanel = ({
/>
</UserTeamSelectableList>
)}
</Space>
<Space>
{selectedData.owner && getEntityName(selectedData.owner) ? (
<Space className="m-r-xss" size={4}>
<ProfilePicture
displayName={getEntityName(selectedData.owner)}
id={selectedData.owner?.id || ''}
name={selectedData.owner?.name || ''}
textClass="text-xs"
width="20"
/>
<Link to={getUserPath(selectedData.owner.name ?? '')}>
{getEntityName(selectedData.owner)}
</Link>
</Space>
) : (
<span className="text-grey-muted">
{t('label.no-entity', {
entity: t('label.owner-lowercase'),
})}
</span>
)}
</Space>
</Space>
<Space className="d-flex" direction="vertical">
<Space size={0}>
</div>
{selectedData.owner && getEntityName(selectedData.owner) ? (
<Space className="m-r-xss" size={4}>
<ProfilePicture
displayName={getEntityName(selectedData.owner)}
id={selectedData.owner?.id || ''}
name={selectedData.owner?.name || ''}
textClass="text-xs"
width="20"
/>
<Link to={getUserPath(selectedData.owner.name ?? '')}>
{getEntityName(selectedData.owner)}
</Link>
</Space>
) : (
<span className="text-grey-muted">
{t('label.no-entity', {
entity: t('label.owner-lowercase'),
})}
</span>
)}
</Col>
<Col span="24">
<div className="d-flex items-center m-b-xs">
<Typography.Text
className="m-b-xs tw-text-base font-medium"
data-testid="glossary-display-name">
className="tw-text-base font-medium"
data-testid="glossary-reviewer-heading-name">
{t('label.reviewer-plural')}
</Typography.Text>
{hasEditReviewerAccess &&
@ -151,14 +150,15 @@ const GlossaryDetailsRightPanel = ({
className="cursor-pointer flex-center"
data-testid="edit-reviewer-button"
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
/>
</UserSelectableList>
)}
</Space>
<Space>
</div>
<div>
{selectedData.reviewers && selectedData.reviewers.length > 0 && (
<Space wrap size={6}>
<Space wrap data-testid="glossary-reviewer-name" size={6}>
{selectedData.reviewers.map((reviewer) => (
<Space className="m-r-xss" key={reviewer.id} size={4}>
<ProfilePicture
@ -191,21 +191,20 @@ const GlossaryDetailsRightPanel = ({
/>
</UserSelectableList>
)}
</Space>
</Space>
{isGlossary && (
<Space className="d-flex" direction="vertical">
<Space data-testid="glossary-tags-name">
</div>
</Col>
<Col span="24">
<div data-testid="glossary-tags-name">
{isGlossary && (
<TagsInput
editable={permissions.EditAll || permissions.EditTags}
tags={selectedData.tags}
onTagsUpdate={handleTagsUpdate}
/>
</Space>
</Space>
)}
</Space>
)}
</div>
</Col>
</Row>
</Card>
);
};

View File

@ -54,7 +54,7 @@ describe('GlossaryDetailsRightPanel', () => {
);
expect(getByTestId('glossary-owner-name')).toHaveTextContent('label.owner');
expect(getByTestId('glossary-display-name')).toHaveTextContent(
expect(getByTestId('glossary-reviewer-heading-name')).toHaveTextContent(
'label.reviewer-plural'
);
expect(getByTestId('glossary-tags-name')).toHaveTextContent(

View File

@ -54,7 +54,7 @@ const GlossaryTermReferencesModal = ({
{t('label.cancel')}
</Button>,
<Button
data-testid="save-button"
data-testid="save-btn"
key="save-btn"
type="primary"
onClick={() => form.submit()}>
@ -126,12 +126,11 @@ const GlossaryTermReferencesModal = ({
<Form.Item>
<Button
className="text-primary d-flex items-center"
data-testid="add-references-button"
icon={<PlusIcon className="anticon" />}
size="small"
onClick={() => add()}>
{t('label.add-entity', {
entity: t('label.reference-plural'),
})}
{t('label.add')}
</Button>
</Form.Item>
</>

View File

@ -85,26 +85,22 @@ const GlossaryOverviewTab = ({
/>
</Col>
<Col span={24}>
<Row gutter={[0, 48]}>
<Row gutter={[0, 40]}>
{!isGlossary && (
<>
<Col span={12}>
<Space className="w-full" direction="vertical">
<GlossaryTermSynonyms
glossaryTerm={selectedData as GlossaryTerm}
permissions={permissions}
onGlossaryTermUpdate={onUpdate}
/>
</Space>
<GlossaryTermSynonyms
glossaryTerm={selectedData as GlossaryTerm}
permissions={permissions}
onGlossaryTermUpdate={onUpdate}
/>
</Col>
<Col span={12}>
<Space className="w-full" direction="vertical">
<RelatedTerms
glossaryTerm={selectedData as GlossaryTerm}
permissions={permissions}
onGlossaryTermUpdate={onUpdate}
/>
</Space>
<RelatedTerms
glossaryTerm={selectedData as GlossaryTerm}
permissions={permissions}
onGlossaryTermUpdate={onUpdate}
/>
</Col>
<Col span={12}>
<GlossaryTermReferences

View File

@ -78,7 +78,7 @@ const GlossaryTermReferences = ({
return (
<div data-testid="references-container">
<Space className="w-full" direction="vertical">
<Space className="w-full" direction="vertical" size={4}>
<Space
className="w-full"
data-testid={`section-${t('label.reference-plural')}`}>
@ -109,18 +109,25 @@ const GlossaryTermReferences = ({
<>
<div className="d-flex flex-wrap">
{references.map((ref) => (
<Tag className="term-reference-tag tw-bg-white" key={ref.name}>
<a
className=""
data-testid="owner-link"
href={ref?.endpoint}
rel="noopener noreferrer"
target="_blank">
<Space align="center" size={4}>
<ExternalLinkIcon color={TEXT_BODY_COLOR} width="12px" />
<Typography.Text>{ref?.name}</Typography.Text>
</Space>
</a>
<Tag
className="tw-mr-2 tw-mt-1 d-flex items-center term-reference-tag tw-bg-white"
key={ref.name}>
<Tooltip title={ref.name}>
<a
data-testid="owner-link"
href={ref?.endpoint}
rel="noopener noreferrer"
target="_blank">
<div className="d-flex items-center">
<ExternalLinkIcon
className="m-r-xss"
color={TEXT_BODY_COLOR}
width="12px"
/>
<span className="text-body">{ref?.name}</span>
</div>
</a>
</Tooltip>
</Tag>
))}
{permissions.EditAll && references.length === 0 && (

View File

@ -12,7 +12,7 @@
*/
import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { Button, Select, Space, Tooltip, Typography } from 'antd';
import { Button, Select, Tooltip, Typography } from 'antd';
import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import TagButton from 'components/TagButton/TagButton.component';
import { DE_ACTIVE_COLOR } from 'constants/constants';
@ -86,65 +86,62 @@ const GlossaryTermSynonyms = ({
}, [glossaryTerm]);
return (
<div className="flex" data-testid="synonyms-container">
<Space direction="vertical">
<div className="d-flex items-center">
<Typography.Text className="glossary-subheading">
{t('label.synonym-plural')}
</Typography.Text>
{permissions.EditAll && synonyms.length > 0 && (
<Tooltip
title={
permissions.EditAll ? t('label.edit') : NO_PERMISSION_FOR_ACTION
}>
<Button
className="cursor-pointer m--t-xss m-l-xss"
data-testid="edit-button"
disabled={!permissions.EditAll}
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsViewMode(false)}
/>
</Tooltip>
)}
</div>
{isViewMode ? (
getSynonyms()
) : (
<Space align="center" className="w-full" size={8}>
<Select
className="w-min-15"
id="synonyms-select"
mode="tags"
placeholder={t('label.add-entity', {
entity: t('label.synonym-plural'),
})}
style={{ width: '100%' }}
value={synonyms}
onChange={(value) => setSynonyms(value)}
<div className="flex flex-col m-r-xs" data-testid="synonyms-container">
<div className="d-flex items-center">
<Typography.Text className="glossary-subheading">
{t('label.synonym-plural')}
</Typography.Text>
{permissions.EditAll && synonyms.length > 0 && (
<Tooltip
title={
permissions.EditAll ? t('label.edit') : NO_PERMISSION_FOR_ACTION
}>
<Button
className="cursor-pointer m--t-xss m-l-xss"
data-testid="edit-button"
disabled={!permissions.EditAll}
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsViewMode(false)}
/>
<>
<Button
className="w-6 p-x-05"
data-testid="cancelAssociatedTag"
icon={<CloseOutlined size={12} />}
size="small"
onClick={handleCancel}
/>
<Button
className="w-6 p-x-05"
data-testid="saveAssociatedTag"
icon={<CheckOutlined size={12} />}
size="small"
type="primary"
onClick={() => handleSynonymsSave(synonyms)}
/>
</>
</Space>
</Tooltip>
)}
</Space>
</div>
{isViewMode ? (
getSynonyms()
) : (
<div className="d-flex items-center gap-2">
<Select
className="glossary-select"
id="synonyms-select"
mode="tags"
placeholder={t('label.add-entity', {
entity: t('label.synonym-plural'),
})}
value={synonyms}
onChange={(value) => setSynonyms(value)}
/>
<>
<Button
className="w-6 p-x-05"
data-testid="cancel-synonym-btn"
icon={<CloseOutlined size={12} />}
size="small"
onClick={handleCancel}
/>
<Button
className="w-6 p-x-05"
data-testid="save-synonym-btn"
icon={<CheckOutlined size={12} />}
size="small"
type="primary"
onClick={() => handleSynonymsSave(synonyms)}
/>
</>
</div>
)}
</div>
);
};

View File

@ -12,7 +12,7 @@
*/
import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { Button, Select, Space, Spin, Tooltip, Typography } from 'antd';
import { Button, Select, Spin, Tooltip, Typography } from 'antd';
import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import { ReactComponent as IconFlatDoc } from 'assets/svg/ic-flat-doc.svg';
import TagButton from 'components/TagButton/TagButton.component';
@ -131,97 +131,91 @@ const RelatedTerms = ({
}, [glossaryTerm]);
return (
<div className="flex" data-testid="related-term-container">
<Space
className="w-full"
data-testid={`section-${t('label.related-term-plural')}`}
direction="vertical">
<div className="d-flex items-center">
<Typography.Text className="glossary-subheading">
{t('label.related-term-plural')}
</Typography.Text>
{permissions.EditAll && selectedOption.length > 0 && (
<Tooltip
title={
permissions.EditAll ? t('label.edit') : NO_PERMISSION_FOR_ACTION
}>
<Button
className="cursor-pointer m--t-xss m-l-xss"
data-testid="edit-button"
disabled={!permissions.EditAll}
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsIconVisible(false)}
/>
</Tooltip>
)}
</div>
<Space>
{isIconVisible ? (
<div className="d-flex flex-wrap">
{permissions.EditAll && selectedOption.length === 0 && (
<TagButton
className="tw-text-primary"
icon={<PlusIcon height={16} name="plus" width={16} />}
label={t('label.add')}
onClick={() => {
setIsIconVisible(false);
}}
/>
)}
<div className="flex flex-col gap-3" data-testid="related-term-container">
<div className="d-flex items-center">
<Typography.Text className="glossary-subheading">
{t('label.related-term-plural')}
</Typography.Text>
{permissions.EditAll && selectedOption.length > 0 && (
<Tooltip
title={
permissions.EditAll ? t('label.edit') : NO_PERMISSION_FOR_ACTION
}>
<Button
className="cursor-pointer m--t-xss m-l-xss"
data-testid="edit-button"
disabled={!permissions.EditAll}
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsIconVisible(false)}
/>
</Tooltip>
)}
</div>
{selectedOption.map((entity: EntityReference) => (
<TagButton
icon={<IconFlatDoc height={14} name="folder" width={14} />}
key={entity.fullyQualifiedName}
label={toString(entity.displayName)}
onClick={() => {
handleRelatedTermClick(entity.fullyQualifiedName || '');
}}
/>
))}
</div>
) : (
<Space align="center" className="w-full" size={8}>
<Select
className="w-min-15"
filterOption={false}
mode="multiple"
notFoundContent={isLoading ? <Spin size="small" /> : null}
options={formatOptions(options)}
placeholder={t('label.add-entity', {
entity: t('label.related-term-plural'),
})}
style={{ width: '100%' }}
value={selectedOption}
onChange={(_, data) => {
setSelectedOption(data as EntityReference[]);
}}
onFocus={() => suggestionSearch()}
onSearch={debounceOnSearch}
/>
<>
<Button
className="w-6 p-x-05"
data-testid="cancelAssociatedTag"
icon={<CloseOutlined size={12} />}
size="small"
onClick={() => handleCancel()}
/>
<Button
className="w-6 p-x-05"
data-testid="saveAssociatedTag"
icon={<CheckOutlined size={12} />}
size="small"
type="primary"
onClick={() => handleRelatedTermsSave(selectedOption)}
/>
</>
</Space>
{isIconVisible ? (
<div className="d-flex flex-wrap">
{permissions.EditAll && selectedOption.length === 0 && (
<TagButton
className="tw-text-primary"
dataTestId="related-term-add-button"
icon={<PlusIcon height={16} name="plus" width={16} />}
label={t('label.add')}
onClick={() => {
setIsIconVisible(false);
}}
/>
)}
</Space>
</Space>
{selectedOption.map((entity: EntityReference) => (
<TagButton
icon={<IconFlatDoc height={14} name="folder" width={14} />}
key={entity.fullyQualifiedName}
label={toString(entity.displayName)}
onClick={() => {
handleRelatedTermClick(entity.fullyQualifiedName || '');
}}
/>
))}
</div>
) : (
<div className="d-flex items-center gap-2">
<Select
className="glossary-select"
filterOption={false}
mode="multiple"
notFoundContent={isLoading ? <Spin size="small" /> : null}
options={formatOptions(options)}
placeholder={t('label.add-entity', {
entity: t('label.related-term-plural'),
})}
value={selectedOption}
onChange={(_, data) => {
setSelectedOption(data as EntityReference[]);
}}
onFocus={() => suggestionSearch()}
onSearch={debounceOnSearch}
/>
<>
<Button
className="w-6 p-x-05"
data-testid="cancel-related-term-btn"
icon={<CloseOutlined size={12} />}
size="small"
onClick={() => handleCancel()}
/>
<Button
className="w-6 p-x-05"
data-testid="save-related-term-btn"
icon={<CheckOutlined size={12} />}
size="small"
type="primary"
onClick={() => handleRelatedTermsSave(selectedOption)}
/>
</>
</div>
)}
</div>
);
};

View File

@ -10,7 +10,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Space } from 'antd';
import { AxiosError } from 'axios';
import PageContainer from 'components/containers/PageContainer';
import EntityVersionTimeLine from 'components/EntityVersionTimeLine/EntityVersionTimeLine';
@ -29,6 +28,7 @@ import {
getGlossaryVersionsList,
} from 'rest/glossaryAPI';
import {
getGlossaryPath,
getGlossaryTermsVersionsPath,
getGlossaryVersionsPath,
} from 'utils/RouterUtils';
@ -78,6 +78,11 @@ const GlossaryVersion = ({ isGlossary = false }: GlossaryVersionProps) => {
history.push(path);
};
const onBackHandler = () => {
const path = getGlossaryPath(selectedData?.fullyQualifiedName);
history.push(path);
};
useEffect(() => {
fetchVersionsInfo();
fetchActiveVersion();
@ -85,26 +90,24 @@ const GlossaryVersion = ({ isGlossary = false }: GlossaryVersionProps) => {
return (
<PageContainer>
<div className="version-data p-l-lg p-r-xss">
<Space className="w-full" direction="vertical">
<GlossaryV1
isVersionsView
deleteStatus={LOADING_STATE.INITIAL}
isGlossaryActive={isGlossary}
selectedData={selectedData as Glossary}
updateGlossary={mockFnGlossary}
onGlossaryDelete={mockFn}
onGlossaryTermDelete={mockFn}
onGlossaryTermUpdate={mockFnGlossary}
/>
</Space>
<div className="version-data p-l-lg p-r-sm">
<GlossaryV1
isVersionsView
deleteStatus={LOADING_STATE.INITIAL}
isGlossaryActive={isGlossary}
selectedData={selectedData as Glossary}
updateGlossary={mockFnGlossary}
onGlossaryDelete={mockFn}
onGlossaryTermDelete={mockFn}
onGlossaryTermUpdate={mockFnGlossary}
/>
</div>
<EntityVersionTimeLine
show
currentVersion={version}
versionHandler={onVersionHandler}
versionList={versionList}
onBack={mockFn}
onBack={onBackHandler}
/>
</PageContainer>
);

View File

@ -61,7 +61,7 @@ const Tags: FunctionComponent<TagProps> = ({
return (
<div
className={classNames(baseStyle, layoutStyles, className)}
className={classNames(baseStyle, layoutStyles, className, 'tags-item')}
data-testid="tags"
onClick={() => {
if (source) {

View File

@ -28,4 +28,5 @@ export type TagsContainerProps = {
containerClass?: string;
onSelectionChange?: (selectedTags: Array<EntityTags>) => void;
onCancel?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
onAddButtonClick?: () => void;
};

View File

@ -38,6 +38,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
tagList,
onCancel,
onSelectionChange,
onAddButtonClick,
className,
containerClass,
showTags = true,
@ -141,19 +142,17 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
);
return (
<Space
align="center"
className={classNames('w-full', containerClass)}
data-testid="tag-container"
size={8}>
<div
className={classNames('w-full d-flex items-center gap-2', containerClass)}
data-testid="tag-container">
{showTags && !editable && (
<Space wrap size={0}>
{showAddTagButton && (
<span className="tw-text-primary">
<span className="tw-text-primary" onClick={onAddButtonClick}>
<Tags
className="tw-font-semibold"
startWith="+ "
tag="Add"
tag={t('label.add')}
type="border"
/>
</span>
@ -165,7 +164,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
<>
<Select
autoFocus
className={classNames('w-min-10', className)}
className={classNames('flex-grow', className)}
data-testid="tag-selector"
defaultValue={selectedTagsInternal}
mode="multiple"
@ -188,14 +187,14 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
</Select>
<>
<Button
className="w-6 p-x-05"
className="p-x-05"
data-testid="cancelAssociatedTag"
icon={<CloseOutlined size={12} />}
size="small"
onClick={handleCancel}
/>
<Button
className="w-6 p-x-05"
className="p-x-05"
data-testid="saveAssociatedTag"
icon={<CheckOutlined size={12} />}
size="small"
@ -207,7 +206,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
) : (
children
)}
</Space>
</div>
);
};

View File

@ -11,7 +11,7 @@
* limitations under the License.
*/
import { CloseOutlined } from '@ant-design/icons';
import { Space } from 'antd';
import { Tooltip } from 'antd';
import classNames from 'classnames';
import React from 'react';
@ -20,6 +20,7 @@ interface TagButtonProps {
icon?: React.ReactNode;
className?: string;
isRemovable?: boolean;
dataTestId?: string;
onClick?: () => void;
removeTag?: (
event: React.MouseEvent<HTMLElement, MouseEvent>,
@ -34,23 +35,26 @@ const TagButton: React.FC<TagButtonProps> = ({
className = '',
isRemovable = false,
removeTag,
dataTestId = label,
}) => {
const buttonClassNames = classNames(
'tag-button-container tw-inline-flex text-xs font-medium rounded-4 whitespace-nowrap tw-bg-white tw-border tw-items-center tw-mr-2 tw-mt-1 tw-font-semibold',
'tag-button-container tw-inline-flex text-xs font-medium rounded-4 whitespace-nowrap tw-bg-white tw-border tw-items-center tw-mr-2 tw-mt-2 tw-font-semibold',
{ 'tw-pl-2': isRemovable },
{ 'tw-px-2': !isRemovable },
className
);
return (
<div className={buttonClassNames} data-testid="tags" onClick={onClick}>
<Space
align="center"
className="d-flex items-center cursor-pointer"
size={4}>
{icon}
<span className="text-xs font-medium">{label}</span>
</Space>
<div
className={buttonClassNames}
data-testid={dataTestId}
onClick={onClick}>
<Tooltip title={label}>
<div className="d-flex items-center">
{icon && <span className="m-r-xss">{icon}</span>}
<span className="text-xs font-medium">{label}</span>
</div>
</Tooltip>
{isRemovable && (
<span
className="tw-py-0.5 tw-px-2 tw-rounded tw-cursor-pointer"

View File

@ -10,18 +10,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Button, Space, Typography } from 'antd';
import { Button, Typography } from 'antd';
import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import classNames from 'classnames';
import { TagDetails } from 'components/TableQueries/TableQueryRightPanel/TableQueryRightPanel.interface';
import TagsContainer from 'components/Tag/TagsContainer/tags-container';
import TagsViewer from 'components/Tag/TagsViewer/tags-viewer';
import { DE_ACTIVE_COLOR } from 'constants/constants';
import { LabelType, State, TagLabel } from 'generated/type/tagLabel';
import { t } from 'i18next';
import { isEmpty, isUndefined } from 'lodash';
import { isEmpty } from 'lodash';
import { EntityTags } from 'Models';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { fetchTagsAndGlossaryTerms } from 'utils/TagsUtils';
type Props = {
@ -79,58 +77,48 @@ const TagsInput: React.FC<Props> = ({ tags = [], editable, onTagsUpdate }) => {
}
};
return (
<div className="tags-input-container">
<Space direction="vertical">
<div className="d-flex items-center">
<Typography.Text className="glossary-subheading">
{t('label.tag-plural')}
</Typography.Text>
{editable && tags.length > 0 && (
<Button
className="cursor-pointer m-l-xss"
data-testid="edit-button"
disabled={!editable}
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsEditTags(true)}
/>
)}
</div>
const addButtonHandler = () => {
setIsEditTags(true);
if (isEmpty(tagDetails.options) || tagDetails.isError) {
fetchTags();
}
};
{editable ? (
<div
className={classNames(
`tw-flex tw-justify-content`,
!isUndefined(tags)
? 'tw-flex-col tw-items-start'
: 'tw-items-center'
)}
data-testid="tags-wrapper"
onClick={() => {
setIsEditTags(true);
if (isEmpty(tagDetails.options) || tagDetails.isError) {
fetchTags();
}
}}>
<TagsContainer
className="w-min-15 "
editable={isEditTags}
isLoading={tagDetails.isLoading}
selectedTags={getSelectedTags()}
showAddTagButton={tags.length === 0}
size="small"
tagList={tagDetails.options}
type="label"
onCancel={() => setIsEditTags(false)}
onSelectionChange={handleTagSelection}
/>
</div>
) : (
<TagsViewer sizeCap={-1} tags={tags || []} />
useEffect(() => {
fetchTags();
}, []);
return (
<div className="tags-input-container" data-testid="tags-input-container">
<div className="d-flex items-center">
<Typography.Text className="glossary-subheading">
{t('label.tag-plural')}
</Typography.Text>
{editable && tags.length > 0 && (
<Button
className="cursor-pointer m-l-xs"
data-testid="edit-button"
disabled={!editable}
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
onClick={() => setIsEditTags(true)}
/>
)}
</Space>
</div>
<TagsContainer
className="glossary-select"
editable={isEditTags}
isLoading={tagDetails.isLoading}
selectedTags={getSelectedTags()}
showAddTagButton={editable && tags.length === 0}
size="small"
tagList={tagDetails.options}
type="label"
onAddButtonClick={addButtonHandler}
onCancel={() => setIsEditTags(false)}
onSelectionChange={handleTagSelection}
/>
</div>
);
};

View File

@ -188,6 +188,7 @@ const TopicSchemaFields: FC<TopicSchemaFieldsProps> = ({
direction={styleFlag ? 'vertical' : 'horizontal'}
onClick={() => handleAddTagClick(record)}>
<TagsContainer
className="w-min-10"
editable={isSelectedField}
isLoading={isTagLoading && isSelectedField}
selectedTags={tags || []}

View File

@ -427,12 +427,6 @@ const AuthenticatedAppRouter: FunctionComponent = () => {
hasPermission={glossaryPermission}
path={ROUTES.GLOSSARY_DETAILS_WITH_ACTION}
/>
<AdminProtectedRoute
exact
component={GlossaryPage}
hasPermission={glossaryTermPermission}
path={ROUTES.GLOSSARY_TERMS}
/>
<Route exact component={UserPage} path={ROUTES.USER_PROFILE} />
<Route exact component={UserPage} path={ROUTES.USER_PROFILE_WITH_TAB} />
<Route exact component={MlModelPage} path={ROUTES.MLMODEL_DETAILS} />
@ -467,6 +461,12 @@ const AuthenticatedAppRouter: FunctionComponent = () => {
component={AddGlossaryTermPage}
path={ROUTES.ADD_GLOSSARY_TERMS}
/>
<AdminProtectedRoute
exact
component={GlossaryPage}
hasPermission={glossaryTermPermission}
path={ROUTES.GLOSSARY_TERMS}
/>
<AdminProtectedRoute
exact
component={GlossaryPage}

View File

@ -87,7 +87,7 @@ const GlossaryLeftPanel = ({ glossaries }: GlossaryLeftPanelProps) => {
onClick={handleAddGlossaryClick}>
<div className="flex-center">
<PlusIcon className="anticon m-r-xss" />
{t('label.add-entity', { entity: t('label.glossary') })}
{t('label.add')}
</div>
</Button>
</Col>

View File

@ -43,6 +43,7 @@ import {
import { checkPermission } from 'utils/PermissionsUtils';
import { getGlossaryPath, getGlossaryTermsPath } from 'utils/RouterUtils';
import { showErrorToast, showSuccessToast } from 'utils/ToastUtils';
import Fqn from '../../../utils/Fqn';
import GlossaryLeftPanel from '../GlossaryLeftPanel/GlossaryLeftPanel.component';
const GlossaryPage = () => {
@ -63,7 +64,7 @@ const GlossaryPage = () => {
setIsRightPanelLoading(true);
setSelectedData(undefined);
if (glossaryFqn) {
return glossaryFqn.split(FQN_SEPARATOR_CHAR).length === 1;
return Fqn.split(glossaryFqn).length === 1;
}
return true;

View File

@ -79,11 +79,18 @@
}
.term-reference-tag {
height: 24px;
.ant-tag-close-icon {
padding-left: 0.5rem;
padding-right: 0.5rem;
color: @primary-color;
}
span {
white-space: nowrap;
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
}
}
.glossary-tabs {
@ -95,13 +102,26 @@
.tag-button-container {
height: 24px;
}
.glossary-overview-tab {
margin-right: 8px !important;
span {
white-space: nowrap;
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
}
}
.glossary-subheading {
font-size: 16px;
font-weight: 500;
}
.glossary-select {
width: calc(100% - 64px);
}
.tags-input-container {
.tags-item {
margin-top: 8px;
margin-right: 8px;
}
}