devKA #4
@@ -1 +0,0 @@
|
|||||||
// Hi
|
|
||||||
16
frontend/pshared/.gitignore
vendored
Normal file
16
frontend/pshared/.gitignore
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# https://dart.dev/guides/libraries/private-files
|
||||||
|
# Created by `dart pub`
|
||||||
|
.dart_tool/
|
||||||
|
|
||||||
|
build/
|
||||||
|
# Avoid committing pubspec.lock for library packages; see
|
||||||
|
# https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||||
|
pubspec.lock
|
||||||
|
|
||||||
|
*.g.dart
|
||||||
|
lib/generated
|
||||||
|
untranslated.txt
|
||||||
|
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
devtools_options.yaml
|
||||||
3
frontend/pshared/CHANGELOG.md
Normal file
3
frontend/pshared/CHANGELOG.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
- Initial version.
|
||||||
39
frontend/pshared/README.md
Normal file
39
frontend/pshared/README.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<!--
|
||||||
|
This README describes the package. If you publish this package to pub.dev,
|
||||||
|
this README's contents appear on the landing page for your package.
|
||||||
|
|
||||||
|
For information about how to write a good package README, see the guide for
|
||||||
|
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
|
||||||
|
|
||||||
|
For general information about developing packages, see the Dart guide for
|
||||||
|
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
|
||||||
|
and the Flutter guide for
|
||||||
|
[developing packages and plugins](https://flutter.dev/developing-packages).
|
||||||
|
-->
|
||||||
|
|
||||||
|
TODO: Put a short description of the package here that helps potential users
|
||||||
|
know whether this package might be useful for them.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
TODO: List prerequisites and provide or point to information on how to
|
||||||
|
start using the package.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
TODO: Include short and useful examples for package users. Add longer examples
|
||||||
|
to `/example` folder.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
const like = 'sample';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
TODO: Tell users more about the package: where to find more information, how to
|
||||||
|
contribute to the package, how to file issues, what response they can expect
|
||||||
|
from the package authors, and more.
|
||||||
30
frontend/pshared/analysis_options.yaml
Normal file
30
frontend/pshared/analysis_options.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# This file configures the static analysis results for your project (errors,
|
||||||
|
# warnings, and lints).
|
||||||
|
#
|
||||||
|
# This enables the 'recommended' set of lints from `package:lints`.
|
||||||
|
# This set helps identify many issues that may lead to problems when running
|
||||||
|
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
|
||||||
|
# style and format.
|
||||||
|
#
|
||||||
|
# If you want a smaller set of lints you can change this to specify
|
||||||
|
# 'package:lints/core.yaml'. These are just the most critical lints
|
||||||
|
# (the recommended set includes the core lints).
|
||||||
|
# The core lints are also what is used by pub.dev for scoring packages.
|
||||||
|
|
||||||
|
include: package:lints/recommended.yaml
|
||||||
|
|
||||||
|
# Uncomment the following section to specify additional rules.
|
||||||
|
|
||||||
|
# linter:
|
||||||
|
# rules:
|
||||||
|
# - camel_case_types
|
||||||
|
|
||||||
|
# analyzer:
|
||||||
|
# exclude:
|
||||||
|
# - path/to/excluded/files/**
|
||||||
|
|
||||||
|
# For more information about the core and recommended set of lints, see
|
||||||
|
# https://dart.dev/go/core-lints
|
||||||
|
|
||||||
|
# For additional information about configuring this file, see
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
||||||
BIN
frontend/pshared/assets/flag_of_catalonia.si
Normal file
BIN
frontend/pshared/assets/flag_of_catalonia.si
Normal file
Binary file not shown.
7
frontend/pshared/l10n.yaml
Normal file
7
frontend/pshared/l10n.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
arb-dir: lib/l10n
|
||||||
|
template-arb-file: ps_en.arb
|
||||||
|
output-dir: lib/generated/i18n
|
||||||
|
output-localization-file: ps_localizations.dart
|
||||||
|
output-class: PSLocalizations
|
||||||
|
synthetic-package: false
|
||||||
|
untranslated-messages-file: untranslated.txt
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
class AuthorizationFailed implements Exception {
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
class ErrorFailedToReadImage implements Exception {
|
||||||
|
}
|
||||||
2
frontend/pshared/lib/api/errors/unauthorized.dart
Normal file
2
frontend/pshared/lib/api/errors/unauthorized.dart
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
class ErrorUnauthorized implements Exception {
|
||||||
|
}
|
||||||
2
frontend/pshared/lib/api/errors/upload_failed.dart
Normal file
2
frontend/pshared/lib/api/errors/upload_failed.dart
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
class ErrorUploadFailed implements Exception {
|
||||||
|
}
|
||||||
18
frontend/pshared/lib/api/requests/change_password.dart
Normal file
18
frontend/pshared/lib/api/requests/change_password.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'change_password.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class ChangePassword {
|
||||||
|
@JsonKey(name: 'old')
|
||||||
|
final String oldPassword;
|
||||||
|
|
||||||
|
@JsonKey(name: 'new')
|
||||||
|
final String newPassword;
|
||||||
|
|
||||||
|
const ChangePassword({required this.oldPassword, required this.newPassword});
|
||||||
|
|
||||||
|
factory ChangePassword.fromJson(Map<String, dynamic> json) => _$ChangePasswordFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$ChangePasswordToJson(this);
|
||||||
|
}
|
||||||
18
frontend/pshared/lib/api/requests/change_role.dart
Normal file
18
frontend/pshared/lib/api/requests/change_role.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'change_role.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class ChangeRole {
|
||||||
|
final String accountRef;
|
||||||
|
final String newRoleDescriptionRef;
|
||||||
|
|
||||||
|
const ChangeRole({
|
||||||
|
required this.accountRef,
|
||||||
|
required this.newRoleDescriptionRef,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ChangeRole.fromJson(Map<String, dynamic> json) => _$ChangeRoleFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$ChangeRoleToJson(this);
|
||||||
|
}
|
||||||
15
frontend/pshared/lib/api/requests/file_upload.dart
Normal file
15
frontend/pshared/lib/api/requests/file_upload.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'file_upload.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class FileUpload {
|
||||||
|
|
||||||
|
final String objRef;
|
||||||
|
|
||||||
|
const FileUpload({ required this.objRef });
|
||||||
|
|
||||||
|
factory FileUpload.fromJson(Map<String, dynamic> json) => _$FileUploadFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$FileUploadToJson(this);
|
||||||
|
}
|
||||||
24
frontend/pshared/lib/api/requests/login.dart
Normal file
24
frontend/pshared/lib/api/requests/login.dart
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'login.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class LoginRequest {
|
||||||
|
final String login;
|
||||||
|
final String password;
|
||||||
|
final String locale;
|
||||||
|
final String clientId;
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
const LoginRequest({
|
||||||
|
required this.login,
|
||||||
|
required this.password,
|
||||||
|
required this.locale,
|
||||||
|
required this.clientId,
|
||||||
|
required this.deviceId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory LoginRequest.fromJson(Map<String, dynamic> json) => _$LoginRequestFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$LoginRequestToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/permissions/data/policy.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/data/policy.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/policy.dart';
|
||||||
|
|
||||||
|
part 'change_policies.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class PoliciesChangeRequest {
|
||||||
|
final List<PolicyDTO>? add;
|
||||||
|
final List<PolicyDTO>? remove;
|
||||||
|
|
||||||
|
const PoliciesChangeRequest({
|
||||||
|
this.add,
|
||||||
|
this.remove,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PoliciesChangeRequest.add({required List<Policy> policies}) => PoliciesChangeRequest(
|
||||||
|
add: policies.map((policy) => policy.toDTO()).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
factory PoliciesChangeRequest.remove({required List<Policy> policies}) => PoliciesChangeRequest(
|
||||||
|
remove: policies.map((policy) => policy.toDTO()).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
factory PoliciesChangeRequest.change({
|
||||||
|
required List<Policy> add,
|
||||||
|
required List<Policy> remove,
|
||||||
|
}) => PoliciesChangeRequest(
|
||||||
|
add: add.map((policy) => policy.toDTO()).toList(),
|
||||||
|
remove: remove.map((policy) => policy.toDTO()).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
factory PoliciesChangeRequest.fromJson(Map<String, dynamic> json) => _$PoliciesChangeRequestFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$PoliciesChangeRequestToJson(this);
|
||||||
|
}
|
||||||
42
frontend/pshared/lib/api/requests/signup.dart
Normal file
42
frontend/pshared/lib/api/requests/signup.dart
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'signup.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class SignupRequest {
|
||||||
|
final String name;
|
||||||
|
final String login;
|
||||||
|
final String password;
|
||||||
|
final String locale;
|
||||||
|
final String organizationName;
|
||||||
|
final String organizationTimeZone;
|
||||||
|
|
||||||
|
const SignupRequest({
|
||||||
|
required this.name,
|
||||||
|
required this.login,
|
||||||
|
required this.password,
|
||||||
|
required this.locale,
|
||||||
|
required this.organizationName,
|
||||||
|
required this.organizationTimeZone,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SignupRequest.build({
|
||||||
|
required String name,
|
||||||
|
required String login,
|
||||||
|
required String password,
|
||||||
|
required String locale,
|
||||||
|
required String organizationName,
|
||||||
|
required String organizationTimeZone,
|
||||||
|
}) => SignupRequest(
|
||||||
|
name: name,
|
||||||
|
login: login,
|
||||||
|
password: password,
|
||||||
|
locale: locale,
|
||||||
|
organizationName: organizationName,
|
||||||
|
organizationTimeZone: organizationTimeZone,
|
||||||
|
);
|
||||||
|
|
||||||
|
factory SignupRequest.fromJson(Map<String, dynamic> json) => _$SignupRequestFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$SignupRequestToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import 'package:pshared/api/requests/tokens/refresh_rotate.dart';
|
||||||
|
|
||||||
|
|
||||||
|
typedef AccessTokenRefreshRequest = RotateRefreshTokenRequest;
|
||||||
21
frontend/pshared/lib/api/requests/tokens/refresh_rotate.dart
Normal file
21
frontend/pshared/lib/api/requests/tokens/refresh_rotate.dart
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/requests/tokens/session_id.dart';
|
||||||
|
|
||||||
|
part 'refresh_rotate.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class RotateRefreshTokenRequest extends SessionID {
|
||||||
|
final String token;
|
||||||
|
|
||||||
|
const RotateRefreshTokenRequest({
|
||||||
|
required this.token,
|
||||||
|
required super.clientId,
|
||||||
|
required super.deviceId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory RotateRefreshTokenRequest.fromJson(Map<String, dynamic> json) => _$RotateRefreshTokenRequestFromJson(json);
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$RotateRefreshTokenRequestToJson(this);
|
||||||
|
}
|
||||||
18
frontend/pshared/lib/api/requests/tokens/session_id.dart
Normal file
18
frontend/pshared/lib/api/requests/tokens/session_id.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'session_id.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class SessionID {
|
||||||
|
final String clientId;
|
||||||
|
final String deviceId;
|
||||||
|
|
||||||
|
const SessionID({
|
||||||
|
required this.clientId,
|
||||||
|
required this.deviceId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SessionID.fromJson(Map<String, dynamic> json) => _$SessionIDFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$SessionIDToJson(this);
|
||||||
|
}
|
||||||
18
frontend/pshared/lib/api/responses/account.dart
Normal file
18
frontend/pshared/lib/api/responses/account.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/responses/token.dart';
|
||||||
|
import 'package:pshared/data/dto/account/account.dart';
|
||||||
|
|
||||||
|
part 'account.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class AccountResponse {
|
||||||
|
final AccountDTO account;
|
||||||
|
final TokenData accessToken;
|
||||||
|
|
||||||
|
const AccountResponse({required this.accessToken, required this.account});
|
||||||
|
|
||||||
|
factory AccountResponse.fromJson(Map<String, dynamic> json) => _$AccountResponseFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$AccountResponseToJson(this);
|
||||||
|
}
|
||||||
16
frontend/pshared/lib/api/responses/base.dart
Normal file
16
frontend/pshared/lib/api/responses/base.dart
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/responses/token.dart';
|
||||||
|
|
||||||
|
part 'base.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class BaseAuthorizedResponse {
|
||||||
|
final TokenData accessToken;
|
||||||
|
|
||||||
|
const BaseAuthorizedResponse({required this.accessToken});
|
||||||
|
|
||||||
|
factory BaseAuthorizedResponse.fromJson(Map<String, dynamic> json) => _$BaseAuthorizedResponseFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$BaseAuthorizedResponseToJson(this);
|
||||||
|
}
|
||||||
18
frontend/pshared/lib/api/responses/employees.dart
Normal file
18
frontend/pshared/lib/api/responses/employees.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/responses/token.dart';
|
||||||
|
import 'package:pshared/data/dto/account/account.dart';
|
||||||
|
|
||||||
|
part 'employees.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class EmployeesResponse {
|
||||||
|
final List<AccountDTO> accounts;
|
||||||
|
final TokenData accessToken;
|
||||||
|
|
||||||
|
const EmployeesResponse({required this.accessToken, required this.accounts});
|
||||||
|
|
||||||
|
factory EmployeesResponse.fromJson(Map<String, dynamic> json) => _$EmployeesResponseFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$EmployeesResponseToJson(this);
|
||||||
|
}
|
||||||
13
frontend/pshared/lib/api/responses/error/connectivity.dart
Normal file
13
frontend/pshared/lib/api/responses/error/connectivity.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class ConnectivityError implements Exception {
|
||||||
|
final int? code;
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
const ConnectivityError({this.code, required this.message});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return code == null
|
||||||
|
? 'Error response, message: $message)'
|
||||||
|
: 'Error response (code: $code, message: $message)';
|
||||||
|
}
|
||||||
|
}
|
||||||
43
frontend/pshared/lib/api/responses/error/server.dart
Normal file
43
frontend/pshared/lib/api/responses/error/server.dart
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'server.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ErrorResponse implements Exception {
|
||||||
|
final int code;
|
||||||
|
final String details;
|
||||||
|
final String source;
|
||||||
|
final String error;
|
||||||
|
|
||||||
|
const ErrorResponse({
|
||||||
|
required this.code,
|
||||||
|
required this.details,
|
||||||
|
required this.error,
|
||||||
|
required this.source,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final buffer = StringBuffer('Error response (code: $code');
|
||||||
|
|
||||||
|
if (details.isNotEmpty) {
|
||||||
|
buffer.write(', details: $details');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.isNotEmpty) {
|
||||||
|
buffer.write(', error: $error');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source.isNotEmpty) {
|
||||||
|
buffer.write(', source: $source');
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.write(')');
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ErrorResponse.fromJson(Map<String, dynamic> json) => _$ErrorResponseFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$ErrorResponseToJson(this);
|
||||||
|
}
|
||||||
15
frontend/pshared/lib/api/responses/file_uploaded.dart
Normal file
15
frontend/pshared/lib/api/responses/file_uploaded.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'file_uploaded.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class FileUploaded {
|
||||||
|
|
||||||
|
final String url;
|
||||||
|
|
||||||
|
const FileUploaded({ required this.url });
|
||||||
|
|
||||||
|
factory FileUploaded.fromJson(Map<String, dynamic> json) => _$FileUploadedFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$FileUploadedToJson(this);
|
||||||
|
}
|
||||||
19
frontend/pshared/lib/api/responses/login.dart
Normal file
19
frontend/pshared/lib/api/responses/login.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/responses/account.dart';
|
||||||
|
import 'package:pshared/api/responses/token.dart';
|
||||||
|
import 'package:pshared/data/dto/account/account.dart';
|
||||||
|
|
||||||
|
part 'login.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class LoginResponse extends AccountResponse {
|
||||||
|
final TokenData refreshToken;
|
||||||
|
|
||||||
|
const LoginResponse({required super.accessToken, required super.account, required this.refreshToken});
|
||||||
|
|
||||||
|
factory LoginResponse.fromJson(Map<String, dynamic> json) => _$LoginResponseFromJson(json);
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$LoginResponseToJson(this);
|
||||||
|
}
|
||||||
19
frontend/pshared/lib/api/responses/message.dart
Normal file
19
frontend/pshared/lib/api/responses/message.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/responses/type.dart';
|
||||||
|
|
||||||
|
part 'message.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class HTTPMessage {
|
||||||
|
|
||||||
|
@JsonKey(fromJson: MessageTypeExtension.fromJson, toJson: MessageTypeExtension.toJson)
|
||||||
|
final MessageType status;
|
||||||
|
final Map<String, dynamic> data;
|
||||||
|
|
||||||
|
const HTTPMessage({ required this.data, required this.status });
|
||||||
|
|
||||||
|
factory HTTPMessage.fromJson(Map<String, dynamic> json) => _$HTTPMessageFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$HTTPMessageToJson(this);
|
||||||
|
}
|
||||||
19
frontend/pshared/lib/api/responses/organization.dart
Normal file
19
frontend/pshared/lib/api/responses/organization.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/responses/base.dart';
|
||||||
|
import 'package:pshared/api/responses/token.dart';
|
||||||
|
import 'package:pshared/data/dto/organization.dart';
|
||||||
|
|
||||||
|
part 'organization.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class OrganizationResponse extends BaseAuthorizedResponse {
|
||||||
|
final List<OrganizationDTO> organizations;
|
||||||
|
|
||||||
|
const OrganizationResponse({required super.accessToken, required this.organizations});
|
||||||
|
|
||||||
|
factory OrganizationResponse.fromJson(Map<String, dynamic> json) => _$OrganizationResponseFromJson(json);
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$OrganizationResponseToJson(this);
|
||||||
|
}
|
||||||
21
frontend/pshared/lib/api/responses/policies.dart
Normal file
21
frontend/pshared/lib/api/responses/policies.dart
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/api/responses/base.dart';
|
||||||
|
import 'package:pshared/api/responses/token.dart';
|
||||||
|
import 'package:pshared/data/dto/permissions/data/permissions.dart';
|
||||||
|
import 'package:pshared/data/dto/permissions/description/description.dart';
|
||||||
|
|
||||||
|
part 'policies.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable(explicitToJson: true)
|
||||||
|
class PoliciesResponse extends BaseAuthorizedResponse {
|
||||||
|
final PermissionsDescriptionDTO descriptions;
|
||||||
|
final PermissionsDataDTO permissions;
|
||||||
|
|
||||||
|
const PoliciesResponse({required this.descriptions, required this.permissions, required super.accessToken});
|
||||||
|
|
||||||
|
factory PoliciesResponse.fromJson(Map<String, dynamic> json) => _$PoliciesResponseFromJson(json);
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$PoliciesResponseToJson(this);
|
||||||
|
}
|
||||||
15
frontend/pshared/lib/api/responses/token.dart
Normal file
15
frontend/pshared/lib/api/responses/token.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'token.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class TokenData {
|
||||||
|
final String token;
|
||||||
|
final DateTime expiration;
|
||||||
|
|
||||||
|
const TokenData({required this.token, required this.expiration});
|
||||||
|
|
||||||
|
factory TokenData.fromJson(Map<String, dynamic> json) => _$TokenDataFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$TokenDataToJson(this);
|
||||||
|
}
|
||||||
32
frontend/pshared/lib/api/responses/type.dart
Normal file
32
frontend/pshared/lib/api/responses/type.dart
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
enum MessageType {
|
||||||
|
success,
|
||||||
|
error,
|
||||||
|
request
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MessageTypeExtension on MessageType {
|
||||||
|
static String toJson(MessageType value) {
|
||||||
|
switch (value) {
|
||||||
|
case MessageType.success:
|
||||||
|
return 'success';
|
||||||
|
case MessageType.error:
|
||||||
|
return 'error';
|
||||||
|
case MessageType.request:
|
||||||
|
return 'request';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MessageType fromJson(String json) {
|
||||||
|
switch (json) {
|
||||||
|
case 'success':
|
||||||
|
return MessageType.success;
|
||||||
|
case 'error':
|
||||||
|
return MessageType.error;
|
||||||
|
case 'request':
|
||||||
|
return MessageType.request;
|
||||||
|
default:
|
||||||
|
throw ArgumentError('Unknown HTTPMType string: $json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
frontend/pshared/lib/config/common.dart
Normal file
47
frontend/pshared/lib/config/common.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class CommonConstants {
|
||||||
|
static String apiProto = const String.fromEnvironment('API_PROTO', defaultValue: 'http');
|
||||||
|
static String apiHost = const String.fromEnvironment('API_HOST', defaultValue: 'localhost');
|
||||||
|
// static String apiHost = 'localhost';
|
||||||
|
// static String apiHost = '10.0.2.2';
|
||||||
|
static String apiEndpoint = '/api/v1';
|
||||||
|
static String amplitudeSecret = 'c3d75b3e2520d708440acbb16b923e79';
|
||||||
|
static String amplitudeServerZone = 'EU';
|
||||||
|
static Locale defaultLocale = const Locale('en');
|
||||||
|
static String defaultCurrency = 'EUR';
|
||||||
|
static int defaultDimensionLength = 500;
|
||||||
|
static String clientId = '';
|
||||||
|
static String wsProto = 'ws';
|
||||||
|
static String wsEndpoint = '/ws';
|
||||||
|
static Color themeColor = Color.fromARGB(255, 80, 63, 224);
|
||||||
|
static String nilObjectRef = '000000000000000000000000';
|
||||||
|
|
||||||
|
// Public getters for shared properties
|
||||||
|
static String get serviceUrl => '$apiProto://$apiHost';
|
||||||
|
static String get apiUrl => '$serviceUrl$apiEndpoint';
|
||||||
|
static String get wsUrl => '$wsProto://$apiHost$apiEndpoint$wsEndpoint';
|
||||||
|
static const String accessTokenStorageKey = 'access_token';
|
||||||
|
static const String refreshTokenStorageKey = 'refresh_token';
|
||||||
|
static const String currentOrgKey = 'current_org';
|
||||||
|
static const String deviceIdStorageKey = 'device_id';
|
||||||
|
|
||||||
|
// Method to apply the configuration, called by platform-specific implementations
|
||||||
|
static void applyConfiguration(Map<String, dynamic> configJson) {
|
||||||
|
apiProto = configJson['apiProto'] ?? apiProto;
|
||||||
|
apiHost = configJson['apiHost'] ?? apiHost;
|
||||||
|
apiEndpoint = configJson['apiEndpoint'] ?? apiEndpoint;
|
||||||
|
amplitudeSecret = configJson['amplitudeSecret'] ?? amplitudeSecret;
|
||||||
|
amplitudeServerZone = configJson['amplitudeServerZone'] ?? amplitudeServerZone;
|
||||||
|
defaultLocale = Locale(configJson['defaultLocale'] ?? defaultLocale.languageCode);
|
||||||
|
defaultCurrency = configJson['defaultCurrency'] ?? defaultCurrency;
|
||||||
|
wsProto = configJson['wsProto'] ?? wsProto;
|
||||||
|
wsEndpoint = configJson['wsEndpoint'] ?? wsEndpoint;
|
||||||
|
defaultDimensionLength = configJson['defaultDimensionLength'] ?? defaultDimensionLength;
|
||||||
|
clientId = configJson['clientId'] ?? clientId;
|
||||||
|
if (configJson.containsKey('themeColor')) {
|
||||||
|
themeColor = Color(int.parse(configJson['themeColor']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
frontend/pshared/lib/config/constants.dart
Normal file
2
frontend/pshared/lib/config/constants.dart
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export 'mobile.dart'
|
||||||
|
if (dart.library.html) 'web.dart';
|
||||||
35
frontend/pshared/lib/config/mobile.dart
Normal file
35
frontend/pshared/lib/config/mobile.dart
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:pshared/config/common.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class Constants extends CommonConstants {
|
||||||
|
static const String _clientIdMobile = 'com.profee.pay.mobile-3f9c3b76-2f89-4e9e-95a2-1a5b705b7a1d';
|
||||||
|
|
||||||
|
static Locale get defaultLocale => CommonConstants.defaultLocale;
|
||||||
|
static String get clientId => _clientIdMobile;
|
||||||
|
static String get accessTokenStorageKey => CommonConstants.accessTokenStorageKey;
|
||||||
|
static String get refreshTokenStorageKey => CommonConstants.refreshTokenStorageKey;
|
||||||
|
static String get currentOrgKey => CommonConstants.currentOrgKey;
|
||||||
|
static String get apiUrl => CommonConstants.apiUrl;
|
||||||
|
static String get serviceUrl => CommonConstants.serviceUrl;
|
||||||
|
static int get defaultDimensionLength => CommonConstants.defaultDimensionLength;
|
||||||
|
static String get deviceIdStorageKey => CommonConstants.deviceIdStorageKey;
|
||||||
|
static String get nilObjectRef => CommonConstants.nilObjectRef;
|
||||||
|
static Color get themeColor => CommonConstants.themeColor;
|
||||||
|
|
||||||
|
static Future<void> initialize() async {
|
||||||
|
var configFile = File('./config/config.json');
|
||||||
|
if (await configFile.exists()) {
|
||||||
|
var configJson = jsonDecode(await configFile.readAsString());
|
||||||
|
CommonConstants.applyConfiguration({
|
||||||
|
...configJson,
|
||||||
|
'clientId': configJson['clientId'] ?? _clientIdMobile,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
CommonConstants.clientId = _clientIdMobile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
frontend/pshared/lib/config/web.dart
Normal file
75
frontend/pshared/lib/config/web.dart
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'dart:js_interop';
|
||||||
|
|
||||||
|
import 'package:pshared/config/common.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Bind to the global JS `appConfig` (if it exists).
|
||||||
|
@JS()
|
||||||
|
external AppConfig? get appConfig;
|
||||||
|
|
||||||
|
/// A staticInterop class for the JS object returned by `appConfig`.
|
||||||
|
@JS()
|
||||||
|
@staticInterop
|
||||||
|
class AppConfig {}
|
||||||
|
|
||||||
|
/// Extension methods to expose each property on `AppConfig`.
|
||||||
|
extension AppConfigExtension on AppConfig {
|
||||||
|
external String? get apiProto;
|
||||||
|
external String? get apiHost;
|
||||||
|
external String? get apiEndpoint;
|
||||||
|
external String? get amplitudeSecret;
|
||||||
|
external String? get amplitudeServerZone;
|
||||||
|
external String? get defaultLocale;
|
||||||
|
external String? get wsProto;
|
||||||
|
external String? get wsEndpoint;
|
||||||
|
external int? get defaultDimensionLength;
|
||||||
|
external String? get themeColor;
|
||||||
|
external String? get clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Constants extends CommonConstants {
|
||||||
|
static const String _clientIdWeb = 'com.profee.pay.web-4b6e8a0f-9b5c-4f57-b3a6-3c456e9bb2cd';
|
||||||
|
|
||||||
|
// Just re-expose these from CommonConstants:
|
||||||
|
static Locale get defaultLocale => CommonConstants.defaultLocale;
|
||||||
|
static String get clientId => _clientIdWeb;
|
||||||
|
static String get accessTokenStorageKey => CommonConstants.accessTokenStorageKey;
|
||||||
|
static String get refreshTokenStorageKey => CommonConstants.refreshTokenStorageKey;
|
||||||
|
static String get currentOrgKey => CommonConstants.currentOrgKey;
|
||||||
|
static String get apiUrl => CommonConstants.apiUrl;
|
||||||
|
static String get serviceUrl => CommonConstants.serviceUrl;
|
||||||
|
static int get defaultDimensionLength => CommonConstants.defaultDimensionLength;
|
||||||
|
static String get deviceIdStorageKey => CommonConstants.deviceIdStorageKey;
|
||||||
|
static String get nilObjectRef => CommonConstants.nilObjectRef;
|
||||||
|
static Color get themeColor => CommonConstants.themeColor;
|
||||||
|
|
||||||
|
static Future<void> initialize() async {
|
||||||
|
// Try to grab the JS `appConfig` if it exists:
|
||||||
|
final config = appConfig;
|
||||||
|
|
||||||
|
if (config != null) {
|
||||||
|
// Build a Dart Map from the JS object’s properties:
|
||||||
|
final configJson = <String, dynamic>{
|
||||||
|
'apiProto': config.apiProto,
|
||||||
|
'apiHost': config.apiHost,
|
||||||
|
'apiEndpoint': config.apiEndpoint,
|
||||||
|
'amplitudeSecret': config.amplitudeSecret,
|
||||||
|
'amplitudeServerZone': config.amplitudeServerZone,
|
||||||
|
'defaultLocale': config.defaultLocale,
|
||||||
|
'wsProto': config.wsProto,
|
||||||
|
'wsEndpoint': config.wsEndpoint,
|
||||||
|
'defaultDimensionLength': config.defaultDimensionLength,
|
||||||
|
'themeColor': config.themeColor,
|
||||||
|
// If the JS side didn’t supply a clientId, fall back to our Dart constant
|
||||||
|
'clientId': config.clientId ?? _clientIdWeb,
|
||||||
|
};
|
||||||
|
|
||||||
|
CommonConstants.applyConfiguration(configJson);
|
||||||
|
} else {
|
||||||
|
// No appConfig on JS side → just use the default Dart client ID.
|
||||||
|
CommonConstants.clientId = _clientIdWeb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
frontend/pshared/lib/data/dto/account/account.dart
Normal file
25
frontend/pshared/lib/data/dto/account/account.dart
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/account/base.dart';
|
||||||
|
|
||||||
|
part 'account.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class AccountDTO extends AccountBaseDTO {
|
||||||
|
final String login;
|
||||||
|
|
||||||
|
const AccountDTO({
|
||||||
|
required super.id,
|
||||||
|
required super.createdAt,
|
||||||
|
required super.updatedAt,
|
||||||
|
required super.name,
|
||||||
|
required super.avatarUrl,
|
||||||
|
required super.locale,
|
||||||
|
required this.login,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory AccountDTO.fromJson(Map<String, dynamic> json) => _$AccountDTOFromJson(json);
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$AccountDTOToJson(this);
|
||||||
|
}
|
||||||
27
frontend/pshared/lib/data/dto/account/base.dart
Normal file
27
frontend/pshared/lib/data/dto/account/base.dart
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/storable.dart';
|
||||||
|
|
||||||
|
part 'base.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class AccountBaseDTO extends StorableDTO {
|
||||||
|
final String name;
|
||||||
|
final String locale;
|
||||||
|
final String? avatarUrl;
|
||||||
|
|
||||||
|
const AccountBaseDTO({
|
||||||
|
required super.id,
|
||||||
|
required super.createdAt,
|
||||||
|
required super.updatedAt,
|
||||||
|
required this.name,
|
||||||
|
required this.avatarUrl,
|
||||||
|
required this.locale,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory AccountBaseDTO.fromJson(Map<String, dynamic> json) => _$AccountBaseDTOFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$AccountBaseDTOToJson(this);
|
||||||
|
}
|
||||||
23
frontend/pshared/lib/data/dto/organization.dart
Normal file
23
frontend/pshared/lib/data/dto/organization.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:pshared/data/dto/storable.dart';
|
||||||
|
|
||||||
|
part 'organization.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class OrganizationDTO extends StorableDTO {
|
||||||
|
final String timeZone;
|
||||||
|
final String? logoUrl;
|
||||||
|
|
||||||
|
const OrganizationDTO({
|
||||||
|
required super.id,
|
||||||
|
required super.createdAt,
|
||||||
|
required super.updatedAt,
|
||||||
|
required this.timeZone,
|
||||||
|
this.logoUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory OrganizationDTO.fromJson(Map<String, dynamic> json) => _$OrganizationDTOFromJson(json);
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$OrganizationDTOToJson(this);
|
||||||
|
}
|
||||||
16
frontend/pshared/lib/data/dto/organization/description.dart
Normal file
16
frontend/pshared/lib/data/dto/organization/description.dart
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'description.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class OrganizationDescriptionDTO {
|
||||||
|
final String? logoUrl;
|
||||||
|
|
||||||
|
const OrganizationDescriptionDTO({
|
||||||
|
this.logoUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory OrganizationDescriptionDTO.fromJson(Map<String, dynamic> json) => _$OrganizationDescriptionDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$OrganizationDescriptionDTOToJson(this);
|
||||||
|
}
|
||||||
22
frontend/pshared/lib/data/dto/permissions/access.dart
Normal file
22
frontend/pshared/lib/data/dto/permissions/access.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/permissions/data/permissions.dart';
|
||||||
|
import 'package:pshared/data/dto/permissions/description/description.dart';
|
||||||
|
|
||||||
|
part 'access.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class UserAccessDTO {
|
||||||
|
final PermissionsDescriptionDTO descriptions;
|
||||||
|
final PermissionsDataDTO permissions;
|
||||||
|
|
||||||
|
const UserAccessDTO({
|
||||||
|
required this.descriptions,
|
||||||
|
required this.permissions,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UserAccessDTO.fromJson(Map<String, dynamic> json) => _$UserAccessDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$UserAccessDTOToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
19
frontend/pshared/lib/data/dto/permissions/action_effect.dart
Normal file
19
frontend/pshared/lib/data/dto/permissions/action_effect.dart
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// data/action_effect_dto.dart
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'action_effect.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ActionEffectDTO {
|
||||||
|
final String action;
|
||||||
|
final String effect;
|
||||||
|
|
||||||
|
const ActionEffectDTO({
|
||||||
|
required this.action,
|
||||||
|
required this.effect,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ActionEffectDTO.fromJson(Map<String, dynamic> json) => _$ActionEffectDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$ActionEffectDTOToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/permissions/action_effect.dart';
|
||||||
|
|
||||||
|
part 'permission.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PermissionDTO {
|
||||||
|
final String roleDescriptionRef;
|
||||||
|
final String organizationRef;
|
||||||
|
final String descriptionRef;
|
||||||
|
final String? objectRef;
|
||||||
|
final ActionEffectDTO effect;
|
||||||
|
final String accountRef;
|
||||||
|
|
||||||
|
const PermissionDTO({
|
||||||
|
required this.roleDescriptionRef,
|
||||||
|
required this.organizationRef,
|
||||||
|
required this.descriptionRef,
|
||||||
|
required this.objectRef,
|
||||||
|
required this.effect,
|
||||||
|
required this.accountRef,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PermissionDTO.fromJson(Map<String, dynamic> json) => _$PermissionDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$PermissionDTOToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/permissions/data/permission.dart';
|
||||||
|
import 'package:pshared/data/dto/permissions/data/policy.dart';
|
||||||
|
import 'package:pshared/data/dto/permissions/data/role.dart';
|
||||||
|
|
||||||
|
part 'permissions.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PermissionsDataDTO {
|
||||||
|
final List<RoleDTO> roles;
|
||||||
|
final List<PolicyDTO> policies;
|
||||||
|
final List<PermissionDTO> permissions;
|
||||||
|
|
||||||
|
const PermissionsDataDTO({
|
||||||
|
required this.roles,
|
||||||
|
required this.policies,
|
||||||
|
required this.permissions,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PermissionsDataDTO.fromJson(Map<String, dynamic> json) => _$PermissionsDataDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$PermissionsDataDTOToJson(this);
|
||||||
|
}
|
||||||
26
frontend/pshared/lib/data/dto/permissions/data/policy.dart
Normal file
26
frontend/pshared/lib/data/dto/permissions/data/policy.dart
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/permissions/action_effect.dart';
|
||||||
|
|
||||||
|
part 'policy.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PolicyDTO {
|
||||||
|
final String roleDescriptionRef;
|
||||||
|
final String organizationRef;
|
||||||
|
final String descriptionRef;
|
||||||
|
final String? objectRef;
|
||||||
|
final ActionEffectDTO effect;
|
||||||
|
|
||||||
|
const PolicyDTO({
|
||||||
|
required this.roleDescriptionRef,
|
||||||
|
required this.organizationRef,
|
||||||
|
required this.descriptionRef,
|
||||||
|
required this.objectRef,
|
||||||
|
required this.effect,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PolicyDTO.fromJson(Map<String, dynamic> json) => _$PolicyDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$PolicyDTOToJson(this);
|
||||||
|
}
|
||||||
20
frontend/pshared/lib/data/dto/permissions/data/role.dart
Normal file
20
frontend/pshared/lib/data/dto/permissions/data/role.dart
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'role.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class RoleDTO {
|
||||||
|
final String accountRef;
|
||||||
|
final String organizationRef;
|
||||||
|
final String descriptionRef;
|
||||||
|
|
||||||
|
const RoleDTO({
|
||||||
|
required this.accountRef,
|
||||||
|
required this.descriptionRef,
|
||||||
|
required this.organizationRef,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory RoleDTO.fromJson(Map<String, dynamic> json) => _$RoleDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$RoleDTOToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/data/dto/permissions/description/policy.dart';
|
||||||
|
import 'package:pshared/data/dto/permissions/description/role.dart';
|
||||||
|
|
||||||
|
part 'description.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PermissionsDescriptionDTO {
|
||||||
|
final List<RoleDescriptionDTO> roles;
|
||||||
|
final List<PolicyDescriptionDTO> policies;
|
||||||
|
|
||||||
|
const PermissionsDescriptionDTO({
|
||||||
|
required this.roles,
|
||||||
|
required this.policies,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PermissionsDescriptionDTO.fromJson(Map<String, dynamic> json) => _$PermissionsDescriptionDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$PermissionsDescriptionDTOToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:pshared/data/dto/storable.dart';
|
||||||
|
import 'package:pshared/models/resources.dart';
|
||||||
|
|
||||||
|
part 'policy.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class PolicyDescriptionDTO extends StorableDTO {
|
||||||
|
final List<ResourceType>? resourceTypes;
|
||||||
|
final String? organizationRef;
|
||||||
|
|
||||||
|
const PolicyDescriptionDTO({
|
||||||
|
required super.id,
|
||||||
|
required super.createdAt,
|
||||||
|
required super.updatedAt,
|
||||||
|
required this.resourceTypes,
|
||||||
|
required this.organizationRef,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PolicyDescriptionDTO.fromJson(Map<String, dynamic> json) => _$PolicyDescriptionDTOFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$PolicyDescriptionDTOToJson(this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:pshared/data/dto/storable.dart';
|
||||||
|
|
||||||
|
part 'role.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class RoleDescriptionDTO extends StorableDTO {
|
||||||
|
final String organizationRef;
|
||||||
|
|
||||||
|
const RoleDescriptionDTO({
|
||||||
|
required super.id,
|
||||||
|
required super.createdAt,
|
||||||
|
required super.updatedAt,
|
||||||
|
required this.organizationRef,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory RoleDescriptionDTO.fromJson(Map<String, dynamic> json) => _$RoleDescriptionDTOFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => _$RoleDescriptionDTOToJson(this);
|
||||||
|
}
|
||||||
0
frontend/pshared/lib/data/dto/pfe/services.dart
Normal file
0
frontend/pshared/lib/data/dto/pfe/services.dart
Normal file
20
frontend/pshared/lib/data/dto/storable.dart
Normal file
20
frontend/pshared/lib/data/dto/storable.dart
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'storable.g.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class StorableDTO {
|
||||||
|
final String id;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final DateTime updatedAt;
|
||||||
|
|
||||||
|
const StorableDTO({
|
||||||
|
required this.id,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory StorableDTO.fromJson(Map<String, dynamic> json) => _$StorableDTOFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$StorableDTOToJson(this);
|
||||||
|
}
|
||||||
BIN
frontend/pshared/lib/data/mapper/.DS_Store
vendored
Normal file
BIN
frontend/pshared/lib/data/mapper/.DS_Store
vendored
Normal file
Binary file not shown.
26
frontend/pshared/lib/data/mapper/account/account.dart
Normal file
26
frontend/pshared/lib/data/mapper/account/account.dart
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:pshared/data/dto/account/account.dart';
|
||||||
|
import 'package:pshared/models/account/account.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension AccountMapper on Account {
|
||||||
|
AccountDTO toDTO() => AccountDTO(
|
||||||
|
id: id,
|
||||||
|
createdAt: createdAt,
|
||||||
|
updatedAt: updatedAt,
|
||||||
|
name: name,
|
||||||
|
avatarUrl: avatarUrl,
|
||||||
|
locale: locale,
|
||||||
|
login: login,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountDTOMapper on AccountDTO {
|
||||||
|
Account toDomain() => Account(
|
||||||
|
storable: newStorable(id: id, createdAt: createdAt, updatedAt: updatedAt),
|
||||||
|
avatarUrl: avatarUrl,
|
||||||
|
locale: locale,
|
||||||
|
login: login,
|
||||||
|
name: name,
|
||||||
|
);
|
||||||
|
}
|
||||||
24
frontend/pshared/lib/data/mapper/account/base.dart
Normal file
24
frontend/pshared/lib/data/mapper/account/base.dart
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:pshared/data/dto/account/base.dart';
|
||||||
|
import 'package:pshared/models/account/base.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension AccountBaseMapper on AccountBase {
|
||||||
|
AccountBaseDTO toDTO() => AccountBaseDTO(
|
||||||
|
id: storable.id,
|
||||||
|
createdAt: storable.createdAt,
|
||||||
|
updatedAt: storable.updatedAt,
|
||||||
|
avatarUrl: avatarUrl,
|
||||||
|
name: name,
|
||||||
|
locale: locale,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountDTOMapper on AccountBaseDTO {
|
||||||
|
AccountBase toDomain() => AccountBase(
|
||||||
|
storable: newStorable(id: id, createdAt: createdAt, updatedAt: updatedAt),
|
||||||
|
avatarUrl: avatarUrl,
|
||||||
|
name: name,
|
||||||
|
locale: locale,
|
||||||
|
);
|
||||||
|
}
|
||||||
164
frontend/pshared/lib/data/mapper/icon.dart
Normal file
164
frontend/pshared/lib/data/mapper/icon.dart
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|
||||||
|
final Map<String, IconData> iconMapping = {
|
||||||
|
// General Project Management Icons
|
||||||
|
'dashboard': Icons.dashboard, // Overview screen
|
||||||
|
'project': Icons.work, // Represents a project
|
||||||
|
'tasks': Icons.check_box, // Task list
|
||||||
|
'calendar': Icons.calendar_today, // Calendar view
|
||||||
|
'team': Icons.group, // Team collaboration
|
||||||
|
'kanban': Icons.view_column, // Kanban board
|
||||||
|
'timeline': Icons.timeline, // Project timeline
|
||||||
|
'milestone': Icons.flag, // Milestones
|
||||||
|
'priority': Icons.priority_high, // General priority indicator
|
||||||
|
'settings': Icons.settings, // Settings or configurations
|
||||||
|
'chat': Icons.chat, // Communication/chat
|
||||||
|
'files': Icons.insert_drive_file, // File management
|
||||||
|
'notes': Icons.note, // Notes or documentation
|
||||||
|
'report': Icons.insert_chart, // Reporting and analytics
|
||||||
|
|
||||||
|
// Priority Related Icons
|
||||||
|
'to_do': Icons.assignment, // To do tasks
|
||||||
|
'in_progress': Icons.autorenew, // Tasks in progress
|
||||||
|
'complete': Icons.check_circle, // Completed tasks
|
||||||
|
'archived': Icons.archive, // Archived tasks
|
||||||
|
|
||||||
|
// Deadline Related Icons
|
||||||
|
'deadline': Icons.timer, // Deadline indicator
|
||||||
|
'reminder': Icons.alarm, // Deadline reminder
|
||||||
|
'due_today': Icons.today, // Tasks due today
|
||||||
|
'upcoming': Icons.event_available, // Upcoming deadlines
|
||||||
|
|
||||||
|
// Additional
|
||||||
|
'overdue': Icons.warning, // Overdue tasks or deadlines
|
||||||
|
'budget': Icons.account_balance_wallet, // Budget and finance
|
||||||
|
'resource': Icons.perm_contact_calendar, // Resource allocation
|
||||||
|
'risk': Icons.warning_amber, // Risk management
|
||||||
|
'feedback': Icons.feedback, // Feedback and reviews
|
||||||
|
'timeline_edit': Icons.edit_calendar, // Edit project timeline
|
||||||
|
'workflow': Icons.shuffle, // Workflow management
|
||||||
|
'dependencies': Icons.link, // Task dependencies
|
||||||
|
'progress': Icons.show_chart, // Project progress
|
||||||
|
'schedule': Icons.schedule, // Scheduling
|
||||||
|
'support': Icons.support, // Support/help
|
||||||
|
'permissions': Icons.lock, // Access permissions
|
||||||
|
'backup': Icons.backup, // Data backup
|
||||||
|
'integration': Icons.extension, // Integrations
|
||||||
|
'search': Icons.search, // Search functionality
|
||||||
|
'announcement': Icons.announcement, // Announcements or updates
|
||||||
|
'analytics': Icons.analytics, // Project analytics
|
||||||
|
'assignment': Icons.assignment_turned_in, // Task assignments
|
||||||
|
'discussions': Icons.forum, // Discussions/threads
|
||||||
|
'timeline_view': Icons.view_timeline, // Detailed timeline view
|
||||||
|
'board': Icons.dashboard_customize, // Custom project boards
|
||||||
|
'approval': Icons.how_to_vote, // Approvals
|
||||||
|
'review': Icons.rate_review, // Reviews and feedback
|
||||||
|
'objective': Icons.golf_course, // Objectives/goals
|
||||||
|
'settings_advanced': Icons.tune, // Advanced settings
|
||||||
|
'time_tracking': Icons.timer_outlined, // Time tracking
|
||||||
|
'checklist': Icons.checklist, // Checklists
|
||||||
|
'sync': Icons.sync, // Syncing data
|
||||||
|
'upload': Icons.cloud_upload, // Upload files
|
||||||
|
'download': Icons.cloud_download, // Download files
|
||||||
|
'share': Icons.share, // Sharing options
|
||||||
|
'tag': Icons.label, // Tags/labels
|
||||||
|
'notifications': Icons.notifications, // Notifications
|
||||||
|
'user_roles': Icons.manage_accounts, // User roles and permissions
|
||||||
|
'logout': Icons.logout, // Logout
|
||||||
|
'automation': Icons.auto_awesome, // Automation
|
||||||
|
'history': Icons.history, // Project history/logs
|
||||||
|
'estimate': Icons.calculate, // Estimates and costing
|
||||||
|
'quality': Icons.verified, // Quality assurance
|
||||||
|
'strategy': Icons.lightbulb, // Strategy planning
|
||||||
|
'feedback_form': Icons.comment, // Feedback forms
|
||||||
|
'presentation': Icons.slideshow, // Project presentations
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectIcons {
|
||||||
|
static const IconData dashboard = Icons.dashboard;
|
||||||
|
static const IconData project = Icons.work;
|
||||||
|
static const IconData tasks = Icons.check_box;
|
||||||
|
static const IconData calendar = Icons.calendar_today;
|
||||||
|
static const IconData team = Icons.group;
|
||||||
|
static const IconData kanban = Icons.view_column;
|
||||||
|
static const IconData timeline = Icons.timeline;
|
||||||
|
static const IconData milestone = Icons.flag;
|
||||||
|
static const IconData priority = Icons.priority_high;
|
||||||
|
static const IconData settings = Icons.settings;
|
||||||
|
static const IconData chat = Icons.chat;
|
||||||
|
static const IconData files = Icons.insert_drive_file;
|
||||||
|
static const IconData notes = Icons.note;
|
||||||
|
static const IconData report = Icons.insert_chart;
|
||||||
|
static const IconData todo = Icons.assignment;
|
||||||
|
static const IconData inProgress = Icons.autorenew;
|
||||||
|
static const IconData complete = Icons.check_circle;
|
||||||
|
static const IconData archived = Icons.archive;
|
||||||
|
static const IconData deadline = Icons.timer;
|
||||||
|
static const IconData reminder = Icons.alarm;
|
||||||
|
static const IconData dueToday = Icons.today;
|
||||||
|
static const IconData upcoming = Icons.event_available;
|
||||||
|
static const IconData overdue = Icons.warning;
|
||||||
|
static const IconData budget = Icons.account_balance_wallet;
|
||||||
|
static const IconData resource = Icons.perm_contact_calendar;
|
||||||
|
static const IconData risk = Icons.warning_amber;
|
||||||
|
static const IconData feedback = Icons.feedback;
|
||||||
|
static const IconData timelineEdit = Icons.edit_calendar;
|
||||||
|
static const IconData workflow = Icons.shuffle;
|
||||||
|
static const IconData dependencies = Icons.link;
|
||||||
|
static const IconData progress = Icons.show_chart;
|
||||||
|
static const IconData schedule = Icons.schedule;
|
||||||
|
static const IconData support = Icons.support;
|
||||||
|
static const IconData permissions = Icons.lock;
|
||||||
|
static const IconData backup = Icons.backup;
|
||||||
|
static const IconData integration = Icons.extension;
|
||||||
|
static const IconData search = Icons.search;
|
||||||
|
static const IconData announcement = Icons.announcement;
|
||||||
|
static const IconData analytics = Icons.analytics;
|
||||||
|
static const IconData assignment = Icons.assignment_turned_in;
|
||||||
|
static const IconData discussions = Icons.forum;
|
||||||
|
static const IconData timelineView = Icons.view_timeline;
|
||||||
|
static const IconData board = Icons.dashboard_customize;
|
||||||
|
static const IconData approval = Icons.how_to_vote;
|
||||||
|
static const IconData review = Icons.rate_review;
|
||||||
|
static const IconData objective = Icons.golf_course;
|
||||||
|
static const IconData settingsAdvanced = Icons.tune;
|
||||||
|
static const IconData timeTracking = Icons.timer_outlined;
|
||||||
|
static const IconData checklist = Icons.checklist;
|
||||||
|
static const IconData sync = Icons.sync;
|
||||||
|
static const IconData upload = Icons.cloud_upload;
|
||||||
|
static const IconData download = Icons.cloud_download;
|
||||||
|
static const IconData share = Icons.share;
|
||||||
|
static const IconData tag = Icons.label;
|
||||||
|
static const IconData notifications = Icons.notifications;
|
||||||
|
static const IconData userRoles = Icons.manage_accounts;
|
||||||
|
static const IconData logout = Icons.logout;
|
||||||
|
static const IconData automation = Icons.auto_awesome;
|
||||||
|
static const IconData history = Icons.history;
|
||||||
|
static const IconData estimate = Icons.calculate;
|
||||||
|
static const IconData quality = Icons.verified;
|
||||||
|
static const IconData strategy = Icons.lightbulb;
|
||||||
|
static const IconData feedbackForm = Icons.comment;
|
||||||
|
static const IconData presentation = Icons.slideshow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension IconDataKeyExtension on IconData {
|
||||||
|
String get toIconKey {
|
||||||
|
return iconMapping.entries.firstWhere(
|
||||||
|
(entry) => entry.value == this,
|
||||||
|
orElse: () => throw Exception('IconData not found in mapping.'),
|
||||||
|
).key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension IconDataFromKeyExtension on String {
|
||||||
|
IconData get toIconData {
|
||||||
|
final iconData = iconMapping[this];
|
||||||
|
if (iconData == null) {
|
||||||
|
throw Exception('No IconData found for key: $this');
|
||||||
|
}
|
||||||
|
return iconData;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
frontend/pshared/lib/data/mapper/organization.dart
Normal file
22
frontend/pshared/lib/data/mapper/organization.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:pshared/data/dto/organization.dart';
|
||||||
|
import 'package:pshared/models/organization/organization.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension OrganizationMapper on Organization {
|
||||||
|
OrganizationDTO toDTO() => OrganizationDTO(
|
||||||
|
id: storable.id,
|
||||||
|
createdAt: storable.createdAt,
|
||||||
|
updatedAt: storable.updatedAt,
|
||||||
|
timeZone: timeZone,
|
||||||
|
logoUrl: logoUrl,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension OrganizationDTOMapper on OrganizationDTO {
|
||||||
|
Organization toDomain() => Organization(
|
||||||
|
storable: newStorable(id: id, createdAt: createdAt, updatedAt: updatedAt),
|
||||||
|
timeZone: timeZone,
|
||||||
|
logoUrl: logoUrl,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:pshared/data/dto/organization/description.dart';
|
||||||
|
import 'package:pshared/models/organization/description.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension OrganizationDescriptionMapper on OrganizationDescription {
|
||||||
|
OrganizationDescriptionDTO toDTO() => OrganizationDescriptionDTO(
|
||||||
|
logoUrl: logoUrl,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountDescriptionDTOMapper on OrganizationDescriptionDTO {
|
||||||
|
OrganizationDescription toDomain() => OrganizationDescription(
|
||||||
|
logoUrl: logoUrl,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/action_effect.dart';
|
||||||
|
import 'package:pshared/models/permissions/action_effect.dart';
|
||||||
|
import 'package:pshared/models/permissions/action.dart';
|
||||||
|
import 'package:pshared/models/permissions/effect.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension ActionEffectMapper on ActionEffect {
|
||||||
|
ActionEffectDTO toDTO() {
|
||||||
|
return ActionEffectDTO(
|
||||||
|
action: action.toShortString(),
|
||||||
|
effect: effect.toShortString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ActionEffectDTOMapper on ActionEffectDTO {
|
||||||
|
ActionEffect toDomain() {
|
||||||
|
return ActionEffect(
|
||||||
|
action: ActionExtension.fromString(action),
|
||||||
|
effect: EffectExtension.fromString(effect),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/data/permission.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/action_effect.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/permission.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/policy.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension PermissionMapper on Permission {
|
||||||
|
PermissionDTO toDTO() {
|
||||||
|
return PermissionDTO(
|
||||||
|
roleDescriptionRef: policy.roleDescriptionRef,
|
||||||
|
organizationRef: policy.organizationRef,
|
||||||
|
descriptionRef: policy.descriptionRef,
|
||||||
|
objectRef: policy.objectRef,
|
||||||
|
effect: policy.effect.toDTO(),
|
||||||
|
accountRef: accountRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PermissionDTOMapper on PermissionDTO {
|
||||||
|
Permission toDomain() {
|
||||||
|
return Permission(
|
||||||
|
policy: Policy(
|
||||||
|
roleDescriptionRef: roleDescriptionRef,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
descriptionRef: descriptionRef,
|
||||||
|
objectRef: objectRef,
|
||||||
|
effect: effect.toDomain(),
|
||||||
|
),
|
||||||
|
accountRef: accountRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/data/permissions.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/data/permission.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/data/policy.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/data/role.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/permissions.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension PermissionsDataMapper on PermissionsData {
|
||||||
|
PermissionsDataDTO toDTO() {
|
||||||
|
return PermissionsDataDTO(
|
||||||
|
roles: roles.map((role) => role.toDTO()).toList(),
|
||||||
|
policies: policies.map((policy) => policy.toDTO()).toList(),
|
||||||
|
permissions: permissions.map((permission) => permission.toDTO()).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PermissionsDataDTOMapper on PermissionsDataDTO {
|
||||||
|
PermissionsData toDomain() {
|
||||||
|
return PermissionsData(
|
||||||
|
roles: roles.map((role) => role.toDomain()).toList(),
|
||||||
|
policies: policies.map((policy) => policy.toDomain()).toList(),
|
||||||
|
permissions: permissions.map((permission) => permission.toDomain()).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/data/policy.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/action_effect.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/policy.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension PolicyMapper on Policy {
|
||||||
|
PolicyDTO toDTO() {
|
||||||
|
return PolicyDTO(
|
||||||
|
roleDescriptionRef: roleDescriptionRef,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
descriptionRef: descriptionRef,
|
||||||
|
objectRef: objectRef,
|
||||||
|
effect: effect.toDTO(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PolicyDTOMapper on PolicyDTO {
|
||||||
|
Policy toDomain() {
|
||||||
|
return Policy(
|
||||||
|
roleDescriptionRef: roleDescriptionRef,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
descriptionRef: descriptionRef,
|
||||||
|
objectRef: objectRef,
|
||||||
|
effect: effect.toDomain(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
frontend/pshared/lib/data/mapper/permissions/data/role.dart
Normal file
25
frontend/pshared/lib/data/mapper/permissions/data/role.dart
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/data/role.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/role.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension RoleMapper on Role {
|
||||||
|
/// Converts a `Role` domain model to a `RoleDTO`.
|
||||||
|
RoleDTO toDTO() {
|
||||||
|
return RoleDTO(
|
||||||
|
accountRef: accountRef,
|
||||||
|
descriptionRef: descriptionRef,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RoleDTOMapper on RoleDTO {
|
||||||
|
/// Converts a `RoleDTO` to a `Role` domain model.
|
||||||
|
Role toDomain() {
|
||||||
|
return Role(
|
||||||
|
accountRef: accountRef,
|
||||||
|
descriptionRef: descriptionRef,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/description/description.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/descriptions/policy.dart';
|
||||||
|
import 'package:pshared/data/mapper/permissions/descriptions/role.dart';
|
||||||
|
import 'package:pshared/models/permissions/descriptions/permissions.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension PermissionsDescriptionMapper on PermissionsDescription {
|
||||||
|
PermissionsDescriptionDTO toDTO() {
|
||||||
|
return PermissionsDescriptionDTO(
|
||||||
|
roles: roles.map((role) => role.toDTO()).toList(),
|
||||||
|
policies: policies.map((policy) => policy.toDTO()).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PermissionsDescriptionDTOMapper on PermissionsDescriptionDTO {
|
||||||
|
PermissionsDescription toDomain() {
|
||||||
|
return PermissionsDescription(
|
||||||
|
roles: roles.map((role) => role.toDomain()).toList(),
|
||||||
|
policies: policies.map((policy) => policy.toDomain()).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/description/policy.dart';
|
||||||
|
import 'package:pshared/models/permissions/descriptions/policy.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension PolicyDescriptionMapper on PolicyDescription {
|
||||||
|
PolicyDescriptionDTO toDTO() => PolicyDescriptionDTO(
|
||||||
|
id: storable.id,
|
||||||
|
createdAt: storable.createdAt,
|
||||||
|
updatedAt: storable.updatedAt,
|
||||||
|
resourceTypes: resourceTypes,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PolicyDescriptionDTOMapper on PolicyDescriptionDTO {
|
||||||
|
PolicyDescription toDomain() => PolicyDescription(
|
||||||
|
storable: newStorable(id: id, createdAt: createdAt, updatedAt: createdAt),
|
||||||
|
resourceTypes: resourceTypes,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import 'package:pshared/data/dto/permissions/description/role.dart';
|
||||||
|
import 'package:pshared/models/permissions/descriptions/role.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension RoleDescriptionMapper on RoleDescription {
|
||||||
|
RoleDescriptionDTO toDTO() => RoleDescriptionDTO(
|
||||||
|
id: storable.id,
|
||||||
|
createdAt: storable.createdAt,
|
||||||
|
updatedAt: storable.updatedAt,
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RoleDescriptionDTOMapper on RoleDescriptionDTO {
|
||||||
|
RoleDescription toDomain() => RoleDescription(
|
||||||
|
storable: newStorable(id: id, createdAt: createdAt, updatedAt: updatedAt),
|
||||||
|
organizationRef: organizationRef,
|
||||||
|
);
|
||||||
|
}
|
||||||
11
frontend/pshared/lib/data/mapper/storable.dart
Normal file
11
frontend/pshared/lib/data/mapper/storable.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:pshared/data/dto/storable.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
extension StorableMapper on Storable {
|
||||||
|
StorableDTO toDTO() => StorableDTO(id: id, createdAt: createdAt, updatedAt: updatedAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StorableDTOMapper on StorableDTO {
|
||||||
|
Storable toDomain() => newStorable(id: id, createdAt: createdAt, updatedAt: updatedAt);
|
||||||
|
}
|
||||||
23
frontend/pshared/lib/l10n/ps_en.arb
Normal file
23
frontend/pshared/lib/l10n/ps_en.arb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"@@locale": "en",
|
||||||
|
|
||||||
|
"statusReady": "Ready",
|
||||||
|
"statusRegistered": "Registered",
|
||||||
|
"statusNotRegistered": "Not Registered",
|
||||||
|
"typeInternal": "Internal",
|
||||||
|
"typeExternal": "External",
|
||||||
|
"operationStatusProcessing": "Processing",
|
||||||
|
"@operationStatusProcessing": {
|
||||||
|
"description": "Label for the “processing” operation status"
|
||||||
|
},
|
||||||
|
|
||||||
|
"operationStatusSuccess": "Success",
|
||||||
|
"@operationStatusSuccess": {
|
||||||
|
"description": "Label for the “success” operation status"
|
||||||
|
},
|
||||||
|
|
||||||
|
"operationStatusError": "Error",
|
||||||
|
"@operationStatusError": {
|
||||||
|
"description": "Label for the “error” operation status"
|
||||||
|
}
|
||||||
|
}
|
||||||
36
frontend/pshared/lib/models/account/account.dart
Normal file
36
frontend/pshared/lib/models/account/account.dart
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import 'package:pshared/models/account/base.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class Account extends AccountBase {
|
||||||
|
final String login;
|
||||||
|
|
||||||
|
const Account({
|
||||||
|
required super.storable,
|
||||||
|
required super.avatarUrl,
|
||||||
|
required this.login,
|
||||||
|
required super.locale,
|
||||||
|
required super.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Account.fromBase(AccountBase accountBase, String login) => Account(
|
||||||
|
storable: accountBase.storable,
|
||||||
|
avatarUrl: accountBase.avatarUrl,
|
||||||
|
locale: accountBase.locale,
|
||||||
|
name: accountBase.name,
|
||||||
|
login: login,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Account copyWith({
|
||||||
|
String? Function()? avatarUrl,
|
||||||
|
String? name,
|
||||||
|
String? locale,
|
||||||
|
}) {
|
||||||
|
final updatedBase = super.copyWith(
|
||||||
|
avatarUrl: avatarUrl,
|
||||||
|
name: name,
|
||||||
|
locale: locale,
|
||||||
|
);
|
||||||
|
return Account.fromBase(updatedBase, login);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
frontend/pshared/lib/models/account/base.dart
Normal file
35
frontend/pshared/lib/models/account/base.dart
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class AccountBase implements Storable {
|
||||||
|
final Storable storable;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get id => storable.id;
|
||||||
|
@override
|
||||||
|
DateTime get createdAt => storable.createdAt;
|
||||||
|
@override
|
||||||
|
DateTime get updatedAt => storable.updatedAt;
|
||||||
|
|
||||||
|
final String? avatarUrl;
|
||||||
|
final String name;
|
||||||
|
final String locale;
|
||||||
|
|
||||||
|
const AccountBase({
|
||||||
|
required this.storable,
|
||||||
|
required this.name,
|
||||||
|
required this.locale,
|
||||||
|
required this.avatarUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
AccountBase copyWith({
|
||||||
|
String? Function()? avatarUrl,
|
||||||
|
String? name,
|
||||||
|
String? locale,
|
||||||
|
}) => AccountBase(
|
||||||
|
storable: storable,
|
||||||
|
avatarUrl: avatarUrl != null ? avatarUrl() : this.avatarUrl,
|
||||||
|
locale: locale ?? this.locale,
|
||||||
|
name: name ?? this.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class OrganizationDescription {
|
||||||
|
final String? logoUrl;
|
||||||
|
|
||||||
|
const OrganizationDescription({
|
||||||
|
this.logoUrl,
|
||||||
|
});
|
||||||
|
}
|
||||||
4
frontend/pshared/lib/models/organization/employee.dart
Normal file
4
frontend/pshared/lib/models/organization/employee.dart
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import 'package:pshared/models/account/account.dart';
|
||||||
|
|
||||||
|
|
||||||
|
typedef Employee = Account;
|
||||||
34
frontend/pshared/lib/models/organization/organization.dart
Normal file
34
frontend/pshared/lib/models/organization/organization.dart
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class Organization implements Storable {
|
||||||
|
final Storable storable;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get id => storable.id;
|
||||||
|
@override
|
||||||
|
DateTime get createdAt => storable.createdAt;
|
||||||
|
@override
|
||||||
|
DateTime get updatedAt => storable.updatedAt;
|
||||||
|
|
||||||
|
final String timeZone;
|
||||||
|
final String? logoUrl;
|
||||||
|
|
||||||
|
const Organization({
|
||||||
|
required this.storable,
|
||||||
|
required this.timeZone,
|
||||||
|
this.logoUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Organization copyWith({
|
||||||
|
String? name,
|
||||||
|
String? Function()? description,
|
||||||
|
String? timeZone,
|
||||||
|
String? Function()? logoUrl,
|
||||||
|
}) => Organization(
|
||||||
|
storable: storable, // Same Storable, same id
|
||||||
|
timeZone: timeZone ?? this.timeZone,
|
||||||
|
logoUrl: logoUrl != null ? logoUrl() : this.logoUrl,
|
||||||
|
);
|
||||||
|
}
|
||||||
18
frontend/pshared/lib/models/payment/methods/card.dart
Normal file
18
frontend/pshared/lib/models/payment/methods/card.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:pshared/models/payment/methods/data.dart';
|
||||||
|
import 'package:pshared/models/payment/type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class CardPaymentMethod extends PaymentMethodData {
|
||||||
|
@override
|
||||||
|
final PaymentType type = PaymentType.card;
|
||||||
|
|
||||||
|
final String pan;
|
||||||
|
final String firstName;
|
||||||
|
final String lastName;
|
||||||
|
|
||||||
|
CardPaymentMethod({
|
||||||
|
required this.pan,
|
||||||
|
required this.firstName,
|
||||||
|
required this.lastName,
|
||||||
|
});
|
||||||
|
}
|
||||||
6
frontend/pshared/lib/models/payment/methods/data.dart
Normal file
6
frontend/pshared/lib/models/payment/methods/data.dart
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import 'package:pshared/models/payment/type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
abstract class PaymentMethodData {
|
||||||
|
PaymentType get type;
|
||||||
|
}
|
||||||
20
frontend/pshared/lib/models/payment/methods/iban.dart
Normal file
20
frontend/pshared/lib/models/payment/methods/iban.dart
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import 'package:pshared/models/payment/methods/data.dart';
|
||||||
|
import 'package:pshared/models/payment/type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class IbanPaymentMethod extends PaymentMethodData {
|
||||||
|
@override
|
||||||
|
final PaymentType type = PaymentType.iban;
|
||||||
|
|
||||||
|
final String iban; // e.g. DE89 3704 0044 0532 0130 00
|
||||||
|
final String accountHolder; // Full name of the recipient
|
||||||
|
final String? bic; // Optional: for cross-border transfers
|
||||||
|
final String? bankName; // Optional: for UI clarity
|
||||||
|
|
||||||
|
IbanPaymentMethod({
|
||||||
|
required this.iban,
|
||||||
|
required this.accountHolder,
|
||||||
|
this.bic,
|
||||||
|
this.bankName,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:pshared/models/payment/methods/data.dart';
|
||||||
|
import 'package:pshared/models/payment/type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class RussianBankAccountPaymentMethod extends PaymentMethodData {
|
||||||
|
@override
|
||||||
|
final PaymentType type = PaymentType.bankAccount;
|
||||||
|
|
||||||
|
final String recipientName;
|
||||||
|
final String inn;
|
||||||
|
final String kpp;
|
||||||
|
final String bankName;
|
||||||
|
final String bik;
|
||||||
|
final String accountNumber;
|
||||||
|
final String correspondentAccount;
|
||||||
|
|
||||||
|
RussianBankAccountPaymentMethod({
|
||||||
|
required this.recipientName,
|
||||||
|
required this.inn,
|
||||||
|
required this.kpp,
|
||||||
|
required this.bankName,
|
||||||
|
required this.bik,
|
||||||
|
required this.accountNumber,
|
||||||
|
required this.correspondentAccount,
|
||||||
|
});
|
||||||
|
}
|
||||||
21
frontend/pshared/lib/models/payment/methods/type.dart
Normal file
21
frontend/pshared/lib/models/payment/methods/type.dart
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:pshared/models/payment/type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentMethod {
|
||||||
|
PaymentMethod({
|
||||||
|
required this.id,
|
||||||
|
required this.label,
|
||||||
|
required this.details,
|
||||||
|
required this.type,
|
||||||
|
this.isEnabled = true,
|
||||||
|
this.isMain = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String id;
|
||||||
|
final String label;
|
||||||
|
final String details;
|
||||||
|
final PaymentType type;
|
||||||
|
|
||||||
|
bool isEnabled;
|
||||||
|
bool isMain;
|
||||||
|
}
|
||||||
12
frontend/pshared/lib/models/payment/methods/wallet.dart
Normal file
12
frontend/pshared/lib/models/payment/methods/wallet.dart
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import 'package:pshared/models/payment/methods/data.dart';
|
||||||
|
import 'package:pshared/models/payment/type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class WalletPaymentMethod extends PaymentMethodData {
|
||||||
|
@override
|
||||||
|
final PaymentType type = PaymentType.wallet;
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
WalletPaymentMethod({required this.walletId});
|
||||||
|
}
|
||||||
30
frontend/pshared/lib/models/payment/operation.dart
Normal file
30
frontend/pshared/lib/models/payment/operation.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:pshared/models/payment/status.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class OperationItem {
|
||||||
|
final OperationStatus status;
|
||||||
|
final String? fileName;
|
||||||
|
final double amount;
|
||||||
|
final String currency;
|
||||||
|
final double toAmount;
|
||||||
|
final String toCurrency;
|
||||||
|
final String payId;
|
||||||
|
final String? cardNumber;
|
||||||
|
final String name;
|
||||||
|
final DateTime date;
|
||||||
|
final String comment;
|
||||||
|
|
||||||
|
OperationItem({
|
||||||
|
required this.status,
|
||||||
|
this.fileName,
|
||||||
|
required this.amount,
|
||||||
|
required this.currency,
|
||||||
|
required this.toAmount,
|
||||||
|
required this.toCurrency,
|
||||||
|
required this.payId,
|
||||||
|
this.cardNumber,
|
||||||
|
required this.name,
|
||||||
|
required this.date,
|
||||||
|
required this.comment,
|
||||||
|
});
|
||||||
|
}
|
||||||
25
frontend/pshared/lib/models/payment/status.dart
Normal file
25
frontend/pshared/lib/models/payment/status.dart
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:pshared/generated/i18n/ps_localizations.dart';
|
||||||
|
|
||||||
|
enum OperationStatus {
|
||||||
|
processing,
|
||||||
|
success,
|
||||||
|
error,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension OperationStatusX on OperationStatus {
|
||||||
|
/// Returns the localized string for this status,
|
||||||
|
/// e.g. “Processing”, “Success”, “Error”.
|
||||||
|
String localized(BuildContext context) {
|
||||||
|
final loc = PSLocalizations.of(context)!;
|
||||||
|
switch (this) {
|
||||||
|
case OperationStatus.processing:
|
||||||
|
return loc.operationStatusProcessing;
|
||||||
|
case OperationStatus.success:
|
||||||
|
return loc.operationStatusSuccess;
|
||||||
|
case OperationStatus.error:
|
||||||
|
return loc.operationStatusError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
frontend/pshared/lib/models/payment/type.dart
Normal file
6
frontend/pshared/lib/models/payment/type.dart
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
enum PaymentType {
|
||||||
|
bankAccount,
|
||||||
|
iban,
|
||||||
|
wallet,
|
||||||
|
card,
|
||||||
|
}
|
||||||
11
frontend/pshared/lib/models/payment/upload_history_item.dart
Normal file
11
frontend/pshared/lib/models/payment/upload_history_item.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
class UploadHistoryItem {
|
||||||
|
final String name;
|
||||||
|
final String status;
|
||||||
|
final String time;
|
||||||
|
|
||||||
|
UploadHistoryItem({
|
||||||
|
required this.name,
|
||||||
|
required this.status,
|
||||||
|
required this.time,
|
||||||
|
});
|
||||||
|
}
|
||||||
22
frontend/pshared/lib/models/permission_bound.dart
Normal file
22
frontend/pshared/lib/models/permission_bound.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:pshared/config/constants.dart';
|
||||||
|
|
||||||
|
|
||||||
|
abstract class PermissionBound {
|
||||||
|
String get permissionRef;
|
||||||
|
String get organizationRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PermissionBoundImp implements PermissionBound {
|
||||||
|
@override
|
||||||
|
final String permissionRef;
|
||||||
|
@override
|
||||||
|
final String organizationRef;
|
||||||
|
|
||||||
|
const _PermissionBoundImp({
|
||||||
|
required this.permissionRef,
|
||||||
|
required this.organizationRef,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
PermissionBound newPermissionBound({ required String organizationRef, String? permissionRef}) =>
|
||||||
|
_PermissionBoundImp(permissionRef: permissionRef ?? Constants.nilObjectRef, organizationRef: organizationRef);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import 'package:pshared/models/permission_bound.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
abstract class PermissionBoundStorable implements PermissionBound, Storable {
|
||||||
|
}
|
||||||
13
frontend/pshared/lib/models/permissions/access.dart
Normal file
13
frontend/pshared/lib/models/permissions/access.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:pshared/models/permissions/data/permissions.dart';
|
||||||
|
import 'package:pshared/models/permissions/descriptions/permissions.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class UserAccess {
|
||||||
|
final PermissionsDescription descriptions;
|
||||||
|
final PermissionsData permissions;
|
||||||
|
|
||||||
|
const UserAccess({
|
||||||
|
required this.descriptions,
|
||||||
|
required this.permissions,
|
||||||
|
});
|
||||||
|
}
|
||||||
15
frontend/pshared/lib/models/permissions/action.dart
Normal file
15
frontend/pshared/lib/models/permissions/action.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
enum Action {
|
||||||
|
create,
|
||||||
|
read,
|
||||||
|
update,
|
||||||
|
delete,
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ActionExtension on Action {
|
||||||
|
String toShortString() => toString().split('.').last;
|
||||||
|
|
||||||
|
static Action fromString(String value) => Action.values.firstWhere(
|
||||||
|
(e) => e.toShortString() == value,
|
||||||
|
orElse: () => throw ArgumentError('Invalid action: $value'),
|
||||||
|
);
|
||||||
|
}
|
||||||
13
frontend/pshared/lib/models/permissions/action_effect.dart
Normal file
13
frontend/pshared/lib/models/permissions/action_effect.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:pshared/models/permissions/action.dart';
|
||||||
|
import 'package:pshared/models/permissions/effect.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class ActionEffect {
|
||||||
|
final Action action; // The action allowed or denied
|
||||||
|
final Effect effect; // The effect of the policy ("allow" or "deny")
|
||||||
|
|
||||||
|
const ActionEffect({
|
||||||
|
required this.action,
|
||||||
|
required this.effect,
|
||||||
|
});
|
||||||
|
}
|
||||||
12
frontend/pshared/lib/models/permissions/data/permission.dart
Normal file
12
frontend/pshared/lib/models/permissions/data/permission.dart
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import 'package:pshared/models/permissions/data/policy.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class Permission {
|
||||||
|
final Policy policy;
|
||||||
|
final String accountRef;
|
||||||
|
|
||||||
|
const Permission({
|
||||||
|
required this.policy,
|
||||||
|
required this.accountRef,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import 'package:pshared/models/permissions/data/permission.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/policy.dart';
|
||||||
|
import 'package:pshared/models/permissions/data/role.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionsData {
|
||||||
|
final List<Role> roles;
|
||||||
|
final List<Policy> policies;
|
||||||
|
final List<Permission> permissions;
|
||||||
|
|
||||||
|
const PermissionsData({
|
||||||
|
required this.roles,
|
||||||
|
required this.policies,
|
||||||
|
required this.permissions,
|
||||||
|
});
|
||||||
|
}
|
||||||
18
frontend/pshared/lib/models/permissions/data/policy.dart
Normal file
18
frontend/pshared/lib/models/permissions/data/policy.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:pshared/models/permissions/action_effect.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class Policy {
|
||||||
|
final String roleDescriptionRef;
|
||||||
|
final String organizationRef;
|
||||||
|
final String descriptionRef;
|
||||||
|
final String? objectRef;
|
||||||
|
final ActionEffect effect;
|
||||||
|
|
||||||
|
const Policy({
|
||||||
|
required this.roleDescriptionRef,
|
||||||
|
required this.organizationRef,
|
||||||
|
required this.descriptionRef,
|
||||||
|
required this.objectRef,
|
||||||
|
required this.effect,
|
||||||
|
});
|
||||||
|
}
|
||||||
11
frontend/pshared/lib/models/permissions/data/role.dart
Normal file
11
frontend/pshared/lib/models/permissions/data/role.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
class Role {
|
||||||
|
final String accountRef;
|
||||||
|
final String organizationRef;
|
||||||
|
final String descriptionRef;
|
||||||
|
|
||||||
|
const Role({
|
||||||
|
required this.accountRef,
|
||||||
|
required this.descriptionRef,
|
||||||
|
required this.organizationRef,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:pshared/models/permissions/descriptions/policy.dart';
|
||||||
|
import 'package:pshared/models/permissions/descriptions/role.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionsDescription {
|
||||||
|
final List<RoleDescription> roles;
|
||||||
|
final List<PolicyDescription> policies;
|
||||||
|
|
||||||
|
const PermissionsDescription({
|
||||||
|
required this.roles,
|
||||||
|
required this.policies,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:pshared/models/resources.dart';
|
||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class PolicyDescription implements Storable {
|
||||||
|
final Storable storable;
|
||||||
|
final List<ResourceType>? resourceTypes;
|
||||||
|
final String? organizationRef;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get id => storable.id;
|
||||||
|
@override
|
||||||
|
DateTime get createdAt => storable.createdAt;
|
||||||
|
@override
|
||||||
|
DateTime get updatedAt => storable.updatedAt;
|
||||||
|
|
||||||
|
const PolicyDescription({
|
||||||
|
required this.storable,
|
||||||
|
required this.resourceTypes,
|
||||||
|
required this.organizationRef,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import 'package:pshared/models/storable.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class RoleDescription implements Storable {
|
||||||
|
final Storable storable;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get id => storable.id;
|
||||||
|
@override
|
||||||
|
DateTime get createdAt => storable.createdAt;
|
||||||
|
@override
|
||||||
|
DateTime get updatedAt => storable.updatedAt;
|
||||||
|
|
||||||
|
final String organizationRef;
|
||||||
|
|
||||||
|
const RoleDescription({
|
||||||
|
required this.storable,
|
||||||
|
required this.organizationRef,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory RoleDescription.build({
|
||||||
|
required String organizationRef,
|
||||||
|
}) => RoleDescription(
|
||||||
|
storable: newStorable(),
|
||||||
|
organizationRef: organizationRef
|
||||||
|
);
|
||||||
|
}
|
||||||
13
frontend/pshared/lib/models/permissions/effect.dart
Normal file
13
frontend/pshared/lib/models/permissions/effect.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
enum Effect {
|
||||||
|
allow,
|
||||||
|
deny,
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EffectExtension on Effect {
|
||||||
|
String toShortString() => toString().split('.').last;
|
||||||
|
|
||||||
|
static Effect fromString(String value) => Effect.values.firstWhere(
|
||||||
|
(e) => e.toShortString() == value,
|
||||||
|
orElse: () => throw ArgumentError('Invalid effect: $value'),
|
||||||
|
);
|
||||||
|
}
|
||||||
0
frontend/pshared/lib/models/pfe/services.dart
Normal file
0
frontend/pshared/lib/models/pfe/services.dart
Normal file
1
frontend/pshared/lib/models/recipient/filter.dart
Normal file
1
frontend/pshared/lib/models/recipient/filter.dart
Normal file
@@ -0,0 +1 @@
|
|||||||
|
enum RecipientFilter { all, ready, registered, notRegistered }
|
||||||
78
frontend/pshared/lib/models/recipient/recipient.dart
Normal file
78
frontend/pshared/lib/models/recipient/recipient.dart
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import 'package:pshared/models/payment/methods/card.dart';
|
||||||
|
import 'package:pshared/models/payment/methods/iban.dart';
|
||||||
|
import 'package:pshared/models/payment/methods/russian_bank.dart';
|
||||||
|
import 'package:pshared/models/payment/methods/wallet.dart';
|
||||||
|
import 'package:pshared/models/recipient/status.dart';
|
||||||
|
import 'package:pshared/models/recipient/type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class Recipient {
|
||||||
|
final String? avatarUrl; // network URL / local asset
|
||||||
|
final String name;
|
||||||
|
final String email;
|
||||||
|
final RecipientStatus status;
|
||||||
|
final RecipientType type;
|
||||||
|
final CardPaymentMethod? card;
|
||||||
|
final IbanPaymentMethod? iban;
|
||||||
|
final RussianBankAccountPaymentMethod? bank;
|
||||||
|
final WalletPaymentMethod? wallet;
|
||||||
|
|
||||||
|
const Recipient({
|
||||||
|
this.avatarUrl,
|
||||||
|
required this.name,
|
||||||
|
required this.email,
|
||||||
|
required this.status,
|
||||||
|
required this.type,
|
||||||
|
this.card,
|
||||||
|
this.iban,
|
||||||
|
this.bank,
|
||||||
|
this.wallet,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Convenience factory for quickly creating mock recipients.
|
||||||
|
factory Recipient.mock({
|
||||||
|
required String name,
|
||||||
|
required String email,
|
||||||
|
required RecipientStatus status,
|
||||||
|
required RecipientType type,
|
||||||
|
CardPaymentMethod? card,
|
||||||
|
IbanPaymentMethod? iban,
|
||||||
|
RussianBankAccountPaymentMethod? bank,
|
||||||
|
WalletPaymentMethod? wallet,
|
||||||
|
}) =>
|
||||||
|
Recipient(
|
||||||
|
avatarUrl: null,
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
status: status,
|
||||||
|
type: type,
|
||||||
|
card: card,
|
||||||
|
iban: iban,
|
||||||
|
bank: bank,
|
||||||
|
wallet: wallet,
|
||||||
|
);
|
||||||
|
|
||||||
|
bool matchesQuery(String q) {
|
||||||
|
final searchable = [
|
||||||
|
name,
|
||||||
|
email,
|
||||||
|
card?.pan,
|
||||||
|
card?.firstName,
|
||||||
|
card?.lastName,
|
||||||
|
iban?.iban,
|
||||||
|
iban?.accountHolder,
|
||||||
|
iban?.bic,
|
||||||
|
iban?.bankName,
|
||||||
|
bank?.accountNumber,
|
||||||
|
bank?.recipientName,
|
||||||
|
bank?.inn,
|
||||||
|
bank?.kpp,
|
||||||
|
bank?.bankName,
|
||||||
|
bank?.bik,
|
||||||
|
bank?.correspondentAccount,
|
||||||
|
wallet?.walletId,
|
||||||
|
];
|
||||||
|
|
||||||
|
return searchable.any((field) => field?.toLowerCase().contains(q) ?? false);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
frontend/pshared/lib/models/recipient/status.dart
Normal file
22
frontend/pshared/lib/models/recipient/status.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'package:pshared/generated/i18n/ps_localizations.dart';
|
||||||
|
|
||||||
|
|
||||||
|
/// Possible payout readiness states.
|
||||||
|
enum RecipientStatus { ready, registered, notRegistered }
|
||||||
|
|
||||||
|
extension RecipientStatusExtension on RecipientStatus {
|
||||||
|
/// Human-readable, **localized** label for display in the UI.
|
||||||
|
String label(BuildContext context) {
|
||||||
|
final l10n = PSLocalizations.of(context)!;
|
||||||
|
switch (this) {
|
||||||
|
case RecipientStatus.ready:
|
||||||
|
return l10n.statusReady;
|
||||||
|
case RecipientStatus.registered:
|
||||||
|
return l10n.statusRegistered;
|
||||||
|
case RecipientStatus.notRegistered:
|
||||||
|
return l10n.statusNotRegistered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user