diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts
index 0347c083f812..ca177932a21d 100644
--- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts
+++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts
@@ -2249,6 +2249,88 @@ description:
});
}
});
+
+ test('Contract created from the form defaults to Draft', async ({ page }) => {
+ const { apiContext } = await getApiContext(page);
+ const table = new TableClass();
+ await table.create(apiContext);
+
+ try {
+ await redirectToHomePage(page);
+ await table.visitEntityPage(page);
+ await navigateToContractTab(page);
+ await clickAddContractButton(page);
+
+ await expect(page.getByTestId('contract-entity-status')).toContainText(
+ 'Draft'
+ );
+
+ await page.getByTestId('contract-name').fill('draft_default_contract');
+
+ const createResponse = page.waitForResponse(
+ (response) =>
+ response.url().endsWith('/api/v1/dataContracts') &&
+ response.request().method() === 'POST'
+ );
+ await page.getByTestId('save-contract-btn').click();
+ const created = await createResponse;
+
+ expect(created.ok()).toBe(true);
+ expect((await created.json()).entityStatus).toBe('Draft');
+
+ const statusCard = page.getByTestId('contract-status-card');
+ const statusBadge = statusCard.getByText('Draft', { exact: true });
+
+ await expect(statusBadge).toBeVisible();
+ // A Draft must not be painted with the green success palette.
+ await expect(statusBadge).toHaveClass(/utility-warning/);
+ await expect(statusBadge).not.toHaveClass(/utility-success/);
+ } finally {
+ await table.delete(apiContext);
+ }
+ });
+
+ test('Contract is created with the status picked in the form', async ({
+ page,
+ }) => {
+ const { apiContext } = await getApiContext(page);
+ const table = new TableClass();
+ await table.create(apiContext);
+
+ try {
+ await redirectToHomePage(page);
+ await table.visitEntityPage(page);
+ await navigateToContractTab(page);
+ await clickAddContractButton(page);
+
+ await page.getByTestId('contract-name').fill('approved_choice_contract');
+
+ await selectOption(
+ page,
+ page.getByTestId('contract-entity-status'),
+ 'Approved'
+ );
+
+ const createResponse = page.waitForResponse(
+ (response) =>
+ response.url().endsWith('/api/v1/dataContracts') &&
+ response.request().method() === 'POST'
+ );
+ await page.getByTestId('save-contract-btn').click();
+ const created = await createResponse;
+
+ expect(created.ok()).toBe(true);
+ expect((await created.json()).entityStatus).toBe('Approved');
+
+ const statusCard = page.getByTestId('contract-status-card');
+ const statusBadge = statusCard.getByText('Approved', { exact: true });
+
+ await expect(statusBadge).toBeVisible();
+ await expect(statusBadge).toHaveClass(/utility-success/);
+ } finally {
+ await table.delete(apiContext);
+ }
+ });
});
entitiesWithDataContracts.forEach((EntityClass) => {
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.test.tsx
index e297b9fe9a79..9d99697e9d34 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.test.tsx
@@ -96,6 +96,11 @@ jest.mock('../ContractDetailFormTab/ContractDetailFormTab', () => ({
+
)),
@@ -442,7 +447,7 @@ describe('AddDataContract', () => {
type: EntityType.TABLE,
},
semantics: undefined, // validSemantics - undefined when no semantics provided
- entityStatus: EntityStatus.Approved,
+ entityStatus: EntityStatus.Draft,
})
);
expect(showSuccessToast).toHaveBeenCalledWith(
@@ -474,7 +479,7 @@ describe('AddDataContract', () => {
type: EntityType.TABLE,
},
semantics: undefined, // validSemantics - undefined when no semantics provided
- entityStatus: EntityStatus.Approved,
+ entityStatus: EntityStatus.Draft,
})
);
expect(showSuccessToast).toHaveBeenCalledWith(
@@ -483,6 +488,43 @@ describe('AddDataContract', () => {
expect(mockOnSave).toHaveBeenCalled();
});
+ it('should send the status picked in the form instead of forcing Approved', async () => {
+ render();
+
+ await act(async () => {
+ fireEvent.click(screen.getByText('Change'));
+ });
+
+ await act(async () => {
+ fireEvent.click(screen.getByTestId('entity-status-change-btn'));
+ });
+
+ await act(async () => {
+ fireEvent.click(screen.getByTestId('save-contract-btn'));
+ });
+
+ expect((createContract as jest.Mock).mock.calls[0][0]).toEqual(
+ expect.objectContaining({ entityStatus: EntityStatus.InReview })
+ );
+ });
+
+ it('should default a newly created contract to Draft, never Approved', async () => {
+ render();
+
+ await act(async () => {
+ fireEvent.click(screen.getByText('Change'));
+ });
+
+ await act(async () => {
+ fireEvent.click(screen.getByTestId('save-contract-btn'));
+ });
+
+ const payload = (createContract as jest.Mock).mock.calls[0][0];
+
+ expect(payload.entityStatus).toBe(EntityStatus.Draft);
+ expect(payload.entityStatus).not.toBe(EntityStatus.Approved);
+ });
+
it('should call updateContract for existing contract with JSON patch', async () => {
render(
{
expect(mockOnSave).toHaveBeenCalled();
});
+ it('should not patch entityStatus when editing without touching the status', async () => {
+ render(
+
+ );
+
+ // Change an unrelated field; mockContract is already Approved, so a
+ // spurious /entityStatus op would silently rewrite an existing status.
+ await act(async () => {
+ fireEvent.click(screen.getByText('Change'));
+ });
+
+ await act(async () => {
+ fireEvent.click(screen.getByTestId('save-contract-btn'));
+ });
+
+ expect((updateContract as jest.Mock).mock.calls[0][1]).toEqual(
+ expect.not.arrayContaining([
+ expect.objectContaining({ path: '/entityStatus' }),
+ ])
+ );
+ });
+
+ it('should patch entityStatus when the author changes the status', async () => {
+ render(
+
+ );
+
+ await act(async () => {
+ fireEvent.click(screen.getByTestId('entity-status-change-btn'));
+ });
+
+ await act(async () => {
+ fireEvent.click(screen.getByTestId('save-contract-btn'));
+ });
+
+ expect((updateContract as jest.Mock).mock.calls[0][1]).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ path: '/entityStatus',
+ value: EntityStatus.InReview,
+ }),
+ ])
+ );
+ });
+
it('should handle save errors gracefully', async () => {
const mockError = new Error('Save failed');
(createContract as jest.Mock).mockRejectedValue(mockError);
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.tsx
index a47add6b8ea2..bb53b41393c3 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.tsx
@@ -26,13 +26,13 @@ import { ReactComponent as TableIcon } from '../../../assets/svg/table-outline.s
import { ReactComponent as SLAIcon } from '../../../assets/svg/timeout.svg';
import {
DataContractMode,
+ DEFAULT_DATA_CONTRACT_STATUS,
EDataContractTab,
} from '../../../constants/DataContract.constants';
import { CSMode } from '../../../enums/codemirror.enum';
import { EntityType } from '../../../enums/entity.enum';
import {
DataContract,
- EntityStatus,
TermsOfUse,
} from '../../../generated/entity/data/dataContract';
import { Table } from '../../../generated/entity/data/table';
@@ -264,7 +264,7 @@ const AddDataContract: React.FC<{
semantics: validSemantics,
security: validSecurity,
termsOfUse: termsOfUseContent,
- entityStatus: EntityStatus.Approved,
+ entityStatus: formValues.entityStatus ?? DEFAULT_DATA_CONTRACT_STATUS,
});
}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.entityStatus.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.entityStatus.test.tsx
new file mode 100644
index 000000000000..94dbb9ce400c
--- /dev/null
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.entityStatus.test.tsx
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2025 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.
+ */
+
+/*
+ * ContractDetailFormTab.test.tsx stubs `generateFormFields`, so it can only
+ * inspect the field descriptors. These cases render the real Ant Design control
+ * to assert what the author actually sees and can pick.
+ */
+import '@testing-library/jest-dom';
+import { act, fireEvent, render, screen } from '@testing-library/react';
+import { DATA_CONTRACT_AUTHORING_STATUS_OPTIONS } from '../../../constants/DataContract.constants';
+import { EntityStatus } from '../../../generated/entity/data/dataContract';
+import { ContractDetailFormTab } from './ContractDetailFormTab';
+
+jest.mock('../../../hooks/useEntityRules', () => ({
+ useEntityRules: jest.fn().mockImplementation(() => ({
+ entityRules: {
+ canAddMultipleUserOwners: true,
+ canAddMultipleTeamOwner: true,
+ },
+ })),
+}));
+
+const commonProps = {
+ buttonProps: { isNextVisible: true },
+ onChange: jest.fn(),
+ onNext: jest.fn(),
+};
+
+const getStatusSelect = () => screen.getByTestId('contract-entity-status');
+
+const openStatusDropdown = async () => {
+ await act(async () => {
+ fireEvent.mouseDown(
+ getStatusSelect().querySelector('.ant-select-selector') as Element
+ );
+ });
+};
+
+describe('ContractDetailFormTab entity status control', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('should show Draft as the pre-selected status when creating a contract', () => {
+ render();
+
+ expect(getStatusSelect()).toHaveTextContent('label.draft');
+ expect(getStatusSelect()).not.toHaveTextContent('label.approved');
+ });
+
+ it('should show the contract status when editing an existing contract', () => {
+ render(
+
+ );
+
+ expect(getStatusSelect()).toHaveTextContent('label.approved');
+ });
+
+ it('should offer only Draft, In Review and Approved as authoring statuses', async () => {
+ render();
+
+ await openStatusDropdown();
+
+ const options = document.querySelectorAll('.ant-select-item-option');
+
+ // Compare against the authoring list itself rather than literal i18n keys,
+ // so renaming a key cannot fail this for a non-behavioural reason. Which
+ // statuses that list may contain is asserted in ContractDetailFormTab.test.tsx.
+ expect(Array.from(options).map((option) => option.textContent)).toEqual(
+ DATA_CONTRACT_AUTHORING_STATUS_OPTIONS.map(({ labelKey }) => labelKey)
+ );
+ });
+
+ it('should report the picked status to the parent form', async () => {
+ render();
+
+ await openStatusDropdown();
+
+ await act(async () => {
+ fireEvent.click(screen.getByText('label.in-review'));
+ });
+
+ expect(commonProps.onChange).toHaveBeenCalledWith(
+ { entityStatus: EntityStatus.InReview },
+ expect.anything()
+ );
+ });
+});
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.test.tsx
index b16389e66a2b..f9e7b9248be6 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.test.tsx
@@ -12,8 +12,12 @@
*/
import '@testing-library/jest-dom';
import { act, fireEvent, render, screen } from '@testing-library/react';
-import { DataContract } from '../../../generated/entity/data/dataContract';
+import {
+ DataContract,
+ EntityStatus,
+} from '../../../generated/entity/data/dataContract';
import { EntityReference } from '../../../generated/entity/type';
+import { FieldProp, FieldTypes } from '../../../interface/FormUtils.interface';
import { ContractDetailFormTab } from './ContractDetailFormTab';
jest.mock('../../../utils/formUtils', () => ({
@@ -38,6 +42,10 @@ jest.mock('react-i18next', () => ({
'label.contract-detail-plural': 'Contract Details',
'message.contract-detail-plural-description': 'Enter contract details',
'label.next': 'Next',
+ 'label.status': 'Status',
+ 'label.draft': 'Draft',
+ 'label.in-review': 'In Review',
+ 'label.approved': 'Approved',
};
return translations[key] || key;
@@ -118,6 +126,31 @@ describe('ContractDetailFormTab', () => {
expect(screen.getByText('Owners')).toBeInTheDocument();
});
+ it('should render a status field so the author can pick the initial status', () => {
+ render();
+
+ expect(screen.getByText('Status')).toBeInTheDocument();
+ });
+
+ it('should only offer authoring statuses, never Rejected/Archived/Unprocessed', () => {
+ const generateFormFields = jest.requireMock(
+ '../../../utils/formUtils'
+ ).generateFormFields;
+
+ render();
+
+ const statusField = generateFormFields.mock.calls[0][0].find(
+ (field: FieldProp) => field.name === 'entityStatus'
+ );
+
+ expect(statusField.type).toBe(FieldTypes.SELECT);
+ expect(statusField.props.options).toEqual([
+ { label: 'Draft', value: EntityStatus.Draft },
+ { label: 'In Review', value: EntityStatus.InReview },
+ { label: 'Approved', value: EntityStatus.Approved },
+ ]);
+ });
+
it('should set form values when initial values are provided', () => {
const { container } = render(
({ label: t(labelKey), value })
+ );
+
const fields: FieldProp[] = [
{
label: t('label.contract-title'),
@@ -77,6 +85,20 @@ export const ContractDetailFormTab: React.FC<{
trigger: 'onUpdate',
},
},
+ {
+ label: t('label.status'),
+ id: 'entityStatus',
+ name: 'entityStatus',
+ type: FieldTypes.SELECT,
+ required: false,
+ props: {
+ 'data-testid': 'contract-entity-status',
+ options: entityStatusOptions,
+ placeholder: t('label.please-select-entity', {
+ entity: t('label.status'),
+ }),
+ },
+ },
{
label: t('label.description'),
id: 'description',
@@ -91,6 +113,12 @@ export const ContractDetailFormTab: React.FC<{
];
useEffect(() => {
+ // Create mode has no initialValues, so the select would render blank and the
+ // payload would fall back silently. Seed it with the same Draft default.
+ form.setFieldsValue({
+ entityStatus: initialValues?.entityStatus ?? DEFAULT_DATA_CONTRACT_STATUS,
+ });
+
if (initialValues) {
form.setFieldsValue({
name: getEntityName(initialValues),
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.test.tsx
index 4631d0025b32..9065e914a0ac 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.test.tsx
@@ -25,6 +25,7 @@ import { DataContractMode } from '../../../constants/DataContract.constants';
import {
ContractExecutionStatus,
DataContract,
+ EntityStatus,
} from '../../../generated/entity/data/dataContract';
import { Column } from '../../../generated/entity/data/table';
import { DataContractResult } from '../../../generated/entity/datacontract/dataContractResult';
@@ -46,9 +47,11 @@ jest.mock('@openmetadata/ui-core-components', () => ({
Badge: jest.fn(({ children }: { children?: React.ReactNode }) => (
{children}
)),
- BadgeWithIcon: jest.fn(({ children }: { children?: React.ReactNode }) => (
- {children}
- )),
+ BadgeWithIcon: jest.fn(
+ ({ children, color }: { children?: React.ReactNode; color?: string }) => (
+ {children}
+ )
+ ),
Box: jest.fn(
({
children,
@@ -615,6 +618,45 @@ describe('ContractDetail', () => {
});
});
+ describe('Entity Status Badge', () => {
+ const renderWithStatus = (entityStatus?: EntityStatus) => {
+ render(
+ ,
+ { wrapper: MemoryRouter }
+ );
+
+ return screen
+ .getByTestId('contract-status-card')
+ .querySelector('[data-color]');
+ };
+
+ it.each([
+ [EntityStatus.Draft, 'warning'],
+ [EntityStatus.InReview, 'purple'],
+ [EntityStatus.Approved, 'success'],
+ [EntityStatus.Rejected, 'error'],
+ [EntityStatus.Deprecated, 'gray'],
+ [EntityStatus.Archived, 'gray'],
+ ])('should render %s with the %s colour', (entityStatus, expectedColor) => {
+ const badge = renderWithStatus(entityStatus);
+
+ expect(badge).toHaveTextContent(entityStatus);
+ expect(badge).toHaveAttribute('data-color', expectedColor);
+ });
+
+ it('should not paint a success colour when the status is missing', () => {
+ const badge = renderWithStatus(undefined);
+
+ expect(badge).toHaveAttribute('data-color', 'gray');
+ });
+ });
+
describe('Contract Actions', () => {
it('should call onEdit when edit button is clicked', () => {
render(
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.tsx
index a5b389883172..d2c8c3ad4029 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailTab/ContractDetail.tsx
@@ -67,6 +67,7 @@ import {
} from '../../../utils/DataContract/DataContractUtils';
import { formatDateTime } from '../../../utils/date-time/DateTimeUtils';
import { getEntityName } from '../../../utils/EntityNameUtils';
+import { getEntityStatusBadgeColor } from '../../../utils/EntityStatusUtils';
import { pruneEmptyChildren } from '../../../utils/TablePureUtils';
import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils';
import AlertBar from '../../AlertBar/AlertBar';
@@ -500,13 +501,13 @@ const ContractDetail: React.FC<{
orientation="vertical"
/>
-
+
{`${t('label.status')} : `}
@@ -520,7 +521,7 @@ const ContractDetail: React.FC<{
/>
-
+
{`${t('label.owner-plural')} : `}
diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/DataContract.constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/DataContract.constants.ts
index 2d24433f873d..b659292a5540 100644
--- a/openmetadata-ui/src/main/resources/ui/src/constants/DataContract.constants.ts
+++ b/openmetadata-ui/src/main/resources/ui/src/constants/DataContract.constants.ts
@@ -14,9 +14,33 @@
import type { BarProps } from 'recharts';
import { EntityReferenceFields } from '../enums/AdvancedSearch.enum';
import { EntityType } from '../enums/entity.enum';
+import { EntityStatus } from '../generated/entity/data/dataContract';
export const CONTRACT_DATE_TIME_FORMAT = 'MM/dd/yyyy, h:mma';
+/**
+ * A new contract starts as a Draft so it goes through review instead of being
+ * published on creation. The schema documents the same default, but that default
+ * is inert (jsonschema2pojo resolves the `$ref`ed `type/status.json` default of
+ * `Unprocessed` instead), so the client has to send the status explicitly.
+ */
+export const DEFAULT_DATA_CONTRACT_STATUS = EntityStatus.Draft;
+
+/**
+ * Statuses a human can author a contract into. `Rejected` is an outcome a reviewer
+ * produces by closing the approval task, `Archived`/`Deprecated` are end-of-life
+ * states, and `Unprocessed` is an internal sentinel — none of them is a state
+ * somebody writing a contract should be able to pick.
+ */
+export const DATA_CONTRACT_AUTHORING_STATUS_OPTIONS: {
+ labelKey: string;
+ value: EntityStatus;
+}[] = [
+ { labelKey: 'label.draft', value: EntityStatus.Draft },
+ { labelKey: 'label.in-review', value: EntityStatus.InReview },
+ { labelKey: 'label.approved', value: EntityStatus.Approved },
+];
+
export enum DataContractMode {
YAML,
UI,
diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/EntityStatusUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/EntityStatusUtils.ts
index c5ec4de99da9..17c89ae4d228 100644
--- a/openmetadata-ui/src/main/resources/ui/src/utils/EntityStatusUtils.ts
+++ b/openmetadata-ui/src/main/resources/ui/src/utils/EntityStatusUtils.ts
@@ -11,6 +11,7 @@
* limitations under the License.
*/
+import { BadgeColors } from '@openmetadata/ui-core-components';
import { isNil } from 'lodash';
import { StatusType } from '../components/common/StatusBadge/StatusBadge.interface';
import { EntityStatus } from '../generated/entity/data/glossaryTerm';
@@ -29,6 +30,36 @@ export const getEntityStatusClass = (status: EntityStatus): StatusType => {
return EntityStatusClass[status] ?? StatusType.Pending;
};
+/**
+ * BadgeColors equivalent of EntityStatusClass, for the UntitledUI Badge family.
+ * Kept in the same palette as the legacy StatusBadge (`status-badge.less`) so a
+ * status looks the same in both stacks: approved green, draft/unprocessed
+ * yellow, in-review purple, rejected red, deprecated/archived grey.
+ */
+export const EntityStatusBadgeColor: Record = {
+ [EntityStatus.Approved]: 'success',
+ [EntityStatus.Draft]: 'warning',
+ [EntityStatus.Rejected]: 'error',
+ [EntityStatus.Deprecated]: 'gray',
+ [EntityStatus.InReview]: 'purple',
+ [EntityStatus.Unprocessed]: 'warning',
+ [EntityStatus.Archived]: 'gray',
+};
+
+/**
+ * Takes the enum's string values rather than the enum itself: quicktype re-emits
+ * EntityStatus per entity with no shared module, and TS string enums are nominal,
+ * so callers holding e.g. the dataContract copy could not otherwise pass it.
+ *
+ * Falls back to a neutral grey — an unknown or absent status must not be painted
+ * as a confident success.
+ */
+export const getEntityStatusBadgeColor = (
+ status?: `${EntityStatus}`
+): BadgeColors => {
+ return (status ? EntityStatusBadgeColor[status] : undefined) ?? 'gray';
+};
+
export const isDeleted = (deleted: unknown): boolean => {
return (deleted as string) === 'false' || deleted === false || isNil(deleted)
? false