@agridea/suibi-module 0.1.0-preview.cf0616d → 0.1.0-preview.d54bad3
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/README.md +10 -10
- package/dist/elements/browser/main.js +71 -71
- package/dist/elements/browser/styles.css +1 -1
- package/dist/elements/browser/suibi-module-latest.css +1 -1
- package/dist/elements/browser/suibi-module-latest.js +71 -71
- package/dist/elements/browser/{suibi-module.v0.1.0-preview.cf0616d.css → suibi-module.v0.1.0-preview.d54bad3.css} +1 -1
- package/dist/elements/browser/suibi-module.v0.1.0-preview.d54bad3.js +78 -0
- package/dist/elements/browser/suibi-theme-dark.css +1 -1
- package/dist/elements/browser/version.txt +1 -1
- package/dist/elements/browser/wc-global-utilities.css +1 -1
- package/dist/types/app/components/data-preview/data-preview.component.d.ts +223 -2
- package/dist/types/app/components/{suissebilanz-dashboard → gauge-arc}/gauge-arc.component.d.ts +2 -0
- package/dist/types/app/{header-bar.d.ts → components/header-bar/header-bar.component.d.ts} +2 -2
- package/dist/types/app/components/inline-table/inline-table.component.d.ts +167 -0
- package/dist/types/app/components/inline-table/inline-table.types.d.ts +212 -0
- package/dist/types/app/components/planning-result-row/planning-result-row.component.d.ts +34 -0
- package/dist/types/app/components/results-page/results-page.component.d.ts +9 -0
- package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts +10 -2
- package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-metrics.service.d.ts +1 -1
- package/dist/types/app/components/{suissebilanz-dashboard → suissebilanz-minibar}/suissebilanz-minibar.component.d.ts +2 -2
- package/dist/types/app/components/validation-page/validation-page.component.d.ts +1 -0
- package/dist/types/app/components/welcome-page/metadata.types.d.ts +1 -1
- package/dist/types/app/components/welcome-page/welcome-page.component.d.ts +5 -3
- package/dist/types/app/components/workflow-stepper/workflow-stepper.component.d.ts +1 -4
- package/dist/types/app/core/data/naebi-data.service.d.ts +28 -28
- package/dist/types/app/core/error/global-error-handler.d.ts +2 -3
- package/dist/types/app/core/i18n/i18n.service.d.ts +7 -3
- package/dist/types/app/core/i18n/locales/fr.d.ts +2 -0
- package/dist/types/app/core/i18n/locales/it.d.ts +2 -0
- package/dist/types/app/core/master-data/master-data.service.d.ts +2 -0
- package/dist/types/app/core/metadata/suibi-metadata.types.d.ts +11 -1
- package/dist/types/app/core/navigation/navigation.service.d.ts +34 -1
- package/dist/types/app/core/planning/planning-balance.service.d.ts +9 -0
- package/dist/types/app/core/utils/custom-unit.util.d.ts +39 -0
- package/dist/types/app/core/utils/object.util.d.ts +22 -0
- package/dist/types/app/core/validation/ajv-custom.d.ts +1 -0
- package/dist/types/app/core/validation/capabilities.d.ts +6 -0
- package/dist/types/app/core/validation/global-validation.service.d.ts +21 -1
- package/dist/types/app/jsonforms/filters/code-list-filter-resolvers.d.ts +3 -0
- package/dist/types/app/jsonforms/registry/renderers.registry.d.ts +4 -0
- package/dist/types/app/jsonforms/renderers/controls/selects/animal-category/animal-category-select.renderer.d.ts +5 -2
- package/dist/types/app/jsonforms/renderers/controls/selects/code-list/code-list-select.renderer.d.ts +13 -4
- package/dist/types/app/jsonforms/renderers/layout/constraint/constraint-layout.renderer.d.ts +1 -0
- package/dist/types/app/jsonforms/renderers/layout/group/base-group.renderer.d.ts +2 -0
- package/dist/types/app/jsonforms/renderers/layout/group/module-toggle-group.renderer.d.ts +38 -0
- package/dist/types/app/jsonforms/shared/searchable-select/search-highlight.d.ts +18 -0
- package/dist/types/app/jsonforms/shared/searchable-select/searchable-select.component.d.ts +63 -0
- package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-detail/animal-stock-detail.component.d.ts +21 -0
- package/dist/types/app/nutrient-cycle/animal-stock/{animal-stock-list.component.d.ts → animal-stock-list/animal-stock-list.component.d.ts} +6 -9
- 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-master-detail/farm-manure-trading-master-detail.component.d.ts +19 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-table/farm-manure-trading-table.component.d.ts +37 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-table/farm-manure-trading-table.config.d.ts +24 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading.types.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +3 -3
- package/dist/types/app/nutrient-cycle/farm-manure-trading/transaction-unit.util.d.ts +2 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.component.d.ts +23 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.config.d.ts +16 -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/field-cultivation-detail.component.d.ts +22 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-general/field-cultivation-general.component.d.ts +20 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-list/field-cultivation-list.component.d.ts +17 -0
- 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 +45 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.util.d.ts +10 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.config.d.ts +21 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/index.d.ts +9 -0
- 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 +51 -0
- package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.component.d.ts +58 -0
- package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.config.d.ts +20 -0
- package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.component.d.ts +18 -3
- package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.types.d.ts +2 -0
- 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 +32 -0
- package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.config.d.ts +17 -0
- 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 +28 -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 +34 -0
- package/dist/types/app/nutrient-cycle/fodder/index.d.ts +3 -0
- package/dist/types/app/nutrient-cycle/fodder/ingredient.util.d.ts +8 -0
- package/dist/types/app/nutrient-cycle/fodder/transaction-unit.util.d.ts +2 -0
- package/dist/types/app/nutrient-cycle/lifetime-performance/index.d.ts +2 -0
- package/dist/types/app/nutrient-cycle/storage/index.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/storage/storage-detail/storage-detail.component.d.ts +30 -0
- package/dist/types/app/nutrient-cycle/storage/storage-general/storage-general.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/storage/storage-list/storage-list.component.d.ts +23 -0
- package/dist/types/app/nutrient-cycle/storage/storage-master-detail/storage-master-detail.component.d.ts +32 -0
- package/dist/types/app/nutrient-cycle/storage/storage.types.d.ts +40 -0
- package/package.json +68 -17
- package/dist/elements/browser/suibi-module.v0.1.0-preview.cf0616d.js +0 -78
- package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-detail.component.d.ts +0 -22
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-detail.component.d.ts +0 -27
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-list.component.d.ts +0 -23
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-master-detail.component.d.ts +0 -25
- /package/dist/types/app/components/{planning-result → planning-trigger}/planning-trigger.component.d.ts +0 -0
- /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,39 @@
|
|
|
1
|
+
export interface CustomUnit {
|
|
2
|
+
/** Unit code stored on the row (e.g. 'ha', 't', 'dt'). */
|
|
3
|
+
code: string;
|
|
4
|
+
/** API base unit this custom unit converts to (e.g. 'm2', 'kg'). */
|
|
5
|
+
baseUnit: string;
|
|
6
|
+
/** Multiplier from the custom unit to its base unit (1 ha = 10'000 m2 → 10000). */
|
|
7
|
+
factor: number;
|
|
8
|
+
descriptor?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare const CUSTOM_UNITS: readonly CustomUnit[];
|
|
11
|
+
/** True when the unit code is a custom display unit (not an API base unit). */
|
|
12
|
+
export declare function isCustomUnit(unit: unknown): boolean;
|
|
13
|
+
/** Base unit a quantity can be converted to: the custom unit's `baseUnit`, or the unit
|
|
14
|
+
* itself when it already is a base (or unknown) unit. */
|
|
15
|
+
export declare function baseUnitOf(unit: string | null | undefined): string | null | undefined;
|
|
16
|
+
/** Custom units convertible to the given base unit (e.g. 'kg' → [t, dt]). */
|
|
17
|
+
export declare function customUnitsForBaseUnit(baseUnit: string): CustomUnit[];
|
|
18
|
+
/**
|
|
19
|
+
* Builds a filter (compatible with the inline table's `optionsFilter`) keeping only the
|
|
20
|
+
* units compatible with the given context base unit(s) — i.e. each base unit plus its
|
|
21
|
+
* custom units. Pass a nullable base (e.g. derived from a product's matterState): `null`
|
|
22
|
+
* keeps the full list (nothing derived yet); pass an array of bases (e.g. ['kg', 'm3'])
|
|
23
|
+
* to pre-filter to their union before the exact base is known.
|
|
24
|
+
*
|
|
25
|
+
* Works on any entry shape exposing `id` (and `baseUnit` for custom units).
|
|
26
|
+
*/
|
|
27
|
+
export declare function unitOptionsForBaseUnit<T extends {
|
|
28
|
+
id: string | number;
|
|
29
|
+
}>(contextBaseUnit: string | readonly string[] | null | undefined): (entry: T) => boolean;
|
|
30
|
+
/** Converts a quantity expressed in a custom unit to its base unit; pass-through for
|
|
31
|
+
* base/unknown units and null quantities. */
|
|
32
|
+
export declare function convertToBaseUnit(quantity: number | null | undefined, unit: string | null | undefined): {
|
|
33
|
+
quantity: number | null | undefined;
|
|
34
|
+
unit: string | null | undefined;
|
|
35
|
+
};
|
|
36
|
+
/** Converts a quantity between two units sharing the same base unit (kg ↔ t ↔ dt,
|
|
37
|
+
* m2 ↔ ha). Returns the quantity unchanged when either unit is missing or the units
|
|
38
|
+
* are incompatible (different base units). */
|
|
39
|
+
export declare function convertQuantityBetween(quantity: number | null | undefined, fromUnit: string | null | undefined, toUnit: string | null | undefined): number | null | undefined;
|
|
@@ -22,3 +22,25 @@ 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
|
+
export declare function stripIncompleteIngredients<T>(value: T): T;
|
|
26
|
+
/**
|
|
27
|
+
* Sanitizes the planning payload: the calculation API (OpenAPI, no `nullable: true`
|
|
28
|
+
* anywhere) accepts an optional field as *absent* but rejects it when present with a
|
|
29
|
+
* null value ("must be string/number"). The working data model normalizes optional
|
|
30
|
+
* fields to null, so strip them at the submission boundary — mirroring what
|
|
31
|
+
* `stripIncompleteIngredients` does for ingredient slots.
|
|
32
|
+
*
|
|
33
|
+
* - inside `fieldCultivation` entry collections (fodderCropland, arableLand, special,
|
|
34
|
+
* feedingOfCropHarvest, dispenseOfCropHarvest): any null property is dropped
|
|
35
|
+
* (fieldName, userSpecificPlantName, yieldPerSquareMeasure, effectiveYield, …)
|
|
36
|
+
* - `nutrientCycle.fodder.trading.<collection>[].quantity`: null → dropped
|
|
37
|
+
* - `nutrientCycle.animalStock[].feeding.(winter|summer)Feeding`: never-filled routine
|
|
38
|
+
* slots (`{}` rows pre-created by the inline tables) and null fields are dropped;
|
|
39
|
+
* a season — and `feeding` itself — is removed when nothing filled-in remains
|
|
40
|
+
* - `nutrientCycle.fieldSpreading`: null fields dropped (`soilPh`, `slurry.*`,
|
|
41
|
+
* `manure.*`); `slurry`/`manure` removed when nothing filled-in remains
|
|
42
|
+
*/
|
|
43
|
+
export declare function sanitizePlanningPayload(data: NaebiDataLike): NaebiDataLike;
|
|
44
|
+
/** Structural type so object.util stays free of a NaebiData import (circular-safe). */
|
|
45
|
+
type NaebiDataLike = Record<string, unknown>;
|
|
46
|
+
export {};
|
|
@@ -9,6 +9,7 @@ import Ajv from 'ajv';
|
|
|
9
9
|
*
|
|
10
10
|
* Custom keywords:
|
|
11
11
|
* - `permittedStableSystem`: Validates stable system against animal category constraints
|
|
12
|
+
* - `proportionSum`: Validates the sum of one numeric field across array items
|
|
12
13
|
*
|
|
13
14
|
* @param options - Additional AJV options to merge with defaults
|
|
14
15
|
*/
|
|
@@ -16,3 +16,9 @@ export declare function derivePermittedStableSystems(animalCategoryPRIF: number
|
|
|
16
16
|
* Maps animalCategoryPRIF -> array of permitted stableSystem enum strings.
|
|
17
17
|
*/
|
|
18
18
|
export declare const PERMITTED_STABLE_SYSTEMS: Record<number, string[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Pre-computed map of non-zero per-category minimum yields (yieldPerSquareMeasure).
|
|
21
|
+
* Only 8 of the 314 crop categories declare a minimum > 0 (e.g. cereals, peas);
|
|
22
|
+
* all others fall back to the schema-level `minimum: 0`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const CROP_MINIMUM_YIELD_PER_SQUARE_MEASURE: Record<string, number>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ErrorObject } from 'ajv';
|
|
2
|
-
import { AnimalStockCategory, FarmManureTradingCategory, FarmManureTradingMode, FieldSpreadingCategory, PageId } from '../navigation/navigation.service';
|
|
2
|
+
import { AnimalStockCategory, FarmManureTradingCategory, FarmManureTradingMode, FieldCultivationTab, FieldSpreadingCategory, FodderCategory, FodderMode, PageId, StorageEntryType, StorageTab } from '../navigation/navigation.service';
|
|
3
3
|
export interface EnrichedValidationError extends ErrorObject {
|
|
4
4
|
/** Human-friendly field label (e.g., "Animal Category") */
|
|
5
5
|
fieldLabel?: string;
|
|
@@ -17,8 +17,26 @@ export interface EnrichedValidationError extends ErrorObject {
|
|
|
17
17
|
targetFarmManureTradingIndex?: number;
|
|
18
18
|
/** Category tab inside farm manure trading detail */
|
|
19
19
|
targetFarmManureTradingCategory?: FarmManureTradingCategory;
|
|
20
|
+
/** Navigation target: fodder mode */
|
|
21
|
+
targetFodderMode?: FodderMode;
|
|
22
|
+
/** Navigation target: fodder entry index */
|
|
23
|
+
targetFodderIndex?: number;
|
|
24
|
+
/** Category tab inside fodder detail */
|
|
25
|
+
targetFodderCategory?: FodderCategory;
|
|
20
26
|
/** Category tab inside field spreading */
|
|
21
27
|
targetFieldSpreadingCategory?: FieldSpreadingCategory;
|
|
28
|
+
/** Row index inside a field spreading tab (fertiliser/recycling) */
|
|
29
|
+
targetFieldSpreadingIndex?: number;
|
|
30
|
+
/** Category tab inside field cultivation */
|
|
31
|
+
targetFieldCultivationTab?: FieldCultivationTab;
|
|
32
|
+
/** Field cultivation detail index */
|
|
33
|
+
targetFieldCultivationIndex?: number;
|
|
34
|
+
/** Storage detail type */
|
|
35
|
+
targetStorageType?: StorageEntryType;
|
|
36
|
+
/** Storage detail index */
|
|
37
|
+
targetStorageIndex?: number;
|
|
38
|
+
/** Storage tab for list-level or scalar navigation */
|
|
39
|
+
targetStorageTab?: StorageTab;
|
|
22
40
|
}
|
|
23
41
|
/**
|
|
24
42
|
* GlobalValidationService
|
|
@@ -37,5 +55,7 @@ export declare class GlobalValidationService {
|
|
|
37
55
|
private inferCategory;
|
|
38
56
|
private inferFarmTradingCategory;
|
|
39
57
|
private inferFieldSpreadingCategory;
|
|
58
|
+
private inferFodderCategory;
|
|
59
|
+
private inferStorageTab;
|
|
40
60
|
private inferFieldLabel;
|
|
41
61
|
}
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { MasterDataService } from '../../core/master-data/master-data.service';
|
|
22
22
|
import { I18nService } from '../../core/i18n/i18n.service';
|
|
23
|
+
import { NaebiDataService } from '../../core/data/naebi-data.service';
|
|
23
24
|
import { BaseCodeListEntry } from '../shared/option-sources/code-lists';
|
|
24
25
|
export interface FilterContext {
|
|
25
26
|
data: unknown;
|
|
27
|
+
rootData: unknown;
|
|
26
28
|
get<T = unknown>(pointer: string): T | undefined;
|
|
27
29
|
masterData: MasterDataService;
|
|
28
30
|
locale: string;
|
|
@@ -57,4 +59,5 @@ export declare function registerCodeListFilter(name: string, fn: CodeListFilterR
|
|
|
57
59
|
export declare function evaluateFilter(list: BaseCodeListEntry[], cfg: FilterConfig | undefined, services: {
|
|
58
60
|
masterData: MasterDataService;
|
|
59
61
|
i18n: I18nService;
|
|
62
|
+
naebiData?: NaebiDataService;
|
|
60
63
|
}, data: unknown): BaseCodeListEntry[];
|
|
@@ -3,6 +3,7 @@ import { CodeListSelectRenderer } from '../renderers/controls/selects/code-list/
|
|
|
3
3
|
import { CardGroupRenderer } from '../renderers/layout/group/card-group.renderer';
|
|
4
4
|
import { PlainGroupRenderer } from '../renderers/layout/group/plain-group.renderer';
|
|
5
5
|
import { LogicalGroupRenderer } from '../renderers/layout/group/logical-group.renderer';
|
|
6
|
+
import { ModuleToggleGroupRenderer } from '../renderers/layout/group/module-toggle-group.renderer';
|
|
6
7
|
import { RankedTester } from '@jsonforms/core';
|
|
7
8
|
import { ConstraintLayoutRenderer } from '../renderers/layout/constraint/constraint-layout.renderer';
|
|
8
9
|
import { SelectedCategoryCategorizationRenderer } from '../renderers/layout/categorization/selected-category-categorization.renderer';
|
|
@@ -22,6 +23,9 @@ export declare const CUSTOM_JSONFORMS_RENDERERS: ({
|
|
|
22
23
|
} | {
|
|
23
24
|
tester: RankedTester;
|
|
24
25
|
renderer: typeof LogicalGroupRenderer;
|
|
26
|
+
} | {
|
|
27
|
+
tester: RankedTester;
|
|
28
|
+
renderer: typeof ModuleToggleGroupRenderer;
|
|
25
29
|
} | {
|
|
26
30
|
tester: RankedTester;
|
|
27
31
|
renderer: typeof AnimalCategorySelectRenderer;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { Signal } from '@angular/core';
|
|
1
2
|
import { JsonFormsAngularService } from '@jsonforms/angular';
|
|
2
3
|
import { RankedTester } from '@jsonforms/core';
|
|
3
4
|
import { BaseSelectControl } from '../../../../shared/base-control/base-select-control';
|
|
5
|
+
import { SearchableSelectOption } from '../../../../shared/searchable-select/searchable-select.component';
|
|
4
6
|
interface AnimalCategoryPrifEntry {
|
|
5
7
|
id: number;
|
|
6
8
|
animalGroup?: string;
|
|
@@ -10,12 +12,13 @@ interface AnimalCategoryPrifEntry {
|
|
|
10
12
|
};
|
|
11
13
|
}
|
|
12
14
|
export declare class AnimalCategorySelectRenderer extends BaseSelectControl<number> {
|
|
13
|
-
options: AnimalCategoryPrifEntry[]
|
|
15
|
+
options: import("@angular/core").InputSignal<AnimalCategoryPrifEntry[]>;
|
|
14
16
|
private readonly masterData;
|
|
15
17
|
constructor(jsonFormsService: JsonFormsAngularService);
|
|
16
18
|
getEventValue: (event: any) => any;
|
|
17
19
|
optLabel(opt: AnimalCategoryPrifEntry): string;
|
|
18
|
-
|
|
20
|
+
readonly selectOptions: Signal<SearchableSelectOption[]>;
|
|
21
|
+
onSelectionChange(value: unknown): void;
|
|
19
22
|
}
|
|
20
23
|
export declare const animalCategorySelectTester: RankedTester;
|
|
21
24
|
export {};
|
package/dist/types/app/jsonforms/renderers/controls/selects/code-list/code-list-select.renderer.d.ts
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
import { Signal } from '@angular/core';
|
|
2
2
|
import { JsonFormsAngularService } from '@jsonforms/angular';
|
|
3
|
-
import { RankedTester } from '@jsonforms/core';
|
|
3
|
+
import { ControlElement, RankedTester } from '@jsonforms/core';
|
|
4
4
|
import { BaseSelectControl } from '../../../../shared/base-control/base-select-control';
|
|
5
5
|
import { BaseCodeListEntry } from '../../../../shared/option-sources/code-lists';
|
|
6
|
+
import { SearchableSelectOption } from '../../../../shared/searchable-select/searchable-select.component';
|
|
7
|
+
export declare function replaceDataPathLeaf(path: string | null | undefined, replacement: string): string | null;
|
|
8
|
+
export declare function deriveSiblingDependencyPath(uischema: ControlElement | null | undefined, path: string | null | undefined, replacement: string): string | null;
|
|
6
9
|
export declare class CodeListSelectRenderer extends BaseSelectControl<number | string> {
|
|
7
10
|
private readonly masterData;
|
|
8
11
|
private readonly i18n;
|
|
12
|
+
private readonly naebiData;
|
|
9
13
|
private readonly formData;
|
|
10
14
|
private readonly controlScope;
|
|
11
15
|
private explicitCodeListKey;
|
|
12
16
|
private controlKey;
|
|
13
17
|
private listKey;
|
|
14
18
|
readonly options: Signal<BaseCodeListEntry[]>;
|
|
19
|
+
readonly isMultiSelect: Signal<boolean>;
|
|
15
20
|
private readonly filterConfig;
|
|
21
|
+
private readonly emptyHintKey;
|
|
16
22
|
private readonly dependsOnDataPath;
|
|
17
|
-
private readonly
|
|
23
|
+
private readonly autoDependsOnDataPath;
|
|
18
24
|
private scopePointerToDataPath;
|
|
19
|
-
private replacePointerLeaf;
|
|
20
25
|
private inferListKeyFromScope;
|
|
21
26
|
private readValueAtPath;
|
|
22
27
|
readonly filteredOptions: Signal<BaseCodeListEntry[]>;
|
|
23
28
|
constructor(jsonFormsService: JsonFormsAngularService);
|
|
24
29
|
getEventValue: (event: any) => any;
|
|
25
30
|
optionLabel(opt: BaseCodeListEntry): string;
|
|
26
|
-
|
|
31
|
+
readonly selectOptions: Signal<SearchableSelectOption[]>;
|
|
32
|
+
emptyHint(): string;
|
|
33
|
+
shouldShowEmptyHint(): boolean;
|
|
34
|
+
currentHints(): string[];
|
|
35
|
+
onSelectionChange(value: unknown): void;
|
|
27
36
|
}
|
|
28
37
|
export declare const codeListSelectTester: RankedTester;
|
|
@@ -21,6 +21,8 @@ export declare class BaseGroupRenderer extends JsonFormsBaseRenderer<GroupLayout
|
|
|
21
21
|
registryRenderers(): JsonFormsRendererRegistryEntry[];
|
|
22
22
|
registryCells(): JsonFormsCellRendererRegistryEntry[] | undefined;
|
|
23
23
|
private subscription;
|
|
24
|
+
private _destroyed;
|
|
25
|
+
private _prevSig?;
|
|
24
26
|
ngOnInit(): void;
|
|
25
27
|
ngOnDestroy(): void;
|
|
26
28
|
protected resolveHost(): ViewContainerRef | undefined;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { JsonFormsBaseRenderer } from '@jsonforms/angular';
|
|
3
|
+
import { GroupLayout, RankedTester } from '@jsonforms/core';
|
|
4
|
+
interface ModuleCard {
|
|
5
|
+
path: string;
|
|
6
|
+
value: boolean;
|
|
7
|
+
label: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const moduleToggleGroupTester: RankedTester;
|
|
11
|
+
/**
|
|
12
|
+
* Layout renderer for `{ type: 'Group', options: { variant: 'module-toggle' } }`.
|
|
13
|
+
*
|
|
14
|
+
* Renders boolean control children as interactive card-toggles in a horizontal
|
|
15
|
+
* row. Label and description are read from the (already-localised) schema that
|
|
16
|
+
* JSONForms passes into the renderer, so no extra i18n wiring is needed here.
|
|
17
|
+
*/
|
|
18
|
+
export declare class ModuleToggleGroupRenderer extends JsonFormsBaseRenderer<GroupLayout> implements OnInit, OnDestroy {
|
|
19
|
+
private readonly service;
|
|
20
|
+
private readonly cdr;
|
|
21
|
+
private subscription?;
|
|
22
|
+
protected readonly _hidden: import("@angular/core").WritableSignal<boolean>;
|
|
23
|
+
protected readonly _enabled: import("@angular/core").WritableSignal<boolean>;
|
|
24
|
+
protected readonly _label: import("@angular/core").WritableSignal<string | undefined>;
|
|
25
|
+
protected readonly _description: import("@angular/core").WritableSignal<string | undefined>;
|
|
26
|
+
protected readonly _modules: import("@angular/core").WritableSignal<ModuleCard[]>;
|
|
27
|
+
readonly labelId: string;
|
|
28
|
+
hidden: () => boolean;
|
|
29
|
+
enabled: () => boolean;
|
|
30
|
+
label: () => string | undefined;
|
|
31
|
+
description: () => string | undefined;
|
|
32
|
+
modules: () => ModuleCard[];
|
|
33
|
+
ngOnInit(): void;
|
|
34
|
+
ngOnDestroy(): void;
|
|
35
|
+
/** Flip a single module boolean in the JSONForms data store. No-op while the group is disabled. */
|
|
36
|
+
toggle(dataPath: string): void;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accent- and case-insensitive matching/highlighting helpers for the searchable select.
|
|
3
|
+
* Pure functions (no DI) so matching semantics stay unit-testable without a component fixture.
|
|
4
|
+
*/
|
|
5
|
+
export interface HighlightSegment {
|
|
6
|
+
text: string;
|
|
7
|
+
match: boolean;
|
|
8
|
+
}
|
|
9
|
+
/** Folds a string for comparison: NFD decomposition + strip diacritics + lowercase. */
|
|
10
|
+
export declare function normalizeForSearch(value: string): string;
|
|
11
|
+
/** True when `query` (raw or normalized) is found in the label, ignoring case/accents. */
|
|
12
|
+
export declare function matchesSearch(label: string, query: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Splits `label` into segments flagging every occurrence of `normalizedQuery`.
|
|
15
|
+
* Matching runs on the normalized form but slices the original string, so accents/casing
|
|
16
|
+
* typed by the user still highlight the original characters (e.g. "mat" highlights "Mât").
|
|
17
|
+
*/
|
|
18
|
+
export declare function highlightSegments(label: string, normalizedQuery: string): HighlightSegment[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { FormControl } from '@angular/forms';
|
|
2
|
+
import { HighlightSegment } from './search-highlight';
|
|
3
|
+
export interface SearchableSelectOption<T = string | number> {
|
|
4
|
+
value: T;
|
|
5
|
+
label: string;
|
|
6
|
+
}
|
|
7
|
+
interface VisibleOption {
|
|
8
|
+
value: unknown;
|
|
9
|
+
segments: HighlightSegment[];
|
|
10
|
+
/** True when the option does not match the current search — kept in the DOM (hidden +
|
|
11
|
+
* disabled) so the mat-select trigger keeps the selected option's label while typing,
|
|
12
|
+
* and so the panel key manager natively skips it during arrow navigation. */
|
|
13
|
+
filteredOut: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* mat-select with a sticky search field inside the panel: typing filters options and highlights
|
|
17
|
+
* the matched text (`<mark>`-style), arrows move the active (highlighted) option and Enter
|
|
18
|
+
* selects it — so the control stays fully usable with the keyboard only.
|
|
19
|
+
*
|
|
20
|
+
* Two binding modes:
|
|
21
|
+
* - reactive: pass `control` (JSONForms renderers);
|
|
22
|
+
* - plain value: pass `value` (+ `disabled`, `nullable`) — used by the inline-table cells.
|
|
23
|
+
* The panel content is duplicated in both mat-select branches on purpose: nodes rendered
|
|
24
|
+
* through a shared `<ng-template>` outlet are NOT moved into the select overlay by content
|
|
25
|
+
* projection (the anchor moves, the embedded view stays), so options/trigger would break.
|
|
26
|
+
*/
|
|
27
|
+
export declare class SearchableSelectComponent {
|
|
28
|
+
readonly control: import("@angular/core").InputSignal<FormControl<any> | null>;
|
|
29
|
+
readonly value: import("@angular/core").InputSignal<unknown>;
|
|
30
|
+
readonly disabled: import("@angular/core").InputSignal<boolean>;
|
|
31
|
+
readonly options: import("@angular/core").InputSignal<readonly SearchableSelectOption<string | number>[]>;
|
|
32
|
+
readonly label: import("@angular/core").InputSignal<string | null | undefined>;
|
|
33
|
+
readonly id: import("@angular/core").InputSignal<string>;
|
|
34
|
+
readonly multiple: import("@angular/core").InputSignal<boolean>;
|
|
35
|
+
readonly hidden: import("@angular/core").InputSignal<boolean>;
|
|
36
|
+
readonly hints: import("@angular/core").InputSignal<readonly string[]>;
|
|
37
|
+
readonly error: import("@angular/core").InputSignal<string | null | undefined>;
|
|
38
|
+
/** Adds a leading null option rendered as « – » so the selection can be cleared. */
|
|
39
|
+
readonly nullable: import("@angular/core").InputSignal<boolean>;
|
|
40
|
+
/** Table-cell density: no label, 40px container, hidden subscript wrapper. */
|
|
41
|
+
readonly compact: import("@angular/core").InputSignal<boolean>;
|
|
42
|
+
readonly selectionChange: import("@angular/core").OutputEmitterRef<unknown>;
|
|
43
|
+
private readonly i18n;
|
|
44
|
+
private readonly matSelect;
|
|
45
|
+
private readonly searchInput;
|
|
46
|
+
protected readonly query: import("@angular/core").WritableSignal<string>;
|
|
47
|
+
private readonly panelOpen;
|
|
48
|
+
protected readonly placeholderText: import("@angular/core").Signal<string>;
|
|
49
|
+
protected readonly noResultsText: import("@angular/core").Signal<string>;
|
|
50
|
+
protected readonly optionViews: import("@angular/core").Signal<VisibleOption[]>;
|
|
51
|
+
protected readonly hasVisibleOptions: import("@angular/core").Signal<boolean>;
|
|
52
|
+
constructor();
|
|
53
|
+
protected onQueryInput(event: Event): void;
|
|
54
|
+
protected onSearchKeydown(event: KeyboardEvent): void;
|
|
55
|
+
protected onOpenedChange(open: boolean): void;
|
|
56
|
+
/**
|
|
57
|
+
* mat-select keeps a stale active item when filtering shrinks the option list, which would
|
|
58
|
+
* let Enter pick an invisible option. There is no public API for this, so reach the key
|
|
59
|
+
* manager defensively and pin the highlight to the first visible match.
|
|
60
|
+
*/
|
|
61
|
+
private syncActiveOption;
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { JsonSchema, UISchemaElement } from '@jsonforms/core';
|
|
2
|
+
import { AnimalStockRow } from '../animal-stock.types';
|
|
3
|
+
import { ErrorObject } from 'ajv';
|
|
4
|
+
export declare class AnimalStockDetailComponent {
|
|
5
|
+
private readonly i18n;
|
|
6
|
+
row: import("@angular/core").InputSignal<AnimalStockRow | null>;
|
|
7
|
+
index: import("@angular/core").InputSignal<number | null>;
|
|
8
|
+
rowChange: import("@angular/core").OutputEmitterRef<AnimalStockRow>;
|
|
9
|
+
close: import("@angular/core").OutputEmitterRef<void>;
|
|
10
|
+
itemSchema: import("@angular/core").Signal<JsonSchema>;
|
|
11
|
+
private readonly baseUi;
|
|
12
|
+
localizedUi: import("@angular/core").Signal<UISchemaElement>;
|
|
13
|
+
jsonFormsData: import("@angular/core").Signal<(AnimalStockRow & import("../../../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
|
|
14
|
+
readonly renderers: {
|
|
15
|
+
tester: import("@jsonforms/core").RankedTester;
|
|
16
|
+
renderer: any;
|
|
17
|
+
}[];
|
|
18
|
+
readonly suibiAjv: import("ajv").Ajv;
|
|
19
|
+
onDataChange(newData: any): void;
|
|
20
|
+
onValidationErrors(_errors: ErrorObject[] | null | undefined): void;
|
|
21
|
+
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { EventEmitter, Signal } from '@angular/core';
|
|
2
|
-
import { MatTable } from '@angular/material/table';
|
|
3
1
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
4
|
-
import { AnimalStockRow } from '
|
|
2
|
+
import { AnimalStockRow } from '../animal-stock.types';
|
|
5
3
|
export declare class AnimalStockListComponent {
|
|
6
4
|
private readonly masterData;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
reorder: EventEmitter<{
|
|
5
|
+
rows: import("@angular/core").InputSignal<AnimalStockRow[]>;
|
|
6
|
+
select: import("@angular/core").OutputEmitterRef<number>;
|
|
7
|
+
add: import("@angular/core").OutputEmitterRef<void>;
|
|
8
|
+
delete: import("@angular/core").OutputEmitterRef<number>;
|
|
9
|
+
reorder: import("@angular/core").OutputEmitterRef<{
|
|
13
10
|
previousIndex: number;
|
|
14
11
|
currentIndex: number;
|
|
15
12
|
}>;
|
|
@@ -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';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FarmManureTradingSupply, FarmManureTradingDispense } from '../farm-manure-trading.types';
|
|
2
|
+
/**
|
|
3
|
+
* Farm manure trading page — two inline tables (supply "Reprises" / dispense
|
|
4
|
+
* "Cessions") editing `nutrientCycle.farmManureTrading` directly. The former
|
|
5
|
+
* master-detail round-trip (list + JSONForms detail pane) was replaced by inline
|
|
6
|
+
* editing, so validation deep-links (`selectedFarmManureTrading`) are merely
|
|
7
|
+
* consumed and cleared — there is no detail pane left to open (fodder pattern).
|
|
8
|
+
*/
|
|
9
|
+
export declare class FarmManureTradingMasterDetailComponent {
|
|
10
|
+
private readonly dataSvc;
|
|
11
|
+
private readonly navigationSvc;
|
|
12
|
+
constructor();
|
|
13
|
+
readonly supplyRows: import("@angular/core").Signal<FarmManureTradingSupply[]>;
|
|
14
|
+
readonly dispenseRows: import("@angular/core").Signal<FarmManureTradingDispense[]>;
|
|
15
|
+
onSupplyChange(rows: FarmManureTradingSupply[]): void;
|
|
16
|
+
onDispenseChange(rows: FarmManureTradingDispense[]): void;
|
|
17
|
+
private patchRows;
|
|
18
|
+
private cloneTrading;
|
|
19
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { InlineTableConfig } from '../../../components/inline-table/inline-table.types';
|
|
2
|
+
import { FarmManureTradingMode } from '../../../core/navigation/navigation.service';
|
|
3
|
+
import { FarmManureTradingSupply, FarmManureTradingDispense } from '../farm-manure-trading.types';
|
|
4
|
+
type TradingRow = FarmManureTradingSupply | FarmManureTradingDispense;
|
|
5
|
+
/**
|
|
6
|
+
* FarmManureTradingTableComponent — thin wrapper around InlineTableComponent.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* 1. Provides the per-mode column/section config (the "uischema").
|
|
10
|
+
* 2. Bridges typed `FarmManureTradingSupply[]`/`Dispense[]` to/from the generic
|
|
11
|
+
* `Record<string, unknown>[]` API of InlineTableComponent.
|
|
12
|
+
* 3. Supplies `deriveUnits` as a `rowTransform` — the base `transactionUnit` ('kg'/'m3')
|
|
13
|
+
* and every ingredient's `unit` ('kg/t'/'kg/m3') are derived from the selected
|
|
14
|
+
* product's matterState; the user may switch to a custom unit sharing the same base
|
|
15
|
+
* (t, dt for kg), which converts the entered quantity on the fly.
|
|
16
|
+
*/
|
|
17
|
+
export declare class FarmManureTradingTableComponent {
|
|
18
|
+
readonly mode: import("@angular/core").InputSignal<FarmManureTradingMode>;
|
|
19
|
+
readonly entries: import("@angular/core").InputSignal<TradingRow[]>;
|
|
20
|
+
readonly entriesChange: import("@angular/core").OutputEmitterRef<TradingRow[]>;
|
|
21
|
+
protected readonly config: import("@angular/core").Signal<InlineTableConfig>;
|
|
22
|
+
/** Cast typed entries to generic Record[] for InlineTableComponent. */
|
|
23
|
+
readonly rowsForTable: import("@angular/core").Signal<Record<string, unknown>[]>;
|
|
24
|
+
/** Cast generic output back to typed trading rows. */
|
|
25
|
+
onRowsChange(rows: Record<string, unknown>[]): void;
|
|
26
|
+
/**
|
|
27
|
+
* Row transform deriving the ingredient units from the product's matterState on each
|
|
28
|
+
* edit, and handling `transactionUnit`:
|
|
29
|
+
* - product change (or missing unit on legacy rows): reset to the derived base unit,
|
|
30
|
+
* - unit switch: convert the entered quantity from the previous to the new unit
|
|
31
|
+
* (both share the same base), so the transacted amount is preserved.
|
|
32
|
+
* - no product picked yet: keep the pre-filtered unit the user chose (kg/m3/t/dt)
|
|
33
|
+
* instead of clearing it on every edit.
|
|
34
|
+
*/
|
|
35
|
+
readonly deriveUnits: (changedKey: string, newValue: unknown, row: Record<string, unknown>, previousRow?: Record<string, unknown>) => Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column and section configuration for the Farm Manure Trading inline tables.
|
|
3
|
+
*
|
|
4
|
+
* This is the "uischema" for the supply ("Reprises") and dispense ("Cessions")
|
|
5
|
+
* tables — one InlineTableConfig per mode, mirroring recycling-table.config.ts.
|
|
6
|
+
* Columns:
|
|
7
|
+
* - Product: typeOfManureRecyclingProduct (code list filtered per mode)
|
|
8
|
+
* - Quantity: quantity (number)
|
|
9
|
+
* - Unit: transactionUnit (readonly — derived from the product's
|
|
10
|
+
* matterState, never user-editable, per the API spec)
|
|
11
|
+
* - Origin: manureDerivation[] (expandable key/share pair editor,
|
|
12
|
+
* expected total 100 %)
|
|
13
|
+
* - Nutrients: Ntot, Nsol (molecularFormula 'Nlos'), P₂O₅, K₂O, Mg read/written
|
|
14
|
+
* via the ingredient[] sub-array (same 5 nutrients as recycling).
|
|
15
|
+
* - Nutrient unit: readonly, derived from the product's matterState (kg/t | kg/m³).
|
|
16
|
+
*/
|
|
17
|
+
import type { InlineTableConfig } from '../../../components/inline-table/inline-table.types';
|
|
18
|
+
import type { FarmManureTradingMode } from '../../../core/navigation/navigation.service';
|
|
19
|
+
/** Nutrient formulas tracked per trading entry, in display order. 'Nlos' = soluble nitrogen
|
|
20
|
+
* (matches the `molecularFormula` enum from assets/master-data/substances.json — there is no 'NSol'). */
|
|
21
|
+
export declare const TRADING_NUTRIENT_COLUMNS: readonly ["Ntot", "Nlos", "P2O5", "K2O", "Mg"];
|
|
22
|
+
export type TradingNutrientFormula = (typeof TRADING_NUTRIENT_COLUMNS)[number];
|
|
23
|
+
/** Builds the inline-table config for one mode ('supply' | 'dispense'). */
|
|
24
|
+
export declare function createTradingTableConfig(mode: FarmManureTradingMode): InlineTableConfig;
|
|
@@ -10,6 +10,8 @@ export interface ManureDerivation {
|
|
|
10
10
|
export interface FarmManureTradingSupply {
|
|
11
11
|
quantity?: number;
|
|
12
12
|
typeOfManureRecyclingProduct?: string;
|
|
13
|
+
/** Host-only free text: persisted in the emitted dossier, stripped before API calls. */
|
|
14
|
+
productDesignation?: string;
|
|
13
15
|
transactionUnit?: string;
|
|
14
16
|
manureDerivation?: ManureDerivation[];
|
|
15
17
|
ingredient?: ManureIngredient[];
|
|
@@ -17,6 +19,8 @@ export interface FarmManureTradingSupply {
|
|
|
17
19
|
export interface FarmManureTradingDispense {
|
|
18
20
|
quantity?: number;
|
|
19
21
|
typeOfManureRecyclingProduct?: string;
|
|
22
|
+
/** Host-only free text: persisted in the emitted dossier, stripped before API calls. */
|
|
23
|
+
productDesignation?: string;
|
|
20
24
|
transactionUnit?: string;
|
|
21
25
|
manureDerivation?: ManureDerivation[];
|
|
22
26
|
ingredient?: ManureIngredient[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './farm-manure-trading-
|
|
2
|
-
export * from './farm-manure-trading-
|
|
3
|
-
export * from './farm-manure-trading-master-detail.component';
|
|
1
|
+
export * from './farm-manure-trading-table/farm-manure-trading-table.component';
|
|
2
|
+
export * from './farm-manure-trading-table/farm-manure-trading-table.config';
|
|
3
|
+
export * from './farm-manure-trading-master-detail/farm-manure-trading-master-detail.component';
|
|
4
4
|
export * from './farm-manure-trading.types';
|
|
@@ -1 +1,3 @@
|
|
|
1
1
|
export declare function deriveTransactionUnit(productCode: string | null | undefined): string | undefined;
|
|
2
|
+
/** Derives the mandatory ingredient unit ('kg/t' or 'kg/m3') from the product's matterState. */
|
|
3
|
+
export declare function deriveTradingIngredientUnit(productCode: string | null | undefined): string | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
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. A crop that cannot serve
|
|
19
|
+
* as pre/catch crop forces `isMainCrop: true`. Requirement corrections are
|
|
20
|
+
* special-crops-only (SUIBIL-1143): strip them so they never reach the emitted JSON.
|
|
21
|
+
*/
|
|
22
|
+
readonly enforceArableRules: (changedKey: string, newValue: unknown, row: Record<string, unknown>, previousRow?: Record<string, unknown>) => Record<string, unknown>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
/** Looks up the row's selected crop in the arable-land code list. */
|
|
10
|
+
export declare function arableCrop(row: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Main crop is forced (checked + disabled) when the selected crop cannot serve as a
|
|
13
|
+
* pre/catch crop (`isPermittedForPreOrCatchCrop: false` in the master data).
|
|
14
|
+
*/
|
|
15
|
+
export declare function mainCropForced(row: Record<string, unknown>): boolean;
|
|
16
|
+
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
|
+
}
|