108 lines
2.9 KiB
TypeScript
108 lines
2.9 KiB
TypeScript
import type { UsageReport } from './product-usage';
|
|
|
|
export type ExperimentValues = Record<string, string>;
|
|
export type ExperimentDocument = {
|
|
definition_version: string;
|
|
version: number;
|
|
at: string;
|
|
actor: { id: number; name: string };
|
|
reason: string;
|
|
values: ExperimentValues;
|
|
indicator: {
|
|
id: string;
|
|
title: string;
|
|
unit: string;
|
|
source: string;
|
|
limits: string;
|
|
definition_version: string;
|
|
} | null;
|
|
plan_sha256: string;
|
|
observation_plan_sha256: string | null;
|
|
registration: {
|
|
first_at: string | null;
|
|
original_plan_sha256: string | null;
|
|
amendments: number;
|
|
amended_after_observation: boolean;
|
|
};
|
|
operational_report: UsageReport | null;
|
|
report_matches_observation: boolean | null;
|
|
report_scope: string;
|
|
};
|
|
export type ExperimentView = {
|
|
installed: boolean;
|
|
id: string | null;
|
|
currentVersion: number;
|
|
historical: boolean;
|
|
document: ExperimentDocument | null;
|
|
values: ExperimentValues;
|
|
states: Record<string, string>;
|
|
changeKinds: Record<string, string>;
|
|
decisions: Record<string, string>;
|
|
labels: Record<string, string>;
|
|
catalogue: {
|
|
definition_version: string;
|
|
items: Omit<
|
|
NonNullable<ExperimentDocument['indicator']>,
|
|
'definition_version'
|
|
>[];
|
|
services: { code: string; title: string; version: number }[];
|
|
};
|
|
history: {
|
|
version: number;
|
|
at: string;
|
|
actor: string;
|
|
state: string;
|
|
reason: string;
|
|
}[];
|
|
historyNext: number | null;
|
|
};
|
|
|
|
export function experimentDifferences(
|
|
base: ExperimentValues,
|
|
mine: ExperimentValues,
|
|
current: ExperimentValues,
|
|
editedKeys?: readonly string[],
|
|
): string[] {
|
|
return [
|
|
...new Set([
|
|
...Object.keys(base),
|
|
...Object.keys(mine),
|
|
...Object.keys(current),
|
|
]),
|
|
].filter(
|
|
(key) =>
|
|
(base[key] ?? '') !== (current[key] ?? '') &&
|
|
(editedKeys
|
|
? editedKeys.includes(key)
|
|
: (mine[key] ?? '') !== (base[key] ?? '')) &&
|
|
(mine[key] ?? '') !== (current[key] ?? ''),
|
|
);
|
|
}
|
|
|
|
/** Merge only changes the user did not edit; conflicts remain explicit. */
|
|
export function mergeExperimentValues(
|
|
base: ExperimentValues,
|
|
mine: ExperimentValues,
|
|
current: ExperimentValues,
|
|
editedKeys?: readonly string[],
|
|
): ExperimentValues {
|
|
return Object.fromEntries(
|
|
[
|
|
...new Set([
|
|
...Object.keys(base),
|
|
...Object.keys(mine),
|
|
...Object.keys(current),
|
|
]),
|
|
].map((key) => [
|
|
key,
|
|
(
|
|
editedKeys
|
|
? !editedKeys.includes(key)
|
|
: (mine[key] ?? '') === (base[key] ?? '')
|
|
)
|
|
? (current[key] ?? '')
|
|
: (mine[key] ?? ''),
|
|
]),
|
|
);
|
|
}
|