Skip to content
Open
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
4 changes: 2 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2026-04-20T04:35:46.003Z\n"
"PO-Revision-Date: 2026-04-20T04:35:46.003Z\n"
"POT-Creation-Date: 2026-04-27T07:43:21.475Z\n"
"PO-Revision-Date: 2026-04-27T07:43:21.476Z\n"

msgid ""
"THIS NEW RELEASE INCLUDES SHARING SETTINGS PER INSTANCES. FOR THIS VERSION "
Expand Down
19 changes: 14 additions & 5 deletions src/data/metadata/MetadataD2ApiRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,20 @@ export class MetadataD2ApiRepository implements MetadataRepository {
public async getMetadataByIds<T>(
ids: string[],
fields?: object | string,
includeDefaults = false
includeDefaults = false,
preserveNestedDefaultRefs = false
): Promise<MetadataPackage<T>> {
const { apiVersion } = this.targetInstance;

const d2ApiDataStore = new D2ApiDataStore(this.targetInstance);
const dataStoreIds = DataStoreMetadata.getDataStoreIds(ids);
const requestFields = typeof fields === "object" ? getFieldsAsString(fields) : fields;
const d2Metadata = await this.getMetadata<D2Model>(ids, requestFields, includeDefaults);
const d2Metadata = await this.getMetadata<D2Model>(
ids,
requestFields,
includeDefaults,
preserveNestedDefaultRefs
);

if (apiVersion >= 32 && d2Metadata["dashboards"] && fields === undefined) {
//Fix dashboard bug from 2.32
Expand All @@ -84,7 +90,8 @@ export class MetadataD2ApiRepository implements MetadataRepository {
const fixedD2Metadata = await this.getMetadata<D2Model>(
ids,
":all,dashboardItems[:all,visualization[id,type]]",
includeDefaults
includeDefaults,
preserveNestedDefaultRefs
);

const metadataPackage = this.transformationRepository.mapPackageFrom(
Expand Down Expand Up @@ -589,11 +596,13 @@ export class MetadataD2ApiRepository implements MetadataRepository {
private async getMetadata<T>(
elements: string[],
fields = ":all",
includeDefaults: boolean
includeDefaults: boolean,
preserveNestedDefaultRefs: boolean
): Promise<Record<string, T[]>> {
try {
const promises = [];
const chunkSize = 50;
const keepDefaults = includeDefaults || preserveNestedDefaultRefs;

for (let i = 0; i < elements.length; i += chunkSize) {
const requestElements = elements.slice(i, i + chunkSize).toString();
Expand All @@ -602,7 +611,7 @@ export class MetadataD2ApiRepository implements MetadataRepository {
.get("/metadata", {
fields,
filter: "id:in:[" + requestElements + "]",
defaults: includeDefaults ? undefined : "EXCLUDE",
defaults: keepDefaults ? undefined : "EXCLUDE",
})
.getData()
);
Expand Down
8 changes: 7 additions & 1 deletion src/domain/metadata/builders/MetadataPayloadBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,13 @@ export class MetadataPayloadBuilder {
// Get all the required metadata
const originInstance = await this.getOriginInstance(originInstanceId);
const metadataRepository = this.repositoryFactory.metadataRepository(originInstance);
const syncMetadata = await metadataRepository.getMetadataByIds(newIds);
// DataSets need preserveNestedDefaultRefs because the server-side defaults=EXCLUDE
// strips the default categoryOptionCombo.id from compulsoryDataElementOperands,
// which then fails on import. Client-side default stripping still runs.
const syncMetadata =
type === "dataSets"
? await metadataRepository.getMetadataByIds(newIds, undefined, false, true)
: await metadataRepository.getMetadataByIds(newIds);
const elements = syncMetadata[collectionName] || [];
this.registry.addList(builder, newIds);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,10 @@ describe("MetadataPayloadBuilder", () => {
if (includeObjectsAndReferences) {
const metadataByIdsResponses = getDataSetMetadataByIdsResponsesWithIncludeAll();

when(
mockedMetadataRepository.getMetadataByIds(anything(), anything(), anything(), anything())
).thenResolve(metadataByIdsResponses.first);
when(mockedMetadataRepository.getMetadataByIds(anything()))
.thenResolve(metadataByIdsResponses.first)
.thenResolve(metadataByIdsResponses.second)
.thenResolve(metadataByIdsResponses.third)
.thenResolve(metadataByIdsResponses.fourth)
Expand All @@ -359,8 +361,12 @@ describe("MetadataPayloadBuilder", () => {
.thenResolve(metadataByIdsResponses.seventh)
.thenResolve(metadataByIdsResponses.eighth);
} else {
when(
mockedMetadataRepository.getMetadataByIds(anything(), anything(), anything(), anything())
).thenResolve({
dataSets: [getDataSetMetadata()],
});
when(mockedMetadataRepository.getMetadataByIds(anything()))
.thenResolve({ dataSets: [getDataSetMetadata()] })
.thenResolve({
dataSets: [getDataSetMetadata()],
dataElements: [getDataElementDataSetMetadata()],
Expand Down
7 changes: 6 additions & 1 deletion src/domain/metadata/repositories/MetadataRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import {
import { MetadataImportParams } from "../entities/MetadataSynchronizationParams";

export interface MetadataRepository {
getMetadataByIds<T>(ids: Id[], fields?: object | string, includeDefaults?: boolean): Promise<MetadataPackage<T>>;
getMetadataByIds<T>(
ids: Id[],
fields?: object | string,
includeDefaults?: boolean,
preserveNestedDefaultRefs?: boolean
): Promise<MetadataPackage<T>>;
getByFilterRules(filterRules: FilterRule[]): Promise<Id[]>;
getDefaultIds(filter?: string): Promise<string[]>;
getCategoryOptionCombos(): Promise<
Expand Down
Loading