@agridea/suibi-module 0.1.0-preview.8
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 +67 -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 +67 -0
- package/dist/elements/browser/suibi-module.v0.1.0-preview.8.css +1 -0
- package/dist/elements/browser/suibi-module.v0.1.0-preview.8.js +67 -0
- package/dist/elements/browser/suibi-theme-dark.css +1 -0
- package/dist/elements/browser/version.txt +1 -0
- package/dist/types/app/animal-stock/animal-stock-detail.component.d.ts +22 -0
- package/dist/types/app/animal-stock/animal-stock-list.component.d.ts +21 -0
- package/dist/types/app/animal-stock/animal-stock-master-detail.component.d.ts +21 -0
- package/dist/types/app/animal-stock/animal-stock.types.d.ts +69 -0
- package/dist/types/app/app.config.d.ts +2 -0
- package/dist/types/app/app.d.ts +26 -0
- package/dist/types/app/core/data/naebi-data.service.d.ts +232 -0
- package/dist/types/app/core/i18n/i18n.service.d.ts +20 -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/master-data/master-data.service.d.ts +18 -0
- package/dist/types/app/core/navigation/navigation.service.d.ts +53 -0
- package/dist/types/app/core/schemas/index.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/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 +32 -0
- package/dist/types/app/core/validation/validation-errors-panel.d.ts +36 -0
- package/dist/types/app/data-preview.d.ts +7 -0
- package/dist/types/app/header-bar.d.ts +19 -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 +60 -0
- package/dist/types/app/jsonforms/registry/renderers.registry.d.ts +26 -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 +20 -0
- package/dist/types/app/jsonforms/renderers/layout/constraint/constraint-layout.renderer.d.ts +30 -0
- package/dist/types/app/jsonforms/renderers/layout/group/base-group.renderer.d.ts +29 -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/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/welcome-page.d.ts +4 -0
- package/dist/types/public-api.d.ts +4 -0
- package/dist/types/shared/material-icons.d.ts +16 -0
- package/package.json +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:host,suibi-module{color-scheme:dark;--mat-sys-background: #121410;--mat-sys-error: #ffb4ab;--mat-sys-error-container: #93000a;--mat-sys-inverse-on-surface: #2f312d;--mat-sys-inverse-primary: #e722ff;--mat-sys-inverse-surface: #e2e3dc;--mat-sys-on-background: #e2e3dc;--mat-sys-on-error: #690005;--mat-sys-on-error-container: #ffdad6;--mat-sys-on-primary: #013a00;--mat-sys-on-primary-container: #77ff61;--mat-sys-on-primary-fixed: #002200;--mat-sys-on-primary-fixed-variant: #015300;--mat-sys-on-secondary: #263422;--mat-sys-on-secondary-container: #d7e8cd;--mat-sys-on-secondary-fixed: #121f0e;--mat-sys-on-secondary-fixed-variant: #3c4b37;--mat-sys-on-surface: #e2e3dc;--mat-sys-on-surface-variant: #dfe4d7;--mat-sys-on-tertiary: #013a00;--mat-sys-on-tertiary-container: #77ff61;--mat-sys-on-tertiary-fixed: #002200;--mat-sys-on-tertiary-fixed-variant: #015300;--mat-sys-outline: #8d9387;--mat-sys-outline-variant: #43483f;--mat-sys-primary: #02e600;--mat-sys-primary-container: #015300;--mat-sys-primary-fixed: #77ff61;--mat-sys-primary-fixed-dim: #02e600;--mat-sys-scrim: #000000;--mat-sys-secondary: #bbcbb2;--mat-sys-secondary-container: #3c4b37;--mat-sys-secondary-fixed: #d7e8cd;--mat-sys-secondary-fixed-dim: #bbcbb2;--mat-sys-shadow: #000000;--mat-sys-surface: #121410;--mat-sys-surface-bright: #383a35;--mat-sys-surface-container: #1e201c;--mat-sys-surface-container-high: #282b26;--mat-sys-surface-container-highest: #333531;--mat-sys-surface-container-low: #1a1c18;--mat-sys-surface-container-lowest: #0c0f0b;--mat-sys-surface-dim: #121410;--mat-sys-surface-tint: #02e600;--mat-sys-surface-variant: #43483f;--mat-sys-tertiary: #02e600;--mat-sys-tertiary-container: #015300;--mat-sys-tertiary-fixed: #77ff61;--mat-sys-tertiary-fixed-dim: #02e600;--mat-sys-neutral-variant20: #2c3229;--mat-sys-neutral10: #1a1c18;--mat-sys-level0: 0px 0px 0px 0px rgba(0, 0, 0, .2), 0px 0px 0px 0px rgba(0, 0, 0, .14), 0px 0px 0px 0px rgba(0, 0, 0, .12);--mat-sys-level1: 0px 2px 1px -1px rgba(0, 0, 0, .2), 0px 1px 1px 0px rgba(0, 0, 0, .14), 0px 1px 3px 0px rgba(0, 0, 0, .12);--mat-sys-level2: 0px 3px 3px -2px rgba(0, 0, 0, .2), 0px 3px 4px 0px rgba(0, 0, 0, .14), 0px 1px 8px 0px rgba(0, 0, 0, .12);--mat-sys-level3: 0px 3px 5px -1px rgba(0, 0, 0, .2), 0px 6px 10px 0px rgba(0, 0, 0, .14), 0px 1px 18px 0px rgba(0, 0, 0, .12);--mat-sys-level4: 0px 5px 5px -3px rgba(0, 0, 0, .2), 0px 8px 10px 1px rgba(0, 0, 0, .14), 0px 3px 14px 2px rgba(0, 0, 0, .12);--mat-sys-level5: 0px 7px 8px -4px rgba(0, 0, 0, .2), 0px 12px 17px 2px rgba(0, 0, 0, .14), 0px 5px 22px 4px rgba(0, 0, 0, .12);--mat-sys-body-large: 300 1rem / 1.5rem Serif;--mat-sys-body-large-font: Serif;--mat-sys-body-large-line-height: 1.5rem;--mat-sys-body-large-size: 1rem;--mat-sys-body-large-tracking: .031rem;--mat-sys-body-large-weight: 300;--mat-sys-body-medium: 300 .875rem / 1.25rem Serif;--mat-sys-body-medium-font: Serif;--mat-sys-body-medium-line-height: 1.25rem;--mat-sys-body-medium-size: .875rem;--mat-sys-body-medium-tracking: .016rem;--mat-sys-body-medium-weight: 300;--mat-sys-body-small: 300 .75rem / 1rem Serif;--mat-sys-body-small-font: Serif;--mat-sys-body-small-line-height: 1rem;--mat-sys-body-small-size: .75rem;--mat-sys-body-small-tracking: .025rem;--mat-sys-body-small-weight: 300;--mat-sys-display-large: 300 3.562rem / 4rem Serif;--mat-sys-display-large-font: Serif;--mat-sys-display-large-line-height: 4rem;--mat-sys-display-large-size: 3.562rem;--mat-sys-display-large-tracking: -.016rem;--mat-sys-display-large-weight: 300;--mat-sys-display-medium: 300 2.812rem / 3.25rem Serif;--mat-sys-display-medium-font: Serif;--mat-sys-display-medium-line-height: 3.25rem;--mat-sys-display-medium-size: 2.812rem;--mat-sys-display-medium-tracking: 0;--mat-sys-display-medium-weight: 300;--mat-sys-display-small: 300 2.25rem / 2.75rem Serif;--mat-sys-display-small-font: Serif;--mat-sys-display-small-line-height: 2.75rem;--mat-sys-display-small-size: 2.25rem;--mat-sys-display-small-tracking: 0;--mat-sys-display-small-weight: 300;--mat-sys-headline-large: 300 2rem / 2.5rem Serif;--mat-sys-headline-large-font: Serif;--mat-sys-headline-large-line-height: 2.5rem;--mat-sys-headline-large-size: 2rem;--mat-sys-headline-large-tracking: 0;--mat-sys-headline-large-weight: 300;--mat-sys-headline-medium: 300 1.75rem / 2.25rem Serif;--mat-sys-headline-medium-font: Serif;--mat-sys-headline-medium-line-height: 2.25rem;--mat-sys-headline-medium-size: 1.75rem;--mat-sys-headline-medium-tracking: 0;--mat-sys-headline-medium-weight: 300;--mat-sys-headline-small: 300 1.5rem / 2rem Serif;--mat-sys-headline-small-font: Serif;--mat-sys-headline-small-line-height: 2rem;--mat-sys-headline-small-size: 1.5rem;--mat-sys-headline-small-tracking: 0;--mat-sys-headline-small-weight: 300;--mat-sys-label-large: 600 .875rem / 1.25rem Serif;--mat-sys-label-large-font: Serif;--mat-sys-label-large-line-height: 1.25rem;--mat-sys-label-large-size: .875rem;--mat-sys-label-large-tracking: .006rem;--mat-sys-label-large-weight: 600;--mat-sys-label-large-weight-prominent: 800;--mat-sys-label-medium: 600 .75rem / 1rem Serif;--mat-sys-label-medium-font: Serif;--mat-sys-label-medium-line-height: 1rem;--mat-sys-label-medium-size: .75rem;--mat-sys-label-medium-tracking: .031rem;--mat-sys-label-medium-weight: 600;--mat-sys-label-medium-weight-prominent: 800;--mat-sys-label-small: 600 .688rem / 1rem Serif;--mat-sys-label-small-font: Serif;--mat-sys-label-small-line-height: 1rem;--mat-sys-label-small-size: .688rem;--mat-sys-label-small-tracking: .031rem;--mat-sys-label-small-weight: 600;--mat-sys-title-large: 300 1.375rem / 1.75rem Serif;--mat-sys-title-large-font: Serif;--mat-sys-title-large-line-height: 1.75rem;--mat-sys-title-large-size: 1.375rem;--mat-sys-title-large-tracking: 0;--mat-sys-title-large-weight: 300;--mat-sys-title-medium: 600 1rem / 1.5rem Serif;--mat-sys-title-medium-font: Serif;--mat-sys-title-medium-line-height: 1.5rem;--mat-sys-title-medium-size: 1rem;--mat-sys-title-medium-tracking: .009rem;--mat-sys-title-medium-weight: 600;--mat-sys-title-small: 600 .875rem / 1.25rem Serif;--mat-sys-title-small-font: Serif;--mat-sys-title-small-line-height: 1.25rem;--mat-sys-title-small-size: .875rem;--mat-sys-title-small-tracking: .006rem;--mat-sys-title-small-weight: 600;--mat-sys-corner-extra-large: 28px;--mat-sys-corner-extra-large-top: 28px 28px 0 0;--mat-sys-corner-extra-small: 4px;--mat-sys-corner-extra-small-top: 4px 4px 0 0;--mat-sys-corner-full: 9999px;--mat-sys-corner-large: 16px;--mat-sys-corner-large-end: 0 16px 16px 0;--mat-sys-corner-large-start: 16px 0 0 16px;--mat-sys-corner-large-top: 16px 16px 0 0;--mat-sys-corner-medium: 12px;--mat-sys-corner-none: 0;--mat-sys-corner-small: 8px;--mat-sys-dragged-state-layer-opacity: .16;--mat-sys-focus-state-layer-opacity: .12;--mat-sys-hover-state-layer-opacity: .08;--mat-sys-pressed-state-layer-opacity: .12;--mat-sys-surface: #121212;--mat-form-field-filled-container-color: #2a2a2a;--mat-card-elevated-container-color: #1e1e1e;font-family:Roboto Thin,Roboto,Arial,sans-serif;display:block;line-height:1.4;box-sizing:border-box;background:var(--mat-sys-surface, #121212);color:var(--mat-sys-on-surface, #e0e0e0)}*,*:before,*:after{box-sizing:inherit}.suibi-surface{background:var(--mat-sys-surface-container-low, #1e1e1e);border:1px solid var(--mat-sys-outline-variant, #2a2a2a);border-radius:8px;padding:16px}pre{background:#1d1f21;color:#c5c8c6;padding:8px 16px;border-radius:4px}:host .mat-mdc-form-field-error,suibi-module .mat-mdc-form-field-error{color:#e72200}.group-layout.mat-mdc-card-outlined{border:0;--mdc-outlined-card-outline-color: transparent;box-shadow:0 3px 1px -2px #0003,0 2px 2px #00000024,0 1px 5px #0000001f;border-radius:8px}.horizontal-layout>div:has([style*="display: none"]){display:none!important}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0-preview.8 c276491
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { EventEmitter, Signal } from '@angular/core';
|
|
2
|
+
import { JsonSchema, UISchemaElement } from '@jsonforms/core';
|
|
3
|
+
import { AnimalStockRow } from './animal-stock.types';
|
|
4
|
+
import { ErrorObject } from 'ajv';
|
|
5
|
+
export declare class AnimalStockDetailComponent {
|
|
6
|
+
private readonly i18n;
|
|
7
|
+
row: Signal<AnimalStockRow | null>;
|
|
8
|
+
index: Signal<number | null>;
|
|
9
|
+
rowChange: EventEmitter<AnimalStockRow>;
|
|
10
|
+
close: EventEmitter<void>;
|
|
11
|
+
itemSchema: Signal<JsonSchema>;
|
|
12
|
+
private readonly baseUi;
|
|
13
|
+
localizedUi: Signal<UISchemaElement>;
|
|
14
|
+
jsonFormsData: Signal<(AnimalStockRow & import("../core/schemas/ui-helper-registry").UiHelperDefinitions) | null>;
|
|
15
|
+
readonly renderers: {
|
|
16
|
+
tester: import("@jsonforms/core").RankedTester;
|
|
17
|
+
renderer: any;
|
|
18
|
+
}[];
|
|
19
|
+
readonly suibiAjv: import("ajv").Ajv;
|
|
20
|
+
onDataChange(newData: any): void;
|
|
21
|
+
onValidationErrors(_errors: ErrorObject[] | null | undefined): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { EventEmitter, Signal } from '@angular/core';
|
|
2
|
+
import { MatTable } from '@angular/material/table';
|
|
3
|
+
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
4
|
+
import { AnimalStockRow } from './animal-stock.types';
|
|
5
|
+
export declare class AnimalStockListComponent {
|
|
6
|
+
private readonly masterData;
|
|
7
|
+
table: MatTable<AnimalStockRow>;
|
|
8
|
+
rows: Signal<AnimalStockRow[]>;
|
|
9
|
+
select: EventEmitter<number>;
|
|
10
|
+
add: EventEmitter<void>;
|
|
11
|
+
delete: EventEmitter<number>;
|
|
12
|
+
reorder: EventEmitter<{
|
|
13
|
+
previousIndex: number;
|
|
14
|
+
currentIndex: number;
|
|
15
|
+
}>;
|
|
16
|
+
displayedColumns: string[];
|
|
17
|
+
onDelete(index: number, event: Event): void;
|
|
18
|
+
drop(event: CdkDragDrop<AnimalStockRow[]>): void;
|
|
19
|
+
resolveAnimalCategory(id: unknown): string;
|
|
20
|
+
resolveUtilisation(id: unknown): string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AnimalStockRow } from './animal-stock.types';
|
|
2
|
+
export declare class AnimalStockMasterDetailComponent {
|
|
3
|
+
private readonly dataSvc;
|
|
4
|
+
private readonly navigationSvc;
|
|
5
|
+
private readonly rootData;
|
|
6
|
+
constructor();
|
|
7
|
+
readonly rows: import("@angular/core").Signal<AnimalStockRow[]>;
|
|
8
|
+
readonly selectedIndex: import("@angular/core").WritableSignal<number | null>;
|
|
9
|
+
readonly detailData: import("@angular/core").Signal<any>;
|
|
10
|
+
openDetail(index: number): void;
|
|
11
|
+
closeDetail(): void;
|
|
12
|
+
onRowClick(_row: AnimalStockRow, index: number): void;
|
|
13
|
+
addRow(): void;
|
|
14
|
+
deleteRow(index: number): void;
|
|
15
|
+
reorderRow(event: {
|
|
16
|
+
previousIndex: number;
|
|
17
|
+
currentIndex: number;
|
|
18
|
+
}): void;
|
|
19
|
+
onDetailChange(newData: any): void;
|
|
20
|
+
private patchRows;
|
|
21
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface FeedingRoutineItem {
|
|
2
|
+
typeOfFeedstuffProduct?: string;
|
|
3
|
+
transactionUnit?: string;
|
|
4
|
+
quantity?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface SeasonalFeeding {
|
|
7
|
+
feedingRoutine?: FeedingRoutineItem[];
|
|
8
|
+
dailyConcentratedFeedstuff?: {
|
|
9
|
+
quantity?: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface Feeding {
|
|
13
|
+
fodderConsumption?: number;
|
|
14
|
+
concentratedFeedstuffConsumption?: number;
|
|
15
|
+
winterFeeding?: SeasonalFeeding;
|
|
16
|
+
summerFeeding?: SeasonalFeeding;
|
|
17
|
+
}
|
|
18
|
+
export interface Stall {
|
|
19
|
+
stableSystem?: number;
|
|
20
|
+
stableCapacity?: number;
|
|
21
|
+
stableVentilationType?: number;
|
|
22
|
+
stableAirPurification?: number;
|
|
23
|
+
hasStableDeepLitter?: boolean;
|
|
24
|
+
hasStableManureBeltDrying?: boolean;
|
|
25
|
+
stableManureRemovalFrequency?: number;
|
|
26
|
+
stableWaterSupply?: number;
|
|
27
|
+
hasStableManureAndSlurryProduction?: boolean;
|
|
28
|
+
hasStableFeedingStationElevated?: boolean;
|
|
29
|
+
hasStableFloorSlopedUrineDrainage?: boolean;
|
|
30
|
+
hasYard?: boolean;
|
|
31
|
+
yardFeeding?: number;
|
|
32
|
+
yardFloorType?: number;
|
|
33
|
+
yardDays?: number;
|
|
34
|
+
yardHoursPerDay?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface Pasture {
|
|
37
|
+
days?: number;
|
|
38
|
+
hoursPerDay?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface FormOfDetention {
|
|
41
|
+
hasGrazing?: boolean;
|
|
42
|
+
pasture?: Pasture;
|
|
43
|
+
stall?: Stall;
|
|
44
|
+
}
|
|
45
|
+
export interface LivestockReport {
|
|
46
|
+
durationSumTotalNutrientBalance?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface SelfReportedLivestock {
|
|
49
|
+
averageQuantity?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface LinearCorrection {
|
|
52
|
+
duration?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface AnimalStockRow {
|
|
55
|
+
order?: number | string;
|
|
56
|
+
animalCategoryPRIF?: number;
|
|
57
|
+
livestockReportViaAnimalTracingOriginal?: LivestockReport;
|
|
58
|
+
livestockReportedViaAnimalTracingFinal?: LivestockReport;
|
|
59
|
+
selfReportedLivestock?: SelfReportedLivestock;
|
|
60
|
+
durationCorrectionQuantity?: number;
|
|
61
|
+
durationCorrectionDays?: number;
|
|
62
|
+
hasImpexDerivedExcretion?: boolean;
|
|
63
|
+
hasLinearCorrectionDerivedExcretion?: boolean;
|
|
64
|
+
linearCorrection?: LinearCorrection;
|
|
65
|
+
utilisation?: number;
|
|
66
|
+
formOfDetention?: FormOfDetention;
|
|
67
|
+
feeding?: Feeding;
|
|
68
|
+
[key: string]: unknown;
|
|
69
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Locale } from './core/i18n/i18n.service';
|
|
2
|
+
import { EnrichedValidationError } from './core/validation/global-validation.service';
|
|
3
|
+
import { PageId } from './core/navigation/navigation.service';
|
|
4
|
+
import { ErrorObject } from 'ajv';
|
|
5
|
+
export declare class App {
|
|
6
|
+
localeInput: import("@angular/core").InputSignal<Locale>;
|
|
7
|
+
themeSrc: import("@angular/core").InputSignal<string | null>;
|
|
8
|
+
pageInput: import("@angular/core").InputSignal<PageId>;
|
|
9
|
+
naebiDataInput: import("@angular/core").InputSignal<any>;
|
|
10
|
+
private readonly i18n;
|
|
11
|
+
private readonly hostEl;
|
|
12
|
+
private readonly destroyRef;
|
|
13
|
+
private readonly naebi;
|
|
14
|
+
private readonly globalValidation;
|
|
15
|
+
private readonly navigationSvc;
|
|
16
|
+
private readonly isCustomElement;
|
|
17
|
+
readonly locale: import("@angular/core").Signal<Locale>;
|
|
18
|
+
readonly validationErrors: import("@angular/core").Signal<EnrichedValidationError[]>;
|
|
19
|
+
constructor();
|
|
20
|
+
readonly currentPage: import("@angular/core").WritableSignal<PageId>;
|
|
21
|
+
private lastPageInput;
|
|
22
|
+
private readonly syncPageEffect;
|
|
23
|
+
go(page: PageId): void;
|
|
24
|
+
setLocale(locale: Locale): void;
|
|
25
|
+
onValidationErrorSelected(error: ErrorObject): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import naebiExample from '../../../../assets/example-data/example-naebi-data.json';
|
|
2
|
+
export type NaebiData = typeof naebiExample;
|
|
3
|
+
/**
|
|
4
|
+
* Calculation mode determines which validation rules and features are active.
|
|
5
|
+
*/
|
|
6
|
+
export declare enum CalculationMode {
|
|
7
|
+
SuiBi = "SuiBi",// SuisseBilanz (standard)
|
|
8
|
+
ExBi = "ExBi"
|
|
9
|
+
}
|
|
10
|
+
export declare class NaebiDataService {
|
|
11
|
+
private readonly _data;
|
|
12
|
+
readonly data: import("@angular/core").Signal<{
|
|
13
|
+
nutrientCycle: {
|
|
14
|
+
animalStock: {
|
|
15
|
+
order: string;
|
|
16
|
+
animalCategoryPRIF: number;
|
|
17
|
+
selfReportedLivestock: {
|
|
18
|
+
averageQuantity: number;
|
|
19
|
+
};
|
|
20
|
+
durationCorrectionQuantity: number;
|
|
21
|
+
durationCorrectionDays: number;
|
|
22
|
+
utilisation: number;
|
|
23
|
+
formOfDetention: {
|
|
24
|
+
hasGrazing: boolean;
|
|
25
|
+
pasture: {
|
|
26
|
+
days: number;
|
|
27
|
+
hoursPerDay: number;
|
|
28
|
+
};
|
|
29
|
+
stall: {
|
|
30
|
+
stableSystem: number;
|
|
31
|
+
stableCapacity: number;
|
|
32
|
+
stableVentilationType: number;
|
|
33
|
+
stableAirPurification: 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
|
+
yardFeeding: number;
|
|
43
|
+
yardFloorType: number;
|
|
44
|
+
yardDays: number;
|
|
45
|
+
yardHoursPerDay: number;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
hasImpexDerivedExcretion: boolean;
|
|
49
|
+
hasLinearCorrectionDerivedExcretion: boolean;
|
|
50
|
+
feeding: {
|
|
51
|
+
fodderConsumption: number;
|
|
52
|
+
concentratedFeedstuffConsumption: number;
|
|
53
|
+
winterFeeding: {
|
|
54
|
+
feedingRoutine: {
|
|
55
|
+
typeOfFeedstuffProduct: string;
|
|
56
|
+
transactionUnit: string;
|
|
57
|
+
quantity: number;
|
|
58
|
+
}[];
|
|
59
|
+
dailyConcentratedFeedstuff: {
|
|
60
|
+
quantity: number;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
summerFeeding: {
|
|
64
|
+
feedingRoutine: {
|
|
65
|
+
typeOfFeedstuffProduct: string;
|
|
66
|
+
transactionUnit: string;
|
|
67
|
+
quantity: number;
|
|
68
|
+
}[];
|
|
69
|
+
dailyConcentratedFeedstuff: {
|
|
70
|
+
quantity: number;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}[];
|
|
75
|
+
storage: {
|
|
76
|
+
stableStrawLitter: number;
|
|
77
|
+
manureSupplyProportionStored: number;
|
|
78
|
+
slurrySupplyProportionStored: number;
|
|
79
|
+
createFacilitySpecificManureProduct: boolean;
|
|
80
|
+
createFacilitySpecificSlurryProduct: boolean;
|
|
81
|
+
dilutionRatio: number;
|
|
82
|
+
manurePit: {
|
|
83
|
+
cover: number;
|
|
84
|
+
manureFromAnimalStockStored: {
|
|
85
|
+
manureDerivation: string;
|
|
86
|
+
proportionStored: number;
|
|
87
|
+
}[];
|
|
88
|
+
}[];
|
|
89
|
+
slurryTank: {
|
|
90
|
+
volumeInM3: number;
|
|
91
|
+
depthInM: number;
|
|
92
|
+
cover: number;
|
|
93
|
+
mixingFrequency: number;
|
|
94
|
+
manureDerivation: string[];
|
|
95
|
+
}[];
|
|
96
|
+
};
|
|
97
|
+
farmManureTrading: {
|
|
98
|
+
supply: {
|
|
99
|
+
quantity: number;
|
|
100
|
+
typeOfManureRecyclingProduct: string;
|
|
101
|
+
transactionUnit: string;
|
|
102
|
+
ingredient: {
|
|
103
|
+
quantity: number;
|
|
104
|
+
molecularFormula: string;
|
|
105
|
+
unit: string;
|
|
106
|
+
}[];
|
|
107
|
+
}[];
|
|
108
|
+
dispense: {
|
|
109
|
+
quantity: number;
|
|
110
|
+
typeOfManureRecyclingProduct: string;
|
|
111
|
+
transactionUnit: string;
|
|
112
|
+
manureDerivation: {
|
|
113
|
+
zoologicalAnimal: string;
|
|
114
|
+
percentageAllocation: number;
|
|
115
|
+
}[];
|
|
116
|
+
}[];
|
|
117
|
+
};
|
|
118
|
+
fieldSpreading: {
|
|
119
|
+
soilPh: number;
|
|
120
|
+
slurry: {
|
|
121
|
+
quantity: number;
|
|
122
|
+
dilutionRatio: number;
|
|
123
|
+
otherApplicationTechnologies: {
|
|
124
|
+
applicationTechnologyType: number;
|
|
125
|
+
proportionOfArea: number;
|
|
126
|
+
}[];
|
|
127
|
+
applicationDuringWarmDays: number;
|
|
128
|
+
proportionAppliedAfter6PM: number;
|
|
129
|
+
dragHoseAreaSize: number;
|
|
130
|
+
};
|
|
131
|
+
manure: {
|
|
132
|
+
applicationIncorporationTime: number;
|
|
133
|
+
proportionAppliedSummerMonths: number;
|
|
134
|
+
};
|
|
135
|
+
fertiliser: {
|
|
136
|
+
fertiliserProductCategory: string;
|
|
137
|
+
quantity: number;
|
|
138
|
+
transactionUnit: string;
|
|
139
|
+
ingredient: {
|
|
140
|
+
molecularFormula: string;
|
|
141
|
+
quantity: number;
|
|
142
|
+
unit: string;
|
|
143
|
+
}[];
|
|
144
|
+
}[];
|
|
145
|
+
recycling: {
|
|
146
|
+
typeOfManureRecyclingProduct: string;
|
|
147
|
+
quantity: number;
|
|
148
|
+
transactionUnit: string;
|
|
149
|
+
ingredient: {
|
|
150
|
+
molecularFormula: string;
|
|
151
|
+
quantity: number;
|
|
152
|
+
unit: string;
|
|
153
|
+
}[];
|
|
154
|
+
}[];
|
|
155
|
+
};
|
|
156
|
+
lifetimePerformance: {
|
|
157
|
+
dailyGain: number;
|
|
158
|
+
liveWeight: number;
|
|
159
|
+
milkProductionReport: number;
|
|
160
|
+
};
|
|
161
|
+
fodder: {
|
|
162
|
+
trading: {
|
|
163
|
+
supply: {
|
|
164
|
+
typeOfFeedstuffProduct: string;
|
|
165
|
+
quantity: number;
|
|
166
|
+
transactionUnit: string;
|
|
167
|
+
ingredient: {
|
|
168
|
+
quantity: number;
|
|
169
|
+
molecularFormula: string;
|
|
170
|
+
unit: string;
|
|
171
|
+
}[];
|
|
172
|
+
}[];
|
|
173
|
+
};
|
|
174
|
+
cropFromNonFodderCropland: {
|
|
175
|
+
typeOfFeedstuffProduct: string;
|
|
176
|
+
quantity: number;
|
|
177
|
+
transactionUnit: string;
|
|
178
|
+
ingredient: {
|
|
179
|
+
quantity: number;
|
|
180
|
+
molecularFormula: string;
|
|
181
|
+
unit: string;
|
|
182
|
+
}[];
|
|
183
|
+
}[];
|
|
184
|
+
proportionStorageLoss: number;
|
|
185
|
+
totalBalanceErrorMargin: number;
|
|
186
|
+
};
|
|
187
|
+
fieldCultivation: {
|
|
188
|
+
fodderCropland: ({
|
|
189
|
+
agronomicCropCategory: string;
|
|
190
|
+
isMainCrop: boolean;
|
|
191
|
+
areaSize: number;
|
|
192
|
+
calculateYieldThroughFodderBalance: boolean;
|
|
193
|
+
yieldPerSquareMeasure?: undefined;
|
|
194
|
+
} | {
|
|
195
|
+
agronomicCropCategory: string;
|
|
196
|
+
isMainCrop: boolean;
|
|
197
|
+
areaSize: number;
|
|
198
|
+
yieldPerSquareMeasure: number;
|
|
199
|
+
calculateYieldThroughFodderBalance?: undefined;
|
|
200
|
+
})[];
|
|
201
|
+
arableLand: {
|
|
202
|
+
agronomicCropCategory: string;
|
|
203
|
+
isMainCrop: boolean;
|
|
204
|
+
areaSize: number;
|
|
205
|
+
yieldPerSquareMeasure: number;
|
|
206
|
+
}[];
|
|
207
|
+
special: {
|
|
208
|
+
agronomicCropCategory: string;
|
|
209
|
+
userSpecificPlantName: string;
|
|
210
|
+
isMainCrop: boolean;
|
|
211
|
+
areaSize: number;
|
|
212
|
+
yieldPerSquareMeasure: number;
|
|
213
|
+
}[];
|
|
214
|
+
};
|
|
215
|
+
generateReport: boolean;
|
|
216
|
+
};
|
|
217
|
+
}>;
|
|
218
|
+
private readonly _calculationMode;
|
|
219
|
+
readonly calculationMode: import("@angular/core").Signal<CalculationMode>;
|
|
220
|
+
/**
|
|
221
|
+
* Set new data value; accepts plain object (already parsed) matching NaebiData shape.
|
|
222
|
+
* Silent no-op if value is structurally equal reference to avoid unnecessary updates (cheap ref check only).
|
|
223
|
+
*/
|
|
224
|
+
setData(value: NaebiData): void;
|
|
225
|
+
/**
|
|
226
|
+
* Set calculation mode (SuiBi or ExBi).
|
|
227
|
+
* Can affect which validation rules are active or which features are enabled.
|
|
228
|
+
*/
|
|
229
|
+
setCalculationMode(mode: CalculationMode): void;
|
|
230
|
+
/** Reset to bundled example */
|
|
231
|
+
reset(): void;
|
|
232
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { PipeTransform, Signal } from '@angular/core';
|
|
2
|
+
export type Locale = 'en' | 'de';
|
|
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
|
+
}>;
|
|
12
|
+
setLocale(locale: Locale): void;
|
|
13
|
+
t(key: string, defaultMessage?: string): string;
|
|
14
|
+
}
|
|
15
|
+
export declare class TranslatePipe implements PipeTransform {
|
|
16
|
+
private readonly i18n;
|
|
17
|
+
private readonly cache;
|
|
18
|
+
constructor(i18n: I18nService);
|
|
19
|
+
transform(key: string, defaultMessage?: string): Signal<string>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Locale } from '../i18n/i18n.service';
|
|
2
|
+
declare const MASTER_DATA: Record<string, any[]>;
|
|
3
|
+
export type MasterDataKind = keyof typeof MASTER_DATA;
|
|
4
|
+
export declare class MasterDataService {
|
|
5
|
+
private readonly i18n;
|
|
6
|
+
private readonly locale;
|
|
7
|
+
private readonly indices;
|
|
8
|
+
/** Public lookup of raw master-data entry (typed as any for now). */
|
|
9
|
+
entry<T = any>(kind: MasterDataKind, id: number | string | null | undefined): T | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Returns the localized designation for a master-data entry by kind and id.
|
|
12
|
+
* Falls back to 'deu' if not found in the current locale.
|
|
13
|
+
*/
|
|
14
|
+
designation(kind: MasterDataKind, id: number | string | null | undefined, locale?: Locale): string;
|
|
15
|
+
resolveAnimalCategory(id: number | string | null | undefined, locale?: Locale): string;
|
|
16
|
+
resolveUtilisation(id: number | string | null | undefined, locale?: Locale): string;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type PageId = 'welcome' | 'animal_stock' | 'data_preview' | 'storage' | 'field_spreading' | 'farm_manure_trading';
|
|
2
|
+
export type AnimalStockCategory = 'base' | 'formOfDetention' | 'feeding';
|
|
3
|
+
/**
|
|
4
|
+
* NavigationService
|
|
5
|
+
* Global reactive store for application routing and deep-link state.
|
|
6
|
+
* Follows Pinia/Vuex pattern: signals = state, computed = getters, methods = actions.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* - Track current page and page-specific context (e.g., selected entity index, active tab)
|
|
10
|
+
* - Provide navigation actions that update state atomically
|
|
11
|
+
* - Used by validation system to deep-link users to fields requiring correction
|
|
12
|
+
*
|
|
13
|
+
* Pattern for adding new pages:
|
|
14
|
+
* 1. Add page ID to PageId type
|
|
15
|
+
* 2. Add page-specific state signals (e.g., selectedStorageIndex)
|
|
16
|
+
* 3. Add navigation actions (e.g., navigateToStorageDetail)
|
|
17
|
+
* 4. Update reset logic in resetPageContext()
|
|
18
|
+
*/
|
|
19
|
+
export declare class NavigationService {
|
|
20
|
+
/** Current active page */
|
|
21
|
+
readonly currentPage: import("@angular/core").WritableSignal<PageId>;
|
|
22
|
+
/** Selected animal stock entry index (null = list view) */
|
|
23
|
+
readonly selectedAnimalStockIndex: import("@angular/core").WritableSignal<number | null>;
|
|
24
|
+
/** Selected category (tab) within animal stock detail */
|
|
25
|
+
readonly selectedAnimalStockCategory: import("@angular/core").WritableSignal<AnimalStockCategory>;
|
|
26
|
+
/** True if currently viewing animal stock detail (not list) */
|
|
27
|
+
readonly isAnimalStockDetailView: import("@angular/core").Signal<boolean>;
|
|
28
|
+
/** True if currently on animal stock page (list or detail) */
|
|
29
|
+
readonly isAnimalStockPage: import("@angular/core").Signal<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Navigate to a top-level page. Resets page-specific context.
|
|
32
|
+
* Use this for simple page switches (e.g., nav menu clicks).
|
|
33
|
+
*/
|
|
34
|
+
navigateToPage(page: PageId): void;
|
|
35
|
+
/**
|
|
36
|
+
* Navigate to animal stock list view (no entry selected).
|
|
37
|
+
*/
|
|
38
|
+
navigateToAnimalStockList(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Navigate to animal stock detail view (specific entry + optional tab).
|
|
41
|
+
* Used by validation error navigation and internal routing.
|
|
42
|
+
*/
|
|
43
|
+
navigateToAnimalStockDetail(index: number, category?: AnimalStockCategory): void;
|
|
44
|
+
/**
|
|
45
|
+
* Set active category/tab within animal stock detail (without changing page/entry).
|
|
46
|
+
*/
|
|
47
|
+
setAnimalStockCategory(category: AnimalStockCategory): void;
|
|
48
|
+
/**
|
|
49
|
+
* Reset page-specific context when navigating away.
|
|
50
|
+
* Prevents stale state (e.g., old selected index) from affecting new page.
|
|
51
|
+
*/
|
|
52
|
+
private resetPageContext;
|
|
53
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema utilities for managing UI-only helper fields in JSONForms components.
|
|
3
|
+
*
|
|
4
|
+
* This module provides centralized schema merging and helper field filtering to maintain
|
|
5
|
+
* clean separation between domain schemas (nutrient balance calculation model) and
|
|
6
|
+
* UI-only helper fields that drive conditional rendering logic.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { mergeSchemas, getUiHelperFields, stripUiHelpers } from '@core/schemas';
|
|
11
|
+
* import globalUiExtensions from '@core/schemas/ui-schema-extensions.json';
|
|
12
|
+
*
|
|
13
|
+
* const helpers = getUiHelperFields(globalUiExtensions);
|
|
14
|
+
* const merged = mergeSchemas(domainSchema, globalUiExtensions);
|
|
15
|
+
* const clean = stripUiHelpers(formData, helpers);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export { mergeSchemas, getUiHelperFields, stripUiHelpers } from './schema-merge.util';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { JsonSchema } from '@jsonforms/core';
|
|
2
|
+
/**
|
|
3
|
+
* Merges a base domain schema with UI-only extension properties at runtime.
|
|
4
|
+
* Extensions are deep-cloned into the base schema to avoid mutation.
|
|
5
|
+
*
|
|
6
|
+
* @param base - Domain schema (e.g., nutrient balance data model)
|
|
7
|
+
* @param extensions - UI helper schema with `x-ui-helper: true` fields
|
|
8
|
+
* @returns Merged schema suitable for JSONForms consumption
|
|
9
|
+
*/
|
|
10
|
+
export declare function mergeSchemas(base: JsonSchema, extensions: JsonSchema): JsonSchema;
|
|
11
|
+
/**
|
|
12
|
+
* Extracts field names marked as UI helpers from a schema.
|
|
13
|
+
* Scans properties for `"x-ui-helper": true` metadata.
|
|
14
|
+
*
|
|
15
|
+
* @param schema - Schema to scan (typically UI extensions schema)
|
|
16
|
+
* @returns Set of field names that should be filtered from persisted data
|
|
17
|
+
*/
|
|
18
|
+
export declare function getUiHelperFields(schema: JsonSchema): Set<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Removes all UI helper fields from a data object.
|
|
21
|
+
* Mutates the input object (use with caution; prefer spreading first).
|
|
22
|
+
*
|
|
23
|
+
* @param data - Data object to clean (typically form state)
|
|
24
|
+
* @param helperFields - Set of field names to remove
|
|
25
|
+
*/
|
|
26
|
+
export declare function stripUiHelpers<T extends Record<string, any>>(data: T, helperFields: Set<string>): Omit<T, string>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface UiHelperDefinitions {
|
|
2
|
+
durationSourceType?: 'tvd-original' | 'tvd-final' | 'self-reported';
|
|
3
|
+
quantity_correction?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface UiHelperConfig<K extends keyof UiHelperDefinitions = keyof UiHelperDefinitions> {
|
|
6
|
+
key: K;
|
|
7
|
+
default: () => UiHelperDefinitions[K] | undefined;
|
|
8
|
+
derive?: (domain: any) => UiHelperDefinitions[K] | undefined;
|
|
9
|
+
readonly?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function getHelperKeys(): (keyof UiHelperDefinitions)[];
|
|
12
|
+
export declare function deriveHelpers(domain: any): Partial<UiHelperDefinitions>;
|
|
13
|
+
export declare function augmentData<T extends object>(domain: T): T & UiHelperDefinitions;
|
|
14
|
+
export declare function stripHelpers<T extends object>(data: T): T;
|
|
15
|
+
export declare function prepareJsonFormsData<T extends object>(domain: T | null | undefined): (T & UiHelperDefinitions) | null;
|
|
16
|
+
export declare function sanitizeJsonFormsData<T extends object>(formData: T): T;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom AJV instance with capability-based validation keywords.
|
|
3
|
+
* Focus: keep declarative business rules in JSON Schema while deriving dynamic
|
|
4
|
+
* constraints from static master data (no runtime HTTP calls).
|
|
5
|
+
*/
|
|
6
|
+
import Ajv from 'ajv';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a custom AJV instance with domain-specific validation keywords.
|
|
9
|
+
*
|
|
10
|
+
* Custom keywords:
|
|
11
|
+
* - `permittedStableSystem`: Validates stable system against animal category constraints
|
|
12
|
+
*
|
|
13
|
+
* @param options - Additional AJV options to merge with defaults
|
|
14
|
+
*/
|
|
15
|
+
export declare function createSuibiAjv(options?: Record<string, any>): Ajv;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic capability derivation from master data.
|
|
3
|
+
* Computes permitted stable systems, utilisations, etc. based on animal categories.
|
|
4
|
+
*
|
|
5
|
+
* All master data is embedded statically at compile time - no runtime HTTP calls.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Derives permitted stable systems (husbandry type IDs) for a given animal category.
|
|
9
|
+
*
|
|
10
|
+
* @param animalCategoryPRIF - The PRIF animal category ID
|
|
11
|
+
* @returns Array of permitted husbandry type IDs (stable systems)
|
|
12
|
+
*/
|
|
13
|
+
export declare function derivePermittedStableSystems(animalCategoryPRIF: number | null | undefined): number[];
|
|
14
|
+
/**
|
|
15
|
+
* Pre-computed map for performance (memoized at module load).
|
|
16
|
+
* Maps animalCategoryPRIF -> array of permitted stableSystem values.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PERMITTED_STABLE_SYSTEMS: Record<number, number[]>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error message formatter for JSON Schema validation.
|
|
3
|
+
* Maps AJV error objects to i18n keys with parameters.
|
|
4
|
+
*
|
|
5
|
+
* Since validation is handled by AJV/JSON Schema, we don't need a custom engine.
|
|
6
|
+
* We just need to format error messages for better UX.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Format an AJV error object for display, mapping to i18n keys where applicable.
|
|
10
|
+
*
|
|
11
|
+
* @param error AJV error object
|
|
12
|
+
* @param translateFn Translation function (key, defaultMessage) => string
|
|
13
|
+
* @returns Formatted error message
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatValidationError(error: any, translateFn: (key: string, defaultMessage?: string) => string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Format multiple AJV errors for display.
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatValidationErrors(errors: any[], translateFn: (key: string, defaultMessage?: string) => string): string[];
|