@agridea/suibi-module 0.1.0-preview.01100f9
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/LICENSE +21 -0
- package/README.md +120 -0
- package/dist/elements/browser/main.js +78 -0
- package/dist/elements/browser/polyfills.js +1 -0
- package/dist/elements/browser/styles.css +1 -0
- package/dist/elements/browser/suibi-module-latest.css +1 -0
- package/dist/elements/browser/suibi-module-latest.js +78 -0
- package/dist/elements/browser/suibi-module.v0.1.0-preview.01100f9.css +1 -0
- package/dist/elements/browser/suibi-module.v0.1.0-preview.01100f9.js +78 -0
- package/dist/elements/browser/suibi-theme-dark.css +1 -0
- package/dist/elements/browser/version.txt +1 -0
- package/dist/elements/browser/wc-global-utilities.css +1 -0
- package/dist/types/app/app.config.d.ts +2 -0
- package/dist/types/app/app.d.ts +34 -0
- package/dist/types/app/components/add-dashed-button/add-dashed-button.component.d.ts +9 -0
- package/dist/types/app/components/data-preview/data-preview.component.d.ts +11 -0
- package/dist/types/app/components/empty-state/empty-state.component.d.ts +12 -0
- package/dist/types/app/components/gauge-arc/gauge-arc.component.d.ts +49 -0
- package/dist/types/app/components/header-bar/header-bar.component.d.ts +14 -0
- package/dist/types/app/components/inline-table/inline-table.component.d.ts +137 -0
- package/dist/types/app/components/inline-table/inline-table.types.d.ts +203 -0
- package/dist/types/app/components/module-placeholder-page/module-placeholder-page.component.d.ts +6 -0
- package/dist/types/app/components/planning-result/planning-result.component.d.ts +46 -0
- package/dist/types/app/components/planning-result-row/planning-result-row.component.d.ts +34 -0
- package/dist/types/app/components/planning-trigger/planning-trigger.component.d.ts +13 -0
- package/dist/types/app/components/results-page/results-page.component.d.ts +13 -0
- package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts +32 -0
- package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-metrics.service.d.ts +21 -0
- package/dist/types/app/components/suissebilanz-minibar/suissebilanz-minibar.component.d.ts +19 -0
- package/dist/types/app/components/validation-errors-panel/validation-errors-panel.component.d.ts +36 -0
- package/dist/types/app/components/validation-page/validation-page.component.d.ts +18 -0
- package/dist/types/app/components/welcome-page/metadata.types.d.ts +1 -0
- package/dist/types/app/components/welcome-page/welcome-page.component.d.ts +30 -0
- package/dist/types/app/components/workflow-stepper/workflow-stepper.component.d.ts +49 -0
- package/dist/types/app/core/data/naebi-data.service.d.ts +253 -0
- package/dist/types/app/core/error/global-error-handler.d.ts +5 -0
- package/dist/types/app/core/events/suibi-data-emitter.service.d.ts +13 -0
- package/dist/types/app/core/events/suibi-data-event.d.ts +26 -0
- package/dist/types/app/core/i18n/i18n.service.d.ts +22 -0
- package/dist/types/app/core/i18n/locales/de.d.ts +2 -0
- package/dist/types/app/core/i18n/locales/en.d.ts +2 -0
- 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 +32 -0
- package/dist/types/app/core/metadata/suibi-metadata.service.d.ts +6 -0
- package/dist/types/app/core/metadata/suibi-metadata.types.d.ts +18 -0
- package/dist/types/app/core/navigation/navigation.service.d.ts +100 -0
- package/dist/types/app/core/planning/planning-balance.service.d.ts +38 -0
- package/dist/types/app/core/planning/planning-balance.types.d.ts +206 -0
- package/dist/types/app/core/planning/planning-balance.utils.d.ts +10 -0
- package/dist/types/app/core/schemas/index.d.ts +18 -0
- package/dist/types/app/core/schemas/schema-localization.util.d.ts +18 -0
- package/dist/types/app/core/schemas/schema-merge.util.d.ts +26 -0
- package/dist/types/app/core/schemas/ui-helper-registry.d.ts +16 -0
- package/dist/types/app/core/telemetry/telemetry.service.d.ts +12 -0
- package/dist/types/app/core/utils/object.util.d.ts +50 -0
- package/dist/types/app/core/validation/ajv-custom.d.ts +15 -0
- package/dist/types/app/core/validation/capabilities.d.ts +18 -0
- package/dist/types/app/core/validation/error-formatter.d.ts +19 -0
- package/dist/types/app/core/validation/global-validation.service.d.ts +59 -0
- package/dist/types/app/jsonforms/constraints/constraint-resolvers.d.ts +50 -0
- package/dist/types/app/jsonforms/filters/code-list-filter-resolvers.d.ts +63 -0
- package/dist/types/app/jsonforms/registry/renderers.registry.d.ts +38 -0
- package/dist/types/app/jsonforms/renderers/controls/selects/animal-category/animal-category-select.renderer.d.ts +21 -0
- package/dist/types/app/jsonforms/renderers/controls/selects/code-list/code-list-select.renderer.d.ts +34 -0
- package/dist/types/app/jsonforms/renderers/layout/array/array-layout.renderer.d.ts +43 -0
- package/dist/types/app/jsonforms/renderers/layout/categorization/selected-category-categorization.renderer.d.ts +34 -0
- package/dist/types/app/jsonforms/renderers/layout/constraint/constraint-layout.renderer.d.ts +31 -0
- package/dist/types/app/jsonforms/renderers/layout/group/base-group.renderer.d.ts +31 -0
- package/dist/types/app/jsonforms/renderers/layout/group/card-group.renderer.d.ts +6 -0
- package/dist/types/app/jsonforms/renderers/layout/group/group-testers.d.ts +4 -0
- package/dist/types/app/jsonforms/renderers/layout/group/logical-group.renderer.d.ts +6 -0
- package/dist/types/app/jsonforms/renderers/layout/group/module-toggle-group.renderer.d.ts +38 -0
- package/dist/types/app/jsonforms/renderers/layout/group/plain-group.renderer.d.ts +6 -0
- package/dist/types/app/jsonforms/shared/base-control/base-select-control.d.ts +16 -0
- package/dist/types/app/jsonforms/shared/option-sources/code-lists.d.ts +11 -0
- package/dist/types/app/jsonforms/shared/validation/field-error.service.d.ts +18 -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/animal-stock-list.component.d.ts +18 -0
- package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-master-detail/animal-stock-master-detail.component.d.ts +24 -0
- package/dist/types/app/nutrient-cycle/animal-stock/animal-stock.types.d.ts +69 -0
- package/dist/types/app/nutrient-cycle/animal-stock/index.d.ts +4 -0
- 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 +34 -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 +27 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/transaction-unit.util.d.ts +3 -0
- 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/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 +41 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.util.d.ts +6 -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 +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 +61 -0
- package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.component.d.ts +43 -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 +34 -0
- package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.types.d.ts +43 -0
- package/dist/types/app/nutrient-cycle/field-spreading/index.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 +31 -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 +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 +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/lifetime-performance/lifetime-performance-form.component.d.ts +27 -0
- package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance.types.d.ts +5 -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/dist/types/environments/environment.d.ts +11 -0
- package/dist/types/public-api.d.ts +6 -0
- package/dist/types/shared/material-icons.d.ts +16 -0
- package/package.json +142 -0
package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { SafeUrl } from '@angular/platform-browser';
|
|
2
|
+
import { PlanningBalanceService } from '../../core/planning/planning-balance.service';
|
|
3
|
+
import { GaugeStatus } from '../gauge-arc/gauge-arc.component';
|
|
4
|
+
import { SuisseBilanzMetricsService } from './suissebilanz-metrics.service';
|
|
5
|
+
/**
|
|
6
|
+
* Dashboard card displaying the 5 main SuisseBilanz metrics as semicircular
|
|
7
|
+
* SVG gauges. Derives all display data from `PlanningBalanceService` via
|
|
8
|
+
* computed signals — fully zoneless-safe, `OnPush`.
|
|
9
|
+
*
|
|
10
|
+
* Shows an empty-state panel when no planning result is available yet.
|
|
11
|
+
*/
|
|
12
|
+
export declare class SuisseBilanzDashboardComponent {
|
|
13
|
+
readonly embedded: import("@angular/core").InputSignal<boolean>;
|
|
14
|
+
/** Shows the official PDF download link even when `embedded` (header hidden). */
|
|
15
|
+
readonly showPdfButton: import("@angular/core").InputSignal<boolean>;
|
|
16
|
+
protected readonly planning: PlanningBalanceService;
|
|
17
|
+
private readonly sanitizer;
|
|
18
|
+
protected readonly metricsService: SuisseBilanzMetricsService;
|
|
19
|
+
private readonly result;
|
|
20
|
+
protected readonly metrics: import("@angular/core").Signal<import("../gauge-arc/gauge-arc.component").GaugeMetric[]>;
|
|
21
|
+
/** Surface areas in ha, derived from the latest planning result. */
|
|
22
|
+
protected readonly surfaces: import("@angular/core").Signal<{
|
|
23
|
+
sau: number;
|
|
24
|
+
sfe: number;
|
|
25
|
+
to: number;
|
|
26
|
+
} | null>;
|
|
27
|
+
protected readonly officialPdfUrl: import("@angular/core").Signal<SafeUrl | null>;
|
|
28
|
+
private prevBlobUrl;
|
|
29
|
+
private readonly blobCleanup;
|
|
30
|
+
/** Maps a `GaugeStatus` to its Material icon name for the status badge. */
|
|
31
|
+
protected statusIcon(status: GaugeStatus): string;
|
|
32
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GaugeMetric } from '../gauge-arc/gauge-arc.component';
|
|
2
|
+
/**
|
|
3
|
+
* Shared source of truth for all SuisseBilanz metric view-models.
|
|
4
|
+
*
|
|
5
|
+
* Both the full dashboard card and the slim minibar consume this service so
|
|
6
|
+
* the derivation logic lives in exactly one place. Metrics re-compute via
|
|
7
|
+
* `computed()` when either the planning result or the locale signal changes.
|
|
8
|
+
*/
|
|
9
|
+
export declare class SuisseBilanzMetricsService {
|
|
10
|
+
private readonly planning;
|
|
11
|
+
private readonly i18n;
|
|
12
|
+
/** Wall-clock time of the most recent successful planning result. */
|
|
13
|
+
readonly lastUpdated: import("@angular/core").WritableSignal<Date | null>;
|
|
14
|
+
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* Five gauge view-models for N avail., P₂O₅, K₂O, Mg and Rendement prairies.
|
|
17
|
+
* Returns placeholder 'empty' metrics until the first planning result arrives.
|
|
18
|
+
*/
|
|
19
|
+
readonly metrics: import("@angular/core").Signal<GaugeMetric[]>;
|
|
20
|
+
private emptyMetric;
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { GaugeMetric, GaugeStatus } from '../gauge-arc/gauge-arc.component';
|
|
2
|
+
import { SuisseBilanzMetricsService } from '../suissebilanz-dashboard/suissebilanz-metrics.service';
|
|
3
|
+
/**
|
|
4
|
+
* Slim, always-visible metrics card placed above the workflow stepper.
|
|
5
|
+
*
|
|
6
|
+
* Shows the same 5 SuisseBilanz metrics as the full dashboard card but in a
|
|
7
|
+
* compact single-row layout: metric label → bold coloured value → thin
|
|
8
|
+
* progress bar. Shares all data logic via `SuisseBilanzMetricsService`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SuisseBilanzMinibarComponent {
|
|
11
|
+
protected readonly metricsService: SuisseBilanzMetricsService;
|
|
12
|
+
/** Returns the status colour for a given metric status. */
|
|
13
|
+
protected statusColor(status: GaugeStatus): string;
|
|
14
|
+
/**
|
|
15
|
+
* Maps the metric value to a 0–100 fill percentage for the progress bar,
|
|
16
|
+
* clamped so bars never overflow the track.
|
|
17
|
+
*/
|
|
18
|
+
protected fillPct(metric: GaugeMetric): number;
|
|
19
|
+
}
|
package/dist/types/app/components/validation-errors-panel/validation-errors-panel.component.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ErrorObject } from 'ajv';
|
|
2
|
+
/**
|
|
3
|
+
* ValidationErrorsPanelComponent
|
|
4
|
+
* Reusable expansion panel summarizing & listing AJV validation issues.
|
|
5
|
+
* - Collapsed summary shows count + error icon.
|
|
6
|
+
* - Expands to list formatted, translated messages (stable ordering).
|
|
7
|
+
* - Hides entirely when there are no errors.
|
|
8
|
+
* - Emits `errorSelected` when user clicks an error (for navigation).
|
|
9
|
+
* Inputs:
|
|
10
|
+
* errors: ErrorObject[] (raw / consolidated) – consumer decides consolidation strategy.
|
|
11
|
+
* clickable: boolean – when true, list items are interactive and emit selection events.
|
|
12
|
+
* Outputs:
|
|
13
|
+
* errorSelected: ErrorObject – emitted when user clicks an error item.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ValidationErrorsPanelComponent {
|
|
16
|
+
/** Raw (or already consolidated) AJV errors */
|
|
17
|
+
errors: import("@angular/core").InputSignal<ErrorObject<string, Record<string, any>, unknown>[] | null | undefined>;
|
|
18
|
+
/** When true, list items are clickable and emit errorSelected */
|
|
19
|
+
clickable: import("@angular/core").InputSignal<boolean>;
|
|
20
|
+
/** Emitted when user clicks an error (only if clickable is true) */
|
|
21
|
+
errorSelected: import("@angular/core").OutputEmitterRef<ErrorObject<string, Record<string, any>, unknown>>;
|
|
22
|
+
private readonly i18n;
|
|
23
|
+
expanded: import("@angular/core").WritableSignal<boolean>;
|
|
24
|
+
hasErrors: import("@angular/core").Signal<boolean>;
|
|
25
|
+
/** Stable sort: by instancePath then keyword for predictability */
|
|
26
|
+
private sortedErrors;
|
|
27
|
+
formattedItems: import("@angular/core").Signal<{
|
|
28
|
+
message: string;
|
|
29
|
+
field: string;
|
|
30
|
+
error: ErrorObject<string, Record<string, any>, unknown>;
|
|
31
|
+
}[]>;
|
|
32
|
+
issueCountLabel: import("@angular/core").Signal<string>;
|
|
33
|
+
panelAriaLabel: import("@angular/core").Signal<string>;
|
|
34
|
+
collapse(): void;
|
|
35
|
+
onErrorClick(error: ErrorObject): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ErrorObject } from 'ajv';
|
|
2
|
+
import { PlanningBalanceService } from '../../core/planning/planning-balance.service';
|
|
3
|
+
/**
|
|
4
|
+
* Final submission step: review validation status and submit the planning balance.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ValidationPageComponent {
|
|
7
|
+
readonly showHeader: import("@angular/core").InputSignal<boolean>;
|
|
8
|
+
/** Navigation callback for validation error clicks — provided by App to keep routing logic centralised. */
|
|
9
|
+
readonly onErrorSelected: import("@angular/core").InputSignal<(error: ErrorObject) => void>;
|
|
10
|
+
/** Navigation callback triggered after a fresh successful planning submission. */
|
|
11
|
+
readonly onSubmitSuccess: import("@angular/core").InputSignal<() => void>;
|
|
12
|
+
protected readonly planning: PlanningBalanceService;
|
|
13
|
+
private readonly globalValidation;
|
|
14
|
+
private lastHandledSuccessRequestId;
|
|
15
|
+
constructor();
|
|
16
|
+
protected readonly validationErrors: import("@angular/core").Signal<import("../../../public-api").EnrichedValidationError[]>;
|
|
17
|
+
protected readonly errorCount: import("@angular/core").Signal<number>;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DEFAULT_SUIBI_METADATA, DEFAULT_COMPUTATION_MODULES, type ComputationModules, type SubmissionStatus, type SuibiVersion, type SuibiMetadata } from '../../core/metadata/suibi-metadata.types';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { JsonSchema, UISchemaElement } from '@jsonforms/core';
|
|
2
|
+
import { SuibiMetadata } from '../../core/metadata/suibi-metadata.types';
|
|
3
|
+
export declare class WelcomePageComponent {
|
|
4
|
+
private readonly i18n;
|
|
5
|
+
private readonly metadataSvc;
|
|
6
|
+
private readonly naebi;
|
|
7
|
+
startEvent: import("@angular/core").OutputEmitterRef<void>;
|
|
8
|
+
metadataChange: import("@angular/core").OutputEmitterRef<SuibiMetadata>;
|
|
9
|
+
private readonly baseSchema;
|
|
10
|
+
private readonly baseUiSchema;
|
|
11
|
+
readonly suibiAjv: import("ajv").Ajv;
|
|
12
|
+
readonly renderers: {
|
|
13
|
+
tester: import("@jsonforms/core").RankedTester;
|
|
14
|
+
renderer: any;
|
|
15
|
+
}[];
|
|
16
|
+
readonly metadata: import("@angular/core").Signal<SuibiMetadata>;
|
|
17
|
+
readonly localizedSchema: import("@angular/core").Signal<JsonSchema>;
|
|
18
|
+
readonly localizedUi: import("@angular/core").Signal<UISchemaElement>;
|
|
19
|
+
readonly jsonFormsData: import("@angular/core").Signal<{}>;
|
|
20
|
+
constructor();
|
|
21
|
+
start(): void;
|
|
22
|
+
loadExampleData(): void;
|
|
23
|
+
onMetadataChange(newValue: unknown): void;
|
|
24
|
+
private normalizeJsonFormsPayload;
|
|
25
|
+
private toMetadata;
|
|
26
|
+
private extractModules;
|
|
27
|
+
private isSuibiVersion;
|
|
28
|
+
private isSubmissionStatus;
|
|
29
|
+
private isSameMetadata;
|
|
30
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PageId } from '../../core/navigation/navigation.service';
|
|
2
|
+
/**
|
|
3
|
+
* WorkflowStepperComponent
|
|
4
|
+
* Horizontal navigation stepper for the main data-entry workflow.
|
|
5
|
+
*
|
|
6
|
+
* Design contract:
|
|
7
|
+
* - Uses mat-stepper as a header-only nav bar (step content is empty; content
|
|
8
|
+
* area is hidden via CSS so the stepper acts as a pure navigation indicator).
|
|
9
|
+
* - [selectedIndex] is driven by the currentPage input — no internal routing state.
|
|
10
|
+
* - Navigation is delegated back to App via the onNavigate callback, preserving
|
|
11
|
+
* the custom-element page-attribute reflection.
|
|
12
|
+
* - Error indicators: any page with at least one enriched validation error shows
|
|
13
|
+
* the error ring on its step circle. Requires STEPPER_GLOBAL_OPTIONS { showError: true }.
|
|
14
|
+
* - Non-workflow pages (e.g. data_preview): mat-stepper rejects out-of-bounds selectedIndex,
|
|
15
|
+
* so we clamp to 0; the no-active-step CSS class neutralises the visual active indicator,
|
|
16
|
+
* and onStepperClick delegates clicks for all headers (bypassing the stepper's
|
|
17
|
+
* "no-change" guard that suppresses selectedIndexChange for the currently selected step).
|
|
18
|
+
*
|
|
19
|
+
* Extension points:
|
|
20
|
+
* - Completed state: replace the hardcoded `false` on [completed] with a per-page
|
|
21
|
+
* computed once domain completion rules are defined (e.g. all required fields valid).
|
|
22
|
+
* - New pages: add an entry to WORKFLOW_STEPS and extend PageId.
|
|
23
|
+
*/
|
|
24
|
+
export declare class WorkflowStepperComponent {
|
|
25
|
+
protected readonly steps: readonly {
|
|
26
|
+
readonly pageId: PageId;
|
|
27
|
+
readonly labelKey: string;
|
|
28
|
+
}[];
|
|
29
|
+
/**
|
|
30
|
+
* Current page from the parent. Controls which step circle is highlighted.
|
|
31
|
+
* Non-workflow pages (e.g. data_preview) use index 0 as a valid CDK fallback;
|
|
32
|
+
* the no-active-step CSS class removes the visual active indicator for those pages.
|
|
33
|
+
*/
|
|
34
|
+
readonly currentPage: import("@angular/core").InputSignal<PageId>;
|
|
35
|
+
/**
|
|
36
|
+
* Navigation callback provided by App.
|
|
37
|
+
* Using a callback (instead of an output EventEmitter) matches the existing
|
|
38
|
+
* header-bar pattern and ensures the custom-element page-attribute is reflected.
|
|
39
|
+
*/
|
|
40
|
+
readonly onNavigate: import("@angular/core").InputSignal<(page: PageId) => void>;
|
|
41
|
+
private readonly validationSvc;
|
|
42
|
+
private readonly workflowPage;
|
|
43
|
+
protected readonly pagesWithErrors: import("@angular/core").Signal<Set<PageId>>;
|
|
44
|
+
protected readonly isOnWorkflowPage: import("@angular/core").Signal<boolean>;
|
|
45
|
+
protected readonly clampedStepIndex: import("@angular/core").Signal<number>;
|
|
46
|
+
protected onSelectedIndexChange(index: number): void;
|
|
47
|
+
protected onStepperClick(event: MouseEvent): void;
|
|
48
|
+
private navigateTo;
|
|
49
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import exampleDetail from '../../../../assets/example-data/example-naebi-data.json';
|
|
2
|
+
type SampleEvent = typeof exampleDetail;
|
|
3
|
+
type SampleData = SampleEvent['payload']['data'];
|
|
4
|
+
export type NaebiData = SampleData;
|
|
5
|
+
/**
|
|
6
|
+
* Calculation mode determines which validation rules and features are active.
|
|
7
|
+
*/
|
|
8
|
+
export declare enum CalculationMode {
|
|
9
|
+
SuiBi = "SuiBi",// SuisseBilanz (standard)
|
|
10
|
+
ExBi = "ExBi"
|
|
11
|
+
}
|
|
12
|
+
export declare class NaebiDataService {
|
|
13
|
+
private readonly _data;
|
|
14
|
+
readonly data: import("@angular/core").Signal<{
|
|
15
|
+
nutrientCycle: {
|
|
16
|
+
animalStock: {
|
|
17
|
+
order: string;
|
|
18
|
+
animalCategoryPRIF: number;
|
|
19
|
+
selfReportedLivestock: {
|
|
20
|
+
averageQuantity: number;
|
|
21
|
+
};
|
|
22
|
+
durationCorrectionQuantity: number;
|
|
23
|
+
durationCorrectionDays: number;
|
|
24
|
+
utilisation: number;
|
|
25
|
+
formOfDetention: {
|
|
26
|
+
hasGrazing: boolean;
|
|
27
|
+
pasture: {
|
|
28
|
+
days: number;
|
|
29
|
+
hoursPerDay: number;
|
|
30
|
+
};
|
|
31
|
+
stall: {
|
|
32
|
+
stableSystem: string;
|
|
33
|
+
stableVentilationType: number;
|
|
34
|
+
hasStableDeepLitter: boolean;
|
|
35
|
+
hasStableManureBeltDrying: boolean;
|
|
36
|
+
stableManureRemovalFrequency: number;
|
|
37
|
+
stableWaterSupply: number;
|
|
38
|
+
hasStableManureAndSlurryProduction: boolean;
|
|
39
|
+
hasStableFeedingStationElevated: boolean;
|
|
40
|
+
hasStableFloorSlopedUrineDrainage: boolean;
|
|
41
|
+
hasYard: boolean;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
hasImpexDerivedExcretion: boolean;
|
|
45
|
+
hasLinearCorrectionDerivedExcretion: boolean;
|
|
46
|
+
feeding: {
|
|
47
|
+
fodderConsumption: number;
|
|
48
|
+
concentratedFeedstuffConsumption: number;
|
|
49
|
+
concentratedFeedStuffConsumption: number;
|
|
50
|
+
winterFeeding: {
|
|
51
|
+
feedingRoutine: {
|
|
52
|
+
typeOfFeedstuffProduct: string;
|
|
53
|
+
transactionUnit: string;
|
|
54
|
+
quantity: number;
|
|
55
|
+
}[];
|
|
56
|
+
dailyConcentratedFeedstuff: {
|
|
57
|
+
quantity: number;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
summerFeeding: {
|
|
61
|
+
feedingRoutine: {
|
|
62
|
+
typeOfFeedstuffProduct: string;
|
|
63
|
+
transactionUnit: string;
|
|
64
|
+
quantity: number;
|
|
65
|
+
}[];
|
|
66
|
+
dailyConcentratedFeedstuff: {
|
|
67
|
+
quantity: number;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
}[];
|
|
72
|
+
storage: {
|
|
73
|
+
stableStrawLitter: number;
|
|
74
|
+
slurrySupplyProportionStored: number;
|
|
75
|
+
createFacilitySpecificManureProduct: boolean;
|
|
76
|
+
createFacilitySpecificSlurryProduct: boolean;
|
|
77
|
+
slurryTankQuantity: number;
|
|
78
|
+
dilutionRatio: number;
|
|
79
|
+
manurePit: never[];
|
|
80
|
+
slurryTank: {
|
|
81
|
+
descriptor: string;
|
|
82
|
+
volumeInM3: number;
|
|
83
|
+
depthInM: number;
|
|
84
|
+
cover: number;
|
|
85
|
+
mixingFrequency: number;
|
|
86
|
+
manureDerivation: string[];
|
|
87
|
+
}[];
|
|
88
|
+
};
|
|
89
|
+
farmManureTrading: {
|
|
90
|
+
supply: never[];
|
|
91
|
+
dispense: {
|
|
92
|
+
quantity: number;
|
|
93
|
+
typeOfManureRecyclingProduct: string;
|
|
94
|
+
transactionUnit: string;
|
|
95
|
+
manureDerivation: {
|
|
96
|
+
zoologicalAnimal: string;
|
|
97
|
+
percentageAllocation: number;
|
|
98
|
+
}[];
|
|
99
|
+
ingredient: {
|
|
100
|
+
quantity: number;
|
|
101
|
+
molecularFormula: string;
|
|
102
|
+
unit: string;
|
|
103
|
+
}[];
|
|
104
|
+
}[];
|
|
105
|
+
};
|
|
106
|
+
fieldSpreading: {
|
|
107
|
+
soilPh: number;
|
|
108
|
+
slurry: {
|
|
109
|
+
quantity: number;
|
|
110
|
+
dilutionRatio: number;
|
|
111
|
+
otherApplicationTechnologies: {
|
|
112
|
+
applicationTechnologyType: number;
|
|
113
|
+
proportionOfArea: number;
|
|
114
|
+
}[];
|
|
115
|
+
applicationDuringWarmDays: number;
|
|
116
|
+
proportionAppliedSummerMonths: number;
|
|
117
|
+
proportionAppliedOtherMonths: number;
|
|
118
|
+
proportionAppliedAfter6PM: number;
|
|
119
|
+
dragHoseAreaSize: number;
|
|
120
|
+
};
|
|
121
|
+
manure: {
|
|
122
|
+
applicationIncorporationTime: number;
|
|
123
|
+
proportionAppliedSummerMonths: number;
|
|
124
|
+
proportionAppliedOtherMonths: number;
|
|
125
|
+
};
|
|
126
|
+
fertiliser: {
|
|
127
|
+
descriptor: string;
|
|
128
|
+
fertiliserProductCategory: string;
|
|
129
|
+
quantity: number;
|
|
130
|
+
transactionUnit: string;
|
|
131
|
+
ingredient: {
|
|
132
|
+
molecularFormula: string;
|
|
133
|
+
quantity: number;
|
|
134
|
+
unit: string;
|
|
135
|
+
}[];
|
|
136
|
+
}[];
|
|
137
|
+
recycling: {
|
|
138
|
+
typeOfManureRecyclingProduct: string;
|
|
139
|
+
quantity: number;
|
|
140
|
+
transactionUnit: string;
|
|
141
|
+
ingredient: {
|
|
142
|
+
molecularFormula: string;
|
|
143
|
+
quantity: number;
|
|
144
|
+
unit: string;
|
|
145
|
+
}[];
|
|
146
|
+
}[];
|
|
147
|
+
};
|
|
148
|
+
lifetimePerformance: {
|
|
149
|
+
milkProductionReport: number;
|
|
150
|
+
};
|
|
151
|
+
fodder: {
|
|
152
|
+
trading: {
|
|
153
|
+
supply: {
|
|
154
|
+
typeOfFeedstuffProduct: string;
|
|
155
|
+
quantity: number;
|
|
156
|
+
transactionUnit: string;
|
|
157
|
+
ingredient: {
|
|
158
|
+
quantity: number;
|
|
159
|
+
molecularFormula: string;
|
|
160
|
+
unit: string;
|
|
161
|
+
}[];
|
|
162
|
+
}[];
|
|
163
|
+
dispense: {
|
|
164
|
+
typeOfFeedstuffProduct: string;
|
|
165
|
+
quantity: number;
|
|
166
|
+
transactionUnit: string;
|
|
167
|
+
ingredient: never[];
|
|
168
|
+
}[];
|
|
169
|
+
};
|
|
170
|
+
cropFromNonFodderCropland: {
|
|
171
|
+
typeOfFeedstuffProduct: string;
|
|
172
|
+
quantity: number;
|
|
173
|
+
transactionUnit: string;
|
|
174
|
+
ingredient: {
|
|
175
|
+
quantity: number;
|
|
176
|
+
molecularFormula: string;
|
|
177
|
+
unit: string;
|
|
178
|
+
}[];
|
|
179
|
+
}[];
|
|
180
|
+
proportionStorageLoss: number;
|
|
181
|
+
totalBalanceErrorMargin: number;
|
|
182
|
+
};
|
|
183
|
+
fieldCultivation: {
|
|
184
|
+
buildingZoneAreaSize: number;
|
|
185
|
+
outdoorVegetableMainCropAreaSize: number;
|
|
186
|
+
indoorVegetableMainCropAreaSize: number;
|
|
187
|
+
feedingOfCropHarvest: {
|
|
188
|
+
agronomicCropCategory: string;
|
|
189
|
+
effectiveYield: number;
|
|
190
|
+
}[];
|
|
191
|
+
dispenseOfCropHarvest: {
|
|
192
|
+
agronomicCropCategory: string;
|
|
193
|
+
effectiveYield: number;
|
|
194
|
+
}[];
|
|
195
|
+
fodderCropland: ({
|
|
196
|
+
agronomicCropCategory: string;
|
|
197
|
+
isMainCrop: boolean;
|
|
198
|
+
areaSize: number;
|
|
199
|
+
calculateYieldThroughFodderBalance: boolean;
|
|
200
|
+
yieldPerSquareMeasure?: undefined;
|
|
201
|
+
} | {
|
|
202
|
+
agronomicCropCategory: string;
|
|
203
|
+
isMainCrop: boolean;
|
|
204
|
+
areaSize: number;
|
|
205
|
+
yieldPerSquareMeasure: number;
|
|
206
|
+
calculateYieldThroughFodderBalance?: undefined;
|
|
207
|
+
})[];
|
|
208
|
+
arableLand: {
|
|
209
|
+
agronomicCropCategory: string;
|
|
210
|
+
isMainCrop: boolean;
|
|
211
|
+
areaSize: number;
|
|
212
|
+
yieldPerSquareMeasure: number;
|
|
213
|
+
hasLongTermYieldDivergence: boolean;
|
|
214
|
+
}[];
|
|
215
|
+
special: {
|
|
216
|
+
agronomicCropCategory: string;
|
|
217
|
+
userSpecificPlantName: string;
|
|
218
|
+
isMainCrop: boolean;
|
|
219
|
+
areaSize: number;
|
|
220
|
+
requirementCorrection: {
|
|
221
|
+
quantity: number;
|
|
222
|
+
molecularFormula: string;
|
|
223
|
+
unit: string;
|
|
224
|
+
}[];
|
|
225
|
+
}[];
|
|
226
|
+
};
|
|
227
|
+
generateReport: boolean;
|
|
228
|
+
};
|
|
229
|
+
calculationVersion: {
|
|
230
|
+
version: string;
|
|
231
|
+
};
|
|
232
|
+
}>;
|
|
233
|
+
private readonly _lastEmitted;
|
|
234
|
+
private readonly _dirty;
|
|
235
|
+
readonly dirty: import("@angular/core").Signal<boolean>;
|
|
236
|
+
private readonly _calculationMode;
|
|
237
|
+
readonly calculationMode: import("@angular/core").Signal<CalculationMode>;
|
|
238
|
+
/**
|
|
239
|
+
* Set new data value; accepts plain object (already parsed) matching NaebiData shape.
|
|
240
|
+
* Silent no-op if value is structurally equal after normalization to avoid unnecessary updates.
|
|
241
|
+
*/
|
|
242
|
+
setData(value: NaebiData): void;
|
|
243
|
+
/** Mark current data as saved (clears dirty state and updates snapshot). */
|
|
244
|
+
markSaved(): void;
|
|
245
|
+
/**
|
|
246
|
+
* Set calculation mode (SuiBi or ExBi).
|
|
247
|
+
* Can affect which validation rules are active or which features are enabled.
|
|
248
|
+
*/
|
|
249
|
+
setCalculationMode(mode: CalculationMode): void;
|
|
250
|
+
/** Reset to bundled example */
|
|
251
|
+
reset(): void;
|
|
252
|
+
}
|
|
253
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SuibiDataEventDetail, SuibiDataEventMetadata } from './suibi-data-event';
|
|
2
|
+
/**
|
|
3
|
+
* Centralizes construction + dispatch of the `suibi-data-emitted` payload so multiple UI entry points can reuse it.
|
|
4
|
+
*/
|
|
5
|
+
export declare class SuibiDataEmitterService {
|
|
6
|
+
private readonly i18n;
|
|
7
|
+
private readonly validation;
|
|
8
|
+
private readonly metadataSvc;
|
|
9
|
+
private readonly naebi;
|
|
10
|
+
buildMetadata(): SuibiDataEventMetadata;
|
|
11
|
+
buildDetail(): SuibiDataEventDetail;
|
|
12
|
+
emitFrom(target: HTMLElement): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Locale } from '../i18n/i18n.service';
|
|
2
|
+
import { NaebiData } from '../data/naebi-data.service';
|
|
3
|
+
import { SuibiMetadata } from '../metadata/suibi-metadata.types';
|
|
4
|
+
/**
|
|
5
|
+
* Increment when the payload contract changes in a backwards-incompatible way.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SUIBI_DATA_EVENT_VERSION = "suibi-data.v1";
|
|
8
|
+
/** Detail object emitted with the `suibi-data` CustomEvent. */
|
|
9
|
+
export interface SuibiDataEventDetail {
|
|
10
|
+
version: typeof SUIBI_DATA_EVENT_VERSION;
|
|
11
|
+
payload: SuibiDataEventPayload;
|
|
12
|
+
}
|
|
13
|
+
/** Top-level payload structure delivered to host applications. */
|
|
14
|
+
export interface SuibiDataEventPayload {
|
|
15
|
+
metadata: SuibiDataEventMetadata;
|
|
16
|
+
data: NaebiData;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Metadata describing the dataset at the moment of emission so hosts can audit and reason about it.
|
|
20
|
+
*/
|
|
21
|
+
export type SuibiDataEventMetadata = SuibiMetadata & {
|
|
22
|
+
emittedAt: string;
|
|
23
|
+
locale: Locale;
|
|
24
|
+
isValid: boolean;
|
|
25
|
+
errorCount: number;
|
|
26
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PipeTransform, Signal } from '@angular/core';
|
|
2
|
+
export type Locale = 'en' | 'de' | 'fr' | 'it';
|
|
3
|
+
export type JsonFormsTranslator = (key: string, defaultMessage: string | undefined, context: unknown) => string;
|
|
4
|
+
export declare class I18nService {
|
|
5
|
+
private readonly _locale;
|
|
6
|
+
locale: Signal<Locale>;
|
|
7
|
+
private readonly translator;
|
|
8
|
+
readonly jsonFormsI18n: Signal<{
|
|
9
|
+
locale: Locale;
|
|
10
|
+
translate: JsonFormsTranslator;
|
|
11
|
+
translateError: (error: unknown, translate: JsonFormsTranslator) => string;
|
|
12
|
+
}>;
|
|
13
|
+
setLocale(locale: Locale): void;
|
|
14
|
+
/** Returns true if the given string is a supported locale key. */
|
|
15
|
+
isValidLocale(value: string): value is Locale;
|
|
16
|
+
t(key: string, defaultMessage?: string): string;
|
|
17
|
+
}
|
|
18
|
+
export declare class TranslatePipe implements PipeTransform {
|
|
19
|
+
private readonly cache;
|
|
20
|
+
private readonly i18n;
|
|
21
|
+
transform(key: string, defaultMessage?: string): Signal<string>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Locale } from '../i18n/i18n.service';
|
|
2
|
+
/** The property name of the primary key in a master-data catalog entry. */
|
|
3
|
+
type MasterDataKeyField = string;
|
|
4
|
+
interface MasterDataCatalog {
|
|
5
|
+
entries: any[];
|
|
6
|
+
/** Property name to use as the lookup key; 'id' entries are coerced to Number. */
|
|
7
|
+
key: MasterDataKeyField;
|
|
8
|
+
}
|
|
9
|
+
declare const MASTER_DATA: Record<string, MasterDataCatalog>;
|
|
10
|
+
export type MasterDataKind = keyof typeof MASTER_DATA;
|
|
11
|
+
export declare class MasterDataService {
|
|
12
|
+
private readonly i18n;
|
|
13
|
+
private readonly locale;
|
|
14
|
+
private readonly indices;
|
|
15
|
+
/** Public lookup of raw master-data entry (typed as any for now). */
|
|
16
|
+
entry<T = any>(kind: MasterDataKind, id: number | string | null | undefined): T | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the localized designation for a master-data entry by kind and id.
|
|
19
|
+
* Falls back to 'deu' if not found in the current locale.
|
|
20
|
+
*/
|
|
21
|
+
designation(kind: MasterDataKind, id: number | string | null | undefined, locale?: Locale): string;
|
|
22
|
+
resolveAnimalCategory(id: number | string | null | undefined, locale?: Locale): string;
|
|
23
|
+
resolveUtilisation(id: number | string | null | undefined, locale?: Locale): string;
|
|
24
|
+
resolveManureProduct(code: string | null | undefined, locale?: Locale): string;
|
|
25
|
+
resolveZoologicalAnimal(code: string | null | undefined, locale?: Locale): string;
|
|
26
|
+
resolveCultivationCategory(code: string | null | undefined, locale?: Locale): string;
|
|
27
|
+
resolveAgronomicCropCategory(code: string | null | undefined, locale?: Locale): string;
|
|
28
|
+
resolveFeedstuffProduct(code: string | null | undefined, locale?: Locale): string;
|
|
29
|
+
resolveCover(id: number | string | null | undefined, locale?: Locale): string;
|
|
30
|
+
resolveMixingFrequency(id: number | string | null | undefined, locale?: Locale): string;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type SuibiVersion = 'v2.0';
|
|
2
|
+
export type SubmissionStatus = 'draft' | 'submitted' | 'final';
|
|
3
|
+
/** Which computation modules are active for this dossier. */
|
|
4
|
+
export interface ComputationModules {
|
|
5
|
+
suisseBilanz: boolean;
|
|
6
|
+
gmf: boolean;
|
|
7
|
+
nh3: boolean;
|
|
8
|
+
impex: boolean;
|
|
9
|
+
linear: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const DEFAULT_COMPUTATION_MODULES: ComputationModules;
|
|
12
|
+
export interface SuibiMetadata {
|
|
13
|
+
title: string;
|
|
14
|
+
suibiVersion: SuibiVersion;
|
|
15
|
+
status: SubmissionStatus;
|
|
16
|
+
modules: ComputationModules;
|
|
17
|
+
}
|
|
18
|
+
export declare const DEFAULT_SUIBI_METADATA: SuibiMetadata;
|