@agridea/suibi-module 0.1.0-preview.8 → 0.1.0-preview.82d9ee0

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 (121) 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.8.css → suibi-module.v0.1.0-preview.82d9ee0.css} +1 -1
  7. package/dist/elements/browser/suibi-module.v0.1.0-preview.82d9ee0.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 +233 -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/components/header-bar/header-bar.component.d.ts +14 -0
  17. package/dist/types/app/components/inline-table/inline-table.component.d.ts +159 -0
  18. package/dist/types/app/components/inline-table/inline-table.types.d.ts +212 -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 +32 -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 +5 -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 +59 -5
  42. package/dist/types/app/core/planning/planning-balance.service.d.ts +46 -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/custom-unit.util.d.ts +39 -0
  48. package/dist/types/app/core/utils/object.util.d.ts +46 -0
  49. package/dist/types/app/core/validation/ajv-custom.d.ts +1 -0
  50. package/dist/types/app/core/validation/capabilities.d.ts +11 -5
  51. package/dist/types/app/core/validation/global-validation.service.d.ts +33 -4
  52. package/dist/types/app/jsonforms/filters/code-list-filter-resolvers.d.ts +3 -0
  53. package/dist/types/app/jsonforms/registry/renderers.registry.d.ts +12 -0
  54. package/dist/types/app/jsonforms/renderers/controls/selects/animal-category/animal-category-select.renderer.d.ts +1 -1
  55. package/dist/types/app/jsonforms/renderers/controls/selects/code-list/code-list-select.renderer.d.ts +16 -2
  56. package/dist/types/app/jsonforms/renderers/layout/array/array-layout.renderer.d.ts +43 -0
  57. package/dist/types/app/jsonforms/renderers/layout/categorization/selected-category-categorization.renderer.d.ts +34 -0
  58. package/dist/types/app/jsonforms/renderers/layout/constraint/constraint-layout.renderer.d.ts +1 -0
  59. package/dist/types/app/jsonforms/renderers/layout/group/base-group.renderer.d.ts +2 -0
  60. package/dist/types/app/jsonforms/renderers/layout/group/module-toggle-group.renderer.d.ts +38 -0
  61. package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-detail/animal-stock-detail.component.d.ts +21 -0
  62. package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock/animal-stock-list}/animal-stock-list.component.d.ts +6 -9
  63. package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock/animal-stock-master-detail}/animal-stock-master-detail.component.d.ts +5 -2
  64. package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock}/animal-stock.types.d.ts +6 -6
  65. package/dist/types/app/nutrient-cycle/animal-stock/index.d.ts +4 -0
  66. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-master-detail/farm-manure-trading-master-detail.component.d.ts +19 -0
  67. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-table/farm-manure-trading-table.component.d.ts +37 -0
  68. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-table/farm-manure-trading-table.config.d.ts +24 -0
  69. package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading.types.d.ts +31 -0
  70. package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +4 -0
  71. package/dist/types/app/nutrient-cycle/farm-manure-trading/transaction-unit.util.d.ts +3 -0
  72. package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.component.d.ts +23 -0
  73. package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.config.d.ts +16 -0
  74. package/dist/types/app/nutrient-cycle/field-cultivation/crop-harvest-table/crop-harvest-table.component.d.ts +21 -0
  75. package/dist/types/app/nutrient-cycle/field-cultivation/crop-harvest-table/crop-harvest-table.config.d.ts +13 -0
  76. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-detail/field-cultivation-detail.component.d.ts +22 -0
  77. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-general/field-cultivation-general.component.d.ts +20 -0
  78. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-list/field-cultivation-list.component.d.ts +17 -0
  79. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-master-detail/field-cultivation-master-detail.component.d.ts +29 -0
  80. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.types.d.ts +45 -0
  81. package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.util.d.ts +10 -0
  82. package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.component.d.ts +29 -0
  83. package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.config.d.ts +21 -0
  84. package/dist/types/app/nutrient-cycle/field-cultivation/index.d.ts +9 -0
  85. package/dist/types/app/nutrient-cycle/field-cultivation/special-crops-table/special-crops-table.component.d.ts +29 -0
  86. package/dist/types/app/nutrient-cycle/field-cultivation/special-crops-table/special-crops-table.config.d.ts +54 -0
  87. package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.component.d.ts +52 -0
  88. package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.config.d.ts +20 -0
  89. package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.component.d.ts +36 -0
  90. package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.types.d.ts +44 -0
  91. package/dist/types/app/nutrient-cycle/field-spreading/index.d.ts +2 -0
  92. package/dist/types/app/nutrient-cycle/field-spreading/ingredient.util.d.ts +8 -0
  93. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.component.d.ts +32 -0
  94. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.config.d.ts +17 -0
  95. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-transaction-unit.util.d.ts +4 -0
  96. package/dist/types/app/nutrient-cycle/fodder/fodder-master-detail/fodder-master-detail.component.d.ts +25 -0
  97. package/dist/types/app/nutrient-cycle/fodder/fodder-table/fodder-table.component.d.ts +28 -0
  98. package/dist/types/app/nutrient-cycle/fodder/fodder-table/fodder-table.config.d.ts +9 -0
  99. package/dist/types/app/nutrient-cycle/fodder/fodder.types.d.ts +34 -0
  100. package/dist/types/app/nutrient-cycle/fodder/index.d.ts +3 -0
  101. package/dist/types/app/nutrient-cycle/fodder/ingredient.util.d.ts +8 -0
  102. package/dist/types/app/nutrient-cycle/fodder/transaction-unit.util.d.ts +2 -0
  103. package/dist/types/app/nutrient-cycle/lifetime-performance/index.d.ts +2 -0
  104. package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance-form.component.d.ts +27 -0
  105. package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance.types.d.ts +5 -0
  106. package/dist/types/app/nutrient-cycle/storage/index.d.ts +4 -0
  107. package/dist/types/app/nutrient-cycle/storage/storage-detail/storage-detail.component.d.ts +30 -0
  108. package/dist/types/app/nutrient-cycle/storage/storage-general/storage-general.component.d.ts +29 -0
  109. package/dist/types/app/nutrient-cycle/storage/storage-list/storage-list.component.d.ts +23 -0
  110. package/dist/types/app/nutrient-cycle/storage/storage-master-detail/storage-master-detail.component.d.ts +32 -0
  111. package/dist/types/app/nutrient-cycle/storage/storage.types.d.ts +40 -0
  112. package/dist/types/environments/environment.d.ts +11 -0
  113. package/dist/types/public-api.d.ts +2 -0
  114. package/dist/types/shared/material-icons.d.ts +3 -3
  115. package/package.json +69 -17
  116. package/dist/elements/browser/suibi-module.v0.1.0-preview.8.js +0 -67
  117. package/dist/types/app/animal-stock/animal-stock-detail.component.d.ts +0 -22
  118. package/dist/types/app/data-preview.d.ts +0 -7
  119. package/dist/types/app/header-bar.d.ts +0 -19
  120. package/dist/types/app/welcome-page.d.ts +0 -4
  121. /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,212 @@
1
+ /**
2
+ * Type definitions for the generic InlineTableComponent.
3
+ *
4
+ * Usage pattern (the "uischema" concept):
5
+ * 1. Define an `InlineTableConfig` object describing your columns and labels.
6
+ * 2. Pass it to `<app-inline-table [config]="…" [rows]="…">`.
7
+ * 3. For business-logic side-effects (e.g. auto-populating fields on selection),
8
+ * pass an optional `rowTransform` function — the generic component knows nothing
9
+ * about domain rules.
10
+ *
11
+ * To reuse the table for a different domain, create a new config file and a thin
12
+ * wrapper component. Only the config changes; the rendering component stays the same.
13
+ */
14
+ import type { BaseCodeListEntry } from '../../jsonforms/shared/option-sources/code-lists';
15
+ /** Supported cell widget types. Extend with new literal types as needed.
16
+ * 'readonly' renders the resolved value as plain text (no input) — for columns
17
+ * that are fully derived from other fields and must not be user-editable.
18
+ * 'checkbox' renders a boolean mat-checkbox bound to a true/false row field.
19
+ * 'subrows' renders an expandable editor for a nested list of key/percentage
20
+ * pairs (e.g. manureDerivation[]) — see `InlineSubrowsConfig`. */
21
+ export type InlineCellType = 'select' | 'number' | 'text' | 'readonly' | 'checkbox' | 'subrows';
22
+ /**
23
+ * Per-cell validation resolver — returns a translated error message to display
24
+ * under the cell, or `null` when the cell is valid. Passed as the `cellError`
25
+ * input of InlineTableComponent for domain tables that bypass JSONForms/AJV
26
+ * (inline tables are not schema-validated, so business rules like percentage
27
+ * caps must be surfaced visually through this hook).
28
+ */
29
+ export type InlineCellErrorResolver = (row: Record<string, unknown>, col: InlineColumnDef) => string | null;
30
+ /**
31
+ * Configuration for a `type: 'subrows'` column — an expandable editor for a nested
32
+ * array of `{ key, value }` entries (e.g. manureDerivation: zoologicalAnimal +
33
+ * percentageAllocation). The collapsed cell shows a joined summary; expanding it
34
+ * opens a floating panel with one select + number input per entry, an add button,
35
+ * and a total indicator (green when the sum matches `expectedTotal`).
36
+ */
37
+ export interface InlineSubrowsConfig {
38
+ /** Path to the nested array on the row object (e.g. `'manureDerivation'`). */
39
+ arrayPath: string;
40
+ /** Field holding the code-list key in each sub-entry (e.g. `'zoologicalAnimal'`). */
41
+ keyField: string;
42
+ /** Key into the shared `CODE_LISTS` map for the key select options. */
43
+ keyCodeListKey: string;
44
+ /** i18n key for the key sub-column header inside the panel. */
45
+ keyLabelKey: string;
46
+ /** Field holding the numeric share in each sub-entry (e.g. `'percentageAllocation'`). */
47
+ valueField: string;
48
+ /** i18n key for the value sub-column header inside the panel. */
49
+ valueLabelKey: string;
50
+ /** i18n key for the "add sub-entry" button label. */
51
+ addLabelKey: string;
52
+ /** i18n key for the expand toggle label (collapsed state). */
53
+ expandLabelKey: string;
54
+ /** i18n key for the collapse toggle label (expanded state). */
55
+ collapseLabelKey: string;
56
+ /** i18n key for the total indicator label. */
57
+ totalLabelKey: string;
58
+ /** Expected sum of the value fields (e.g. 100) — the indicator turns green on exact
59
+ * match (no more, no less) and entered values are clamped so the sum never exceeds it. */
60
+ expectedTotal?: number;
61
+ /** Min for the value number input (default 0). */
62
+ valueMin?: number;
63
+ /** Max for the value number input (default: none). */
64
+ valueMax?: number;
65
+ }
66
+ /**
67
+ * Definition for a single column in an inline table.
68
+ *
69
+ * Each definition drives both the column header and the cell widget for that column.
70
+ * This is the per-column equivalent of a JSONForms uischema Control element.
71
+ */
72
+ export interface InlineColumnDef {
73
+ /**
74
+ * Unique key for this column.
75
+ * - For simple flat fields: also the property path on the row object.
76
+ * - For nested sub-array columns: used as a stable identifier; actual read/write
77
+ * path is determined by `arrayPath` + `arrayKeyField` + `arrayKeyValue`.
78
+ */
79
+ key: string;
80
+ /**
81
+ * Header label source.
82
+ * - By default treated as an i18n translation key (e.g. `'fieldSpreading.fields.fertiliser.product'`).
83
+ * - Set `labelLiteral: true` to use the value verbatim (e.g. `'Ntot (%)'`).
84
+ */
85
+ labelKey: string;
86
+ /**
87
+ * When `true`, `labelKey` is rendered as a plain string rather than passed through
88
+ * the translation service. Use this for labels that are already final (e.g. chemical
89
+ * formulas such as "P₂O₅ (%)").
90
+ * Default: `false`.
91
+ */
92
+ labelLiteral?: boolean;
93
+ /** Widget rendered inside the cell. */
94
+ type: InlineCellType;
95
+ /**
96
+ * For `type: 'select'` — key into the shared `CODE_LISTS` map.
97
+ * The generic component resolves the option list and their localized labels
98
+ * automatically via the `descriptor.designation_eng / designation_deu` convention.
99
+ */
100
+ codeListKey?: string;
101
+ /**
102
+ * For `type: 'select'` — how to display an option's label in the dropdown.
103
+ * - `'label'` (default): use `descriptor.designation_eng/deu` — best for named products.
104
+ * - `'id'`: use `String(entry.id)` verbatim — best for codes that are already
105
+ * human-readable (e.g. unit codes like "kg", "t", "l").
106
+ */
107
+ optionDisplay?: 'label' | 'id';
108
+ /**
109
+ * For `type: 'select'` — optional per-row narrowing of the code-list options,
110
+ * e.g. to restrict the product list based on another cell of the same row.
111
+ * Evaluated for every option of every row, so keep it cheap.
112
+ */
113
+ optionsFilter?: (entry: BaseCodeListEntry, row: Record<string, unknown>) => boolean;
114
+ /**
115
+ * For `type: 'select'` — resolve an option's label through an i18n key instead of the
116
+ * master-data descriptor (for literal option lists whose labels live in the locales,
117
+ * e.g. a row-type selector). Takes precedence over `optionDisplay`.
118
+ */
119
+ optionLabelKey?: (entry: BaseCodeListEntry) => string;
120
+ /**
121
+ * Optional i18n key for an explanatory tooltip shown via an info icon next to
122
+ * the column header (e.g. to explain a checkbox whose effect is not obvious).
123
+ * Omit for columns that need no extra explanation.
124
+ */
125
+ tooltipKey?: string;
126
+ /**
127
+ * CSS grid column-sizing token, e.g. `'minmax(140px, 2fr)'` or `'84px'`.
128
+ * These values are joined to build the `grid-template-columns` style on the table.
129
+ * Defaults to `'1fr'` when omitted.
130
+ */
131
+ width?: string;
132
+ /** Minimum allowed value — sets the `min` attribute (type `'number'` only). */
133
+ min?: number;
134
+ /** Maximum allowed value — sets the `max` attribute (type `'number'` only). */
135
+ max?: number;
136
+ /**
137
+ * `step` attribute value (type `'number'` only).
138
+ * Defaults to `'any'` when omitted, allowing any decimal.
139
+ */
140
+ step?: string;
141
+ /**
142
+ * Custom cell-value resolver — takes precedence over the default read path.
143
+ * Use this for `type: 'readonly'` columns whose value is derived from master
144
+ * data or other cells (e.g. a standard yield looked up from the selected crop)
145
+ * and therefore does not live on the row object.
146
+ */
147
+ valueResolver?: (row: Record<string, unknown>) => unknown;
148
+ /**
149
+ * Per-row disabling of the cell widget (e.g. grey out the yield input when the
150
+ * selected crop does not permit yield input). Evaluated per row, keep it cheap.
151
+ */
152
+ disabledForRow?: (row: Record<string, unknown>) => boolean;
153
+ /**
154
+ * Sub-array navigation config — for columns whose value lives inside a nested array
155
+ * on the row object (e.g. `ingredient[].quantity`).
156
+ *
157
+ * When all four sub-fields are set, the component:
158
+ * - **reads** `row[arrayPath].find(e => e[arrayKeyField] === arrayKeyValue)[arrayValueField]`
159
+ * - **writes** back immutably into that same slot
160
+ *
161
+ * Example — "Ntot %" column that reads `row.ingredient[{molecularFormula:'Ntot'}].quantity`:
162
+ * ```
163
+ * arrayPath: 'ingredient'
164
+ * arrayKeyField: 'molecularFormula'
165
+ * arrayKeyValue: 'Ntot'
166
+ * arrayValueField: 'quantity'
167
+ * ```
168
+ */
169
+ arrayPath?: string;
170
+ arrayKeyField?: string;
171
+ arrayKeyValue?: string;
172
+ arrayValueField?: string;
173
+ /**
174
+ * Sub-rows editor config — required when `type: 'subrows'`, ignored otherwise.
175
+ * Drives the expandable key/percentage pair editor (see `InlineSubrowsConfig`).
176
+ */
177
+ subrows?: InlineSubrowsConfig;
178
+ }
179
+ /**
180
+ * Full configuration for one inline-table instance — the "uischema" equivalent.
181
+ *
182
+ * Creating a table for a new domain means defining one `InlineTableConfig` object
183
+ * (and an optional `rowTransform` for business logic); the generic component handles
184
+ * all layout, rendering, and data binding.
185
+ */
186
+ export interface InlineTableConfig {
187
+ /** Ordered list of column definitions — determines column count and order. */
188
+ columns: InlineColumnDef[];
189
+ /** i18n key for the section heading (`<h2>`). */
190
+ titleKey: string;
191
+ /**
192
+ * i18n key for the section description paragraph.
193
+ * Omit (or set to `undefined`) to hide the description.
194
+ */
195
+ descriptionKey?: string;
196
+ /** i18n key for the "Add entry" dashed-button label. */
197
+ addLabelKey: string;
198
+ /** i18n key for the empty-state primary text (shown when `rows` is empty). */
199
+ emptyLabelKey: string;
200
+ /**
201
+ * i18n key for the empty-state hint text (secondary line).
202
+ * Omit to show only the primary text.
203
+ */
204
+ emptyHintKey?: string;
205
+ /**
206
+ * Factory function invoked when the user clicks "Add entry".
207
+ * Should return a fresh row object with sensible defaults (e.g. pre-initialised
208
+ * sub-arrays such as `ingredient`).
209
+ * Defaults to `() => ({})` when omitted.
210
+ */
211
+ createRow?: () => Record<string, unknown>;
212
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generic page wrapper for workflow steps that are present in navigation but not implemented yet.
3
+ */
4
+ export declare class ModulePlaceholderPageComponent {
5
+ readonly titleKey: import("@angular/core").InputSignal<string>;
6
+ }
@@ -0,0 +1,46 @@
1
+ import { PlanningBalanceService } from '../../core/planning/planning-balance.service';
2
+ import { MasterDataService } from '../../core/master-data/master-data.service';
3
+ import type { CropRequirementRow, NutrientEntry, ValidationMessage } from '../../core/planning/planning-balance.types';
4
+ export declare class PlanningResultComponent {
5
+ readonly embedded: import("@angular/core").InputSignal<boolean>;
6
+ readonly planning: PlanningBalanceService;
7
+ readonly masterData: MasterDataService;
8
+ private readonly result;
9
+ readonly validationMessages: import("@angular/core").Signal<ValidationMessage[]>;
10
+ /** Fodder net balance (positive = surplus, negative = deficit). */
11
+ readonly fodderTotal: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").FodderQuantity | null>;
12
+ readonly animalStockTotals: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").AnimalStock | null>;
13
+ /** Housing-type segments for the A2 table, pre-built to avoid dynamic key access in template. */
14
+ readonly animalStockSegments: import("@angular/core").Signal<{
15
+ label: string;
16
+ data: import("../../core/planning/planning-balance.types").TotalNutrientSet;
17
+ }[]>;
18
+ /** A3 equivalent: manure trading balance per product. */
19
+ readonly manureTradingBalance: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").FarmManureTrading | null>;
20
+ /** A4 equivalent: manure storage totals. */
21
+ readonly storageBalance: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").TotalNutrientSet | null>;
22
+ /** A5 equivalent: field spreading totals for key nutrients. */
23
+ readonly fieldSpreadingBalance: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").TotalNutrientSet | null>;
24
+ readonly requirementPerCultivationCategory: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").NutrientRequirementEntry[]>;
25
+ readonly totalRequirement: import("@angular/core").Signal<NutrientEntry[]>;
26
+ /**
27
+ * Merge area/yield data from fieldCultivation with nutrient requirements so
28
+ * each row has everything needed to display Section C of the PDF report.
29
+ */
30
+ readonly cropRequirementRows: import("@angular/core").Signal<CropRequirementRow[]>;
31
+ readonly fodderDetail: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").RequiredEffectiveYieldFromFodderCropland | null>;
32
+ readonly fodderEffectiveYield: import("@angular/core").Signal<import("../../core/planning/planning-balance.types").FodderQuantity | null>;
33
+ /** Human-readable label for a molecular formula symbol. */
34
+ formulaLabel(f: string): string;
35
+ /** Returns the quantity for a given formula from a nutrient entry list, or 0 if absent. */
36
+ reqValue(requirement: NutrientEntry[], formula: string): number;
37
+ /**
38
+ * Sums entries by formula for the given ordered formula list (kg unit only).
39
+ * Multiple per-product rows with the same formula are aggregated into one.
40
+ */
41
+ sumNutrients(entries: NutrientEntry[], formulas: readonly string[]): NutrientEntry[];
42
+ /** Summary chips for Sections A1–A5 (Ntot / P₂O₅ / K₂O / Mg). */
43
+ sumStockNutrients(entries: NutrientEntry[]): NutrientEntry[];
44
+ /** Summary chips for Sections C & D (N avail. / P₂O₅ / K₂O / Mg). */
45
+ sumKeyNutrients(entries: NutrientEntry[]): NutrientEntry[];
46
+ }
@@ -0,0 +1,34 @@
1
+ import { SuisseBilanzMetricsService } from '../suissebilanz-dashboard/suissebilanz-metrics.service';
2
+ import { GaugeStatus } from '../gauge-arc/gauge-arc.component';
3
+ /** Compact row + expandable detail for the latest planning-balance result. */
4
+ export declare class PlanningResultRowComponent {
5
+ protected readonly STATUS_ICONS: Record<GaugeStatus, string>;
6
+ private readonly planning;
7
+ private readonly naebi;
8
+ private readonly metadataSvc;
9
+ protected readonly metricsService: SuisseBilanzMetricsService;
10
+ protected readonly expanded: import("@angular/core").WritableSignal<boolean>;
11
+ protected readonly isLoading: import("@angular/core").Signal<boolean>;
12
+ protected readonly hasResult: import("@angular/core").Signal<boolean>;
13
+ protected readonly title: import("@angular/core").Signal<string>;
14
+ private readonly result;
15
+ /** Derived overall status: worst status across all nutrient metrics. */
16
+ protected readonly overallStatus: import("@angular/core").Signal<GaugeStatus>;
17
+ /** Compact chips for the 4 nutrient metrics + rendement, with kg values merged in. */
18
+ protected readonly nutrientChips: import("@angular/core").Signal<{
19
+ key: string;
20
+ label: string;
21
+ pct: number | null;
22
+ kg: number | null;
23
+ dt: number | null;
24
+ status: GaugeStatus;
25
+ }[]>;
26
+ /** Areas in ha (converted from m²). */
27
+ protected readonly areas: import("@angular/core").Signal<{
28
+ sau: number;
29
+ sfe: number;
30
+ to: number;
31
+ } | null>;
32
+ protected refresh(): void;
33
+ protected toggleDetail(): void;
34
+ }
@@ -0,0 +1,13 @@
1
+ import { PlanningBalanceService } from '../../core/planning/planning-balance.service';
2
+ /**
3
+ * Extracted trigger UI for running the planning balance calculation.
4
+ * Contains: submit button and progress bar.
5
+ * Delegates actual HTTP call to `PlanningBalanceService`.
6
+ */
7
+ export declare class PlanningTriggerComponent {
8
+ readonly planning: PlanningBalanceService;
9
+ private readonly naebi;
10
+ /** When true, the submit button is disabled regardless of loading state. */
11
+ readonly hasErrors: import("@angular/core").InputSignal<boolean>;
12
+ runPlanning(): void;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { ErrorObject } from 'ajv';
2
+ import { PageId } from '../../core/navigation/navigation.service';
3
+ import { PlanningBalanceService } from '../../core/planning/planning-balance.service';
4
+ export declare class ResultsPageComponent {
5
+ readonly currentPage: import("@angular/core").InputSignal<PageId>;
6
+ readonly onNavigate: import("@angular/core").InputSignal<(page: PageId) => void>;
7
+ readonly onErrorSelected: import("@angular/core").InputSignal<(error: ErrorObject) => void>;
8
+ readonly onSubmitSuccess: import("@angular/core").InputSignal<() => void>;
9
+ protected readonly planning: PlanningBalanceService;
10
+ protected readonly selectedTabIndex: import("@angular/core").WritableSignal<number>;
11
+ constructor();
12
+ protected onTabChange(index: number): void;
13
+ }
@@ -0,0 +1,32 @@
1
+ import { SafeUrl } from '@angular/platform-browser';
2
+ import { PlanningBalanceService } from '../../core/planning/planning-balance.service';
3
+ import { GaugeStatus } from '../gauge-arc/gauge-arc.component';
4
+ import { SuisseBilanzMetricsService } from './suissebilanz-metrics.service';
5
+ /**
6
+ * Dashboard card displaying the 5 main SuisseBilanz metrics as semicircular
7
+ * SVG gauges. Derives all display data from `PlanningBalanceService` via
8
+ * computed signals — fully zoneless-safe, `OnPush`.
9
+ *
10
+ * Shows an empty-state panel when no planning result is available yet.
11
+ */
12
+ export declare class SuisseBilanzDashboardComponent {
13
+ readonly embedded: import("@angular/core").InputSignal<boolean>;
14
+ /** Shows the official PDF download link even when `embedded` (header hidden). */
15
+ readonly showPdfButton: import("@angular/core").InputSignal<boolean>;
16
+ protected readonly planning: PlanningBalanceService;
17
+ private readonly sanitizer;
18
+ protected readonly metricsService: SuisseBilanzMetricsService;
19
+ private readonly result;
20
+ protected readonly metrics: import("@angular/core").Signal<import("../gauge-arc/gauge-arc.component").GaugeMetric[]>;
21
+ /** Surface areas in ha, derived from the latest planning result. */
22
+ protected readonly surfaces: import("@angular/core").Signal<{
23
+ sau: number;
24
+ sfe: number;
25
+ to: number;
26
+ } | null>;
27
+ protected readonly officialPdfUrl: import("@angular/core").Signal<SafeUrl | null>;
28
+ private prevBlobUrl;
29
+ private readonly blobCleanup;
30
+ /** Maps a `GaugeStatus` to its Material icon name for the status badge. */
31
+ protected statusIcon(status: GaugeStatus): string;
32
+ }
@@ -0,0 +1,21 @@
1
+ import { GaugeMetric } from '../gauge-arc/gauge-arc.component';
2
+ /**
3
+ * Shared source of truth for all SuisseBilanz metric view-models.
4
+ *
5
+ * Both the full dashboard card and the slim minibar consume this service so
6
+ * the derivation logic lives in exactly one place. Metrics re-compute via
7
+ * `computed()` when either the planning result or the locale signal changes.
8
+ */
9
+ export declare class SuisseBilanzMetricsService {
10
+ private readonly planning;
11
+ private readonly i18n;
12
+ /** Wall-clock time of the most recent successful planning result. */
13
+ readonly lastUpdated: import("@angular/core").WritableSignal<Date | null>;
14
+ constructor();
15
+ /**
16
+ * Five gauge view-models for N avail., P₂O₅, K₂O, Mg and Rendement prairies.
17
+ * Returns placeholder 'empty' metrics until the first planning result arrives.
18
+ */
19
+ readonly metrics: import("@angular/core").Signal<GaugeMetric[]>;
20
+ private emptyMetric;
21
+ }
@@ -0,0 +1,19 @@
1
+ import { GaugeMetric, GaugeStatus } from '../gauge-arc/gauge-arc.component';
2
+ import { SuisseBilanzMetricsService } from '../suissebilanz-dashboard/suissebilanz-metrics.service';
3
+ /**
4
+ * Slim, always-visible metrics card placed above the workflow stepper.
5
+ *
6
+ * Shows the same 5 SuisseBilanz metrics as the full dashboard card but in a
7
+ * compact single-row layout: metric label → bold coloured value → thin
8
+ * progress bar. Shares all data logic via `SuisseBilanzMetricsService`.
9
+ */
10
+ export declare class SuisseBilanzMinibarComponent {
11
+ protected readonly metricsService: SuisseBilanzMetricsService;
12
+ /** Returns the status colour for a given metric status. */
13
+ protected statusColor(status: GaugeStatus): string;
14
+ /**
15
+ * Maps the metric value to a 0–100 fill percentage for the progress bar,
16
+ * clamped so bars never overflow the track.
17
+ */
18
+ protected fillPct(metric: GaugeMetric): number;
19
+ }
@@ -0,0 +1,18 @@
1
+ import { ErrorObject } from 'ajv';
2
+ import { PlanningBalanceService } from '../../core/planning/planning-balance.service';
3
+ /**
4
+ * Final submission step: review validation status and submit the planning balance.
5
+ */
6
+ export declare class ValidationPageComponent {
7
+ readonly showHeader: import("@angular/core").InputSignal<boolean>;
8
+ /** Navigation callback for validation error clicks — provided by App to keep routing logic centralised. */
9
+ readonly onErrorSelected: import("@angular/core").InputSignal<(error: ErrorObject) => void>;
10
+ /** Navigation callback triggered after a fresh successful planning submission. */
11
+ readonly onSubmitSuccess: import("@angular/core").InputSignal<() => void>;
12
+ protected readonly planning: PlanningBalanceService;
13
+ private readonly globalValidation;
14
+ private lastHandledSuccessRequestId;
15
+ constructor();
16
+ protected readonly validationErrors: import("@angular/core").Signal<import("../../../public-api").EnrichedValidationError[]>;
17
+ protected readonly errorCount: import("@angular/core").Signal<number>;
18
+ }
@@ -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
+ }