Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { SsoProviderTableView } from '@/components/auth0/my-organization/sso-pro
import * as useConfigModule from '@/hooks/my-organization/use-config';
import * as useIdpConfigModule from '@/hooks/my-organization/use-idp-config';
import * as useCoreClientModule from '@/hooks/shared/use-core-client';
import { createMockSsoProviderTableHandler, createMockSsoProviderTableLogic } from '@/tests/utils';
import { createMockSsoProviderTableView } from '@/tests/utils';
import { createMockUseConfig } from '@/tests/utils/__mocks__/my-organization/config/config.mocks';
import { createMockIdentityProvider } from '@/tests/utils/__mocks__/my-organization/domain-management/domain.mocks';
import { createMockUseIdpConfig } from '@/tests/utils/__mocks__/my-organization/idp-management/idp-config.mocks';
Expand Down Expand Up @@ -864,49 +864,38 @@ describe('SsoProviderTable', () => {
});

describe('SsoProviderTableView', () => {
const logic = createMockSsoProviderTableLogic();
const handlers = createMockSsoProviderTableHandler();
const viewProps = createMockSsoProviderTableView();

it('renders the table and header', () => {
renderWithProviders(<SsoProviderTableView logic={logic} handlers={handlers} />);
renderWithProviders(<SsoProviderTableView {...viewProps} />);
expect(screen.getByRole('table')).toBeInTheDocument();
expect(screen.getByRole('banner')).toBeInTheDocument();
});

it('renders empty state when data is empty', () => {
renderWithProviders(
<SsoProviderTableView logic={{ ...logic, data: [] }} handlers={handlers} />,
);
renderWithProviders(<SsoProviderTableView {...viewProps} providers={[]} />);
expect(screen.getByText(/empty/i)).toBeInTheDocument();
});

it('disables create button when readOnly is true', () => {
renderWithProviders(
<SsoProviderTableView logic={{ ...logic, readOnly: true }} handlers={handlers} />,
);
renderWithProviders(<SsoProviderTableView {...viewProps} readOnly={true} />);
const createButton = screen.getByRole('button', { name: /create/i });
expect(createButton).toBeDisabled();
});

it('renders loading state when isLoading is true', () => {
renderWithProviders(
<SsoProviderTableView logic={{ ...logic, isLoading: true }} handlers={handlers} />,
);
expect(screen.getByRole('table')).toBeInTheDocument();
// Optionally check for a loading indicator if present in your DataTable
it('renders loading state when isViewLoading is true', () => {
renderWithProviders(<SsoProviderTableView {...viewProps} isViewLoading={true} />);
expect(screen.queryByRole('table')).not.toBeInTheDocument();
});

it('renders custom header class if provided', () => {
renderWithProviders(
<SsoProviderTableView
logic={{
...logic,
styling: {
...logic.styling,
classes: { ...logic?.styling?.classes, 'SsoProviderTable-header': 'custom-header' },
},
{...viewProps}
styling={{
...viewProps.styling,
classes: { ...viewProps.styling?.classes, 'SsoProviderTable-header': 'custom-header' },
}}
handlers={handlers}
/>,
);
expect(document.querySelector('.custom-header')).toBeInTheDocument();
Expand All @@ -915,14 +904,11 @@ describe('SsoProviderTableView', () => {
it('renders custom table class if provided', () => {
renderWithProviders(
<SsoProviderTableView
logic={{
...logic,
styling: {
...logic.styling,
classes: { ...logic?.styling?.classes, 'SsoProviderTable-table': 'custom-table' },
},
{...viewProps}
styling={{
...viewProps.styling,
classes: { ...viewProps.styling?.classes, 'SsoProviderTable-table': 'custom-table' },
}}
handlers={handlers}
/>,
);
expect(document.querySelector('.custom-table')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,19 @@ import { DataTable, type Column } from '@/components/auth0/shared/data-table';
import { Header } from '@/components/auth0/shared/header';
import { StyledScope } from '@/components/auth0/shared/styled-scope';
import { useSsoProviderTable } from '@/hooks/my-organization/use-sso-provider-table';
import { useSsoProviderTableLogic } from '@/hooks/my-organization/use-sso-provider-table-logic';
import { useTheme } from '@/hooks/shared/use-theme';
import { useTranslator } from '@/hooks/shared/use-translator';
import type {
SsoProviderTableProps,
SsoProviderTableLogicProps,
SsoProviderTableHandlerProps,
SsoProviderTableViewProps,
} from '@/types/my-organization/idp-management/sso-provider/sso-provider-table-types';

/**
* Internal SSO provider table container(logic) component.
* @param props - Component props
* @param props.customMessages - Custom translation messages to override defaults
* @param props.styling - Custom styling configuration with variables and classes
* @param props.readOnly - Whether the component is in read-only mode
* @param props.createAction - Configuration for the create action
* @param props.editAction - Configuration for the edit action
* @param props.deleteAction - Configuration for the delete action
* @param props.deleteFromOrganizationAction - Configuration for removing from organization
* @param props.enableProviderAction - Configuration for enabling a provider
* @returns JSX element
* @internal
*/
function SsoProviderTableContainer(props: SsoProviderTableProps) {
function SsoProviderTable(props: SsoProviderTableProps) {
const {
customMessages = {},
styling = { variables: { common: {}, light: {}, dark: {} }, classes: {} },
Expand All @@ -51,122 +39,61 @@ function SsoProviderTableContainer(props: SsoProviderTableProps) {
enableProviderAction,
} = props;

const ssoProviderTable = useSsoProviderTable(
deleteAction,
deleteFromOrganizationAction,
enableProviderAction,
customMessages,
);

const {
providers,
organization,
isLoading,
isDeleting,
isRemoving,
isUpdating,
isUpdatingId,
onDeleteConfirm,
onRemoveConfirm,
onEnableProvider,
} = ssoProviderTable;

const tableLogic = useSsoProviderTableLogic({
isLoading,
readOnly,
const hook = useSsoProviderTable({
createAction,
editAction,
deleteAction,
deleteFromOrganizationAction,
onEnableProvider,
onDeleteConfirm,
onRemoveConfirm,
});

const ssoProviderCreateLogicProps: SsoProviderTableLogicProps = {
data: providers,
styling,
customMessages,
enableProviderAction,
readOnly,
createAction,
editAction,
organization,
isUpdating,
isUpdatingId,
isDeleting,
isRemoving,
hideHeader: false,
isLoading: tableLogic.isViewLoading,
shouldHideCreate: tableLogic.shouldHideCreate,
isViewLoading: tableLogic.isViewLoading,
selectedIdp: tableLogic.selectedIdp,
showDeleteModal: tableLogic.showDeleteModal,
showRemoveModal: tableLogic.showRemoveModal,
shouldAllowDeletion: tableLogic.shouldAllowDeletion,
};

const ssoProviderCreateHandlerProps: SsoProviderTableHandlerProps = {
handleCreate: tableLogic.handleCreate,
handleEdit: tableLogic.handleEdit,
handleDelete: tableLogic.handleDelete,
handleDeleteFromOrganization: tableLogic.handleDeleteFromOrganization,
handleToggleEnabled: tableLogic.handleToggleEnabled,
handleDeleteConfirm: tableLogic.handleDeleteConfirm,
handleRemoveConfirm: tableLogic.handleRemoveConfirm,
setShowDeleteModal: tableLogic.setShowDeleteModal,
setShowRemoveModal: tableLogic.setShowRemoveModal,
setSelectedIdp: tableLogic.setSelectedIdp,
};
customMessages,
});

return (
<SsoProviderTableView
logic={ssoProviderCreateLogicProps}
handlers={ssoProviderCreateHandlerProps}
{...hook}
styling={styling}
customMessages={customMessages}
readOnly={readOnly}
createAction={createAction}
editAction={editAction}
/>
);
}

/**
* Internal SSO provider table view component
* @param props - Component props
* @param props.logic - Component logic props
* @param props.handlers - Component handler props
* @internal
* @param props - View props
* @returns JSX element
* @internal
*/
function SsoProviderTableView({ logic, handlers }: SsoProviderTableViewProps) {
const {
styling,
customMessages,
readOnly,
data,
shouldHideCreate,
isViewLoading,
createAction,
editAction,
selectedIdp,
showDeleteModal,
showRemoveModal,
shouldAllowDeletion,
organization,
isUpdating,
isUpdatingId,
isDeleting,
isRemoving,
} = logic;

const {
handleCreate,
handleEdit,
handleDelete,
handleDeleteFromOrganization,
handleToggleEnabled,
handleDeleteConfirm,
handleRemoveConfirm,
setShowDeleteModal,
setShowRemoveModal,
} = handlers;

function SsoProviderTableView({
styling,
customMessages,
readOnly,
createAction,
editAction,
providers,
organization,
isViewLoading,
isDeleting,
isRemoving,
isUpdating,
isUpdatingId,
shouldHideCreate,
shouldAllowDeletion,
showDeleteModal,
showRemoveModal,
selectedIdp,
handleCreate,
handleEdit,
handleDelete,
handleDeleteFromOrganization,
handleToggleEnabled,
handleDeleteConfirm,
handleRemoveConfirm,
setShowDeleteModal,
setShowRemoveModal,
}: SsoProviderTableViewProps) {
const { isDarkMode } = useTheme();
const { t } = useTranslator('idp_management.sso_provider_table', customMessages);
const currentStyles = React.useMemo(
Expand Down Expand Up @@ -254,7 +181,7 @@ function SsoProviderTableView({ logic, handlers }: SsoProviderTableViewProps) {
<DataTable
loading={isViewLoading}
columns={columns}
data={data}
data={providers}
emptyState={{ title: t('table.empty_message') }}
className={currentStyles.classes?.['SsoProviderTable-table']}
/>
Expand Down Expand Up @@ -320,6 +247,4 @@ function SsoProviderTableView({ logic, handlers }: SsoProviderTableViewProps) {
* />
* ```
*/
const SsoProviderTable = SsoProviderTableContainer;

export { SsoProviderTable, SsoProviderTableView };
Loading