diff --git a/project/FrontEnd/collaborative_science_platform/lib/providers/workspace_provider.dart b/project/FrontEnd/collaborative_science_platform/lib/providers/workspace_provider.dart index 0fe0c73c..de85a190 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/providers/workspace_provider.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/providers/workspace_provider.dart @@ -277,6 +277,29 @@ class WorkspaceProvider with ChangeNotifier { throw Exception("Something has happened"); } } + Future sendWorkspaceToReview(int workspaceId, int userId, String token) async { + Uri url = Uri.parse("${Constants.apiUrl}/send_rev_req/"); + + var request = http.MultipartRequest('POST', url); + request.headers.addAll({ + "Authorization": "Token $token", + "content-type": "application/json", + }); + request.fields.addAll({ + 'workspace_id': "$workspaceId", + 'sender': "$userId", + }); + + http.StreamedResponse response = await request.send(); + if (response.statusCode == 200) { + //print(await response.stream.bytesToString()); + notifyListeners(); + } else if (response.statusCode == 400) { + throw FinalizeWorkspaceException(); + } else { + throw Exception("Something has happened"); + } + } Future deleteReference(int workspaceId, int nodeId, String token) async { Uri url = Uri.parse("${Constants.apiUrl}/delete_reference/"); diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/mobile_workspace_page.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/mobile_workspace_page.dart index f50b3cc3..fff0bf49 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/mobile_workspace_page.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/mobile_workspace_page.dart @@ -27,6 +27,7 @@ class MobileWorkspacePage extends StatefulWidget { final Function sendCollaborationRequest; final Function finalizeWorkspace; final Function addSemanticTags; + final Function sendWorkspaceToReview; const MobileWorkspacePage({ super.key, @@ -39,10 +40,11 @@ class MobileWorkspacePage extends StatefulWidget { required this.addReference, required this.deleteReference, required this.editTitle, - required this.addSemanticTags, - required this.finalizeWorkspace, - required this.sendCollaborationRequest, - required this.updateRequest + required this.addSemanticTags, + required this.finalizeWorkspace, + required this.sendCollaborationRequest, + required this.updateRequest, + required this.sendWorkspaceToReview, }); @override @@ -146,67 +148,6 @@ class _MobileWorkspacesPageState extends State { ], ), ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 3.0), - child: IconButton( - icon: pending - ? const Icon(Icons.keyboard_arrow_right) - : const Icon(Icons.send), - onPressed: pending - ? () { - // accept or reject the review - showDialog( - context: context, - builder: (context) => AppAlertDialog( - text: "Do you accept the work?", - actions: [ - AppButton( - text: "Accept", - height: 40, - onTap: () { - /* Send to review */ - Navigator.of(context).pop(); - }, - ), - AppButton( - text: "Reject", - height: 40, - onTap: () { - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - } - : () { - // send to review - showDialog( - context: context, - builder: (context) => AppAlertDialog( - text: "Do you want to send it to review?", - actions: [ - AppButton( - text: "Yes", - height: 40, - onTap: () { - /* Send to review */ - Navigator.of(context).pop(); - }, - ), - AppButton( - text: "No", - height: 40, - onTap: () { - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - }, - ), - ), ], ), ), @@ -356,7 +297,7 @@ class _MobileWorkspacesPageState extends State { finalizeWorkspace: widget.finalizeWorkspace, sendCollaborationRequest: widget.sendCollaborationRequest, updateRequest: widget.updateRequest, - + sendWorkspaceToReview: widget.sendWorkspaceToReview, ) : const SizedBox( width: 100, diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/widget/mobile_workspace_content.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/widget/mobile_workspace_content.dart index 13b32173..a2de072f 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/widget/mobile_workspace_content.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/mobile_workspace_page/widget/mobile_workspace_content.dart @@ -4,6 +4,7 @@ import 'package:collaborative_science_platform/screens/workspace_page/mobile_wor import 'package:collaborative_science_platform/screens/workspace_page/mobile_workspace_page/widget/semantic_tag_card.dart'; import 'package:collaborative_science_platform/screens/workspace_page/mobile_workspace_page/widget/subsection_title.dart'; import 'package:collaborative_science_platform/utils/text_styles.dart'; +import 'package:collaborative_science_platform/widgets/app_button.dart'; import 'package:collaborative_science_platform/widgets/app_text_field.dart'; import 'package:collaborative_science_platform/widgets/semantic_search_bar.dart'; import 'package:flutter/material.dart'; @@ -28,6 +29,7 @@ class MobileWorkspaceContent extends StatefulWidget { final Function sendCollaborationRequest; final Function finalizeWorkspace; final Function addSemanticTags; + final Function sendWorkspaceToReview; const MobileWorkspaceContent({ super.key, @@ -43,7 +45,7 @@ class MobileWorkspaceContent extends StatefulWidget { required this.finalizeWorkspace, required this.sendCollaborationRequest, required this.updateRequest, - + required this.sendWorkspaceToReview, }); @override @@ -103,7 +105,11 @@ class _MobileWorkspaceContentState extends State { Widget semanticTagList() { List tags = [ - SemanticTag(id: "1", label: "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Label 1", description: "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Description 1"), + SemanticTag( + id: "1", + label: "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Label 1", + description: + "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Description 1"), SemanticTag(id: "2", label: "Label 2", description: "Description 2"), SemanticTag(id: "2", label: "Label 3", description: "Description 3"), ]; @@ -119,7 +125,7 @@ class _MobileWorkspaceContentState extends State { return SemanticTagCard( tag: tags[index], backgroundColor: const Color.fromARGB(255, 220, 235, 220), - onDelete: () { /* delete the semantic tag */ }, + onDelete: () {/* delete the semantic tag */}, ); }, ), @@ -137,21 +143,23 @@ class _MobileWorkspaceContentState extends State { physics: const NeverScrollableScrollPhysics(), itemCount: length + 1, itemBuilder: (context, index) { - return (index < length) ? MobileEntryCard( - entry: widget.workspace.entries[index], - onDelete: () async { - await widget.deleteEntry( - widget.workspace.entries[index].entryId); - }, - editEntry: widget.editEntry, - ) : NewEntry( - onCreate: widget.createNewEntry, - backgroundColor: const Color.fromARGB(255, 220, 220, 240), - isMobile: true, - ); + return (index < length) + ? MobileEntryCard( + entry: widget.workspace.entries[index], + onDelete: () async { + await widget.deleteEntry(widget.workspace.entries[index].entryId); + }, + editEntry: widget.editEntry, + ) + : NewEntry( + onCreate: widget.createNewEntry, + backgroundColor: const Color.fromARGB(255, 220, 220, 240), + isMobile: true, + ); }, ), - ) : Column( + ) + : Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -168,8 +176,8 @@ class _MobileWorkspaceContentState extends State { backgroundColor: const Color.fromARGB(255, 220, 220, 240), isMobile: true, ), - ], - ); + ], + ); } Widget contributorList() { @@ -190,18 +198,20 @@ class _MobileWorkspaceContentState extends State { physics: const NeverScrollableScrollPhysics(), itemCount: length + pendingLength + 1, itemBuilder: (context, index) => (index < length) - ? ContributorCard( - contributor: widget.workspace.contributors[index], - pending: false, - ) - : (index < length + pendingLength) ? ContributorCard( - contributor: widget.workspace.pendingContributors[index-length], - pending: true, - ) : addIcon(() { - showDialog(context: context, builder: (context) => alertDialog); - }), - ), - ); + ? ContributorCard( + contributor: widget.workspace.contributors[index], + pending: false, + ) + : (index < length + pendingLength) + ? ContributorCard( + contributor: widget.workspace.pendingContributors[index - length], + pending: true, + ) + : addIcon(() { + showDialog(context: context, builder: (context) => alertDialog); + }), + ), + ); } Widget referenceList() { @@ -259,12 +269,12 @@ class _MobileWorkspaceContentState extends State { children: titleReadOnly ? [ SizedBox( - width: Responsive.getGenericPageWidth(context)-100, + width: Responsive.getGenericPageWidth(context) - 150, child: Text( - widget.workspace.workspaceTitle, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyles.title2, + widget.workspace.workspaceTitle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyles.title2, ), ), if (widget.workspace.status == WorkspaceStatus.workable) @@ -276,6 +286,84 @@ class _MobileWorkspaceContentState extends State { }); }, icon: const Icon(Icons.edit)), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 3.0), + child: IconButton( + icon: widget.pending + ? const Icon(Icons.approval) + : (widget.workspace.status == WorkspaceStatus.workable + ? const Icon(Icons.lock) + : const Icon(Icons.send)), + onPressed: widget.pending + ? () { + // accept or reject the review + showDialog( + context: context, + builder: (context) => AppAlertDialog( + text: "Do you accept the work?", + actions: [ + AppButton( + text: "Accept", + height: 40, + onTap: () { + /* Send to review */ + Navigator.of(context).pop(); + }, + ), + AppButton( + text: "Reject", + height: 40, + onTap: () { + Navigator.of(context).pop(); + }, + ), + ], + ), + ); + } + : () { + // send to review + showDialog( + context: context, + builder: (context) => AppAlertDialog( + text: widget.workspace.status == WorkspaceStatus.workable + ? "Do you want to finalize the workspace?" + : "Do you want to send it to review?", + actions: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: AppButton( + text: "Yes", + height: 40, + onTap: () { + if (widget.workspace.status == + WorkspaceStatus.workable) { + widget.finalizeWorkspace(); + Navigator.of(context).pop(); + } else { + /* Send to review */ + widget.sendWorkspaceToReview(); + Navigator.of(context).pop(); + } + }, + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: AppButton( + text: "No", + height: 40, + onTap: () { + Navigator.of(context).pop(); + }, + ), + ), + ], + ), + ); + }, + ), + ), ] : [ SizedBox( @@ -292,14 +380,14 @@ class _MobileWorkspaceContentState extends State { width: 50, height: 50, child: IconButton( - onPressed: () { - widget.editTitle(titleController.text); - widget.workspace.workspaceTitle = titleController.text; - setState(() { - titleReadOnly = true; - }); - }, - icon: const Icon(Icons.save), + onPressed: () { + widget.editTitle(titleController.text); + widget.workspace.workspaceTitle = titleController.text; + setState(() { + titleReadOnly = true; + }); + }, + icon: const Icon(Icons.save), ), ) ], diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/web_workspace_page/web_workspace_page.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/web_workspace_page/web_workspace_page.dart index a7e2de36..36e8524a 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/web_workspace_page/web_workspace_page.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/web_workspace_page/web_workspace_page.dart @@ -16,7 +16,6 @@ import 'package:collaborative_science_platform/models/semantic_tag.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - class WebWorkspacePage extends StatefulWidget { final Workspace? workspace; final Workspaces? workspaces; @@ -32,7 +31,7 @@ class WebWorkspacePage extends StatefulWidget { final Function sendCollaborationRequest; final Function finalizeWorkspace; final Function addSemanticTags; - + final Function sendWorkspaceToReview; const WebWorkspacePage({ super.key, @@ -50,6 +49,7 @@ class WebWorkspacePage extends StatefulWidget { required this.finalizeWorkspace, required this.sendCollaborationRequest, required this.updateRequest, + required this.sendWorkspaceToReview, }); @override @@ -231,15 +231,45 @@ class _WebWorkspacePageState extends State { ) ], ), - SizedBox( - width: MediaQuery.of(context).size.width / 5, - child: AppButton( - text: (MediaQuery.of(context).size.width > Responsive.desktopPageWidth) ? "Send Review" : "Send", - height: 45, - onTap: () {}, - type: "primary", + if (widget.workspace!.status == WorkspaceStatus.workable || + widget.workspace!.status == WorkspaceStatus.finalized || + widget.workspace!.status == WorkspaceStatus.inReview) + SizedBox( + width: MediaQuery.of(context).size.width / 5, + child: AppButton( + isActive: widget.workspace!.status == + WorkspaceStatus.workable || + widget.workspace!.status == WorkspaceStatus.finalized, + text: widget.workspace!.status == WorkspaceStatus.workable + ? ((MediaQuery.of(context).size.width > + Responsive.desktopPageWidth) + ? "Finalize Workspace" + : "Finalize") + : widget.workspace!.status == WorkspaceStatus.finalized + ? ((MediaQuery.of(context).size.width > + Responsive.desktopPageWidth) + ? "Send to Review" + : "Send") + : ((MediaQuery.of(context).size.width > + Responsive.desktopPageWidth) + ? "In Review" + : "In Review"), + height: 45, + onTap: () { + /* finalize workspace*/ + if (widget.workspace!.status == + WorkspaceStatus.workable) { + widget.finalizeWorkspace(); + } + /*send workspace to review */ + else if (widget.workspace!.status == + WorkspaceStatus.finalized) { + widget.sendWorkspaceToReview(); + } + }, + type: "primary", + ), ), - ), ], ), ), @@ -260,10 +290,21 @@ class _WebWorkspacePageState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ SemanticTagListView( - tags: [ - SemanticTag(id: "1", label: "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Label 1", description: "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Description 1"), - SemanticTag(id: "2", label: "Label 2", description: "Description 2"), - SemanticTag(id: "2", label: "Label 3", description: "Description 3"), + tags: [ + SemanticTag( + id: "1", + label: + "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Label 1", + description: + "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong Description 1"), + SemanticTag( + id: "2", + label: "Label 2", + description: "Description 2"), + SemanticTag( + id: "2", + label: "Label 3", + description: "Description 3"), ], addSemanticTags: widget.addSemanticTags, height: minHeight / 2, diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/workspaces_page.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/workspaces_page.dart index b906625b..4e1c01cf 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/workspaces_page.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/workspace_page/workspaces_page.dart @@ -305,6 +305,41 @@ class _WorkspacesPageState extends State { isLoading = true; }); await workspaceProvider.finalizeWorkspace(widget.workspaceId, auth.user!.token); + await workspaceProvider.getWorkspaceById(widget.workspaceId, auth.user!.token); + setState(() { + workspace = (workspaceProvider.workspace ?? {} as Workspace); + }); + } on FinalizeWorkspaceException { + setState(() { + error = true; + errorMessage = FinalizeWorkspaceException().message; + }); + } catch (e) { + setState(() { + error = true; + errorMessage = "Something went wrong!"; + }); + } finally { + setState(() { + isLoading = false; + }); + } + } + + void sendWorkspaceToReview() async { + try { + final auth = Provider.of(context, listen: false); + final workspaceProvider = Provider.of(context, listen: false); + setState(() { + error = false; + isLoading = true; + }); + await workspaceProvider.sendWorkspaceToReview( + widget.workspaceId, auth.basicUser!.basicUserId, auth.user!.token); + await workspaceProvider.getWorkspaceById(widget.workspaceId, auth.user!.token); + setState(() { + workspace = (workspaceProvider.workspace ?? {} as Workspace); + }); } on FinalizeWorkspaceException { setState(() { error = true; @@ -442,7 +477,7 @@ class _WorkspacesPageState extends State { updateRequest: updateCollaborationRequest, sendCollaborationRequest: sendCollaborationRequest, finalizeWorkspace: finalizeWorkspace, - + sendWorkspaceToReview: sendWorkspaceToReview, ), desktop: WebWorkspacePage( isLoading: isLoading, @@ -459,6 +494,7 @@ class _WorkspacesPageState extends State { updateRequest: updateCollaborationRequest, sendCollaborationRequest: sendCollaborationRequest, finalizeWorkspace: finalizeWorkspace, + sendWorkspaceToReview: sendWorkspaceToReview, ), ); }