mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-23 17:30:35 +00:00
ui : supported delete functionality for sample data (#12871)
This commit is contained in:
parent
795294c87f
commit
c6d03a6eaf
@ -1,3 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
<path fill="#37352F" d="M20.184 2.813H16.67v-.704C16.669.946 15.722 0 14.559 0H8.934C7.771 0 6.825.946 6.825 2.11v.703H3.309c-1.163 0-2.109.946-2.109 2.109 0 .934.61 1.728 1.453 2.004l1.254 15.14A2.122 2.122 0 0 0 6.01 24h11.474c1.089 0 2.012-.85 2.102-1.935L20.84 6.926a2.113 2.113 0 0 0 1.454-2.004c0-1.163-.947-2.11-2.11-2.11ZM8.231 2.109c0-.387.316-.703.703-.703h5.625c.388 0 .704.316.704.703v.704H8.23v-.704Zm9.954 19.84a.707.707 0 0 1-.7.645H6.01a.707.707 0 0 1-.701-.645L4.073 7.031h15.348L18.184 21.95Zm2-16.324H3.308a.704.704 0 0 1 0-1.406h16.875a.704.704 0 0 1 0 1.406Z"/><path fill="#37352F" d="M9.186 20.44 8.483 9.098a.704.704 0 0 0-1.404.087l.704 11.344a.703.703 0 1 0 1.403-.087ZM12 8.438a.703.703 0 0 0-.703.703v11.343a.703.703 0 0 0 1.406 0V9.141A.703.703 0 0 0 12 8.437ZM16.262 8.439a.704.704 0 0 0-.745.658l-.703 11.344a.703.703 0 0 0 1.403.087l.704-11.344a.703.703 0 0 0-.659-.745Z"/>
|
<path fill="currentColor" d="M20.184 2.813H16.67v-.704C16.669.946 15.722 0 14.559 0H8.934C7.771 0 6.825.946 6.825 2.11v.703H3.309c-1.163 0-2.109.946-2.109 2.109 0 .934.61 1.728 1.453 2.004l1.254 15.14A2.122 2.122 0 0 0 6.01 24h11.474c1.089 0 2.012-.85 2.102-1.935L20.84 6.926a2.113 2.113 0 0 0 1.454-2.004c0-1.163-.947-2.11-2.11-2.11ZM8.231 2.109c0-.387.316-.703.703-.703h5.625c.388 0 .704.316.704.703v.704H8.23v-.704Zm9.954 19.84a.707.707 0 0 1-.7.645H6.01a.707.707 0 0 1-.701-.645L4.073 7.031h15.348L18.184 21.95Zm2-16.324H3.308a.704.704 0 0 1 0-1.406h16.875a.704.704 0 0 1 0 1.406Z"/><path fill="currentColor" d="M9.186 20.44 8.483 9.098a.704.704 0 0 0-1.404.087l.704 11.344a.703.703 0 1 0 1.403-.087ZM12 8.438a.703.703 0 0 0-.703.703v11.343a.703.703 0 0 0 1.406 0V9.141A.703.703 0 0 0 12 8.437ZM16.262 8.439a.704.704 0 0 0-.745.658l-.703 11.344a.703.703 0 0 0 1.403.087l.704-11.344a.703.703 0 0 0-.659-.745Z"/>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 984 B After Width: | Height: | Size: 994 B |
@ -11,19 +11,39 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Space, Table as AntdTable, Typography } from 'antd';
|
import {
|
||||||
|
Button,
|
||||||
|
Dropdown,
|
||||||
|
Space,
|
||||||
|
Table as AntdTable,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
} from 'antd';
|
||||||
|
import { ItemType } from 'antd/lib/menu/hooks/useItems';
|
||||||
|
import AppState from 'AppState';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { ManageButtonItemLabel } from 'components/common/ManageButtonContentItem/ManageButtonContentItem.component';
|
||||||
|
import EntityDeleteModal from 'components/Modals/EntityDeleteModal/EntityDeleteModal';
|
||||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||||
|
import { DROPDOWN_ICON_SIZE_PROPS } from 'constants/ManageButton.constants';
|
||||||
import { mockDatasetData } from 'constants/mockTourData.constants';
|
import { mockDatasetData } from 'constants/mockTourData.constants';
|
||||||
|
import { LOADING_STATE } from 'enums/common.enum';
|
||||||
|
import { EntityType } from 'enums/entity.enum';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { isEmpty, lowerCase } from 'lodash';
|
import { isEmpty, lowerCase } from 'lodash';
|
||||||
import React, { useEffect, useState } from 'react';
|
import { observer } from 'mobx-react';
|
||||||
import { getSampleDataByTableId } from 'rest/tableAPI';
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
import {
|
||||||
|
deleteSampleDataByTableId,
|
||||||
|
getSampleDataByTableId,
|
||||||
|
} from 'rest/tableAPI';
|
||||||
|
import { ReactComponent as IconDelete } from '../../assets/svg/ic-delete.svg';
|
||||||
|
import { ReactComponent as IconDropdown } from '../../assets/svg/menu.svg';
|
||||||
import { WORKFLOWS_PROFILER_DOCS } from '../../constants/docs.constants';
|
import { WORKFLOWS_PROFILER_DOCS } from '../../constants/docs.constants';
|
||||||
import { Table } from '../../generated/entity/data/table';
|
import { Table } from '../../generated/entity/data/table';
|
||||||
import { withLoader } from '../../hoc/withLoader';
|
import { withLoader } from '../../hoc/withLoader';
|
||||||
import { Transi18next } from '../../utils/CommonUtils';
|
import { getEntityDeleteMessage, Transi18next } from '../../utils/CommonUtils';
|
||||||
import { showErrorToast } from '../../utils/ToastUtils';
|
import { showErrorToast } from '../../utils/ToastUtils';
|
||||||
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import Loader from '../Loader/Loader';
|
import Loader from '../Loader/Loader';
|
||||||
@ -34,11 +54,38 @@ import {
|
|||||||
SampleDataType,
|
SampleDataType,
|
||||||
} from './sample.interface';
|
} from './sample.interface';
|
||||||
import './SampleDataTable.style.less';
|
import './SampleDataTable.style.less';
|
||||||
const SampleDataTable = ({ isTableDeleted, tableId }: SampleDataProps) => {
|
|
||||||
|
const SampleDataTable = ({
|
||||||
|
isTableDeleted,
|
||||||
|
tableId,
|
||||||
|
ownerId,
|
||||||
|
permissions,
|
||||||
|
}: SampleDataProps) => {
|
||||||
const { isTourPage } = useTourProvider();
|
const { isTourPage } = useTourProvider();
|
||||||
|
|
||||||
const [sampleData, setSampleData] = useState<SampleData>();
|
const [sampleData, setSampleData] = useState<SampleData>();
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<boolean>(false);
|
||||||
|
const [deleteState, setDeleteState] = useState(LOADING_STATE.INITIAL);
|
||||||
|
const [showActions, setShowActions] = useState(false);
|
||||||
|
|
||||||
|
const currentUser = useMemo(
|
||||||
|
() => AppState.getCurrentUserDetails(),
|
||||||
|
[AppState.userDetails]
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasPermission = useMemo(
|
||||||
|
() =>
|
||||||
|
permissions.EditAll ||
|
||||||
|
permissions.EditSampleData ||
|
||||||
|
currentUser?.id === ownerId,
|
||||||
|
[ownerId, permissions, currentUser]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDeleteModal = useCallback(
|
||||||
|
() => setIsDeleteModalOpen((prev) => !prev),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const getSampleDataWithType = (table: Table) => {
|
const getSampleDataWithType = (table: Table) => {
|
||||||
const { sampleData, columns } = table;
|
const { sampleData, columns } = table;
|
||||||
@ -91,6 +138,52 @@ const SampleDataTable = ({ isTableDeleted, tableId }: SampleDataProps) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDeleteSampleData = async () => {
|
||||||
|
setDeleteState(LOADING_STATE.WAITING);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await deleteSampleDataByTableId(tableId);
|
||||||
|
handleDeleteModal();
|
||||||
|
fetchSampleData();
|
||||||
|
} catch (error) {
|
||||||
|
showErrorToast(
|
||||||
|
error as AxiosError,
|
||||||
|
t('server.delete-entity-error', {
|
||||||
|
entity: t('label.sample-data'),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setDeleteState(LOADING_STATE.SUCCESS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const manageButtonContent: ItemType[] = [
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<ManageButtonItemLabel
|
||||||
|
description={t('message.delete-entity-type-action-description', {
|
||||||
|
entityType: t('label.sample-data'),
|
||||||
|
})}
|
||||||
|
icon={
|
||||||
|
<IconDelete
|
||||||
|
className="m-t-xss"
|
||||||
|
{...DROPDOWN_ICON_SIZE_PROPS}
|
||||||
|
name="Delete"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
id="delete-button"
|
||||||
|
name={t('label.delete')}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
key: 'delete-button',
|
||||||
|
onClick: (e) => {
|
||||||
|
e.domEvent.stopPropagation();
|
||||||
|
setShowActions(false);
|
||||||
|
handleDeleteModal();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
if (!isTableDeleted && tableId && !isTourPage) {
|
if (!isTableDeleted && tableId && !isTourPage) {
|
||||||
@ -114,7 +207,7 @@ const SampleDataTable = ({ isTableDeleted, tableId }: SampleDataProps) => {
|
|||||||
|
|
||||||
if (isEmpty(sampleData?.rows) && isEmpty(sampleData?.columns)) {
|
if (isEmpty(sampleData?.rows) && isEmpty(sampleData?.columns)) {
|
||||||
return (
|
return (
|
||||||
<ErrorPlaceHolder>
|
<ErrorPlaceHolder className="error-placeholder">
|
||||||
<Typography.Paragraph>
|
<Typography.Paragraph>
|
||||||
<Transi18next
|
<Transi18next
|
||||||
i18nKey="message.view-sample-data-entity"
|
i18nKey="message.view-sample-data-entity"
|
||||||
@ -142,6 +235,30 @@ const SampleDataTable = ({ isTableDeleted, tableId }: SampleDataProps) => {
|
|||||||
})}
|
})}
|
||||||
data-testid="sample-data"
|
data-testid="sample-data"
|
||||||
id="sampleDataDetails">
|
id="sampleDataDetails">
|
||||||
|
<Space className="m-b-md justify-end w-full">
|
||||||
|
{hasPermission && (
|
||||||
|
<Dropdown
|
||||||
|
menu={{
|
||||||
|
items: manageButtonContent,
|
||||||
|
}}
|
||||||
|
open={showActions}
|
||||||
|
overlayClassName="manage-dropdown-list-container"
|
||||||
|
overlayStyle={{ width: '350px' }}
|
||||||
|
placement="bottomRight"
|
||||||
|
trigger={['click']}
|
||||||
|
onOpenChange={setShowActions}>
|
||||||
|
<Tooltip placement="right">
|
||||||
|
<Button
|
||||||
|
className="flex-center px-1.5"
|
||||||
|
data-testid="sample-data-manage-button"
|
||||||
|
onClick={() => setShowActions(true)}>
|
||||||
|
<IconDropdown className="anticon self-center " />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Dropdown>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
|
||||||
<AntdTable
|
<AntdTable
|
||||||
bordered
|
bordered
|
||||||
columns={sampleData?.columns}
|
columns={sampleData?.columns}
|
||||||
@ -152,8 +269,20 @@ const SampleDataTable = ({ isTableDeleted, tableId }: SampleDataProps) => {
|
|||||||
scroll={{ x: true }}
|
scroll={{ x: true }}
|
||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{isDeleteModalOpen && (
|
||||||
|
<EntityDeleteModal
|
||||||
|
bodyText={getEntityDeleteMessage(t('label.sample-data'), '')}
|
||||||
|
entityName={t('label.sample-data')}
|
||||||
|
entityType={EntityType.SAMPLE_DATA}
|
||||||
|
loadingState={deleteState}
|
||||||
|
visible={isDeleteModalOpen}
|
||||||
|
onCancel={handleDeleteModal}
|
||||||
|
onConfirm={handleDeleteSampleData}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withLoader<SampleDataProps>(SampleDataTable);
|
export default withLoader<SampleDataProps>(observer(SampleDataTable));
|
||||||
|
@ -11,11 +11,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@border-color: #e5e7eb;
|
.error-placeholder {
|
||||||
|
height: calc(100vh - 255px);
|
||||||
.no-data-placeholder {
|
|
||||||
width: 100%;
|
|
||||||
padding: 32px;
|
|
||||||
border: 1px solid @border-color;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { act, render, screen } from '@testing-library/react';
|
import { act, render, screen } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { OperationPermission } from 'components/PermissionProvider/PermissionProvider.interface';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { getSampleDataByTableId } from 'rest/tableAPI';
|
import { getSampleDataByTableId } from 'rest/tableAPI';
|
||||||
import { MOCK_TABLE } from '../../mocks/TableData.mock';
|
import { MOCK_TABLE } from '../../mocks/TableData.mock';
|
||||||
import SampleDataTable from './SampleDataTable.component';
|
import SampleDataTable from './SampleDataTable.component';
|
||||||
|
|
||||||
|
const mockProps = {
|
||||||
|
tableId: 'id',
|
||||||
|
ownerId: 'ownerId',
|
||||||
|
permissions: {
|
||||||
|
Create: true,
|
||||||
|
Delete: true,
|
||||||
|
ViewAll: true,
|
||||||
|
EditAll: true,
|
||||||
|
EditDescription: true,
|
||||||
|
EditDisplayName: true,
|
||||||
|
EditCustomFields: true,
|
||||||
|
} as OperationPermission,
|
||||||
|
};
|
||||||
|
|
||||||
jest.mock('react-router-dom', () => ({
|
jest.mock('react-router-dom', () => ({
|
||||||
Link: jest.fn().mockImplementation(({ children }) => <span>{children}</span>),
|
Link: jest.fn().mockImplementation(({ children }) => <span>{children}</span>),
|
||||||
useLocation: jest.fn().mockImplementation(() => ({ pathname: 'test' })),
|
useLocation: jest.fn().mockImplementation(() => ({ pathname: 'test' })),
|
||||||
@ -36,6 +52,10 @@ jest.mock('../common/error-with-placeholder/ErrorPlaceHolder', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.mock('components/Modals/EntityDeleteModal/EntityDeleteModal', () => {
|
||||||
|
return jest.fn().mockReturnValue(<p>EntityDeleteModal</p>);
|
||||||
|
});
|
||||||
|
|
||||||
describe('Test SampleDataTable Component', () => {
|
describe('Test SampleDataTable Component', () => {
|
||||||
it('Render error placeholder if the columns passed are empty', async () => {
|
it('Render error placeholder if the columns passed are empty', async () => {
|
||||||
(getSampleDataByTableId as jest.Mock).mockImplementationOnce(() =>
|
(getSampleDataByTableId as jest.Mock).mockImplementationOnce(() =>
|
||||||
@ -43,7 +63,7 @@ describe('Test SampleDataTable Component', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(<SampleDataTable tableId="id" />);
|
render(<SampleDataTable {...mockProps} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
const errorPlaceholder = screen.getByTestId('error-placeholder');
|
const errorPlaceholder = screen.getByTestId('error-placeholder');
|
||||||
@ -53,11 +73,51 @@ describe('Test SampleDataTable Component', () => {
|
|||||||
|
|
||||||
it('Renders all the data that was sent to the component', async () => {
|
it('Renders all the data that was sent to the component', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(<SampleDataTable tableId="id" />);
|
render(<SampleDataTable {...mockProps} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const deleteButton = screen.getByTestId('sample-data-manage-button');
|
||||||
const table = screen.getByTestId('sample-data-table');
|
const table = screen.getByTestId('sample-data-table');
|
||||||
|
|
||||||
|
expect(deleteButton).toBeInTheDocument();
|
||||||
expect(table).toBeInTheDocument();
|
expect(table).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Sample Data menu dropdown should not be present when not have permission', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(
|
||||||
|
<SampleDataTable
|
||||||
|
{...mockProps}
|
||||||
|
permissions={{
|
||||||
|
...mockProps.permissions,
|
||||||
|
EditAll: false,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
screen.queryByTestId('sample-data-manage-button')
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Render Delete Modal when delete sample data button is clicked', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
render(<SampleDataTable {...mockProps} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
const dropdown = screen.getByTestId('sample-data-manage-button');
|
||||||
|
|
||||||
|
expect(dropdown).toBeInTheDocument();
|
||||||
|
|
||||||
|
userEvent.click(dropdown);
|
||||||
|
|
||||||
|
const deleteButton = screen.getByTestId('delete-button-details-container');
|
||||||
|
|
||||||
|
userEvent.click(deleteButton);
|
||||||
|
|
||||||
|
const deleteModal = screen.getByText('EntityDeleteModal');
|
||||||
|
|
||||||
|
expect(deleteModal).toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { ColumnsType } from 'antd/lib/table';
|
import { ColumnsType } from 'antd/lib/table';
|
||||||
|
import { OperationPermission } from 'components/PermissionProvider/PermissionProvider.interface';
|
||||||
|
|
||||||
export type SampleDataType =
|
export type SampleDataType =
|
||||||
| string
|
| string
|
||||||
@ -29,4 +30,6 @@ export interface SampleData {
|
|||||||
export interface SampleDataProps {
|
export interface SampleDataProps {
|
||||||
isTableDeleted?: boolean;
|
isTableDeleted?: boolean;
|
||||||
tableId: string;
|
tableId: string;
|
||||||
|
ownerId: string;
|
||||||
|
permissions: OperationPermission;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Popover } from 'antd';
|
import { Button, Popover, Space } from 'antd';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import React, {
|
import React, {
|
||||||
@ -25,11 +25,12 @@ import { useHistory } from 'react-router-dom';
|
|||||||
import { getUserByName } from 'rest/userAPI';
|
import { getUserByName } from 'rest/userAPI';
|
||||||
import { getEntityName } from 'utils/EntityUtils';
|
import { getEntityName } from 'utils/EntityUtils';
|
||||||
import AppState from '../../../AppState';
|
import AppState from '../../../AppState';
|
||||||
|
import { ReactComponent as IconTeams } from '../../../assets/svg/teams-grey.svg';
|
||||||
|
import { ReactComponent as IconUsers } from '../../../assets/svg/user.svg';
|
||||||
import { getUserPath, TERM_ADMIN } from '../../../constants/constants';
|
import { getUserPath, TERM_ADMIN } from '../../../constants/constants';
|
||||||
import { User } from '../../../generated/entity/teams/user';
|
import { User } from '../../../generated/entity/teams/user';
|
||||||
import { EntityReference } from '../../../generated/type/entityReference';
|
import { EntityReference } from '../../../generated/type/entityReference';
|
||||||
import { getNonDeletedTeams } from '../../../utils/CommonUtils';
|
import { getNonDeletedTeams } from '../../../utils/CommonUtils';
|
||||||
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
|
|
||||||
import Loader from '../../Loader/Loader';
|
import Loader from '../../Loader/Loader';
|
||||||
import ProfilePicture from '../ProfilePicture/ProfilePicture';
|
import ProfilePicture from '../ProfilePicture/ProfilePicture';
|
||||||
|
|
||||||
@ -44,9 +45,9 @@ const UserPopOverCard: FC<Props> = ({ children, userName, type = 'user' }) => {
|
|||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
const userdetails = AppState.userDataProfiles[userName];
|
const userDetails = AppState.userDataProfiles[userName];
|
||||||
if (userdetails) {
|
if (userDetails) {
|
||||||
setUserData(userdetails);
|
setUserData(userDetails);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
} else {
|
} else {
|
||||||
if (type === 'user') {
|
if (type === 'user') {
|
||||||
@ -68,21 +69,24 @@ const UserPopOverCard: FC<Props> = ({ children, userName, type = 'user' }) => {
|
|||||||
const teams = getNonDeletedTeams(userData.teams ?? []);
|
const teams = getNonDeletedTeams(userData.teams ?? []);
|
||||||
|
|
||||||
return teams?.length ? (
|
return teams?.length ? (
|
||||||
<p className="m-t-xs">
|
<div className="m-t-xs">
|
||||||
<SVGIcons alt="icon" className="w-4" icon={Icons.TEAMS_GREY} />
|
<p className="d-flex items-center">
|
||||||
<span className="m-r-xs m-l-xss align-middle font-medium">
|
<IconTeams height={16} width={16} />
|
||||||
{t('label.team-plural')}
|
<span className="m-r-xs m-l-xss align-middle font-medium">
|
||||||
</span>
|
{t('label.team-plural')}
|
||||||
<span className="d-flex flex-wrap m-t-xss">
|
</span>
|
||||||
{teams.map((team, i) => (
|
</p>
|
||||||
|
|
||||||
|
<p className="d-flex flex-wrap m-t-xss">
|
||||||
|
{teams.map((team) => (
|
||||||
<span
|
<span
|
||||||
className="bg-grey rounded-4 p-x-xs text-grey-body text-xs"
|
className="bg-grey rounded-4 p-x-xs text-grey-body text-xs m-b-xss"
|
||||||
key={i}>
|
key={team.id}>
|
||||||
{team?.displayName ?? team?.name}
|
{team?.displayName ?? team?.name}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</span>
|
</p>
|
||||||
</p>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,24 +95,29 @@ const UserPopOverCard: FC<Props> = ({ children, userName, type = 'user' }) => {
|
|||||||
const isAdmin = userData?.isAdmin;
|
const isAdmin = userData?.isAdmin;
|
||||||
|
|
||||||
return roles?.length ? (
|
return roles?.length ? (
|
||||||
<p className="m-t-xs">
|
<div className="m-t-xs">
|
||||||
<SVGIcons alt="icon" className="w-4" icon={Icons.USERS} />
|
<p className="d-flex items-center">
|
||||||
<span className="m-r-xs m-l-xss align-middle font-medium">
|
<IconUsers height={16} width={16} />
|
||||||
{t('label.role-plural')}
|
<span className="m-r-xs m-l-xss align-middle font-medium">
|
||||||
</span>
|
{t('label.role-plural')}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
<span className="d-flex flex-wrap m-t-xss">
|
<span className="d-flex flex-wrap m-t-xss">
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<span className="bg-grey rounded-4 p-x-xs text-xs">
|
<span className="bg-grey rounded-4 p-x-xs text-xs m-b-xss">
|
||||||
{TERM_ADMIN}
|
{TERM_ADMIN}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{roles.map((role, i) => (
|
{roles.map((role) => (
|
||||||
<span className="bg-grey rounded-4 p-x-xs text-xs" key={i}>
|
<span
|
||||||
|
className="bg-grey rounded-4 p-x-xs text-xs m-b-xss"
|
||||||
|
key={role.id}>
|
||||||
{role?.displayName ?? role?.name}
|
{role?.displayName ?? role?.name}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -117,25 +126,24 @@ const UserPopOverCard: FC<Props> = ({ children, userName, type = 'user' }) => {
|
|||||||
const displayName = getEntityName(userData as unknown as EntityReference);
|
const displayName = getEntityName(userData as unknown as EntityReference);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="d-flex">
|
<Space align="center">
|
||||||
<div className="m-r-xs">
|
<ProfilePicture id="" name={userName} width="24" />
|
||||||
<ProfilePicture id="" name={userName} width="24" />
|
|
||||||
</div>
|
|
||||||
<div className="self-center">
|
<div className="self-center">
|
||||||
<button
|
<Button
|
||||||
className="text-info"
|
className="text-info p-0"
|
||||||
|
type="link"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onTitleClickHandler(getUserPath(name));
|
onTitleClickHandler(getUserPath(name));
|
||||||
}}>
|
}}>
|
||||||
<span className="font-medium m-r-xs">{displayName}</span>
|
<span className="font-medium m-r-xs">{displayName}</span>
|
||||||
</button>
|
</Button>
|
||||||
{displayName !== name ? (
|
{displayName !== name ? (
|
||||||
<span className="text-grey-muted">{name}</span>
|
<span className="text-grey-muted">{name}</span>
|
||||||
) : null}
|
) : null}
|
||||||
{isEmpty(userData) && <span>{userName}</span>}
|
{isEmpty(userData) && <span>{userName}</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Space>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ export enum EntityType {
|
|||||||
SUBSCRIPTION = 'subscription',
|
SUBSCRIPTION = 'subscription',
|
||||||
USER_NAME = 'username',
|
USER_NAME = 'username',
|
||||||
CHART = 'chart',
|
CHART = 'chart',
|
||||||
|
SAMPLE_DATA = 'sampleData',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AssetsType {
|
export enum AssetsType {
|
||||||
|
@ -563,6 +563,8 @@ const TableDetailsPageV1 = () => {
|
|||||||
) : (
|
) : (
|
||||||
<SampleDataTableComponent
|
<SampleDataTableComponent
|
||||||
isTableDeleted={tableDetails?.deleted}
|
isTableDeleted={tableDetails?.deleted}
|
||||||
|
ownerId={tableDetails?.owner?.id ?? ''}
|
||||||
|
permissions={tablePermissions}
|
||||||
tableId={tableDetails?.id ?? ''}
|
tableId={tableDetails?.id ?? ''}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
@ -246,3 +246,7 @@ export const getTableList = async (params?: TableListParams) => {
|
|||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteSampleDataByTableId = async (id: string) => {
|
||||||
|
return await APIClient.delete<Table>(`/tables/${id}/sampleData`);
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user