Merge pull request #13127 from Ultimaker/CURA-9221_show_message_cloud_approval

[CURA-9221] Show message cloud approval
This commit is contained in:
Remco Burema 2022-08-30 16:53:47 +02:00 committed by GitHub
commit e69b855b2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 15 deletions

View file

@ -189,9 +189,9 @@ class CloudApiClient:
Logger.logException("e", "Could not parse the stardust response: %s", error.toDict()) Logger.logException("e", "Could not parse the stardust response: %s", error.toDict())
return status_code, {"errors": [error.toDict()]} return status_code, {"errors": [error.toDict()]}
def _parseModels(self, response: Dict[str, Any], on_finished: Union[Callable[[CloudApiClientModel], Any], def _parseResponse(self, response: Dict[str, Any], on_finished: Union[Callable[[CloudApiClientModel], Any],
Callable[[List[CloudApiClientModel]], Any]], model_class: Type[CloudApiClientModel]) -> None: Callable[[List[CloudApiClientModel]], Any]], model_class: Type[CloudApiClientModel]) -> None:
"""Parses the given models and calls the correct callback depending on the result. """Parses the given response and calls the correct callback depending on the result.
:param response: The response from the server, after being converted to a dict. :param response: The response from the server, after being converted to a dict.
:param on_finished: The callback in case the response is successful. :param on_finished: The callback in case the response is successful.
@ -200,7 +200,10 @@ class CloudApiClient:
if "data" in response: if "data" in response:
data = response["data"] data = response["data"]
if isinstance(data, list): if "status" in data and data["status"] == "wait_approval":
on_finished_empty = cast(Callable[[List], Any], on_finished)
on_finished_empty([])
elif isinstance(data, list):
results = [model_class(**c) for c in data] # type: List[CloudApiClientModel] results = [model_class(**c) for c in data] # type: List[CloudApiClientModel]
on_finished_list = cast(Callable[[List[CloudApiClientModel]], Any], on_finished) on_finished_list = cast(Callable[[List[CloudApiClientModel]], Any], on_finished)
on_finished_list(results) on_finished_list(results)
@ -242,7 +245,7 @@ class CloudApiClient:
if status_code >= 300 and on_error is not None: if status_code >= 300 and on_error is not None:
on_error() on_error()
else: else:
self._parseModels(response, on_finished, model) self._parseResponse(response, on_finished, model)
self._anti_gc_callbacks.append(parse) self._anti_gc_callbacks.append(parse)
return parse return parse

View file

@ -3,7 +3,7 @@
from time import time from time import time
import os import os
from typing import cast, List, Optional, TYPE_CHECKING from typing import cast, List, Optional
from PyQt6.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot from PyQt6.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
from PyQt6.QtGui import QDesktopServices from PyQt6.QtGui import QDesktopServices
@ -21,6 +21,7 @@ from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
from .CloudApiClient import CloudApiClient from .CloudApiClient import CloudApiClient
from ..ExportFileJob import ExportFileJob from ..ExportFileJob import ExportFileJob
from ..Messages.PrintJobAwaitingApprovalMessage import PrintJobPendingApprovalMessage
from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice
from ..Messages.PrintJobUploadBlockedMessage import PrintJobUploadBlockedMessage from ..Messages.PrintJobUploadBlockedMessage import PrintJobUploadBlockedMessage
from ..Messages.PrintJobUploadErrorMessage import PrintJobUploadErrorMessage from ..Messages.PrintJobUploadErrorMessage import PrintJobUploadErrorMessage
@ -230,6 +231,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
:param job_response: The response received from the cloud API. :param job_response: The response received from the cloud API.
""" """
if not self._tool_path: if not self._tool_path:
return self._onUploadError() return self._onUploadError()
self._pre_upload_print_job = job_response # store the last uploaded job to prevent re-upload of the same file self._pre_upload_print_job = job_response # store the last uploaded job to prevent re-upload of the same file
@ -258,6 +260,8 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
""" """
self._uploaded_print_job = self._pre_upload_print_job self._uploaded_print_job = self._pre_upload_print_job
self._progress.hide() self._progress.hide()
if response:
message = PrintJobUploadSuccessMessage() message = PrintJobUploadSuccessMessage()
message.addAction("monitor print", message.addAction("monitor print",
name=I18N_CATALOG.i18nc("@action:button", "Monitor print"), name=I18N_CATALOG.i18nc("@action:button", "Monitor print"),
@ -268,6 +272,9 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
message.pyQtActionTriggered.connect(lambda message, action: (QDesktopServices.openUrl(QUrl(df_url)), message.hide())) message.pyQtActionTriggered.connect(lambda message, action: (QDesktopServices.openUrl(QUrl(df_url)), message.hide()))
message.show() message.show()
else:
PrintJobPendingApprovalMessage(self._cluster.cluster_id).show()
self.writeFinished.emit() self.writeFinished.emit()
def _onPrintUploadSpecificError(self, reply: "QNetworkReply", _: "QNetworkReply.NetworkError"): def _onPrintUploadSpecificError(self, reply: "QNetworkReply", _: "QNetworkReply.NetworkError"):

View file

@ -0,0 +1,38 @@
# Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt6.QtCore import QUrl
from PyQt6.QtGui import QDesktopServices
from UM import i18nCatalog
from UM.Message import Message
I18N_CATALOG = i18nCatalog("cura")
class PrintJobPendingApprovalMessage(Message):
"""Message shown when waiting for approval on an uploaded print job."""
def __init__(self, cluster_id: str) -> None:
super().__init__(
text = I18N_CATALOG.i18nc("@info:status", "You will receive a confirmation via email when the print job is approved"),
title=I18N_CATALOG.i18nc("@info:title", "The print job was successfully submitted"),
message_type=Message.MessageType.POSITIVE
)
self.addAction("manage_print_jobs", I18N_CATALOG.i18nc("@action", "Manage print jobs"), "", "")
self.addAction("learn_more", I18N_CATALOG.i18nc("@action", "Learn more"), "", "",
button_style = Message.ActionButtonStyle.LINK,
button_align = Message.ActionButtonAlignment.ALIGN_LEFT)
self.actionTriggered.connect(self._onActionTriggered)
self.cluster_id = cluster_id
def _onActionTriggered(self, message: Message, action: str) -> None:
""" Callback function for the "Manage print jobs" button on the pending approval notification. """
match action:
case "manage_print_jobs":
QDesktopServices.openUrl(QUrl(f"https://digitalfactory.ultimaker.com/app/jobs/{self._cluster.cluster_id}?utm_source=cura&utm_medium=software&utm_campaign=message-printjob-sent"))
case "learn_more":
QDesktopServices.openUrl(QUrl("https://support.ultimaker.com/hc/en-us/articles/5329940078620?utm_source=cura&utm_medium=software&utm_campaign=message-printjob-sent"))