@agridea/suibi-module 0.1.0-preview.5f912f0 → 0.1.0-preview.68e6607
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.
- package/dist/elements/browser/main.js +71 -71
- package/dist/elements/browser/suibi-module-latest.js +71 -71
- package/dist/elements/browser/suibi-module.v0.1.0-preview.68e6607.js +78 -0
- package/dist/elements/browser/version.txt +1 -1
- package/dist/types/app/components/inline-table/inline-table.component.d.ts +10 -0
- package/dist/types/app/components/inline-table/inline-table.types.d.ts +36 -2
- package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts +2 -0
- package/dist/types/app/core/i18n/i18n.service.d.ts +1 -0
- package/dist/types/app/core/utils/object.util.d.ts +26 -0
- package/dist/types/app/jsonforms/renderers/layout/group/module-toggle-group.renderer.d.ts +3 -1
- 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
- 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
- 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
- package/dist/types/app/nutrient-cycle/animal-stock/index.d.ts +3 -3
- 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
- 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
- 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
- package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +3 -3
- package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.component.d.ts +21 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.config.d.ts +9 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/crop-harvest-table/crop-harvest-table.component.d.ts +21 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/crop-harvest-table/crop-harvest-table.config.d.ts +13 -0
- 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
- package/dist/types/app/nutrient-cycle/field-cultivation/{field-cultivation-general.component.d.ts → field-cultivation-general/field-cultivation-general.component.d.ts} +2 -4
- 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
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-master-detail/field-cultivation-master-detail.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.types.d.ts +1 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.component.d.ts +27 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.config.d.ts +16 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/index.d.ts +8 -3
- package/dist/types/app/nutrient-cycle/field-cultivation/special-crops-table/special-crops-table.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/special-crops-table/special-crops-table.config.d.ts +61 -0
- package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.component.d.ts +6 -1
- package/dist/types/app/nutrient-cycle/field-spreading/ingredient.util.d.ts +8 -0
- package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.component.d.ts +13 -4
- package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-transaction-unit.util.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder-master-detail/fodder-master-detail.component.d.ts +25 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder-table/fodder-table.component.d.ts +26 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder-table/fodder-table.config.d.ts +9 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder.types.d.ts +7 -0
- package/dist/types/app/nutrient-cycle/fodder/index.d.ts +2 -3
- package/dist/types/app/nutrient-cycle/fodder/ingredient.util.d.ts +8 -0
- package/dist/types/app/nutrient-cycle/storage/index.d.ts +3 -3
- package/dist/types/app/nutrient-cycle/storage/{storage-detail.component.d.ts → storage-detail/storage-detail.component.d.ts} +3 -3
- package/dist/types/app/nutrient-cycle/storage/{storage-general.component.d.ts → storage-general/storage-general.component.d.ts} +4 -4
- package/dist/types/app/nutrient-cycle/storage/{storage-list.component.d.ts → storage-list/storage-list.component.d.ts} +1 -1
- package/dist/types/app/nutrient-cycle/storage/{storage-master-detail.component.d.ts → storage-master-detail/storage-master-detail.component.d.ts} +2 -2
- package/package.json +1 -1
- package/dist/elements/browser/suibi-module.v0.1.0-preview.5f912f0.js +0 -78
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-master-detail.component.d.ts +0 -37
- package/dist/types/app/nutrient-cycle/fodder/fodder-detail.component.d.ts +0 -31
- package/dist/types/app/nutrient-cycle/fodder/fodder-list.component.d.ts +0 -20
- package/dist/types/app/nutrient-cycle/fodder/fodder-master-detail.component.d.ts +0 -37
- /package/dist/elements/browser/{suibi-module.v0.1.0-preview.5f912f0.css → suibi-module.v0.1.0-preview.68e6607.css} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.0-preview.
|
|
1
|
+
0.1.0-preview.68e6607 68e6607
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MatCheckboxChange } from '@angular/material/checkbox';
|
|
1
2
|
import { BaseCodeListEntry } from '../../jsonforms/shared/option-sources/code-lists';
|
|
2
3
|
import { InlineColumnDef, InlineTableConfig } from './inline-table.types';
|
|
3
4
|
/**
|
|
@@ -62,8 +63,12 @@ export declare class InlineTableComponent {
|
|
|
62
63
|
readonly emptyHint: import("@angular/core").Signal<string>;
|
|
63
64
|
/** Returns the option array for a select column from the shared CODE_LISTS map. */
|
|
64
65
|
getOptions(col: InlineColumnDef): BaseCodeListEntry[];
|
|
66
|
+
/** Options for a select column, narrowed per row when the column defines `optionsFilter`. */
|
|
67
|
+
optionsForRow(col: InlineColumnDef, row: Record<string, unknown>): BaseCodeListEntry[];
|
|
65
68
|
/**
|
|
66
69
|
* Returns the localized display label for a code-list option.
|
|
70
|
+
* - `optionLabelKey`: translates the i18n key returned by the column's resolver — for
|
|
71
|
+
* literal option lists whose labels live in the locales rather than in master data.
|
|
67
72
|
* - `optionDisplay: 'id'`: returns `String(entry.id)` (e.g. "kg", "t").
|
|
68
73
|
* - default (`'label'`): uses `descriptor.designation_eng / designation_deu`;
|
|
69
74
|
* falls back to `String(entry.id)` when no descriptor is present.
|
|
@@ -72,6 +77,7 @@ export declare class InlineTableComponent {
|
|
|
72
77
|
/**
|
|
73
78
|
* Reads the current cell value for a column from a row object.
|
|
74
79
|
*
|
|
80
|
+
* - `valueResolver` columns: fully derived value (e.g. from master data).
|
|
75
81
|
* - Simple field: returns `row[col.key]`.
|
|
76
82
|
* - Sub-array field: navigates `row[arrayPath]`, finds the entry matching
|
|
77
83
|
* `arrayKeyField === arrayKeyValue`, and returns `entry[arrayValueField]`.
|
|
@@ -92,6 +98,10 @@ export declare class InlineTableComponent {
|
|
|
92
98
|
onNumberChange(rowIdx: number, col: InlineColumnDef, event: Event): void;
|
|
93
99
|
/** Called on `(input)` of a text `<input>` (see onNumberChange for why not `(change)`). */
|
|
94
100
|
onTextChange(rowIdx: number, col: InlineColumnDef, event: Event): void;
|
|
101
|
+
/** Called when a `mat-checkbox` is toggled. */
|
|
102
|
+
onCheckboxChange(rowIdx: number, col: InlineColumnDef, change: MatCheckboxChange): void;
|
|
103
|
+
/** Whether the cell widget is disabled for this row (per-row constraint hook). */
|
|
104
|
+
isCellDisabled(col: InlineColumnDef, row: Record<string, unknown>): boolean;
|
|
95
105
|
/** Appends a blank row produced by `config.createRow()`. */
|
|
96
106
|
addRow(): void;
|
|
97
107
|
/** Removes the row at `idx` from the array. */
|
|
@@ -11,8 +11,12 @@
|
|
|
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
|
-
|
|
15
|
-
|
|
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
|
+
export type InlineCellType = 'select' | 'number' | 'text' | 'readonly' | 'checkbox';
|
|
16
20
|
/**
|
|
17
21
|
* Definition for a single column in an inline table.
|
|
18
22
|
*
|
|
@@ -55,6 +59,24 @@ export interface InlineColumnDef {
|
|
|
55
59
|
* human-readable (e.g. unit codes like "kg", "t", "l").
|
|
56
60
|
*/
|
|
57
61
|
optionDisplay?: 'label' | 'id';
|
|
62
|
+
/**
|
|
63
|
+
* For `type: 'select'` — optional per-row narrowing of the code-list options,
|
|
64
|
+
* e.g. to restrict the product list based on another cell of the same row.
|
|
65
|
+
* Evaluated for every option of every row, so keep it cheap.
|
|
66
|
+
*/
|
|
67
|
+
optionsFilter?: (entry: BaseCodeListEntry, row: Record<string, unknown>) => boolean;
|
|
68
|
+
/**
|
|
69
|
+
* For `type: 'select'` — resolve an option's label through an i18n key instead of the
|
|
70
|
+
* master-data descriptor (for literal option lists whose labels live in the locales,
|
|
71
|
+
* e.g. a row-type selector). Takes precedence over `optionDisplay`.
|
|
72
|
+
*/
|
|
73
|
+
optionLabelKey?: (entry: BaseCodeListEntry) => string;
|
|
74
|
+
/**
|
|
75
|
+
* Optional i18n key for an explanatory tooltip shown via an info icon next to
|
|
76
|
+
* the column header (e.g. to explain a checkbox whose effect is not obvious).
|
|
77
|
+
* Omit for columns that need no extra explanation.
|
|
78
|
+
*/
|
|
79
|
+
tooltipKey?: string;
|
|
58
80
|
/**
|
|
59
81
|
* CSS grid column-sizing token, e.g. `'minmax(140px, 2fr)'` or `'84px'`.
|
|
60
82
|
* These values are joined to build the `grid-template-columns` style on the table.
|
|
@@ -70,6 +92,18 @@ export interface InlineColumnDef {
|
|
|
70
92
|
* Defaults to `'any'` when omitted, allowing any decimal.
|
|
71
93
|
*/
|
|
72
94
|
step?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Custom cell-value resolver — takes precedence over the default read path.
|
|
97
|
+
* Use this for `type: 'readonly'` columns whose value is derived from master
|
|
98
|
+
* data or other cells (e.g. a standard yield looked up from the selected crop)
|
|
99
|
+
* and therefore does not live on the row object.
|
|
100
|
+
*/
|
|
101
|
+
valueResolver?: (row: Record<string, unknown>) => unknown;
|
|
102
|
+
/**
|
|
103
|
+
* Per-row disabling of the cell widget (e.g. grey out the yield input when the
|
|
104
|
+
* selected crop does not permit yield input). Evaluated per row, keep it cheap.
|
|
105
|
+
*/
|
|
106
|
+
disabledForRow?: (row: Record<string, unknown>) => boolean;
|
|
73
107
|
/**
|
|
74
108
|
* Sub-array navigation config — for columns whose value lives inside a nested array
|
|
75
109
|
* on the row object (e.g. `ingredient[].quantity`).
|
package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ import { SuisseBilanzMetricsService } from './suissebilanz-metrics.service';
|
|
|
11
11
|
*/
|
|
12
12
|
export declare class SuisseBilanzDashboardComponent {
|
|
13
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>;
|
|
14
16
|
protected readonly planning: PlanningBalanceService;
|
|
15
17
|
private readonly sanitizer;
|
|
16
18
|
protected readonly metricsService: SuisseBilanzMetricsService;
|
|
@@ -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. */
|
|
@@ -22,3 +22,29 @@ 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;
|
|
35
|
+
/**
|
|
36
|
+
* Sanitizes the planning payload: the calculation API (OpenAPI, no `nullable: true`
|
|
37
|
+
* anywhere) accepts an optional field as *absent* but rejects it when present with a
|
|
38
|
+
* null value ("must be string/number"). The working data model normalizes optional
|
|
39
|
+
* fields to null, so strip them at the submission boundary — mirroring what
|
|
40
|
+
* `stripIncompleteIngredients` does for ingredient slots.
|
|
41
|
+
*
|
|
42
|
+
* - inside `fieldCultivation` entry collections (fodderCropland, arableLand, special,
|
|
43
|
+
* feedingOfCropHarvest, dispenseOfCropHarvest): any null property is dropped
|
|
44
|
+
* (fieldName, userSpecificPlantName, yieldPerSquareMeasure, effectiveYield, …)
|
|
45
|
+
* - `nutrientCycle.fodder.trading.<collection>[].quantity`: null → dropped
|
|
46
|
+
*/
|
|
47
|
+
export declare function sanitizePlanningPayload(data: NaebiDataLike): NaebiDataLike;
|
|
48
|
+
/** Structural type so object.util stays free of a NaebiData import (circular-safe). */
|
|
49
|
+
type NaebiDataLike = Record<string, unknown>;
|
|
50
|
+
export {};
|
|
@@ -20,17 +20,19 @@ export declare class ModuleToggleGroupRenderer extends JsonFormsBaseRenderer<Gro
|
|
|
20
20
|
private readonly cdr;
|
|
21
21
|
private subscription?;
|
|
22
22
|
protected readonly _hidden: import("@angular/core").WritableSignal<boolean>;
|
|
23
|
+
protected readonly _enabled: import("@angular/core").WritableSignal<boolean>;
|
|
23
24
|
protected readonly _label: import("@angular/core").WritableSignal<string | undefined>;
|
|
24
25
|
protected readonly _description: import("@angular/core").WritableSignal<string | undefined>;
|
|
25
26
|
protected readonly _modules: import("@angular/core").WritableSignal<ModuleCard[]>;
|
|
26
27
|
readonly labelId: string;
|
|
27
28
|
hidden: () => boolean;
|
|
29
|
+
enabled: () => boolean;
|
|
28
30
|
label: () => string | undefined;
|
|
29
31
|
description: () => string | undefined;
|
|
30
32
|
modules: () => ModuleCard[];
|
|
31
33
|
ngOnInit(): void;
|
|
32
34
|
ngOnDestroy(): void;
|
|
33
|
-
/** Flip a single module boolean in the JSONForms data store. */
|
|
35
|
+
/** Flip a single module boolean in the JSONForms data store. No-op while the group is disabled. */
|
|
34
36
|
toggle(dataPath: string): void;
|
|
35
37
|
}
|
|
36
38
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JsonSchema, UISchemaElement } from '@jsonforms/core';
|
|
2
|
-
import { AnimalStockRow } from '
|
|
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("
|
|
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 '
|
|
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 '
|
|
2
|
-
import { LifetimePerformance } from '
|
|
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 '
|
|
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("
|
|
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 '
|
|
2
|
-
import { FarmManureTradingMode } from '
|
|
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 '
|
|
2
|
-
import { FarmManureTradingSupply, FarmManureTradingDispense } from '
|
|
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("
|
|
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';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FieldCultivationArableLand } from '../field-cultivation.types';
|
|
2
|
+
/**
|
|
3
|
+
* ArableLandTableComponent — thin wrapper around InlineTableComponent for the
|
|
4
|
+
* "Grandes cultures" tab: arable-land entries are edited directly in the table
|
|
5
|
+
* (no detail pane). The config provides the columns; the rowTransform clears the
|
|
6
|
+
* yield-related fields when the newly selected crop does not permit yield input.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ArableLandTableComponent {
|
|
9
|
+
readonly entries: import("@angular/core").InputSignal<FieldCultivationArableLand[]>;
|
|
10
|
+
readonly entriesChange: import("@angular/core").OutputEmitterRef<FieldCultivationArableLand[]>;
|
|
11
|
+
/** Column/section config (constant — no signal needed). */
|
|
12
|
+
protected readonly config: import("../../../components/inline-table/inline-table.types").InlineTableConfig;
|
|
13
|
+
/** Cast typed entries to the generic Record[] expected by InlineTableComponent. */
|
|
14
|
+
readonly rowsForTable: import("@angular/core").Signal<Record<string, unknown>[]>;
|
|
15
|
+
onRowsChange(rows: Record<string, unknown>[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* Crop change: clear yield + divergence when the new crop forbids yield input,
|
|
18
|
+
* so no stale values linger under the now-disabled cells.
|
|
19
|
+
*/
|
|
20
|
+
readonly enforceArableRules: (changedKey: string, newValue: unknown, row: Record<string, unknown>) => Record<string, unknown>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column and section configuration for the arable-land inline table ("Grandes cultures").
|
|
3
|
+
*
|
|
4
|
+
* Replaces the former list + JSONForms detail pane for arable land: the main entry
|
|
5
|
+
* fields are edited directly in the table. The crop dropdown reuses the
|
|
6
|
+
* `agronomicCropCategoryArableLand` code list as-is, keeping its existing order.
|
|
7
|
+
*/
|
|
8
|
+
import type { InlineTableConfig } from '../../../components/inline-table/inline-table.types';
|
|
9
|
+
export declare const ARABLE_LAND_TABLE_CONFIG: InlineTableConfig;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FieldCultivationCropHarvest } from '../field-cultivation.types';
|
|
2
|
+
import { CropHarvestTableKind } from './crop-harvest-table.config';
|
|
3
|
+
/**
|
|
4
|
+
* CropHarvestTableComponent — thin wrapper around InlineTableComponent for one of the
|
|
5
|
+
* two crop-harvest tables of the "Général" tab (fed / dispensed).
|
|
6
|
+
*
|
|
7
|
+
* Rows without a selected crop (freshly added) exist only in the local `uiRows`
|
|
8
|
+
* state and are emitted upstream once a crop is picked, so no empty rows ever
|
|
9
|
+
* reach the data store (fodder `uiRows` pattern).
|
|
10
|
+
*/
|
|
11
|
+
export declare class CropHarvestTableComponent {
|
|
12
|
+
readonly entries: import("@angular/core").InputSignal<FieldCultivationCropHarvest[]>;
|
|
13
|
+
readonly kind: import("@angular/core").InputSignal<CropHarvestTableKind>;
|
|
14
|
+
readonly entriesChange: import("@angular/core").OutputEmitterRef<FieldCultivationCropHarvest[]>;
|
|
15
|
+
readonly config: import("@angular/core").Signal<import("../../../components/inline-table/inline-table.types").InlineTableConfig>;
|
|
16
|
+
/** Rows as last edited locally (may contain not-yet-committed empty rows); null = follow data. */
|
|
17
|
+
private readonly uiRows;
|
|
18
|
+
readonly rowsForTable: import("@angular/core").Signal<Record<string, unknown>[]>;
|
|
19
|
+
constructor();
|
|
20
|
+
onRowsChange(rows: Record<string, unknown>[]): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column and section configuration for the two crop-harvest inline tables of the
|
|
3
|
+
* "Général" tab (fed crop harvest / dispensed crop harvest).
|
|
4
|
+
*
|
|
5
|
+
* Both tables share the same columns — the same three fields the JSONForms array
|
|
6
|
+
* detail exposed before (crop, plant name, effective yield) — and differ only by
|
|
7
|
+
* their labels. The crop dropdown reuses the full `agronomicCropCategory` code
|
|
8
|
+
* list, exactly like the former JSONForms control.
|
|
9
|
+
*/
|
|
10
|
+
import type { InlineTableConfig } from '../../../components/inline-table/inline-table.types';
|
|
11
|
+
export type CropHarvestTableKind = 'feeding' | 'dispense';
|
|
12
|
+
export declare const FEEDING_TABLE_CONFIG: InlineTableConfig;
|
|
13
|
+
export declare const DISPENSE_TABLE_CONFIG: InlineTableConfig;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JsonSchema, UISchemaElement } from '@jsonforms/core';
|
|
2
|
-
import { FieldCultivationDetailEntry, FieldCultivationDetailMode } from '
|
|
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("
|
|
20
|
+
readonly jsonFormsData: import("@angular/core").Signal<(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 {
|
|
2
|
+
import { 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>;
|
|
@@ -15,8 +15,6 @@ export declare class FieldCultivationGeneralComponent {
|
|
|
15
15
|
buildingZoneAreaSize: number | null | undefined;
|
|
16
16
|
outdoorVegetableMainCropAreaSize: number | null | undefined;
|
|
17
17
|
indoorVegetableMainCropAreaSize: number | null | undefined;
|
|
18
|
-
|
|
19
|
-
dispenseOfCropHarvest: FieldCultivationCropHarvest[] | undefined;
|
|
20
|
-
} & import("../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
|
|
18
|
+
} & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
|
|
21
19
|
onDataChange(event: unknown): void;
|
|
22
20
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FieldCultivationDetailEntry, FieldCultivationDetailMode } from '
|
|
1
|
+
import { FieldCultivationDetailEntry, FieldCultivationDetailMode } from '../field-cultivation.types';
|
|
2
2
|
export declare class FieldCultivationListComponent {
|
|
3
3
|
private readonly masterData;
|
|
4
4
|
private readonly i18n;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FieldCultivationTab } from '../../../core/navigation/navigation.service';
|
|
2
|
+
import { CropHarvestTableKind } from '../crop-harvest-table/crop-harvest-table.config';
|
|
3
|
+
import { FieldCultivationArableLand, FieldCultivationCropHarvest, FieldCultivationData, FieldCultivationFodderCropland, FieldCultivationSpecial } from '../field-cultivation.types';
|
|
4
|
+
export declare class FieldCultivationMasterDetailComponent {
|
|
5
|
+
private readonly dataSvc;
|
|
6
|
+
private readonly navigationSvc;
|
|
7
|
+
constructor();
|
|
8
|
+
readonly fieldCultivation: import("@angular/core").Signal<FieldCultivationData>;
|
|
9
|
+
readonly fodderCroplandRows: import("@angular/core").Signal<FieldCultivationFodderCropland[]>;
|
|
10
|
+
readonly arableLandRows: import("@angular/core").Signal<FieldCultivationArableLand[]>;
|
|
11
|
+
readonly specialRows: import("@angular/core").Signal<FieldCultivationSpecial[]>;
|
|
12
|
+
readonly feedingRows: import("@angular/core").Signal<FieldCultivationCropHarvest[]>;
|
|
13
|
+
readonly dispenseRows: import("@angular/core").Signal<FieldCultivationCropHarvest[]>;
|
|
14
|
+
readonly activeTab: import("@angular/core").WritableSignal<FieldCultivationTab>;
|
|
15
|
+
readonly activeTabIndex: import("@angular/core").Signal<0 | 1 | 2 | 3>;
|
|
16
|
+
onTabChange(index: number): void;
|
|
17
|
+
onGeneralChange(value: FieldCultivationData): void;
|
|
18
|
+
/** Persists one crop-harvest table's rows (fed / dispensed harvests of the general tab). */
|
|
19
|
+
onCropHarvestRowsChange(kind: CropHarvestTableKind, rows: FieldCultivationCropHarvest[]): void;
|
|
20
|
+
/** Persists the fodder-cropland rows produced by the inline table (edit / add / delete). */
|
|
21
|
+
onFodderCroplandRowsChange(rows: FieldCultivationFodderCropland[]): void;
|
|
22
|
+
/** Persists the arable-land rows produced by the inline table (edit / add / delete). */
|
|
23
|
+
onArableRowsChange(rows: FieldCultivationArableLand[]): void;
|
|
24
|
+
/** Persists the special-crops rows produced by the inline table (edit / add / delete). */
|
|
25
|
+
onSpecialRowsChange(rows: FieldCultivationSpecial[]): void;
|
|
26
|
+
private patchRows;
|
|
27
|
+
private patchFieldCultivation;
|
|
28
|
+
private parseTab;
|
|
29
|
+
}
|
|
@@ -18,6 +18,7 @@ export interface FieldCultivationBaseEntry {
|
|
|
18
18
|
export interface FieldCultivationFodderCropland extends FieldCultivationBaseEntry {
|
|
19
19
|
fieldName?: string | null;
|
|
20
20
|
calculateYieldThroughFodderBalance?: boolean;
|
|
21
|
+
requirementCorrection?: FieldCultivationRequirementCorrection[];
|
|
21
22
|
}
|
|
22
23
|
export interface FieldCultivationArableLand extends FieldCultivationBaseEntry {
|
|
23
24
|
hasLongTermYieldDivergence?: boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { FieldCultivationFodderCropland } from '../field-cultivation.types';
|
|
2
|
+
/**
|
|
3
|
+
* FodderCroplandTableComponent — thin wrapper around InlineTableComponent for the
|
|
4
|
+
* "Surface fourragère" tab: entries are edited directly in the table (no detail pane).
|
|
5
|
+
*
|
|
6
|
+
* Rows without a selected crop (freshly added) exist only in the local `uiRows`
|
|
7
|
+
* state and are emitted upstream once a crop is picked, so no empty rows ever
|
|
8
|
+
* reach the data store (fodder `uiRows` pattern). The rowTransform clears the
|
|
9
|
+
* yield whenever it is not user-editable for the row.
|
|
10
|
+
*/
|
|
11
|
+
export declare class FodderCroplandTableComponent {
|
|
12
|
+
readonly entries: import("@angular/core").InputSignal<FieldCultivationFodderCropland[]>;
|
|
13
|
+
readonly entriesChange: import("@angular/core").OutputEmitterRef<FieldCultivationFodderCropland[]>;
|
|
14
|
+
/** Column/section config (constant — no signal needed). */
|
|
15
|
+
protected readonly config: import("../../../components/inline-table/inline-table.types").InlineTableConfig;
|
|
16
|
+
/** Rows as last edited locally (may contain not-yet-committed empty rows); null = follow data. */
|
|
17
|
+
private readonly uiRows;
|
|
18
|
+
readonly rowsForTable: import("@angular/core").Signal<Record<string, unknown>[]>;
|
|
19
|
+
constructor();
|
|
20
|
+
onRowsChange(rows: Record<string, unknown>[]): void;
|
|
21
|
+
/**
|
|
22
|
+
* Clears the yield whenever it stops being user-editable for the row (fodder-balance
|
|
23
|
+
* calculation switched on, or new crop without yield input), so no stale value
|
|
24
|
+
* lingers under the now-disabled cell.
|
|
25
|
+
*/
|
|
26
|
+
readonly enforceFodderCroplandRules: (changedKey: string, newValue: unknown, row: Record<string, unknown>) => Record<string, unknown>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column and section configuration for the fodder-cropland inline table
|
|
3
|
+
* ("Surface fourragère" tab).
|
|
4
|
+
*
|
|
5
|
+
* Replaces the former list + JSONForms detail pane: entries are edited directly
|
|
6
|
+
* in the table. `userSpecificPlantName` and `fieldName` stay in the data model
|
|
7
|
+
* (filled by imports/API) but are no longer editable in the UI.
|
|
8
|
+
*/
|
|
9
|
+
import type { InlineTableConfig } from '../../../components/inline-table/inline-table.types';
|
|
10
|
+
/**
|
|
11
|
+
* Yield is user-editable only when the selected crop permits yield input AND the
|
|
12
|
+
* yield is not calculated through the fodder balance — mirrors the former
|
|
13
|
+
* `fieldCultivation_shouldShowYieldInput` constraint of the detail form.
|
|
14
|
+
*/
|
|
15
|
+
export declare function yieldNotEditable(row: Record<string, unknown>): boolean;
|
|
16
|
+
export declare const FODDER_CROPLAND_TABLE_CONFIG: InlineTableConfig;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
export * from './field-cultivation-list.component';
|
|
2
|
-
export * from './field-cultivation-detail.component';
|
|
3
|
-
export * from './field-cultivation-
|
|
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';
|
|
5
|
+
export * from './crop-harvest-table/crop-harvest-table.component';
|
|
6
|
+
export * from './fodder-cropland-table/fodder-cropland-table.component';
|
|
7
|
+
export * from './arable-land-table/arable-land-table.component';
|
|
8
|
+
export * from './special-crops-table/special-crops-table.component';
|
|
4
9
|
export * from './field-cultivation.types';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FieldCultivationSpecial } from '../field-cultivation.types';
|
|
2
|
+
/**
|
|
3
|
+
* SpecialCropsTableComponent — thin wrapper around InlineTableComponent for the
|
|
4
|
+
* "Cultures spéciales" tab: one table for the whole CULT_SPECIAL category.
|
|
5
|
+
*
|
|
6
|
+
* Rows without a selected crop (freshly added) exist only in the local `uiRows`
|
|
7
|
+
* state and are emitted upstream once a crop is picked, so no empty rows ever
|
|
8
|
+
* reach the data store (fodder `uiRows` pattern).
|
|
9
|
+
*/
|
|
10
|
+
export declare class SpecialCropsTableComponent {
|
|
11
|
+
readonly entries: import("@angular/core").InputSignal<FieldCultivationSpecial[]>;
|
|
12
|
+
readonly entriesChange: import("@angular/core").OutputEmitterRef<FieldCultivationSpecial[]>;
|
|
13
|
+
/** Column/section config (constant — no signal needed). */
|
|
14
|
+
protected readonly config: import("../../../components/inline-table/inline-table.types").InlineTableConfig;
|
|
15
|
+
/** Rows as last edited locally (may contain not-yet-committed empty rows); null = follow data. */
|
|
16
|
+
private readonly uiRows;
|
|
17
|
+
readonly rowsForTable: import("@angular/core").Signal<Record<string, unknown>[]>;
|
|
18
|
+
constructor();
|
|
19
|
+
onRowsChange(rows: Record<string, unknown>[]): void;
|
|
20
|
+
/**
|
|
21
|
+
* Domain rules applied on every edit:
|
|
22
|
+
* - units of the managed nutrient slots are fixed (N2 in kg, corrections in %),
|
|
23
|
+
* - managed slots left empty are dropped (the API rejects null quantities),
|
|
24
|
+
* - selecting a crop pre-fills Nmin from its standard N2 requirement and resets the
|
|
25
|
+
* corrections to 100 %; clearing the crop (or picking one that forbids corrections)
|
|
26
|
+
* removes the managed slots.
|
|
27
|
+
*/
|
|
28
|
+
readonly enforceSpecialCropRules: (changedKey: string, newValue: unknown, row: Record<string, unknown>) => Record<string, unknown>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column and section configuration for the special-crops inline table
|
|
3
|
+
* ("Cultures spéciales" tab).
|
|
4
|
+
*
|
|
5
|
+
* ONE table for the whole CULT_SPECIAL category: the crop dropdown reuses the
|
|
6
|
+
* `agronomicCropCategorySpecial` code list, which is already filtered on
|
|
7
|
+
* cultivationCategory === 'CULT_SPECIAL'. Nutrient columns live in the row's
|
|
8
|
+
* `requirementCorrection[]` sub-array: Nmin is the N2 slot in kg, the three
|
|
9
|
+
* corrections are the P2O5/K2O/Mg slots in %.
|
|
10
|
+
*/
|
|
11
|
+
import type { InlineTableConfig } from '../../../components/inline-table/inline-table.types';
|
|
12
|
+
/** Nmin maps to the N2 requirement-correction slot, always expressed in kg. */
|
|
13
|
+
export declare const NMIN_FORMULA = "N2";
|
|
14
|
+
export declare const NMIN_UNIT = "kg";
|
|
15
|
+
/** Correction slots managed by the table, always expressed in % (100 % = no correction). */
|
|
16
|
+
export declare const CORRECTION_FORMULAS: readonly ["P2O5", "K2O", "Mg"];
|
|
17
|
+
export declare const CORRECTION_UNIT = "%";
|
|
18
|
+
export declare const CORRECTION_DEFAULT = 100;
|
|
19
|
+
/** Code list feeding the crop dropdown — the whole CULT_SPECIAL category. */
|
|
20
|
+
export declare const SPECIAL_CROPS_CODE_LIST = "agronomicCropCategorySpecial";
|
|
21
|
+
/** Crop ids permitted in the table — every CULT_SPECIAL entry of the master data. */
|
|
22
|
+
export declare const SPECIAL_CROPS_IDS: Set<string>;
|
|
23
|
+
/** Looks up a crop entry in the table's code list. */
|
|
24
|
+
export declare function specialCropEntry(id: unknown): Record<string, unknown> | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Nutrient columns are read-only unless the selected crop has the
|
|
27
|
+
* `isPermittedForRequirementCorrection` flag: without it, the pre-filled Nmin and
|
|
28
|
+
* correction values are fixed defaults from master data and must not be user-editable.
|
|
29
|
+
*/
|
|
30
|
+
export declare function nutrientColumnsLocked(crop: Record<string, unknown> | undefined): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Applies the crop's defaults to the requirement-correction slots.
|
|
33
|
+
* - If the crop does NOT permit requirement corrections (or none is selected): the
|
|
34
|
+
* managed slots are removed entirely — nothing is editable and nothing is sent to the API.
|
|
35
|
+
* - If the crop DOES permit them: the managed slots are pre-filled from the crop's
|
|
36
|
+
* master-data `requirement` (N2 in kg; P2O5/K2O/Mg in %) and stay user-editable.
|
|
37
|
+
*/
|
|
38
|
+
export declare function applyCropDefaults(row: Record<string, unknown>, crop: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Normalizes the managed requirement-correction slots on every edit: fixed units
|
|
41
|
+
* (N2 → kg, corrections → %) and removal of managed entries left without a quantity
|
|
42
|
+
* (the API rejects present-but-null quantities).
|
|
43
|
+
*/
|
|
44
|
+
export declare function normalizeManagedCorrections(row: Record<string, unknown>): Record<string, unknown>;
|
|
45
|
+
/**
|
|
46
|
+
* Shared column definitions for the requirement-correction sub-array (Nmin + P2O5/K2O/Mg),
|
|
47
|
+
* reusable across fodder, arable and special tables. `lockRow` disables editing per row.
|
|
48
|
+
*/
|
|
49
|
+
export declare function requirementCorrectionColumns(lockRow: (row: Record<string, unknown>) => boolean): InlineTableConfig['columns'];
|
|
50
|
+
/**
|
|
51
|
+
* Row-transform helper shared by fodder/arable: on every edit it normalizes the managed
|
|
52
|
+
* slots and, if the selected crop does not permit requirement corrections, strips them
|
|
53
|
+
* entirely (so nothing is sent to the API for those rows).
|
|
54
|
+
*/
|
|
55
|
+
export declare function stripCorrectionsUnlessPermitted(row: Record<string, unknown>, codeListKey: string): Record<string, unknown>;
|
|
56
|
+
/**
|
|
57
|
+
* Row-transform helper shared by fodder/arable: on crop change it applies the crop's
|
|
58
|
+
* master-data defaults (when permitted) or strips the managed slots (when not).
|
|
59
|
+
*/
|
|
60
|
+
export declare function applyCropChangeRules(row: Record<string, unknown>, codeListKey: string): Record<string, unknown>;
|
|
61
|
+
export declare const SPECIAL_CROPS_TABLE_CONFIG: InlineTableConfig;
|
|
@@ -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[];
|