@agridea/suibi-module 0.1.0-preview.09bcbd4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/elements/browser/main.js +78 -0
  4. package/dist/elements/browser/polyfills.js +1 -0
  5. package/dist/elements/browser/styles.css +1 -0
  6. package/dist/elements/browser/suibi-module-latest.css +1 -0
  7. package/dist/elements/browser/suibi-module-latest.js +78 -0
  8. package/dist/elements/browser/suibi-module.v0.1.0-preview.09bcbd4.css +1 -0
  9. package/dist/elements/browser/suibi-module.v0.1.0-preview.09bcbd4.js +78 -0
  10. package/dist/elements/browser/suibi-theme-dark.css +1 -0
  11. package/dist/elements/browser/version.txt +1 -0
  12. package/dist/elements/browser/wc-global-utilities.css +1 -0
  13. package/dist/types/app/app.config.d.ts +2 -0
  14. package/dist/types/app/app.d.ts +34 -0
  15. package/dist/types/app/components/add-dashed-button/add-dashed-button.component.d.ts +9 -0
  16. package/dist/types/app/components/data-preview/data-preview.component.d.ts +12 -0
  17. package/dist/types/app/components/empty-state/empty-state.component.d.ts +12 -0
  18. package/dist/types/app/components/module-placeholder-page/module-placeholder-page.component.d.ts +6 -0
  19. package/dist/types/app/components/planning-result/planning-result.component.d.ts +46 -0
  20. package/dist/types/app/components/planning-result/planning-trigger.component.d.ts +13 -0
  21. package/dist/types/app/components/results-page/results-page.component.d.ts +13 -0
  22. package/dist/types/app/components/suissebilanz-dashboard/gauge-arc.component.d.ts +47 -0
  23. package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts +24 -0
  24. package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-metrics.service.d.ts +21 -0
  25. package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-minibar.component.d.ts +19 -0
  26. package/dist/types/app/components/validation-page/validation-page.component.d.ts +18 -0
  27. package/dist/types/app/components/welcome-page/metadata.types.d.ts +1 -0
  28. package/dist/types/app/components/welcome-page/welcome-page.component.d.ts +28 -0
  29. package/dist/types/app/components/workflow-stepper/workflow-stepper.component.d.ts +49 -0
  30. package/dist/types/app/core/data/naebi-data.service.d.ts +278 -0
  31. package/dist/types/app/core/error/global-error-handler.d.ts +6 -0
  32. package/dist/types/app/core/events/suibi-data-emitter.service.d.ts +13 -0
  33. package/dist/types/app/core/events/suibi-data-event.d.ts +26 -0
  34. package/dist/types/app/core/i18n/i18n.service.d.ts +20 -0
  35. package/dist/types/app/core/i18n/locales/de.d.ts +2 -0
  36. package/dist/types/app/core/i18n/locales/en.d.ts +2 -0
  37. package/dist/types/app/core/master-data/master-data.service.d.ts +32 -0
  38. package/dist/types/app/core/metadata/suibi-metadata.service.d.ts +6 -0
  39. package/dist/types/app/core/metadata/suibi-metadata.types.d.ts +8 -0
  40. package/dist/types/app/core/navigation/navigation.service.d.ts +100 -0
  41. package/dist/types/app/core/planning/planning-balance.service.d.ts +37 -0
  42. package/dist/types/app/core/planning/planning-balance.types.d.ts +206 -0
  43. package/dist/types/app/core/planning/planning-balance.utils.d.ts +10 -0
  44. package/dist/types/app/core/schemas/index.d.ts +18 -0
  45. package/dist/types/app/core/schemas/schema-localization.util.d.ts +18 -0
  46. package/dist/types/app/core/schemas/schema-merge.util.d.ts +26 -0
  47. package/dist/types/app/core/schemas/ui-helper-registry.d.ts +16 -0
  48. package/dist/types/app/core/telemetry/telemetry.service.d.ts +12 -0
  49. package/dist/types/app/core/utils/object.util.d.ts +24 -0
  50. package/dist/types/app/core/validation/ajv-custom.d.ts +15 -0
  51. package/dist/types/app/core/validation/capabilities.d.ts +18 -0
  52. package/dist/types/app/core/validation/error-formatter.d.ts +19 -0
  53. package/dist/types/app/core/validation/global-validation.service.d.ts +59 -0
  54. package/dist/types/app/core/validation/validation-errors-panel.d.ts +36 -0
  55. package/dist/types/app/header-bar.d.ts +14 -0
  56. package/dist/types/app/jsonforms/constraints/constraint-resolvers.d.ts +50 -0
  57. package/dist/types/app/jsonforms/filters/code-list-filter-resolvers.d.ts +63 -0
  58. package/dist/types/app/jsonforms/registry/renderers.registry.d.ts +34 -0
  59. package/dist/types/app/jsonforms/renderers/controls/selects/animal-category/animal-category-select.renderer.d.ts +21 -0
  60. package/dist/types/app/jsonforms/renderers/controls/selects/code-list/code-list-select.renderer.d.ts +34 -0
  61. package/dist/types/app/jsonforms/renderers/layout/array/array-layout.renderer.d.ts +43 -0
  62. package/dist/types/app/jsonforms/renderers/layout/categorization/selected-category-categorization.renderer.d.ts +34 -0
  63. package/dist/types/app/jsonforms/renderers/layout/constraint/constraint-layout.renderer.d.ts +30 -0
  64. package/dist/types/app/jsonforms/renderers/layout/group/base-group.renderer.d.ts +29 -0
  65. package/dist/types/app/jsonforms/renderers/layout/group/card-group.renderer.d.ts +6 -0
  66. package/dist/types/app/jsonforms/renderers/layout/group/group-testers.d.ts +4 -0
  67. package/dist/types/app/jsonforms/renderers/layout/group/logical-group.renderer.d.ts +6 -0
  68. package/dist/types/app/jsonforms/renderers/layout/group/plain-group.renderer.d.ts +6 -0
  69. package/dist/types/app/jsonforms/shared/base-control/base-select-control.d.ts +16 -0
  70. package/dist/types/app/jsonforms/shared/option-sources/code-lists.d.ts +11 -0
  71. package/dist/types/app/jsonforms/shared/validation/field-error.service.d.ts +18 -0
  72. package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-detail.component.d.ts +22 -0
  73. package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-list.component.d.ts +21 -0
  74. package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-master-detail.component.d.ts +24 -0
  75. package/dist/types/app/nutrient-cycle/animal-stock/animal-stock.types.d.ts +69 -0
  76. package/dist/types/app/nutrient-cycle/animal-stock/index.d.ts +4 -0
  77. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-detail.component.d.ts +27 -0
  78. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-list.component.d.ts +23 -0
  79. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-master-detail.component.d.ts +25 -0
  80. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading.types.d.ts +27 -0
  81. package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +4 -0
  82. package/dist/types/app/nutrient-cycle/farm-manure-trading/transaction-unit.util.d.ts +1 -0
  83. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-detail.component.d.ts +22 -0
  84. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-general.component.d.ts +22 -0
  85. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-list.component.d.ts +17 -0
  86. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-master-detail.component.d.ts +36 -0
  87. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.types.d.ts +40 -0
  88. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.util.d.ts +6 -0
  89. package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.component.d.ts +21 -0
  90. package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.types.d.ts +43 -0
  91. package/dist/types/app/nutrient-cycle/field-spreading/index.d.ts +2 -0
  92. package/dist/types/app/nutrient-cycle/fodder/fodder-detail.component.d.ts +32 -0
  93. package/dist/types/app/nutrient-cycle/fodder/fodder-list.component.d.ts +21 -0
  94. package/dist/types/app/nutrient-cycle/fodder/fodder-master-detail.component.d.ts +37 -0
  95. package/dist/types/app/nutrient-cycle/fodder/fodder.types.d.ts +27 -0
  96. package/dist/types/app/nutrient-cycle/fodder/transaction-unit.util.d.ts +2 -0
  97. package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance-form.component.d.ts +27 -0
  98. package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance.types.d.ts +5 -0
  99. package/dist/types/app/nutrient-cycle/storage/storage-detail.component.d.ts +30 -0
  100. package/dist/types/app/nutrient-cycle/storage/storage-general.component.d.ts +29 -0
  101. package/dist/types/app/nutrient-cycle/storage/storage-list.component.d.ts +20 -0
  102. package/dist/types/app/nutrient-cycle/storage/storage-master-detail.component.d.ts +31 -0
  103. package/dist/types/app/nutrient-cycle/storage/storage.types.d.ts +40 -0
  104. package/dist/types/environments/environment.d.ts +11 -0
  105. package/dist/types/public-api.d.ts +6 -0
  106. package/dist/types/shared/material-icons.d.ts +16 -0
  107. package/package.json +91 -0
@@ -0,0 +1,206 @@
1
+ /**
2
+ * TypeScript interfaces for the planning-balance API response.
3
+ * These match the eBilanz / BLW response shape observed in the example data.
4
+ */
5
+ /** A single nutrient quantity entry (kg or % unit). */
6
+ export interface NutrientEntry {
7
+ molecularFormula: string;
8
+ quantity: number;
9
+ quantityCorrected?: number;
10
+ unit: string;
11
+ productFamilyType?: string;
12
+ typeOfManureRecyclingProduct?: string;
13
+ fertiliserProductCategory?: string;
14
+ }
15
+ export interface CalculationVersion {
16
+ version: string;
17
+ validFrom: string;
18
+ validTo: string;
19
+ }
20
+ export interface AreaAndYieldPerAgronomicCropCategory {
21
+ agronomicCropCategory: string;
22
+ areaSize: number;
23
+ effectiveYield: number;
24
+ isMainCrop: boolean;
25
+ isNutrientPoorFodder: boolean;
26
+ yieldPerSquareMeasure?: number;
27
+ }
28
+ export interface AreaPerCultivationType {
29
+ areaSize: number;
30
+ isMainCrop: boolean;
31
+ }
32
+ export interface AreaAndYieldPerCultivationCategory {
33
+ cultivationCategory: string;
34
+ areaAndYieldPerAgronomicCropCategory: AreaAndYieldPerAgronomicCropCategory[];
35
+ areaPerCultivationType: AreaPerCultivationType[];
36
+ }
37
+ export interface AreaPerSubCategory {
38
+ cultivationSubCategory: string;
39
+ areaSize: number;
40
+ isMainCrop: boolean;
41
+ }
42
+ export interface FieldCultivation {
43
+ areaAndYieldPerCultivationCategory: AreaAndYieldPerCultivationCategory[];
44
+ areaPerSubCategory: AreaPerSubCategory[];
45
+ fertilizableAreaSize: number;
46
+ slurrySpreadingAreaSize: number;
47
+ totalAgriculturalLandAreaSize: number;
48
+ }
49
+ export interface FodderQuantity {
50
+ quantity: number;
51
+ unit: string;
52
+ proportionNutrientPoorFodder?: number;
53
+ }
54
+ export interface FodderProduct {
55
+ typeOfFeedstuffProduct: string;
56
+ quantity: number;
57
+ unit: string;
58
+ isNutrientPoorFodder: boolean;
59
+ }
60
+ export interface ConsumptionAnimalStock {
61
+ animalCategoryPRIF: number;
62
+ averageQuantity: number;
63
+ order: string;
64
+ quantity: number;
65
+ unit: string;
66
+ }
67
+ export interface RequiredEffectiveYieldFromFodderCropland {
68
+ consumptionAnimalStock: ConsumptionAnimalStock[];
69
+ cropFromNonFodderCroplandPerProduct: FodderProduct[];
70
+ dispensePerProduct: FodderProduct[];
71
+ supplyPerProduct: FodderProduct[];
72
+ totalBalance: FodderQuantity;
73
+ totalConsumptionAnimalStock: FodderQuantity;
74
+ totalCropFromNonFodderCropland: FodderQuantity;
75
+ totalDispense: FodderQuantity;
76
+ totalSupply: FodderQuantity;
77
+ }
78
+ export interface FodderBalance {
79
+ requiredEffectiveYieldFromFodderCropland: RequiredEffectiveYieldFromFodderCropland;
80
+ totalBalance: FodderQuantity;
81
+ totalEffectiveYieldFromFodderCropland: FodderQuantity;
82
+ totalNutrientPoorFodder: FodderQuantity;
83
+ }
84
+ export interface EmissionAndAccumulationEntry {
85
+ animalCategoryPRIF: number;
86
+ order: string;
87
+ accumulation: NutrientEntry[];
88
+ emission: NutrientEntry[];
89
+ manureExcretion?: unknown[];
90
+ }
91
+ export interface AccumulationEntireExcretion {
92
+ animalCategoryPRIF: number;
93
+ order: string;
94
+ durationSumTotalCorrectedNutrientBalance: number;
95
+ accumulation: NutrientEntry[];
96
+ }
97
+ export interface TotalNutrientSet {
98
+ accumulation: NutrientEntry[];
99
+ emission?: NutrientEntry[];
100
+ }
101
+ export interface AnimalStock {
102
+ accumulationEntireExcretion: AccumulationEntireExcretion[];
103
+ emissionAndAccumulationPasture: EmissionAndAccumulationEntry[];
104
+ emissionAndAccumulationStall: EmissionAndAccumulationEntry[];
105
+ emissionAndAccumulationYard: EmissionAndAccumulationEntry[];
106
+ totalAccumulationEntireExcretion: TotalNutrientSet;
107
+ totalEmissionAndAccumulationAnimalStock: TotalNutrientSet;
108
+ totalEmissionAndAccumulationPasture: TotalNutrientSet;
109
+ totalEmissionAndAccumulationStall: TotalNutrientSet;
110
+ totalEmissionAndAccumulationYard: TotalNutrientSet;
111
+ }
112
+ export interface ManureTradingProduct {
113
+ typeOfManureRecyclingProduct: string;
114
+ quantity: number;
115
+ unit: string;
116
+ ingredient: NutrientEntry[];
117
+ }
118
+ export interface FarmManureTrading {
119
+ balancePerProduct: ManureTradingProduct[];
120
+ dispensePerProduct: ManureTradingProduct[];
121
+ supplyPerProduct: ManureTradingProduct[];
122
+ totalBalance: {
123
+ ingredient: NutrientEntry[];
124
+ };
125
+ }
126
+ export interface NutrientRequirementEntry {
127
+ agronomicCropCategory?: string;
128
+ cultivationCategory?: string;
129
+ isMainCrop?: boolean;
130
+ requirement: NutrientEntry[];
131
+ }
132
+ export interface FieldCultivationNutrients {
133
+ nutrientTransferUnfertilizedCultivation: NutrientEntry[];
134
+ requirementPerAgronomicCropCategory: NutrientRequirementEntry[];
135
+ requirementPerCultivationCategory: NutrientRequirementEntry[];
136
+ totalRequirement: NutrientEntry[];
137
+ }
138
+ export interface FieldSpreading {
139
+ emissionAndAccumulationFieldSpreading: TotalNutrientSet;
140
+ totalEmissionAndAccumulationFieldSpreading: TotalNutrientSet;
141
+ }
142
+ export interface StorageBalance {
143
+ emissionAndAccumulationManureStorage: TotalNutrientSet;
144
+ totalEmissionAndAccumulationManureStorage: TotalNutrientSet;
145
+ }
146
+ export interface NutrientBalance {
147
+ animalStock: AnimalStock;
148
+ farmManureTrading: FarmManureTrading;
149
+ fieldCultivation: FieldCultivationNutrients;
150
+ fieldSpreading: FieldSpreading;
151
+ storage: StorageBalance;
152
+ /** Final per-nutrient balance figures: kg lines + % lines interleaved. */
153
+ totalBalance: NutrientEntry[];
154
+ /** Farm-wide gas emissions (NH3, NO, N2O, N2). */
155
+ totalEmissionFarm: NutrientEntry[];
156
+ nutrientBalanceTMP?: unknown[];
157
+ }
158
+ export interface NutrientCycle {
159
+ creationDateTime: string;
160
+ facilitySpecificProducts: {
161
+ manureRecyclingProduct: unknown[];
162
+ };
163
+ fieldCultivation: FieldCultivation;
164
+ fodderBalance: FodderBalance;
165
+ nutrientBalance: NutrientBalance;
166
+ version: string;
167
+ /** Base64-encoded PDF report, if returned by the endpoint. */
168
+ report?: string;
169
+ }
170
+ export interface ValidationMessageDetail {
171
+ designation_deu: string;
172
+ designation_eng: string;
173
+ designation_fra: string;
174
+ designation_ita: string;
175
+ }
176
+ export interface ValidationMessage {
177
+ field: string;
178
+ type: string;
179
+ detail: ValidationMessageDetail;
180
+ }
181
+ /** Full response from the planning-balance endpoint. */
182
+ export interface PlanningBalanceResponse {
183
+ calculationVersion: CalculationVersion;
184
+ nutrientCycle: NutrientCycle;
185
+ validationMessage: ValidationMessage[];
186
+ }
187
+ /** Merged kg + % row for the final balance table (Section D). */
188
+ export interface BalanceRow {
189
+ molecularFormula: string;
190
+ quantity: number;
191
+ quantityCorrected: number;
192
+ quantityPct: number | null;
193
+ quantityCorrectedPct: number | null;
194
+ unit: 'kg';
195
+ }
196
+ /** Crop requirement row enriched with area and yield for display (Section C). */
197
+ export interface CropRequirementRow {
198
+ cropCode: string;
199
+ cultivationCategory: string;
200
+ isMainCrop: boolean;
201
+ areaHa: number;
202
+ effectiveYield: number;
203
+ /** kg/ha yield per square measure field (m² basis), converted to dt/ha for display. */
204
+ yieldDtHa: number | null;
205
+ requirement: NutrientEntry[];
206
+ }
@@ -0,0 +1,10 @@
1
+ import type { BalanceRow, NutrientEntry } from './planning-balance.types';
2
+ /**
3
+ * Merges the interleaved kg / % rows from `totalBalance` into one `BalanceRow`
4
+ * per nutrient formula, preserving the canonical KEY_NUTRIENTS display order.
5
+ *
6
+ * The planning-balance API returns two `NutrientEntry` objects per formula
7
+ * (one with `unit === 'kg'`, one with `unit === '%'`). This function coalesces
8
+ * them so callers work with a single, normalised row.
9
+ */
10
+ export declare function mergeBalanceRows(totalBalance: NutrientEntry[]): BalanceRow[];
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Schema utilities for managing UI-only helper fields in JSONForms components.
3
+ *
4
+ * This module provides centralized schema merging and helper field filtering to maintain
5
+ * clean separation between domain schemas (nutrient balance calculation model) and
6
+ * UI-only helper fields that drive conditional rendering logic.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { mergeSchemas, getUiHelperFields, stripUiHelpers } from '@core/schemas';
11
+ * import globalUiExtensions from '@core/schemas/ui-schema-extensions.json';
12
+ *
13
+ * const helpers = getUiHelperFields(globalUiExtensions);
14
+ * const merged = mergeSchemas(domainSchema, globalUiExtensions);
15
+ * const clean = stripUiHelpers(formData, helpers);
16
+ * ```
17
+ */
18
+ export { mergeSchemas, getUiHelperFields, stripUiHelpers } from './schema-merge.util';
@@ -0,0 +1,18 @@
1
+ import { UISchemaElement } from '@jsonforms/core';
2
+ /**
3
+ * Deeply clones a UI schema and translates its labels.
4
+ *
5
+ * This utility is essential for JSONForms integration in a multi-language environment.
6
+ * Since UI schemas are typically static JSON objects, we must clone them before
7
+ * modifying their labels to avoid mutating the shared source or leaking translations
8
+ * across language switches.
9
+ *
10
+ * It traverses:
11
+ * - Nested `elements` arrays (standard layouts)
12
+ * - `options.detail` objects (often used in array controls)
13
+ *
14
+ * @param ui The original UI schema to localize
15
+ * @param translate A function that takes a translation key and returns the translated string
16
+ * @returns A new UI schema object with translated labels
17
+ */
18
+ export declare function cloneAndLocalize(ui: any, translate: (key: string) => string): UISchemaElement;
@@ -0,0 +1,26 @@
1
+ import { JsonSchema } from '@jsonforms/core';
2
+ /**
3
+ * Merges a base domain schema with UI-only extension properties at runtime.
4
+ * Extensions are deep-cloned into the base schema to avoid mutation.
5
+ *
6
+ * @param base - Domain schema (e.g., nutrient balance data model)
7
+ * @param extensions - UI helper schema with `x-ui-helper: true` fields
8
+ * @returns Merged schema suitable for JSONForms consumption
9
+ */
10
+ export declare function mergeSchemas(base: JsonSchema, extensions: JsonSchema): JsonSchema;
11
+ /**
12
+ * Extracts field names marked as UI helpers from a schema.
13
+ * Scans properties for `"x-ui-helper": true` metadata.
14
+ *
15
+ * @param schema - Schema to scan (typically UI extensions schema)
16
+ * @returns Set of field names that should be filtered from persisted data
17
+ */
18
+ export declare function getUiHelperFields(schema: JsonSchema): Set<string>;
19
+ /**
20
+ * Removes all UI helper fields from a data object.
21
+ * Mutates the input object (use with caution; prefer spreading first).
22
+ *
23
+ * @param data - Data object to clean (typically form state)
24
+ * @param helperFields - Set of field names to remove
25
+ */
26
+ export declare function stripUiHelpers<T extends Record<string, any>>(data: T, helperFields: Set<string>): Omit<T, string>;
@@ -0,0 +1,16 @@
1
+ export interface UiHelperDefinitions {
2
+ durationSourceType?: 'tvd-original' | 'tvd-final' | 'self-reported';
3
+ quantity_correction?: boolean;
4
+ }
5
+ export interface UiHelperConfig<K extends keyof UiHelperDefinitions = keyof UiHelperDefinitions> {
6
+ key: K;
7
+ default: () => UiHelperDefinitions[K] | undefined;
8
+ derive?: (domain: any) => UiHelperDefinitions[K] | undefined;
9
+ readonly?: boolean;
10
+ }
11
+ export declare function getHelperKeys(): (keyof UiHelperDefinitions)[];
12
+ export declare function deriveHelpers(domain: any): Partial<UiHelperDefinitions>;
13
+ export declare function augmentData<T extends object>(domain: T): T & UiHelperDefinitions;
14
+ export declare function stripHelpers<T extends object>(data: T): T;
15
+ export declare function prepareJsonFormsData<T extends object>(domain: T | null | undefined): (T & UiHelperDefinitions) | null;
16
+ export declare function sanitizeJsonFormsData<T extends object>(formData: T): T;
@@ -0,0 +1,12 @@
1
+ export declare class TelemetryService {
2
+ private appInsights;
3
+ private isEnabled;
4
+ constructor();
5
+ private init;
6
+ setTelemetryEnabled(enabled: boolean): void;
7
+ trackPageView(name?: string, uri?: string): void;
8
+ trackEvent(name: string, properties?: {
9
+ [key: string]: any;
10
+ }): void;
11
+ trackException(exception: Error): void;
12
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Recursively compares two values for deep equality.
3
+ *
4
+ * Useful for checking if complex objects or arrays have changed content,
5
+ * often used in change detection strategies or form dirty checking.
6
+ *
7
+ * @param a The first value to compare
8
+ * @param b The second value to compare
9
+ * @returns True if the values are deeply equal, false otherwise
10
+ */
11
+ export declare function deepEqual(a: unknown, b: unknown): boolean;
12
+ /**
13
+ * Creates a deep copy of a value.
14
+ *
15
+ * Essential for immutable state updates where you need to modify a nested property
16
+ * without mutating the original object.
17
+ *
18
+ * Uses `structuredClone` if available, falling back to JSON serialization.
19
+ * Note: The JSON fallback has limitations (e.g. loses Date objects, functions, undefined).
20
+ *
21
+ * @param value The value to clone
22
+ * @returns A deep copy of the value
23
+ */
24
+ export declare function deepClone<T>(value: T): T;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Custom AJV instance with capability-based validation keywords.
3
+ * Focus: keep declarative business rules in JSON Schema while deriving dynamic
4
+ * constraints from static master data (no runtime HTTP calls).
5
+ */
6
+ import Ajv from 'ajv';
7
+ /**
8
+ * Creates a custom AJV instance with domain-specific validation keywords.
9
+ *
10
+ * Custom keywords:
11
+ * - `permittedStableSystem`: Validates stable system against animal category constraints
12
+ *
13
+ * @param options - Additional AJV options to merge with defaults
14
+ */
15
+ export declare function createSuibiAjv(options?: Record<string, any>): Ajv;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Dynamic capability derivation from master data.
3
+ * Computes permitted stable systems, utilisations, etc. based on animal categories.
4
+ *
5
+ * All master data is embedded statically at compile time - no runtime HTTP calls.
6
+ */
7
+ /**
8
+ * Derives permitted stable systems (stableSystem enum strings) for a given animal category.
9
+ *
10
+ * @param animalCategoryPRIF - The PRIF animal category ID
11
+ * @returns Array of permitted stableSystem enum strings (e.g. 'HUS_TETHER')
12
+ */
13
+ export declare function derivePermittedStableSystems(animalCategoryPRIF: number | null | undefined): string[];
14
+ /**
15
+ * Pre-computed map for performance (memoized at module load).
16
+ * Maps animalCategoryPRIF -> array of permitted stableSystem enum strings.
17
+ */
18
+ export declare const PERMITTED_STABLE_SYSTEMS: Record<number, string[]>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Error message formatter for JSON Schema validation.
3
+ * Maps AJV error objects to i18n keys with parameters.
4
+ *
5
+ * Since validation is handled by AJV/JSON Schema, we don't need a custom engine.
6
+ * We just need to format error messages for better UX.
7
+ */
8
+ /**
9
+ * Format an AJV error object for display, mapping to i18n keys where applicable.
10
+ *
11
+ * @param error AJV error object
12
+ * @param translateFn Translation function (key, defaultMessage) => string
13
+ * @returns Formatted error message
14
+ */
15
+ export declare function formatValidationError(error: any, translateFn: (key: string, defaultMessage?: string) => string): string;
16
+ /**
17
+ * Format multiple AJV errors for display.
18
+ */
19
+ export declare function formatValidationErrors(errors: any[], translateFn: (key: string, defaultMessage?: string) => string): string[];
@@ -0,0 +1,59 @@
1
+ import { ErrorObject } from 'ajv';
2
+ import { AnimalStockCategory, FarmManureTradingCategory, FarmManureTradingMode, FieldCultivationTab, FieldSpreadingCategory, FodderCategory, FodderMode, PageId, StorageEntryType, StorageTab } from '../navigation/navigation.service';
3
+ export interface EnrichedValidationError extends ErrorObject {
4
+ /** Human-friendly field label (e.g., "Animal Category") */
5
+ fieldLabel?: string;
6
+ /** Navigation target: page */
7
+ targetPage?: PageId;
8
+ /** Navigation target: animal stock array index */
9
+ targetAnimalStockIndex?: number;
10
+ /** Navigation target: detail category (tab) */
11
+ targetCategory?: AnimalStockCategory;
12
+ /** Navigation target: static section (e.g., lifetime performance panel) */
13
+ targetSection?: 'lifetimePerformance';
14
+ /** Navigation target: farm manure trading tab */
15
+ targetFarmManureTradingMode?: FarmManureTradingMode;
16
+ /** Navigation target: farm manure trading entry index */
17
+ targetFarmManureTradingIndex?: number;
18
+ /** Category tab inside farm manure trading detail */
19
+ targetFarmManureTradingCategory?: FarmManureTradingCategory;
20
+ /** Navigation target: fodder mode */
21
+ targetFodderMode?: FodderMode;
22
+ /** Navigation target: fodder entry index */
23
+ targetFodderIndex?: number;
24
+ /** Category tab inside fodder detail */
25
+ targetFodderCategory?: FodderCategory;
26
+ /** Category tab inside field spreading */
27
+ targetFieldSpreadingCategory?: FieldSpreadingCategory;
28
+ /** Category tab inside field cultivation */
29
+ targetFieldCultivationTab?: FieldCultivationTab;
30
+ /** Field cultivation detail index */
31
+ targetFieldCultivationIndex?: number;
32
+ /** Storage detail type */
33
+ targetStorageType?: StorageEntryType;
34
+ /** Storage detail index */
35
+ targetStorageIndex?: number;
36
+ /** Storage tab for list-level or scalar navigation */
37
+ targetStorageTab?: StorageTab;
38
+ }
39
+ /**
40
+ * GlobalValidationService
41
+ * Validates the entire NaebiData structure using the root JSON Schema + AJV.
42
+ * Consolidates errors and enriches them with navigation metadata for deep-linking.
43
+ *
44
+ * Usage: Inject in App or top-level components; errors() signal exposes enriched errors.
45
+ */
46
+ export declare class GlobalValidationService {
47
+ private readonly dataSvc;
48
+ private readonly ajv;
49
+ private readonly validateFn;
50
+ readonly errors: import("@angular/core").Signal<EnrichedValidationError[]>;
51
+ private consolidateErrors;
52
+ private enrichErrors;
53
+ private inferCategory;
54
+ private inferFarmTradingCategory;
55
+ private inferFieldSpreadingCategory;
56
+ private inferFodderCategory;
57
+ private inferStorageTab;
58
+ private inferFieldLabel;
59
+ }
@@ -0,0 +1,36 @@
1
+ import { ErrorObject } from 'ajv';
2
+ /**
3
+ * ValidationErrorsPanelComponent
4
+ * Reusable expansion panel summarizing & listing AJV validation issues.
5
+ * - Collapsed summary shows count + error icon.
6
+ * - Expands to list formatted, translated messages (stable ordering).
7
+ * - Hides entirely when there are no errors.
8
+ * - Emits `errorSelected` when user clicks an error (for navigation).
9
+ * Inputs:
10
+ * errors: ErrorObject[] (raw / consolidated) – consumer decides consolidation strategy.
11
+ * clickable: boolean – when true, list items are interactive and emit selection events.
12
+ * Outputs:
13
+ * errorSelected: ErrorObject – emitted when user clicks an error item.
14
+ */
15
+ export declare class ValidationErrorsPanelComponent {
16
+ /** Raw (or already consolidated) AJV errors */
17
+ errors: import("@angular/core").InputSignal<ErrorObject<string, Record<string, any>, unknown>[] | null | undefined>;
18
+ /** When true, list items are clickable and emit errorSelected */
19
+ clickable: import("@angular/core").InputSignal<boolean>;
20
+ /** Emitted when user clicks an error (only if clickable is true) */
21
+ errorSelected: import("@angular/core").OutputEmitterRef<ErrorObject<string, Record<string, any>, unknown>>;
22
+ private readonly i18n;
23
+ expanded: import("@angular/core").WritableSignal<boolean>;
24
+ hasErrors: import("@angular/core").Signal<boolean>;
25
+ /** Stable sort: by instancePath then keyword for predictability */
26
+ private sortedErrors;
27
+ formattedItems: import("@angular/core").Signal<{
28
+ message: string;
29
+ field: string;
30
+ error: ErrorObject<string, Record<string, any>, unknown>;
31
+ }[]>;
32
+ issueCountLabel: import("@angular/core").Signal<string>;
33
+ panelAriaLabel: import("@angular/core").Signal<string>;
34
+ collapse(): void;
35
+ onErrorClick(error: ErrorObject): void;
36
+ }
@@ -0,0 +1,14 @@
1
+ import { Locale } from './core/i18n/i18n.service';
2
+ import { PageId } from './core/navigation/navigation.service';
3
+ /**
4
+ * HeaderBarComponent
5
+ * Footer actions for quick access to data preview and the current save state.
6
+ */
7
+ export declare class HeaderBarComponent {
8
+ locale: import("@angular/core").InputSignal<Locale>;
9
+ currentPage: import("@angular/core").InputSignal<PageId>;
10
+ isDirty: import("@angular/core").InputSignal<boolean>;
11
+ onNavigate: import("@angular/core").InputSignal<(page: PageId) => void>;
12
+ onLocaleChange: import("@angular/core").InputSignal<(locale: Locale) => void>;
13
+ navigate(page: PageId): void;
14
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Constraint resolver registry enabling UI schema elements to declare dynamic
3
+ * visibility rules referencing domain-specific predicates. A resolver is a
4
+ * pure function returning a boolean. It receives a contextual accessor for
5
+ * current form data (root object) plus master-data + locale.
6
+ *
7
+ * UI schema structured example:
8
+ * {
9
+ * "type": "Constraint",
10
+ * "options": {
11
+ * "constraint": {
12
+ * "resolver": "animalCategory_isPermittedForConcentratedFeedstuffSummering",
13
+ * "args": ["#/animalCategoryPRIF"],
14
+ * "fallbackVisible": false
15
+ * }
16
+ * },
17
+ * "elements": [ { "type": "Group", ... } ]
18
+ * }
19
+ */
20
+ import { MasterDataService } from '../../core/master-data/master-data.service';
21
+ import { I18nService } from '../../core/i18n/i18n.service';
22
+ export interface ConstraintCall {
23
+ resolver: string;
24
+ args?: unknown[];
25
+ fallbackVisible?: boolean;
26
+ }
27
+ export type ConstraintConfig = ConstraintCall;
28
+ export interface ConstraintContext {
29
+ /** Root data object from JSONForms state */
30
+ data: unknown;
31
+ /** Dereference a JSON Pointer (starts with '#/'); returns undefined if invalid */
32
+ get<T = unknown>(pointer: string): T | undefined;
33
+ /** Master-data service */
34
+ masterData: MasterDataService;
35
+ /** Current locale (from I18nService) */
36
+ locale: string;
37
+ }
38
+ export type ConstraintResolver = (ctx: ConstraintContext, ...args: any[]) => boolean;
39
+ export declare function registerConstraint(name: string, fn: ConstraintResolver): void;
40
+ /**
41
+ * Evaluate a constraint configuration.
42
+ * @param cfg constraint object (or undefined => visible)
43
+ * @param data current form data root
44
+ * @param services injected service wrappers
45
+ * @param ctxOverrides optional context override (testing/extensibility)
46
+ */
47
+ export declare function evaluateConstraint(cfg: ConstraintConfig | undefined, data: unknown, services: {
48
+ masterData: MasterDataService;
49
+ i18n: I18nService;
50
+ }, ctxOverrides?: Partial<ConstraintContext>): boolean;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Code list filtering engine & resolver registry.
3
+ *
4
+ * Purpose: Allow UI schema controls rendering code list selects to declaratively
5
+ * filter the available options based on current form data (JSONForms), master data,
6
+ * locale, and arbitrary domain predicates – without baking domain logic into the
7
+ * generic select renderer.
8
+ *
9
+ * UI schema extension example (implicit generic filter using entryField/valueFrom):
10
+ * {
11
+ * "type": "Control",
12
+ * "scope": "#/properties/formOfDetention/properties/stall/properties/stableManureRemovalFrequency",
13
+ * "options": {
14
+ * "codeList": { "filter": { "entryField": "permittedForStableSystem", "valueFrom": "#/formOfDetention/stall/stableSystem", "fallback": "all" } }
15
+ * }
16
+ * }
17
+ *
18
+ * Named resolver example:
19
+ * "filter": { "resolver": "stableManureRemoval_permittedForSystem", "args": ["#/formOfDetention/stall/stableSystem"], "fallback": "all" }
20
+ */
21
+ import { MasterDataService } from '../../core/master-data/master-data.service';
22
+ import { I18nService } from '../../core/i18n/i18n.service';
23
+ import { NaebiDataService } from '../../core/data/naebi-data.service';
24
+ import { BaseCodeListEntry } from '../shared/option-sources/code-lists';
25
+ export interface FilterContext {
26
+ data: unknown;
27
+ rootData: unknown;
28
+ get<T = unknown>(pointer: string): T | undefined;
29
+ masterData: MasterDataService;
30
+ locale: string;
31
+ i18n: I18nService;
32
+ }
33
+ export type CodeListFilterResolver = (ctx: FilterContext, entry: BaseCodeListEntry, ...args: any[]) => boolean;
34
+ export interface LeafFilterCall {
35
+ resolver?: string;
36
+ args?: unknown[];
37
+ entryField?: string;
38
+ valueFrom?: string;
39
+ fallback?: 'all' | 'none';
40
+ }
41
+ export type FilterConfig = LeafFilterCall | {
42
+ all: FilterConfig[];
43
+ fallback?: 'all' | 'none';
44
+ } | {
45
+ any: FilterConfig[];
46
+ fallback?: 'all' | 'none';
47
+ } | {
48
+ not: FilterConfig;
49
+ fallback?: 'all' | 'none';
50
+ } | {
51
+ true: boolean;
52
+ fallback?: 'all' | 'none';
53
+ };
54
+ export declare function registerCodeListFilter(name: string, fn: CodeListFilterResolver): void;
55
+ /**
56
+ * Public entry to filter a list. Returns the provided list unchanged if cfg is falsy or
57
+ * if top-level fallback === 'all' and an unrecoverable error occurs.
58
+ */
59
+ export declare function evaluateFilter(list: BaseCodeListEntry[], cfg: FilterConfig | undefined, services: {
60
+ masterData: MasterDataService;
61
+ i18n: I18nService;
62
+ naebiData?: NaebiDataService;
63
+ }, data: unknown): BaseCodeListEntry[];
@@ -0,0 +1,34 @@
1
+ import { AnimalCategorySelectRenderer } from '../renderers/controls/selects/animal-category/animal-category-select.renderer';
2
+ import { CodeListSelectRenderer } from '../renderers/controls/selects/code-list/code-list-select.renderer';
3
+ import { CardGroupRenderer } from '../renderers/layout/group/card-group.renderer';
4
+ import { PlainGroupRenderer } from '../renderers/layout/group/plain-group.renderer';
5
+ import { LogicalGroupRenderer } from '../renderers/layout/group/logical-group.renderer';
6
+ import { RankedTester } from '@jsonforms/core';
7
+ import { ConstraintLayoutRenderer } from '../renderers/layout/constraint/constraint-layout.renderer';
8
+ import { SelectedCategoryCategorizationRenderer } from '../renderers/layout/categorization/selected-category-categorization.renderer';
9
+ import { CustomArrayLayoutRenderer } from '../renderers/layout/array/array-layout.renderer';
10
+ export declare const CUSTOM_JSONFORMS_RENDERERS: ({
11
+ tester: RankedTester;
12
+ renderer: typeof ConstraintLayoutRenderer;
13
+ } | {
14
+ tester: RankedTester;
15
+ renderer: typeof SelectedCategoryCategorizationRenderer;
16
+ } | {
17
+ tester: RankedTester;
18
+ renderer: typeof CardGroupRenderer;
19
+ } | {
20
+ tester: RankedTester;
21
+ renderer: typeof PlainGroupRenderer;
22
+ } | {
23
+ tester: RankedTester;
24
+ renderer: typeof LogicalGroupRenderer;
25
+ } | {
26
+ tester: RankedTester;
27
+ renderer: typeof AnimalCategorySelectRenderer;
28
+ } | {
29
+ tester: RankedTester;
30
+ renderer: typeof CodeListSelectRenderer;
31
+ } | {
32
+ tester: RankedTester;
33
+ renderer: typeof CustomArrayLayoutRenderer;
34
+ })[];