From ce57791700a178679aa51015cd6ec3a37eacc994 Mon Sep 17 00:00:00 2001 From: Reza Rahemtola Date: Sun, 5 Nov 2023 03:10:57 +0100 Subject: [PATCH] feat(mobile/library): Duplicate workflow --- .../lib/components/library/workflow_tile.dart | 23 +++++++++++-- frontend/mobile/lib/locales/app_en.arb | 2 ++ frontend/mobile/lib/locales/app_fr.arb | 2 ++ frontend/mobile/lib/locales/app_is.arb | 2 ++ frontend/mobile/lib/pages/landing.dart | 9 ++--- frontend/mobile/lib/pages/library.dart | 3 +- frontend/mobile/lib/utils/workflows.dart | 34 +++++++++++++++++++ 7 files changed, 65 insertions(+), 10 deletions(-) diff --git a/frontend/mobile/lib/components/library/workflow_tile.dart b/frontend/mobile/lib/components/library/workflow_tile.dart index 8d48ccf8..915c2723 100644 --- a/frontend/mobile/lib/components/library/workflow_tile.dart +++ b/frontend/mobile/lib/components/library/workflow_tile.dart @@ -1,6 +1,7 @@ import 'package:area_mobile/components/editor/modals/name_modal.dart'; import 'package:area_mobile/services/dio.dart'; import 'package:area_mobile/types/services.dart'; +import 'package:area_mobile/types/workflows/editor.dart'; import 'package:area_mobile/types/workflows/workflows.dart'; import 'package:area_mobile/utils/workflows.dart'; import 'package:flutter/material.dart'; @@ -10,7 +11,7 @@ import 'package:flutter_svg/svg.dart'; class WorkflowTile extends StatefulWidget { final Workflow workflow; final Function onUpdate; - final Function(Workflow workflow) onOpenEditor; + final Function(EditorWorkflow workflow) onOpenEditor; const WorkflowTile({ required this.workflow, @@ -64,9 +65,25 @@ class _WorkflowTileState extends State { child: ListTile( leading: const Icon(Icons.edit), title: Text(AppLocalizations.of(context)!.edit), - onTap: () { + onTap: () async { + Navigator.pop(context); + final editorWorkflow = + await convertWorkflowToEditorWorkflow(widget.workflow); + widget.onOpenEditor(editorWorkflow); + }), + ), + PopupMenuItem( + value: "duplicate", + child: ListTile( + leading: const Icon(Icons.content_copy), + title: Text(AppLocalizations.of(context)!.duplicate), + onTap: () async { Navigator.pop(context); - widget.onOpenEditor(widget.workflow); + final duplicatedWorkflow = + await convertWorkflowToDuplicateEditorWorkflow( + widget.workflow, + AppLocalizations.of(context)!.copyWorkflow); + widget.onOpenEditor(duplicatedWorkflow); }), ), PopupMenuItem( diff --git a/frontend/mobile/lib/locales/app_en.arb b/frontend/mobile/lib/locales/app_en.arb index 663af6cd..e112d38d 100644 --- a/frontend/mobile/lib/locales/app_en.arb +++ b/frontend/mobile/lib/locales/app_en.arb @@ -29,6 +29,8 @@ "back": "Back", "rename": "Rename", "edit": "Edit", + "duplicate": "Duplicate", + "copyWorkflow": "Copy", "delete": "Delete", "editorActionDescription": "An event that starts your workflow", "editorReactionDescription": "An event a workflow performs after it start", diff --git a/frontend/mobile/lib/locales/app_fr.arb b/frontend/mobile/lib/locales/app_fr.arb index fd2851ea..216d33d6 100644 --- a/frontend/mobile/lib/locales/app_fr.arb +++ b/frontend/mobile/lib/locales/app_fr.arb @@ -29,6 +29,8 @@ "back": "Précédent", "rename": "Renommer", "edit": "Modifier", + "duplicate": "Dupliquer", + "copyWorkflow": "Copie", "delete": "Supprimer", "editorActionDescription": "Un événement qui lance votre workflow", "editorReactionDescription": "Un événement qu'un workflow exécutes une fois lancé", diff --git a/frontend/mobile/lib/locales/app_is.arb b/frontend/mobile/lib/locales/app_is.arb index 435c8949..d3b4a1ba 100644 --- a/frontend/mobile/lib/locales/app_is.arb +++ b/frontend/mobile/lib/locales/app_is.arb @@ -29,6 +29,8 @@ "back": "Fyrri", "rename": "Endurnefna", "edit": "Til að breyta", + "duplicate": "Afrit", + "copyWorkflow": "Afrita", "delete": "EYÐA", "editorActionDescription": "Atburður sem ræsir vinnuflæðið þitt", "editorReactionDescription": "Atburður sem verkflæði keyrir þegar það er ræst", diff --git a/frontend/mobile/lib/pages/landing.dart b/frontend/mobile/lib/pages/landing.dart index f0c0a6ff..bc74bad2 100644 --- a/frontend/mobile/lib/pages/landing.dart +++ b/frontend/mobile/lib/pages/landing.dart @@ -6,7 +6,6 @@ import 'package:area_mobile/pages/services.dart'; import 'package:area_mobile/pages/user.dart'; import 'package:area_mobile/storage/index.dart'; import 'package:area_mobile/types/workflows/editor.dart'; -import 'package:area_mobile/types/workflows/workflows.dart'; import 'package:area_mobile/utils/workflows.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -141,11 +140,9 @@ class _LandingPageState extends State { Center( child: Library( key: ValueKey(libraryKey), - onOpenEditor: (Workflow workflowToOpen) async { - final newEditorWorkflow = - await convertWorkflowToEditorWorkflow(workflowToOpen); + onOpenEditor: (EditorWorkflow workflowToOpen) async { setState(() { - editorWorkflow = newEditorWorkflow; + editorWorkflow = workflowToOpen; editorKey++; _selectedIndex = 2; }); @@ -157,7 +154,7 @@ class _LandingPageState extends State { ), Center( child: Editor( - key: ValueKey(editorWorkflow.id), + key: ValueKey(editorKey), workflow: editorWorkflow, onSave: () { setState(() { diff --git a/frontend/mobile/lib/pages/library.dart b/frontend/mobile/lib/pages/library.dart index 1eaed18b..b6a4b428 100644 --- a/frontend/mobile/lib/pages/library.dart +++ b/frontend/mobile/lib/pages/library.dart @@ -2,12 +2,13 @@ import 'package:area_mobile/components/empty_notice.dart'; import 'package:area_mobile/components/library/workflow_tile.dart'; import 'package:area_mobile/services/dio.dart'; import 'package:area_mobile/types/services.dart'; +import 'package:area_mobile/types/workflows/editor.dart'; import 'package:area_mobile/types/workflows/workflows.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class Library extends StatefulWidget { - final Function(Workflow workflow) onOpenEditor; + final Function(EditorWorkflow workflow) onOpenEditor; const Library({required this.onOpenEditor, Key? key}) : super(key: key); diff --git a/frontend/mobile/lib/utils/workflows.dart b/frontend/mobile/lib/utils/workflows.dart index dfe24f5a..3a841c00 100644 --- a/frontend/mobile/lib/utils/workflows.dart +++ b/frontend/mobile/lib/utils/workflows.dart @@ -106,6 +106,40 @@ Future convertWorkflowToEditorWorkflow( active: workflow.active); } +Future convertWorkflowToDuplicateEditorWorkflow( + Workflow workflow, String copyText) async { + var editorWorkflow = await convertWorkflowToEditorWorkflow(workflow); + + Map idMapping = {}; + for (var id in [ + editorWorkflow.action.id, + ...editorWorkflow.reactions.map((e) => e.id) + ]) { + idMapping[id] = const UuidV4().generate().toString(); + } + + final newAction = EditorWorkflowAction( + id: idMapping[editorWorkflow.action.id]!, + area: editorWorkflow.action.area, + areaService: editorWorkflow.action.areaService); + + final newReactions = editorWorkflow.reactions + .map((reaction) => EditorWorkflowReaction( + id: idMapping[reaction.id]!, + area: reaction.area, + areaService: reaction.areaService, + previousAreaId: idMapping[editorWorkflow.reactions + .firstWhere((e) => e.id == reaction.id) + .previousAreaId]!)) + .toList(); + + return EditorWorkflow( + name: "${editorWorkflow.name} ($copyText)", + action: newAction, + reactions: newReactions, + active: editorWorkflow.active); +} + List getSortedReactions(List reactions, String basePreviousId) { final sortedReactions = []; var previousId = basePreviousId;