mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2026-01-05 12:07:10 +00:00
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:
parent
1b930fa6f7
commit
51bf8cd754
@ -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',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -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"]')
|
||||
|
||||
@ -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 |
@ -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 |
@ -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 |
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -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,
|
||||
}}
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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} />
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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>
|
||||
</>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 && (
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -28,4 +28,5 @@ export type TagsContainerProps = {
|
||||
containerClass?: string;
|
||||
onSelectionChange?: (selectedTags: Array<EntityTags>) => void;
|
||||
onCancel?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||
onAddButtonClick?: () => void;
|
||||
};
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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 || []}
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user