Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
77ee168
fix: default data contracts to draft status
PRADDZY Aug 2, 2026
56b443d
Apply batched suggestions from code review
TeddyCr Aug 28, 2026
09bb37e
fix: localize data contract status options
PRADDZY Aug 31, 2026
9c3bdc9
fix(playwright): narrow add-reactions locator to fix strict mode viol…
Rohit0301 Aug 31, 2026
6cc4dab
fix(security): bump httpclient5 to 5.6.4 (#32264)
karanh37 Aug 31, 2026
a522bae
ci(playwright): run release-branch nightly E2E with 2 per-test retrie…
ShaileshParmar11 Aug 31, 2026
961d760
fix(ui): re-enable all disabled Jest tests; promote jest/no-disabled-…
ShaileshParmar11 Aug 31, 2026
cd1e3b8
fix(security): bump jsoup to 1.23.2 (#32266)
karanh37 Aug 31, 2026
4b2927a
fix(security): bump qs to 6.16.0 (#32265)
karanh37 Aug 31, 2026
93af7c7
Fixes 32206: stop linking a table to itself from the Databricks syste…
mohittilala Aug 31, 2026
4d37a83
swap hybrid default values keyword vs semantic (#31968)
tomasmontielp Aug 31, 2026
54d7f29
test(playwright): page to the app card; anchor the steward switch (#3…
ShaileshParmar11 Aug 31, 2026
7fb74b1
Fixes #30895: Complete Metrics hierarchy and details (#30896)
harshach Aug 31, 2026
dc220fd
fix(security): bump Apache Jena and Fuseki to 6.2.0 (CVE-2026-61372) …
mohityadav766 Aug 31, 2026
fd69f6f
Fixes #32317: Show relations in Ontology data mode (#32318)
harshach Sep 1, 2026
bfe9b52
Revert "Fixes #30895: Complete Metrics hierarchy and details (#30896)…
karanh37 Sep 1, 2026
0086cb5
fix(ui): full-width ER diagram drawer and column panel double-close (…
Rohit0301 Sep 1, 2026
e99fc10
Fixes 31278: Extract lineage from SQL-defined Databricks DLT pipeline…
mohittilala Sep 1, 2026
793a7f1
Fix user patch permissions (#32323)
harshach Sep 1, 2026
57cf459
Playwright burn-down 1: eliminate no-wait-for-timeout and no-force-op…
ShaileshParmar11 Sep 1, 2026
c50bbf2
Fixes #32320: Enforce ingestion pipeline action permissions (#32321)
harshach Sep 1, 2026
881fbfd
refactor: OIDC login handler and MCP callback auth handling (#32354)
yan-3005 Sep 1, 2026
6e691cb
fix(ui): stop deriving the Explore tab from a tied hybrid top hit (#3…
fmcardoso Sep 1, 2026
e1f079a
fix: mask PubSub credentials in backend (#32102) (#32135)
zhang-arvin Sep 1, 2026
f0ea223
feat(login): drive login video gradient from LoginClassBase (#32311)
anuj-kumary Sep 1, 2026
e8457ee
Fixes #32256: Queries tab shows parent table's description provenance…
chirag-madlani Sep 1, 2026
9119bc7
Improve casing on quick filters across pages for glossary terms and t…
harsh-vador Sep 1, 2026
a665363
feat(ui): use the Ontology Studio glyph in both nav surfaces (#32324)
anuj-kumary Sep 1, 2026
3d1d454
Fixes #30076: Add UI support for soft delete and restore of test case…
shah-harshit Sep 1, 2026
f096655
fix(ui): route hardcoded copy through t(); promote i18next/no-literal…
ShaileshParmar11 Sep 1, 2026
a79d03a
fix(ui): stretch glossary terms table to fill its container (#32269)
anuj-kumary Sep 1, 2026
023b4b3
fix(ui): app-mode page height + native interface switcher, with app-m…
karanh37 Sep 1, 2026
69f2171
refactor(ui): extract axios baseURL into swappable `apiBaseUrl` modul…
chirag-madlani Sep 1, 2026
02df9c1
Fixes #32205: stop KafkaConnect emitting topic-namespace membership a…
mohittilala Sep 1, 2026
528ba05
Placeholder migration ai screens (#32296)
Rohit0301 Sep 1, 2026
2b4edfc
fix(mcp): handle unknown methods and initialized notifications (#32147)
Vishnuujain Sep 1, 2026
b982ffb
ui: Add password change to the profile page (#32344)
harsh-vador Sep 1, 2026
3be728b
Fixes 28727: flatten testCaseResolutionStatusDetails index mapping + …
TeddyCr Sep 2, 2026
5370c78
fix(ingestion): cap pygtrie below 2.6 so `import airflow` works on Py…
Khairajani Sep 1, 2026
27d35d1
[FIX] PII detection missed in numeric columns - coerce values to stri…
zhang-arvin Sep 1, 2026
58bed9c
fix(pii): normalise ALL-CAPS tokens in preprocess_values so spaCy NER…
zerafachris Sep 1, 2026
764b0fc
feat(ui): add dark mode switcher (#32383)
shah-harshit Sep 1, 2026
2e2637b
fix(governance): validate workflow edge conditions and node reference…
yan-3005 Sep 1, 2026
2f5a6e6
chore(deps): bump actions/github-script from 8 to 9 (#32285)
dependabot[bot] Sep 1, 2026
f8f982f
chore(deps): bump EndBug/add-and-commit from 9 to 11 (#32284)
dependabot[bot] Sep 2, 2026
e52d8b4
Fixes #32428: unblock UI Checkstyle and make Playwright lint failures…
ShaileshParmar11 Sep 2, 2026
06e938f
chore(python): modernize typing and enforce lazy logging (#31643)
IceS2 Sep 2, 2026
0f75246
fix(ui): prevent 400 on second domain tag update (#32358)
anuj-kumary Sep 2, 2026
cb99ec2
ci: clean action permissions (#32436)
pmbrull Sep 2, 2026
7f55d9d
fix(ui): show version number in AI mode Help menu (#32387)
anuj-kumary Sep 2, 2026
7aaf5a3
Fixes 32365: stop catalog.log duplicating every rotated openmetadata.…
mohityadav766 Sep 2, 2026
e0dd02e
Fixes #32276: preserve math equations through frontend and backend sa…
Rohit0301 Sep 2, 2026
a560984
Fixes 32397: stop a wildcard include with no directory reducing to th…
mohittilala Sep 2, 2026
d84ab8c
fix(ui): re-seed a profile row's draft when its editor opens (#32406)
harsh-vador Sep 2, 2026
92bedf7
fix(data-insights): declare the data asset types once and make the fi…
manerow Sep 2, 2026
63f8657
feat(skills): add openmetadata-pr-review skill (#32308)
pmbrull Sep 2, 2026
c91fd8d
Fixes #21054: Oracle query history fails with ORA-00933 on Oracle 11g…
Khairajani Sep 2, 2026
f08658b
Fixes #32092: emit ChangeEvents for bulk entity updates (#32350)
manerow Sep 2, 2026
ff7da5c
organize impersonation (#32353)
mohityadav766 Sep 2, 2026
bc00dba
Fixes #32297: Honor Data Product Domain Validation rule in the Add As…
karanh37 Sep 2, 2026
9445004
feat(ui): make TableV2 a real drop-in for the legacy AntD table (#31953)
harsh-vador Sep 2, 2026
a50cfc2
Fix lineage authorization in MCP tools (#32437)
Vishnuujain Sep 2, 2026
8d8318a
Fixes #32063: keep auth tokens in memory when the service worker cann…
neochaotic Sep 2, 2026
a474b66
fix(ui): i18n-aware no-duplicate-string rule; extract non-i18n duplic…
ShaileshParmar11 Sep 2, 2026
703e46d
fix(security): bump browserslist to 4.28.8 (#32418)
karanh37 Sep 2, 2026
c59bf85
Fix MCP entity patch lifecycle handling (#32226)
Vishnuujain Sep 2, 2026
8b6fd6b
fix(clickhouse): create the downstream lineage of materialized views …
Khairajani Sep 2, 2026
bdc5a1c
fix(tags): make provider immutable for system Classifications/Tags (#…
sonika-shah Sep 2, 2026
8445c1e
test(ui): restore the tests and i18n keys left behind by the Collate …
harsh-vador Sep 2, 2026
eb7c2e5
Fixes 6035: Add theme-aware canvas color resolution (#32423)
shah-harshit Sep 2, 2026
6dca618
Fixes #25847: Include bot user in bot list responses (#32398)
IceS2 Sep 2, 2026
16f7365
refactor(ui): consolidate destination form (#32078)
shah-harshit Sep 2, 2026
49fdb09
Fix(ui): Migrate RelatedDataAssets picker to DataAssetSelectList (#32…
Rohit0301 Sep 2, 2026
1126bba
Fix case-sensitive TestSuite pipelineType in the 1.13.0 sampling migr…
TeddyCr Sep 3, 2026
811467c
fix(test): stop HighlightFieldSaveValidationIT sending two Content-Ty…
mohityadav766 Sep 2, 2026
2657710
fix(ingestion): pin anyio<4.15 in the mlflow test image to unblock py…
manerow Sep 3, 2026
1fbee20
Fixes #32519: Make the JavaUIIT suite a required status check (#32521)
mohityadav766 Sep 3, 2026
5991934
Fixes 24806: refresh the Data Contract DQ DAG deployment on every val…
TeddyCr Sep 2, 2026
42cf032
fix(test): keep global mock TableRepository registrations index-polic…
mohityadav766 Sep 3, 2026
4bc04e9
perf(ui): switch build to Rolldown — 10 min → 20 s (#32384)
chirag-madlani Sep 3, 2026
e5ce29c
Fixes #26521: Decouple Incident Manager Permissions from Test Case Ed…
TeddyCr Sep 3, 2026
d12595c
fix(test): select Approved status for Data Product contracts in DataC…
Sep 3, 2026
90f4785
Merge branch 'main' into fix/data-contract-default-status
shrabantipaul-collate Sep 3, 2026
34154ea
Merge branch 'main' into fix/data-contract-default-status
TeddyCr Sep 4, 2026
02c390b
Merge branch 'main' into fix/data-contract-default-status
shrabantipaul-collate Sep 8, 2026
d1763bb
fix(test): use popupClassName + title selector for contract status dr…
Sep 8, 2026
1516431
Merge branch 'main' into fix/data-contract-default-status
shrabantipaul-collate Sep 8, 2026
a268be3
Merge branch 'main' into fix/data-contract-default-status
shrabantipaul-collate Sep 9, 2026
a48b6b7
Merge branch 'main' into fix/data-contract-default-status
shrabantipaul-collate Sep 9, 2026
b97b7d9
Merge branch 'main' into fix/data-contract-default-status
shrabantipaul-collate Sep 9, 2026
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 @@ -71,7 +71,8 @@ const DATA_PRODUCT_SLA = {
const fillContractDetailsForm = async (
page: Page,
contractName: string,
description: string
description: string,
status?: 'Draft' | 'In Review' | 'Approved'
) => {
await page.getByTestId('contract-name').fill(contractName);
await page.fill('.om-block-editor[contenteditable="true"]', description);
Expand All @@ -82,6 +83,14 @@ const fillContractDetailsForm = async (
await firstOwner.click();

await expect(page.getByTestId('user-tag')).toBeVisible();

if (status) {
await page.getByTestId('contract-status').click();
await expect(
page.locator(`.contract-status-dropdown [title="${status}"]`)
).toBeVisible();
await page.locator(`.contract-status-dropdown [title="${status}"]`).click();
}
};

const fillTermsOfServiceForm = async (page: Page, termsContent: string) => {
Expand Down Expand Up @@ -440,7 +449,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
DATA_PRODUCT_CONTRACT_DETAILS.name,
DATA_PRODUCT_CONTRACT_DETAILS.description
DATA_PRODUCT_CONTRACT_DETAILS.description,
'Approved'
);
});

Expand Down Expand Up @@ -565,7 +575,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
`dp_partial_${uuid()}`,
'Data Product contract for partial inheritance'
'Data Product contract for partial inheritance',
'Approved'
);
});

Expand Down Expand Up @@ -683,7 +694,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
`dp_sla_edit_test_${uuid()}`,
'Data Product contract with SLA for edit test'
'Data Product contract with SLA for edit test',
'Approved'
);
});

Expand Down Expand Up @@ -860,7 +872,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
DP_CONTRACT_DETAILS.name,
DP_CONTRACT_DETAILS.description
DP_CONTRACT_DETAILS.description,
'Approved'
);

await fillTermsOfServiceForm(page, DP_CONTRACT_DETAILS.termsOfService);
Expand Down Expand Up @@ -1000,7 +1013,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
DP_CONTRACT_DETAILS.name,
DP_CONTRACT_DETAILS.description
DP_CONTRACT_DETAILS.description,
'Approved'
);

await saveContract(page);
Expand Down Expand Up @@ -1069,7 +1083,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
DP_CONTRACT_DETAILS.name,
DP_CONTRACT_DETAILS.description
DP_CONTRACT_DETAILS.description,
'Approved'
);

await saveContract(page);
Expand Down Expand Up @@ -1150,7 +1165,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
DP_CONTRACT_DETAILS.name,
DP_CONTRACT_DETAILS.description
DP_CONTRACT_DETAILS.description,
'Approved'
);

await saveContract(page);
Expand Down Expand Up @@ -1250,7 +1266,8 @@ test.describe('Data Contract Inheritance', () => {
await fillContractDetailsForm(
page,
DP_CONTRACT_DETAILS.name,
DP_CONTRACT_DETAILS.description
DP_CONTRACT_DETAILS.description,
'Approved'
);

await fillTermsOfServiceForm(page, DP_CONTRACT_DETAILS.termsOfService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import { EDataContractTab } from '../../../constants/DataContract.constants';
import { EntityType } from '../../../enums/entity.enum';
import {
DataContract,
EntityStatus,
SemanticsRule,
} from '../../../generated/entity/data/dataContract';
import { Column, Table } from '../../../generated/entity/data/table';
import { EntityStatus } from '../../../generated/entity/domains/dataProduct';
import { EntityReference } from '../../../generated/entity/type';
import { createContract, updateContract } from '../../../rest/contractAPI';
import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils';
Expand Down Expand Up @@ -96,6 +96,10 @@ jest.mock('../ContractDetailFormTab/ContractDetailFormTab', () => ({
<button onClick={() => onChange({ name: 'Test Contract Change' })}>
Change
</button>
<button
onClick={() => onChange({ entityStatus: EntityStatus.InReview })}>
Change Status
</button>
<button onClick={onNext}>Next</button>
</div>
)),
Expand Down Expand Up @@ -442,7 +446,7 @@ describe('AddDataContract', () => {
type: EntityType.TABLE,
},
semantics: undefined, // validSemantics - undefined when no semantics provided
entityStatus: EntityStatus.Approved,
entityStatus: EntityStatus.Draft,
})
);
expect(showSuccessToast).toHaveBeenCalledWith(
Expand Down Expand Up @@ -474,7 +478,7 @@ describe('AddDataContract', () => {
type: EntityType.TABLE,
},
semantics: undefined, // validSemantics - undefined when no semantics provided
entityStatus: EntityStatus.Approved,
entityStatus: EntityStatus.Draft,
})
);
expect(showSuccessToast).toHaveBeenCalledWith(
Expand All @@ -483,6 +487,32 @@ describe('AddDataContract', () => {
expect(mockOnSave).toHaveBeenCalled();
});

it('should use selected entity status when creating a contract', async () => {
render(<AddDataContract onCancel={mockOnCancel} onSave={mockOnSave} />);

const changeButton = screen.getByText('Change');
await act(async () => {
fireEvent.click(changeButton);
});

const statusButton = screen.getByText('Change Status');
await act(async () => {
fireEvent.click(statusButton);
});

const saveButton = screen.getByTestId('save-contract-btn');

await act(async () => {
fireEvent.click(saveButton);
});

expect(createContract).toHaveBeenCalledWith(
expect.objectContaining({
entityStatus: EntityStatus.InReview,
})
);
});

it('should call updateContract for existing contract with JSON patch', async () => {
render(
<AddDataContract
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@
semantics: validSemantics,
security: validSecurity,
termsOfUse: termsOfUseContent,
entityStatus: EntityStatus.Approved,
entityStatus: formValues.entityStatus ?? EntityStatus.Draft,
});
}

Expand All @@ -300,7 +300,7 @@
} finally {
setIsSubmitting(false);
}
}, [

Check warning on line 303 in openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.tsx

View workflow job for this annotation

GitHub Actions / checkstyle

React Hook useCallback has missing dependencies: 'onSave' and 't'. Either include them or remove the dependency array. If 'onSave' changes too often, find the parent component that defines it and wrap that definition in useCallback
contract,
filteredContract,
formValues,
Expand Down Expand Up @@ -515,7 +515,7 @@
];

return tabs.filter((tab) => entityContractTabs.includes(Number(tab.key)));
}, [

Check warning on line 518 in openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.tsx

View workflow job for this annotation

GitHub Actions / checkstyle

React Hook useMemo has a missing dependency: 't'. Either include it or remove the dependency array
entityContractTabs,
filteredContract,
onFormChange,
Expand Down Expand Up @@ -558,7 +558,7 @@
</div>
</div>
);
}, [

Check warning on line 561 in openmetadata-ui/src/main/resources/ui/src/components/DataContract/AddDataContract/AddDataContract.tsx

View workflow job for this annotation

GitHub Actions / checkstyle

React Hook useMemo has a missing dependency: 't'. Either include it or remove the dependency array
mode,
isSubmitting,
isSaveDisabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 { FieldTypes } from '../../../interface/FormUtils.interface';
import { ContractDetailFormTab } from './ContractDetailFormTab';

jest.mock('../../../utils/formUtils', () => ({
Expand Down Expand Up @@ -47,6 +51,10 @@ jest.mock('react-i18next', () => ({
const translations: Record<string, string> = {
'label.contract-title': 'Contract Title',
'label.owner-plural': 'Owners',
'label.status': 'Status',
'label.draft': 'Draft label',
'label.in-review': 'In Review label',
'label.approved': 'Approved label',
'label.description': 'Description',
'label.contract-detail-plural': 'Contract Details',
'message.contract-detail-plural-description': 'Enter contract details',
Expand Down Expand Up @@ -99,6 +107,7 @@ describe('ContractDetailFormTab', () => {

expect(screen.getByText('Enter contract details')).toBeInTheDocument();
expect(screen.getByText('Contract Title')).toBeInTheDocument();
expect(screen.getByText('Status')).toBeInTheDocument();
expect(screen.getByText('Owners')).toBeInTheDocument();
expect(screen.getByText('Description')).toBeInTheDocument();
});
Expand Down Expand Up @@ -127,6 +136,7 @@ describe('ContractDetailFormTab', () => {
render(<ContractDetailFormTab {...commonProps} />);

expect(screen.getByText('Contract Title')).toBeInTheDocument();
expect(screen.getByText('Status')).toBeInTheDocument();
expect(screen.getByText('Description')).toBeInTheDocument();
expect(screen.getByText('Owners')).toBeInTheDocument();
});
Expand Down Expand Up @@ -261,6 +271,21 @@ describe('ContractDetailFormTab', () => {
name: 'owners',
label: 'Owners',
}),
expect.objectContaining({
formItemProps: {
initialValue: EntityStatus.Draft,
},
name: 'entityStatus',
label: 'Status',
props: expect.objectContaining({
options: [
{ label: 'Draft label', value: EntityStatus.Draft },
{ label: 'In Review label', value: EntityStatus.InReview },
{ label: 'Approved label', value: EntityStatus.Approved },
],
}),
type: FieldTypes.SELECT,
}),
expect.objectContaining({
name: 'description',
label: 'Description',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,31 @@
import { useTranslation } from 'react-i18next';
import { ReactComponent as RightIcon } from '../../../assets/svg/right-arrow.svg';
import { EntityType } from '../../../enums/entity.enum';
import { DataContract } from '../../../generated/entity/data/dataContract';
import {
DataContract,
EntityStatus,
} from '../../../generated/entity/data/dataContract';
import { useEntityRules } from '../../../hooks/useEntityRules';
import { FieldProp, FieldTypes } from '../../../interface/FormUtils.interface';
import { getEntityName } from '../../../utils/EntityNameUtils';
import { generateFormFields } from '../../../utils/formUtils';
import './contract-detail-form-tab.less';

const DATA_CONTRACT_STATUS_OPTION_KEYS = [
{
labelKey: 'label.draft',
value: EntityStatus.Draft,
},
{
labelKey: 'label.in-review',
value: EntityStatus.InReview,
},
{
labelKey: 'label.approved',
value: EntityStatus.Approved,
},
];

export const ContractDetailFormTab: React.FC<{
initialValues?: Partial<DataContract>;
onNext: () => void;
Expand All @@ -40,6 +58,12 @@
const { t } = useTranslation();
const [form] = Form.useForm();
const { entityRules } = useEntityRules(EntityType.TABLE);
const dataContractStatusOptions = DATA_CONTRACT_STATUS_OPTION_KEYS.map(
({ labelKey, value }) => ({
label: t(labelKey),
value,
})
);

const fields: FieldProp[] = [
{
Expand All @@ -55,6 +79,22 @@
'data-testid': 'contract-name',
},
},
{
label: t('label.status'),
id: 'entityStatus',
name: 'entityStatus',
type: FieldTypes.SELECT,
required: false,
placeholder: t('label.select-field', { field: t('label.status') }),
props: {
'data-testid': 'contract-status',
options: dataContractStatusOptions,
popupClassName: 'contract-status-dropdown',
},
formItemProps: {
initialValue: initialValues?.entityStatus ?? EntityStatus.Draft,
},
},
{
label: t('label.owner-plural'),
name: 'owners',
Expand Down Expand Up @@ -95,10 +135,11 @@
form.setFieldsValue({
name: getEntityName(initialValues),
description: initialValues.description,
entityStatus: initialValues.entityStatus ?? EntityStatus.Draft,
owners: initialValues.owners,
});
}
}, [initialValues]);

Check warning on line 142 in openmetadata-ui/src/main/resources/ui/src/components/DataContract/ContractDetailFormTab/ContractDetailFormTab.tsx

View workflow job for this annotation

GitHub Actions / checkstyle

React Hook useEffect has a missing dependency: 'form'. Either include it or remove the dependency array

return (
<>
Expand Down
Loading