@agridea/suibi-module 0.1.0-preview.9 → 0.1.0-preview.b1a9725

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/README.md +10 -10
  2. package/dist/elements/browser/main.js +75 -64
  3. package/dist/elements/browser/styles.css +1 -1
  4. package/dist/elements/browser/suibi-module-latest.css +1 -1
  5. package/dist/elements/browser/suibi-module-latest.js +75 -64
  6. package/dist/elements/browser/{suibi-module.v0.1.0-preview.9.css → suibi-module.v0.1.0-preview.b1a9725.css} +1 -1
  7. package/dist/elements/browser/suibi-module.v0.1.0-preview.b1a9725.js +78 -0
  8. package/dist/elements/browser/suibi-theme-dark.css +1 -1
  9. package/dist/elements/browser/version.txt +1 -1
  10. package/dist/elements/browser/wc-global-utilities.css +1 -0
  11. package/dist/types/app/app.d.ts +14 -6
  12. package/dist/types/app/components/add-dashed-button/add-dashed-button.component.d.ts +9 -0
  13. package/dist/types/app/components/data-preview/data-preview.component.d.ts +11 -0
  14. package/dist/types/app/components/empty-state/empty-state.component.d.ts +12 -0
  15. package/dist/types/app/components/gauge-arc/gauge-arc.component.d.ts +49 -0
  16. package/dist/types/app/{header-bar.d.ts → components/header-bar/header-bar.component.d.ts} +4 -4
  17. package/dist/types/app/components/inline-table/inline-table.component.d.ts +100 -0
  18. package/dist/types/app/components/inline-table/inline-table.types.d.ts +127 -0
  19. package/dist/types/app/components/module-placeholder-page/module-placeholder-page.component.d.ts +6 -0
  20. package/dist/types/app/components/planning-result/planning-result.component.d.ts +46 -0
  21. package/dist/types/app/components/planning-result-row/planning-result-row.component.d.ts +34 -0
  22. package/dist/types/app/components/planning-trigger/planning-trigger.component.d.ts +13 -0
  23. package/dist/types/app/components/results-page/results-page.component.d.ts +13 -0
  24. package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts +30 -0
  25. package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-metrics.service.d.ts +21 -0
  26. package/dist/types/app/components/suissebilanz-minibar/suissebilanz-minibar.component.d.ts +19 -0
  27. package/dist/types/app/components/validation-page/validation-page.component.d.ts +18 -0
  28. package/dist/types/app/components/welcome-page/metadata.types.d.ts +1 -0
  29. package/dist/types/app/components/welcome-page/welcome-page.component.d.ts +30 -0
  30. package/dist/types/app/components/workflow-stepper/workflow-stepper.component.d.ts +49 -0
  31. package/dist/types/app/core/data/naebi-data.service.d.ts +52 -31
  32. package/dist/types/app/core/error/global-error-handler.d.ts +5 -0
  33. package/dist/types/app/core/events/suibi-data-emitter.service.d.ts +13 -0
  34. package/dist/types/app/core/events/suibi-data-event.d.ts +26 -0
  35. package/dist/types/app/core/i18n/i18n.service.d.ts +4 -3
  36. package/dist/types/app/core/i18n/locales/fr.d.ts +2 -0
  37. package/dist/types/app/core/i18n/locales/it.d.ts +2 -0
  38. package/dist/types/app/core/master-data/master-data.service.d.ts +15 -1
  39. package/dist/types/app/core/metadata/suibi-metadata.service.d.ts +6 -0
  40. package/dist/types/app/core/metadata/suibi-metadata.types.d.ts +18 -0
  41. package/dist/types/app/core/navigation/navigation.service.d.ts +40 -1
  42. package/dist/types/app/core/planning/planning-balance.service.d.ts +37 -0
  43. package/dist/types/app/core/planning/planning-balance.types.d.ts +206 -0
  44. package/dist/types/app/core/planning/planning-balance.utils.d.ts +10 -0
  45. package/dist/types/app/core/schemas/schema-localization.util.d.ts +18 -0
  46. package/dist/types/app/core/telemetry/telemetry.service.d.ts +12 -0
  47. package/dist/types/app/core/utils/object.util.d.ts +24 -0
  48. package/dist/types/app/core/validation/capabilities.d.ts +5 -5
  49. package/dist/types/app/core/validation/global-validation.service.d.ts +31 -4
  50. package/dist/types/app/jsonforms/filters/code-list-filter-resolvers.d.ts +3 -0
  51. package/dist/types/app/jsonforms/registry/renderers.registry.d.ts +8 -0
  52. package/dist/types/app/jsonforms/renderers/controls/selects/animal-category/animal-category-select.renderer.d.ts +1 -1
  53. package/dist/types/app/jsonforms/renderers/controls/selects/code-list/code-list-select.renderer.d.ts +16 -2
  54. package/dist/types/app/jsonforms/renderers/layout/array/array-layout.renderer.d.ts +43 -0
  55. package/dist/types/app/jsonforms/renderers/layout/categorization/selected-category-categorization.renderer.d.ts +3 -0
  56. package/dist/types/app/jsonforms/renderers/layout/constraint/constraint-layout.renderer.d.ts +1 -0
  57. package/dist/types/app/jsonforms/renderers/layout/group/base-group.renderer.d.ts +2 -0
  58. package/dist/types/app/jsonforms/renderers/layout/group/module-toggle-group.renderer.d.ts +36 -0
  59. package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-detail.component.d.ts +21 -0
  60. package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock}/animal-stock-list.component.d.ts +5 -8
  61. package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock}/animal-stock-master-detail.component.d.ts +4 -1
  62. package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock}/animal-stock.types.d.ts +6 -6
  63. package/dist/types/app/nutrient-cycle/animal-stock/index.d.ts +4 -0
  64. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-detail.component.d.ts +26 -0
  65. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-list.component.d.ts +22 -0
  66. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-master-detail.component.d.ts +25 -0
  67. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading.types.d.ts +27 -0
  68. package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +4 -0
  69. package/dist/types/app/nutrient-cycle/farm-manure-trading/transaction-unit.util.d.ts +1 -0
  70. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-detail.component.d.ts +22 -0
  71. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-general.component.d.ts +22 -0
  72. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-list.component.d.ts +17 -0
  73. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-master-detail.component.d.ts +37 -0
  74. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.types.d.ts +40 -0
  75. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.util.d.ts +6 -0
  76. package/dist/types/app/nutrient-cycle/field-cultivation/index.d.ts +4 -0
  77. package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.component.d.ts +38 -0
  78. package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.config.d.ts +20 -0
  79. package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.component.d.ts +34 -0
  80. package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.types.d.ts +43 -0
  81. package/dist/types/app/nutrient-cycle/field-spreading/index.d.ts +2 -0
  82. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.component.d.ts +22 -0
  83. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.config.d.ts +16 -0
  84. package/dist/types/app/nutrient-cycle/fodder/fodder-detail.component.d.ts +31 -0
  85. package/dist/types/app/nutrient-cycle/fodder/fodder-list.component.d.ts +20 -0
  86. package/dist/types/app/nutrient-cycle/fodder/fodder-master-detail.component.d.ts +37 -0
  87. package/dist/types/app/nutrient-cycle/fodder/fodder.types.d.ts +27 -0
  88. package/dist/types/app/nutrient-cycle/fodder/index.d.ts +4 -0
  89. package/dist/types/app/nutrient-cycle/fodder/transaction-unit.util.d.ts +2 -0
  90. package/dist/types/app/nutrient-cycle/lifetime-performance/index.d.ts +2 -0
  91. package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance-form.component.d.ts +27 -0
  92. package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance.types.d.ts +5 -0
  93. package/dist/types/app/nutrient-cycle/storage/index.d.ts +4 -0
  94. package/dist/types/app/nutrient-cycle/storage/storage-detail.component.d.ts +30 -0
  95. package/dist/types/app/nutrient-cycle/storage/storage-general.component.d.ts +29 -0
  96. package/dist/types/app/nutrient-cycle/storage/storage-list.component.d.ts +20 -0
  97. package/dist/types/app/nutrient-cycle/storage/storage-master-detail.component.d.ts +29 -0
  98. package/dist/types/app/nutrient-cycle/storage/storage.types.d.ts +40 -0
  99. package/dist/types/environments/environment.d.ts +11 -0
  100. package/dist/types/public-api.d.ts +2 -0
  101. package/dist/types/shared/material-icons.d.ts +3 -3
  102. package/package.json +69 -17
  103. package/dist/elements/browser/suibi-module.v0.1.0-preview.9.js +0 -67
  104. package/dist/types/app/animal-stock/animal-stock-detail.component.d.ts +0 -22
  105. package/dist/types/app/data-preview.d.ts +0 -7
  106. package/dist/types/app/welcome-page.d.ts +0 -4
  107. /package/dist/types/app/{core/validation/validation-errors-panel.d.ts → components/validation-errors-panel/validation-errors-panel.component.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ export { DEFAULT_SUIBI_METADATA, DEFAULT_COMPUTATION_MODULES, type ComputationModules, type SubmissionStatus, type SuibiVersion, type SuibiMetadata } from '../../core/metadata/suibi-metadata.types';
@@ -0,0 +1,30 @@
1
+ import { JsonSchema, UISchemaElement } from '@jsonforms/core';
2
+ import { SuibiMetadata } from '../../core/metadata/suibi-metadata.types';
3
+ export declare class WelcomePageComponent {
4
+ private readonly i18n;
5
+ private readonly metadataSvc;
6
+ private readonly naebi;
7
+ startEvent: import("@angular/core").OutputEmitterRef<void>;
8
+ metadataChange: import("@angular/core").OutputEmitterRef<SuibiMetadata>;
9
+ private readonly baseSchema;
10
+ private readonly baseUiSchema;
11
+ readonly suibiAjv: import("ajv").Ajv;
12
+ readonly renderers: {
13
+ tester: import("@jsonforms/core").RankedTester;
14
+ renderer: any;
15
+ }[];
16
+ readonly metadata: import("@angular/core").Signal<SuibiMetadata>;
17
+ readonly localizedSchema: import("@angular/core").Signal<JsonSchema>;
18
+ readonly localizedUi: import("@angular/core").Signal<UISchemaElement>;
19
+ readonly jsonFormsData: import("@angular/core").Signal<{}>;
20
+ constructor();
21
+ start(): void;
22
+ loadExampleData(): void;
23
+ onMetadataChange(newValue: unknown): void;
24
+ private normalizeJsonFormsPayload;
25
+ private toMetadata;
26
+ private extractModules;
27
+ private isSuibiVersion;
28
+ private isSubmissionStatus;
29
+ private isSameMetadata;
30
+ }
@@ -0,0 +1,49 @@
1
+ import { PageId } from '../../core/navigation/navigation.service';
2
+ /**
3
+ * WorkflowStepperComponent
4
+ * Horizontal navigation stepper for the main data-entry workflow.
5
+ *
6
+ * Design contract:
7
+ * - Uses mat-stepper as a header-only nav bar (step content is empty; content
8
+ * area is hidden via CSS so the stepper acts as a pure navigation indicator).
9
+ * - [selectedIndex] is driven by the currentPage input — no internal routing state.
10
+ * - Navigation is delegated back to App via the onNavigate callback, preserving
11
+ * the custom-element page-attribute reflection.
12
+ * - Error indicators: any page with at least one enriched validation error shows
13
+ * the error ring on its step circle. Requires STEPPER_GLOBAL_OPTIONS { showError: true }.
14
+ * - Non-workflow pages (e.g. data_preview): mat-stepper rejects out-of-bounds selectedIndex,
15
+ * so we clamp to 0; the no-active-step CSS class neutralises the visual active indicator,
16
+ * and onStepperClick delegates clicks for all headers (bypassing the stepper's
17
+ * "no-change" guard that suppresses selectedIndexChange for the currently selected step).
18
+ *
19
+ * Extension points:
20
+ * - Completed state: replace the hardcoded `false` on [completed] with a per-page
21
+ * computed once domain completion rules are defined (e.g. all required fields valid).
22
+ * - New pages: add an entry to WORKFLOW_STEPS and extend PageId.
23
+ */
24
+ export declare class WorkflowStepperComponent {
25
+ protected readonly steps: readonly {
26
+ readonly pageId: PageId;
27
+ readonly labelKey: string;
28
+ }[];
29
+ /**
30
+ * Current page from the parent. Controls which step circle is highlighted.
31
+ * Non-workflow pages (e.g. data_preview) use index 0 as a valid CDK fallback;
32
+ * the no-active-step CSS class removes the visual active indicator for those pages.
33
+ */
34
+ readonly currentPage: import("@angular/core").InputSignal<PageId>;
35
+ /**
36
+ * Navigation callback provided by App.
37
+ * Using a callback (instead of an output EventEmitter) matches the existing
38
+ * header-bar pattern and ensures the custom-element page-attribute is reflected.
39
+ */
40
+ readonly onNavigate: import("@angular/core").InputSignal<(page: PageId) => void>;
41
+ private readonly validationSvc;
42
+ private readonly workflowPage;
43
+ protected readonly pagesWithErrors: import("@angular/core").Signal<Set<PageId>>;
44
+ protected readonly isOnWorkflowPage: import("@angular/core").Signal<boolean>;
45
+ protected readonly clampedStepIndex: import("@angular/core").Signal<number>;
46
+ protected onSelectedIndexChange(index: number): void;
47
+ protected onStepperClick(event: MouseEvent): void;
48
+ private navigateTo;
49
+ }
@@ -1,5 +1,7 @@
1
- import naebiExample from '../../../../assets/example-data/example-naebi-data.json';
2
- export type NaebiData = typeof naebiExample;
1
+ import exampleDetail from '../../../../assets/example-data/example-naebi-data.json';
2
+ type SampleEvent = typeof exampleDetail;
3
+ type SampleData = SampleEvent['payload']['data'];
4
+ export type NaebiData = SampleData;
3
5
  /**
4
6
  * Calculation mode determines which validation rules and features are active.
5
7
  */
@@ -27,10 +29,8 @@ export declare class NaebiDataService {
27
29
  hoursPerDay: number;
28
30
  };
29
31
  stall: {
30
- stableSystem: number;
31
- stableCapacity: number;
32
+ stableSystem: string;
32
33
  stableVentilationType: number;
33
- stableAirPurification: number;
34
34
  hasStableDeepLitter: boolean;
35
35
  hasStableManureBeltDrying: boolean;
36
36
  stableManureRemovalFrequency: number;
@@ -39,10 +39,6 @@ export declare class NaebiDataService {
39
39
  hasStableFeedingStationElevated: boolean;
40
40
  hasStableFloorSlopedUrineDrainage: boolean;
41
41
  hasYard: boolean;
42
- yardFeeding: number;
43
- yardFloorType: number;
44
- yardDays: number;
45
- yardHoursPerDay: number;
46
42
  };
47
43
  };
48
44
  hasImpexDerivedExcretion: boolean;
@@ -50,6 +46,7 @@ export declare class NaebiDataService {
50
46
  feeding: {
51
47
  fodderConsumption: number;
52
48
  concentratedFeedstuffConsumption: number;
49
+ concentratedFeedStuffConsumption: number;
53
50
  winterFeeding: {
54
51
  feedingRoutine: {
55
52
  typeOfFeedstuffProduct: string;
@@ -74,19 +71,14 @@ export declare class NaebiDataService {
74
71
  }[];
75
72
  storage: {
76
73
  stableStrawLitter: number;
77
- manureSupplyProportionStored: number;
78
74
  slurrySupplyProportionStored: number;
79
75
  createFacilitySpecificManureProduct: boolean;
80
76
  createFacilitySpecificSlurryProduct: boolean;
77
+ slurryTankQuantity: number;
81
78
  dilutionRatio: number;
82
- manurePit: {
83
- cover: number;
84
- manureFromAnimalStockStored: {
85
- manureDerivation: string;
86
- proportionStored: number;
87
- }[];
88
- }[];
79
+ manurePit: never[];
89
80
  slurryTank: {
81
+ descriptor: string;
90
82
  volumeInM3: number;
91
83
  depthInM: number;
92
84
  cover: number;
@@ -95,16 +87,7 @@ export declare class NaebiDataService {
95
87
  }[];
96
88
  };
97
89
  farmManureTrading: {
98
- supply: {
99
- quantity: number;
100
- typeOfManureRecyclingProduct: string;
101
- transactionUnit: string;
102
- ingredient: {
103
- quantity: number;
104
- molecularFormula: string;
105
- unit: string;
106
- }[];
107
- }[];
90
+ supply: never[];
108
91
  dispense: {
109
92
  quantity: number;
110
93
  typeOfManureRecyclingProduct: string;
@@ -113,6 +96,11 @@ export declare class NaebiDataService {
113
96
  zoologicalAnimal: string;
114
97
  percentageAllocation: number;
115
98
  }[];
99
+ ingredient: {
100
+ quantity: number;
101
+ molecularFormula: string;
102
+ unit: string;
103
+ }[];
116
104
  }[];
117
105
  };
118
106
  fieldSpreading: {
@@ -125,14 +113,18 @@ export declare class NaebiDataService {
125
113
  proportionOfArea: number;
126
114
  }[];
127
115
  applicationDuringWarmDays: number;
116
+ proportionAppliedSummerMonths: number;
117
+ proportionAppliedOtherMonths: number;
128
118
  proportionAppliedAfter6PM: number;
129
119
  dragHoseAreaSize: number;
130
120
  };
131
121
  manure: {
132
122
  applicationIncorporationTime: number;
133
123
  proportionAppliedSummerMonths: number;
124
+ proportionAppliedOtherMonths: number;
134
125
  };
135
126
  fertiliser: {
127
+ descriptor: string;
136
128
  fertiliserProductCategory: string;
137
129
  quantity: number;
138
130
  transactionUnit: string;
@@ -154,8 +146,6 @@ export declare class NaebiDataService {
154
146
  }[];
155
147
  };
156
148
  lifetimePerformance: {
157
- dailyGain: number;
158
- liveWeight: number;
159
149
  milkProductionReport: number;
160
150
  };
161
151
  fodder: {
@@ -170,6 +160,12 @@ export declare class NaebiDataService {
170
160
  unit: string;
171
161
  }[];
172
162
  }[];
163
+ dispense: {
164
+ typeOfFeedstuffProduct: string;
165
+ quantity: number;
166
+ transactionUnit: string;
167
+ ingredient: never[];
168
+ }[];
173
169
  };
174
170
  cropFromNonFodderCropland: {
175
171
  typeOfFeedstuffProduct: string;
@@ -185,6 +181,17 @@ export declare class NaebiDataService {
185
181
  totalBalanceErrorMargin: number;
186
182
  };
187
183
  fieldCultivation: {
184
+ buildingZoneAreaSize: number;
185
+ outdoorVegetableMainCropAreaSize: number;
186
+ indoorVegetableMainCropAreaSize: number;
187
+ feedingOfCropHarvest: {
188
+ agronomicCropCategory: string;
189
+ effectiveYield: number;
190
+ }[];
191
+ dispenseOfCropHarvest: {
192
+ agronomicCropCategory: string;
193
+ effectiveYield: number;
194
+ }[];
188
195
  fodderCropland: ({
189
196
  agronomicCropCategory: string;
190
197
  isMainCrop: boolean;
@@ -203,25 +210,38 @@ export declare class NaebiDataService {
203
210
  isMainCrop: boolean;
204
211
  areaSize: number;
205
212
  yieldPerSquareMeasure: number;
213
+ hasLongTermYieldDivergence: boolean;
206
214
  }[];
207
215
  special: {
208
216
  agronomicCropCategory: string;
209
217
  userSpecificPlantName: string;
210
218
  isMainCrop: boolean;
211
219
  areaSize: number;
212
- yieldPerSquareMeasure: number;
220
+ requirementCorrection: {
221
+ quantity: number;
222
+ molecularFormula: string;
223
+ unit: string;
224
+ }[];
213
225
  }[];
214
226
  };
215
227
  generateReport: boolean;
216
228
  };
229
+ calculationVersion: {
230
+ version: string;
231
+ };
217
232
  }>;
233
+ private readonly _lastEmitted;
234
+ private readonly _dirty;
235
+ readonly dirty: import("@angular/core").Signal<boolean>;
218
236
  private readonly _calculationMode;
219
237
  readonly calculationMode: import("@angular/core").Signal<CalculationMode>;
220
238
  /**
221
239
  * Set new data value; accepts plain object (already parsed) matching NaebiData shape.
222
- * Silent no-op if value is structurally equal reference to avoid unnecessary updates (cheap ref check only).
240
+ * Silent no-op if value is structurally equal after normalization to avoid unnecessary updates.
223
241
  */
224
242
  setData(value: NaebiData): void;
243
+ /** Mark current data as saved (clears dirty state and updates snapshot). */
244
+ markSaved(): void;
225
245
  /**
226
246
  * Set calculation mode (SuiBi or ExBi).
227
247
  * Can affect which validation rules are active or which features are enabled.
@@ -230,3 +250,4 @@ export declare class NaebiDataService {
230
250
  /** Reset to bundled example */
231
251
  reset(): void;
232
252
  }
253
+ export {};
@@ -0,0 +1,5 @@
1
+ import { ErrorHandler } from '@angular/core';
2
+ export declare class GlobalErrorHandler implements ErrorHandler {
3
+ private readonly injector;
4
+ handleError(error: any): void;
5
+ }
@@ -0,0 +1,13 @@
1
+ import { SuibiDataEventDetail, SuibiDataEventMetadata } from './suibi-data-event';
2
+ /**
3
+ * Centralizes construction + dispatch of the `suibi-data-emitted` payload so multiple UI entry points can reuse it.
4
+ */
5
+ export declare class SuibiDataEmitterService {
6
+ private readonly i18n;
7
+ private readonly validation;
8
+ private readonly metadataSvc;
9
+ private readonly naebi;
10
+ buildMetadata(): SuibiDataEventMetadata;
11
+ buildDetail(): SuibiDataEventDetail;
12
+ emitFrom(target: HTMLElement): void;
13
+ }
@@ -0,0 +1,26 @@
1
+ import { Locale } from '../i18n/i18n.service';
2
+ import { NaebiData } from '../data/naebi-data.service';
3
+ import { SuibiMetadata } from '../metadata/suibi-metadata.types';
4
+ /**
5
+ * Increment when the payload contract changes in a backwards-incompatible way.
6
+ */
7
+ export declare const SUIBI_DATA_EVENT_VERSION = "suibi-data.v1";
8
+ /** Detail object emitted with the `suibi-data` CustomEvent. */
9
+ export interface SuibiDataEventDetail {
10
+ version: typeof SUIBI_DATA_EVENT_VERSION;
11
+ payload: SuibiDataEventPayload;
12
+ }
13
+ /** Top-level payload structure delivered to host applications. */
14
+ export interface SuibiDataEventPayload {
15
+ metadata: SuibiDataEventMetadata;
16
+ data: NaebiData;
17
+ }
18
+ /**
19
+ * Metadata describing the dataset at the moment of emission so hosts can audit and reason about it.
20
+ */
21
+ export type SuibiDataEventMetadata = SuibiMetadata & {
22
+ emittedAt: string;
23
+ locale: Locale;
24
+ isValid: boolean;
25
+ errorCount: number;
26
+ };
@@ -1,5 +1,5 @@
1
1
  import { PipeTransform, Signal } from '@angular/core';
2
- export type Locale = 'en' | 'de';
2
+ export type Locale = 'en' | 'de' | 'fr' | 'it';
3
3
  export type JsonFormsTranslator = (key: string, defaultMessage: string | undefined, context: unknown) => string;
4
4
  export declare class I18nService {
5
5
  private readonly _locale;
@@ -10,11 +10,12 @@ export declare class I18nService {
10
10
  translate: JsonFormsTranslator;
11
11
  }>;
12
12
  setLocale(locale: Locale): void;
13
+ /** Returns true if the given string is a supported locale key. */
14
+ isValidLocale(value: string): value is Locale;
13
15
  t(key: string, defaultMessage?: string): string;
14
16
  }
15
17
  export declare class TranslatePipe implements PipeTransform {
16
- private readonly i18n;
17
18
  private readonly cache;
18
- constructor(i18n: I18nService);
19
+ private readonly i18n;
19
20
  transform(key: string, defaultMessage?: string): Signal<string>;
20
21
  }
@@ -0,0 +1,2 @@
1
+ export declare const frTranslations: Record<string, string>;
2
+ export type FrTranslationKeys = keyof typeof frTranslations;
@@ -0,0 +1,2 @@
1
+ export declare const itTranslations: Record<string, string>;
2
+ export type ItTranslationKeys = keyof typeof itTranslations;
@@ -1,5 +1,12 @@
1
1
  import { Locale } from '../i18n/i18n.service';
2
- declare const MASTER_DATA: Record<string, any[]>;
2
+ /** The property name of the primary key in a master-data catalog entry. */
3
+ type MasterDataKeyField = string;
4
+ interface MasterDataCatalog {
5
+ entries: any[];
6
+ /** Property name to use as the lookup key; 'id' entries are coerced to Number. */
7
+ key: MasterDataKeyField;
8
+ }
9
+ declare const MASTER_DATA: Record<string, MasterDataCatalog>;
3
10
  export type MasterDataKind = keyof typeof MASTER_DATA;
4
11
  export declare class MasterDataService {
5
12
  private readonly i18n;
@@ -14,5 +21,12 @@ export declare class MasterDataService {
14
21
  designation(kind: MasterDataKind, id: number | string | null | undefined, locale?: Locale): string;
15
22
  resolveAnimalCategory(id: number | string | null | undefined, locale?: Locale): string;
16
23
  resolveUtilisation(id: number | string | null | undefined, locale?: Locale): string;
24
+ resolveManureProduct(code: string | null | undefined, locale?: Locale): string;
25
+ resolveZoologicalAnimal(code: string | null | undefined, locale?: Locale): string;
26
+ resolveCultivationCategory(code: string | null | undefined, locale?: Locale): string;
27
+ resolveAgronomicCropCategory(code: string | null | undefined, locale?: Locale): string;
28
+ resolveFeedstuffProduct(code: string | null | undefined, locale?: Locale): string;
29
+ resolveCover(id: number | string | null | undefined, locale?: Locale): string;
30
+ resolveMixingFrequency(id: number | string | null | undefined, locale?: Locale): string;
17
31
  }
18
32
  export {};
@@ -0,0 +1,6 @@
1
+ import { SuibiMetadata } from './suibi-metadata.types';
2
+ export declare class SuibiMetadataService {
3
+ private readonly metadataSignal;
4
+ readonly metadata: import("@angular/core").Signal<SuibiMetadata>;
5
+ setMetadata(next: SuibiMetadata): void;
6
+ }
@@ -0,0 +1,18 @@
1
+ export type SuibiVersion = '1.19' | '1.20';
2
+ export type SubmissionStatus = 'draft' | 'submitted' | 'final';
3
+ /** Which computation modules are active for this dossier. */
4
+ export interface ComputationModules {
5
+ suisseBilanz: boolean;
6
+ gmf: boolean;
7
+ nh3: boolean;
8
+ impex: boolean;
9
+ linear: boolean;
10
+ }
11
+ export declare const DEFAULT_COMPUTATION_MODULES: ComputationModules;
12
+ export interface SuibiMetadata {
13
+ title: string;
14
+ suibiVersion: SuibiVersion;
15
+ status: SubmissionStatus;
16
+ modules: ComputationModules;
17
+ }
18
+ export declare const DEFAULT_SUIBI_METADATA: SuibiMetadata;
@@ -1,5 +1,13 @@
1
- export type PageId = 'welcome' | 'animal_stock' | 'data_preview' | 'storage' | 'field_spreading' | 'farm_manure_trading';
1
+ export type PageId = 'welcome' | 'animal_stock' | 'data_preview' | 'storage' | 'field_spreading' | 'farm_manure_trading' | 'fodder' | 'field_cultivation' | 'validation' | 'results';
2
2
  export type AnimalStockCategory = 'base' | 'formOfDetention' | 'feeding';
3
+ export type FarmManureTradingMode = 'supply' | 'dispense';
4
+ export type FarmManureTradingCategory = 'general' | 'derivation' | 'ingredients';
5
+ export type FodderMode = 'supply' | 'dispense' | 'non_fodder_cropland';
6
+ export type FodderCategory = 'general' | 'ingredients';
7
+ export type FieldSpreadingCategory = 'general' | 'fertiliser' | 'recycling';
8
+ export type FieldCultivationTab = 'general' | 'fodderCropland' | 'arableLand' | 'special';
9
+ export type StorageTab = 'manure' | 'slurry';
10
+ export type StorageEntryType = 'manure_pit' | 'slurry_tank';
3
11
  /**
4
12
  * NavigationService
5
13
  * Global reactive store for application routing and deep-link state.
@@ -30,6 +38,26 @@ export declare class NavigationService {
30
38
  page: PageId;
31
39
  category: string;
32
40
  }>;
41
+ /** Selected farm manure trading detail context (mode + index) */
42
+ readonly selectedFarmManureTrading: import("@angular/core").WritableSignal<{
43
+ mode: FarmManureTradingMode;
44
+ index: number;
45
+ } | null>;
46
+ /** Selected fodder detail context (mode + index) */
47
+ readonly selectedFodderDetail: import("@angular/core").WritableSignal<{
48
+ mode: FodderMode;
49
+ index: number;
50
+ } | null>;
51
+ /** Selected field cultivation detail context (tab + index) */
52
+ readonly selectedFieldCultivationDetail: import("@angular/core").WritableSignal<{
53
+ tab: Exclude<FieldCultivationTab, "general">;
54
+ index: number;
55
+ } | null>;
56
+ /** Selected storage detail context (type + index) */
57
+ readonly selectedStorageDetail: import("@angular/core").WritableSignal<{
58
+ type: StorageEntryType;
59
+ index: number;
60
+ } | null>;
33
61
  /** True if currently viewing animal stock detail (not list) */
34
62
  readonly isAnimalStockDetailView: import("@angular/core").Signal<boolean>;
35
63
  /** True if currently on animal stock page (list or detail) */
@@ -48,9 +76,20 @@ export declare class NavigationService {
48
76
  * Used by validation error navigation and internal routing.
49
77
  */
50
78
  navigateToAnimalStockDetail(index: number, category?: AnimalStockCategory): void;
79
+ navigateToFarmManureTradingDetail(mode: FarmManureTradingMode, index: number, category?: FarmManureTradingCategory): void;
80
+ navigateToFarmManureTradingList(): void;
81
+ navigateToFodderDetail(mode: FodderMode, index: number, category?: FodderCategory): void;
82
+ navigateToFodderList(): void;
83
+ navigateToFieldSpreading(category?: FieldSpreadingCategory): void;
84
+ navigateToFieldCultivationDetail(tab: Exclude<FieldCultivationTab, 'general'>, index: number): void;
85
+ navigateToFieldCultivationList(tab?: FieldCultivationTab): void;
86
+ navigateToStorageDetail(type: StorageEntryType, index: number): void;
87
+ navigateToStorageList(tab?: StorageTab): void;
51
88
  /**
52
89
  * Set active category/tab for current page (without changing page/entry).
53
90
  * Generic method supporting any page's categorization navigation.
91
+ * No-op when page and category are already the same values to prevent
92
+ * unnecessary signal emissions that re-trigger the tab index computed.
54
93
  */
55
94
  setCategory(page: PageId, category: string): void;
56
95
  /**
@@ -0,0 +1,37 @@
1
+ import { NaebiData } from '../data/naebi-data.service';
2
+ import type { PlanningBalanceResponse } from './planning-balance.types';
3
+ export type { PlanningBalanceResponse } from './planning-balance.types';
4
+ /** Which backend to target for planning requests. */
5
+ export type PlanningEndpoint = 'ebilanz' | 'blw';
6
+ /**
7
+ * Sends NAEBI data to a planning endpoint and exposes the result as a
8
+ * signal-based resource. Call `runPlanning(data, endpoint)` to trigger a request.
9
+ *
10
+ * The ID counter ensures each call re-fetches even if the payload hasn't changed.
11
+ */
12
+ export declare class PlanningBalanceService {
13
+ private readonly http;
14
+ private readonly _value;
15
+ private readonly _error;
16
+ private readonly _isLoading;
17
+ private readonly _selectedEndpoint;
18
+ private readonly _lastStartedRequestId;
19
+ private readonly _lastCompletedRequestId;
20
+ private readonly _lastSuccessfulRequestId;
21
+ private _nextId;
22
+ private activeRequestId;
23
+ private activeRequestSub;
24
+ readonly planningResource: {
25
+ value: import("@angular/core").Signal<PlanningBalanceResponse | undefined>;
26
+ error: import("@angular/core").Signal<unknown>;
27
+ isLoading: import("@angular/core").Signal<boolean>;
28
+ hasValue: import("@angular/core").Signal<boolean>;
29
+ lastStartedRequestId: import("@angular/core").Signal<number>;
30
+ lastCompletedRequestId: import("@angular/core").Signal<number>;
31
+ lastSuccessfulRequestId: import("@angular/core").Signal<number>;
32
+ };
33
+ readonly selectedEndpoint: import("@angular/core").Signal<PlanningEndpoint>;
34
+ setSelectedEndpoint(endpoint: PlanningEndpoint): void;
35
+ /** Fire a new planning-balance request with the current NAEBI data payload. */
36
+ runPlanning(data: NaebiData, endpoint?: PlanningEndpoint): void;
37
+ }