@auditcore/ui-core 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1326 -0
  3. package/dist/account/camera.d.ts +8 -0
  4. package/dist/account/controller.d.ts +30 -0
  5. package/dist/account/index.d.ts +7 -0
  6. package/dist/account/messages.d.ts +2 -0
  7. package/dist/account/port.d.ts +10 -0
  8. package/dist/account/presentation.d.ts +9 -0
  9. package/dist/account/types.d.ts +42 -0
  10. package/dist/account/view.d.ts +12 -0
  11. package/dist/attributes/controller.d.ts +26 -0
  12. package/dist/attributes/index.d.ts +5 -0
  13. package/dist/attributes/messages.d.ts +3 -0
  14. package/dist/attributes/port.d.ts +4 -0
  15. package/dist/attributes/types.d.ts +60 -0
  16. package/dist/attributes/view.d.ts +49 -0
  17. package/dist/base/icons.d.ts +38 -0
  18. package/dist/base/index.d.ts +3 -0
  19. package/dist/base/types.d.ts +3 -0
  20. package/dist/batchchecks/controller.d.ts +60 -0
  21. package/dist/batchchecks/index.d.ts +7 -0
  22. package/dist/batchchecks/messages.d.ts +3 -0
  23. package/dist/batchchecks/model.d.ts +38 -0
  24. package/dist/batchchecks/port.d.ts +6 -0
  25. package/dist/batchchecks/rest-port.d.ts +4 -0
  26. package/dist/batchchecks/types.d.ts +121 -0
  27. package/dist/batchchecks/view.d.ts +58 -0
  28. package/dist/benford/chart.d.ts +49 -0
  29. package/dist/benford/controller.d.ts +48 -0
  30. package/dist/benford/index.d.ts +7 -0
  31. package/dist/benford/messages.d.ts +3 -0
  32. package/dist/benford/model.d.ts +32 -0
  33. package/dist/benford/rest-port.d.ts +4 -0
  34. package/dist/benford/types.d.ts +144 -0
  35. package/dist/benford/view.d.ts +45 -0
  36. package/dist/dataprotection/dsfa.d.ts +55 -0
  37. package/dist/dataprotection/dsfaView.d.ts +45 -0
  38. package/dist/dataprotection/exporters.d.ts +33 -0
  39. package/dist/dataprotection/index.d.ts +10 -0
  40. package/dist/dataprotection/messages.d.ts +5 -0
  41. package/dist/dataprotection/registerView.d.ts +47 -0
  42. package/dist/dataprotection/requests.d.ts +16 -0
  43. package/dist/dataprotection/rest-port.d.ts +4 -0
  44. package/dist/dataprotection/types.d.ts +291 -0
  45. package/dist/dataprotection/vvt.d.ts +69 -0
  46. package/dist/dbkanban/controller.d.ts +54 -0
  47. package/dist/dbkanban/index.d.ts +3 -0
  48. package/dist/dbkanban/messages.d.ts +5 -0
  49. package/dist/dbkanban/view.d.ts +39 -0
  50. package/dist/documents/controller.d.ts +63 -0
  51. package/dist/documents/form.d.ts +52 -0
  52. package/dist/documents/importing.d.ts +12 -0
  53. package/dist/documents/index.d.ts +6 -0
  54. package/dist/documents/list.d.ts +21 -0
  55. package/dist/documents/messages.d.ts +8 -0
  56. package/dist/documents/view.d.ts +36 -0
  57. package/dist/download.d.ts +14 -0
  58. package/dist/extraction/controller.d.ts +34 -0
  59. package/dist/extraction/index.d.ts +5 -0
  60. package/dist/extraction/messages.d.ts +3 -0
  61. package/dist/extraction/rest-port.d.ts +4 -0
  62. package/dist/extraction/types.d.ts +115 -0
  63. package/dist/extraction/view.d.ts +35 -0
  64. package/dist/extrapolation/controller-subsample.d.ts +20 -0
  65. package/dist/extrapolation/controller.d.ts +72 -0
  66. package/dist/extrapolation/index.d.ts +9 -0
  67. package/dist/extrapolation/messages.d.ts +3 -0
  68. package/dist/extrapolation/model-design.d.ts +28 -0
  69. package/dist/extrapolation/model-subsample.d.ts +40 -0
  70. package/dist/extrapolation/model.d.ts +92 -0
  71. package/dist/extrapolation/rest-port.d.ts +4 -0
  72. package/dist/extrapolation/types.d.ts +255 -0
  73. package/dist/extrapolation/view-details.d.ts +46 -0
  74. package/dist/extrapolation/view.d.ts +50 -0
  75. package/dist/focus.d.ts +10 -0
  76. package/dist/geo/controller.d.ts +87 -0
  77. package/dist/geo/index.d.ts +6 -0
  78. package/dist/geo/mapView.d.ts +30 -0
  79. package/dist/geo/messages.d.ts +3 -0
  80. package/dist/geo/model.d.ts +43 -0
  81. package/dist/geo/rest-port.d.ts +12 -0
  82. package/dist/geo/types.d.ts +195 -0
  83. package/dist/i18n.d.ts +29 -0
  84. package/dist/identifiers/controller.d.ts +63 -0
  85. package/dist/identifiers/index.d.ts +5 -0
  86. package/dist/identifiers/messages.d.ts +3 -0
  87. package/dist/identifiers/model.d.ts +87 -0
  88. package/dist/identifiers/rest-port.d.ts +4 -0
  89. package/dist/identifiers/types.d.ts +101 -0
  90. package/dist/index.d.ts +33 -0
  91. package/dist/index.js +10676 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/kanban/index.d.ts +2 -0
  94. package/dist/kanban/messages.d.ts +6 -0
  95. package/dist/messages.d.ts +2 -0
  96. package/dist/reporting/controller.d.ts +46 -0
  97. package/dist/reporting/index.d.ts +5 -0
  98. package/dist/reporting/messages.d.ts +3 -0
  99. package/dist/reporting/rest-port.d.ts +4 -0
  100. package/dist/reporting/types.d.ts +72 -0
  101. package/dist/reporting/view.d.ts +12 -0
  102. package/dist/reporttemplates/controller.d.ts +46 -0
  103. package/dist/reporttemplates/index.d.ts +5 -0
  104. package/dist/reporttemplates/messages.d.ts +3 -0
  105. package/dist/reporttemplates/port.d.ts +4 -0
  106. package/dist/reporttemplates/types.d.ts +92 -0
  107. package/dist/reporttemplates/view.d.ts +27 -0
  108. package/dist/risk/controller.d.ts +54 -0
  109. package/dist/risk/format.d.ts +13 -0
  110. package/dist/risk/index.d.ts +7 -0
  111. package/dist/risk/labels.d.ts +9 -0
  112. package/dist/risk/messages.d.ts +3 -0
  113. package/dist/risk/port.d.ts +41 -0
  114. package/dist/risk/state.d.ts +61 -0
  115. package/dist/risk/types.d.ts +107 -0
  116. package/dist/runner/aktionen.d.ts +16 -0
  117. package/dist/runner/controller.d.ts +72 -0
  118. package/dist/runner/eingabe.d.ts +5 -0
  119. package/dist/runner/index.d.ts +9 -0
  120. package/dist/runner/messages.d.ts +3 -0
  121. package/dist/runner/port.d.ts +20 -0
  122. package/dist/runner/profil.d.ts +39 -0
  123. package/dist/runner/types.d.ts +109 -0
  124. package/dist/runner/view-listen.d.ts +32 -0
  125. package/dist/runner/view.d.ts +95 -0
  126. package/dist/samplesize/controller.d.ts +33 -0
  127. package/dist/samplesize/index.d.ts +7 -0
  128. package/dist/samplesize/messages.d.ts +3 -0
  129. package/dist/samplesize/model.d.ts +40 -0
  130. package/dist/samplesize/port.d.ts +9 -0
  131. package/dist/samplesize/types.d.ts +92 -0
  132. package/dist/samplesize/view.d.ts +39 -0
  133. package/dist/sampling/controller.d.ts +62 -0
  134. package/dist/sampling/index.d.ts +6 -0
  135. package/dist/sampling/messages.d.ts +3 -0
  136. package/dist/sampling/model.d.ts +63 -0
  137. package/dist/sampling/rest-port.d.ts +4 -0
  138. package/dist/sampling/types.d.ts +136 -0
  139. package/dist/sampling/view.d.ts +45 -0
  140. package/dist/screening/controller.d.ts +52 -0
  141. package/dist/screening/index.d.ts +8 -0
  142. package/dist/screening/messages.d.ts +7 -0
  143. package/dist/screening/rest-port.d.ts +4 -0
  144. package/dist/screening/runForm.d.ts +22 -0
  145. package/dist/screening/types.d.ts +295 -0
  146. package/dist/screening/view.d.ts +84 -0
  147. package/dist/store.d.ts +30 -0
  148. package/dist/synopsis/controller.d.ts +68 -0
  149. package/dist/synopsis/exporters.d.ts +16 -0
  150. package/dist/synopsis/index.d.ts +8 -0
  151. package/dist/synopsis/messages.d.ts +3 -0
  152. package/dist/synopsis/navigation.d.ts +5 -0
  153. package/dist/synopsis/port.d.ts +38 -0
  154. package/dist/synopsis/types.d.ts +121 -0
  155. package/dist/synopsis/viewModel.d.ts +74 -0
  156. package/dist/synopsis/wordDiff.d.ts +31 -0
  157. package/dist/table/index.d.ts +6 -0
  158. package/dist/tabular/index.d.ts +2 -0
  159. package/dist/tabular/messages.d.ts +3 -0
  160. package/dist/tabular/tableImport.d.ts +40 -0
  161. package/package.json +55 -0
  162. package/styles/account.css +37 -0
  163. package/styles/attributes.css +18 -0
  164. package/styles/base.css +116 -0
  165. package/styles/batchchecks.css +26 -0
  166. package/styles/benford.css +39 -0
  167. package/styles/dataprotection.css +68 -0
  168. package/styles/dbkanban.css +38 -0
  169. package/styles/documents.css +51 -0
  170. package/styles/extraction.css +25 -0
  171. package/styles/extrapolation.css +34 -0
  172. package/styles/geo.css +54 -0
  173. package/styles/identifiers.css +38 -0
  174. package/styles/index.css +24 -0
  175. package/styles/kanban.css +115 -0
  176. package/styles/reporting.css +22 -0
  177. package/styles/reporttemplates.css +21 -0
  178. package/styles/risk.css +92 -0
  179. package/styles/runner.css +54 -0
  180. package/styles/samplesize.css +27 -0
  181. package/styles/sampling.css +31 -0
  182. package/styles/screening.css +86 -0
  183. package/styles/synopsis.css +83 -0
  184. package/styles/table.css +17 -0
  185. package/styles/tabular.css +11 -0
  186. package/styles/tokens.css +121 -0
@@ -0,0 +1,291 @@
1
+ export declare const CONTRACT = "dataprotection_ui/1";
2
+ export type FieldKind = 'text' | 'flag' | 'count';
3
+ export type FieldValue = string | boolean | number | null;
4
+ export interface RegisterColumn {
5
+ key: string;
6
+ title: string;
7
+ reference: string;
8
+ kind: FieldKind;
9
+ required: boolean;
10
+ }
11
+ export interface QuestionView {
12
+ key: string;
13
+ text: string;
14
+ reference: string;
15
+ /** `hart` = Muss-Kriterium, `punkt` = Kriterium WP 248, `fria` = Hochrisiko-KI. */
16
+ effect: string;
17
+ explanation: string;
18
+ }
19
+ export interface BlockView {
20
+ key: string;
21
+ title: string;
22
+ questions: QuestionView[];
23
+ }
24
+ export interface LevelView {
25
+ value: number;
26
+ label: string;
27
+ }
28
+ export interface MeasureView {
29
+ key: string;
30
+ title: string;
31
+ category: string;
32
+ reduces_severity: number;
33
+ reduces_likelihood: number;
34
+ }
35
+ export interface KeyTitle {
36
+ key: string;
37
+ title: string;
38
+ }
39
+ export interface DossierFieldView extends KeyTitle {
40
+ kind: 'text' | 'date' | 'choice';
41
+ required: boolean;
42
+ choices: KeyTitle[];
43
+ }
44
+ export interface DataProtectionProfile {
45
+ contract: string;
46
+ profile: {
47
+ id: string;
48
+ version: string;
49
+ fingerprint: string;
50
+ regime: string;
51
+ regime_title: string;
52
+ release_mode: string;
53
+ };
54
+ register: {
55
+ columns: RegisterColumn[];
56
+ };
57
+ screening: {
58
+ blocks: BlockView[];
59
+ points_threshold: number;
60
+ };
61
+ risk: {
62
+ scale_min: number;
63
+ scale_max: number;
64
+ severity_levels: LevelView[];
65
+ likelihood_levels: LevelView[];
66
+ dimensions: KeyTitle[];
67
+ measures: MeasureView[];
68
+ bands: string[];
69
+ method: string;
70
+ };
71
+ decisions: KeyTitle[];
72
+ dossier_fields: DossierFieldView[];
73
+ }
74
+ /** Hinweis der Vollständigkeitsprüfung; `subject` = `<Tätigkeits-ID>:<Feld>` oder `deckblatt:<Teil>`. */
75
+ export interface Issue {
76
+ code: string;
77
+ message: string;
78
+ blocking: boolean;
79
+ subject: string;
80
+ }
81
+ export type Activity = Record<string, FieldValue> & {
82
+ id?: string;
83
+ };
84
+ export interface Person {
85
+ name?: string;
86
+ [field: string]: string | undefined;
87
+ }
88
+ export interface RegisterContent {
89
+ deckblatt: {
90
+ verantwortlicher?: Person;
91
+ dsb?: Person;
92
+ [part: string]: Person | undefined;
93
+ };
94
+ referate: string[];
95
+ taetigkeiten: Activity[];
96
+ }
97
+ export type RegisterStatus = 'entwurf' | 'freigegeben' | 'abgeloest';
98
+ export interface VersionSummary {
99
+ version: number;
100
+ status: RegisterStatus;
101
+ created_by: string;
102
+ created_at: string;
103
+ released_by: string | null;
104
+ released_at: string | null;
105
+ activities: number;
106
+ }
107
+ export interface VersionView extends VersionSummary {
108
+ revision: number;
109
+ locked: boolean;
110
+ content: RegisterContent;
111
+ content_hash: string;
112
+ editors: string[];
113
+ predecessor_version: number | null;
114
+ issues: Issue[];
115
+ }
116
+ export interface RegisterState {
117
+ contract: string;
118
+ draft: VersionView | null;
119
+ released: VersionView | null;
120
+ versions: VersionSummary[];
121
+ }
122
+ export interface OverviewRow {
123
+ id: string;
124
+ position: number;
125
+ name: string;
126
+ referat: string;
127
+ zweck: string;
128
+ vvt_version: number;
129
+ vvt_status: RegisterStatus;
130
+ dsfa: null | {
131
+ id: string;
132
+ version: number;
133
+ status: AssessmentStatus;
134
+ entscheidung: string | null;
135
+ freigegeben_am: string | null;
136
+ pruefung_erforderlich: boolean;
137
+ };
138
+ }
139
+ export type AnswerValue = 'ja' | 'nein' | 'unbekannt';
140
+ export type AssessmentStatus = 'entwurf' | 'dsb_beteiligung' | 'freigegeben' | 'abgeloest';
141
+ export interface AnswerInput {
142
+ value: AnswerValue;
143
+ justification: string;
144
+ }
145
+ export interface ScenarioInput {
146
+ dimension: string;
147
+ description: string;
148
+ severity: number;
149
+ likelihood: number;
150
+ measures: string[];
151
+ residual_severity: number | null;
152
+ residual_likelihood: number | null;
153
+ residual_justification: string;
154
+ }
155
+ export interface ScenarioResult {
156
+ index: number;
157
+ dimension_title: string;
158
+ description: string;
159
+ gross: number;
160
+ gross_band: string;
161
+ net: number;
162
+ net_band: string;
163
+ net_severity: number;
164
+ net_likelihood: number;
165
+ measure_titles: string[];
166
+ explicit_residual: string[];
167
+ }
168
+ export interface Proposal {
169
+ profile: {
170
+ id: string;
171
+ version: string;
172
+ fingerprint: string;
173
+ };
174
+ recommendation: string;
175
+ recommendation_text: string;
176
+ reasoning: string;
177
+ consultation_required: boolean;
178
+ consultation_notice?: {
179
+ status: string;
180
+ text: string;
181
+ final: boolean;
182
+ };
183
+ issues: Issue[];
184
+ screening: {
185
+ outcome: 'pflicht' | 'keine_pflicht' | 'unvollstaendig';
186
+ points: number;
187
+ points_threshold: number;
188
+ hard_triggers: string[];
189
+ point_criteria: string[];
190
+ fria_required: boolean | null;
191
+ unanswered: string[];
192
+ unknown: string[];
193
+ complete: boolean;
194
+ reasoning: string;
195
+ };
196
+ risk: null | {
197
+ gross_maximum: number;
198
+ net_maximum: number;
199
+ net_band: string;
200
+ gross_band?: string;
201
+ scenarios: ScenarioResult[];
202
+ };
203
+ }
204
+ export interface AssessmentSummary {
205
+ id: string;
206
+ version: number;
207
+ status: AssessmentStatus;
208
+ decision: string | null;
209
+ created_at: string;
210
+ released_by: string | null;
211
+ released_at: string | null;
212
+ }
213
+ export interface AssessmentView extends AssessmentSummary {
214
+ contract: string;
215
+ activity_id: string;
216
+ activity_name: string;
217
+ revision: number;
218
+ locked: boolean;
219
+ register_version: number;
220
+ profile: {
221
+ id: string;
222
+ version: string;
223
+ };
224
+ answers: Record<string, AnswerInput>;
225
+ scenarios: ScenarioInput[];
226
+ necessity: string;
227
+ proportionality: string;
228
+ dossier: Record<string, string>;
229
+ proposal: Proposal;
230
+ created_by: string;
231
+ updated_at: string;
232
+ editors: string[];
233
+ deviation: boolean;
234
+ deviation_justification: string | null;
235
+ conditions: string[];
236
+ decided_by: string | null;
237
+ decided_at: string | null;
238
+ dpo_requested_from: string | null;
239
+ dpo_requested_on: string | null;
240
+ release_open_points: string[];
241
+ open_points: string[];
242
+ release_blockers: string[];
243
+ versions: AssessmentSummary[];
244
+ }
245
+ /** Erhebung einer Folgenabschätzung, wie sie `POST /assessments/{id}` erwartet. */
246
+ export interface SurveyInput {
247
+ answers: Record<string, AnswerInput>;
248
+ scenarios: ScenarioInput[];
249
+ necessity: string;
250
+ proportionality: string;
251
+ /** Nur Profile nach Schema 2 (EDSA-Vorlage); sonst weglassen. */
252
+ dossier?: Record<string, string>;
253
+ }
254
+ export interface DecisionInput {
255
+ decision: string;
256
+ justification: string;
257
+ conditions: string[];
258
+ }
259
+ export type RegisterExportFormat = 'html' | 'markdown' | 'csv';
260
+ export type AssessmentExportFormat = 'html' | 'markdown';
261
+ export interface ExportedFile {
262
+ blob: Blob;
263
+ filename: string;
264
+ mediaType: string;
265
+ }
266
+ /**
267
+ * Datenzugang der Komponenten. Die mitgelieferte Umsetzung ist
268
+ * `createDataProtectionRestPort`; Anwendungen können eigene Ports übergeben.
269
+ */
270
+ export interface DataProtectionPort {
271
+ profile: () => Promise<DataProtectionProfile>;
272
+ register: () => Promise<RegisterState>;
273
+ checkRegister: (content: RegisterContent) => Promise<{
274
+ issues: Issue[];
275
+ }>;
276
+ saveDraft: (content: RegisterContent, expectedRevision: number | null) => Promise<VersionView>;
277
+ releaseRegister: (expectedRevision: number) => Promise<VersionView>;
278
+ exportRegister: (format: RegisterExportFormat, source: 'draft' | 'released') => Promise<ExportedFile>;
279
+ overview: () => Promise<{
280
+ items: OverviewRow[];
281
+ }>;
282
+ startAssessment: (activityId: string) => Promise<AssessmentView>;
283
+ assessment: (id: string) => Promise<AssessmentView>;
284
+ calculate: (answers: Record<string, AnswerInput>, scenarios: ScenarioInput[]) => Promise<Proposal>;
285
+ updateAssessment: (id: string, expectedRevision: number, survey: SurveyInput) => Promise<AssessmentView>;
286
+ decide: (id: string, expectedRevision: number, decision: DecisionInput) => Promise<AssessmentView>;
287
+ requestDpo: (id: string, expectedRevision: number, requestedFrom: string, requestedOn: string) => Promise<AssessmentView>;
288
+ releaseAssessment: (id: string, expectedRevision: number) => Promise<AssessmentView>;
289
+ reassess: (id: string) => Promise<AssessmentView>;
290
+ exportAssessment: (id: string, format: AssessmentExportFormat) => Promise<ExportedFile>;
291
+ }
@@ -0,0 +1,69 @@
1
+ import { RequestState, Store } from '../store';
2
+ import { ExportTexts } from './exporters';
3
+ import { DataProtectionTranslate } from './messages';
4
+ import { DataProtectionError, RequestHooks } from './requests';
5
+ import { DataProtectionPort, DataProtectionProfile, FieldValue, Issue, Person, RegisterContent, RegisterState, VersionView } from './types';
6
+ export type VvtExportFormat = 'print' | 'markdown' | 'csv';
7
+ export interface VvtExport {
8
+ format: VvtExportFormat;
9
+ filename: string;
10
+ mimeType: string;
11
+ content: string;
12
+ }
13
+ export interface VvtHooks extends RequestHooks {
14
+ onSaved?: (version: VersionView) => void;
15
+ onReleased?: (version: VersionView) => void;
16
+ /** Wartezeit der Vollständigkeitsprüfung nach einer Eingabe (ms). */
17
+ checkDelay?: number;
18
+ }
19
+ export interface VvtData extends RequestState<DataProtectionError> {
20
+ profile: DataProtectionProfile | null;
21
+ register: RegisterState | null;
22
+ showing: 'draft' | 'released';
23
+ working: RegisterContent | null;
24
+ checked: Issue[] | null;
25
+ /** Ausgewählte Tätigkeit (Index in `content.taetigkeiten`). */
26
+ selected: number | null;
27
+ history: boolean;
28
+ }
29
+ /** Abgeleitete Werte eines Stands (reine Funktion, von beiden Oberflächen genutzt). */
30
+ export interface VvtView {
31
+ version: VersionView | null;
32
+ editing: boolean;
33
+ content: RegisterContent;
34
+ dirty: boolean;
35
+ issues: Issue[];
36
+ }
37
+ export declare function vvtView(state: VvtData): VvtView;
38
+ /** Vier-Augen-Hinweis: die angemeldete Person hat den offenen Entwurf bearbeitet. */
39
+ export declare function vvtFourEyes(state: VvtData, actor: string): boolean;
40
+ export declare function vvtVersionLabel(t: DataProtectionTranslate, version: VersionView | null): string;
41
+ /** Beschriftungen der Exporte (Druckansicht, Markdown, CSV). */
42
+ export declare function vvtExportTexts(t: DataProtectionTranslate): ExportTexts;
43
+ export declare function buildVvtExport(state: VvtData, format: VvtExportFormat, t: DataProtectionTranslate, lang: string): VvtExport;
44
+ export interface VvtControllerOptions extends VvtHooks {
45
+ port: () => DataProtectionPort | null;
46
+ t: () => DataProtectionTranslate;
47
+ }
48
+ export declare function createVvtController(options: VvtControllerOptions): {
49
+ save: () => Promise<VersionView | null>;
50
+ release: () => Promise<VersionView | null>;
51
+ select: (index: number | null) => void;
52
+ toggleHistory: () => void;
53
+ changeField(key: string, value: FieldValue): void;
54
+ addActivity(department: string): void;
55
+ removeActivity(): void;
56
+ changePerson: (part: "verantwortlicher" | "dsb", person: Person) => void;
57
+ changeDepartments: (departments: readonly string[]) => void;
58
+ check: () => Promise<void>;
59
+ update: (next: RegisterContent) => void;
60
+ show: (which: "draft" | "released") => void;
61
+ startDraft: () => void;
62
+ discard: () => void;
63
+ dispose: () => void;
64
+ store: Store<VvtData>;
65
+ load: (editable: boolean) => Promise<void>;
66
+ exportAs: (format: VvtExportFormat, lang: string) => VvtExport;
67
+ setNotice: (notice: string) => void;
68
+ };
69
+ export type VvtController = ReturnType<typeof createVvtController>;
@@ -0,0 +1,54 @@
1
+ import { RecordPort, RecordRow, RecordTable } from '@auditcore/kanban-core';
2
+ import { RequestState, Store } from '../store';
3
+ import { DbKanbanTranslate } from './messages';
4
+ export interface DbKanbanError {
5
+ code: string;
6
+ message: string;
7
+ status: number;
8
+ }
9
+ export type DbKanbanBusy = 'load' | 'move' | 'add';
10
+ export interface DbKanbanData extends RequestState<DbKanbanError> {
11
+ table: RecordTable | null;
12
+ /** Eigenschaft, nach der gruppiert wird (`select`). */
13
+ groupBy: string;
14
+ query: string;
15
+ /** Gezogene Karte (Maus) bzw. aufgenommene Karte (Tastatur). */
16
+ dragging: string | null;
17
+ /** Spalte unter dem Mauszeiger beim Ziehen. */
18
+ dropTarget: string | null;
19
+ }
20
+ /** Verschiebung einer Karte: der gesetzte Zellwert (`null` = ohne Wert). */
21
+ export interface RecordMove {
22
+ rowId: string;
23
+ propertyId: string;
24
+ value: string | null;
25
+ }
26
+ export interface DbKanbanHooks {
27
+ onMoved?: (move: RecordMove) => void;
28
+ onAdded?: (row: RecordRow) => void;
29
+ onGroupBy?: (propertyId: string) => void;
30
+ onError?: (error: DbKanbanError) => void;
31
+ }
32
+ export interface DbKanbanControllerOptions extends DbKanbanHooks {
33
+ port: () => RecordPort | null;
34
+ t: () => DbKanbanTranslate;
35
+ editable?: () => boolean;
36
+ lang?: () => string;
37
+ }
38
+ export declare const INITIAL_DB_KANBAN: DbKanbanData;
39
+ export declare function asDbKanbanError(error: unknown, t: DbKanbanTranslate): DbKanbanError;
40
+ /** Vorgabe: gewünschte Eigenschaft, falls gruppierbar, sonst die erste Auswahl-Eigenschaft. */
41
+ export declare function initialGroupBy(table: RecordTable, preferred: string | undefined): string;
42
+ export declare function createDbKanbanController(options: DbKanbanControllerOptions): {
43
+ setQuery: (query: string) => void;
44
+ startDrag: (rowId: string | null) => void;
45
+ setDropTarget: (column: string | null) => void;
46
+ dismissError: () => void;
47
+ move: (rowId: string, column: string) => Promise<boolean>;
48
+ moveBy: (rowId: string, direction: 1 | -1) => Promise<boolean>;
49
+ addCard: (column: string) => Promise<RecordRow | null>;
50
+ store: Store<DbKanbanData>;
51
+ load: (preferredGroupBy?: string) => Promise<void>;
52
+ setGroupBy: (propertyId: string) => void;
53
+ };
54
+ export type DbKanbanController = ReturnType<typeof createDbKanbanController>;
@@ -0,0 +1,3 @@
1
+ export { dbKanbanMessages, type DbKanbanMessageKey, type DbKanbanTranslate } from './messages';
2
+ export * from './controller';
3
+ export * from './view';
@@ -0,0 +1,5 @@
1
+ import { Translate } from '../i18n';
2
+ /** Texte der Datenbankansicht als Kanban (`<flowaudit-db-kanban>`). */
3
+ export declare const dbKanbanMessages: import('..').Catalogs<"title" | "noMatches" | "added" | "moved" | "noPort" | "networkError" | "yes" | "no" | "searchLabel" | "busy_load" | "readOnly" | "addCard" | "addCardIn" | "groupByLabel" | "noGroupable" | "noGroupBy" | "withoutValue" | "columnCount" | "columnCountOne" | "columnEmpty" | "untitled" | "cardLabel" | "moveHint" | "busy_move" | "busy_add">;
4
+ export type DbKanbanMessageKey = keyof typeof dbKanbanMessages.de;
5
+ export type DbKanbanTranslate = Translate<DbKanbanMessageKey>;
@@ -0,0 +1,39 @@
1
+ import { RecordValue, RecordProperty, RecordTable } from '@auditcore/kanban-core';
2
+ import { DbKanbanData } from './controller';
3
+ import { DbKanbanTranslate } from './messages';
4
+ export interface DbFieldView {
5
+ id: string;
6
+ label: string;
7
+ text: string;
8
+ }
9
+ export interface DbCardView {
10
+ id: string;
11
+ title: string;
12
+ fields: DbFieldView[];
13
+ /** Spalte der Karte (`""` = ohne Wert). */
14
+ column: string;
15
+ }
16
+ export interface DbColumnView {
17
+ value: string;
18
+ label: string;
19
+ countText: string;
20
+ cards: DbCardView[];
21
+ }
22
+ export interface DbGroupOption {
23
+ value: string;
24
+ label: string;
25
+ }
26
+ export interface DbKanbanView {
27
+ groupOptions: DbGroupOption[];
28
+ columns: DbColumnView[];
29
+ /** Hinweis statt Spalten (keine Gruppierung möglich/gewählt), sonst `null`. */
30
+ notice: string | null;
31
+ noMatches: boolean;
32
+ busyText: string;
33
+ }
34
+ /** Anzeigetext eines Zellwerts; leere Werte ergeben `""`. */
35
+ export declare function cellText(value: RecordValue | undefined, t: DbKanbanTranslate, lang: string): string;
36
+ /** Titel-Eigenschaft: die erste Texteigenschaft (wie die erste Spalte der Tabellenansicht). */
37
+ export declare function titleProperty(table: RecordTable): RecordProperty | undefined;
38
+ export declare function columnLabel(value: string, t: DbKanbanTranslate): string;
39
+ export declare function dbKanbanView(state: DbKanbanData, t: DbKanbanTranslate, lang?: string): DbKanbanView;
@@ -0,0 +1,63 @@
1
+ import { RequestState, Store } from '../store';
2
+ import { SynopsisPort, SynopsisRestClient } from '../synopsis/port';
3
+ import { Comparison, ComparisonProfile, ComparisonSummary, RowStatus } from '../synopsis/types';
4
+ import { CompareForm } from './form';
5
+ import { ComparisonsTranslate } from './messages';
6
+ /**
7
+ * Port zur Anwendung: {@link createSynopsisRestClient} erfüllt ihn vollständig.
8
+ * `load`/`updateRows`/`exportUrl` braucht nur die eingebettete Synopse,
9
+ * `importResult` nur der Import.
10
+ */
11
+ export type ComparisonsPort = Pick<SynopsisRestClient, 'profiles' | 'list' | 'create' | 'remove'> & Partial<Pick<SynopsisRestClient, 'importResult' | 'load' | 'updateRows' | 'exportUrl'>>;
12
+ /** Der Port als Datenzugang der eingebetteten Synopse, wenn er Vergleiche laden kann. */
13
+ export declare function synopsisPortOf(port: ComparisonsPort | null | undefined): SynopsisPort | null;
14
+ /** Fehler einer Portanfrage: Meldung des Servers bzw. `network_error` mit Status 0. */
15
+ export interface ComparisonsError {
16
+ code: string;
17
+ message: string;
18
+ status: number;
19
+ }
20
+ export type ComparisonsBusy = 'load' | 'create' | 'import' | 'remove';
21
+ export interface ComparisonsData extends RequestState<ComparisonsError> {
22
+ profiles: ComparisonProfile[];
23
+ items: ComparisonSummary[];
24
+ loaded: boolean;
25
+ query: string;
26
+ form: CompareForm;
27
+ /** Nach dem ersten Absenden werden Befunde der Formularprüfung angezeigt. */
28
+ submitted: boolean;
29
+ /** Geöffneter Vergleich (Synopse). */
30
+ openId: string | null;
31
+ /** Vergleich, dessen Löschen bestätigt werden soll. */
32
+ pendingRemove: string | null;
33
+ }
34
+ export interface ComparisonsHooks {
35
+ onCreated?: (comparison: Comparison) => void;
36
+ onImported?: (comparison: Comparison) => void;
37
+ onRemoved?: (id: string) => void;
38
+ onError?: (error: ComparisonsError) => void;
39
+ }
40
+ export interface ComparisonsControllerOptions extends ComparisonsHooks {
41
+ port: () => ComparisonsPort | null;
42
+ t: () => ComparisonsTranslate;
43
+ maxBytes?: () => number;
44
+ lang?: () => string;
45
+ }
46
+ export declare const INITIAL_COMPARISONS: ComparisonsData;
47
+ export declare function asComparisonsError(error: unknown, t: ComparisonsTranslate): ComparisonsError;
48
+ export declare function createComparisonsController(options: ComparisonsControllerOptions): {
49
+ setQuery: (query: string) => void;
50
+ open: (id: string | null) => void;
51
+ askRemove: (id: string) => void;
52
+ cancelRemove: () => void;
53
+ dismissError: () => void;
54
+ submit: () => Promise<Comparison | null>;
55
+ importText: (text: string) => Promise<Comparison | null>;
56
+ confirmRemove: () => Promise<boolean>;
57
+ updateForm: (patch: Partial<CompareForm>) => void;
58
+ toggleSection: (status: RowStatus, enabled: boolean) => void;
59
+ resetForm: () => void;
60
+ store: Store<ComparisonsData>;
61
+ load: () => Promise<void>;
62
+ };
63
+ export type ComparisonsController = ReturnType<typeof createComparisonsController>;
@@ -0,0 +1,52 @@
1
+ import { CompareFields } from '../synopsis/port';
2
+ import { ComparisonProfile, RowStatus } from '../synopsis/types';
3
+ import { ComparisonsMessageKey } from './messages';
4
+ export type ComparisonKind = 'standard' | 'article_law';
5
+ export type ComparisonMode = 'auto' | 'checklist' | 'text';
6
+ export declare const COMPARISON_KINDS: readonly ComparisonKind[];
7
+ export declare const COMPARISON_MODES: readonly ComparisonMode[];
8
+ export declare const ACCEPTED_EXTENSIONS: readonly string[];
9
+ /** Vorgabe des Servers (`ServiceSettings.max_upload_bytes`). */
10
+ export declare const DEFAULT_MAX_UPLOAD_BYTES: number;
11
+ export declare const MIN_THRESHOLD = 70;
12
+ export declare const MAX_THRESHOLD = 100;
13
+ export declare const MAX_TITLE = 255;
14
+ /** Datei aus einem Eingabefeld (im Browser `File`). */
15
+ export interface UploadFile extends Blob {
16
+ readonly name: string;
17
+ }
18
+ export interface CompareForm {
19
+ oldFile: UploadFile | null;
20
+ newFile: UploadFile | null;
21
+ title: string;
22
+ kind: ComparisonKind;
23
+ mode: ComparisonMode;
24
+ threshold: number;
25
+ includeAnswers: boolean;
26
+ includeNotes: boolean;
27
+ includeEditorial: boolean;
28
+ highlightWords: boolean;
29
+ sections: readonly RowStatus[];
30
+ /** Leer: Standardprofil des Servers. */
31
+ profile: string;
32
+ }
33
+ export declare const DEFAULT_FORM: CompareForm;
34
+ /** Ein Befund der Formularprüfung: Textschlüssel und Platzhalter. */
35
+ export interface FormProblem {
36
+ key: Extract<ComparisonsMessageKey, `problem_${string}`>;
37
+ field: 'oldFile' | 'newFile' | 'threshold' | 'sections' | 'title';
38
+ params?: Readonly<Record<string, string>>;
39
+ }
40
+ /** Größenangabe wie „20 MiB“ oder „512 KiB“. */
41
+ export declare function formatBytes(bytes: number, lang?: string): string;
42
+ export declare function hasAcceptedExtension(name: string): boolean;
43
+ /** Alle Befunde in Formularreihenfolge; leer heißt: absendbar. */
44
+ export declare function formProblems(form: CompareForm, maxBytes?: number, lang?: string): FormProblem[];
45
+ /** PDF-Dateien vergleicht der Server immer als Fließtext. */
46
+ export declare function involvesPdf(form: CompareForm): boolean;
47
+ /** Formularfelder für `POST /comparisons`; Gesetzessynopse ohne die Optionen des Standardvergleichs. */
48
+ export declare function toCompareFields(form: CompareForm): CompareFields;
49
+ /** Abschnitt ein- oder ausschalten; Reihenfolge wie `ROW_STATUSES`. */
50
+ export declare function toggleSection(sections: readonly RowStatus[], status: RowStatus, enabled: boolean): RowStatus[];
51
+ /** Standardprofil des Servers (`default: true`), sonst das erste. */
52
+ export declare function defaultProfile(profiles: readonly ComparisonProfile[]): ComparisonProfile | null;
@@ -0,0 +1,12 @@
1
+ import { ImportRequest } from '../synopsis/port';
2
+ import { ComparisonResult } from '../synopsis/types';
3
+ export type ImportParse = {
4
+ ok: true;
5
+ request: ImportRequest;
6
+ } | {
7
+ ok: false;
8
+ key: 'importUnreadable' | 'importInvalid';
9
+ };
10
+ /** Kennzeichen eines `ComparisonResult.to_dict()`; Einzelheiten prüft `ComparisonResult.from_dict`. */
11
+ export declare function looksLikeResult(value: unknown): value is ComparisonResult;
12
+ export declare function parseImport(text: string): ImportParse;
@@ -0,0 +1,6 @@
1
+ export { comparisonsMessages, type ComparisonsMessageKey, type ComparisonsTranslate } from './messages';
2
+ export * from './form';
3
+ export * from './importing';
4
+ export * from './list';
5
+ export * from './controller';
6
+ export * from './view';
@@ -0,0 +1,21 @@
1
+ import { Comparison, ComparisonSummary } from '../synopsis/types';
2
+ import { ComparisonsTranslate } from './messages';
3
+ export interface SummaryView {
4
+ id: string;
5
+ title: string;
6
+ kind: string;
7
+ kindLabel: string;
8
+ files: string;
9
+ counts: string;
10
+ /** Summe der Änderungen (für Badges). */
11
+ changes: number;
12
+ created: string;
13
+ createdIso: string;
14
+ }
15
+ /** Datum und Uhrzeit in der Sprache der Oberfläche; ungültige Angaben bleiben stehen. */
16
+ export declare function formatDateTime(iso: string, lang: string): string;
17
+ export declare function summaryView(summary: ComparisonSummary, t: ComparisonsTranslate, lang: string): SummaryView;
18
+ /** Suche in Titel und Dateinamen, ohne Groß-/Kleinschreibung; neueste zuerst wie der Server. */
19
+ export declare function filterSummaries(items: readonly ComparisonSummary[], query: string): ComparisonSummary[];
20
+ /** Eintrag der Liste aus einem gespeicherten Vergleich (nach Anlegen oder Import). */
21
+ export declare function summaryOf(comparison: Comparison): ComparisonSummary;
@@ -0,0 +1,8 @@
1
+ import { Translate } from '../i18n';
2
+ /**
3
+ * Texte der Vergleichsverwaltung (`<flowaudit-comparisons>`): Hochladen,
4
+ * gespeicherte Vergleiche, Import und Löschen. Begriffe wie in der Synopse.
5
+ */
6
+ export declare const comparisonsMessages: import('..').Catalogs<"title" | "cancel" | "reset" | "submit" | "empty" | "counts" | "files" | "workAid" | "noMatches" | "removed" | "noPort" | "networkError" | "open" | "remove" | "imported" | "formHeading" | "oldFile" | "newFile" | "oldFileArticleLaw" | "newFileArticleLaw" | "fileHint" | "fileChosen" | "titleLabel" | "titlePlaceholder" | "typeLabel" | "kind_standard" | "kind_article_law" | "modeLabel" | "mode_auto" | "mode_checklist" | "mode_text" | "pdfHint" | "thresholdLabel" | "optionsLegend" | "includeAnswers" | "includeNotes" | "includeEditorial" | "highlightWords" | "sectionsLegend" | "section_changed" | "section_removed" | "section_added" | "section_moved" | "section_unchanged" | "profileLabel" | "profileDefault" | "profileOption" | "problemsHeading" | "problem_oldMissing" | "problem_newMissing" | "problem_type" | "problem_size" | "problem_threshold" | "problem_sections" | "problem_title" | "listHeading" | "searchLabel" | "listCount" | "openLabel" | "removeLabel" | "confirmTitle" | "confirmText" | "importLabel" | "importInvalid" | "importUnreadable" | "importUnsupported" | "created" | "back" | "busy_load" | "busy_create" | "busy_import" | "busy_remove">;
7
+ export type ComparisonsMessageKey = keyof typeof comparisonsMessages.de;
8
+ export type ComparisonsTranslate = Translate<ComparisonsMessageKey>;
@@ -0,0 +1,36 @@
1
+ import { ComparisonsData } from './controller';
2
+ import { FormProblem } from './form';
3
+ import { SummaryView } from './list';
4
+ import { ComparisonsTranslate } from './messages';
5
+ export interface ProblemView {
6
+ field: FormProblem['field'];
7
+ text: string;
8
+ }
9
+ export interface ProfileOption {
10
+ /** Leer: Vorgabe des Servers. */
11
+ value: string;
12
+ label: string;
13
+ }
14
+ export interface ComparisonsView {
15
+ rows: SummaryView[];
16
+ total: number;
17
+ countText: string;
18
+ /** Hinweis bei leerer Liste, sonst `null`. */
19
+ emptyText: string | null;
20
+ problems: ProblemView[];
21
+ profileOptions: ProfileOption[];
22
+ sizeHint: string;
23
+ oldFileText: string;
24
+ newFileText: string;
25
+ oldFileLabel: string;
26
+ newFileLabel: string;
27
+ pdfHint: boolean;
28
+ busyText: string;
29
+ pendingTitle: string | null;
30
+ openTitle: string | null;
31
+ }
32
+ export interface ComparisonsViewOptions {
33
+ lang: string;
34
+ maxBytes?: number;
35
+ }
36
+ export declare function comparisonsView(state: ComparisonsData, t: ComparisonsTranslate, options: ComparisonsViewOptions): ComparisonsView;