1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-31 23:51:09 +03:00

add unsaved workflow changes flow

This commit is contained in:
John Mitchell 2019-03-04 16:58:10 -05:00
parent bf1769af6c
commit 8c5bcffd42
No known key found for this signature in database
GPG Key ID: FE6A9B5BD4EB5C94
5 changed files with 76 additions and 9 deletions

View File

@ -131,7 +131,12 @@ function TemplatesStrings (BaseString) {
NEW_LINK: t.s('Please click on an available node to form a new link.'), NEW_LINK: t.s('Please click on an available node to form a new link.'),
UNLINK: t.s('UNLINK'), UNLINK: t.s('UNLINK'),
READ_ONLY_PROMPT_VALUES: t.s('The following promptable values were provided when this node was created:'), READ_ONLY_PROMPT_VALUES: t.s('The following promptable values were provided when this node was created:'),
READ_ONLY_NO_PROMPT_VALUES: t.s('No promptable values were provided when this node was created.') READ_ONLY_NO_PROMPT_VALUES: t.s('No promptable values were provided when this node was created.'),
UNSAVED_CHANGES_HEADER: t.s('WARNING: UNSAVED CHANGES'),
UNSAVED_CHANGES_PROMPT_TEXT: t.s('Are you sure you want to exit the Workflow Creator without saving your changes?'),
EXIT: t.s('EXIT'),
CANCEL: t.s('CANCEL'),
SAVE_AND_EXIT: t.s('SAVE & EXIT')
}; };
} }

View File

@ -114,7 +114,8 @@
color: @btn-txt; color: @btn-txt;
} }
.WorkflowMaker-deleteOverlay { .WorkflowMaker-deleteOverlay,
.WorkflowMaker-unsavedChangesOverlay {
height: 100%; height: 100%;
width: 100%; width: 100%;
position: absolute; position: absolute;

View File

@ -7,11 +7,11 @@
export default ['$scope', 'TemplatesService', export default ['$scope', 'TemplatesService',
'ProcessErrors', '$q', 'ProcessErrors', '$q',
'PromptService', 'TemplatesStrings', 'WorkflowChartService', 'PromptService', 'TemplatesStrings', 'WorkflowChartService',
'Wait', '$state', 'Wait', '$state', '$transitions',
function ($scope, TemplatesService, function ($scope, TemplatesService,
ProcessErrors, $q, ProcessErrors, $q,
PromptService, TemplatesStrings, WorkflowChartService, PromptService, TemplatesStrings, WorkflowChartService,
Wait, $state Wait, $state, $transitions
) { ) {
let deletedNodeIds = []; let deletedNodeIds = [];
@ -32,6 +32,13 @@ export default ['$scope', 'TemplatesService',
'showLinkForm': false 'showLinkForm': false
}; };
$scope.workflowChangesUnsaved = false;
$scope.workflowChangesStarted = false;
$scope.cancelUnsavedChanges = () => {
$scope.unsavedChangesVisible = false;
}
let getNodes = () => { let getNodes = () => {
Wait('start'); Wait('start');
TemplatesService.getWorkflowJobTemplateNodes($scope.workflowJobTemplateObj.id, page) TemplatesService.getWorkflowJobTemplateNodes($scope.workflowJobTemplateObj.id, page)
@ -72,6 +79,8 @@ export default ['$scope', 'TemplatesService',
Wait('start'); Wait('start');
$scope.unsavedChangesVisible = false;
let buildSendableNodeData = (node) => { let buildSendableNodeData = (node) => {
// Create the node // Create the node
let sendableNodeData = { let sendableNodeData = {
@ -364,6 +373,8 @@ export default ['$scope', 'TemplatesService',
return $q.all(associatePromises.concat(credentialPromises)) return $q.all(associatePromises.concat(credentialPromises))
.then(() => { .then(() => {
Wait('stop'); Wait('stop');
$scope.workflowChangesUnsaved = false;
$scope.workflowChangesStarted = false;
$scope.closeDialog(); $scope.closeDialog();
}).catch(({ data, status }) => { }).catch(({ data, status }) => {
Wait('stop'); Wait('stop');
@ -396,6 +407,8 @@ export default ['$scope', 'TemplatesService',
$q.all(deletePromises) $q.all(deletePromises)
.then(() => { .then(() => {
Wait('stop'); Wait('stop');
$scope.workflowChangesUnsaved = false;
$scope.workflowChangesStarted = false;
$scope.closeDialog(); $scope.closeDialog();
$state.transitionTo('templates'); $state.transitionTo('templates');
}).catch(({ data, status }) => { }).catch(({ data, status }) => {
@ -410,6 +423,7 @@ export default ['$scope', 'TemplatesService',
/* ADD NODE FUNCTIONS */ /* ADD NODE FUNCTIONS */
$scope.startAddNodeWithoutChild = (parent) => { $scope.startAddNodeWithoutChild = (parent) => {
$scope.workflowChangesStarted = true;
if ($scope.nodeConfig) { if ($scope.nodeConfig) {
$scope.cancelNodeForm(); $scope.cancelNodeForm();
} }
@ -448,6 +462,7 @@ export default ['$scope', 'TemplatesService',
}; };
$scope.startAddNodeWithChild = (link) => { $scope.startAddNodeWithChild = (link) => {
$scope.workflowChangesStarted = true;
if ($scope.nodeConfig) { if ($scope.nodeConfig) {
$scope.cancelNodeForm(); $scope.cancelNodeForm();
} }
@ -494,6 +509,7 @@ export default ['$scope', 'TemplatesService',
}; };
$scope.confirmNodeForm = (selectedTemplate, promptData, edgeType) => { $scope.confirmNodeForm = (selectedTemplate, promptData, edgeType) => {
$scope.workflowChangesUnsaved = true;
const nodeId = $scope.nodeConfig.nodeId; const nodeId = $scope.nodeConfig.nodeId;
if ($scope.nodeConfig.mode === "add") { if ($scope.nodeConfig.mode === "add") {
if (selectedTemplate && edgeType && edgeType.value) { if (selectedTemplate && edgeType && edgeType.value) {
@ -543,6 +559,7 @@ export default ['$scope', 'TemplatesService',
}; };
$scope.cancelNodeForm = () => { $scope.cancelNodeForm = () => {
$scope.workflowChangesStarted = false;
const nodeId = $scope.nodeConfig.nodeId; const nodeId = $scope.nodeConfig.nodeId;
if ($scope.nodeConfig.mode === "add") { if ($scope.nodeConfig.mode === "add") {
// Remove the placeholder node from the array // Remove the placeholder node from the array
@ -599,6 +616,7 @@ export default ['$scope', 'TemplatesService',
/* EDIT NODE FUNCTIONS */ /* EDIT NODE FUNCTIONS */
$scope.startEditNode = (nodeToEdit) => { $scope.startEditNode = (nodeToEdit) => {
$scope.workflowChangesStarted = true;
if ($scope.linkConfig) { if ($scope.linkConfig) {
$scope.cancelLinkForm(); $scope.cancelLinkForm();
} }
@ -625,6 +643,7 @@ export default ['$scope', 'TemplatesService',
/* LINK FUNCTIONS */ /* LINK FUNCTIONS */
$scope.startEditLink = (linkToEdit) => { $scope.startEditLink = (linkToEdit) => {
$scope.workflowChangesStarted = true;
const setupLinkEdit = () => { const setupLinkEdit = () => {
// Determine whether or not this link can be removed // Determine whether or not this link can be removed
@ -677,6 +696,7 @@ export default ['$scope', 'TemplatesService',
}; };
$scope.selectNodeForLinking = (node) => { $scope.selectNodeForLinking = (node) => {
$scope.workflowChangesStarted = true;
if ($scope.nodeConfig) { if ($scope.nodeConfig) {
$scope.cancelNodeForm(); $scope.cancelNodeForm();
} }
@ -772,6 +792,7 @@ export default ['$scope', 'TemplatesService',
}; };
$scope.confirmLinkForm = (newEdgeType) => { $scope.confirmLinkForm = (newEdgeType) => {
$scope.workflowChangesUnsaved = true;
$scope.graphState.arrayOfLinksForChart.forEach((link) => { $scope.graphState.arrayOfLinksForChart.forEach((link) => {
if (link.source.id === $scope.linkConfig.source.id && link.target.id === $scope.linkConfig.target.id) { if (link.source.id === $scope.linkConfig.source.id && link.target.id === $scope.linkConfig.target.id) {
link.edgeType = newEdgeType; link.edgeType = newEdgeType;
@ -792,6 +813,7 @@ export default ['$scope', 'TemplatesService',
}; };
$scope.unlink = () => { $scope.unlink = () => {
$scope.workflowChangesUnsaved = true;
// Remove the link // Remove the link
for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){ for( let i = $scope.graphState.arrayOfLinksForChart.length; i--; ){
const link = $scope.graphState.arrayOfLinksForChart[i]; const link = $scope.graphState.arrayOfLinksForChart[i];
@ -807,6 +829,7 @@ export default ['$scope', 'TemplatesService',
}; };
$scope.cancelLinkForm = () => { $scope.cancelLinkForm = () => {
$scope.workflowChangesStarted = false;
if ($scope.linkConfig.mode === "add" && $scope.linkConfig.target) { if ($scope.linkConfig.mode === "add" && $scope.linkConfig.target) {
$scope.graphState.arrayOfLinksForChart.splice($scope.graphState.arrayOfLinksForChart.length-1, 1); $scope.graphState.arrayOfLinksForChart.splice($scope.graphState.arrayOfLinksForChart.length-1, 1);
let targetIsOrphaned = true; let targetIsOrphaned = true;
@ -838,16 +861,19 @@ export default ['$scope', 'TemplatesService',
/* DELETE NODE FUNCTIONS */ /* DELETE NODE FUNCTIONS */
$scope.startDeleteNode = (nodeToDelete) => { $scope.startDeleteNode = (nodeToDelete) => {
$scope.workflowChangesStarted = true;
$scope.nodeToBeDeleted = nodeToDelete; $scope.nodeToBeDeleted = nodeToDelete;
$scope.deleteOverlayVisible = true; $scope.deleteOverlayVisible = true;
}; };
$scope.cancelDeleteNode = () => { $scope.cancelDeleteNode = () => {
$scope.workflowChangesStarted = false;
$scope.nodeToBeDeleted = null; $scope.nodeToBeDeleted = null;
$scope.deleteOverlayVisible = false; $scope.deleteOverlayVisible = false;
}; };
$scope.confirmDeleteNode = () => { $scope.confirmDeleteNode = () => {
$scope.workflowChangesUnsaved = true;
if ($scope.nodeToBeDeleted) { if ($scope.nodeToBeDeleted) {
const nodeId = $scope.nodeToBeDeleted.id; const nodeId = $scope.nodeToBeDeleted.id;

View File

@ -63,10 +63,15 @@ export default ['templateUrl', 'CreateDialog', 'Wait', '$state', '$window',
}); });
scope.closeDialog = function() { scope.closeDialog = function() {
$('#workflow-modal-dialog').dialog('destroy'); if (scope.workflowChangesUnsaved || scope.workflowChangesStarted) {
$('body').removeClass('WorkflowMaker-preventBodyScrolling'); scope.unsavedChangesVisible = true;
} else {
scope.unsavedChangesVisible = false;
$('#workflow-modal-dialog').dialog('destroy');
$('body').removeClass('WorkflowMaker-preventBodyScrolling');
$state.go('^'); $state.go('^');
}
}; };
function onResize(){ function onResize(){

View File

@ -17,8 +17,38 @@
<div class="Prompt-bodyQuery">{{strings.get('workflow_maker.DELETE_NODE_PROMPT_TEXT')}}</div> <div class="Prompt-bodyQuery">{{strings.get('workflow_maker.DELETE_NODE_PROMPT_TEXT')}}</div>
</div> </div>
<div class="Modal-footer"> <div class="Modal-footer">
<button ng-click="cancelDeleteNode()" class="btn Modal-defaultButton Modal-footerButton">{{strings.get('CANCEL')}}</a> <button ng-click="cancelDeleteNode()" class="btn Modal-defaultButton Modal-footerButton">{{strings.get('CANCEL')}}</button>
<button ng-click="confirmDeleteNode()" class="btn Modal-footerButton ng-binding Modal-errorButton">{{strings.get('DELETE')}}</a> <button ng-click="confirmDeleteNode()" class="btn Modal-footerButton ng-binding Modal-errorButton">{{strings.get('DELETE')}}</button>
</div>
</div>
</div>
</div>
<div class="WorkflowMaker-unsavedChangesOverlay" ng-show="unsavedChangesVisible">
<div class="modal-dialog">
<div class="Modal-content modal-content">
<div class="Modal-header">
<div class="Modal-title">
<span>{{strings.get('workflow_maker.UNSAVED_CHANGES_HEADER')}}</span>
</div>
<div class="Modal-exitHolder">
<button class="close Modal-exit" ng-click="cancelUnsavedChanges()">
<i class="fa fa-times-circle"></i>
</button>
</div>
</div>
<div class="Modal-body ng-binding">
<div class="Prompt-bodyQuery">{{strings.get('workflow_maker.UNSAVED_CHANGES_PROMPT_TEXT')}}</div>
</div>
<div class="Modal-footer">
<button ng-click="closeDialog()" class="btn Modal-footerButton Modal-errorButton">{{strings.get('workflow_maker.EXIT')}}</button>
<button ng-click="cancelUnsavedChanges()" class="btn Modal-footerButton Modal-defaultButton">{{strings.get('workflow_maker.CANCEL')}}</button>
<button
ng-hide="formState.showNodeForm || formState.showLinkForm"
ng-click="saveWorkflowMaker()"
class="btn Modal-footerButton btn-success"
>
{{strings.get('workflow_maker.SAVE_AND_EXIT')}}
</button>
</div> </div>
</div> </div>
</div> </div>