This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-ui.git
The following commit(s) were added to refs/heads/master by this push:
new d2334a50 workflow deletion, better replayable and selection support
d2334a50 is described below
commit d2334a50e5ef7727164db84ee02b6624fe3966ee
Author: Alex Heneveld <[email protected]>
AuthorDate: Fri Nov 25 12:18:39 2022 +0000
workflow deletion, better replayable and selection support
---
.../components/providers/entity-api.provider.js | 4 ++
.../workflow/workflow-step.template.html | 15 ++++++-
.../app/components/workflow/workflow-steps.less | 18 +++++++++
.../inspect/activities/detail/detail.controller.js | 47 +++++++++++++++-------
.../inspect/activities/detail/detail.template.html | 4 +-
5 files changed, 72 insertions(+), 16 deletions(-)
diff --git
a/ui-modules/app-inspector/app/components/providers/entity-api.provider.js
b/ui-modules/app-inspector/app/components/providers/entity-api.provider.js
index fea4517b..8ca927c3 100644
--- a/ui-modules/app-inspector/app/components/providers/entity-api.provider.js
+++ b/ui-modules/app-inspector/app/components/providers/entity-api.provider.js
@@ -74,6 +74,7 @@ function EntityApi($http, $q) {
getWorkflows: getWorkflows,
getWorkflow: getWorkflow,
+ deleteWorkflow: deleteWorkflow,
replayWorkflow: replayWorkflow,
};
@@ -197,6 +198,9 @@ function EntityApi($http, $q) {
function getWorkflow(applicationId, entityId, workflowId) {
return $http.get('/v1/applications/'+ applicationId +'/entities/' +
entityId + '/workflows/' + workflowId, {observable: true, ignoreLoadingBar:
true, params: { suppressSecrets: true }});
}
+ function deleteWorkflow(applicationId, entityId, workflowId) {
+ return $http.delete('/v1/applications/'+ applicationId +'/entities/' +
entityId + '/workflows/' + workflowId, {observable: true, ignoreLoadingBar:
true, params: { suppressSecrets: true }});
+ }
function replayWorkflow(applicationId, entityId, workflowId, step,
options) {
return $http.post('/v1/applications/'+ applicationId +'/entities/' +
entityId + '/workflows/' + workflowId
+ '/replay/from/' + step, null, {params: options});
diff --git
a/ui-modules/app-inspector/app/components/workflow/workflow-step.template.html
b/ui-modules/app-inspector/app/components/workflow/workflow-step.template.html
index 28c01fdf..ad34733b 100644
---
a/ui-modules/app-inspector/app/components/workflow/workflow-step.template.html
+++
b/ui-modules/app-inspector/app/components/workflow/workflow-step.template.html
@@ -41,10 +41,23 @@
<div ng-if="isFocusTask" class="workflow-step-pill focus-step
label-info" title="This step instance is for the task currently selected in the
activity view.">
selected
</div>
- <div ng-if="stepTitle.id" class="workflow-step-pill step-id">
+
+ <div ng-if="stepTitle.id && isFocusTask" class="workflow-step-pill
step-id">
+ <i class="fa fa-id-card-o"></i>
+ {{ stepTitle.id }}
+ </div>
+ <div ng-if="stepTitle.id && !isFocusTask"
class="workflow-step-pill step-id handy"
+ title="Select this task"
+ ui-sref="main.inspect.activities.detail({applicationId:
workflow.applicationId, entityId: workflow.entityId, activityId:
stepContext.taskId, workflowId })">
<i class="fa fa-id-card-o"></i>
{{ stepTitle.id }}
</div>
+ <div ng-if="!stepTitle.id && !isFocusTask"
class="workflow-step-pill step-id handy hover-only"
+ title="Select this task"
+ ui-sref="main.inspect.activities.detail({applicationId:
workflow.applicationId, entityId: workflow.entityId, activityId:
stepContext.taskId, workflowId })">
+ <i class="fa fa-id-card-o"></i>
+ </div>
+
<div ng-click="vm.toggleExpandState()" class="expand-toggle">
<i ng-class="expanded ? 'fa fa-chevron-up' : 'fa
fa-chevron-down'"></i>
</div>
diff --git
a/ui-modules/app-inspector/app/components/workflow/workflow-steps.less
b/ui-modules/app-inspector/app/components/workflow/workflow-steps.less
index e1fda49f..39afeb6f 100644
--- a/ui-modules/app-inspector/app/components/workflow/workflow-steps.less
+++ b/ui-modules/app-inspector/app/components/workflow/workflow-steps.less
@@ -42,6 +42,8 @@
display: flex;
gap: 1ex;
align-items: center;
+ max-width: 50%;
+ white-space: nowrap;
margin-left: 1em;
.expand-toggle {
cursor: pointer;
@@ -51,18 +53,34 @@
font-size: 90%;
margin-right: 1ex;
margin-top: 1px;
+ flex: 1 5 auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
.step-id {
.monospace();
font-size: 80%;
+ flex: 5 1 auto;
background-color: @primary-50;
+
+ &.handy {
+ cursor: pointer;
+ }
}
.focus-step {
//background color comes from label-info class
//background: @primary-100;
}
}
+ .step-id.hover-only {
+ visibility: hidden;
+ //display: none;
+ }
+ &:hover .step-id.hover-only {
+ visibility: visible;
+ display: inherit;
+ }
.workflow-step-pill {
padding: 2px 6px;
border-radius: 9px;
diff --git
a/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.controller.js
b/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.controller.js
index 86fa0e6f..22d1d016 100644
---
a/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.controller.js
+++
b/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.controller.js
@@ -68,10 +68,17 @@ function DetailController($scope, $state, $stateParams,
$location, $log, $uibMod
function onActivityOrWorkflowUpdate() {
delete $scope.actions['cancel'];
+ delete $scope.actions['delete'];
+
if (!vm.model.activity.endTimeUtc ||
vm.model.activity.endTimeUtc<=0) {
$scope.actions.cancel = { label: 'Cancel task', doAction: ()
=> { activityApi.cancelActivity(activityId); } };
} else if (vm.model.workflow.data && vm.model.workflow.data.taskId
&& vm.model.workflow.data.status === 'RUNNING') {
$scope.actions.cancel = { label: 'Cancel workflow', doAction:
() => { activityApi.cancelActivity(vm.model.workflow.taskId); } };
+ } else if (vm.model.workflow.data && vm.model.workflow.tag) {
+ $scope.actions.delete = { label: 'Delete workflow', doAction:
() => {
+
entityApi.deleteWorkflow(vm.model.workflow.tag.applicationId || applicationId,
vm.model.workflow.tag.entityId || entityId, $scope.workflowId)
+ .then(result => $state.go($state.current, {}, {reload:
true}) );
+ } };
}
}
@@ -149,41 +156,53 @@ function DetailController($scope, $state, $stateParams,
$location, $log, $uibMod
if (vm.model.workflow.data.status !== 'RUNNING') {
$scope.actions.workflowReplays = [];
- const stepIndex = (vm.model.workflow.tag ||
{}).stepIndex;
+ const stepIndex = (vm.model.workflow.tag ||
{}).stepIndex; // selected by user
+ const currentStepIndex =
vm.model.workflow.data.currentStepIndex; // of workflow
- let replayableFromStart =
vm.model.workflow.data.replayableFromStart, replayableContinuing =
vm.model.workflow.data.replayableLastStep>=0;
+ let replayableDisabled =
vm.model.workflow.data.replayableDisabled;
+ let replayableFromStart =
vm.model.workflow.data.replayableFromStart && !replayableDisabled,
+ replayableFromLastStep =
vm.model.workflow.data.replayableLastStep>=0 && !replayableDisabled;
- if (replayableContinuing) {
- $scope.actions.workflowReplays.push({ targetId:
'end', reason: 'Resume workflow at step
'+(vm.model.workflow.data.replayableLastStep+1)+' from UI',
- label: 'Resume '+(stepIndex>=0 ? 'workflow ' :
'')+' (at step '+(vm.model.workflow.data.replayableLastStep+1)+')' });
+ if (replayableFromLastStep) {
+ let msg = 'Replay from last replay point (step
'+(vm.model.workflow.data.replayableLastStep+1)+')';
+ $scope.actions.workflowReplays.push({ targetId:
'last', reason: msg+' from UI', label: msg });
}
// get current step, replay from that step
if (stepIndex>=0) {
const osi =
vm.model.workflow.data.oldStepInfo[stepIndex] || {};
- if (osi.replayableFromHere) {
- $scope.actions.workflowReplays.push({
targetId: ''+stepIndex, reason: 'Replay workflow from step '+(stepIndex+1)+'
from UI',
+ if (osi.replayableFromHere && !replayableDisabled)
{
+ $scope.actions.workflowReplays.push({
targetId: ''+stepIndex, reason: 'Replay from step '+(stepIndex+1)+' from UI',
label: 'Replay from here (step
'+(stepIndex+1)+')' });
} else {
$scope.actions.workflowReplays.push({
targetId: ''+stepIndex, reason: 'Force replay from step '+(stepIndex+1)+' from
UI',
- label: 'Force replay from here (step
'+(stepIndex+1), force: true });
+ label: 'Force replay from here (step
'+(stepIndex+1)+')', force: true });
}
}
if (replayableFromStart) {
- let w1 = 'Restart', w2 = '(not resumable)';
+ let w1 = 'Replay from start', w2 = '(no other
replay points)';
if (stepIndex<0 || (_.isNil(stepIndex) &&
vm.model.workflow.data.replayableLastStep==-2)) { w1 = 'Run'; w2 = 'again'; }
- else if (replayableContinuing) w2 = '';
+ else if (replayableFromLastStep) w2 = '';
else if (_.isNil(stepIndex)) { w2 = '(did not
start)'; }
- $scope.actions.workflowReplays.push({targetId:
'start', reason: 'Restart workflow from UI',
- label: w1+' '+(stepIndex>=0 ? 'workflow ' :
'')+w2});
+ $scope.actions.workflowReplays.push({targetId:
'start', reason: 'Replay from start from UI',
+ label: w1+' '+w2});
+ }
+
+ if (currentStepIndex>=0 && currentStepIndex <
vm.model.workflow.data.stepsDefinition.length) {
+ let msg = 'eplay resuming (at step ' +
(currentStepIndex + 1);
+ if (!replayableDisabled) {
+ $scope.actions.workflowReplays.push({
targetId: 'last', label: 'R'+msg+' if possible)', reason: 'R'+msg+') from UI'
});
+ }
+ $scope.actions.workflowReplays.push({ targetId:
'last', label: 'Force r'+msg+')', reason: 'Force r'+msg+') from UI', force:
true });
}
if (!replayableFromStart) {
- $scope.actions.workflowReplays.push({targetId:
'start', reason: 'Force restart from UI',
- label: 'Force restart', force: true});
+ $scope.actions.workflowReplays.push({targetId:
'start', reason: 'Force replay from start from UI',
+ label: 'Force replay from start', force:
true});
}
+
// force replays
$scope.actions.workflowReplays.forEach(r => {
// could prompt for a reason
diff --git
a/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.template.html
b/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.template.html
index 1fe8b110..63a2e1c5 100644
---
a/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.template.html
+++
b/ui-modules/app-inspector/app/views/main/inspect/activities/detail/detail.template.html
@@ -45,7 +45,7 @@
<code><a
ui-sref="main.inspect.activities.detail({entityId:
vm.model.activity.blockingTask.metadata.entityId, activityId:
vm.model.activity.blockingTask.metadata.id})">{{vm.model.activity.blockingTask.metadata.taskName}}</a></code>
for <strong><a ui-sref="main.inspect.summary({entityId:
vm.model.activity.blockingTask.metadata.entityId})">{{vm.model.activity.blockingTask.metadata.entityDisplayName}}
entity</a></strong>
</div>
- <div style="float:right;" ng-if="vm.isNonEmpty(actions)"
class="btn-group dropdown-nested dropdown-menu-right" uib-dropdown-nested
dropdown-append-to-body="true">
+ <div style="float:right; margin-left: 1em;"
ng-if="vm.isNonEmpty(actions)" class="btn-group dropdown-nested
dropdown-menu-right" uib-dropdown-nested dropdown-append-to-body="true">
<br-button uib-dropdown-toggle-nested type="btn-primary">
Actions <span class="caret"></span>
</br-button>
@@ -64,6 +64,8 @@
</li>
+ <li><a href="" ng-if="actions.delete"
ng-click="actions.delete.doAction()">{{actions.delete.label}}</a></li>
+
<li><a href="" ng-if="actions.invokeAgain"
ng-click="actions.invokeAgain.doAction()">Reinvoke effector</a></li>
<li><a href="" ng-if="actions.effector"
ui-sref="main.inspect.effectors({search: actions.effector.effectorName})">Open
in effector tab</a></li>