Frontend first draft

This commit is contained in:
Arseni
2025-11-13 15:06:15 +03:00
parent e47f343afb
commit ddb54ddfdc
504 changed files with 25498 additions and 1 deletions

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View 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);
}

View 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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View 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);
}

Binary file not shown.

View 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,
);
}

View 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,
);
}

View 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;
}
}

View 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,
);
}

View File

@@ -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,
);
}

View File

@@ -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),
);
}
}

View File

@@ -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,
);
}
}

View File

@@ -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(),
);
}
}

View File

@@ -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(),
);
}
}

View 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,
);
}
}

View File

@@ -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(),
);
}
}

View File

@@ -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,
);
}

View File

@@ -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,
);
}

View 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);
}