mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 18:09:57 -03:30
Merge pull request #4657 from beeankha/wf_approval_notification
[WIP] Notification Support for Workflow Approval Nodes Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
commit
505dcf9dd2
@ -489,9 +489,12 @@ class SubListAPIView(ParentMixin, ListAPIView):
|
||||
parent = self.get_parent_object()
|
||||
self.check_parent_access(parent)
|
||||
qs = self.request.user.get_queryset(self.model).distinct()
|
||||
sublist_qs = getattrd(parent, self.relationship).distinct()
|
||||
sublist_qs = self.get_sublist_queryset(parent)
|
||||
return qs & sublist_qs
|
||||
|
||||
def get_sublist_queryset(self, parent):
|
||||
return getattrd(parent, self.relationship).distinct()
|
||||
|
||||
|
||||
class DestroyAPIView(generics.DestroyAPIView):
|
||||
|
||||
|
||||
@ -1261,6 +1261,7 @@ class OrganizationSerializer(BaseSerializer):
|
||||
notification_templates_started = self.reverse('api:organization_notification_templates_started_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_success = self.reverse('api:organization_notification_templates_success_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_error = self.reverse('api:organization_notification_templates_error_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_approvals = self.reverse('api:organization_notification_templates_approvals_list', kwargs={'pk': obj.pk}),
|
||||
object_roles = self.reverse('api:organization_object_roles_list', kwargs={'pk': obj.pk}),
|
||||
access_list = self.reverse('api:organization_access_list', kwargs={'pk': obj.pk}),
|
||||
instance_groups = self.reverse('api:organization_instance_groups_list', kwargs={'pk': obj.pk}),
|
||||
@ -3335,6 +3336,7 @@ class WorkflowJobTemplateSerializer(JobTemplateMixin, LabelsListMixin, UnifiedJo
|
||||
notification_templates_started = self.reverse('api:workflow_job_template_notification_templates_started_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_success = self.reverse('api:workflow_job_template_notification_templates_success_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_error = self.reverse('api:workflow_job_template_notification_templates_error_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_approvals = self.reverse('api:workflow_job_template_notification_templates_approvals_list', kwargs={'pk': obj.pk}),
|
||||
access_list = self.reverse('api:workflow_job_template_access_list', kwargs={'pk': obj.pk}),
|
||||
object_roles = self.reverse('api:workflow_job_template_object_roles_list', kwargs={'pk': obj.pk}),
|
||||
survey_spec = self.reverse('api:workflow_job_template_survey_spec', kwargs={'pk': obj.pk}),
|
||||
@ -3490,7 +3492,7 @@ class WorkflowApprovalTemplateSerializer(UnifiedJobTemplateSerializer):
|
||||
if 'last_job' in res:
|
||||
del res['last_job']
|
||||
|
||||
res.update(dict(jobs = self.reverse('api:workflow_approval_template_jobs_list', kwargs={'pk': obj.pk}),))
|
||||
res.update(jobs = self.reverse('api:workflow_approval_template_jobs_list', kwargs={'pk': obj.pk}))
|
||||
return res
|
||||
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ from awx.api.views import (
|
||||
OrganizationNotificationTemplatesErrorList,
|
||||
OrganizationNotificationTemplatesStartedList,
|
||||
OrganizationNotificationTemplatesSuccessList,
|
||||
OrganizationNotificationTemplatesApprovalList,
|
||||
OrganizationInstanceGroupsList,
|
||||
OrganizationObjectRolesList,
|
||||
OrganizationAccessList,
|
||||
@ -43,6 +44,8 @@ urls = [
|
||||
name='organization_notification_templates_error_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', OrganizationNotificationTemplatesSuccessList.as_view(),
|
||||
name='organization_notification_templates_success_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_approvals/$', OrganizationNotificationTemplatesApprovalList.as_view(),
|
||||
name='organization_notification_templates_approvals_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/instance_groups/$', OrganizationInstanceGroupsList.as_view(), name='organization_instance_groups_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', OrganizationObjectRolesList.as_view(), name='organization_object_roles_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/access_list/$', OrganizationAccessList.as_view(), name='organization_access_list'),
|
||||
|
||||
@ -16,6 +16,7 @@ from awx.api.views import (
|
||||
WorkflowJobTemplateNotificationTemplatesErrorList,
|
||||
WorkflowJobTemplateNotificationTemplatesStartedList,
|
||||
WorkflowJobTemplateNotificationTemplatesSuccessList,
|
||||
WorkflowJobTemplateNotificationTemplatesApprovalList,
|
||||
WorkflowJobTemplateAccessList,
|
||||
WorkflowJobTemplateObjectRolesList,
|
||||
WorkflowJobTemplateLabelList,
|
||||
@ -38,6 +39,8 @@ urls = [
|
||||
name='workflow_job_template_notification_templates_error_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', WorkflowJobTemplateNotificationTemplatesSuccessList.as_view(),
|
||||
name='workflow_job_template_notification_templates_success_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_approvals/$', WorkflowJobTemplateNotificationTemplatesApprovalList.as_view(),
|
||||
name='workflow_job_template_notification_templates_approvals_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/access_list/$', WorkflowJobTemplateAccessList.as_view(), name='workflow_job_template_access_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', WorkflowJobTemplateObjectRolesList.as_view(), name='workflow_job_template_object_roles_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/labels/$', WorkflowJobTemplateLabelList.as_view(), name='workflow_job_template_label_list'),
|
||||
|
||||
@ -119,6 +119,7 @@ from awx.api.views.organization import ( # noqa
|
||||
OrganizationNotificationTemplatesErrorList,
|
||||
OrganizationNotificationTemplatesStartedList,
|
||||
OrganizationNotificationTemplatesSuccessList,
|
||||
OrganizationNotificationTemplatesApprovalList,
|
||||
OrganizationInstanceGroupsList,
|
||||
OrganizationAccessList,
|
||||
OrganizationObjectRolesList,
|
||||
@ -3288,6 +3289,11 @@ class WorkflowJobTemplateNotificationTemplatesSuccessList(WorkflowJobTemplateNot
|
||||
relationship = 'notification_templates_success'
|
||||
|
||||
|
||||
class WorkflowJobTemplateNotificationTemplatesApprovalList(WorkflowJobTemplateNotificationTemplatesAnyList):
|
||||
|
||||
relationship = 'notification_templates_approvals'
|
||||
|
||||
|
||||
class WorkflowJobTemplateAccessList(ResourceAccessList):
|
||||
|
||||
model = models.User # needs to be User for AccessLists's
|
||||
@ -3373,6 +3379,11 @@ class WorkflowJobNotificationsList(SubListAPIView):
|
||||
relationship = 'notifications'
|
||||
search_fields = ('subject', 'notification_type', 'body',)
|
||||
|
||||
def get_sublist_queryset(self, parent):
|
||||
return self.model.objects.filter(Q(unifiedjob_notifications=parent) |
|
||||
Q(unifiedjob_notifications__unified_job_node__workflow_job=parent,
|
||||
unifiedjob_notifications__workflowapproval__isnull=False)).distinct()
|
||||
|
||||
|
||||
class WorkflowJobActivityStreamList(SubListAPIView):
|
||||
|
||||
|
||||
@ -195,6 +195,11 @@ class OrganizationNotificationTemplatesSuccessList(OrganizationNotificationTempl
|
||||
relationship = 'notification_templates_success'
|
||||
|
||||
|
||||
class OrganizationNotificationTemplatesApprovalList(OrganizationNotificationTemplatesAnyList):
|
||||
|
||||
relationship = 'notification_templates_approvals'
|
||||
|
||||
|
||||
class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
|
||||
|
||||
model = InstanceGroup
|
||||
|
||||
28
awx/main/migrations/0091_v360_approval_node_notifications.py
Normal file
28
awx/main/migrations/0091_v360_approval_node_notifications.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-11 13:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0090_v360_WFJT_prompts'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='organization',
|
||||
name='notification_templates_approvals',
|
||||
field=models.ManyToManyField(blank=True, related_name='organization_notification_templates_for_approvals', to='main.NotificationTemplate'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowjobtemplate',
|
||||
name='notification_templates_approvals',
|
||||
field=models.ManyToManyField(blank=True, related_name='workflowjobtemplate_notification_templates_for_approvals', to='main.NotificationTemplate'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='workflowjobnode',
|
||||
name='do_not_run',
|
||||
field=models.BooleanField(default=False, help_text='Indicates that a job will not be created when True. Workflow runtime semantics will mark this True if the node is in a path that will decidedly not be ran. A value of False means the node may not run.'),
|
||||
),
|
||||
]
|
||||
@ -51,6 +51,11 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
|
||||
default=0,
|
||||
help_text=_('Maximum number of hosts allowed to be managed by this organization.'),
|
||||
)
|
||||
notification_templates_approvals = models.ManyToManyField(
|
||||
"NotificationTemplate",
|
||||
blank=True,
|
||||
related_name='%(class)s_notification_templates_for_approvals'
|
||||
)
|
||||
|
||||
admin_role = ImplicitRoleField(
|
||||
parent_role='singleton:' + ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
||||
|
||||
@ -3,9 +3,11 @@
|
||||
|
||||
# Python
|
||||
import logging
|
||||
from copy import copy
|
||||
from urllib.parse import urljoin
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.db import connection, models
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
@ -38,9 +40,6 @@ from awx.main.fields import JSONField
|
||||
from awx.main.utils import schedule_task_manager
|
||||
|
||||
|
||||
from copy import copy
|
||||
from urllib.parse import urljoin
|
||||
|
||||
__all__ = ['WorkflowJobTemplate', 'WorkflowJob', 'WorkflowJobOptions', 'WorkflowJobNode',
|
||||
'WorkflowJobTemplateNode', 'WorkflowApprovalTemplate', 'WorkflowApproval']
|
||||
|
||||
@ -196,7 +195,7 @@ class WorkflowJobNode(WorkflowNodeBase):
|
||||
)
|
||||
do_not_run = models.BooleanField(
|
||||
default=False,
|
||||
help_text=_("Indidcates that a job will not be created when True. Workflow runtime "
|
||||
help_text=_("Indicates that a job will not be created when True. Workflow runtime "
|
||||
"semantics will mark this True if the node is in a path that will "
|
||||
"decidedly not be ran. A value of False means the node may not run."),
|
||||
)
|
||||
@ -388,6 +387,12 @@ class WorkflowJobTemplate(UnifiedJobTemplate, WorkflowJobOptions, SurveyJobTempl
|
||||
blank=True,
|
||||
default=False,
|
||||
)
|
||||
notification_templates_approvals = models.ManyToManyField(
|
||||
"NotificationTemplate",
|
||||
blank=True,
|
||||
related_name='%(class)s_notification_templates_for_approvals'
|
||||
)
|
||||
|
||||
admin_role = ImplicitRoleField(parent_role=[
|
||||
'singleton:' + ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
||||
'organization.workflow_admin_role'
|
||||
@ -441,9 +446,16 @@ class WorkflowJobTemplate(UnifiedJobTemplate, WorkflowJobOptions, SurveyJobTempl
|
||||
.filter(unifiedjobtemplate_notification_templates_for_started__in=[self]))
|
||||
success_notification_templates = list(base_notification_templates
|
||||
.filter(unifiedjobtemplate_notification_templates_for_success__in=[self]))
|
||||
approval_notification_templates = list(base_notification_templates
|
||||
.filter(workflowjobtemplate_notification_templates_for_approvals__in=[self]))
|
||||
# Get Organization NotificationTemplates
|
||||
if self.organization is not None:
|
||||
approval_notification_templates = set(approval_notification_templates + list(base_notification_templates.filter(
|
||||
organization_notification_templates_for_approvals=self.organization)))
|
||||
return dict(error=list(error_notification_templates),
|
||||
started=list(started_notification_templates),
|
||||
success=list(success_notification_templates))
|
||||
success=list(success_notification_templates),
|
||||
approvals=list(approval_notification_templates))
|
||||
|
||||
def create_unified_job(self, **kwargs):
|
||||
workflow_job = super(WorkflowJobTemplate, self).create_unified_job(**kwargs)
|
||||
@ -649,7 +661,7 @@ class WorkflowApprovalTemplate(UnifiedJobTemplate):
|
||||
return self.workflowjobtemplatenodes.first().workflow_job_template
|
||||
|
||||
|
||||
class WorkflowApproval(UnifiedJob):
|
||||
class WorkflowApproval(UnifiedJob, JobNotificationMixin):
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
|
||||
@ -689,6 +701,7 @@ class WorkflowApproval(UnifiedJob):
|
||||
def approve(self, request=None):
|
||||
self.status = 'successful'
|
||||
self.save()
|
||||
self.send_approval_notification('approved')
|
||||
self.websocket_emit_status(self.status)
|
||||
schedule_task_manager()
|
||||
return reverse('api:workflow_approval_approve', kwargs={'pk': self.pk}, request=request)
|
||||
@ -696,10 +709,53 @@ class WorkflowApproval(UnifiedJob):
|
||||
def deny(self, request=None):
|
||||
self.status = 'failed'
|
||||
self.save()
|
||||
self.send_approval_notification('denied')
|
||||
self.websocket_emit_status(self.status)
|
||||
schedule_task_manager()
|
||||
return reverse('api:workflow_approval_deny', kwargs={'pk': self.pk}, request=request)
|
||||
|
||||
def signal_start(self, **kwargs):
|
||||
can_start = super(WorkflowApproval, self).signal_start(**kwargs)
|
||||
self.send_approval_notification('running')
|
||||
return can_start
|
||||
|
||||
def send_approval_notification(self, approval_status):
|
||||
from awx.main.tasks import send_notifications # avoid circular import
|
||||
if self.workflow_job_template is None:
|
||||
return
|
||||
for nt in self.workflow_job_template.notification_templates["approvals"]:
|
||||
try:
|
||||
(notification_subject, notification_body) = self.build_approval_notification_message(nt, approval_status)
|
||||
except Exception:
|
||||
raise NotImplementedError("build_approval_notification_message() does not exist")
|
||||
|
||||
# Use kwargs to force late-binding
|
||||
# https://stackoverflow.com/a/3431699/10669572
|
||||
def send_it(local_nt=nt, local_subject=notification_subject, local_body=notification_body):
|
||||
def _func():
|
||||
send_notifications.delay([local_nt.generate_notification(local_subject, local_body).id],
|
||||
job_id=self.id)
|
||||
return _func
|
||||
connection.on_commit(send_it())
|
||||
|
||||
def build_approval_notification_message(self, nt, approval_status):
|
||||
subject = []
|
||||
workflow_url = urljoin(settings.TOWER_URL_BASE, '/#/workflows/{}'.format(self.workflow_job.id))
|
||||
subject.append(('The approval node "{}"').format(self.workflow_approval_template.name))
|
||||
if approval_status == 'running':
|
||||
subject.append(('needs review. This node can be viewed at: {}').format(workflow_url))
|
||||
if approval_status == 'approved':
|
||||
subject.append(('was approved. {}').format(workflow_url))
|
||||
if approval_status == 'timed_out':
|
||||
subject.append(('has timed out. {}').format(workflow_url))
|
||||
elif approval_status == 'denied':
|
||||
subject.append(('was denied. {}').format(workflow_url))
|
||||
subject = " ".join(subject)
|
||||
body = self.notification_data()
|
||||
body['body'] = subject
|
||||
|
||||
return subject, body
|
||||
|
||||
@property
|
||||
def workflow_job_template(self):
|
||||
try:
|
||||
|
||||
@ -533,6 +533,7 @@ class TaskManager():
|
||||
logger.warn(timeout_message)
|
||||
task.timed_out = True
|
||||
task.status = 'failed'
|
||||
task.send_approval_notification('timed_out')
|
||||
task.websocket_emit_status(task.status)
|
||||
task.job_explanation = timeout_message
|
||||
task.save(update_fields=['status', 'job_explanation', 'timed_out'])
|
||||
|
||||
@ -323,7 +323,7 @@ def send_notifications(notification_list, job_id=None):
|
||||
notification.status = "successful"
|
||||
notification.notifications_sent = sent
|
||||
except Exception as e:
|
||||
logger.error("Send Notification Failed {}".format(e))
|
||||
logger.exception("Send Notification Failed {}".format(e))
|
||||
notification.status = "failed"
|
||||
notification.error = smart_str(e)
|
||||
update_fields.append('error')
|
||||
|
||||
@ -135,3 +135,45 @@ def test_search_on_notification_configuration_is_prevented(get, admin):
|
||||
response = get(url, {'notification_configuration__regex': 'ABCDEF'}, admin)
|
||||
assert response.status_code == 403
|
||||
assert response.data == {"detail": "Filtering on notification_configuration is not allowed."}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_get_wfjt_approval_notification(get, admin, workflow_job_template):
|
||||
url = reverse('api:workflow_job_template_notification_templates_approvals_list', kwargs={'pk': workflow_job_template.pk})
|
||||
response = get(url, admin)
|
||||
assert response.status_code == 200
|
||||
assert len(response.data['results']) == 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_post_wfjt_approval_notification(get, post, admin, notification_template, workflow_job_template):
|
||||
url = reverse('api:workflow_job_template_notification_templates_approvals_list', kwargs={'pk': workflow_job_template.pk})
|
||||
response = post(url,
|
||||
dict(id=notification_template.id,
|
||||
associate=True),
|
||||
admin)
|
||||
assert response.status_code == 204
|
||||
response = get(url, admin)
|
||||
assert response.status_code == 200
|
||||
assert len(response.data['results']) == 1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_get_org_approval_notification(get, admin, organization):
|
||||
url = reverse('api:organization_notification_templates_approvals_list', kwargs={'pk': organization.pk})
|
||||
response = get(url, admin)
|
||||
assert response.status_code == 200
|
||||
assert len(response.data['results']) == 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_post_org_approval_notification(get, post, admin, notification_template, organization):
|
||||
url = reverse('api:organization_notification_templates_approvals_list', kwargs={'pk': organization.pk})
|
||||
response = post(url,
|
||||
dict(id=notification_template.id,
|
||||
associate=True),
|
||||
admin)
|
||||
assert response.status_code == 204
|
||||
response = get(url, admin)
|
||||
assert response.status_code == 200
|
||||
assert len(response.data['results']) == 1
|
||||
|
||||
@ -25,15 +25,29 @@ export default ['i18n', 'templateUrl', function(i18n, templateUrl){
|
||||
name: {
|
||||
key: true,
|
||||
label: i18n._('Name'),
|
||||
columnClass: 'col-md-4 col-sm-9 col-xs-9',
|
||||
linkTo: '/#/notification_templates/{{notification.id}}'
|
||||
columnClass: 'col-sm-9 col-xs-9',
|
||||
linkTo: '/#/notification_templates/{{notification.id}}',
|
||||
columnNgClass: "{'col-lg-4 col-md-2': showApprovalColumn, 'col-lg-5 col-md-3': !showApprovalColumn}"
|
||||
},
|
||||
notification_type: {
|
||||
label: i18n._('Type'),
|
||||
searchType: 'select',
|
||||
searchOptions: [],
|
||||
excludeModal: true,
|
||||
columnClass: 'd-none d-sm-flex col-md-4 col-sm-3'
|
||||
columnClass: 'd-none d-sm-flex col-lg-4 col-md-2 col-sm-3',
|
||||
},
|
||||
notification_templates_approvals: {
|
||||
label: i18n._('Approval'),
|
||||
columnClass: 'd-none d-md-flex justify-content-start col-lg-1 col-md-2',
|
||||
flag: 'notification_templates_approvals',
|
||||
type: "toggle",
|
||||
ngClick: "toggleNotification($event, notification.id, 'notification_templates_approvals')",
|
||||
ngDisabled: "!sufficientRoleForNotifToggle",
|
||||
awToolTip: "{{ schedule.play_tip }}",
|
||||
dataTipWatch: "schedule.play_tip",
|
||||
dataPlacement: "right",
|
||||
nosort: true,
|
||||
ngIf: "showApprovalColumn"
|
||||
},
|
||||
notification_templates_started: {
|
||||
label: i18n._("Start"),
|
||||
@ -45,7 +59,7 @@ export default ['i18n', 'templateUrl', function(i18n, templateUrl){
|
||||
dataTipWatch: "schedule.play_tip",
|
||||
dataPlacement: "right",
|
||||
nosort: true,
|
||||
columnClass: 'd-none d-md-flex justify-content-start col-md-1'
|
||||
columnClass: 'd-none d-md-flex justify-content-start col-lg-1 col-md-2'
|
||||
},
|
||||
notification_templates_success: {
|
||||
label: i18n._('Success'),
|
||||
@ -57,11 +71,11 @@ export default ['i18n', 'templateUrl', function(i18n, templateUrl){
|
||||
dataTipWatch: "schedule.play_tip",
|
||||
dataPlacement: "right",
|
||||
nosort: true,
|
||||
columnClass: 'd-none d-md-flex justify-content-start col-md-1'
|
||||
columnClass: 'd-none d-md-flex justify-content-start col-lg-1 col-md-2'
|
||||
},
|
||||
notification_templates_error: {
|
||||
label: i18n._('Failure'),
|
||||
columnClass: 'd-none d-md-flex justify-content-start col-md-1 NotifierList-lastColumn',
|
||||
columnClass: 'd-none d-md-flex justify-content-start col-lg-1 col-md-2 NotifierList-lastColumn',
|
||||
flag: 'notification_templates_error',
|
||||
type: "toggle",
|
||||
ngClick: "toggleNotification($event, notification.id, 'notification_templates_error')",
|
||||
|
||||
@ -22,6 +22,10 @@ export default ['Wait', 'GetBasePath', 'ProcessErrors', 'Rest', 'GetChoices',
|
||||
url = params.url,
|
||||
id = params.id;
|
||||
|
||||
if ($state.includes('templates.editWorkflowJobTemplate') || $state.includes('organizations.edit')) {
|
||||
scope.showApprovalColumn = true;
|
||||
}
|
||||
|
||||
scope.addNotificationTemplate = function() {
|
||||
var org_id;
|
||||
if($stateParams.hasOwnProperty('project_id')){
|
||||
@ -51,6 +55,10 @@ export default ['Wait', 'GetBasePath', 'ProcessErrors', 'Rest', 'GetChoices',
|
||||
scope.relatednotificationsRemove = scope.$on('relatednotifications', function () {
|
||||
var columns = ['/notification_templates_started/', '/notification_templates_success/', '/notification_templates_error/'];
|
||||
|
||||
if ($state.includes('templates.editWorkflowJobTemplate') || $state.includes('organizations.edit')) {
|
||||
columns.push('/notification_templates_approvals');
|
||||
}
|
||||
|
||||
GetChoices({
|
||||
scope: scope,
|
||||
url: GetBasePath('notifications'),
|
||||
@ -64,9 +72,17 @@ export default ['Wait', 'GetBasePath', 'ProcessErrors', 'Rest', 'GetChoices',
|
||||
Rest.setUrl(notifier_url);
|
||||
Rest.get()
|
||||
.then(function(response) {
|
||||
let checkForSuccessOrError = response.config.url.indexOf('success') > 0 ? "notification_templates_success" : "notification_templates_error";
|
||||
let type;
|
||||
|
||||
let type = response.config.url.indexOf('started') > 0 ? "notification_templates_started" : checkForSuccessOrError;
|
||||
if (response.config.url.indexOf('started') > 0) {
|
||||
type = "notification_templates_started";
|
||||
} else if (response.config.url.indexOf('success') > 0) {
|
||||
type = "notification_templates_success";
|
||||
} else if (response.config.url.indexOf('error') > 0) {
|
||||
type = "notification_templates_error";
|
||||
} else if (response.config.url.indexOf('approvals') > 0) {
|
||||
type = "notification_templates_approvals";
|
||||
}
|
||||
|
||||
if (response.data.results) {
|
||||
_.forEach(response.data.results, function(result){
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div id="{{columnIterator}}-{{columnField}}-header" class="List-tableHeader list-header {{columnCustomClass}}" ng-click="columnNoSort !== 'true' && toggleColumnOrderBy()" ng-class="{'list-header-noSort' : columnNoSort === 'true'}" >
|
||||
<div id="{{columnIterator}}-{{columnField}}-header" class="List-tableHeader list-header {{columnCustomClass}}" ng-click="columnNoSort !== 'true' && toggleColumnOrderBy()" >
|
||||
{{columnLabel | translate}}
|
||||
<i ng-if="columnNoSort !== 'true'" class="fa columnSortIcon" ng-class="orderByIcon()">
|
||||
</div>
|
||||
|
||||
@ -527,8 +527,9 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
||||
} else if (field.type === 'template') {
|
||||
html = Template(field);
|
||||
} else if (field.type === 'toggle') {
|
||||
const ngIf = field.ngIf ? `ng-if="${field.ngIf}"` : '';
|
||||
html += `
|
||||
<div class="atSwitch-listTableCell ${field}-column ${field['class']} ${field.columnClass}">
|
||||
<div class="atSwitch-listTableCell ${field['class']} ${field.columnClass}" ${ngIf}>
|
||||
<at-switch on-toggle="${field.ngClick}" switch-on="${"flag" in field} ? ${list.iterator}.${field.flag} : ${list.iterator}.enabled" switch-disabled="${"ngDisabled" in field} ? ${field.ngDisabled} : false" tooltip-string="${field.awToolTip}" tooltip-placement="${field.dataPlacement ? field.dataPlacement : 'right'}" tooltip-watch="${field.dataTipWatch}"></at-switch>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -546,7 +546,9 @@ export default ['$compile', 'Attr', 'Icon',
|
||||
for (fld in list.fields) {
|
||||
if (options.mode !== 'lookup' || (options.mode === 'lookup' && (fld === 'name' || _.has(list.fields[fld], 'includeModal')))){
|
||||
let customClass = list.fields[fld].columnClass || '';
|
||||
const ngIf = list.fields[fld].ngIf ? `ng-if="${list.fields[fld].ngIf}"` : '';
|
||||
html += `<div
|
||||
${ngIf}
|
||||
base-path="${list.basePath || list.name}"
|
||||
collection="${list.name}"
|
||||
dataset="${list.iterator}_dataset"
|
||||
@ -556,6 +558,7 @@ export default ['$compile', 'Attr', 'Icon',
|
||||
column-no-sort="${list.fields[fld].nosort}"
|
||||
column-label="${list.fields[fld].label}"
|
||||
column-custom-class="${customClass}"
|
||||
ng-class="${list.fields[fld].columnNgClass || `{'list-header-noSort': ${list.fields[fld].nosort ? true : false}}`}"
|
||||
query-set="${list.iterator}_queryset">
|
||||
</div>`;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user