-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revamp of mscolab operation menu and addition of "archive" operation #1782
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,6 +59,8 @@ | |
migrate = Migrate(APP, db, render_as_batch=True) | ||
auth = HTTPBasicAuth() | ||
|
||
ARCHIVE_THRESHOLD = 30 | ||
|
||
try: | ||
from mscolab_auth import mscolab_auth | ||
except ImportError as ex: | ||
|
@@ -489,13 +491,17 @@ def get_operation_details(): | |
@verify_user | ||
def set_last_used(): | ||
op_id = request.form.get('op_id', None) | ||
days_ago = int(request.form.get('days', 0)) | ||
operation = Operation.query.filter_by(id=int(op_id)).first() | ||
operation.last_used = datetime.datetime.utcnow() | ||
operation.last_used = datetime.datetime.utcnow() - datetime.timedelta(days=days_ago) | ||
temp_operation_active = operation.active | ||
operation.active = True | ||
if days_ago > ARCHIVE_THRESHOLD: | ||
operation.active = False | ||
else: | ||
operation.active = True | ||
db.session.commit() | ||
# Reload Operation List | ||
if not temp_operation_active: | ||
if temp_operation_active != operation.active: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the wording maybe can be changed to archived, unarchived etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changing operation.active requires changes to the DB, I guess? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, in the models. and on staging you could do this by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. review and also add new parts to the section Operation based features in https://github.com/Open-MSS/MSS/blob/develop/docs/mscolab.rst#operation-based-features There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not convinced that we should change the DB format to be more consistent in a part that is not user-visible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can do this when we need another change. It is not needed now, but at the moment we introduce something new we anyways have to do a server database migration. |
||
token = request.args.get('token', request.form.get('token', False)) | ||
json_config = {"token": token} | ||
sockio.sm.update_operation_list(json_config) | ||
|
@@ -507,11 +513,12 @@ def set_last_used(): | |
def update_last_used(): | ||
operations = Operation.query.filter().all() | ||
for operation in operations: | ||
a = (datetime.datetime.utcnow() - operation.last_used).days | ||
if a > 30: | ||
operation.active = False | ||
else: | ||
operation.active = True | ||
if operation.last_used is not None: | ||
days_ago = (datetime.datetime.utcnow() - operation.last_used).days | ||
if days_ago > ARCHIVE_THRESHOLD: | ||
operation.active = False | ||
else: | ||
operation.active = True | ||
db.session.commit() | ||
return jsonify({"success": True}), 200 | ||
|
||
|
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,43 +111,45 @@ def setupUi(self, MSUIMainWindow): | |
self.gridLayout_3 = QtWidgets.QGridLayout(self.openOperationsGb) | ||
self.gridLayout_3.setContentsMargins(8, 8, 8, 8) | ||
self.gridLayout_3.setObjectName("gridLayout_3") | ||
self.workingStatusLabel = QtWidgets.QLabel(self.openOperationsGb) | ||
self.workingStatusLabel.setWordWrap(True) | ||
self.workingStatusLabel.setObjectName("workingStatusLabel") | ||
self.gridLayout_3.addWidget(self.workingStatusLabel, 6, 0, 1, 2) | ||
self.activeOperationDesc = QtWidgets.QLabel(self.openOperationsGb) | ||
self.activeOperationDesc.setObjectName("activeOperationDesc") | ||
self.gridLayout_3.addWidget(self.activeOperationDesc, 1, 0, 1, 2) | ||
self.activeOperationsLabel = QtWidgets.QLabel(self.openOperationsGb) | ||
self.activeOperationsLabel.setObjectName("activeOperationsLabel") | ||
self.gridLayout_3.addWidget(self.activeOperationsLabel, 2, 0, 1, 1) | ||
self.workLocallyCheckbox = QtWidgets.QCheckBox(self.openOperationsGb) | ||
self.workLocallyCheckbox.setObjectName("workLocallyCheckbox") | ||
self.gridLayout_3.addWidget(self.workLocallyCheckbox, 10, 0, 1, 1) | ||
self.filterCategoryCb = QtWidgets.QComboBox(self.openOperationsGb) | ||
self.filterCategoryCb.setAutoFillBackground(False) | ||
self.filterCategoryCb.setEditable(False) | ||
self.filterCategoryCb.setObjectName("filterCategoryCb") | ||
self.filterCategoryCb.addItem("") | ||
self.gridLayout_3.addWidget(self.filterCategoryCb, 10, 1, 1, 1) | ||
self.categoryLabel = QtWidgets.QLabel(self.openOperationsGb) | ||
self.categoryLabel.setObjectName("categoryLabel") | ||
self.gridLayout_3.addWidget(self.categoryLabel, 10, 0, 1, 1) | ||
self.inactiveOperationsLabel = QtWidgets.QLabel(self.openOperationsGb) | ||
self.inactiveOperationsLabel.setObjectName("inactiveOperationsLabel") | ||
self.gridLayout_3.addWidget(self.inactiveOperationsLabel, 5, 0, 1, 1) | ||
self.listInactiveOperationsMSC = QtWidgets.QListWidget(self.openOperationsGb) | ||
self.listInactiveOperationsMSC.setObjectName("listInactiveOperationsMSC") | ||
self.gridLayout_3.addWidget(self.listInactiveOperationsMSC, 6, 0, 1, 2) | ||
self.workingStatusLabel = QtWidgets.QLabel(self.openOperationsGb) | ||
self.workingStatusLabel.setWordWrap(True) | ||
self.workingStatusLabel.setObjectName("workingStatusLabel") | ||
self.gridLayout_3.addWidget(self.workingStatusLabel, 7, 0, 1, 2) | ||
self.gridLayout_3.addWidget(self.filterCategoryCb, 9, 1, 1, 1) | ||
self.serverOptionsCb = QtWidgets.QComboBox(self.openOperationsGb) | ||
self.serverOptionsCb.setObjectName("serverOptionsCb") | ||
self.serverOptionsCb.addItem("") | ||
self.serverOptionsCb.addItem("") | ||
self.serverOptionsCb.addItem("") | ||
self.gridLayout_3.addWidget(self.serverOptionsCb, 11, 1, 1, 1) | ||
self.workLocallyCheckbox = QtWidgets.QCheckBox(self.openOperationsGb) | ||
self.workLocallyCheckbox.setObjectName("workLocallyCheckbox") | ||
self.gridLayout_3.addWidget(self.workLocallyCheckbox, 11, 0, 1, 1) | ||
self.gridLayout_3.addWidget(self.serverOptionsCb, 10, 1, 1, 1) | ||
self.categoryLabel = QtWidgets.QLabel(self.openOperationsGb) | ||
self.categoryLabel.setObjectName("categoryLabel") | ||
self.gridLayout_3.addWidget(self.categoryLabel, 9, 0, 1, 1) | ||
self.listOperationsMSC = QtWidgets.QListWidget(self.openOperationsGb) | ||
self.listOperationsMSC.setObjectName("listOperationsMSC") | ||
self.gridLayout_3.addWidget(self.listOperationsMSC, 4, 0, 1, 2) | ||
self.activeOperationDesc = QtWidgets.QLabel(self.openOperationsGb) | ||
self.activeOperationDesc.setObjectName("activeOperationDesc") | ||
self.gridLayout_3.addWidget(self.activeOperationDesc, 1, 0, 1, 2) | ||
self.activeOperationsLabel = QtWidgets.QLabel(self.openOperationsGb) | ||
self.activeOperationsLabel.setObjectName("activeOperationsLabel") | ||
self.gridLayout_3.addWidget(self.activeOperationsLabel, 2, 0, 1, 1) | ||
self.pbOpenOperationArchive = QtWidgets.QPushButton(self.openOperationsGb) | ||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) | ||
sizePolicy.setHorizontalStretch(0) | ||
sizePolicy.setVerticalStretch(0) | ||
sizePolicy.setHeightForWidth(self.pbOpenOperationArchive.sizePolicy().hasHeightForWidth()) | ||
self.pbOpenOperationArchive.setSizePolicy(sizePolicy) | ||
self.pbOpenOperationArchive.setObjectName("pbOpenOperationArchive") | ||
self.gridLayout_3.addWidget(self.pbOpenOperationArchive, 11, 0, 1, 2) | ||
self.horizontalLayout.addWidget(self.openOperationsGb) | ||
self.verticalLayout_2.addLayout(self.horizontalLayout) | ||
self.gridLayout.addLayout(self.verticalLayout_2, 0, 0, 1, 2) | ||
|
@@ -221,16 +223,18 @@ def setupUi(self, MSUIMainWindow): | |
self.actionAddOperation.setObjectName("actionAddOperation") | ||
self.actionSearch = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionSearch.setObjectName("actionSearch") | ||
self.actionDescription = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionDescription.setObjectName("actionDescription") | ||
self.actionUpdateOperationDesc = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionUpdateOperationDesc.setObjectName("actionUpdateOperationDesc") | ||
self.actionViewDescription = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionViewDescription.setObjectName("actionViewDescription") | ||
self.actionChangeDescription = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionChangeDescription.setObjectName("actionChangeDescription") | ||
self.actionRenameOperation = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionRenameOperation.setObjectName("actionRenameOperation") | ||
self.actionLeaveOperation = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionLeaveOperation.setObjectName("actionLeaveOperation") | ||
self.actionUnarchiveOperation = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionUnarchiveOperation.setObjectName("actionUnarchiveOperation") | ||
self.actionArchiveOperation = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionArchiveOperation.setObjectName("actionArchiveOperation") | ||
self.actionChangeCategory = QtWidgets.QAction(MSUIMainWindow) | ||
self.actionChangeCategory.setObjectName("actionChangeCategory") | ||
self.menuNew.addAction(self.actionNewFlightTrack) | ||
self.menuNew.addAction(self.actionAddOperation) | ||
self.menuFile.addAction(self.menuNew.menuAction()) | ||
|
@@ -256,16 +260,17 @@ def setupUi(self, MSUIMainWindow): | |
self.menuViews.addAction(self.actionSideView) | ||
self.menuViews.addAction(self.actionTableView) | ||
self.menuViews.addAction(self.actionLinearView) | ||
self.menuProperties.addAction(self.actionDeleteOperation) | ||
self.menuProperties.addAction(self.actionDescription) | ||
self.menuProperties.addAction(self.actionUpdateOperationDesc) | ||
self.menuProperties.addAction(self.actionChangeCategory) | ||
self.menuProperties.addAction(self.actionChangeDescription) | ||
self.menuProperties.addAction(self.actionManageUsers) | ||
self.menuProperties.addAction(self.actionRenameOperation) | ||
self.menuProperties.addAction(self.actionLeaveOperation) | ||
self.menuProperties.addAction(self.actionDeleteOperation) | ||
self.menuProperties.addAction(self.actionArchiveOperation) | ||
self.menuOperation.addAction(self.actionChat) | ||
self.menuOperation.addAction(self.actionVersionHistory) | ||
self.menuOperation.addAction(self.actionManageUsers) | ||
self.menuOperation.addAction(self.actionUnarchiveOperation) | ||
self.menuOperation.addAction(self.actionViewDescription) | ||
self.menuOperation.addSeparator() | ||
self.menuOperation.addAction(self.actionLeaveOperation) | ||
self.menuOperation.addAction(self.menuProperties.menuAction()) | ||
self.menubar.addAction(self.menuFile.menuAction()) | ||
self.menubar.addAction(self.menuViews.menuAction()) | ||
|
@@ -298,30 +303,30 @@ def retranslateUi(self, MSUIMainWindow): | |
"Save a flight track to name it.")) | ||
self.openViewsLabel.setText(_translate("MSUIMainWindow", "Open Views:")) | ||
self.listViews.setToolTip(_translate("MSUIMainWindow", "Double-click a view to bring it to the front.")) | ||
self.workingStatusLabel.setText(_translate("MSUIMainWindow", "No operations selected")) | ||
self.activeOperationDesc.setText(_translate("MSUIMainWindow", "Select Operation to View Description")) | ||
self.activeOperationsLabel.setText(_translate("MSUIMainWindow", "Operations")) | ||
self.workLocallyCheckbox.setToolTip(_translate("MSUIMainWindow", "Check to work asynchronously from the server")) | ||
self.workLocallyCheckbox.setText(_translate("MSUIMainWindow", "Work Asynchronously")) | ||
self.filterCategoryCb.setWhatsThis(_translate("MSUIMainWindow", "filter by operation category")) | ||
self.filterCategoryCb.setCurrentText(_translate("MSUIMainWindow", "ANY")) | ||
self.filterCategoryCb.setItemText(0, _translate("MSUIMainWindow", "ANY")) | ||
self.categoryLabel.setText(_translate("MSUIMainWindow", "Category:")) | ||
self.inactiveOperationsLabel.setText(_translate("MSUIMainWindow", "Archived Operations")) | ||
self.workingStatusLabel.setText(_translate("MSUIMainWindow", "No operations selected")) | ||
self.serverOptionsCb.setToolTip(_translate("MSUIMainWindow", "Fetch/Save Server options")) | ||
self.serverOptionsCb.setItemText(0, _translate("MSUIMainWindow", "Server Options")) | ||
self.serverOptionsCb.setItemText(1, _translate("MSUIMainWindow", "Fetch From Server")) | ||
self.serverOptionsCb.setItemText(2, _translate("MSUIMainWindow", "Save To Server")) | ||
self.workLocallyCheckbox.setToolTip(_translate("MSUIMainWindow", "Check to work asynchronously from the server")) | ||
self.workLocallyCheckbox.setText(_translate("MSUIMainWindow", "Work Asynchronously")) | ||
self.categoryLabel.setText(_translate("MSUIMainWindow", "Category:")) | ||
self.listOperationsMSC.setToolTip(_translate("MSUIMainWindow", "List of mscolab operations.\n" | ||
"Double click a operation to activate and view its description.")) | ||
self.activeOperationDesc.setText(_translate("MSUIMainWindow", "Select Operation to View Description")) | ||
self.activeOperationsLabel.setText(_translate("MSUIMainWindow", "Operations")) | ||
self.pbOpenOperationArchive.setText(_translate("MSUIMainWindow", "Operation Archive")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. plural? on the upper list it is also plural and a : is missing on upper one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. singular in front of "archive" seems to be slightly more common than plural according to google |
||
self.menuFile.setTitle(_translate("MSUIMainWindow", "&File")) | ||
self.menuImportFlightTrack.setTitle(_translate("MSUIMainWindow", "Import Flight Track")) | ||
self.menuExportActiveFlightTrack.setTitle(_translate("MSUIMainWindow", "Export Flight Track")) | ||
self.menuNew.setTitle(_translate("MSUIMainWindow", "New")) | ||
self.menuHelp.setTitle(_translate("MSUIMainWindow", "&Help")) | ||
self.menuViews.setTitle(_translate("MSUIMainWindow", "Views")) | ||
self.menuOperation.setTitle(_translate("MSUIMainWindow", "Operation")) | ||
self.menuProperties.setTitle(_translate("MSUIMainWindow", "Properties")) | ||
self.menuProperties.setTitle(_translate("MSUIMainWindow", "Maintenance")) | ||
self.actionSaveActiveFlightTrack.setText(_translate("MSUIMainWindow", "&Save Active Flight Track")) | ||
self.actionSaveActiveFlightTrack.setShortcut(_translate("MSUIMainWindow", "Ctrl+S")) | ||
self.actionSaveActiveFlightTrackAs.setText(_translate("MSUIMainWindow", "Save Active Flight Track As")) | ||
|
@@ -356,8 +361,9 @@ def retranslateUi(self, MSUIMainWindow): | |
self.actionSearch.setText(_translate("MSUIMainWindow", "Search")) | ||
self.actionSearch.setToolTip(_translate("MSUIMainWindow", "Search for interactive text in the UI")) | ||
self.actionSearch.setShortcut(_translate("MSUIMainWindow", "Ctrl+F")) | ||
self.actionDescription.setText(_translate("MSUIMainWindow", "View Description")) | ||
self.actionUpdateOperationDesc.setText(_translate("MSUIMainWindow", "Update Description")) | ||
self.actionViewDescription.setText(_translate("MSUIMainWindow", "View Description")) | ||
self.actionChangeDescription.setText(_translate("MSUIMainWindow", "Change Description")) | ||
self.actionRenameOperation.setText(_translate("MSUIMainWindow", "Rename Operation")) | ||
self.actionLeaveOperation.setText(_translate("MSUIMainWindow", "&Leave Operation")) | ||
self.actionUnarchiveOperation.setText(_translate("MSUIMainWindow", "Unarchive Operation")) | ||
self.actionArchiveOperation.setText(_translate("MSUIMainWindow", "Archive Operation")) | ||
self.actionChangeCategory.setText(_translate("MSUIMainWindow", "Change Category")) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Form implementation generated from reading ui file 'mslib/msui/ui/ui_operation_archive.ui' | ||
# | ||
# Created by: PyQt5 UI code generator 5.15.7 | ||
# | ||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is | ||
# run again. Do not edit this file unless you know what you are doing. | ||
|
||
|
||
from PyQt5 import QtCore, QtGui, QtWidgets | ||
|
||
|
||
class Ui_OperationArchiveBrowser(object): | ||
def setupUi(self, OperationArchiveBrowser): | ||
OperationArchiveBrowser.setObjectName("OperationArchiveBrowser") | ||
OperationArchiveBrowser.resize(754, 393) | ||
self.verticalLayout = QtWidgets.QVBoxLayout(OperationArchiveBrowser) | ||
self.verticalLayout.setObjectName("verticalLayout") | ||
self.label = QtWidgets.QLabel(OperationArchiveBrowser) | ||
self.label.setObjectName("label") | ||
self.verticalLayout.addWidget(self.label) | ||
self.listArchivedOperations = QtWidgets.QListWidget(OperationArchiveBrowser) | ||
self.listArchivedOperations.setObjectName("listArchivedOperations") | ||
self.verticalLayout.addWidget(self.listArchivedOperations) | ||
self.horizontalLayout = QtWidgets.QHBoxLayout() | ||
self.horizontalLayout.setObjectName("horizontalLayout") | ||
self.pbUnarchiveOperation = QtWidgets.QPushButton(OperationArchiveBrowser) | ||
self.pbUnarchiveOperation.setObjectName("pbUnarchiveOperation") | ||
self.horizontalLayout.addWidget(self.pbUnarchiveOperation) | ||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) | ||
self.horizontalLayout.addItem(spacerItem) | ||
self.pbClose = QtWidgets.QPushButton(OperationArchiveBrowser) | ||
self.pbClose.setObjectName("pbClose") | ||
self.horizontalLayout.addWidget(self.pbClose) | ||
self.verticalLayout.addLayout(self.horizontalLayout) | ||
|
||
self.retranslateUi(OperationArchiveBrowser) | ||
QtCore.QMetaObject.connectSlotsByName(OperationArchiveBrowser) | ||
|
||
def retranslateUi(self, OperationArchiveBrowser): | ||
_translate = QtCore.QCoreApplication.translate | ||
OperationArchiveBrowser.setWindowTitle(_translate("OperationArchiveBrowser", "Browse archived operations")) | ||
self.label.setText(_translate("OperationArchiveBrowser", "Operation Archive")) | ||
self.pbUnarchiveOperation.setToolTip(_translate("OperationArchiveBrowser", "<html><head/><body><p>Becomes available when you have the right to unarchive an operation. Moves this operation to the list of current operations.</p></body></html>")) | ||
self.pbUnarchiveOperation.setText(_translate("OperationArchiveBrowser", "Unarchive")) | ||
self.pbClose.setText(_translate("OperationArchiveBrowser", "close")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should maybe make this configurable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. 30 days seems a tad short for me as a typical campaign may run longer.
New issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this needs also a documentation