Moin @quynh-still-birch,
I created the following example for triggering all computations for existing documents using the Project Template:
initialComputeDataProvider.ts
import { call, put, select } from "typed-redux-saga";
import { Model, ModelSelectors } from "@com.mgmtp.a12.client/client-core/lib/core/model";
import { DataProvider } from "@com.mgmtp.a12.client/client-core/lib/core/data";
import { Activity, ActivityActions, ActivitySelectors } from "@com.mgmtp.a12.client/client-core/lib/core/activity";
import {
DocumentJsonRpc2Request,
JsonRpc2Request,
JsonRpc2ResponseOK
} from "@com.mgmtp.a12.dataservices/dataservices-access";
import {
ConnectorLocator,
RestRequestPayload,
RestServerConnector
} from "@com.mgmtp.a12.utils/utils-connector/lib/main";
import {
DocumentRtService,
DocumentRtServiceFactory,
DocumentServiceFactory
} from "@com.mgmtp.a12.kernel/kernel-md-facade";
const documentService = new DocumentServiceFactory().getDocumentService();
export function initialComputeDataProvider(): DataProvider {
const name = "InitialComputeDataProvider";
let operationCounter = 0;
return {
name,
canHandle({ operation, dataHolder }) {
const descriptorInstance = dataHolder.descriptor.instance;
const descriptorModel = dataHolder.descriptor.model;
// This DataProvider shall only serve data when an existing document is loaded
if (operation === "load" && descriptorInstance && descriptorModel) {
return (descriptorInstance as string).includes(descriptorModel);
}
return false;
},
*provideData({ activityId, dataHolders, ...config }) {
if (config.operation !== "load") {
throw new Error(`${name} does not support ${config.operation}.`);
}
const activity = yield* select(ActivitySelectors.activityById(activityId));
const dataHolder = Activity.findDefaultDataHolder(activity);
if (!dataHolder) {
throw new Error("Activity Dataholder does not exist.");
}
const activityDescriptor: Activity.DataHolderDescriptor = dataHolder.descriptor;
if (!activityDescriptor.instance) {
throw new Error("Activity Descriptor Instance does not exist.");
}
// Retrieve document for given document reference
const getDocumentRpcRequest: DocumentJsonRpc2Request.GetDocumentJsonRpc2Request = {
jsonrpc: "2.0",
method: "GET_DOCUMENT",
id: `GET_DOCUMENT-${++operationCounter}`,
params: {
docRef: activityDescriptor.instance
}
};
const [{ result }] = yield* call(() => dispatchJsonRpc2Requests(getDocumentRpcRequest));
const { document, docRef, documentModelName } = result;
// Select DocumentModel for the generated code
if (!activityDescriptor.model) {
throw new Error("Activity Descriptor Model does not exist.");
}
const documentModelSelector = ModelSelectors.modelByName(
documentModelName,
Model.isDocumentAndValidationModel
);
const documentModel = yield* select(documentModelSelector);
if (!documentModel) {
throw new Error("Document Model could not be loaded.");
}
// Compute document with 'DocumentRtService'
const documentRtService: DocumentRtService = DocumentRtServiceFactory.createDocumentRtService(
documentModel.generatedCodeAccessor
);
const computationResult = documentRtService.compute(document);
// TODO: Error handling in case of computation failing
const computedDocument = documentRtService.applyComputationResult(computationResult, document);
// Provide the data with computed document
yield* put(
ActivityActions.setData({
activityId,
data: {
document: {
id: docRef,
modelId: documentModelName,
...documentService.parseDates(computedDocument, documentModel)
}
}
})
);
}
};
}
async function dispatchJsonRpc2Requests(...requests: JsonRpc2Request[]): Promise<JsonRpc2ResponseOK[]> {
const request = JsonRpc2Request.build(requests);
return await RestRequestDispatcher.json(request);
}
const RestRequestDispatcher = {
async json<T>(request: RestRequestPayload): Promise<T> {
const response = await fetchServerRequest(request);
return await response.json();
}
};
async function fetchServerRequest(request: RestRequestPayload): Promise<Response> {
const response = await (ConnectorLocator.getInstance().getServerConnector() as RestServerConnector).fetchData(
request
);
if (!response.ok) {
throw new Error(response.statusText);
}
return response;
}
Then registering the Data Provider in the setup.
appsetup.ts
const dataHandlers: DataHandlers = {
dataEditors: [],
dataLoaders: platformServerConnectors.loaders.dataLoaders,
dataProviders: [
initialComputeDataProvider(),
cddDataProvider,
RelationshipFactories.createRelationshipDataProvider(),
createEmptyDocumentDataProvider()
]
};