mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-24 17:59:52 +00:00
minor(test): migrate persona spec (#17701)
* minor(test): migrate persona spec * remove persona cypress spec * address comments
This commit is contained in:
parent
35bed7138d
commit
b86f3d8ae7
@ -1,309 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
descriptionBox,
|
||||
interceptURL,
|
||||
toastNotification,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import { validateFormNameFieldInput } from '../../common/Utils/Form';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import { DELETE_TERM } from '../../constants/constants';
|
||||
import { PERSONA_DETAILS, USER_DETAILS } from '../../constants/EntityConstant';
|
||||
import { GlobalSettingOptions } from '../../constants/settings.constant';
|
||||
|
||||
const updatePersonaDisplayName = (displayName) => {
|
||||
interceptURL('PATCH', `/api/v1/personas/*`, 'updatePersona');
|
||||
|
||||
cy.get('[data-testid="manage-button"]').click();
|
||||
|
||||
cy.get(
|
||||
'[data-testid="manage-dropdown-list-container"] [data-testid="rename-button"]'
|
||||
).click();
|
||||
|
||||
cy.get('#name').should('be.disabled');
|
||||
cy.get('#displayName').should('not.be.disabled').clear();
|
||||
|
||||
cy.get('#displayName').type(displayName);
|
||||
|
||||
cy.get('[data-testid="save-button"]').click();
|
||||
verifyResponseStatusCode('@updatePersona', 200);
|
||||
};
|
||||
|
||||
describe('Persona operations', { tags: 'Settings' }, () => {
|
||||
const user = {
|
||||
details: {
|
||||
id: '',
|
||||
name: '',
|
||||
},
|
||||
};
|
||||
const userSearchText = `${USER_DETAILS.firstName}${USER_DETAILS.lastName}`;
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((data) => {
|
||||
const token = getToken(data);
|
||||
|
||||
// Create a new user
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/v1/users/signup`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: USER_DETAILS,
|
||||
}).then((response) => {
|
||||
user.details = response.body;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((data) => {
|
||||
const token = getToken(data);
|
||||
|
||||
// Delete created user
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/v1/users/${user.details.id}?hardDelete=true&recursive=false`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
|
||||
interceptURL('GET', '/api/v1/personas*', 'getPersonas');
|
||||
|
||||
cy.settingClick(GlobalSettingOptions.PERSONA);
|
||||
|
||||
verifyResponseStatusCode('@getPersonas', 200);
|
||||
});
|
||||
|
||||
it('Persona creation should work properly', () => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/users?limit=25&isBot=false',
|
||||
'getInitialUsers'
|
||||
);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/search/query?q=***%20AND%20isBot:false&from=0&size=25&index=user_search_index',
|
||||
'getUserSearch'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="add-persona-button"]').scrollIntoView().click();
|
||||
cy.get('[data-testid="name"]').clear().type(PERSONA_DETAILS.name);
|
||||
validateFormNameFieldInput({
|
||||
value: PERSONA_DETAILS.name,
|
||||
fieldName: 'Name',
|
||||
fieldSelector: '[data-testid="name"]',
|
||||
errorDivSelector: '#name_help',
|
||||
});
|
||||
cy.get('[data-testid="displayName"]')
|
||||
.clear()
|
||||
.type(PERSONA_DETAILS.displayName);
|
||||
cy.get(descriptionBox).type(PERSONA_DETAILS.description);
|
||||
cy.get('[data-testid="add-users"]').scrollIntoView().click();
|
||||
|
||||
verifyResponseStatusCode('@getInitialUsers', 200);
|
||||
|
||||
cy.get('[data-testid="searchbar"]').type(userSearchText);
|
||||
|
||||
verifyResponseStatusCode('@getUserSearch', 200);
|
||||
|
||||
cy.get(`.ant-popover [title="${userSearchText}"]`).click();
|
||||
cy.get('[data-testid="selectable-list-update-btn"]')
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
|
||||
interceptURL('POST', '/api/v1/personas', 'createPersona');
|
||||
|
||||
cy.get('.ant-modal-footer > .ant-btn-primary')
|
||||
.contains('Create')
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@createPersona', 201);
|
||||
|
||||
// Verify created persona details
|
||||
|
||||
cy.get('[data-testid="persona-details-card"] .ant-card-meta-title').should(
|
||||
'contain',
|
||||
PERSONA_DETAILS.displayName
|
||||
);
|
||||
cy.get(
|
||||
'[data-testid="persona-details-card"] .ant-card-meta-description'
|
||||
).should('contain', PERSONA_DETAILS.description);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/personas/name/${PERSONA_DETAILS.name}*`,
|
||||
'getPersonaDetails'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="persona-details-card"]')
|
||||
.contains(PERSONA_DETAILS.displayName)
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@getPersonaDetails', 200);
|
||||
|
||||
cy.get('[data-testid="entity-header-name"]').should(
|
||||
'contain',
|
||||
PERSONA_DETAILS.name
|
||||
);
|
||||
cy.get('[data-testid="entity-header-display-name"]').should(
|
||||
'contain',
|
||||
PERSONA_DETAILS.displayName
|
||||
);
|
||||
cy.get(
|
||||
'[data-testid="viewer-container"] [data-testid="markdown-parser"]'
|
||||
).should('contain', PERSONA_DETAILS.description);
|
||||
|
||||
cy.get(
|
||||
`[data-row-key="${user.details.name}"] [data-testid="${user.details.name}"]`
|
||||
).should('contain', user.details.name);
|
||||
});
|
||||
|
||||
it('Persona update description flow should work properly', () => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/personas/name/${PERSONA_DETAILS.name}*`,
|
||||
'getPersonaDetails'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="persona-details-card"]')
|
||||
.contains(PERSONA_DETAILS.displayName)
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@getPersonaDetails', 200);
|
||||
|
||||
cy.get('[data-testid="edit-description"]').click();
|
||||
|
||||
cy.get(`[data-testid="markdown-editor"] ${descriptionBox}`)
|
||||
.clear()
|
||||
.type('Updated description.');
|
||||
|
||||
interceptURL('PATCH', `/api/v1/personas/*`, 'updatePersona');
|
||||
|
||||
cy.get(`[data-testid="markdown-editor"] [data-testid="save"]`).click();
|
||||
|
||||
verifyResponseStatusCode('@updatePersona', 200);
|
||||
|
||||
cy.get(
|
||||
`[data-testid="viewer-container"] [data-testid="markdown-parser"]`
|
||||
).should('contain', 'Updated description.');
|
||||
});
|
||||
|
||||
it('Persona rename flow should work properly', () => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/personas/name/${PERSONA_DETAILS.name}*`,
|
||||
'getPersonaDetails'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="persona-details-card"]')
|
||||
.contains(PERSONA_DETAILS.displayName)
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@getPersonaDetails', 200);
|
||||
|
||||
updatePersonaDisplayName('Test Persona');
|
||||
|
||||
cy.get('[data-testid="entity-header-display-name"]').should(
|
||||
'contain',
|
||||
'Test Persona'
|
||||
);
|
||||
|
||||
updatePersonaDisplayName(PERSONA_DETAILS.displayName);
|
||||
|
||||
cy.get('[data-testid="entity-header-display-name"]').should(
|
||||
'contain',
|
||||
PERSONA_DETAILS.displayName
|
||||
);
|
||||
});
|
||||
|
||||
it('Remove users in persona should work properly', () => {
|
||||
// Remove user from the users tab
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/personas/name/${PERSONA_DETAILS.name}*`,
|
||||
'getPersonaDetails'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="persona-details-card"]')
|
||||
.contains(PERSONA_DETAILS.displayName)
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@getPersonaDetails', 200);
|
||||
|
||||
cy.get(
|
||||
`[data-row-key="${user.details.name}"] [data-testid="remove-user-btn"]`
|
||||
).click();
|
||||
|
||||
cy.get('[data-testid="remove-confirmation-modal"]').should(
|
||||
'contain',
|
||||
`Are you sure you want to remove ${user.details.name}?`
|
||||
);
|
||||
|
||||
interceptURL('PATCH', `/api/v1/personas/*`, 'updatePersona');
|
||||
|
||||
cy.get('[data-testid="remove-confirmation-modal"]')
|
||||
.contains('Confirm')
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@updatePersona', 200);
|
||||
});
|
||||
|
||||
it('Delete persona should work properly', () => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/personas/name/${PERSONA_DETAILS.name}*`,
|
||||
'getPersonaDetails'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="persona-details-card"]')
|
||||
.contains(PERSONA_DETAILS.displayName)
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@getPersonaDetails', 200);
|
||||
|
||||
cy.get('[data-testid="manage-button"]').click();
|
||||
|
||||
cy.get('[data-testid="delete-button-title"]').click();
|
||||
|
||||
cy.get('.ant-modal-header').should('contain', PERSONA_DETAILS.displayName);
|
||||
|
||||
cy.get(`[data-testid="hard-delete-option"]`).click();
|
||||
|
||||
cy.get('[data-testid="confirm-button"]').should('be.disabled');
|
||||
cy.get('[data-testid="confirmation-text-input"]').type(DELETE_TERM);
|
||||
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
`/api/v1/personas/*?hardDelete=true&recursive=false`,
|
||||
`deletePersona`
|
||||
);
|
||||
cy.get('[data-testid="confirm-button"]').should('not.be.disabled');
|
||||
cy.get('[data-testid="confirm-button"]').click();
|
||||
verifyResponseStatusCode(`@deletePersona`, 200);
|
||||
|
||||
toastNotification(`"${PERSONA_DETAILS.displayName}" deleted successfully!`);
|
||||
});
|
||||
});
|
@ -30,3 +30,5 @@ export const NAME_MIN_MAX_LENGTH_VALIDATION_ERROR =
|
||||
|
||||
export const NAME_MAX_LENGTH_VALIDATION_ERROR =
|
||||
'Name size must be between 1 and 128';
|
||||
|
||||
export const DELETE_TERM = 'DELETE';
|
||||
|
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import test, { expect } from '@playwright/test';
|
||||
|
||||
import { DELETE_TERM } from '../../constant/common';
|
||||
import { GlobalSettingOptions } from '../../constant/settings';
|
||||
import { UserClass } from '../../support/user/UserClass';
|
||||
import {
|
||||
createNewPage,
|
||||
descriptionBox,
|
||||
redirectToHomePage,
|
||||
toastNotification,
|
||||
uuid,
|
||||
} from '../../utils/common';
|
||||
import { validateFormNameFieldInput } from '../../utils/form';
|
||||
import { updatePersonaDisplayName } from '../../utils/persona';
|
||||
import { settingClick } from '../../utils/sidebar';
|
||||
|
||||
const PERSONA_DETAILS = {
|
||||
name: `persona-with-%-${uuid()}`,
|
||||
displayName: `persona ${uuid()}`,
|
||||
description: `Persona description ${uuid()}.`,
|
||||
};
|
||||
|
||||
// use the admin user to login
|
||||
test.use({
|
||||
storageState: 'playwright/.auth/admin.json',
|
||||
});
|
||||
|
||||
test.describe.serial('Persona operations', () => {
|
||||
const user = new UserClass();
|
||||
|
||||
test.beforeAll('pre-requisites', async ({ browser }) => {
|
||||
const { apiContext, afterAction } = await createNewPage(browser);
|
||||
await user.create(apiContext);
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test.afterAll('cleanup', async ({ browser }) => {
|
||||
const { apiContext, afterAction } = await createNewPage(browser);
|
||||
|
||||
await user.delete(apiContext);
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await redirectToHomePage(page);
|
||||
await settingClick(page, GlobalSettingOptions.PERSONA);
|
||||
});
|
||||
|
||||
test('Persona creation should work properly', async ({ page }) => {
|
||||
await page.getByTestId('add-persona-button').click();
|
||||
|
||||
await validateFormNameFieldInput({
|
||||
page,
|
||||
value: PERSONA_DETAILS.name,
|
||||
fieldName: 'Name',
|
||||
fieldSelector: '[data-testid="name"]',
|
||||
errorDivSelector: '#name_help',
|
||||
});
|
||||
|
||||
await page.getByTestId('displayName').fill(PERSONA_DETAILS.displayName);
|
||||
|
||||
await page.locator(descriptionBox).fill(PERSONA_DETAILS.description);
|
||||
await page.getByTestId('add-users').click();
|
||||
|
||||
const searchUser = page.waitForResponse(
|
||||
`/api/v1/search/query?q=*${encodeURIComponent(
|
||||
user.responseData.displayName
|
||||
)}*`
|
||||
);
|
||||
await page.getByTestId('searchbar').fill(user.responseData.displayName);
|
||||
|
||||
await searchUser;
|
||||
await page.click(`.ant-popover [title="${user.responseData.displayName}"]`);
|
||||
await page.getByTestId('selectable-list-update-btn').click();
|
||||
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
// Verify created persona details
|
||||
|
||||
await expect(
|
||||
page
|
||||
.getByTestId('persona-details-card')
|
||||
.getByText(PERSONA_DETAILS.displayName)
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
page
|
||||
.getByTestId('persona-details-card')
|
||||
.getByText(PERSONA_DETAILS.description)
|
||||
).toBeVisible();
|
||||
|
||||
const personaResponse = page.waitForResponse(
|
||||
`/api/v1/personas/name/${encodeURIComponent(
|
||||
PERSONA_DETAILS.name
|
||||
)}?fields=users`
|
||||
);
|
||||
|
||||
await page
|
||||
.locator('[data-testid="persona-details-card"]')
|
||||
.getByText(PERSONA_DETAILS.displayName)
|
||||
.click();
|
||||
|
||||
await personaResponse;
|
||||
|
||||
await page.waitForSelector('[data-testid="entity-header-name"]', {
|
||||
state: 'visible',
|
||||
});
|
||||
|
||||
await expect(page.getByTestId('entity-header-name')).toContainText(
|
||||
PERSONA_DETAILS.name
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('entity-header-display-name')).toContainText(
|
||||
PERSONA_DETAILS.displayName
|
||||
);
|
||||
|
||||
await expect(
|
||||
page.locator(
|
||||
'[data-testid="viewer-container"] [data-testid="markdown-parser"]'
|
||||
)
|
||||
).toContainText(PERSONA_DETAILS.description);
|
||||
|
||||
await expect(page.getByTestId(user.responseData.name)).toContainText(
|
||||
user.responseData.name
|
||||
);
|
||||
});
|
||||
|
||||
test('Persona update description flow should work properly', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page
|
||||
.locator('[data-testid="persona-details-card"]')
|
||||
.getByText(PERSONA_DETAILS.displayName)
|
||||
.click();
|
||||
|
||||
await page.getByTestId('edit-description').click();
|
||||
|
||||
await page
|
||||
.locator(`[data-testid="markdown-editor"] ${descriptionBox}`)
|
||||
.clear();
|
||||
|
||||
await page
|
||||
.locator(`[data-testid="markdown-editor"] ${descriptionBox}`)
|
||||
.fill('Updated description.');
|
||||
|
||||
await page
|
||||
.locator(`[data-testid="markdown-editor"] [data-testid="save"]`)
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.locator(
|
||||
`[data-testid="viewer-container"] [data-testid="markdown-parser"]`
|
||||
)
|
||||
).toContainText('Updated description.');
|
||||
});
|
||||
|
||||
test('Persona rename flow should work properly', async ({ page }) => {
|
||||
await page
|
||||
.locator('[data-testid="persona-details-card"]')
|
||||
.getByText(PERSONA_DETAILS.displayName)
|
||||
|
||||
.click();
|
||||
|
||||
await updatePersonaDisplayName({ page, displayName: 'Test Persona' });
|
||||
|
||||
await expect(page.getByTestId('entity-header-display-name')).toContainText(
|
||||
'Test Persona'
|
||||
);
|
||||
|
||||
await updatePersonaDisplayName({
|
||||
page,
|
||||
displayName: PERSONA_DETAILS.displayName,
|
||||
});
|
||||
|
||||
await expect(page.getByTestId('entity-header-display-name')).toContainText(
|
||||
PERSONA_DETAILS.displayName
|
||||
);
|
||||
});
|
||||
|
||||
test('Remove users in persona should work properly', async ({ page }) => {
|
||||
await page
|
||||
.locator('[data-testid="persona-details-card"]')
|
||||
.getByText(PERSONA_DETAILS.displayName)
|
||||
.click();
|
||||
|
||||
await page
|
||||
.locator(
|
||||
`[data-row-key="${user.responseData.name}"] [data-testid="remove-user-btn"]`
|
||||
)
|
||||
.click();
|
||||
|
||||
await expect(
|
||||
page.locator('[data-testid="remove-confirmation-modal"]')
|
||||
).toContainText(
|
||||
`Are you sure you want to remove ${user.responseData.name}?`
|
||||
);
|
||||
|
||||
const updateResponse = page.waitForResponse(`/api/v1/personas/*`);
|
||||
|
||||
await page
|
||||
.locator('[data-testid="remove-confirmation-modal"]')
|
||||
.getByText('Confirm')
|
||||
.click();
|
||||
|
||||
await updateResponse;
|
||||
});
|
||||
|
||||
test('Delete persona should work properly', async ({ page }) => {
|
||||
await page
|
||||
.locator('[data-testid="persona-details-card"]')
|
||||
.getByText(PERSONA_DETAILS.displayName)
|
||||
.click();
|
||||
|
||||
await page.click('[data-testid="manage-button"]');
|
||||
|
||||
await page.click('[data-testid="delete-button-title"]');
|
||||
|
||||
await expect(page.locator('.ant-modal-header')).toContainText(
|
||||
PERSONA_DETAILS.displayName
|
||||
);
|
||||
|
||||
await page.click(`[data-testid="hard-delete-option"]`);
|
||||
|
||||
await expect(page.locator('[data-testid="confirm-button"]')).toBeDisabled();
|
||||
|
||||
await page
|
||||
.locator('[data-testid="confirmation-text-input"]')
|
||||
.fill(DELETE_TERM);
|
||||
|
||||
const deleteResponse = page.waitForResponse(
|
||||
`/api/v1/personas/*?hardDelete=true&recursive=false`
|
||||
);
|
||||
|
||||
await expect(
|
||||
page.locator('[data-testid="confirm-button"]')
|
||||
).not.toBeDisabled();
|
||||
|
||||
await page.click('[data-testid="confirm-button"]');
|
||||
await deleteResponse;
|
||||
|
||||
await toastNotification(
|
||||
page,
|
||||
`"${PERSONA_DETAILS.displayName}" deleted successfully!`
|
||||
);
|
||||
});
|
||||
});
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { expect, Page } from '@playwright/test';
|
||||
|
||||
export const updatePersonaDisplayName = async ({
|
||||
page,
|
||||
displayName,
|
||||
}: {
|
||||
page: Page;
|
||||
displayName: string;
|
||||
}) => {
|
||||
await page.click('[data-testid="manage-button"]');
|
||||
|
||||
await page.click(
|
||||
'[data-testid="manage-dropdown-list-container"] [data-testid="rename-button"]'
|
||||
);
|
||||
|
||||
await page.waitForSelector('#name', { state: 'visible' });
|
||||
|
||||
await expect(page.locator('#name')).toBeDisabled();
|
||||
|
||||
await page.waitForSelector('#displayName', { state: 'visible' });
|
||||
await page.fill('#displayName', displayName);
|
||||
|
||||
await page.click('[data-testid="save-button"]');
|
||||
};
|
@ -139,7 +139,7 @@ export const UsersTab = ({ users, onRemoveUser }: UsersTabProps) => {
|
||||
),
|
||||
}}
|
||||
pagination={false}
|
||||
rowKey="fullyQualifiedName"
|
||||
rowKey="name"
|
||||
size="small"
|
||||
/>
|
||||
{Boolean(removeUserDetails?.state) && (
|
||||
|
Loading…
x
Reference in New Issue
Block a user