feat: complete leave approval MVP

This commit is contained in:
selfrelease
2026-07-18 19:20:07 +08:00
parent 2105fe3bac
commit 090a7e33ce
133 changed files with 7845 additions and 100 deletions
+85 -1
View File
@@ -10,6 +10,17 @@ class DynamicFormDefinition {
final JsonFormSchema dataSchema;
final FormUiSchema uiSchema;
factory DynamicFormDefinition.fromJson(Map<String, Object?> json) {
return DynamicFormDefinition(
dataSchema: JsonFormSchema.fromJson(
Map<String, Object?>.from(json['dataSchema']! as Map),
),
uiSchema: FormUiSchema.fromJson(
Map<String, Object?>.from(json['uiSchema']! as Map),
),
);
}
}
class JsonFormSchema {
@@ -24,6 +35,23 @@ class JsonFormSchema {
final String title;
final Map<String, JsonFieldSchema> properties;
final Set<String> required;
factory JsonFormSchema.fromJson(Map<String, Object?> json) {
final properties = Map<String, Object?>.from(json['properties']! as Map);
return JsonFormSchema(
id: json[r'$id']! as String,
title: json['title']! as String,
properties: properties.map(
(key, value) => MapEntry(
key,
JsonFieldSchema.fromJson(Map<String, Object?>.from(value as Map)),
),
),
required: ((json['required'] as List?) ?? const [])
.cast<String>()
.toSet(),
);
}
}
class JsonFieldSchema {
@@ -40,6 +68,16 @@ class JsonFieldSchema {
final List<String> enumValues;
final int? minLength;
final int? maxLength;
factory JsonFieldSchema.fromJson(Map<String, Object?> json) {
return JsonFieldSchema(
type: JsonValueType.values.byName(json['type']! as String),
format: json['format'] as String?,
enumValues: ((json['enum'] as List?) ?? const []).cast<String>(),
minLength: json['minLength'] as int?,
maxLength: json['maxLength'] as int?,
);
}
}
class FormUiSchema {
@@ -47,6 +85,19 @@ class FormUiSchema {
final String description;
final List<FormSectionSchema> sections;
factory FormUiSchema.fromJson(Map<String, Object?> json) {
return FormUiSchema(
description: json['description']! as String,
sections: (json['sections']! as List)
.map(
(value) => FormSectionSchema.fromJson(
Map<String, Object?>.from(value as Map),
),
)
.toList(),
);
}
}
class FormSectionSchema {
@@ -54,6 +105,19 @@ class FormSectionSchema {
final String title;
final List<FormControlSchema> controls;
factory FormSectionSchema.fromJson(Map<String, Object?> json) {
return FormSectionSchema(
title: json['title']! as String,
controls: (json['controls']! as List)
.map(
(value) => FormControlSchema.fromJson(
Map<String, Object?>.from(value as Map),
),
)
.toList(),
);
}
}
class FormControlSchema {
@@ -72,21 +136,41 @@ class FormControlSchema {
final String? placeholder;
final String? helperText;
final Map<String, String> optionLabels;
factory FormControlSchema.fromJson(Map<String, Object?> json) {
return FormControlSchema(
field: json['field']! as String,
label: json['label']! as String,
control: FormControlType.values.byName(json['control']! as String),
placeholder: json['placeholder'] as String?,
helperText: json['helperText'] as String?,
optionLabels: ((json['optionLabels'] as Map?) ?? const {})
.cast<String, String>(),
);
}
}
class DynamicFormState {
const DynamicFormState({this.values = const {}, this.errors = const {}});
const DynamicFormState({
this.values = const {},
this.errors = const {},
this.restoredAt,
});
final Map<String, Object?> values;
final Map<String, String> errors;
final DateTime? restoredAt;
DynamicFormState copyWith({
Map<String, Object?>? values,
Map<String, String>? errors,
DateTime? restoredAt,
bool clearRestoredAt = false,
}) {
return DynamicFormState(
values: values ?? this.values,
errors: errors ?? this.errors,
restoredAt: clearRestoredAt ? null : restoredAt ?? this.restoredAt,
);
}
}