Skip to content

Commit

Permalink
Merge pull request #471 from jeffibm/dialog-workflow-options
Browse files Browse the repository at this point in the history
Introducing embedded_workflow to dynamic select box in service dialogs
  • Loading branch information
agrare committed Jul 18, 2023
2 parents a5db071 + ed21527 commit 95b3cb2
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,25 @@
<div ng-if="vm.modalTabIsSet('options') && vm.modalData.dynamic">
<form class="form-horizontal">
<div ng-show="!vm.treeOptions.show">
<div pf-form-group pf-label="{{'Entry Point'|translate}}">
<div class="input-group">
<input type="text" class="form-control" ng-value="vm.showFullyQualifiedName(vm.modalData.resource_action)" disabled>
<div pf-form-group pf-label="Automation Type" class="entry_point_selector_types">
<select ng-show="vm.treeOptions.emsWorkflowsEnabled" class="form-control automation_type_selector" miq-select ng-model="vm.modalData.automation_type" ng-change="vm.treeOptions.onAutomationTypeChange()">
<option value="{{vm.treeOptions.automationTypes.automate}}" translate>Embedded Automate</option>
<option value="{{vm.treeOptions.automationTypes.workflow}}" translate>Embedded Workflows</option>
</select>
<div class="input-group entry_point" style="margin-top:0;" ng-if="vm.treeOptions.displayAutomationType().automate">
<input type="text" placeholder="Embedded Automate" class="form-control" ng-value="vm.showFullyQualifiedName(vm.modalData.resource_action)" disabled>
<span class="input-group-btn">
<button class="btn btn-default" ng-click="vm.treeOptions.toggle();"><i class="ff ff-load-balancer"></i></button>
</span>
</div>
</div>
<div ng-show="vm.treeOptions.emsWorkflowsEnabled" class="input-group" ng-if="vm.treeOptions.displayAutomationType().workflow">
<input type="text" placeholder="Embedded Workflow" class="form-control" ng-value="vm.modalData.resource_action.workflow_name" disabled>
<span class="input-group-btn">
<button class="btn btn-default" ng-click="vm.treeOptions.toggleWorkflows();"><i class="ff ff-load-balancer"></i></button>
</span>
<input type="hidden" class="form-control" ng-value="vm.modalData.resource_action.configuration_script_id" disabled>
</div>
</div>
<dialog-editor-modal-field-template template="dynamic-values.html"
modal-data="vm.modalData">
</dialog-editor-modal-field-template>
Expand Down
100 changes: 92 additions & 8 deletions src/dialog-editor/components/modal-field/modalFieldComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,50 @@ class ModalFieldController extends ModalController {
public validation: any;

public $onInit() {

const emsWorkflowsEnabled = this.treeOptions.emsWorkflowsEnabled === 'true' ? true : false;

/** Function to load the selected workflow if configuration_script_id is available. */
if (emsWorkflowsEnabled && this.modalData.resource_action && this.modalData.resource_action.configuration_script_id) {
this.loadWorkflow(this.modalData.resource_action.configuration_script_id);
};

this.treeOptions = {
...this.treeOptions,

show: false,
includeDomain: false,
data: null,
automationType: null,
automationTypes: {
automate: 'embedded_automate',
workflow: 'embedded_workflow',
},
emsWorkflowsEnabled: emsWorkflowsEnabled,

/** Function to reset the modalData while changin the Automation Type. */
onAutomationTypeChange: () => {
this.treeOptions.automationType = this.modalData.automation_type;
},

/** Function to display the automation_type select box
* 'Embedded Automate' will be displayed, by default.
* When the workflows are enabled, and automation_type === embedded_automate, 'Embedded Automate' select box will be displayed.
* Else, 'Embedded Workflow' will be selected.
*/
displayAutomationType: () => {
let displayAutomate = true;

if(emsWorkflowsEnabled) {
displayAutomate = this.modalData.automation_type === this.treeOptions.automationTypes.automate;
}
return {automate: displayAutomate, workflow: !displayAutomate};
},

/** Function to open the modal box and load the automate tree. */
toggle: () => {
this.treeOptions.show = ! this.treeOptions.show;
this.treeOptions.automationType = this.treeOptions.automationTypes.automate;

if (this.treeOptions.show) {
const fqname = this.showFullyQualifiedName(this.modalData.resource_action) || null;
Expand All @@ -41,38 +76,87 @@ class ModalFieldController extends ModalController {
}
},

/** Function to open the modal box and load the workflows list. */
toggleWorkflows: () => {
this.treeOptions.show = ! this.treeOptions.show;
this.treeOptions.automationType = this.treeOptions.automationTypes.workflow;

if (this.treeOptions.show) {
this.treeOptions.loadAvailableWorkflows().then((data) => {
this.treeOptions.data = data.resources.filter((item: any) => item.payload);
const workflow = this.treeOptions.data.find((item) => item.id === this.modalData.resource_action.configuration_script_id);
this.treeOptions.selected = workflow ? workflow.name : null;
});
}
},

/** Function to handle the onclick event of an item in tree. */
onSelect: (node) => {
this.treeSelectorSelect(node, this.modalData);
}
};
}

public showFullyQualifiedName(resourceAction) {
if (resourceAction.ae_namespace && resourceAction.ae_class && resourceAction.ae_instance) {
if (!resourceAction) {
return '';
}
const actionKeys = ['ae_namespace', 'ae_class', 'ae_instance'];
const keysPresent = actionKeys.every((item) => resourceAction.hasOwnProperty(item));

if (keysPresent && resourceAction.ae_namespace && resourceAction.ae_class && resourceAction.ae_instance) {
return `${resourceAction.ae_namespace}/${resourceAction.ae_class}/${resourceAction.ae_instance}`;
} else {
return '';
}
}

public treeSelectorSelect(node, elementData) {
/** Function to extract the values needed for embedded_automate during onclick event of an item from the tree */
public onEmbeddedAutomateSelect(node, elementData) {
const fqname = node.fqname.split('/');

if (this.treeOptions.includeDomain === false) {
fqname.splice(1, 1);
}
if (elementData.resource_action) {
elementData.resource_action = {
...elementData.resource_action,
ae_instance: fqname.pop(),
ae_class: fqname.pop(),
ae_namespace: fqname.filter(String).join('/'),
};
}
}

elementData.resource_action = {
...elementData.resource_action,
ae_instance: fqname.pop(),
ae_class: fqname.pop(),
ae_namespace: fqname.filter(String).join('/'),
};
/** Function to extract the values needed for embedded_workflow during onclick event of an item from the list */
public onEmbeddedWorkflowsSelect(workflow, elementData) {
if (elementData.resource_action) {
elementData.resource_action = {
...elementData.resource_action,
configuration_script_id: workflow.id,
workflow_name: workflow.name,
};
}
}

/** Function to extract the values needed for entry points during onclick event of an item from the tree or list */
public treeSelectorSelect(node, elementData) {
if (this.treeOptions.automationType === this.treeOptions.automationTypes.automate) {
this.onEmbeddedAutomateSelect(node, elementData);
} else if (this.treeOptions.automationType === this.treeOptions.automationTypes.workflow) {
this.onEmbeddedWorkflowsSelect(node, elementData);
}
this.treeOptions.show = false;
}

public modalFieldIsValid() {
return this.validation.validateField(this.modalData);
}

/** Function to load a selected workflow. */
public loadWorkflow(id: number) {
this.treeOptions.loadWorkflow(id).then(({data, status}) => {
this.modalData.resource_action.workflow_name = status ? data.name : '';
});
}
}
9 changes: 8 additions & 1 deletion src/dialog-editor/components/modal/modalComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,21 @@ class ModalController {
}
}

/** Function to set automationType in modalFieldData. */
private setAutomationType(modalFieldData: any) {
const automationType = modalFieldData.resource_action && modalFieldData.resource_action.configuration_script_id ? 'embedded_workflow' : 'embedded_automate';
modalFieldData.automation_type = automationType;
return modalFieldData;
}

public loadModalFieldData(tab: number, box: number, field: number) {
if (typeof tab !== 'undefined' &&
typeof box !== 'undefined' &&
typeof field !== 'undefined') {
let tabList = this.DialogEditor.getDialogTabs();
let boxList = tabList[tab];
let fieldList = boxList.dialog_groups[box];
return fieldList.dialog_fields[field];
return this.setAutomationType(fieldList.dialog_fields[field]);
}
}

Expand Down
77 changes: 51 additions & 26 deletions src/dialog-editor/components/tree-selector/tree-selector.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,53 @@
<div class="pull-right">
<button type="button" class="close" ng-click="$ctrl.treeOptions.toggle()" aria-hidden="true">
<span class="pficon pficon-close"></span>
</button>
</div>

<div ng-if="!$ctrl.treeOptions.data" class="spinner spinner-lg"></div>
<div ng-if="$ctrl.treeOptions.data">
<miq-tree-selector
name="tree-selector"
data="$ctrl.treeOptions.data"
selectable="{key: '^aei-'}"
on-select="$ctrl.treeOptions.onSelect(node)"
lazy-load="$ctrl.treeOptions.lazyLoad(node)"
selected="$ctrl.treeOptions.selected"
></miq-tree-selector>
</div>

<div class="col-sm-4">
<div class="form-group pull-right">
<label class="control-label" translate>Include domain prefix in the path:</label>
<input bs-switch
type="checkbox"
ng-model="$ctrl.treeOptions.includeDomain"
switch-on-text="{{'Yes'|translate}}"
switch-off-text="{{'No'|translate}}"/>
<div class="tree_selector_wrapper">
<div class="tree_selector_title_wrapper">
<div class="tree_selector_dialog_title">
<span ng-if="$ctrl.treeOptions.automationType==$ctrl.treeOptions.automationTypes.automate">
Select Embededded Automate
</span>
<span ng-if="$ctrl.treeOptions.automationType==$ctrl.treeOptions.automationTypes.workflow">
Select Embededded Workflow
</span>
</div>
<div class="tree_selector_action">
<div class="pull-right">
<button type="button" class="close" ng-click="$ctrl.treeOptions.toggle()" aria-hidden="true">
<span class="pficon pficon-close"></span>
</button>
</div>
</div>
</div>
<div class="tree_selector_content_wrapper">
<div ng-if="!$ctrl.treeOptions.data" class="spinner spinner-lg"></div>
<div ng-if="$ctrl.treeOptions.automationType==$ctrl.treeOptions.automationTypes.automate">
<div ng-if="$ctrl.treeOptions.data">
<miq-tree-selector
name="tree-selector"
data="$ctrl.treeOptions.data"
selectable="{key: '^aei-'}"
on-select="$ctrl.treeOptions.onSelect(node)"
lazy-load="$ctrl.treeOptions.lazyLoad(node)"
selected="$ctrl.treeOptions.selected"
></miq-tree-selector>
</div>
<div class="col-sm-4">
<div class="form-group pull-right">
<label class="control-label" translate>Include domain prefix in the path:</label>
<input bs-switch
type="checkbox"
ng-model="$ctrl.treeOptions.includeDomain"
switch-on-text="{{'Yes'|translate}}"
switch-off-text="{{'No'|translate}}"/>
</div>
</div>
</div>
<div ng-if="$ctrl.treeOptions.automationType==$ctrl.treeOptions.automationTypes.workflow">
<div ng-if="$ctrl.treeOptions.data">
<ul class="nav nav-list workflows_list_wrapper" ng-repeat="workflow in $ctrl.treeOptions.data">
<li class="workflow_item" ng-click="$ctrl.treeOptions.onSelect(workflow)">
{{workflow.name}}
</li>
</ul>
</div>
</div>
</div>
</div>
2 changes: 1 addition & 1 deletion src/dialog-editor/services/dialogValidationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default class DialogValidationService {
field => ({ status: (field.type !== 'DialogFieldTagControl') || tagHasCategory(field),
errorMessage: __('Category needs to be set for TagControl field'),
local: true }),
field => ({ status: ! (field.dynamic && _.isEmpty(field.resource_action.ae_class)),
field => ({ status: ! (field.dynamic && !field.resource_action.configuration_script_id && _.isEmpty(field.resource_action.ae_class)),
errorMessage: __('Entry Point needs to be set for Dynamic elements'),
local: true }),
field => ({ status: ! ((field.type === 'DialogFieldDropDownList' ||
Expand Down
4 changes: 2 additions & 2 deletions src/dialog-user/services/dialogData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ export default class DialogDataService {
options,
values,
}) {
let dropDownValues = values.map((option) => {
let dropDownValues = values && values.map((option) => {
const value = this.convertDropdownValue(option[0], data_type);
const description = (!Number.isInteger(option[1]) ? option[1] : parseInt(option[1], 10));

return [value, description];
});

if (options.sort_by !== 'none') {
if (values && options.sort_by !== 'none') {
return this.updateFieldSortOrder({
options,
values: dropDownValues,
Expand Down
70 changes: 70 additions & 0 deletions src/styles/dialog-editor-boxes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,73 @@
.draggable-field-dropdown {
z-index: initial;
}

.entry_point_selector_types {

.automation_type_selector {
margin-bottom: 20px !important;
}
.entry_point {
margin-top: 20px;
}
}


l.nav.nav-list.workflows {
background-color: #f5f5f5;
border: 1px solid #e3e3e3;

li {
border-bottom: 1px solid lightgray;
padding: 10px;
}
}

.tree_selector_wrapper {
display: flex;
flex-direction: column;
border: 1px solid lightgray;
margin-top: 10px;

.tree_selector_title_wrapper {
display: flex;
flex-direction: row;
background: lightgray;
padding: 5px;

.tree_selector_dialog_title {
display: flex;
flex-grow: 1;
font-weight: bold;
padding: 5px 0;
font-size: 14px;
}
.tree_selector_action {
display: flex;
justify-content: center;
align-items: center;
min-width: 30px;
}
}
.tree_selector_content_wrapper {
display: flex;
flex-direction: column;
padding: 10px;

ul.workflows_list_wrapper {
display: flex;

li.workflow_item {
display: flex;
flex-grow: 1;
padding: 5px;

&:hover {
background: #e4e5e6;
cursor: pointer;
}

}
}
}
}
2 changes: 1 addition & 1 deletion src/styles/ui-components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/* Begin Patternfly Tab overrides used in the Dialog Editor */

.dialog-editor-tab-list {
margin-bottom: 20px;
margin-bottom: 20px !important;
}

.delete-tab {
Expand Down

0 comments on commit 95b3cb2

Please sign in to comment.