@agridea/suibi-module 0.1.0-preview.f010f7a → 0.1.0-preview.f7f4d19

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 (38) hide show
  1. package/dist/elements/browser/main.js +69 -69
  2. package/dist/elements/browser/suibi-module-latest.js +69 -69
  3. package/dist/elements/browser/{suibi-module.v0.1.0-preview.f010f7a.js → suibi-module.v0.1.0-preview.f7f4d19.js} +69 -69
  4. package/dist/elements/browser/version.txt +1 -1
  5. package/dist/types/app/components/inline-table/inline-table.component.d.ts +6 -2
  6. package/dist/types/app/components/inline-table/inline-table.types.d.ts +4 -2
  7. package/dist/types/app/core/i18n/i18n.service.d.ts +1 -0
  8. package/dist/types/app/core/planning/planning-balance.service.d.ts +1 -0
  9. package/dist/types/app/core/utils/object.util.d.ts +10 -0
  10. package/dist/types/app/nutrient-cycle/animal-stock/{animal-stock-detail.component.d.ts → animal-stock-detail/animal-stock-detail.component.d.ts} +2 -2
  11. package/dist/types/app/nutrient-cycle/animal-stock/{animal-stock-list.component.d.ts → animal-stock-list/animal-stock-list.component.d.ts} +1 -1
  12. package/dist/types/app/nutrient-cycle/animal-stock/{animal-stock-master-detail.component.d.ts → animal-stock-master-detail/animal-stock-master-detail.component.d.ts} +2 -2
  13. package/dist/types/app/nutrient-cycle/animal-stock/index.d.ts +3 -3
  14. package/dist/types/app/nutrient-cycle/farm-manure-trading/{farm-manure-trading-detail.component.d.ts → farm-manure-trading-detail/farm-manure-trading-detail.component.d.ts} +2 -2
  15. package/dist/types/app/nutrient-cycle/farm-manure-trading/{farm-manure-trading-list.component.d.ts → farm-manure-trading-list/farm-manure-trading-list.component.d.ts} +2 -2
  16. package/dist/types/app/nutrient-cycle/farm-manure-trading/{farm-manure-trading-master-detail.component.d.ts → farm-manure-trading-master-detail/farm-manure-trading-master-detail.component.d.ts} +3 -3
  17. package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +3 -3
  18. package/dist/types/app/nutrient-cycle/field-cultivation/{field-cultivation-detail.component.d.ts → field-cultivation-detail/field-cultivation-detail.component.d.ts} +2 -2
  19. package/dist/types/app/nutrient-cycle/field-cultivation/{field-cultivation-general.component.d.ts → field-cultivation-general/field-cultivation-general.component.d.ts} +2 -2
  20. package/dist/types/app/nutrient-cycle/field-cultivation/{field-cultivation-list.component.d.ts → field-cultivation-list/field-cultivation-list.component.d.ts} +1 -1
  21. package/dist/types/app/nutrient-cycle/field-cultivation/{field-cultivation-master-detail.component.d.ts → field-cultivation-master-detail/field-cultivation-master-detail.component.d.ts} +2 -2
  22. package/dist/types/app/nutrient-cycle/field-cultivation/index.d.ts +4 -3
  23. package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.component.d.ts +6 -1
  24. package/dist/types/app/nutrient-cycle/field-spreading/ingredient.util.d.ts +8 -0
  25. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.component.d.ts +13 -4
  26. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.config.d.ts +4 -3
  27. package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-transaction-unit.util.d.ts +4 -0
  28. package/dist/types/app/nutrient-cycle/fodder/{fodder-detail.component.d.ts → fodder-detail/fodder-detail.component.d.ts} +4 -4
  29. package/dist/types/app/nutrient-cycle/fodder/{fodder-list.component.d.ts → fodder-list/fodder-list.component.d.ts} +2 -2
  30. package/dist/types/app/nutrient-cycle/fodder/{fodder-master-detail.component.d.ts → fodder-master-detail/fodder-master-detail.component.d.ts} +2 -2
  31. package/dist/types/app/nutrient-cycle/fodder/index.d.ts +3 -3
  32. package/dist/types/app/nutrient-cycle/storage/index.d.ts +3 -3
  33. package/dist/types/app/nutrient-cycle/storage/{storage-detail.component.d.ts → storage-detail/storage-detail.component.d.ts} +3 -3
  34. package/dist/types/app/nutrient-cycle/storage/{storage-general.component.d.ts → storage-general/storage-general.component.d.ts} +4 -4
  35. package/dist/types/app/nutrient-cycle/storage/{storage-list.component.d.ts → storage-list/storage-list.component.d.ts} +4 -1
  36. package/dist/types/app/nutrient-cycle/storage/{storage-master-detail.component.d.ts → storage-master-detail/storage-master-detail.component.d.ts} +5 -2
  37. package/package.json +1 -1
  38. /package/dist/elements/browser/{suibi-module.v0.1.0-preview.f010f7a.css → suibi-module.v0.1.0-preview.f7f4d19.css} +0 -0
@@ -1 +1 @@
1
- 0.1.0-preview.f010f7a f010f7a
1
+ 0.1.0-preview.f7f4d19 f7f4d19
@@ -84,9 +84,13 @@ export declare class InlineTableComponent {
84
84
  private setValue;
85
85
  /** Called when a `mat-select` selection changes. */
86
86
  onSelectChange(rowIdx: number, col: InlineColumnDef, value: unknown): void;
87
- /** Called on `(change)` of a number `<input>` — parses the string value and guards NaN. */
87
+ /** Called on `(input)` of a number `<input>` — parses the string value and guards NaN.
88
+ * Uses `input` (not `change`) so every keystroke commits immediately: relying on blur
89
+ * meant edits were lost whenever the table was destroyed before the field lost focus
90
+ * (e.g. navigating to another page), even though switching same-page tabs hid the bug
91
+ * since mat-tab-group keeps inactive tab content mounted. */
88
92
  onNumberChange(rowIdx: number, col: InlineColumnDef, event: Event): void;
89
- /** Called on `(change)` of a text `<input>`. */
93
+ /** Called on `(input)` of a text `<input>` (see onNumberChange for why not `(change)`). */
90
94
  onTextChange(rowIdx: number, col: InlineColumnDef, event: Event): void;
91
95
  /** Appends a blank row produced by `config.createRow()`. */
92
96
  addRow(): void;
@@ -11,8 +11,10 @@
11
11
  * To reuse the table for a different domain, create a new config file and a thin
12
12
  * wrapper component. Only the config changes; the rendering component stays the same.
13
13
  */
14
- /** Supported cell widget types. Extend with new literal types as needed. */
15
- export type InlineCellType = 'select' | 'number' | 'text';
14
+ /** Supported cell widget types. Extend with new literal types as needed.
15
+ * 'readonly' renders the resolved value as plain text (no input) — for columns
16
+ * that are fully derived from other fields and must not be user-editable. */
17
+ export type InlineCellType = 'select' | 'number' | 'text' | 'readonly';
16
18
  /**
17
19
  * Definition for a single column in an inline table.
18
20
  *
@@ -8,6 +8,7 @@ export declare class I18nService {
8
8
  readonly jsonFormsI18n: Signal<{
9
9
  locale: Locale;
10
10
  translate: JsonFormsTranslator;
11
+ translateError: (error: unknown, translate: JsonFormsTranslator) => string;
11
12
  }>;
12
13
  setLocale(locale: Locale): void;
13
14
  /** Returns true if the given string is a supported locale key. */
@@ -11,6 +11,7 @@ export type PlanningEndpoint = 'ebilanz' | 'blw';
11
11
  */
12
12
  export declare class PlanningBalanceService {
13
13
  private readonly http;
14
+ private readonly metadataSvc;
14
15
  private readonly _value;
15
16
  private readonly _error;
16
17
  private readonly _isLoading;
@@ -22,3 +22,13 @@ export declare function deepEqual(a: unknown, b: unknown): boolean;
22
22
  * @returns A deep copy of the value
23
23
  */
24
24
  export declare function deepClone<T>(value: T): T;
25
+ /**
26
+ * Recursively drops `ingredient[]` entries whose `quantity` is null/undefined.
27
+ *
28
+ * Inline tables (fertiliser/recycling) pre-populate every nutrient slot in `ingredient[]`
29
+ * so the UI always shows all formula columns, but slots the user never fills in stay as
30
+ * `{ molecularFormula, quantity: null, unit }`. The calculation API rejects any ingredient
31
+ * entry that's present but incomplete, so submitted payloads must omit those still-empty
32
+ * slots entirely rather than send them with a null quantity.
33
+ */
34
+ export declare function stripIncompleteIngredients<T>(value: T): T;
@@ -1,5 +1,5 @@
1
1
  import { JsonSchema, UISchemaElement } from '@jsonforms/core';
2
- import { AnimalStockRow } from './animal-stock.types';
2
+ import { AnimalStockRow } from '../animal-stock.types';
3
3
  import { ErrorObject } from 'ajv';
4
4
  export declare class AnimalStockDetailComponent {
5
5
  private readonly i18n;
@@ -10,7 +10,7 @@ export declare class AnimalStockDetailComponent {
10
10
  itemSchema: import("@angular/core").Signal<JsonSchema>;
11
11
  private readonly baseUi;
12
12
  localizedUi: import("@angular/core").Signal<UISchemaElement>;
13
- jsonFormsData: import("@angular/core").Signal<(AnimalStockRow & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
13
+ jsonFormsData: import("@angular/core").Signal<(AnimalStockRow & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
14
14
  readonly renderers: {
15
15
  tester: import("@jsonforms/core").RankedTester;
16
16
  renderer: any;
@@ -1,5 +1,5 @@
1
1
  import { CdkDragDrop } from '@angular/cdk/drag-drop';
2
- import { AnimalStockRow } from './animal-stock.types';
2
+ import { AnimalStockRow } from '../animal-stock.types';
3
3
  export declare class AnimalStockListComponent {
4
4
  private readonly masterData;
5
5
  rows: import("@angular/core").InputSignal<AnimalStockRow[]>;
@@ -1,5 +1,5 @@
1
- import { AnimalStockRow } from './animal-stock.types';
2
- import { LifetimePerformance } from '../lifetime-performance/lifetime-performance.types';
1
+ import { AnimalStockRow } from '../animal-stock.types';
2
+ import { LifetimePerformance } from '../../lifetime-performance/lifetime-performance.types';
3
3
  export declare class AnimalStockMasterDetailComponent {
4
4
  private readonly dataSvc;
5
5
  private readonly navigationSvc;
@@ -1,4 +1,4 @@
1
- export * from './animal-stock-list.component';
2
- export * from './animal-stock-detail.component';
3
- export * from './animal-stock-master-detail.component';
1
+ export * from './animal-stock-list/animal-stock-list.component';
2
+ export * from './animal-stock-detail/animal-stock-detail.component';
3
+ export * from './animal-stock-master-detail/animal-stock-master-detail.component';
4
4
  export * from './animal-stock.types';
@@ -1,5 +1,5 @@
1
1
  import { JsonSchema, UISchemaElement } from '@jsonforms/core';
2
- import { FarmManureTradingSupply, FarmManureTradingDispense } from './farm-manure-trading.types';
2
+ import { FarmManureTradingSupply, FarmManureTradingDispense } from '../farm-manure-trading.types';
3
3
  type Mode = 'supply' | 'dispense';
4
4
  type TradingRow = FarmManureTradingSupply | FarmManureTradingDispense;
5
5
  export declare class FarmManureTradingDetailComponent {
@@ -19,7 +19,7 @@ export declare class FarmManureTradingDetailComponent {
19
19
  itemSchema: import("@angular/core").Signal<JsonSchema>;
20
20
  localizedUi: import("@angular/core").Signal<UISchemaElement>;
21
21
  detailTitle: import("@angular/core").Signal<string>;
22
- jsonFormsData: import("@angular/core").Signal<(FarmManureTradingSupply & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
22
+ jsonFormsData: import("@angular/core").Signal<(FarmManureTradingSupply & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
23
23
  onDataChange(event: any): void;
24
24
  private applyDerivedFields;
25
25
  }
@@ -1,5 +1,5 @@
1
- import { FarmManureTradingSupply, FarmManureTradingDispense } from './farm-manure-trading.types';
2
- import { FarmManureTradingMode } from '../../core/navigation/navigation.service';
1
+ import { FarmManureTradingSupply, FarmManureTradingDispense } from '../farm-manure-trading.types';
2
+ import { FarmManureTradingMode } from '../../../core/navigation/navigation.service';
3
3
  export type TradingMode = FarmManureTradingMode;
4
4
  type TradingRow = FarmManureTradingSupply | FarmManureTradingDispense;
5
5
  export declare class FarmManureTradingListComponent {
@@ -1,12 +1,12 @@
1
- import { TradingMode } from './farm-manure-trading-list.component';
2
- import { FarmManureTradingSupply, FarmManureTradingDispense } from './farm-manure-trading.types';
1
+ import { TradingMode } from '../farm-manure-trading-list/farm-manure-trading-list.component';
2
+ import { FarmManureTradingSupply, FarmManureTradingDispense } from '../farm-manure-trading.types';
3
3
  export declare class FarmManureTradingMasterDetailComponent {
4
4
  private readonly dataSvc;
5
5
  private readonly navigationSvc;
6
6
  constructor();
7
7
  readonly supplyRows: import("@angular/core").Signal<FarmManureTradingSupply[]>;
8
8
  readonly dispenseRows: import("@angular/core").Signal<FarmManureTradingDispense[]>;
9
- readonly activeTab: import("@angular/core").WritableSignal<import("../../core/navigation/navigation.service").FarmManureTradingMode>;
9
+ readonly activeTab: import("@angular/core").WritableSignal<import("../../../core/navigation/navigation.service").FarmManureTradingMode>;
10
10
  readonly selectedSupplyIndex: import("@angular/core").WritableSignal<number | null>;
11
11
  readonly selectedDispenseIndex: import("@angular/core").WritableSignal<number | null>;
12
12
  readonly currentDetail: import("@angular/core").Signal<FarmManureTradingSupply | null>;
@@ -1,4 +1,4 @@
1
- export * from './farm-manure-trading-list.component';
2
- export * from './farm-manure-trading-detail.component';
3
- export * from './farm-manure-trading-master-detail.component';
1
+ export * from './farm-manure-trading-list/farm-manure-trading-list.component';
2
+ export * from './farm-manure-trading-detail/farm-manure-trading-detail.component';
3
+ export * from './farm-manure-trading-master-detail/farm-manure-trading-master-detail.component';
4
4
  export * from './farm-manure-trading.types';
@@ -1,5 +1,5 @@
1
1
  import { JsonSchema, UISchemaElement } from '@jsonforms/core';
2
- import { FieldCultivationDetailEntry, FieldCultivationDetailMode } from './field-cultivation.types';
2
+ import { FieldCultivationDetailEntry, FieldCultivationDetailMode } from '../field-cultivation.types';
3
3
  export declare class FieldCultivationDetailComponent {
4
4
  private readonly i18n;
5
5
  readonly row: import("@angular/core").InputSignal<FieldCultivationDetailEntry | null>;
@@ -17,6 +17,6 @@ export declare class FieldCultivationDetailComponent {
17
17
  readonly itemSchema: import("@angular/core").Signal<JsonSchema>;
18
18
  readonly localizedUi: import("@angular/core").Signal<UISchemaElement>;
19
19
  readonly detailTitle: import("@angular/core").Signal<string>;
20
- readonly jsonFormsData: import("@angular/core").Signal<(import("./field-cultivation.types").FieldCultivationFodderCropland & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | (import("./field-cultivation.types").FieldCultivationSpecial & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
20
+ readonly jsonFormsData: import("@angular/core").Signal<(import("..").FieldCultivationFodderCropland & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | (import("..").FieldCultivationSpecial & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
21
21
  onDataChange(event: unknown): void;
22
22
  }
@@ -1,5 +1,5 @@
1
1
  import { JsonSchema } from '@jsonforms/core';
2
- import { FieldCultivationCropHarvest, FieldCultivationData } from './field-cultivation.types';
2
+ import { FieldCultivationCropHarvest, FieldCultivationData } from '../field-cultivation.types';
3
3
  export declare class FieldCultivationGeneralComponent {
4
4
  private readonly i18n;
5
5
  readonly value: import("@angular/core").InputSignal<FieldCultivationData>;
@@ -17,6 +17,6 @@ export declare class FieldCultivationGeneralComponent {
17
17
  indoorVegetableMainCropAreaSize: number | null | undefined;
18
18
  feedingOfCropHarvest: FieldCultivationCropHarvest[] | undefined;
19
19
  dispenseOfCropHarvest: FieldCultivationCropHarvest[] | undefined;
20
- } & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
20
+ } & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
21
21
  onDataChange(event: unknown): void;
22
22
  }
@@ -1,4 +1,4 @@
1
- import { FieldCultivationDetailEntry, FieldCultivationDetailMode } from './field-cultivation.types';
1
+ import { FieldCultivationDetailEntry, FieldCultivationDetailMode } from '../field-cultivation.types';
2
2
  export declare class FieldCultivationListComponent {
3
3
  private readonly masterData;
4
4
  private readonly i18n;
@@ -1,5 +1,5 @@
1
- import { FieldCultivationTab } from '../../core/navigation/navigation.service';
2
- import { FieldCultivationArableLand, FieldCultivationData, FieldCultivationDetailEntry, FieldCultivationDetailMode, FieldCultivationFodderCropland, FieldCultivationSpecial } from './field-cultivation.types';
1
+ import { FieldCultivationTab } from '../../../core/navigation/navigation.service';
2
+ import { FieldCultivationArableLand, FieldCultivationData, FieldCultivationDetailEntry, FieldCultivationDetailMode, FieldCultivationFodderCropland, FieldCultivationSpecial } from '../field-cultivation.types';
3
3
  export declare class FieldCultivationMasterDetailComponent {
4
4
  private readonly dataSvc;
5
5
  private readonly navigationSvc;
@@ -1,4 +1,5 @@
1
- export * from './field-cultivation-list.component';
2
- export * from './field-cultivation-detail.component';
3
- export * from './field-cultivation-master-detail.component';
1
+ export * from './field-cultivation-list/field-cultivation-list.component';
2
+ export * from './field-cultivation-detail/field-cultivation-detail.component';
3
+ export * from './field-cultivation-general/field-cultivation-general.component';
4
+ export * from './field-cultivation-master-detail/field-cultivation-master-detail.component';
4
5
  export * from './field-cultivation.types';
@@ -23,11 +23,16 @@ export declare class FertiliserTableComponent {
23
23
  protected readonly config: import("../../../components/inline-table/inline-table.types").InlineTableConfig;
24
24
  /** Cast typed entries to the generic Record[] expected by InlineTableComponent. */
25
25
  readonly rowsForTable: import("@angular/core").Signal<Record<string, unknown>[]>;
26
- /** Cast the generic output back to the typed FieldSpreadingFertiliserEntry[]. */
26
+ /** Cast the generic output back to the typed FieldSpreadingFertiliserEntry[], stripping any
27
+ * ingredient with a 0 quantity so it never reaches the final JSON. */
27
28
  onRowsChange(rows: Record<string, unknown>[]): void;
28
29
  /**
29
30
  * Row transform for auto-populating nutrient columns when a product is selected.
30
31
  *
32
+ * Also imposes `transactionUnit = 'kg'` on every edit (not just product changes) so
33
+ * stale/imported rows with a different or null unit get corrected once touched —
34
+ * `createRow` already defaults new rows to 'kg', this is only a safety net.
35
+ *
31
36
  * Defined as an arrow-function property so `this` is never needed and the function
32
37
  * can be passed as a value to InlineTableComponent without losing its context.
33
38
  *
@@ -0,0 +1,8 @@
1
+ import { FieldSpreadingIngredient } from './field-spreading.types';
2
+ /**
3
+ * Ensures all ingredients are present in the output, converting `null` quantities to `0`
4
+ * to satisfy API requirements while still filtering out explicitly zeroed entries.
5
+ */
6
+ export declare function stripZeroQuantityIngredients<T extends {
7
+ ingredient?: FieldSpreadingIngredient[];
8
+ }>(entries: T[]): T[];
@@ -6,9 +6,10 @@ import { FieldSpreadingRecyclingEntry } from '../field-spreading.types';
6
6
  * 1. Provides `RECYCLING_TABLE_CONFIG` (the column/section "uischema").
7
7
  * 2. Bridges typed `FieldSpreadingRecyclingEntry[]` to/from the generic
8
8
  * `Record<string, unknown>[]` API of InlineTableComponent.
9
- *
10
- * Unlike FertiliserTableComponent, no `rowTransform` is needed here — recycling
11
- * products have no auto-population logic; all nutrient values are entered manually.
9
+ * 3. Supplies `deriveUnits` as a `rowTransform` — `transactionUnit` ('kg'/'m3') and every
10
+ * ingredient's `unit` ('kg/t'/'kg/m3') are fully derived from the selected product's
11
+ * matterState (never user-entered) — they are separate mappings, NOT a concatenation of
12
+ * one into the other (kg/kg would be wrong for solid products).
12
13
  */
13
14
  export declare class RecyclingTableComponent {
14
15
  readonly entries: import("@angular/core").InputSignal<FieldSpreadingRecyclingEntry[]>;
@@ -17,6 +18,14 @@ export declare class RecyclingTableComponent {
17
18
  protected readonly config: import("../../../components/inline-table/inline-table.types").InlineTableConfig;
18
19
  /** Cast typed entries to generic Record[] for InlineTableComponent. */
19
20
  readonly rowsForTable: import("@angular/core").Signal<Record<string, unknown>[]>;
20
- /** Cast generic output back to typed FieldSpreadingRecyclingEntry[]. */
21
+ /** Cast generic output back to typed FieldSpreadingRecyclingEntry[], stripping any
22
+ * ingredient with a 0 quantity so it never reaches the final JSON. */
21
23
  onRowsChange(rows: Record<string, unknown>[]): void;
24
+ /**
25
+ * Row transform re-deriving `transactionUnit` and every ingredient's `unit` from the
26
+ * product's matterState on each edit — runs unconditionally (not just when
27
+ * `typeOfManureRecyclingProduct` changes) so an edit made before the product is picked still
28
+ * resolves once it is.
29
+ */
30
+ readonly deriveUnits: (_changedKey: string, _newValue: unknown, row: Record<string, unknown>) => Record<string, unknown>;
22
31
  }
@@ -4,13 +4,14 @@
4
4
  * This is the "uischema" for the Recycling fertilisers tab.
5
5
  * The structure mirrors fertiliser-table.config.ts — only the columns differ:
6
6
  * - Product field: typeOfManureRecyclingProduct (different code list)
7
- * - Nutrient columns: Ntot, NSol, P₂O₅, K₂O, Mg expressed in kg/unit (not %)
7
+ * - Nutrient columns: Ntot, Nlos, P₂O₅, K₂O, Mg expressed in kg/unit (not %)
8
8
  * — 5 nutrients vs 4 for mineral fertilisers, no auto-population on product select.
9
9
  *
10
10
  * To adapt again for a new domain, copy this file and adjust columns + i18n keys.
11
11
  */
12
12
  import type { InlineTableConfig } from '../../../components/inline-table/inline-table.types';
13
- /** Nutrient formulas tracked per recycling entry, in display order. */
14
- export declare const RECYCLING_NUTRIENT_COLUMNS: readonly ["Ntot", "NSol", "P2O5", "K2O", "Mg"];
13
+ /** Nutrient formulas tracked per recycling entry, in display order. 'Nlos' = soluble nitrogen (matches the
14
+ * `molecularFormula` enum from assets/master-data/substances.json — NOT 'NSol', which the API rejects). */
15
+ export declare const RECYCLING_NUTRIENT_COLUMNS: readonly ["Ntot", "Nlos", "P2O5", "K2O", "Mg"];
15
16
  export type RecyclingNutrientFormula = (typeof RECYCLING_NUTRIENT_COLUMNS)[number];
16
17
  export declare const RECYCLING_TABLE_CONFIG: InlineTableConfig;
@@ -0,0 +1,4 @@
1
+ /** Derives the mandatory transaction unit ('kg' or 'm3') from the product's matterState. */
2
+ export declare function deriveRecyclingTransactionUnit(productCode: string | null | undefined): string | null;
3
+ /** Derives the mandatory ingredient unit ('kg/t' or 'kg/m3') from the product's matterState. */
4
+ export declare function deriveRecyclingIngredientUnit(productCode: string | null | undefined): string | null;
@@ -1,6 +1,6 @@
1
1
  import { JsonSchema, UISchemaElement } from '@jsonforms/core';
2
- import { FodderMode } from '../../core/navigation/navigation.service';
3
- import { FodderCropFromNonFodderCropland, FodderDispense, FodderSupply } from './fodder.types';
2
+ import { FodderMode } from '../../../core/navigation/navigation.service';
3
+ import { FodderCropFromNonFodderCropland, FodderDispense, FodderSupply } from '../fodder.types';
4
4
  type FodderRow = FodderSupply | FodderDispense | FodderCropFromNonFodderCropland;
5
5
  export declare class FodderDetailComponent {
6
6
  private readonly i18n;
@@ -23,8 +23,8 @@ export declare class FodderDetailComponent {
23
23
  quantity?: number;
24
24
  typeOfFeedstuffProduct?: string;
25
25
  transactionUnit?: string;
26
- ingredient?: import("./fodder.types").FodderIngredient[];
27
- } & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
26
+ ingredient?: import("..").FodderIngredient[];
27
+ } & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
28
28
  onDataChange(event: unknown): void;
29
29
  private applyDerivedFields;
30
30
  }
@@ -1,5 +1,5 @@
1
- import { FodderCropFromNonFodderCropland, FodderDispense, FodderSupply } from './fodder.types';
2
- import { FodderMode } from '../../core/navigation/navigation.service';
1
+ import { FodderCropFromNonFodderCropland, FodderDispense, FodderSupply } from '../fodder.types';
2
+ import { FodderMode } from '../../../core/navigation/navigation.service';
3
3
  type FodderRow = FodderSupply | FodderDispense | FodderCropFromNonFodderCropland;
4
4
  export declare class FodderListComponent {
5
5
  private readonly masterData;
@@ -1,5 +1,5 @@
1
- import { FodderMode } from '../../core/navigation/navigation.service';
2
- import { FodderCropFromNonFodderCropland, FodderDispense, FodderSupply } from './fodder.types';
1
+ import { FodderMode } from '../../../core/navigation/navigation.service';
2
+ import { FodderCropFromNonFodderCropland, FodderDispense, FodderSupply } from '../fodder.types';
3
3
  type FodderRow = FodderSupply | FodderDispense | FodderCropFromNonFodderCropland;
4
4
  export declare class FodderMasterDetailComponent {
5
5
  private readonly dataSvc;
@@ -1,4 +1,4 @@
1
- export * from './fodder-list.component';
2
- export * from './fodder-detail.component';
3
- export * from './fodder-master-detail.component';
1
+ export * from './fodder-list/fodder-list.component';
2
+ export * from './fodder-detail/fodder-detail.component';
3
+ export * from './fodder-master-detail/fodder-master-detail.component';
4
4
  export * from './fodder.types';
@@ -1,4 +1,4 @@
1
- export * from './storage-list.component';
2
- export * from './storage-detail.component';
3
- export * from './storage-master-detail.component';
1
+ export * from './storage-list/storage-list.component';
2
+ export * from './storage-detail/storage-detail.component';
3
+ export * from './storage-master-detail/storage-master-detail.component';
4
4
  export * from './storage.types';
@@ -1,5 +1,5 @@
1
1
  import { JsonSchema, UISchemaElement } from '@jsonforms/core';
2
- import { ManurePitEntry, SlurryTankEntry, StorageEntryType } from './storage.types';
2
+ import { ManurePitEntry, SlurryTankEntry, StorageEntryType } from '../storage.types';
3
3
  export declare class StorageDetailComponent {
4
4
  private readonly i18n;
5
5
  readonly type: import("@angular/core").InputSignal<StorageEntryType>;
@@ -17,7 +17,7 @@ export declare class StorageDetailComponent {
17
17
  readonly jsonFormsData: import("@angular/core").Signal<(({
18
18
  descriptor?: string;
19
19
  cover?: number | null;
20
- manureFromAnimalStockStored?: import("./storage.types").ManureFromAnimalStockStored[];
20
+ manureFromAnimalStockStored?: import("..").ManureFromAnimalStockStored[];
21
21
  } | {
22
22
  descriptor?: string;
23
23
  volumeInM3?: number | null;
@@ -25,6 +25,6 @@ export declare class StorageDetailComponent {
25
25
  cover?: number | null;
26
26
  mixingFrequency?: number | null;
27
27
  manureDerivation?: string[];
28
- }) & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
28
+ }) & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
29
29
  onDataChange(event: unknown): void;
30
30
  }
@@ -1,5 +1,5 @@
1
1
  import { JsonSchema, UISchemaElement } from '@jsonforms/core';
2
- import { StorageNormalized } from './storage.types';
2
+ import { StorageNormalized } from '../storage.types';
3
3
  type StorageSection = 'manure' | 'slurry' | 'slurryFacilityToggle' | 'general';
4
4
  export declare class StorageGeneralComponent {
5
5
  private readonly i18n;
@@ -17,13 +17,13 @@ export declare class StorageGeneralComponent {
17
17
  stableStrawLitter: number | null;
18
18
  manureSupplyProportionStored: number | null;
19
19
  createFacilitySpecificManureProduct: boolean;
20
- } & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | ({
20
+ } & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | ({
21
21
  createFacilitySpecificSlurryProduct: boolean;
22
- } & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | ({
22
+ } & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | ({
23
23
  slurrySupplyProportionStored: number | null;
24
24
  slurryTankQuantity: number | null;
25
25
  dilutionRatio: number | null;
26
- } & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
26
+ } & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
27
27
  onDataChange(event: unknown): void;
28
28
  }
29
29
  export {};
@@ -1,10 +1,11 @@
1
- import { ManurePitEntry, SlurryTankEntry, StorageEntryType } from './storage.types';
1
+ import { ManurePitEntry, SlurryTankEntry, StorageEntryType } from '../storage.types';
2
2
  export declare class StorageListComponent {
3
3
  private readonly i18n;
4
4
  private readonly masterData;
5
5
  readonly rows: import("@angular/core").InputSignal<(ManurePitEntry | SlurryTankEntry)[]>;
6
6
  readonly selectedIndex: import("@angular/core").InputSignal<number | null>;
7
7
  readonly type: import("@angular/core").InputSignal<StorageEntryType>;
8
+ readonly errorIndices: import("@angular/core").InputSignal<ReadonlySet<number>>;
8
9
  readonly select: import("@angular/core").OutputEmitterRef<number>;
9
10
  readonly add: import("@angular/core").OutputEmitterRef<void>;
10
11
  readonly delete: import("@angular/core").OutputEmitterRef<number>;
@@ -12,6 +13,8 @@ export declare class StorageListComponent {
12
13
  readonly headerName: import("@angular/core").Signal<string>;
13
14
  readonly headerMeta: import("@angular/core").Signal<string>;
14
15
  resolveName(row: ManurePitEntry | SlurryTankEntry, index: number): string;
16
+ rowHasError(index: number): boolean;
17
+ rowErrorLabel(): string;
15
18
  resolveMeta(row: ManurePitEntry | SlurryTankEntry): string;
16
19
  emptyLabel(): string;
17
20
  emptyHintLabel(): string;
@@ -1,8 +1,9 @@
1
- import { StorageTab } from '../../core/navigation/navigation.service';
2
- import { ManurePitEntry, SlurryTankEntry, StorageEntryType, StorageNormalized } from './storage.types';
1
+ import { StorageTab } from '../../../core/navigation/navigation.service';
2
+ import { ManurePitEntry, SlurryTankEntry, StorageEntryType, StorageNormalized } from '../storage.types';
3
3
  export declare class StorageMasterDetailComponent {
4
4
  private readonly dataSvc;
5
5
  private readonly navigationSvc;
6
+ private readonly globalValidation;
6
7
  constructor();
7
8
  readonly storage: import("@angular/core").Signal<StorageNormalized>;
8
9
  readonly manurePitRows: import("@angular/core").Signal<ManurePitEntry[]>;
@@ -11,6 +12,8 @@ export declare class StorageMasterDetailComponent {
11
12
  readonly selectedIndex: import("@angular/core").WritableSignal<number | null>;
12
13
  readonly manureFacilitySpecificEnabled: import("@angular/core").Signal<boolean>;
13
14
  readonly slurryFacilitySpecificEnabled: import("@angular/core").Signal<boolean>;
15
+ readonly manurePitErrorIndices: import("@angular/core").Signal<Set<number>>;
16
+ readonly slurryTankErrorIndices: import("@angular/core").Signal<Set<number>>;
14
17
  readonly detailOpen: import("@angular/core").Signal<boolean>;
15
18
  readonly detailType: import("@angular/core").Signal<StorageEntryType>;
16
19
  readonly currentDetail: import("@angular/core").Signal<ManurePitEntry | SlurryTankEntry | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agridea/suibi-module",
3
- "version": "0.1.0-preview.f010f7a",
3
+ "version": "0.1.0-preview.f7f4d19",
4
4
  "scripts": {
5
5
  "ng": "ng",
6
6
  "start": "ng serve",