onSelect(selectedRow.id)}
+ showPagination={false}
+ truncateText={false}
+ mode="automated-workflow-entry-points"
+ gridChecks={[data.selectedItemId]}
+ />
+
+
+
+
+
+
+ >
+
+ );
+};
+WorkflowEntryPoints.propTypes = {
+ entryPoint: PropTypes.string.isRequired,
+ fieldName: PropTypes.string.isRequired,
+};
+
+export default WorkflowEntryPoints;
diff --git a/app/javascript/components/workflows/workflows-dummy-data.js b/app/javascript/components/workflows/workflows-dummy-data.js
new file mode 100644
index 000000000000..f2b3f140ab9b
--- /dev/null
+++ b/app/javascript/components/workflows/workflows-dummy-data.js
@@ -0,0 +1,159 @@
+/* **********************************************************
+ * This file contains dummy data for List and Summary Page.
+ * This file can be removed when we have API's in place.
+ * ********************************************************** /
+
+/** Dummy data for List Page */
+import { rowData } from '../miq-data-table/helper';
+
+/** Note:
+ * We are restructuing data like this because this is how we get the data from backend.
+ * We can always use a new component and simplify this.
+ */
+
+/** Function to return the header information for the list */
+const headerInfo = () => [
+ { header: __('Name'), key: 'name' },
+];
+
+/** Function to return the header information for the service catalog item's entry points. */
+const entryPointsHeaderInfo = () => [
+ { header: __('Workflows'), key: 'name' },
+];
+
+/** Function to return the cell data for a row item. */
+const celInfo = (workflow) => [
+ { text: workflow.name },
+];
+
+/** Function to return the row information for the list */
+const rowInfo = (headers, response) => {
+ const headerKeys = headers.map((item) => item.key);
+ const rows = response.resources.map((workflow) => ({
+ id: workflow.id.toString(), cells: celInfo(workflow), clickable: true,
+ }));
+ // const rows = [...Array(50)].map((_item, index) => ({
+ // id: index.toString(), cells: celInfo(index), clickable: true,
+ // }));
+ const miqRows = rowData(headerKeys, rows, false);
+ return miqRows.rowItems;
+};
+
+/** Function to return the dummy data for automated workflows
+ * This data is used in data table list.
+*/
+export const workflowsList = (response) => {
+ const headers = headerInfo();
+ return { headers, rows: rowInfo(headers, response) };
+};
+
+export const workflowsEntryPoints = (response) => {
+ const headers = entryPointsHeaderInfo();
+ return { headers, rows: rowInfo(headers, response) };
+};
+
+/** Dummy data for Summary Page */
+
+const summary = (response) => ([
+ { label: __('Name'), value: response.name },
+ { label: __('Ems ID'), value: response.ems_id },
+ { label: __('Created at'), value: response.created_at },
+]);
+
+/** Not being used and can be removed. */
+export const jsonData = ` {
+ "Comment": "An example of the Amazon States Language using a choice state.",
+ "StartAt": "FirstState",
+ "States": {
+ "FirstState": {
+ "Type": "Task",
+ "Resource": "docker://agrare/hello-world:latest",
+ "Credentials": {
+ "mysecret": "dont tell anyone"
+ },
+ "Retry": [
+ {
+ "ErrorEquals": [ "States.Timeout" ],
+ "IntervalSeconds": 3,
+ "MaxAttempts": 2,
+ "BackoffRate": 1.5
+ }
+ ],
+ "Catch": [
+ {
+ "ErrorEquals": [ "States.ALL" ],
+ "Next": "FailState"
+ }
+ ],
+ "Next": "ChoiceState"
+ },
+
+ "ChoiceState": {
+ "Type" : "Choice",
+ "Choices": [
+ {
+ "Variable": "$.foo",
+ "NumericEquals": 1,
+ "Next": "FirstMatchState"
+ },
+ {
+ "Variable": "$.foo",
+ "NumericEquals": 2,
+ "Next": "SecondMatchState"
+ },
+ {
+ "Variable": "$.foo",
+ "NumericEquals": 3,
+ "Next": "SuccessState"
+ }
+ ],
+ "Default": "FailState"
+ },
+
+ "FirstMatchState": {
+ "Type" : "Task",
+ "Resource": "docker://agrare/hello-world:latest",
+ "Next": "PassState"
+ },
+
+ "SecondMatchState": {
+ "Type" : "Task",
+ "Resource": "docker://agrare/hello-world:latest",
+ "Next": "NextState"
+ },
+
+ "PassState": {
+ "Type": "Pass",
+ "Result": {
+ "foo": "bar",
+ "bar": "baz"
+ },
+ "ResultPath": "$.result",
+ "Next": "NextState"
+ },
+
+ "FailState": {
+ "Type": "Fail",
+ "Error": "FailStateError",
+ "Cause": "No Matches!"
+ },
+
+ "SuccessState": {
+ "Type": "Succeed"
+ },
+
+ "NextState": {
+ "Type": "Task",
+ "Resource": "docker://agrare/hello-world:latest",
+ "Secrets": ["vmdb:aaa-bbb-ccc"],
+ "End": true
+ }
+ }
+}`;
+
+export const workflowData = (response) => (
+ {
+ summary: summary(response),
+ jsonData: response.workflow_content,
+ }
+);
diff --git a/app/javascript/oldjs/controllers/dialog_editor/dialog_editor_controller.js b/app/javascript/oldjs/controllers/dialog_editor/dialog_editor_controller.js
index e62addaf7960..0df25e6ac063 100644
--- a/app/javascript/oldjs/controllers/dialog_editor/dialog_editor_controller.js
+++ b/app/javascript/oldjs/controllers/dialog_editor/dialog_editor_controller.js
@@ -8,6 +8,7 @@ ManageIQ.angular.app.controller('dialogEditorController', ['$window', 'miqServic
// options for tree selector
vm.treeOptions = {
load: DialogEditorHttp.treeSelectorLoadData,
+ loadWorkflows: DialogEditorHttp.treeSelectorLoadWorkflows,
lazyLoad: DialogEditorHttp.treeSelectorLazyLoadData,
};
diff --git a/app/javascript/oldjs/miq_application.js b/app/javascript/oldjs/miq_application.js
index d85e9572961e..109a02bc0624 100644
--- a/app/javascript/oldjs/miq_application.js
+++ b/app/javascript/oldjs/miq_application.js
@@ -954,6 +954,12 @@ window.miqShowAE_Tree = function(typ) {
return true;
};
+window.miqShowEmbededdedWorkflowsModal = function(type) {
+ const url = `/${ManageIQ.controller}/embededded_workflows_modal`;
+ miqJqueryRequest(miqPassFields(url, { type }));
+ return true;
+};
+
// Toggle the user options div in the page header (:onclick from layouts/user_options)
window.miqChangeGroup = function(id) {
miqSparkleOn();
diff --git a/app/javascript/oldjs/services/dialog_editor_http_service.js b/app/javascript/oldjs/services/dialog_editor_http_service.js
index 6ccf6b15b700..2492cbd139b7 100644
--- a/app/javascript/oldjs/services/dialog_editor_http_service.js
+++ b/app/javascript/oldjs/services/dialog_editor_http_service.js
@@ -19,6 +19,14 @@ ManageIQ.angular.app.service('DialogEditorHttp', ['$http', 'API', function($http
});
};
+ this.treeSelectorLoadWorkflows = function(fqname) {
+ var url = '/api/workflows/?expand=resources' + (fqname ? '?fqname=' + encodeURIComponent(fqname) : '');
+ return $http.get(url).then(function(response) {
+ return response.data;
+ });
+ };
+
+
this.treeSelectorLazyLoadData = function(node) {
return $http.get('/tree/automate_entrypoint?id=' + encodeURIComponent(node.key)).then(function(response) {
return response.data;
diff --git a/app/javascript/packs/component-definitions-common.js b/app/javascript/packs/component-definitions-common.js
index 5460c5b83301..d1ac92dc8013 100644
--- a/app/javascript/packs/component-definitions-common.js
+++ b/app/javascript/packs/component-definitions-common.js
@@ -10,6 +10,9 @@ import AggregateStatusCard from '../components/aggregate_status_card';
import AnsibleCredentialsForm from '../components/ansible-credentials-form';
import AnsibleRepositoryForm from '../components/ansible-repository-form';
import AuthKeypairCloudForm from '../components/auth-key-pair-cloud';
+import WorkflowEntryPoints from '../components/workflows/workflow-entry-points';
+import WorkflowList from '../components/workflows';
+import WorkflowSummary from '../components/workflows/summary';
import { BreadcrumbsBar } from '../components/breadcrumbs';
import ButtonList from '../components/data-tables/button-list';
import ButtonGroupList from '../components/data-tables/button-group-list';
@@ -166,6 +169,9 @@ ManageIQ.component.addReact('AggregateStatusCard', AggregateStatusCard);
ManageIQ.component.addReact('AnsibleCredentialsForm', AnsibleCredentialsForm);
ManageIQ.component.addReact('AnsibleRepositoryForm', AnsibleRepositoryForm);
ManageIQ.component.addReact('AuthKeypairCloudForm', AuthKeypairCloudForm);
+ManageIQ.component.addReact('WorkflowEntryPoints', WorkflowEntryPoints);
+ManageIQ.component.addReact('WorkflowList', WorkflowList);
+ManageIQ.component.addReact('WorkflowSummary', WorkflowSummary);
ManageIQ.component.addReact('BreadcrumbsBar', BreadcrumbsBar);
ManageIQ.component.addReact('ButtonList', ButtonList);
ManageIQ.component.addReact('ButtonGroupList', ButtonGroupList);
diff --git a/app/presenters/menu/default_menu.rb b/app/presenters/menu/default_menu.rb
index 3d93db7740db..3fc88e86f442 100644
--- a/app/presenters/menu/default_menu.rb
+++ b/app/presenters/menu/default_menu.rb
@@ -188,6 +188,7 @@ def automation_menu_section
automation_manager_menu_section,
configuration_menu_section,
ansible_menu_section,
+ workflow_menu_section,
automate_menu_section,
])
end
@@ -209,6 +210,14 @@ def ansible_menu_section
])
end
+ def workflow_menu_section
+ Menu::Section.new(:embedded_workflow_automation_manager, N_("Embedded Workflow"), nil, [
+ Menu::Item.new('embedded_workflow', N_('Workflows'), 'embedded_workflow', {:feature => 'embedded_workflow_view', :any => true}, '/workflow/show_list'),
+ Menu::Item.new('embedded_workflow_repository', N_('Repositories'), 'embedded_workflow_repository', {:feature => 'embedded_workflow_repository_view', :any => true}, '/workflow_repository/show_list'),
+ Menu::Item.new('embedded_workflow_credential', N_('Credentials'), 'embedded_workflowcredentials', {:feature => 'embedded_workflow_credential_view', :any => true}, '/workflow_credential/show_list'),
+ ])
+ end
+
def automate_menu_section
Menu::Section.new(:automate, N_("Embedded Automate"), nil, [
Menu::Item.new('miq_ae_class', N_('Explorer'), 'miq_ae_class_explorer', {:feature => 'miq_ae_domain_view'}, '/miq_ae_class/explorer'),
diff --git a/app/stylesheet/legacy/miq_tree.scss b/app/stylesheet/legacy/miq_tree.scss
index d52b819f770c..efe9cf752752 100644
--- a/app/stylesheet/legacy/miq_tree.scss
+++ b/app/stylesheet/legacy/miq_tree.scss
@@ -35,3 +35,46 @@
cursor: default !important;
}
}
+
+ul.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;
+ }
+}
diff --git a/app/views/catalog/_embedded_workflows_modal.html.haml b/app/views/catalog/_embedded_workflows_modal.html.haml
new file mode 100644
index 000000000000..5d9a615d0dd5
--- /dev/null
+++ b/app/views/catalog/_embedded_workflows_modal.html.haml
@@ -0,0 +1,23 @@
+.modal.fade{"tabindex" => "-1",
+ "id" => "#{entry_point}_modal",
+ "role" => "dialog",
+ "aria-labelledby" => "ep_modal_label",
+ "aria-describedby" => "modal",
+ "aria-hidden" => "true",
+ "data-keyboard" => "false",
+ "data-backdrop" => "static",
+ :style => "display: none"}
+ .modal-dialog.modal-lg
+ .modal-content
+ .modal-header
+ %button.close{"data-dismiss" => "modal"}
+ %span{"aria-hidden" => "true"}
+ ×
+ %span.sr-only
+ Close
+ %h4.modal-title
+ = _("Select an embededded workflow for provisioning entry point")
+
+ .modal-body
+ = react('WorkflowEntryPoints', {:fieldName => field_name, :entryPoint => entry_point})
+ .modal-footer
diff --git a/app/views/catalog/_form_basic_info.html.haml b/app/views/catalog/_form_basic_info.html.haml
index f19e9fcae47e..ab4e8156b955 100644
--- a/app/views/catalog/_form_basic_info.html.haml
+++ b/app/views/catalog/_form_basic_info.html.haml
@@ -1,5 +1,7 @@
- url = url_for(:id => "#{@edit[:rec_id] || "new"}",
:action => @edit[:new][:service_type] == "composite" ? "st_form_field_changed" : "atomic_form_field_changed")
+- entry_point_options = [["<#{_('No Entry Point')}>", nil], ["Embedded Automate", "embedded_automate"], ["Embedded Workflows", "embedded_workflows"]]
+
%h3= _('Basic Information')
#basic_info_div
@@ -163,67 +165,50 @@
.form-group
%label.col-md-2.control-label{:title => _("Provisioning Entry Point (NameSpace/Class/Instance)")}
= _('Provisioning Entry Point')
- .col-md-8{:title => @edit[:new][:fqname]}
- .input-group
- = text_field_tag("fqname",
- @edit[:new][:fqname],
- :class => "form-control",
- "data-miq_observe" => {:interval => '.5', :url => url}.to_json)
- %span.input-group-btn
- #fqname_div
- %button.btn.btn-default{"onclick" => "miqShowAE_Tree('provision'); miqButtons('hide', 'automate');",
- "title" => _('Click to select Provisioning Entry Point')}
- %i.ff.ff-load-balancer
- %button.btn.btn-default{"id" => "fqname_remove",
- "onclick" => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'provision')}');",
- "title" => _('Remove this Provisioning Entry Point'),
- "data-confirm" => _("Are you sure you want to remove this Provisioning Entry Point?"),
- "disabled" => @edit[:new][:fqname].nil?}
- %i.pficon.pficon-close
- %span.input-group-addon{:style => "visibility:hidden"}
+ .col-md-8{:style => "padding: 0px;"}
+ .col-md-4{:title => @edit[:new][:fqname]}
+ %p.form-control-static
+ = select_tag('provisioning_entry_point_type',
+ options_for_select(entry_point_options, @edit[:new][:provisioning_entry_point_type]),
+ "data-miq_sparkle_on" => true,
+ :class => "selectpicker")
+ :javascript
+ miqInitSelectPicker();
+ miqSelectPickerEvent('provisioning_entry_point_type', '#{url}')
+ .col-md-8#provision_entry_point{:style => "padding: 0px;"}
+ = render(:partial => "provision_entry_points")
- unless %w[generic_container_template generic_ovf_template].include?(@edit[:new][:st_prov_type])
.form-group
%label.col-md-2.control-label{:title => _("Reconfigure Entry Point (NameSpace/Class/Instance)")}
= _('Reconfigure Entry Point')
- .col-md-8{:title => @edit[:new][:reconfigure_fqname]}
- .input-group
- = text_field_tag("reconfigure_fqname",
- @edit[:new][:reconfigure_fqname],
- :class => "form-control",
- "data-miq_observe" => {:interval => '.5', :url => url}.to_json)
- %span.input-group-btn
- #reconfigure_fqname_div
- %button.btn.btn-default{"onclick" => "miqShowAE_Tree('reconfigure'); miqButtons('hide', 'automate');",
- "title" => _('Click to select Reconfigure Entry Point')}
- %i.ff.ff-load-balancer
- %button.btn.btn-default{"id" => "reconfigure_fqname_remove",
- "onclick" => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'reconfigure')}');",
- "title" => _('Remove this Reconfigure Entry Point'),
- "data-confirm" => _("Are you sure you want to remove this Reconfigure Entry Point?"),
- "disabled" => @edit[:new][:reconfigure_fqname].nil?}
- %i.pficon.pficon-close
- %span.input-group-addon{:style => "visibility:hidden"}
+ .col-md-8{:style => "padding: 0px;"}
+ .col-md-4{:title => @edit[:new][:reconfigure_fqname]}
+ %p.form-control-static
+ = select_tag('reconfigure_entry_point_type',
+ options_for_select(entry_point_options, @edit[:new][:reconfigure_entry_point_type]),
+ "data-miq_sparkle_on" => true,
+ :class => "selectpicker")
+ :javascript
+ miqInitSelectPicker();
+ miqSelectPickerEvent('reconfigure_entry_point_type', '#{url}')
+ .col-md-8#reconfigure_entry_point{:style => "padding: 0px;"}
+ = render(:partial => "reconfigure_entry_points")
.form-group
%label.col-md-2.control-label{:title => _("Retirement Entry Point (NameSpace/Class/Instance)")}
= _('Retirement Entry Point')
- .col-md-8{:title => @edit[:new][:retire_fqname]}
- .input-group
- = text_field_tag("retire_fqname",
- @edit[:new][:retire_fqname],
- :class => "form-control",
- "data-miq_observe" => {:interval => '.5', :url => url}.to_json)
- %span.input-group-btn
- #retire_fqname_div
- %button.btn.btn-default{"onclick" => "miqShowAE_Tree('retire'); miqButtons('hide', 'automate');",
- "title" => _('Click to select Retirement Entry Point')}
- %i.ff.ff-load-balancer
- %button.btn.btn-default{"id" => "retire_fqname_remove",
- "onclick" => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'retire')}');",
- "title" => _('Remove this Retirement Entry Point'),
- "data-confirm" => _("Are you sure you want to remove this Retirement Entry Point?"),
- "disabled" => @edit[:new][:retire_fqname].nil?}
- %i.pficon.pficon-close
- %span.input-group-addon{:style => "visibility:hidden"}
+ .col-md-8{:style => "padding: 0px;"}
+ .col-md-4{:title => @edit[:new][:fqname]}
+ %p.form-control-static
+ = select_tag('retirement_entry_point_type',
+ options_for_select(entry_point_options, @edit[:new][:retire_fqname]),
+ "data-miq_sparkle_on" => true,
+ :class => "selectpicker")
+ :javascript
+ miqInitSelectPicker();
+ miqSelectPickerEvent('retirement_entry_point_type', '#{url}')
+ .col-md-8#retirement_entry_point{:style => "padding: 0px;"}
+ = render(:partial => "retirement_entry_points")
+
- if role_allows?(:feature => 'rbac_tenant_view')
= render(:partial => "tenants_tree_show")
- if @edit[:new][:st_prov_type] == "generic_ovf_template"
diff --git a/app/views/catalog/_provision_entry_points.html.haml b/app/views/catalog/_provision_entry_points.html.haml
new file mode 100644
index 000000000000..94f88af5b731
--- /dev/null
+++ b/app/views/catalog/_provision_entry_points.html.haml
@@ -0,0 +1,29 @@
+- if params[:provisioning_entry_point_type] && params[:provisioning_entry_point_type] != "nil"
+ - url = url_for(:id => "#{@edit[:rec_id] || "new"}",
+ :action => @edit[:new][:service_type] == "composite" ? "st_form_field_changed" : "atomic_form_field_changed")
+
+ - if params[:provisioning_entry_point_type] == "embedded_workflows"
+ = hidden_div_if(@edit, :id => "provision_entry_workflows") do
+ = render(:partial => 'embedded_workflows_modal', :locals => {:field_name => :fqname, :entry_point => "provision_entry_workflows"})
+ - modal = {:open => "miqShowEmbededdedWorkflowsModal('provision_entry_workflows'); miqButtons('hide', 'automate');",:close => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'provision')}');"}
+ - elsif params[:provisioning_entry_point_type] == "embedded_automate"
+ - modal = {:open => "miqShowAE_Tree('provision'); miqButtons('hide', 'automate');", :close => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'provision')}');"}
+
+ .col-md-12{:title => @edit[:new][:fqname], :style => "padding: 3px;"}
+ .input-group
+ = text_field_tag("fqname",
+ @edit[:new][:fqname],
+ :class => "form-control",
+ "data-miq_observe" => {:interval => '.5', :url => url}.to_json)
+ %span.input-group-btn
+ #fqname_div
+ %button.btn.btn-default{"onclick" => modal[:open],
+ "title" => _('Click to select Provisioning Entry Point')}
+ %i.ff.ff-load-balancer
+ %button.btn.btn-default{"id" => "fqname_remove",
+ "onclick" => modal[:close],
+ "title" => _('Remove this Provisioning Entry Point'),
+ "data-confirm" => _("Are you sure you want to remove this Provisioning Entry Point?"),
+ "disabled" => @edit[:new][:fqname].nil?}
+ %i.pficon.pficon-close
+ %span.input-group-addon{:style => "visibility:hidden"}
diff --git a/app/views/catalog/_reconfigure_entry_points.html.haml b/app/views/catalog/_reconfigure_entry_points.html.haml
new file mode 100644
index 000000000000..5d729e46f5bf
--- /dev/null
+++ b/app/views/catalog/_reconfigure_entry_points.html.haml
@@ -0,0 +1,29 @@
+- if params[:reconfigure_entry_point_type] && params[:reconfigure_entry_point_type] != "nil"
+ - url = url_for(:id => "#{@edit[:rec_id] || "new"}",
+ :action => @edit[:new][:service_type] == "composite" ? "st_form_field_changed" : "atomic_form_field_changed")
+
+ - if params[:reconfigure_entry_point_type] == "embedded_workflows"
+ = hidden_div_if(@edit, :id => "reconfigure_entry_workflows") do
+ = render(:partial => 'embedded_workflows_modal', :locals => {:field_name => :reconfigure_fqname, :entry_point => "reconfigure_entry_workflows" })
+ - modal = {:open => "miqShowEmbededdedWorkflowsModal('reconfigure_entry_workflows'); miqButtons('hide', 'automate');",:close => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'provision')}');"}
+ - elsif params[:reconfigure_entry_point_type] == "embedded_automate"
+ - modal = {:open => "miqShowAE_Tree('reconfigure'); miqButtons('hide', 'automate');", :close => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'reconfigure')}');"}
+
+ .col-md-12{:title => @edit[:new][:reconfigure_fqname], :style => "padding: 3px;"}
+ .input-group
+ = text_field_tag("reconfigure_fqname",
+ @edit[:new][:reconfigure_fqname],
+ :class => "form-control",
+ "data-miq_observe" => {:interval => '.5', :url => url}.to_json)
+ %span.input-group-btn
+ #reconfigure_fqname_div
+ %button.btn.btn-default{"onclick" => modal[:open],
+ "title" => _('Click to select Reconfigure Entry Point')}
+ %i.ff.ff-load-balancer
+ %button.btn.btn-default{"id" => "reconfigure_fqname_remove",
+ "onclick" => modal[:close],
+ "title" => _('Remove this Reconfigure Entry Point'),
+ "data-confirm" => _("Are you sure you want to remove this Reconfigure Entry Point?"),
+ "disabled" => @edit[:new][:reconfigure_fqname].nil?}
+ %i.pficon.pficon-close
+ %span.input-group-addon{:style => "visibility:hidden"}
diff --git a/app/views/catalog/_retirement_entry_points.html.haml b/app/views/catalog/_retirement_entry_points.html.haml
new file mode 100644
index 000000000000..aa66b7434f5f
--- /dev/null
+++ b/app/views/catalog/_retirement_entry_points.html.haml
@@ -0,0 +1,29 @@
+- if params[:retirement_entry_point_type] && params[:retirement_entry_point_type] != "nil"
+ - url = url_for(:id => "#{@edit[:rec_id] || "new"}",
+ :action => @edit[:new][:service_type] == "composite" ? "st_form_field_changed" : "atomic_form_field_changed")
+
+ - if params[:retirement_entry_point_type] == "embedded_workflows"
+ = hidden_div_if(@edit, :id => "retirement_entry_workflows") do
+ = render(:partial => 'embedded_workflows_modal', :locals => {:field_name => :retire_fqname, :entry_point => "retirement_entry_workflows" })
+ - modal = {:open => "miqShowEmbededdedWorkflowsModal('retirement_entry_workflows'); miqButtons('hide', 'automate');",:close => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'provision')}');"}
+ - elsif params[:retirement_entry_point_type] == "embedded_automate"
+ - modal = {:open => "miqShowAE_Tree('retire'); miqButtons('hide', 'automate');", :close => "miqAjax('#{url_for_only_path(:action => 'ae_tree_select_discard', :typ => 'retire')}');"}
+
+ .col-md-12{:title => @edit[:new][:retire_fqname], :style => "padding: 3px;"}
+ .input-group
+ = text_field_tag("retire_fqname",
+ @edit[:new][:retire_fqname],
+ :class => "form-control",
+ "data-miq_observe" => {:interval => '.5', :url => url}.to_json)
+ %span.input-group-btn
+ #retire_fqname_div
+ %button.btn.btn-default{"onclick" => modal[:open],
+ "title" => _('Click to select Reconfigure Entry Point')}
+ %i.ff.ff-load-balancer
+ %button.btn.btn-default{"id" => "retire_fqname_remove",
+ "onclick" => modal[:close],
+ "title" => _('Remove this Reconfigure Entry Point'),
+ "data-confirm" => _("Are you sure you want to remove this Retirement Entry Point?"),
+ "disabled" => @edit[:new][:retire_fqname].nil?}
+ %i.pficon.pficon-close
+ %span.input-group-addon{:style => "visibility:hidden"}
diff --git a/app/views/workflow/show.html.haml b/app/views/workflow/show.html.haml
new file mode 100644
index 000000000000..cf47915a5b84
--- /dev/null
+++ b/app/views/workflow/show.html.haml
@@ -0,0 +1,2 @@
+#main_div
+ = react('WorkflowSummary', {:recordId => params[:id]})
diff --git a/app/views/workflow/show_list.html.haml b/app/views/workflow/show_list.html.haml
new file mode 100644
index 000000000000..a9ceba83ceeb
--- /dev/null
+++ b/app/views/workflow/show_list.html.haml
@@ -0,0 +1,2 @@
+#main_div
+ = react('WorkflowList')
diff --git a/app/views/workflow_credential/show.html.haml b/app/views/workflow_credential/show.html.haml
new file mode 100644
index 000000000000..6ed558ea9bf3
--- /dev/null
+++ b/app/views/workflow_credential/show.html.haml
@@ -0,0 +1 @@
+= "Show credential"
diff --git a/app/views/workflow_credential/show_list.html.haml b/app/views/workflow_credential/show_list.html.haml
new file mode 100644
index 000000000000..9aa1226b1a14
--- /dev/null
+++ b/app/views/workflow_credential/show_list.html.haml
@@ -0,0 +1 @@
+= "Show credential list"
diff --git a/app/views/workflow_repository/show.html.haml b/app/views/workflow_repository/show.html.haml
new file mode 100644
index 000000000000..94a81181eabf
--- /dev/null
+++ b/app/views/workflow_repository/show.html.haml
@@ -0,0 +1 @@
+= "Show repository"
diff --git a/app/views/workflow_repository/show_list.html.haml b/app/views/workflow_repository/show_list.html.haml
new file mode 100644
index 000000000000..d0483341947d
--- /dev/null
+++ b/app/views/workflow_repository/show_list.html.haml
@@ -0,0 +1 @@
+= "Show repository list"
diff --git a/config/routes.rb b/config/routes.rb
index 6122aa82b418..c9733b8a7f0a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -314,6 +314,7 @@
atomic_st_edit
automate_button_field_changed
playbook_options_field_changed
+ embededded_workflows_modal
explorer
group_create
group_reorder_field_changed
@@ -3182,6 +3183,27 @@
snap_post
},
+ :workflow => {
+ :get => %w(
+ show_list
+ show
+ ),
+ },
+
+ :workflow_credential => {
+ :get => %w(
+ show_list
+ show
+ ),
+ },
+
+ :workflow_repository => {
+ :get => %w(
+ show_list
+ show
+ ),
+ },
+
:firmware_registry => {
:get => %w[
download_data
diff --git a/package.json b/package.json
index d115b67cb9a0..8f1cad512b50 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
"@manageiq/ui-components": "1.4.4",
"@novnc/novnc": "~1.2.0",
"@pf3/select": "~1.12.6",
+ "@tshepomgaga/aws-sfn-graph": "0.0.6",
"actioncable": "^5.2.4-2",
"angular": "~1.6.6",
"angular-animate": "~1.6.6",
diff --git a/spec/config/routes.pending.yml b/spec/config/routes.pending.yml
index a7901fdd1233..07a1461f749d 100644
--- a/spec/config/routes.pending.yml
+++ b/spec/config/routes.pending.yml
@@ -1460,3 +1460,12 @@ VmOrTemplateController:
- x_show
VolumeMappingController:
- index
+WorkflowController:
+- report_data
+- index
+WorkflowCredentialController:
+- report_data
+- index
+WorkflowRepositoryController:
+- report_data
+- index
diff --git a/yarn.lock b/yarn.lock
index 319ea3123c43..78e1ab7ae2d3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2057,6 +2057,13 @@ __metadata:
languageName: node
linkType: hard
+"@tshepomgaga/aws-sfn-graph@npm:0.0.6":
+ version: 0.0.6
+ resolution: "@tshepomgaga/aws-sfn-graph@npm:0.0.6"
+ checksum: 1e8263472c2ec0579d459c04fcd9aa1e5cbc37c07dfaa594b1f1c295603db6d97741e5629b2a60da8e7ce04a1899b4cf0afe1e625ff43a27d877d1495e6df258
+ languageName: node
+ linkType: hard
+
"@types/babel__core@npm:^7.1.0, @types/babel__core@npm:^7.1.7":
version: 7.20.0
resolution: "@types/babel__core@npm:7.20.0"
@@ -11377,6 +11384,7 @@ fsevents@^1.2.7:
"@manageiq/ui-components": 1.4.4
"@novnc/novnc": ~1.2.0
"@pf3/select": ~1.12.6
+ "@tshepomgaga/aws-sfn-graph": 0.0.6
actioncable: ^5.2.4-2
angular: ~1.6.6
angular-animate: ~1.6.6