mirror of
https://github.com/ansible/awx.git
synced 2026-03-07 19:51:08 -03:30
Merge branch 'devel' into 3201-labels-pagination
This commit is contained in:
1
Makefile
1
Makefile
@@ -353,6 +353,7 @@ init:
|
|||||||
if [ "$(EXTRA_GROUP_QUEUES)" == "thepentagon" ]; then \
|
if [ "$(EXTRA_GROUP_QUEUES)" == "thepentagon" ]; then \
|
||||||
tower-manage register_instance --hostname=isolated; \
|
tower-manage register_instance --hostname=isolated; \
|
||||||
tower-manage register_queue --queuename='thepentagon' --hostnames=isolated --controller=tower; \
|
tower-manage register_queue --queuename='thepentagon' --hostnames=isolated --controller=tower; \
|
||||||
|
tower-manage generate_isolated_key | ssh -o "StrictHostKeyChecking no" root@isolated 'cat > /root/.ssh/authorized_keys'; \
|
||||||
elif [ "$(EXTRA_GROUP_QUEUES)" != "" ]; then \
|
elif [ "$(EXTRA_GROUP_QUEUES)" != "" ]; then \
|
||||||
tower-manage register_queue --queuename=$(EXTRA_GROUP_QUEUES) --hostnames=$(COMPOSE_HOST); \
|
tower-manage register_queue --queuename=$(EXTRA_GROUP_QUEUES) --hostnames=$(COMPOSE_HOST); \
|
||||||
fi;
|
fi;
|
||||||
|
|||||||
@@ -155,6 +155,47 @@ register(
|
|||||||
category_slug='jobs',
|
category_slug='jobs',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register(
|
||||||
|
'AWX_ISOLATED_CHECK_INTERVAL',
|
||||||
|
field_class=fields.IntegerField,
|
||||||
|
label=_('Isolated status check interval'),
|
||||||
|
help_text=_('The number of seconds to sleep between status checks for jobs running on isolated instances.'), # noqa
|
||||||
|
category=_('Jobs'),
|
||||||
|
category_slug='jobs',
|
||||||
|
)
|
||||||
|
|
||||||
|
register(
|
||||||
|
'AWX_ISOLATED_LAUNCH_TIMEOUT',
|
||||||
|
field_class=fields.IntegerField,
|
||||||
|
label=_('Isolated launch timeout'),
|
||||||
|
help_text=_('The timeout (in seconds) for launching jobs on isolated instances. This includes the time needed to copy source control files (playbooks) to the isolated instance.'),
|
||||||
|
category=_('Jobs'),
|
||||||
|
category_slug='jobs',
|
||||||
|
)
|
||||||
|
|
||||||
|
register(
|
||||||
|
'AWX_ISOLATED_PRIVATE_KEY',
|
||||||
|
field_class=fields.CharField,
|
||||||
|
default='',
|
||||||
|
allow_blank=True,
|
||||||
|
encrypted=True,
|
||||||
|
label=_('The RSA private key for SSH traffic to isolated instances'),
|
||||||
|
help_text=_('The RSA private key for SSH traffic to isolated instances'), # noqa
|
||||||
|
category=_('Jobs'),
|
||||||
|
category_slug='jobs',
|
||||||
|
)
|
||||||
|
|
||||||
|
register(
|
||||||
|
'AWX_ISOLATED_PUBLIC_KEY',
|
||||||
|
field_class=fields.CharField,
|
||||||
|
default='',
|
||||||
|
allow_blank=True,
|
||||||
|
label=_('The RSA public key for SSH traffic to isolated instances'),
|
||||||
|
help_text=_('The RSA public key for SSH traffic to isolated instances'), # noqa
|
||||||
|
category=_('Jobs'),
|
||||||
|
category_slug='jobs',
|
||||||
|
)
|
||||||
|
|
||||||
register(
|
register(
|
||||||
'STDOUT_MAX_BYTES_DISPLAY',
|
'STDOUT_MAX_BYTES_DISPLAY',
|
||||||
field_class=fields.IntegerField,
|
field_class=fields.IntegerField,
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import StringIO
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import shutil
|
||||||
import stat
|
import stat
|
||||||
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -141,7 +143,7 @@ class IsolatedManager(object):
|
|||||||
args.append('-%s' % ('v' * min(5, self.instance.verbosity)))
|
args.append('-%s' % ('v' * min(5, self.instance.verbosity)))
|
||||||
buff = StringIO.StringIO()
|
buff = StringIO.StringIO()
|
||||||
logger.debug('Starting job on isolated host with `run_isolated.yml` playbook.')
|
logger.debug('Starting job on isolated host with `run_isolated.yml` playbook.')
|
||||||
status, rc = run.run_pexpect(
|
status, rc = IsolatedManager.run_pexpect(
|
||||||
args, self.awx_playbook_path(), self.env, buff,
|
args, self.awx_playbook_path(), self.env, buff,
|
||||||
expect_passwords={
|
expect_passwords={
|
||||||
re.compile(r'Secret:\s*?$', re.M): base64.b64encode(json.dumps(secrets))
|
re.compile(r'Secret:\s*?$', re.M): base64.b64encode(json.dumps(secrets))
|
||||||
@@ -154,6 +156,22 @@ class IsolatedManager(object):
|
|||||||
self.stdout_handle.write(buff.getvalue())
|
self.stdout_handle.write(buff.getvalue())
|
||||||
return status, rc
|
return status, rc
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run_pexpect(cls, pexpect_args, *args, **kw):
|
||||||
|
isolated_ssh_path = None
|
||||||
|
try:
|
||||||
|
if getattr(settings, 'AWX_ISOLATED_PRIVATE_KEY', None):
|
||||||
|
isolated_ssh_path = tempfile.mkdtemp(prefix='ansible_tower_isolated')
|
||||||
|
os.chmod(isolated_ssh_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
|
||||||
|
isolated_key = os.path.join(isolated_ssh_path, '.isolated')
|
||||||
|
ssh_sock = os.path.join(isolated_ssh_path, '.isolated_ssh_auth.sock')
|
||||||
|
run.open_fifo_write(isolated_key, settings.AWX_ISOLATED_PRIVATE_KEY)
|
||||||
|
pexpect_args = run.wrap_args_with_ssh_agent(pexpect_args, isolated_key, ssh_sock)
|
||||||
|
return run.run_pexpect(pexpect_args, *args, **kw)
|
||||||
|
finally:
|
||||||
|
if isolated_ssh_path:
|
||||||
|
shutil.rmtree(isolated_ssh_path)
|
||||||
|
|
||||||
def build_isolated_job_data(self):
|
def build_isolated_job_data(self):
|
||||||
'''
|
'''
|
||||||
Write the playbook and metadata into a collection of files on the local
|
Write the playbook and metadata into a collection of files on the local
|
||||||
@@ -251,7 +269,7 @@ class IsolatedManager(object):
|
|||||||
|
|
||||||
buff = cStringIO.StringIO()
|
buff = cStringIO.StringIO()
|
||||||
logger.debug('Checking job on isolated host with `check_isolated.yml` playbook.')
|
logger.debug('Checking job on isolated host with `check_isolated.yml` playbook.')
|
||||||
status, rc = run.run_pexpect(
|
status, rc = IsolatedManager.run_pexpect(
|
||||||
args, self.awx_playbook_path(), self.env, buff,
|
args, self.awx_playbook_path(), self.env, buff,
|
||||||
cancelled_callback=self.cancelled_callback,
|
cancelled_callback=self.cancelled_callback,
|
||||||
idle_timeout=remaining,
|
idle_timeout=remaining,
|
||||||
@@ -302,7 +320,7 @@ class IsolatedManager(object):
|
|||||||
json.dumps(extra_vars)]
|
json.dumps(extra_vars)]
|
||||||
logger.debug('Cleaning up job on isolated host with `clean_isolated.yml` playbook.')
|
logger.debug('Cleaning up job on isolated host with `clean_isolated.yml` playbook.')
|
||||||
buff = cStringIO.StringIO()
|
buff = cStringIO.StringIO()
|
||||||
status, rc = run.run_pexpect(
|
status, rc = IsolatedManager.run_pexpect(
|
||||||
args, self.awx_playbook_path(), self.env, buff,
|
args, self.awx_playbook_path(), self.env, buff,
|
||||||
idle_timeout=60, job_timeout=60,
|
idle_timeout=60, job_timeout=60,
|
||||||
pexpect_timeout=5
|
pexpect_timeout=5
|
||||||
@@ -333,7 +351,7 @@ class IsolatedManager(object):
|
|||||||
env['ANSIBLE_STDOUT_CALLBACK'] = 'json'
|
env['ANSIBLE_STDOUT_CALLBACK'] = 'json'
|
||||||
|
|
||||||
buff = cStringIO.StringIO()
|
buff = cStringIO.StringIO()
|
||||||
status, rc = run.run_pexpect(
|
status, rc = IsolatedManager.run_pexpect(
|
||||||
args, cls.awx_playbook_path(), env, buff,
|
args, cls.awx_playbook_path(), env, buff,
|
||||||
idle_timeout=60, job_timeout=60,
|
idle_timeout=60, job_timeout=60,
|
||||||
pexpect_timeout=5
|
pexpect_timeout=5
|
||||||
@@ -357,7 +375,7 @@ class IsolatedManager(object):
|
|||||||
continue
|
continue
|
||||||
if 'capacity' in task_result:
|
if 'capacity' in task_result:
|
||||||
instance.capacity = int(task_result['capacity'])
|
instance.capacity = int(task_result['capacity'])
|
||||||
instance.save(update_fields=['capacity'])
|
instance.save(update_fields=['capacity', 'modified'])
|
||||||
else:
|
else:
|
||||||
logger.warning('Could not update capacity of {}, msg={}'.format(
|
logger.warning('Could not update capacity of {}, msg={}'.format(
|
||||||
instance.hostname, task_result.get('msg', 'unknown failure')))
|
instance.hostname, task_result.get('msg', 'unknown failure')))
|
||||||
|
|||||||
45
awx/main/management/commands/generate_isolated_key.py
Normal file
45
awx/main/management/commands/generate_isolated_key.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
|
# All Rights Reserved
|
||||||
|
import datetime
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
from awx.conf.models import Setting
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
"""Generate and store a randomized RSA key for SSH traffic to isolated instances"""
|
||||||
|
help = 'Generates and stores a randomized RSA key for SSH traffic to isolated instances'
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
if getattr(settings, 'AWX_ISOLATED_PRIVATE_KEY', False):
|
||||||
|
print settings.AWX_ISOLATED_PUBLIC_KEY
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
key = rsa.generate_private_key(
|
||||||
|
public_exponent=65537,
|
||||||
|
key_size=4096,
|
||||||
|
backend=default_backend()
|
||||||
|
)
|
||||||
|
Setting.objects.create(
|
||||||
|
key='AWX_ISOLATED_PRIVATE_KEY',
|
||||||
|
value=key.private_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||||
|
encryption_algorithm=serialization.NoEncryption()
|
||||||
|
)
|
||||||
|
).save()
|
||||||
|
pemfile = Setting.objects.create(
|
||||||
|
key='AWX_ISOLATED_PUBLIC_KEY',
|
||||||
|
value=key.public_key().public_bytes(
|
||||||
|
encoding=serialization.Encoding.OpenSSH,
|
||||||
|
format=serialization.PublicFormat.OpenSSH
|
||||||
|
) + " generated-by-awx@%s" % datetime.datetime.utcnow().isoformat()
|
||||||
|
)
|
||||||
|
pemfile.save()
|
||||||
|
print pemfile.value
|
||||||
@@ -609,7 +609,8 @@ AWX_ISOLATED_CHECK_INTERVAL = 30
|
|||||||
|
|
||||||
# The timeout (in seconds) for launching jobs on isolated nodes
|
# The timeout (in seconds) for launching jobs on isolated nodes
|
||||||
AWX_ISOLATED_LAUNCH_TIMEOUT = 600
|
AWX_ISOLATED_LAUNCH_TIMEOUT = 600
|
||||||
# The time between the background isolated heartbeat status check
|
|
||||||
|
# The time (in seconds) between the periodic isolated heartbeat status check
|
||||||
AWX_ISOLATED_PERIODIC_CHECK = 600
|
AWX_ISOLATED_PERIODIC_CHECK = 600
|
||||||
|
|
||||||
# Enable Pendo on the UI, possible values are 'off', 'anonymous', and 'detailed'
|
# Enable Pendo on the UI, possible values are 'off', 'anonymous', and 'detailed'
|
||||||
|
|||||||
@@ -7,8 +7,11 @@ from django.conf import settings
|
|||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
# Django REST Framework
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
# Tower
|
# Tower
|
||||||
from awx.conf import register
|
from awx.conf import register, register_validate
|
||||||
from awx.sso import fields
|
from awx.sso import fields
|
||||||
from awx.main.validators import validate_private_key, validate_certificate
|
from awx.main.validators import validate_private_key, validate_certificate
|
||||||
from awx.sso.validators import * # noqa
|
from awx.sso.validators import * # noqa
|
||||||
@@ -1083,3 +1086,23 @@ register(
|
|||||||
placeholder=SOCIAL_AUTH_TEAM_MAP_PLACEHOLDER,
|
placeholder=SOCIAL_AUTH_TEAM_MAP_PLACEHOLDER,
|
||||||
feature_required='enterprise_auth',
|
feature_required='enterprise_auth',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def tacacs_validate(serializer, attrs):
|
||||||
|
if not serializer.instance:
|
||||||
|
return attrs
|
||||||
|
errors = []
|
||||||
|
host = serializer.instance.TACACSPLUS_HOST
|
||||||
|
if 'TACACSPLUS_HOST' in attrs:
|
||||||
|
host = attrs['TACACSPLUS_HOST']
|
||||||
|
secret = serializer.instance.TACACSPLUS_SECRET
|
||||||
|
if 'TACACSPLUS_SECRET' in attrs:
|
||||||
|
secret = attrs['TACACSPLUS_SECRET']
|
||||||
|
if bool(host) ^ bool(secret):
|
||||||
|
errors.append('TACACSPLUS_HOST and TACACSPLUS_SECRET can only be both empty or both populated.')
|
||||||
|
if errors:
|
||||||
|
raise serializers.ValidationError(_('\n'.join(errors)))
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
|
register_validate('tacacsplus', tacacs_validate)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ function AddCredentialsController (models, $state) {
|
|||||||
let me = models.me;
|
let me = models.me;
|
||||||
let credential = models.credential;
|
let credential = models.credential;
|
||||||
let credentialType = models.credentialType;
|
let credentialType = models.credentialType;
|
||||||
let organization = models.organization;
|
|
||||||
|
|
||||||
vm.panelTitle = 'NEW CREDENTIAL';
|
vm.panelTitle = 'NEW CREDENTIAL';
|
||||||
|
|
||||||
@@ -23,22 +22,18 @@ function AddCredentialsController (models, $state) {
|
|||||||
omit: ['user', 'team', 'inputs']
|
omit: ['user', 'team', 'inputs']
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.form.organization._placeholder = DEFAULT_ORGANIZATION_PLACEHOLDER;
|
vm.form.organization._resource = 'organization';
|
||||||
vm.form.organization._data = organization.get('results');
|
vm.form.organization._route = 'credentials.add.organization';
|
||||||
vm.form.organization._format = 'objects';
|
|
||||||
vm.form.organization._exp = 'org as org.name for org in state._data';
|
|
||||||
vm.form.organization._display = 'name';
|
|
||||||
vm.form.organization._key = 'id';
|
|
||||||
|
|
||||||
vm.form.credential_type._data = credentialType.get('results');
|
vm.form.credential_type._resource = 'credential_type';
|
||||||
vm.form.credential_type._placeholder = 'SELECT A TYPE';
|
vm.form.credential_type._route = 'credentials.add.credentialType';
|
||||||
vm.form.credential_type._format = 'grouped-object';
|
|
||||||
vm.form.credential_type._display = 'name';
|
|
||||||
vm.form.credential_type._key = 'id';
|
|
||||||
vm.form.credential_type._exp = 'type as type.name group by type.kind for type in state._data';
|
|
||||||
|
|
||||||
vm.form.inputs = {
|
vm.form.inputs = {
|
||||||
_get: credentialType.mergeInputProperties,
|
_get: id => {
|
||||||
|
let type = credentialType.getById(id);
|
||||||
|
|
||||||
|
return credentialType.mergeInputProperties(type);
|
||||||
|
},
|
||||||
_source: vm.form.credential_type,
|
_source: vm.form.credential_type,
|
||||||
_reference: 'vm.form.inputs',
|
_reference: 'vm.form.inputs',
|
||||||
_key: 'inputs'
|
_key: 'inputs'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<at-panel ng-if="$state.current.name === 'credentials.add' || $state.current.name === 'credentials.edit'">
|
<at-panel ng-if="!$state.current.name.includes('permissions')">
|
||||||
<at-panel-heading>{{ vm.panelTitle }}</at-panel-heading>
|
<at-panel-heading>{{ vm.panelTitle }}</at-panel-heading>
|
||||||
|
|
||||||
<at-tab-group>
|
<at-tab-group>
|
||||||
@@ -10,27 +10,26 @@
|
|||||||
<at-form state="vm.form">
|
<at-form state="vm.form">
|
||||||
<at-input-text col="4" tab="1" state="vm.form.name"></at-input-text>
|
<at-input-text col="4" tab="1" state="vm.form.name"></at-input-text>
|
||||||
<at-input-text col="4" tab="2" state="vm.form.description"></at-input-text>
|
<at-input-text col="4" tab="2" state="vm.form.description"></at-input-text>
|
||||||
<at-input-select col="4" tab="3" state="vm.form.organization"></at-input-select>
|
<at-input-lookup col="4" tab="3" state="vm.form.organization"></at-input-lookup>
|
||||||
|
|
||||||
<at-divider></at-divider>
|
<at-divider></at-divider>
|
||||||
|
|
||||||
<at-input-select col="4" tab="4" state="vm.form.credential_type"></at-input-select>
|
<at-input-lookup col="4" tab="4" state="vm.form.credential_type"></at-input-lookup>
|
||||||
|
|
||||||
<at-input-group col="4" tab="4" state="vm.form.inputs">
|
<at-input-group col="4" tab="5" state="vm.form.inputs">
|
||||||
Type Details
|
Type Details
|
||||||
</at-input-group>
|
</at-input-group>
|
||||||
|
|
||||||
<at-action-group col="12" pos="right">
|
<at-action-group col="12" pos="right">
|
||||||
<at-form-action type="cancel"></at-form-action>
|
<at-form-action type="cancel" to="credentials"></at-form-action>
|
||||||
<at-form-action type="save"></at-form-action>
|
<at-form-action type="save"></at-form-action>
|
||||||
</at-action-group>
|
</at-action-group>
|
||||||
</at-form>
|
</at-form>
|
||||||
</at-panel-body>
|
</at-panel-body>
|
||||||
</at-panel>
|
</at-panel>
|
||||||
|
|
||||||
<at-panel ng-if="$state.current.name === 'credentials.edit.permissions' ||
|
<at-panel ng-if="$state.current.name.includes('permissions')">
|
||||||
$state.current.name === 'credentials.edit.permissions.add'">
|
<at-panel-heading>CREDENTIALS PERMISSIONS</at-panel-heading>
|
||||||
<at-panel-heading>Credentials Permissions</at-panel-heading>
|
|
||||||
|
|
||||||
<at-tab-group>
|
<at-tab-group>
|
||||||
<at-tab state="vm.tab.details">Details</at-tab>
|
<at-tab state="vm.tab.details">Details</at-tab>
|
||||||
@@ -42,5 +41,5 @@
|
|||||||
</at-panel-body>
|
</at-panel-body>
|
||||||
</at-panel>
|
</at-panel>
|
||||||
|
|
||||||
<div ng-if="$state.current.name === 'credentials.edit.permissions.add'" ui-view="modal"></div>
|
<div ng-if="$state.current.name.includes('permissions.add')" ui-view="modal"></div>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ function EditCredentialsController (models, $state, $scope) {
|
|||||||
let me = models.me;
|
let me = models.me;
|
||||||
let credential = models.credential;
|
let credential = models.credential;
|
||||||
let credentialType = models.credentialType;
|
let credentialType = models.credentialType;
|
||||||
let organization = models.organization;
|
let selectedCredentialType = credentialType.getById(credential.get('credential_type'));
|
||||||
|
|
||||||
vm.tab = {
|
vm.tab = {
|
||||||
details: {
|
details: {
|
||||||
@@ -21,9 +21,9 @@ function EditCredentialsController (models, $state, $scope) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.$watch('$state.current.name', (value) => {
|
$scope.$watch('$state.current.name', (value) => {
|
||||||
if (value === 'credentials.edit') {
|
if (/credentials.edit($|\.organization$)/.test(value)) {
|
||||||
vm.tab.details._active = true;
|
vm.tab.details._active = true;
|
||||||
vm.tab.details._permissions = false;
|
vm.tab.permissions._active = false;
|
||||||
} else {
|
} else {
|
||||||
vm.tab.permissions._active = true;
|
vm.tab.permissions._active = true;
|
||||||
vm.tab.details._active = false;
|
vm.tab.details._active = false;
|
||||||
@@ -39,23 +39,19 @@ function EditCredentialsController (models, $state, $scope) {
|
|||||||
omit: ['user', 'team', 'inputs']
|
omit: ['user', 'team', 'inputs']
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.form.organization._placeholder = DEFAULT_ORGANIZATION_PLACEHOLDER;
|
vm.form.organization._resource = 'organization';
|
||||||
vm.form.organization._data = organization.get('results');
|
vm.form.organization._route = 'credentials.edit.organization';
|
||||||
vm.form.organization._format = 'objects';
|
vm.form.organization._value = credential.get('summary_fields.organization.id');
|
||||||
vm.form.organization._exp = 'org as org.name for org in state._data';
|
vm.form.organization._displayValue = credential.get('summary_fields.organization.name');
|
||||||
vm.form.organization._display = 'name';
|
|
||||||
vm.form.organization._key = 'id';
|
|
||||||
vm.form.organization._value = organization.getById(credential.get('organization'));
|
|
||||||
|
|
||||||
vm.form.credential_type._data = credentialType.get('results');
|
|
||||||
vm.form.credential_type._format = 'grouped-object';
|
|
||||||
vm.form.credential_type._display = 'name';
|
|
||||||
vm.form.credential_type._key = 'id';
|
|
||||||
vm.form.credential_type._exp = 'type as type.name group by type.kind for type in state._data';
|
|
||||||
vm.form.credential_type._value = credentialType.getById(credential.get('credential_type'));
|
|
||||||
|
|
||||||
|
vm.form.credential_type._resource = 'credential_type';
|
||||||
|
vm.form.credential_type._route = 'credentials.edit.credentialType';
|
||||||
|
vm.form.credential_type._value = selectedCredentialType.id;
|
||||||
|
vm.form.credential_type._displayValue = selectedCredentialType.name;
|
||||||
|
|
||||||
vm.form.inputs = {
|
vm.form.inputs = {
|
||||||
_get (type) {
|
_get (id) {
|
||||||
|
let type = credentialType.getById(id);
|
||||||
let inputs = credentialType.mergeInputProperties(type);
|
let inputs = credentialType.mergeInputProperties(type);
|
||||||
|
|
||||||
if (type.id === credential.get('credential_type')) {
|
if (type.id === credential.get('credential_type')) {
|
||||||
@@ -77,7 +73,7 @@ function EditCredentialsController (models, $state, $scope) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vm.form.onSaveSuccess = res => {
|
vm.form.onSaveSuccess = res => {
|
||||||
$state.go('credentials', { reload: true });
|
$state.go('credentials.edit', { credential_id: credential.get('id') }, { reload: true });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
import PermissionsList from '../../src/access/permissions-list.controller';
|
import LegacyCredentials from './legacy.credentials';
|
||||||
import CredentialForm from '../../src/credentials/credentials.form';
|
|
||||||
import CredentialList from '../../src/credentials/credentials.list';
|
|
||||||
import ListController from '../../src/credentials/list/credentials-list.controller';
|
|
||||||
import AddController from './add-credentials.controller.js';
|
import AddController from './add-credentials.controller.js';
|
||||||
import EditController from './edit-credentials.controller.js';
|
import EditController from './edit-credentials.controller.js';
|
||||||
import { N_ } from '../../src/i18n';
|
import { N_ } from '../../src/i18n';
|
||||||
|
|
||||||
function CredentialsResolve ($q, $stateParams, Me, Credential, CredentialType, Organization) {
|
function CredentialsResolve ($q, $stateParams, Me, Credential, CredentialType) {
|
||||||
let id = $stateParams.credential_id;
|
let id = $stateParams.credential_id;
|
||||||
|
|
||||||
let promises = {
|
let promises = {
|
||||||
me: new Me('get'),
|
me: new Me('get'),
|
||||||
credentialType: new CredentialType('get'),
|
credentialType: new CredentialType('get')
|
||||||
organization: new Organization('get')
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
@@ -29,46 +25,13 @@ CredentialsResolve.$inject = [
|
|||||||
'$stateParams',
|
'$stateParams',
|
||||||
'MeModel',
|
'MeModel',
|
||||||
'CredentialModel',
|
'CredentialModel',
|
||||||
'CredentialTypeModel',
|
'CredentialTypeModel'
|
||||||
'OrganizationModel'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function CredentialsConfig ($stateProvider, $stateExtenderProvider, pathServiceProvider) {
|
function CredentialsConfig ($stateExtenderProvider, legacyProvider, pathProvider) {
|
||||||
let pathService = pathServiceProvider.$get();
|
let path = pathProvider.$get();
|
||||||
let stateExtender = $stateExtenderProvider.$get();
|
let stateExtender = $stateExtenderProvider.$get();
|
||||||
|
let legacy = legacyProvider.$get();
|
||||||
stateExtender.addState({
|
|
||||||
name: 'credentials',
|
|
||||||
route: '/credentials',
|
|
||||||
ncyBreadcrumb: {
|
|
||||||
label: N_('CREDENTIALS')
|
|
||||||
},
|
|
||||||
views: {
|
|
||||||
'@': {
|
|
||||||
templateUrl: pathService.getViewPath('credentials/index')
|
|
||||||
},
|
|
||||||
'list@credentials': {
|
|
||||||
templateProvider: function(CredentialList, generateList) {
|
|
||||||
let html = generateList.build({
|
|
||||||
list: CredentialList,
|
|
||||||
mode: 'edit'
|
|
||||||
});
|
|
||||||
|
|
||||||
return html;
|
|
||||||
},
|
|
||||||
controller: ListController
|
|
||||||
}
|
|
||||||
},
|
|
||||||
searchPrefix: 'credential',
|
|
||||||
resolve: {
|
|
||||||
Dataset: ['CredentialList', 'QuerySet', '$stateParams', 'GetBasePath',
|
|
||||||
function(list, qs, $stateParams, GetBasePath) {
|
|
||||||
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
|
||||||
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
stateExtender.addState({
|
stateExtender.addState({
|
||||||
name: 'credentials.add',
|
name: 'credentials.add',
|
||||||
@@ -78,7 +41,7 @@ function CredentialsConfig ($stateProvider, $stateExtenderProvider, pathServiceP
|
|||||||
},
|
},
|
||||||
views: {
|
views: {
|
||||||
'add@credentials': {
|
'add@credentials': {
|
||||||
templateUrl: pathService.getViewPath('credentials/add-edit-credentials'),
|
templateUrl: path.getViewPath('credentials/add-edit-credentials'),
|
||||||
controller: AddController,
|
controller: AddController,
|
||||||
controllerAs: 'vm'
|
controllerAs: 'vm'
|
||||||
}
|
}
|
||||||
@@ -96,7 +59,7 @@ function CredentialsConfig ($stateProvider, $stateExtenderProvider, pathServiceP
|
|||||||
},
|
},
|
||||||
views: {
|
views: {
|
||||||
'edit@credentials': {
|
'edit@credentials': {
|
||||||
templateUrl: pathService.getViewPath('credentials/add-edit-credentials'),
|
templateUrl: path.getViewPath('credentials/add-edit-credentials'),
|
||||||
controller: EditController,
|
controller: EditController,
|
||||||
controllerAs: 'vm'
|
controllerAs: 'vm'
|
||||||
}
|
}
|
||||||
@@ -106,178 +69,24 @@ function CredentialsConfig ($stateProvider, $stateExtenderProvider, pathServiceP
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stateExtender.addState({
|
stateExtender.addState(legacy.getStateConfiguration('list'));
|
||||||
name: "credentials.edit.permissions",
|
stateExtender.addState(legacy.getStateConfiguration('edit-permissions'));
|
||||||
url: "/permissions?{permission_search:queryset}",
|
stateExtender.addState(legacy.getStateConfiguration('add-permissions'));
|
||||||
resolve: {
|
stateExtender.addState(legacy.getStateConfiguration('add-organization'));
|
||||||
ListDefinition: () => {
|
stateExtender.addState(legacy.getStateConfiguration('edit-organization'));
|
||||||
return {
|
stateExtender.addState(legacy.getStateConfiguration('add-credential-type'));
|
||||||
name: 'permissions',
|
stateExtender.addState(legacy.getStateConfiguration('edit-credential-type'));
|
||||||
disabled: '(organization === undefined ? true : false)',
|
|
||||||
// Do not transition the state if organization is undefined
|
|
||||||
ngClick: `(organization === undefined ? true : false)||$state.go('credentials.edit.permissions')`,
|
|
||||||
awToolTip: '{{permissionsTooltip}}',
|
|
||||||
dataTipWatch: 'permissionsTooltip',
|
|
||||||
awToolTipTabEnabledInEditMode: true,
|
|
||||||
dataPlacement: 'right',
|
|
||||||
basePath: 'api/v2/credentials/{{$stateParams.id}}/access_list/',
|
|
||||||
search: {
|
|
||||||
order_by: 'username'
|
|
||||||
},
|
|
||||||
type: 'collection',
|
|
||||||
title: N_('Permissions'),
|
|
||||||
iterator: 'permission',
|
|
||||||
index: false,
|
|
||||||
open: false,
|
|
||||||
actions: {
|
|
||||||
add: {
|
|
||||||
ngClick: "$state.go('.add')",
|
|
||||||
label: 'Add',
|
|
||||||
awToolTip: N_('Add a permission'),
|
|
||||||
actionClass: 'btn List-buttonSubmit',
|
|
||||||
buttonContent: '+ ' + N_('ADD'),
|
|
||||||
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fields: {
|
|
||||||
username: {
|
|
||||||
key: true,
|
|
||||||
label: N_('User'),
|
|
||||||
linkBase: 'users',
|
|
||||||
class: 'col-lg-3 col-md-3 col-sm-3 col-xs-4'
|
|
||||||
},
|
|
||||||
role: {
|
|
||||||
label: N_('Role'),
|
|
||||||
type: 'role',
|
|
||||||
nosort: true,
|
|
||||||
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
|
|
||||||
},
|
|
||||||
team_roles: {
|
|
||||||
label: N_('Team Roles'),
|
|
||||||
type: 'team_roles',
|
|
||||||
nosort: true,
|
|
||||||
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
Dataset: ['QuerySet', '$stateParams', (qs, $stateParams) => {
|
|
||||||
let id = $stateParams.credential_id;
|
|
||||||
let path = `api/v2/credentials/${id}/access_list/`;
|
|
||||||
|
|
||||||
return qs.search(path, $stateParams[`permission_search`]);
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
params: {
|
|
||||||
permission_search: {
|
|
||||||
value: {
|
|
||||||
page_size: "20",
|
|
||||||
order_by: "username"
|
|
||||||
},
|
|
||||||
dynamic:true,
|
|
||||||
squash:""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ncyBreadcrumb: {
|
|
||||||
parent: "credentials.edit",
|
|
||||||
label: "PERMISSIONS"
|
|
||||||
},
|
|
||||||
views: {
|
|
||||||
'related': {
|
|
||||||
templateProvider: function(CredentialForm, GenerateForm) {
|
|
||||||
let html = GenerateForm.buildCollection({
|
|
||||||
mode: 'edit',
|
|
||||||
related: `permissions`,
|
|
||||||
form: typeof(CredentialForm) === 'function' ?
|
|
||||||
CredentialForm() : CredentialForm
|
|
||||||
});
|
|
||||||
return html;
|
|
||||||
},
|
|
||||||
controller: 'PermissionsList'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
stateExtender.addState({
|
|
||||||
name: 'credentials.edit.permissions.add',
|
|
||||||
url: '/add-permissions',
|
|
||||||
resolve: {
|
|
||||||
usersDataset: [
|
|
||||||
'addPermissionsUsersList',
|
|
||||||
'QuerySet',
|
|
||||||
'$stateParams',
|
|
||||||
'GetBasePath',
|
|
||||||
(list, qs, $stateParams, GetBasePath) => {
|
|
||||||
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
|
||||||
return qs.search(path, $stateParams.user_search);
|
|
||||||
|
|
||||||
}
|
|
||||||
],
|
|
||||||
teamsDataset: [
|
|
||||||
'addPermissionsTeamsList',
|
|
||||||
'QuerySet',
|
|
||||||
'$stateParams',
|
|
||||||
'GetBasePath',
|
|
||||||
(list, qs, $stateParams, GetBasePath) => {
|
|
||||||
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
|
||||||
return qs.search(path, $stateParams.team_search);
|
|
||||||
}
|
|
||||||
],
|
|
||||||
resourceData: ['CredentialModel', '$stateParams', (Credential, $stateParams) => {
|
|
||||||
return new Credential('get', $stateParams.credential_id)
|
|
||||||
.then(credential => ({ data: credential.get() }));
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
params: {
|
|
||||||
user_search: {
|
|
||||||
value: {
|
|
||||||
order_by: 'username',
|
|
||||||
page_size: 5
|
|
||||||
},
|
|
||||||
dynamic: true
|
|
||||||
},
|
|
||||||
team_search: {
|
|
||||||
value: {
|
|
||||||
order_by: 'name',
|
|
||||||
page_size: 5
|
|
||||||
},
|
|
||||||
dynamic: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ncyBreadcrumb: {
|
|
||||||
skip: true
|
|
||||||
},
|
|
||||||
views: {
|
|
||||||
'modal@credentials.edit': {
|
|
||||||
template: `
|
|
||||||
<add-rbac-resource
|
|
||||||
users-dataset="$resolve.usersDataset"
|
|
||||||
teams-dataset="$resolve.teamsDataset"
|
|
||||||
selected="allSelected"
|
|
||||||
resource-data="$resolve.resourceData"
|
|
||||||
title="Add Users / Teams">
|
|
||||||
</add-rbac-resource>`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onExit: $state => {
|
|
||||||
if ($state.transition) {
|
|
||||||
$('#add-permissions-modal').modal('hide');
|
|
||||||
$('.modal-backdrop').remove();
|
|
||||||
$('body').removeClass('modal-open');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CredentialsConfig.$inject = [
|
CredentialsConfig.$inject = [
|
||||||
'$stateProvider',
|
'$stateExtenderProvider',
|
||||||
'$stateExtenderProvider',
|
'LegacyCredentialsServiceProvider',
|
||||||
'PathServiceProvider'
|
'PathServiceProvider'
|
||||||
];
|
];
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('at.features.credentials', [])
|
.module('at.features.credentials', [])
|
||||||
.config(CredentialsConfig)
|
.config(CredentialsConfig)
|
||||||
.controller('AddController', AddController)
|
.controller('AddController', AddController)
|
||||||
.controller('EditController', EditController);
|
.controller('EditController', EditController)
|
||||||
|
.service('LegacyCredentialsService', LegacyCredentials);
|
||||||
|
|||||||
348
awx/ui/client/features/credentials/legacy.credentials.js
Normal file
348
awx/ui/client/features/credentials/legacy.credentials.js
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
import PermissionsList from '../../src/access/permissions-list.controller';
|
||||||
|
import CredentialForm from '../../src/credentials/credentials.form';
|
||||||
|
import CredentialList from '../../src/credentials/credentials.list';
|
||||||
|
import OrganizationList from '../../src/organizations/organizations.list';
|
||||||
|
import ListController from '../../src/credentials/list/credentials-list.controller';
|
||||||
|
import { N_ } from '../../src/i18n';
|
||||||
|
|
||||||
|
function LegacyCredentialsService (pathService) {
|
||||||
|
this.list = {
|
||||||
|
name: 'credentials',
|
||||||
|
route: '/credentials',
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
label: N_('CREDENTIALS')
|
||||||
|
},
|
||||||
|
views: {
|
||||||
|
'@': {
|
||||||
|
templateUrl: pathService.getViewPath('credentials/index')
|
||||||
|
},
|
||||||
|
'list@credentials': {
|
||||||
|
templateProvider: function(CredentialList, generateList) {
|
||||||
|
let html = generateList.build({
|
||||||
|
list: CredentialList,
|
||||||
|
mode: 'edit'
|
||||||
|
});
|
||||||
|
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
controller: ListController
|
||||||
|
}
|
||||||
|
},
|
||||||
|
searchPrefix: 'credential',
|
||||||
|
resolve: {
|
||||||
|
Dataset: ['CredentialList', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||||
|
function(list, qs, $stateParams, GetBasePath) {
|
||||||
|
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
||||||
|
return qs.search(path, $stateParams[`${list.iterator}_search`]);
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.editPermissions = {
|
||||||
|
name: 'credentials.edit.permissions',
|
||||||
|
url: '/permissions?{permission_search:queryset}',
|
||||||
|
resolve: {
|
||||||
|
ListDefinition: () => {
|
||||||
|
return {
|
||||||
|
name: 'permissions',
|
||||||
|
disabled: 'organization === undefined',
|
||||||
|
ngClick: `organization === undefined || $state.go('credentials.edit.permissions')`,
|
||||||
|
awToolTip: '{{permissionsTooltip}}',
|
||||||
|
dataTipWatch: 'permissionsTooltip',
|
||||||
|
awToolTipTabEnabledInEditMode: true,
|
||||||
|
dataPlacement: 'right',
|
||||||
|
basePath: 'api/v2/credentials/{{$stateParams.id}}/access_list/',
|
||||||
|
search: {
|
||||||
|
order_by: 'username'
|
||||||
|
},
|
||||||
|
type: 'collection',
|
||||||
|
title: N_('Permissions'),
|
||||||
|
iterator: 'permission',
|
||||||
|
index: false,
|
||||||
|
open: false,
|
||||||
|
actions: {
|
||||||
|
add: {
|
||||||
|
ngClick: `$state.go('.add')`,
|
||||||
|
label: 'Add',
|
||||||
|
awToolTip: N_('Add a permission'),
|
||||||
|
actionClass: 'btn List-buttonSubmit',
|
||||||
|
buttonContent: '+ ' + N_('ADD'),
|
||||||
|
ngShow: '(credential_obj.summary_fields.user_capabilities.edit || canAdd)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
username: {
|
||||||
|
key: true,
|
||||||
|
label: N_('User'),
|
||||||
|
linkBase: 'users',
|
||||||
|
class: 'col-lg-3 col-md-3 col-sm-3 col-xs-4'
|
||||||
|
},
|
||||||
|
role: {
|
||||||
|
label: N_('Role'),
|
||||||
|
type: 'role',
|
||||||
|
nosort: true,
|
||||||
|
class: 'col-lg-4 col-md-4 col-sm-4 col-xs-4'
|
||||||
|
},
|
||||||
|
team_roles: {
|
||||||
|
label: N_('Team Roles'),
|
||||||
|
type: 'team_roles',
|
||||||
|
nosort: true,
|
||||||
|
class: 'col-lg-5 col-md-5 col-sm-5 col-xs-4'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
Dataset: ['QuerySet', '$stateParams', (qs, $stateParams) => {
|
||||||
|
let id = $stateParams.credential_id;
|
||||||
|
let path = `api/v2/credentials/${id}/access_list/`;
|
||||||
|
|
||||||
|
return qs.search(path, $stateParams[`permission_search`]);
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
permission_search: {
|
||||||
|
value: {
|
||||||
|
page_size: '20',
|
||||||
|
order_by: 'username'
|
||||||
|
},
|
||||||
|
dynamic:true,
|
||||||
|
squash:''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
parent: 'credentials.edit',
|
||||||
|
label: 'PERMISSIONS'
|
||||||
|
},
|
||||||
|
views: {
|
||||||
|
'related': {
|
||||||
|
templateProvider: function(CredentialForm, GenerateForm) {
|
||||||
|
let html = GenerateForm.buildCollection({
|
||||||
|
mode: 'edit',
|
||||||
|
related: `permissions`,
|
||||||
|
form: typeof(CredentialForm) === 'function' ?
|
||||||
|
CredentialForm() : CredentialForm
|
||||||
|
});
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
controller: 'PermissionsList'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addPermissions = {
|
||||||
|
name: 'credentials.edit.permissions.add',
|
||||||
|
url: '/add-permissions',
|
||||||
|
resolve: {
|
||||||
|
usersDataset: [
|
||||||
|
'addPermissionsUsersList',
|
||||||
|
'QuerySet',
|
||||||
|
'$stateParams',
|
||||||
|
'GetBasePath',
|
||||||
|
(list, qs, $stateParams, GetBasePath) => {
|
||||||
|
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
||||||
|
return qs.search(path, $stateParams.user_search);
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
teamsDataset: [
|
||||||
|
'addPermissionsTeamsList',
|
||||||
|
'QuerySet',
|
||||||
|
'$stateParams',
|
||||||
|
'GetBasePath',
|
||||||
|
(list, qs, $stateParams, GetBasePath) => {
|
||||||
|
let path = GetBasePath(list.basePath) || GetBasePath(list.name);
|
||||||
|
return qs.search(path, $stateParams.team_search);
|
||||||
|
}
|
||||||
|
],
|
||||||
|
resourceData: ['CredentialModel', '$stateParams', (Credential, $stateParams) => {
|
||||||
|
return new Credential('get', $stateParams.credential_id)
|
||||||
|
.then(credential => ({ data: credential.get() }));
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
user_search: {
|
||||||
|
value: {
|
||||||
|
order_by: 'username',
|
||||||
|
page_size: 5
|
||||||
|
},
|
||||||
|
dynamic: true
|
||||||
|
},
|
||||||
|
team_search: {
|
||||||
|
value: {
|
||||||
|
order_by: 'name',
|
||||||
|
page_size: 5
|
||||||
|
},
|
||||||
|
dynamic: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
skip: true
|
||||||
|
},
|
||||||
|
views: {
|
||||||
|
'modal@credentials.edit': {
|
||||||
|
template: `
|
||||||
|
<add-rbac-resource
|
||||||
|
users-dataset='$resolve.usersDataset'
|
||||||
|
teams-dataset='$resolve.teamsDataset'
|
||||||
|
selected='allSelected'
|
||||||
|
resource-data='$resolve.resourceData'
|
||||||
|
title='Add Users / Teams'>
|
||||||
|
</add-rbac-resource>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onExit: $state => {
|
||||||
|
if ($state.transition) {
|
||||||
|
$('#add-permissions-modal').modal('hide');
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.lookupTemplateProvider = (ListDefinition, generateList) => {
|
||||||
|
let html = generateList.build({
|
||||||
|
mode: 'lookup',
|
||||||
|
list: ListDefinition,
|
||||||
|
input_type: 'radio'
|
||||||
|
});
|
||||||
|
|
||||||
|
return `<lookup-modal>${html}</lookup-modal>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.organization = {
|
||||||
|
url: '/organization?selected',
|
||||||
|
searchPrefix: 'organization',
|
||||||
|
params: {
|
||||||
|
organization_search: {
|
||||||
|
value: {
|
||||||
|
page_size: 5,
|
||||||
|
order_by: 'name',
|
||||||
|
role_level: 'admin_role'
|
||||||
|
},
|
||||||
|
dynamic: true,
|
||||||
|
squash: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
basePath: 'organizations',
|
||||||
|
formChildState: true
|
||||||
|
},
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
skip: true
|
||||||
|
},
|
||||||
|
views: {},
|
||||||
|
resolve: {
|
||||||
|
ListDefinition: ['OrganizationList', list => {
|
||||||
|
return list;
|
||||||
|
}],
|
||||||
|
Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||||
|
(list, qs, $stateParams, GetBasePath) => {
|
||||||
|
return qs.search(
|
||||||
|
GetBasePath('organizations'),
|
||||||
|
$stateParams[`${list.iterator}_search`]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
onExit: function($state) {
|
||||||
|
if ($state.transition) {
|
||||||
|
$('#form-modal').modal('hide');
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.credentialType = {
|
||||||
|
url: '/credential_type?selected',
|
||||||
|
searchPrefix: 'credential_type',
|
||||||
|
params: {
|
||||||
|
credential_type_search: {
|
||||||
|
value: {
|
||||||
|
page_size: 5,
|
||||||
|
order_by: 'name'
|
||||||
|
},
|
||||||
|
dynamic: true,
|
||||||
|
squash: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
basePath: 'credential_types',
|
||||||
|
formChildState: true
|
||||||
|
},
|
||||||
|
ncyBreadcrumb: {
|
||||||
|
skip: true
|
||||||
|
},
|
||||||
|
views: {},
|
||||||
|
resolve: {
|
||||||
|
ListDefinition: ['CredentialTypesList', list => {
|
||||||
|
return list;
|
||||||
|
}],
|
||||||
|
Dataset: ['ListDefinition', 'QuerySet', '$stateParams', 'GetBasePath',
|
||||||
|
(list, qs, $stateParams, GetBasePath) => {
|
||||||
|
return qs.search(
|
||||||
|
GetBasePath('credential_types'),
|
||||||
|
$stateParams[`${list.iterator}_search`]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
onExit: function($state) {
|
||||||
|
if ($state.transition) {
|
||||||
|
$('#form-modal').modal('hide');
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getStateConfiguration = (name) => {
|
||||||
|
switch (name) {
|
||||||
|
case 'list':
|
||||||
|
return this.list;
|
||||||
|
case 'edit-permissions':
|
||||||
|
return this.editPermissions;
|
||||||
|
case 'add-permissions':
|
||||||
|
return this.addPermissions;
|
||||||
|
case 'add-organization':
|
||||||
|
this.organization.name = 'credentials.add.organization';
|
||||||
|
this.organization.views['organization@credentials.add'] = {
|
||||||
|
templateProvider: this.lookupTemplateProvider
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.organization;
|
||||||
|
case 'edit-organization':
|
||||||
|
this.organization.name = 'credentials.edit.organization';
|
||||||
|
this.organization.views['organization@credentials.edit'] = {
|
||||||
|
templateProvider: this.lookupTemplateProvider
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.organization;
|
||||||
|
case 'add-credential-type':
|
||||||
|
this.credentialType.name = 'credentials.add.credentialType';
|
||||||
|
this.credentialType.views['credential_type@credentials.add'] = {
|
||||||
|
templateProvider: this.lookupTemplateProvider
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.credentialType;
|
||||||
|
case 'edit-credential-type':
|
||||||
|
this.credentialType.name = 'credentials.edit.credentialType';
|
||||||
|
this.credentialType.views['credential_type@credentials.edit'] = {
|
||||||
|
templateProvider: this.lookupTemplateProvider
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.credentialType;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(`Legacy state configuration for ${name} does not exist`);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
LegacyCredentialsService.$inject = [
|
||||||
|
'PathService'
|
||||||
|
];
|
||||||
|
|
||||||
|
export default LegacyCredentialsService;
|
||||||
@@ -80,6 +80,28 @@ table, tbody {
|
|||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.List-tableRow--disabled {
|
||||||
|
.List-tableCell, .List-tableCell * {
|
||||||
|
color: @b7grey;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.List-tableRow--disabled {
|
||||||
|
.List-actionButton:hover {
|
||||||
|
color: @list-action-icon;
|
||||||
|
background-color: @list-actn-bg !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.List-tableRow--disabled {
|
||||||
|
.List-actionButtonCell * {
|
||||||
|
color: @default-err;
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.List-tableCell {
|
.List-tableCell {
|
||||||
padding: 7px 15px;
|
padding: 7px 15px;
|
||||||
border-top:0px!important;
|
border-top:0px!important;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@import 'action/_index';
|
@import 'action/_index';
|
||||||
@import 'input/_index';
|
@import 'input/_index';
|
||||||
@import 'panel/_index';
|
|
||||||
@import 'modal/_index';
|
@import 'modal/_index';
|
||||||
|
@import 'panel/_index';
|
||||||
@import 'popover/_index';
|
@import 'popover/_index';
|
||||||
@import 'tabs/_index';
|
@import 'tabs/_index';
|
||||||
@import 'utility/_index';
|
@import 'utility/_index';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.at-ActionGroup {
|
.at-ActionGroup {
|
||||||
margin-top: @at-space-6x;
|
margin-top: @at-margin-panel;
|
||||||
|
|
||||||
button:last-child {
|
button:last-child {
|
||||||
margin-left: @at-space-5x;
|
margin-left: @at-margin-panel-inset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ function atFormActionController ($state) {
|
|||||||
vm.setCancelDefaults = () => {
|
vm.setCancelDefaults = () => {
|
||||||
scope.text = 'CANCEL';
|
scope.text = 'CANCEL';
|
||||||
scope.fill = 'Hollow';
|
scope.fill = 'Hollow';
|
||||||
scope.color = 'white';
|
scope.color = 'default';
|
||||||
scope.action = () => $state.go('^');
|
scope.action = () => $state.go(scope.to || '^');
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.setSaveDefaults = () => {
|
vm.setSaveDefaults = () => {
|
||||||
scope.text = 'SAVE';
|
scope.text = 'SAVE';
|
||||||
scope.fill = '';
|
scope.fill = '';
|
||||||
scope.color = 'green';
|
scope.color = 'success';
|
||||||
scope.action = () => form.submit();
|
scope.action = () => form.submit();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,8 @@ function atFormAction (pathService) {
|
|||||||
link,
|
link,
|
||||||
scope: {
|
scope: {
|
||||||
state: '=',
|
state: '=',
|
||||||
type: '@'
|
type: '@',
|
||||||
|
to: '@'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ function atFormLink (scope, el, attrs, controllers) {
|
|||||||
let formController = controllers[0];
|
let formController = controllers[0];
|
||||||
let form = el[0];
|
let form = el[0];
|
||||||
|
|
||||||
|
scope.ns = 'form';
|
||||||
|
scope[scope.ns] = { modal: {} };
|
||||||
|
|
||||||
formController.init(scope, form);
|
formController.init(scope, form);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9,10 +12,10 @@ function AtFormController (eventService) {
|
|||||||
let vm = this || {};
|
let vm = this || {};
|
||||||
|
|
||||||
let scope;
|
let scope;
|
||||||
|
let modal;
|
||||||
let form;
|
let form;
|
||||||
|
|
||||||
vm.components = [];
|
vm.components = [];
|
||||||
vm.modal = {};
|
|
||||||
vm.state = {
|
vm.state = {
|
||||||
isValid: false,
|
isValid: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -22,6 +25,7 @@ function AtFormController (eventService) {
|
|||||||
vm.init = (_scope_, _form_) => {
|
vm.init = (_scope_, _form_) => {
|
||||||
scope = _scope_;
|
scope = _scope_;
|
||||||
form = _form_;
|
form = _form_;
|
||||||
|
modal = scope[scope.ns].modal;
|
||||||
|
|
||||||
vm.setListeners();
|
vm.setListeners();
|
||||||
};
|
};
|
||||||
@@ -102,7 +106,7 @@ function AtFormController (eventService) {
|
|||||||
message = err.data;
|
message = err.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.modal.show('Unable to Submit', `Unexpected Error: ${message}`);
|
modal.show('Unable to Submit', `Unexpected Error: ${message}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,7 +114,7 @@ function AtFormController (eventService) {
|
|||||||
let title = 'Unable to Submit';
|
let title = 'Unable to Submit';
|
||||||
let message = 'Unexpected server error. View the console for more information';
|
let message = 'Unexpected server error. View the console for more information';
|
||||||
|
|
||||||
vm.modal.show(title, message);
|
modal.show(title, message);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,5 +5,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<at-modal state="vm.modal"></at-modal>
|
<at-modal></at-modal>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import inputGroup from './input/group.directive';
|
|||||||
import inputLabel from './input/label.directive';
|
import inputLabel from './input/label.directive';
|
||||||
import inputLookup from './input/lookup.directive';
|
import inputLookup from './input/lookup.directive';
|
||||||
import inputMessage from './input/message.directive';
|
import inputMessage from './input/message.directive';
|
||||||
import inputNumber from './input/number.directive';
|
|
||||||
import inputSelect from './input/select.directive';
|
|
||||||
import inputSecret from './input/secret.directive';
|
import inputSecret from './input/secret.directive';
|
||||||
import inputText from './input/text.directive';
|
import inputText from './input/text.directive';
|
||||||
import inputTextarea from './input/textarea.directive';
|
import inputTextarea from './input/textarea.directive';
|
||||||
@@ -34,9 +32,7 @@ angular
|
|||||||
.directive('atInputLabel', inputLabel)
|
.directive('atInputLabel', inputLabel)
|
||||||
.directive('atInputLookup', inputLookup)
|
.directive('atInputLookup', inputLookup)
|
||||||
.directive('atInputMessage', inputMessage)
|
.directive('atInputMessage', inputMessage)
|
||||||
.directive('atInputNumber', inputNumber)
|
|
||||||
.directive('atInputSecret', inputSecret)
|
.directive('atInputSecret', inputSecret)
|
||||||
.directive('atInputSelect', inputSelect)
|
|
||||||
.directive('atInputText', inputText)
|
.directive('atInputText', inputText)
|
||||||
.directive('atInputTextarea', inputTextarea)
|
.directive('atInputTextarea', inputTextarea)
|
||||||
.directive('atInputTextareaSecret', inputTextareaSecret)
|
.directive('atInputTextareaSecret', inputTextareaSecret)
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
.at-Input {
|
.at-Input {
|
||||||
.at-mixin-Placeholder(@at-gray-dark-3x);
|
.at-mixin-Placeholder(@at-color-input-placeholder);
|
||||||
|
|
||||||
height: @at-input-height;
|
height: @at-height-input;
|
||||||
background: @at-white;
|
background: @at-color-input-background;
|
||||||
border-radius: @at-border-radius;
|
border-radius: @at-border-radius;
|
||||||
color: @at-gray-dark-5x;
|
color: @at-color-input-text;
|
||||||
|
|
||||||
&, &:active {
|
&, &:active {
|
||||||
border-color: @at-gray-dark-2x;
|
border-color: @at-color-input-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
border-color: @at-blue;
|
border-color: @at-color-input-focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
background: @at-color-input-disabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,43 +25,43 @@
|
|||||||
|
|
||||||
& > label {
|
& > label {
|
||||||
& > input[type=checkbox] {
|
& > input[type=checkbox] {
|
||||||
height: @at-input-height;
|
height: @at-height-input;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > p {
|
& > p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 0 0 @at-space-6x;
|
padding: 0 0 0 @at-padding-panel;
|
||||||
line-height: @at-line-height-tall;
|
line-height: @at-line-height-tall;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputContainer {
|
.at-InputContainer {
|
||||||
margin-top: @at-space-6x;
|
margin-top: @at-margin-panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Input-button {
|
.at-Input-button {
|
||||||
min-width: @at-input-button-width;
|
|
||||||
display: block;
|
display: block;
|
||||||
height: @at-input-height;
|
height: @at-height-button;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
&, &:active, &:hover, &:focus {
|
&, &:active, &:hover, &:focus {
|
||||||
color: @at-gray-dark-3x;
|
color: @at-color-button-text-default;
|
||||||
border-color: @at-gray-dark-2x;
|
border-color: @at-color-input-border;
|
||||||
background-color: @at-white;
|
background-color: @at-color-default;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Input--focus {
|
.at-Input--focus {
|
||||||
border-color: @at-blue;
|
border-color: @at-color-input-focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Input--rejected {
|
.at-Input--rejected {
|
||||||
&, &:focus {
|
&, &:focus {
|
||||||
border-color: @at-red;
|
border-color: @at-color-input-error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +70,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: @at-input-button-width;
|
|
||||||
z-index: -2;
|
z-index: -2;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -77,15 +80,15 @@
|
|||||||
|
|
||||||
.at-InputGroup {
|
.at-InputGroup {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: @at-space-6x 0 0 0;
|
margin: @at-margin-panel 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputGroup-border {
|
.at-InputGroup-border {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: @at-inset-width;
|
width: 5px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: @at-gray-dark;
|
background: @at-color-panel-border;
|
||||||
left: -@at-inset-width;
|
left: -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputGroup-button {
|
.at-InputGroup-button {
|
||||||
@@ -93,19 +96,22 @@
|
|||||||
|
|
||||||
& > button {
|
& > button {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
border-right: none;
|
||||||
|
color: @at-color-button-text-default;
|
||||||
|
min-width: @at-input-button-width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputGroup-title {
|
.at-InputGroup-title {
|
||||||
.at-mixin-Heading(@at-font-size-2x);
|
.at-mixin-Heading(@at-font-size-panel-inset-heading);
|
||||||
margin: 0 0 0 @at-space-5x;
|
margin: 0 0 0 @at-margin-panel-inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputGroup-divider {
|
.at-InputGroup-divider {
|
||||||
clear: both;
|
clear: both;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: @at-space-6x;
|
height: @at-height-divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputLabel {
|
.at-InputLabel {
|
||||||
@@ -114,17 +120,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-InputLabel-name {
|
.at-InputLabel-name {
|
||||||
color: @at-gray-dark-4x;
|
color: @at-color-form-label;
|
||||||
font-size: @at-font-size-2x;
|
font-size: @at-font-size-form-label;
|
||||||
font-weight: @at-font-weight;
|
font-weight: @at-font-weight-body;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputLabel-hint {
|
.at-InputLabel-hint {
|
||||||
margin-left: @at-space-4x;
|
margin-left: @at-margin-form-label-hint;
|
||||||
color: @at-gray-dark-3x;
|
color: @at-color-input-hint;
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size-help-text;
|
||||||
font-weight: @at-font-weight;
|
font-weight: @at-font-weight-body;
|
||||||
line-height: @at-line-height-short;
|
line-height: @at-line-height-short;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,15 +143,15 @@
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
& > input[type=checkbox] {
|
& > input[type=checkbox] {
|
||||||
margin: 0 @at-space 0 0;
|
margin: 0 3px 0 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: @at-space;
|
top: 3px
|
||||||
}
|
}
|
||||||
|
|
||||||
& > p {
|
& > p {
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size-help-text;
|
||||||
color: @at-gray-dark-4x;
|
color: @at-color-form-label;
|
||||||
font-weight: @at-font-weight;
|
font-weight: @at-font-weight-body;
|
||||||
display: inline;
|
display: inline;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -153,16 +159,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-InputMessage--rejected {
|
.at-InputMessage--rejected {
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size-help-text;
|
||||||
color: @at-red;
|
color: @at-color-error;
|
||||||
margin: @at-space-3x 0 0 0;
|
margin: @at-margin-input-message 0 0 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-InputLabel-required {
|
.at-InputLabel-required {
|
||||||
color: @at-red;
|
color: @at-color-error;
|
||||||
font-weight: @at-font-weight-2x;
|
font-weight: @at-font-weight-heading;
|
||||||
font-size: @at-font-size-2x;
|
font-size: @at-font-size-form-label;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,13 +177,13 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
& > i {
|
& > i {
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size-button;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
top: @at-space-4x;
|
top: @at-height-input / 3;
|
||||||
right: @at-space-4x;
|
right: @at-height-input / 3;
|
||||||
color: @at-gray-dark-2x;
|
color: @at-color-input-icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +194,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-InputSelect-select {
|
.at-InputSelect-select {
|
||||||
height: @at-input-height;
|
height: @at-height-input;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ function AtInputGroupController ($scope, $compile) {
|
|||||||
|
|
||||||
vm.insert(group);
|
vm.insert(group);
|
||||||
state._group = group;
|
state._group = group;
|
||||||
vm.compile(group);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.createComponentConfigs = inputs => {
|
vm.createComponentConfigs = inputs => {
|
||||||
@@ -138,20 +137,22 @@ function AtInputGroupController ($scope, $compile) {
|
|||||||
vm.createComponent = (input, index) => {
|
vm.createComponent = (input, index) => {
|
||||||
let tabindex = Number(scope.tab) + index;
|
let tabindex = Number(scope.tab) + index;
|
||||||
let col = input._expand ? 12 : scope.col;
|
let col = input._expand ? 12 : scope.col;
|
||||||
|
let component = angular.element(
|
||||||
return angular.element(
|
|
||||||
`<${input._component} col="${col}" tab="${tabindex}"
|
`<${input._component} col="${col}" tab="${tabindex}"
|
||||||
state="${state._reference}._group[${index}]">
|
state="${state._reference}._group[${index}]">
|
||||||
</${input._component}>`
|
</${input._component}>`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$compile(component)(scope.$parent)
|
||||||
|
|
||||||
|
return component;
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.createDivider = () => {
|
vm.createDivider = () => {
|
||||||
return angular.element('<at-divider></at-divider>');
|
let divider = angular.element('<at-divider></at-divider>');
|
||||||
};
|
$compile(divider[0])(scope.$parent);
|
||||||
|
|
||||||
vm.compile = group => {
|
return divider;
|
||||||
group.forEach(component => $compile(component._element[0])(scope.$parent));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.clear = () => {
|
vm.clear = () => {
|
||||||
|
|||||||
@@ -9,43 +9,46 @@ function atInputLookupLink (scope, element, attrs, controllers) {
|
|||||||
inputController.init(scope, element, formController);
|
inputController.init(scope, element, formController);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtInputLookupController (baseInputController) {
|
function AtInputLookupController (baseInputController, $state, $stateParams) {
|
||||||
let vm = this || {};
|
let vm = this || {};
|
||||||
|
|
||||||
vm.lookup = {};
|
let scope;
|
||||||
|
|
||||||
vm.init = (scope, element, form) => {
|
vm.init = (_scope_, element, form) => {
|
||||||
baseInputController.call(vm, 'input', scope, element, form);
|
baseInputController.call(vm, 'input', _scope_, element, form);
|
||||||
|
|
||||||
vm.lookup.modal = {
|
scope = _scope_;
|
||||||
title: 'Select Organization',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
type: 'cancel'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'select'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
vm.lookup.search = {
|
scope.$watch(scope.state._resource, vm.watchResource);
|
||||||
placeholder: 'test'
|
|
||||||
};
|
|
||||||
|
|
||||||
vm.lookup.table = {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
vm.check();
|
vm.check();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vm.watchResource = () => {
|
||||||
|
if (scope[scope.state._resource]) {
|
||||||
|
scope.state._value = scope[scope.state._resource];
|
||||||
|
scope.state._displayValue = scope[`${scope.state._resource}_name`];
|
||||||
|
|
||||||
|
vm.check();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
vm.search = () => {
|
vm.search = () => {
|
||||||
vm.modal.show('test');
|
let params = {};
|
||||||
|
|
||||||
|
if (scope.state._value) {
|
||||||
|
params.selected = scope.state._value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$state.go(scope.state._route, params);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
AtInputLookupController.$inject = ['BaseInputController'];
|
AtInputLookupController.$inject = [
|
||||||
|
'BaseInputController',
|
||||||
|
'$state',
|
||||||
|
'$stateParams'
|
||||||
|
];
|
||||||
|
|
||||||
function atInputLookup (pathService) {
|
function atInputLookup (pathService) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button class="btn at-ButtonHollow--white at-Input-button"
|
<button class="btn at-ButtonHollow--default at-Input-button"
|
||||||
ng-disabled="state._disabled || form.disabled"
|
ng-disabled="state._disabled || form.disabled"
|
||||||
ng-click="vm.search()">
|
ng-click="vm.search()">
|
||||||
<i class="fa fa-search"></i>
|
<i class="fa fa-search"></i>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<input type="text"
|
<input type="text"
|
||||||
class="form-control at-Input"
|
class="form-control at-Input"
|
||||||
ng-class="{ 'at-Input--rejected': state.rejected }"
|
ng-class="{ 'at-Input--rejected': state.rejected }"
|
||||||
ng-model="state._value"
|
ng-model="state._displayValue"
|
||||||
ng-attr-tabindex="{{ tab || undefined }}"
|
ng-attr-tabindex="{{ tab || undefined }}"
|
||||||
ng-attr-placeholder="{{::state._placeholder || undefined }}"
|
ng-attr-placeholder="{{::state._placeholder || undefined }}"
|
||||||
ng-change="vm.check()"
|
ng-change="vm.check()"
|
||||||
@@ -23,8 +23,5 @@
|
|||||||
<at-input-message></at-input-message>
|
<at-input-message></at-input-message>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<at-modal state="vm.lookup">
|
<div ui-view="{{ state._resource }}"></div>
|
||||||
<at-search></at-search>
|
|
||||||
<at-table></at-table>
|
|
||||||
</at-modal>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
const DEFAULT_STEP = '1';
|
|
||||||
const DEFAULT_MIN = '0';
|
|
||||||
const DEFAULT_MAX = '1000000000';
|
|
||||||
const DEFAULT_PLACEHOLDER = '';
|
|
||||||
|
|
||||||
function atInputNumberLink (scope, element, attrs, controllers) {
|
|
||||||
let formController = controllers[0];
|
|
||||||
let inputController = controllers[1];
|
|
||||||
|
|
||||||
if (scope.tab === '1') {
|
|
||||||
element.find('input')[0].focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
inputController.init(scope, element, formController);
|
|
||||||
}
|
|
||||||
|
|
||||||
function AtInputNumberController (baseInputController) {
|
|
||||||
let vm = this || {};
|
|
||||||
|
|
||||||
vm.init = (scope, element, form) => {
|
|
||||||
baseInputController.call(vm, 'input', scope, element, form);
|
|
||||||
|
|
||||||
scope.state._step = scope.state._step || DEFAULT_STEP;
|
|
||||||
scope.state._min = scope.state._min || DEFAULT_MIN;
|
|
||||||
scope.state._max = scope.state._max || DEFAULT_MAX;
|
|
||||||
scope.state._placeholder = scope.state._placeholder || DEFAULT_PLACEHOLDER;
|
|
||||||
|
|
||||||
vm.check();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
AtInputNumberController.$inject = ['BaseInputController'];
|
|
||||||
|
|
||||||
function atInputNumber (pathService) {
|
|
||||||
return {
|
|
||||||
restrict: 'E',
|
|
||||||
transclude: true,
|
|
||||||
replace: true,
|
|
||||||
require: ['^^atForm', 'atInputNumber'],
|
|
||||||
templateUrl: pathService.getPartialPath('components/input/number'),
|
|
||||||
controller: AtInputNumberController,
|
|
||||||
controllerAs: 'vm',
|
|
||||||
link: atInputNumberLink,
|
|
||||||
scope: {
|
|
||||||
state: '=',
|
|
||||||
col: '@',
|
|
||||||
tab: '@'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
atInputNumber.$inject = ['PathService'];
|
|
||||||
|
|
||||||
export default atInputNumber;
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<div class="col-sm-{{::col}} at-InputContainer">
|
|
||||||
<div class="form-group at-u-flat">
|
|
||||||
<at-input-label></at-input-label>
|
|
||||||
|
|
||||||
<input type="number"
|
|
||||||
class="form-control at-Input"
|
|
||||||
ng-class="{ 'at-Input--rejected': state.rejected }"
|
|
||||||
ng-model="state._value"
|
|
||||||
ng-attr-min="state._min"
|
|
||||||
ng-attr-max="state._max"
|
|
||||||
ng-attr-step="state._step"
|
|
||||||
ng-attr-tabindex="{{ tab || undefined }}"
|
|
||||||
ng-attr-placeholder="{{::state._placeholder || undefined }}"
|
|
||||||
ng-change="vm.check()"
|
|
||||||
ng-disabled="state._disabled || form.disabled" />
|
|
||||||
|
|
||||||
<at-input-message></at-input-message>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,10 +1,28 @@
|
|||||||
|
.at-Modal-body {
|
||||||
|
font-size: @at-font-size;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Modal-dismiss {
|
||||||
|
.at-mixin-ButtonIcon();
|
||||||
|
font-size: @at-font-size-modal-dismiss;
|
||||||
|
color: @at-color-icon-dismiss;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Modal-heading {
|
||||||
|
margin: 0;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
& > .at-Modal-dismiss {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.at-Modal-title {
|
.at-Modal-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
.at-mixin-Heading(@at-font-size-3x);
|
.at-mixin-Heading(@at-font-size-modal-heading);
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Modal-body {
|
|
||||||
font-size: @at-font-size;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,45 +1,74 @@
|
|||||||
const DEFAULT_ANIMATION_DURATION = 150;
|
const DEFAULT_ANIMATION_DURATION = 150;
|
||||||
|
|
||||||
function atModalLink (scope, el, attr, controllers) {
|
function atModalLink (scope, el, attrs, controllers) {
|
||||||
let modalController = controllers[0];
|
let modalController = controllers[0];
|
||||||
let container = el[0];
|
let property = `scope.${scope.ns}.modal`;
|
||||||
|
|
||||||
modalController.init(scope, container);
|
let done = scope.$watch(property, () => {
|
||||||
|
modalController.init(scope, el);
|
||||||
|
done();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtModalController () {
|
function AtModalController (eventService) {
|
||||||
let vm = this;
|
let vm = this;
|
||||||
|
|
||||||
let scope;
|
let overlay;
|
||||||
let container;
|
let modal;
|
||||||
|
let listeners;
|
||||||
|
|
||||||
vm.init = (_scope_, _container_) => {
|
vm.init = (scope, el) => {
|
||||||
scope = _scope_;
|
overlay = el[0];
|
||||||
container = _container_;
|
modal = el.find('.at-Modal-window')[0];
|
||||||
|
|
||||||
scope.state.show = vm.show;
|
vm.modal = scope[scope.ns].modal;
|
||||||
scope.state.hide = vm.hide;
|
vm.modal.show = vm.show;
|
||||||
|
vm.modal.hide = vm.hide;
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.show = (title, message) => {
|
vm.show = (title, message) => {
|
||||||
scope.title = title;
|
vm.modal.title = title;
|
||||||
scope.message = message;
|
vm.modal.message = message;
|
||||||
|
|
||||||
container.style.display = 'block';
|
event.stopPropagation();
|
||||||
container.style.opacity = 1;
|
|
||||||
|
listeners = eventService.addListeners([
|
||||||
|
[window, 'click', vm.clickToHide]
|
||||||
|
]);
|
||||||
|
|
||||||
|
overlay.style.display = 'block';
|
||||||
|
overlay.style.opacity = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.hide = () => {
|
vm.hide = () => {
|
||||||
container.style.opacity = 0;
|
overlay.style.opacity = 0;
|
||||||
|
|
||||||
setTimeout(() => {
|
eventService.remove(listeners);
|
||||||
container.style.display = 'none';
|
|
||||||
scope.message = '';
|
setTimeout(() => overlay.style.display = 'none', DEFAULT_ANIMATION_DURATION);
|
||||||
scope.title = '';
|
};
|
||||||
}, DEFAULT_ANIMATION_DURATION);
|
|
||||||
|
vm.clickToHide = event => {
|
||||||
|
if (vm.clickIsOutsideModal(event)) {
|
||||||
|
vm.hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.clickIsOutsideModal = e => {
|
||||||
|
let m = modal.getBoundingClientRect();
|
||||||
|
let cx = e.clientX;
|
||||||
|
let cy = e.clientY;
|
||||||
|
|
||||||
|
if (cx < m.left || cx > m.right || cy > m.bottom || cy < m.top) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AtModalController.$inject = ['EventService'];
|
||||||
|
|
||||||
function atModal (pathService) {
|
function atModal (pathService) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
@@ -50,9 +79,7 @@ function atModal (pathService) {
|
|||||||
controller: AtModalController,
|
controller: AtModalController,
|
||||||
controllerAs: 'vm',
|
controllerAs: 'vm',
|
||||||
link: atModalLink,
|
link: atModalLink,
|
||||||
scope: {
|
scope: true
|
||||||
state: '='
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,31 @@
|
|||||||
<div class="modal at-Modal fade" tabindex="-1" role="dialog">
|
<div class="modal at-Modal fade" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content at-Modal-window">
|
||||||
<div class="modal-header">
|
<div class="row">
|
||||||
<button type="button" class="close" ng-click="vm.hide()">
|
<div class="col-xs-10">
|
||||||
<i class="fa fa-times"></i>
|
<div class="at-Modal-heading">
|
||||||
</button>
|
<h4 class="modal-title at-Modal-title">{{ vm.modal.title }}</h4>
|
||||||
<h4 class="modal-title at-Modal-title">{{ title }}</h4>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-2">
|
||||||
|
<div class="at-Modal-dismiss">
|
||||||
|
<i class="fa fa-lg fa-times-circle" ng-click="vm.hide()"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body at-Modal-body">
|
|
||||||
<p ng-show="message">{{ message }}</p>
|
<ng-transclude></ng-transclude>
|
||||||
<ng-transclude></ng-transclude>
|
|
||||||
</div>
|
<div ng-show="vm.modal.message">
|
||||||
<div class="modal-footer">
|
<div class="modal-body at-Modal-body">
|
||||||
<button type="button" class="btn at-ButtonHollow--white" ng-click="vm.hide()">
|
<p>{{ vm.modal.message }}</p>
|
||||||
OK
|
</div>
|
||||||
</button>
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn at-ButtonHollow--default"
|
||||||
|
ng-click="vm.hide()">
|
||||||
|
OK
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.at-Panel {
|
.at-Panel {
|
||||||
margin: @at-space-6x 0 0 0;
|
margin: @at-margin-panel 0 0 0;
|
||||||
padding: @at-space-6x;
|
padding: @at-padding-panel;
|
||||||
border-color: @at-gray-dark;
|
border-color: @at-color-panel-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Panel-heading {
|
.at-Panel-heading {
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
.at-Panel-dismiss {
|
.at-Panel-dismiss {
|
||||||
.at-mixin-ButtonIcon();
|
.at-mixin-ButtonIcon();
|
||||||
|
color: @at-color-icon-dismiss;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,6 +21,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-Panel-headingTitle {
|
.at-Panel-headingTitle {
|
||||||
.at-mixin-Heading(@at-font-size-3x);
|
.at-mixin-Heading(@at-font-size-panel-heading);
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.at-Popover {
|
.at-Popover {
|
||||||
padding: 0 0 0 @at-space-3x;
|
padding: 0 0 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Popover--inline {
|
.at-Popover--inline {
|
||||||
@@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
.at-Popover-icon {
|
.at-Popover-icon {
|
||||||
.at-mixin-ButtonIcon();
|
.at-mixin-ButtonIcon();
|
||||||
font-size: @at-font-size-4x;
|
color: @at-color-icon-popover;
|
||||||
|
font-size: @at-font-size-icon;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -17,35 +18,35 @@
|
|||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
color: @at-white;
|
color: @at-white;
|
||||||
background-color: @at-gray-dark-4x;
|
background-color: @at-color-body-background-dark;
|
||||||
max-width: @at-popover-width;
|
max-width: @at-popover-maxwidth;
|
||||||
padding: @at-space-4x;
|
padding: @at-padding-popover;
|
||||||
height: auto;
|
height: auto;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
margin: 0 0 0 @at-space-6x;
|
margin: 0 0 0 18px;
|
||||||
border-radius: @at-border-radius;
|
border-radius: @at-border-radius;
|
||||||
box-shadow: 0 5px 10px rgba(0,0,0, 0.2);
|
box-shadow: 0 5px 10px rgba(0,0,0, 0.2);
|
||||||
transition: opacity .15s linear;
|
transition: opacity .15s linear;
|
||||||
font-weight: @at-font-weight
|
font-weight: @at-font-weight-body;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Popover-arrow {
|
.at-Popover-arrow {
|
||||||
color: @at-gray-dark-4x;
|
color: @at-color-body-background-dark;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1999;
|
z-index: 1999;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: @at-space-4x 0 0 @at-space;
|
margin: 8px 0 0 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Popover-title {
|
.at-Popover-title {
|
||||||
.at-mixin-Heading(@at-font-size);
|
.at-mixin-Heading(@at-font-size-body);
|
||||||
color: @at-white;
|
color: @at-color-body-text-dark;
|
||||||
margin-bottom: @at-space-4x;
|
margin-bottom: @at-margin-popover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Popover-text {
|
.at-Popover-text {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size-body;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
.at-TabGroup {
|
.at-TabGroup {
|
||||||
margin-top: @at-space-6x;
|
margin-top: @at-margin-panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Tab {
|
.at-Tab {
|
||||||
margin: 0 @at-space-5x 0 0;
|
margin: 0 @at-margin-item-column 0 0;
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size-body;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Tab--active {
|
.at-Tab--active {
|
||||||
&, &:hover, &:active, &:focus {
|
&, &:hover, &:active, &:focus {
|
||||||
color: @at-white;
|
color: @at-color-tab-text-default-active;
|
||||||
background-color: @at-gray-dark-3x;
|
background-color: @at-color-tab-default-active;
|
||||||
border-color: @at-gray-dark-3x;
|
border-color: @at-color-tab-border-default-active;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Tab--disabled {
|
.at-Tab--disabled {
|
||||||
&, &:hover, &:active, &:focus {
|
&, &:hover, &:active, &:focus {
|
||||||
background-color: @at-white;
|
background-color: @at-color-tab-default-disabled;
|
||||||
color: @at-gray-dark-2x;
|
color: @at-color-tab-text-default-disabled;
|
||||||
border-color: @at-gray-dark-2x;
|
border-color: @at-color-tab-border-default-disabled;
|
||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<button class="btn at-ButtonHollow--white at-Tab"
|
<button class="btn at-ButtonHollow--default at-Tab"
|
||||||
ng-attr-disabled="{{ state._disabled || undefined }}"
|
ng-attr-disabled="{{ state._disabled || undefined }}"
|
||||||
ng-class="{ 'at-Tab--active': state._active, 'at-Tab--disabled': state._disabled }"
|
ng-class="{ 'at-Tab--active': state._active, 'at-Tab--disabled': state._disabled }"
|
||||||
ng-click="vm.go()">
|
ng-click="vm.go()">
|
||||||
|
|||||||
@@ -77,25 +77,24 @@ function httpOptions (resource) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get (method, keys) {
|
function options (keys) {
|
||||||
let model;
|
return this.find('options', keys);
|
||||||
|
}
|
||||||
|
|
||||||
if (keys) {
|
function get (keys) {
|
||||||
model = this.model[method.toUpperCase()];
|
return this.find('get', keys);
|
||||||
} else {
|
}
|
||||||
model = this.model.GET;
|
|
||||||
keys = method;
|
function find (method, keys) {
|
||||||
}
|
let value = this.model[method.toUpperCase()];
|
||||||
|
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
return model;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys = keys.split('.');
|
|
||||||
|
|
||||||
let value = model;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
keys = keys.split('.');
|
||||||
|
|
||||||
keys.forEach(key => {
|
keys.forEach(key => {
|
||||||
let bracketIndex = key.indexOf('[');
|
let bracketIndex = key.indexOf('[');
|
||||||
let hasArray = bracketIndex !== -1;
|
let hasArray = bracketIndex !== -1;
|
||||||
@@ -137,6 +136,8 @@ function getById (id) {
|
|||||||
function BaseModel (path) {
|
function BaseModel (path) {
|
||||||
this.model = {};
|
this.model = {};
|
||||||
this.get = get;
|
this.get = get;
|
||||||
|
this.options = options;
|
||||||
|
this.find = find;
|
||||||
this.normalizePath = normalizePath;
|
this.normalizePath = normalizePath;
|
||||||
this.getById = getById;
|
this.getById = getById;
|
||||||
this.request = request;
|
this.request = request;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const ENCRYPTED_VALUE = '$encrypted$';
|
|||||||
let BaseModel;
|
let BaseModel;
|
||||||
|
|
||||||
function createFormSchema (method, config) {
|
function createFormSchema (method, config) {
|
||||||
let schema = Object.assign({}, this.get('options', `actions.${method.toUpperCase()}`));
|
let schema = Object.assign({}, this.options(`actions.${method.toUpperCase()}`));
|
||||||
|
|
||||||
if (config && config.omit) {
|
if (config && config.omit) {
|
||||||
config.omit.forEach(key => {
|
config.omit.forEach(key => {
|
||||||
|
|||||||
68
awx/ui/client/lib/theme/_base-variables.less
Normal file
68
awx/ui/client/lib/theme/_base-variables.less
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* All base variables used. These should only be referenced by the contextual variables defined
|
||||||
|
* in the _contextual-variables.less file. In development, unless you are intentionally making a
|
||||||
|
* fundamental change, these variables should not be modified, removed, or added to.
|
||||||
|
*
|
||||||
|
* These variables should not be used directly in development of components or features. If an
|
||||||
|
* alias doesn't exist for the context you're working within, check with UX to create a new alias
|
||||||
|
* or to define a more applicable alias.
|
||||||
|
*
|
||||||
|
* The goal is for UX to define the contexts for the contextual variables, so it's easy to make
|
||||||
|
* modifications like, "Change heading text to be smaller" or "Make all warnings a lighter shade
|
||||||
|
* of orange"
|
||||||
|
*
|
||||||
|
* 1. Colors
|
||||||
|
* 2. Typography
|
||||||
|
* 3. Layout
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. Colors --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-gray-light-3x: #fcfcfc;
|
||||||
|
@at-gray-light-2x: #f2f2f2;
|
||||||
|
@at-gray-light: #ebebeb;
|
||||||
|
@at-gray: #e1e1e1;
|
||||||
|
@at-gray-dark: #d7d7d7;
|
||||||
|
@at-gray-dark-2x: #b7b7b7;
|
||||||
|
@at-gray-dark-3x: #A9A9A9;
|
||||||
|
@at-gray-dark-4x: #848992;
|
||||||
|
@at-gray-dark-5x: #707070;
|
||||||
|
@at-gray-dark-6x: #161b1f;
|
||||||
|
|
||||||
|
@at-white: #ffffff;
|
||||||
|
@at-white-hover: #f2f2f2;
|
||||||
|
|
||||||
|
@at-blue: #337ab7;
|
||||||
|
@at-blue-hover: #286090;
|
||||||
|
|
||||||
|
@at-green: #5cb85c;
|
||||||
|
@at-green-hover: #449D44;
|
||||||
|
|
||||||
|
@at-orange: #f0ad4e;
|
||||||
|
@at-orange-hover: #ec971f;
|
||||||
|
|
||||||
|
@at-red: #d9534f;
|
||||||
|
@at-red-hover: #c9302c;
|
||||||
|
|
||||||
|
@at-red-bright: #ff0000;
|
||||||
|
@at-red-bright-hover: #d81f1f;
|
||||||
|
|
||||||
|
// 2. Typography ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-font-size: 12px;
|
||||||
|
@at-font-size-2x: 13px;
|
||||||
|
@at-font-size-3x: 14px;
|
||||||
|
@at-font-size-4x: 16px;
|
||||||
|
@at-font-size-5x: 20px;
|
||||||
|
|
||||||
|
@at-font-weight: 400;
|
||||||
|
@at-font-weight-2x: 700;
|
||||||
|
|
||||||
|
// 3. Layout --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-space: 5px;
|
||||||
|
@at-space-2x: 10px;
|
||||||
|
@at-space-3x: 15px;
|
||||||
|
@at-space-4x: 20px;
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* For styles that are used in more than one place throughout the application.
|
|
||||||
*
|
|
||||||
* 1. Buttons
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 1. Buttons -------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.at-Button--green {
|
|
||||||
.at-mixin-Button();
|
|
||||||
.at-mixin-ButtonColor('at-green', 'at-white');
|
|
||||||
|
|
||||||
&[disabled] {
|
|
||||||
background: @at-gray-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.at-Button--blue {
|
|
||||||
.at-mixin-Button();
|
|
||||||
.at-mixin-ButtonColor('at-blue', 'at-white');
|
|
||||||
}
|
|
||||||
|
|
||||||
.at-Button--red {
|
|
||||||
.at-mixin-Button();
|
|
||||||
.at-mixin-ButtonColor('at-red', 'at-white');
|
|
||||||
}
|
|
||||||
|
|
||||||
.at-ButtonHollow--white {
|
|
||||||
.at-mixin-Button();
|
|
||||||
.at-mixin-ButtonHollow('at-gray-dark-3x', 'at-gray-dark-2x');
|
|
||||||
border-color: @at-gray-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.at-ButtonIcon {
|
|
||||||
padding: @at-space-2x @at-space-4x;
|
|
||||||
font-size: @at-font-size-3x;
|
|
||||||
}
|
|
||||||
139
awx/ui/client/lib/theme/_contextual-variables.less
Normal file
139
awx/ui/client/lib/theme/_contextual-variables.less
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* All variables used in the UI. Use these variables directly during the development of components
|
||||||
|
* and features. Be sure the context of the variable name applies to the work that's being done.
|
||||||
|
* For example, it wouldn't make sense to use `@at-input-height` to describe the height of a
|
||||||
|
* button. Either add an alias if it makes sense to use the same base variable, or add a new
|
||||||
|
* base variable to reference.
|
||||||
|
*
|
||||||
|
* Keep in mind the goal is to be able to modify an item by referencing its context instead of
|
||||||
|
* an arbitrary variable name. For example, tt should be a simple change when an ask comes in to
|
||||||
|
* "increase the height of inputs"
|
||||||
|
*
|
||||||
|
* 1. Colors
|
||||||
|
* 2. Typography
|
||||||
|
* 3. Layout
|
||||||
|
* 4. Buttons
|
||||||
|
* 5. Misc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. Colors --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-color-default: @at-white;
|
||||||
|
@at-color-default-hover: @at-white-hover;
|
||||||
|
|
||||||
|
@at-color-unreachable: @at-red-bright;
|
||||||
|
@at-color-unreachable-hover: @at-red-bright-hover;
|
||||||
|
|
||||||
|
@at-color-error: @at-red;
|
||||||
|
@at-color-error-hover: @at-red-hover;
|
||||||
|
|
||||||
|
@at-color-warning: @at-orange;
|
||||||
|
@at-color-warning-hover: @at-orange-hover;
|
||||||
|
|
||||||
|
@at-color-info: @at-blue;
|
||||||
|
@at-color-info-hover: @at-blue-hover;
|
||||||
|
|
||||||
|
@at-color-success: @at-green;
|
||||||
|
@at-color-success-hover: @at-green-hover;
|
||||||
|
|
||||||
|
@at-color-disabled: @at-gray-dark;
|
||||||
|
|
||||||
|
@at-color-body-background-dark: @at-gray-dark-5x;
|
||||||
|
@at-color-body-text-dark: @at-white;
|
||||||
|
@at-color-body-background: @at-gray-light-3x;
|
||||||
|
@at-color-body-text: @at-gray-dark-5x;
|
||||||
|
|
||||||
|
@at-color-button-border-default: @at-gray-dark-2x;
|
||||||
|
@at-color-button-text-default: @at-gray-dark-5x;
|
||||||
|
|
||||||
|
@at-color-tab-default-active: @at-gray-dark-2x;
|
||||||
|
@at-color-tab-border-default-active: @at-gray-dark-2x;
|
||||||
|
@at-color-tab-text-default-active: @at-white;
|
||||||
|
|
||||||
|
@at-color-tab-default-disabled: @at-white;
|
||||||
|
@at-color-tab-border-default-disabled: @at-gray-dark-2x;
|
||||||
|
@at-color-tab-text-default-disabled: @at-gray-dark-5x;
|
||||||
|
|
||||||
|
@at-color-form-label: @at-gray-dark-5x;
|
||||||
|
|
||||||
|
@at-color-input-border: @at-gray-dark-2x;
|
||||||
|
@at-color-input-error: @at-color-error;
|
||||||
|
@at-color-input-focus: @at-color-info;
|
||||||
|
@at-color-input-hint: @at-gray-dark-4x;
|
||||||
|
@at-color-input-icon: @at-gray-dark-2x;
|
||||||
|
@at-color-input-placeholder: @at-gray-dark-4x;
|
||||||
|
@at-color-input-text: @at-gray-dark-6x;
|
||||||
|
@at-color-input-background: @at-gray-light-3x;
|
||||||
|
@at-color-input-disabled: @at-gray-light-2x;
|
||||||
|
|
||||||
|
@at-color-icon-dismiss: @at-gray-dark;
|
||||||
|
@at-color-icon-popover: @at-gray-dark-3x;
|
||||||
|
@at-color-icon-hover: @at-gray-dark-5x;
|
||||||
|
|
||||||
|
@at-color-panel-heading: @at-gray-dark-5x;
|
||||||
|
@at-color-panel-border: @at-gray-dark;
|
||||||
|
|
||||||
|
@at-color-search-key-active: @at-blue;
|
||||||
|
|
||||||
|
@at-color-table-header-background: @at-gray-light;
|
||||||
|
@at-color-line-separator: @at-gray;
|
||||||
|
|
||||||
|
// 2. Typography ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-font-size-body: @at-font-size-3x;
|
||||||
|
@at-font-size-button: @at-font-size;
|
||||||
|
@at-font-size-breadcrumb: @at-font-size-3x;
|
||||||
|
@at-font-size-form-label: @at-font-size-2x;
|
||||||
|
@at-font-size-help-text: @at-font-size;
|
||||||
|
@at-font-size-icon: @at-font-size-4x;
|
||||||
|
@at-font-size-input: @at-font-size-3x;
|
||||||
|
@at-font-size-panel-heading: @at-font-size-3x;
|
||||||
|
@at-font-size-panel-inset-heading: @at-font-size-2x;
|
||||||
|
@at-font-size-modal-heading: @at-font-size-3x;
|
||||||
|
@at-font-size-modal-dismiss: @at-font-size-3x;
|
||||||
|
@at-font-size-navigation: @at-font-size-3x;
|
||||||
|
@at-font-size-table-heading: @at-font-size-3x;
|
||||||
|
@at-font-size-menu-icon: @at-font-size-5x;
|
||||||
|
|
||||||
|
@at-font-weight-body: @at-font-weight;
|
||||||
|
@at-font-weight-heading: @at-font-weight-2x;
|
||||||
|
|
||||||
|
// 3. Layout --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-padding-button-horizontal: @at-space-2x;
|
||||||
|
@at-padding-button-vertical: @at-space;
|
||||||
|
@at-padding-inset: @at-space-3x;
|
||||||
|
@at-padding-panel: @at-space-4x;
|
||||||
|
@at-padding-popover: @at-space-2x;
|
||||||
|
@at-padding-well: @at-space-2x;
|
||||||
|
|
||||||
|
@at-margin-input-message: @at-space;
|
||||||
|
@at-margin-item-column: @at-space-3x;
|
||||||
|
@at-margin-panel: @at-space-4x;
|
||||||
|
@at-margin-panel-inset: @at-space-3x;
|
||||||
|
@at-margin-popover: @at-space-2x;
|
||||||
|
@at-margin-tag: @at-space-2x;
|
||||||
|
@at-margin-form-label: @at-space;
|
||||||
|
@at-margin-form-label-hint: @at-space-2x;
|
||||||
|
|
||||||
|
@at-margin-top-search-key: @at-space-2x;
|
||||||
|
|
||||||
|
@at-height-divider: @at-margin-panel;
|
||||||
|
@at-height-input: 30px;
|
||||||
|
@at-height-button: 30px;
|
||||||
|
@at-height-tab: 30px;
|
||||||
|
|
||||||
|
// 4. Transitions ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-transition-icon-button: 0.2s;
|
||||||
|
|
||||||
|
// 5. Misc ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@at-border-radius: 5px;
|
||||||
|
@at-popover-maxwidth: 320px;
|
||||||
|
@at-line-height-short: 0.9;
|
||||||
|
@at-line-height-tall: 2;
|
||||||
|
@at-line-height: 24px;
|
||||||
|
@at-input-button-width: 72px;
|
||||||
|
|
||||||
45
awx/ui/client/lib/theme/_global.less
Normal file
45
awx/ui/client/lib/theme/_global.less
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* For styles that are used in more than one place throughout the application.
|
||||||
|
*
|
||||||
|
* 1. Buttons
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. Buttons -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.at-Button--success {
|
||||||
|
.at-mixin-Button();
|
||||||
|
.at-mixin-ButtonColor('at-color-success', 'at-color-default');
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
background: @at-color-disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Button--info {
|
||||||
|
.at-mixin-Button();
|
||||||
|
.at-mixin-ButtonColor('at-color-info', 'at-color-default');
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Button--error {
|
||||||
|
.at-mixin-Button();
|
||||||
|
.at-mixin-ButtonColor('at-color-error', 'at-color-default');
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-ButtonHollow--default {
|
||||||
|
.at-mixin-Button();
|
||||||
|
.at-mixin-ButtonHollow(
|
||||||
|
'at-color-default',
|
||||||
|
'at-color-button-border-default',
|
||||||
|
'at-color-button-text-default'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-ButtonIcon {
|
||||||
|
padding: 4px @at-padding-button-horizontal;
|
||||||
|
font-size: @at-font-size-body;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Button--expand {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@@ -11,9 +11,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-mixin-Heading (@size) {
|
.at-mixin-Heading (@size) {
|
||||||
color: @at-gray-dark-4x;
|
color: @at-color-body-text;
|
||||||
font-size: @size;
|
font-size: @size;
|
||||||
font-weight: @at-font-weight-2x;
|
font-weight: @at-font-weight-heading;
|
||||||
line-height: @at-line-height-short;
|
line-height: @at-line-height-short;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -21,12 +21,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-mixin-Button () {
|
.at-mixin-Button () {
|
||||||
height: @at-input-height;
|
height: @at-height-input;
|
||||||
padding: @at-space-2x @at-space-4x;
|
padding: @at-padding-button-vertical @at-padding-button-horizontal;
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size-body;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-mixin-ButtonColor (@background, @color, @hover: '@{background}--hover') {
|
.at-mixin-ButtonColor (@background, @color, @hover: '@{background}-hover') {
|
||||||
background-color: @@background;
|
background-color: @@background;
|
||||||
|
|
||||||
&, &:hover, &:focus {
|
&, &:hover, &:focus {
|
||||||
@@ -42,21 +43,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-mixin-ButtonHollow (@color, @accent) {
|
.at-mixin-ButtonHollow (@bg, @border, @text) {
|
||||||
background-color: @at-white;
|
@hover: '@{bg}-hover';
|
||||||
color: @@color;
|
|
||||||
border-color: @@color;
|
background-color: @@bg;
|
||||||
|
color: @@text;
|
||||||
|
border-color: @@border;
|
||||||
|
|
||||||
&:hover, &:active {
|
&:hover, &:active {
|
||||||
color: @@color;
|
color: @@text;
|
||||||
background-color: @at-white--hover;
|
background-color: @@hover;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
color: @at-white;
|
color: @@text;
|
||||||
background-color: @@accent;
|
background-color: @@hover;
|
||||||
border-color: @@accent;
|
border-color: @@border;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +70,14 @@
|
|||||||
|
|
||||||
.at-mixin-ButtonIcon () {
|
.at-mixin-ButtonIcon () {
|
||||||
line-height: @at-line-height-short;
|
line-height: @at-line-height-short;
|
||||||
color: @at-gray-dark-2x;
|
|
||||||
|
|
||||||
& > i {
|
& > i {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition: color @at-transition-icon-button;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > i:hover {
|
& > i:hover {
|
||||||
color: @at-gray-dark-3x;
|
color: @at-color-icon-hover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
/**
|
|
||||||
* All variables used in the UI.
|
|
||||||
*
|
|
||||||
* 1. Colors
|
|
||||||
* 2. Typography
|
|
||||||
* 3. Layout
|
|
||||||
* 4. Input
|
|
||||||
* 5. Misc
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 1. Colors --------------------------------------------------------------------------------------
|
|
||||||
@at-gray-light-5x: #fcfcfc;
|
|
||||||
@at-gray-light-4x: #fafafa;
|
|
||||||
@at-gray-light-3x: #f6f6f6;
|
|
||||||
@at-gray-light-2x: #f2f2f2;
|
|
||||||
@at-gray-light: #ebebeb;
|
|
||||||
@at-gray: #e1e1e1;
|
|
||||||
@at-gray-dark: #d7d7d7;
|
|
||||||
@at-gray-dark-2x: #b7b7b7;
|
|
||||||
@at-gray-dark-3x: #848992;
|
|
||||||
@at-gray-dark-4x: #707070;
|
|
||||||
@at-gray-dark-5x: #161b1f;
|
|
||||||
|
|
||||||
@at-white: #ffffff;
|
|
||||||
@at-white--hover: #f2f2f2;
|
|
||||||
|
|
||||||
@at-blue: #337ab7;
|
|
||||||
@at-blue--hover: #286090;
|
|
||||||
|
|
||||||
@at-green: #5cb85c;
|
|
||||||
@at-green--hover: #449D44;
|
|
||||||
|
|
||||||
@at-yellow: #f0ad4e;
|
|
||||||
@at-yellow--hover: #ec971f;
|
|
||||||
|
|
||||||
@at-red: #d9534f;
|
|
||||||
@at-red--hover: #c9302c;
|
|
||||||
|
|
||||||
@at-redAlert: #ff0000;
|
|
||||||
@at-redAlert--hover: #d81f1f;
|
|
||||||
|
|
||||||
// 2. Typography ----------------------------------------------------------------------------------
|
|
||||||
@at-font-size: 12px;
|
|
||||||
@at-font-size-2x: 13px;
|
|
||||||
@at-font-size-3x: 14px;
|
|
||||||
@at-font-size-4x: 16px;
|
|
||||||
|
|
||||||
@at-font-weight: 400;
|
|
||||||
@at-font-weight-2x: 700;
|
|
||||||
@at-font-weight-3x: 900;
|
|
||||||
|
|
||||||
@at-line-height-short: 0.9;
|
|
||||||
@at-line-height-tall: 2;
|
|
||||||
@at-line-height: 24px;
|
|
||||||
|
|
||||||
// 3. Layout --------------------------------------------------------------------------------------
|
|
||||||
@at-space: 3px;
|
|
||||||
@at-space-2x: 4px;
|
|
||||||
@at-space-3x: 5px;
|
|
||||||
@at-space-4x: 10px;
|
|
||||||
@at-space-5x: 15px;
|
|
||||||
@at-space-6x: 20px;
|
|
||||||
|
|
||||||
// 4. Input ---------------------------------------------------------------------------------------
|
|
||||||
@at-input-button-width: 72px;
|
|
||||||
@at-input-height: 30px;
|
|
||||||
|
|
||||||
// 5. Misc ----------------------------------------------------------------------------------------
|
|
||||||
@at-border-radius: 5px;
|
|
||||||
@at-popover-width: 320px;
|
|
||||||
@at-inset-width: 5px;
|
|
||||||
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
// App-wide styles
|
// App-wide styles
|
||||||
@import '_variables';
|
@import '_base-variables';
|
||||||
|
@import '_contextual-variables';
|
||||||
@import '_mixins';
|
@import '_mixins';
|
||||||
@import '_utility';
|
@import '_utility';
|
||||||
@import '_common';
|
@import '_global';
|
||||||
|
|
||||||
// Aggregated component and feature specific styles
|
// Aggregated component and feature specific styles
|
||||||
@import '../components/_index';
|
@import '../components/_index';
|
||||||
|
|||||||
@@ -203,12 +203,12 @@ var tower = angular.module('Tower', [
|
|||||||
])
|
])
|
||||||
.run(['$stateExtender', '$q', '$compile', '$cookies', '$rootScope', '$log', '$stateParams',
|
.run(['$stateExtender', '$q', '$compile', '$cookies', '$rootScope', '$log', '$stateParams',
|
||||||
'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
|
'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer',
|
||||||
'ClearScope', 'LoadConfig', 'Store', 'pendoService', 'Prompt', 'Rest',
|
'LoadConfig', 'Store', 'pendoService', 'Prompt', 'Rest',
|
||||||
'Wait', 'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
|
'Wait', 'ProcessErrors', '$state', 'GetBasePath', 'ConfigService',
|
||||||
'FeaturesService', '$filter', 'SocketService',
|
'FeaturesService', '$filter', 'SocketService',
|
||||||
function($stateExtender, $q, $compile, $cookies, $rootScope, $log, $stateParams,
|
function($stateExtender, $q, $compile, $cookies, $rootScope, $log, $stateParams,
|
||||||
CheckLicense, $location, Authorization, LoadBasePaths, Timer,
|
CheckLicense, $location, Authorization, LoadBasePaths, Timer,
|
||||||
ClearScope, LoadConfig, Store, pendoService, Prompt, Rest, Wait,
|
LoadConfig, Store, pendoService, Prompt, Rest, Wait,
|
||||||
ProcessErrors, $state, GetBasePath, ConfigService, FeaturesService,
|
ProcessErrors, $state, GetBasePath, ConfigService, FeaturesService,
|
||||||
$filter, SocketService) {
|
$filter, SocketService) {
|
||||||
|
|
||||||
@@ -305,6 +305,28 @@ var tower = angular.module('Tower', [
|
|||||||
window.clearInterval($rootScope.jobStdOutInterval);
|
window.clearInterval($rootScope.jobStdOutInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
|
||||||
|
$('#form-modal2 .modal-body').empty();
|
||||||
|
|
||||||
|
$('.tooltip').each(function() {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.popover').each(function() {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.ui-dialog-content').each(function() {
|
||||||
|
$(this).dialog('close');
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
$('#help-modal').dialog('close');
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
// On each navigation request, check that the user is logged in
|
// On each navigation request, check that the user is logged in
|
||||||
if (!/^\/(login|logout)/.test($location.path())) {
|
if (!/^\/(login|logout)/.test($location.path())) {
|
||||||
// capture most recent URL, excluding login/logout
|
// capture most recent URL, excluding login/logout
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
'$scope', '$rootScope', '$state', '$stateParams', '$timeout', '$q', 'Alert', 'ClearScope',
|
'$scope', '$rootScope', '$state', '$stateParams', '$timeout', '$q', 'Alert',
|
||||||
'ConfigurationService', 'ConfigurationUtils', 'CreateDialog', 'CreateSelect2', 'i18n', 'ParseTypeChange', 'ProcessErrors', 'Store',
|
'ConfigurationService', 'ConfigurationUtils', 'CreateDialog', 'CreateSelect2', 'i18n', 'ParseTypeChange', 'ProcessErrors', 'Store',
|
||||||
'Wait', 'configDataResolve', 'ToJSON',
|
'Wait', 'configDataResolve', 'ToJSON',
|
||||||
//Form definitions
|
//Form definitions
|
||||||
@@ -24,7 +24,7 @@ export default [
|
|||||||
'ConfigurationJobsForm',
|
'ConfigurationJobsForm',
|
||||||
'ConfigurationUiForm',
|
'ConfigurationUiForm',
|
||||||
function(
|
function(
|
||||||
$scope, $rootScope, $state, $stateParams, $timeout, $q, Alert, ClearScope,
|
$scope, $rootScope, $state, $stateParams, $timeout, $q, Alert,
|
||||||
ConfigurationService, ConfigurationUtils, CreateDialog, CreateSelect2, i18n, ParseTypeChange, ProcessErrors, Store,
|
ConfigurationService, ConfigurationUtils, CreateDialog, CreateSelect2, i18n, ParseTypeChange, ProcessErrors, Store,
|
||||||
Wait, configDataResolve, ToJSON,
|
Wait, configDataResolve, ToJSON,
|
||||||
//Form definitions
|
//Form definitions
|
||||||
@@ -450,12 +450,39 @@ export default [
|
|||||||
};
|
};
|
||||||
|
|
||||||
var resetAll = function() {
|
var resetAll = function() {
|
||||||
|
var keys = _.keys(formDefs[formTracker.getCurrent()].fields);
|
||||||
|
var payload = {};
|
||||||
|
clearApiErrors();
|
||||||
|
_.each(keys, function(key) {
|
||||||
|
payload[key] = $scope.configDataResolve[key].default;
|
||||||
|
});
|
||||||
|
|
||||||
Wait('start');
|
Wait('start');
|
||||||
ConfigurationService.resetAll()
|
ConfigurationService.patchConfiguration(payload)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
populateFromApi();
|
populateFromApi();
|
||||||
$scope[formTracker.currentFormName()].$setPristine();
|
$scope[formTracker.currentFormName()].$setPristine();
|
||||||
$scope.$broadcast('CUSTOM_LOGO_reverted');
|
|
||||||
|
let keys = _.keys(formDefs[formTracker.getCurrent()].fields);
|
||||||
|
_.each(keys, function(key) {
|
||||||
|
$scope[key] = $scope.configDataResolve[key].default;
|
||||||
|
if($scope[key + '_field'].type === "select"){
|
||||||
|
// We need to re-instantiate the Select2 element
|
||||||
|
// after resetting the value. Example:
|
||||||
|
$scope.$broadcast(key+'_populated', null, false);
|
||||||
|
}
|
||||||
|
else if($scope[key + '_field'].reset === "CUSTOM_LOGO"){
|
||||||
|
$scope.$broadcast(key+'_reverted');
|
||||||
|
}
|
||||||
|
else if($scope[key + '_field'].type === "textarea" && _.isArray($scope.configDataResolve[key].default)){
|
||||||
|
$scope[key] = ConfigurationUtils.arrayToList($scope[key], key);
|
||||||
|
}
|
||||||
|
else if($scope[key + '_field'].hasOwnProperty('codeMirror')){
|
||||||
|
$scope[key] = '{}';
|
||||||
|
$scope.$broadcast('codeMirror_populated', key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
ProcessErrors($scope, error, status, formDefs[formTracker.getCurrent()],
|
ProcessErrors($scope, error, status, formDefs[formTracker.getCurrent()],
|
||||||
|
|||||||
@@ -68,21 +68,6 @@ export default ['$rootScope', 'GetBasePath', 'ProcessErrors', '$q', '$http', 'Re
|
|||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
},
|
|
||||||
|
|
||||||
resetAll: function() {
|
|
||||||
var deferred = $q.defer();
|
|
||||||
|
|
||||||
Rest.setUrl(url);
|
|
||||||
Rest.destroy()
|
|
||||||
.success(function(data) {
|
|
||||||
deferred.resolve(data);
|
|
||||||
})
|
|
||||||
.error(function(error) {
|
|
||||||
deferred.reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -61,10 +61,18 @@ export default ['$rootScope', '$scope', 'Wait', 'CredentialTypesList',
|
|||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function() {
|
.success(function() {
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.credential_types.length === 1 && $state.params.credential_type_search && !_.isEmpty($state.params.credential_type_search.page) && $state.params.credential_type_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.credential_type_search.page = (parseInt(reloadListStateParams.credential_type_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.credential_type_id) === id) {
|
if (parseInt($state.params.credential_type_id) === id) {
|
||||||
$state.go('^', null, { reload: true });
|
$state.go('^', reloadListStateParams, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
$state.go('.', null, { reload: true });
|
$state.go('.', reloadListStateParams, { reload: true });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
|
|||||||
@@ -4,14 +4,12 @@
|
|||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ClearScope',
|
export default ['$scope', 'Rest', 'CredentialList', 'Prompt',
|
||||||
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'i18n',
|
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter', 'rbacUiControlService', 'Dataset', 'i18n',
|
||||||
function($scope, Rest, CredentialList, Prompt, ClearScope,
|
function($scope, Rest, CredentialList, Prompt,
|
||||||
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset,
|
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset,
|
||||||
i18n) {
|
i18n) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var list = CredentialList,
|
var list = CredentialList,
|
||||||
defaultUrl = GetBasePath('credentials');
|
defaultUrl = GetBasePath('credentials');
|
||||||
|
|
||||||
@@ -76,10 +74,18 @@ export default ['$scope', 'Rest', 'CredentialList', 'Prompt', 'ClearScope',
|
|||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function() {
|
.success(function() {
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.credentials.length === 1 && $state.params.credential_search && !_.isEmpty($state.params.credential_search.page) && $state.params.credential_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.credential_search.page = (parseInt(reloadListStateParams.credential_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.credential_id) === id) {
|
if (parseInt($state.params.credential_id) === id) {
|
||||||
$state.go("^", null, { reload: true });
|
$state.go("^", reloadListStateParams, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
$state.go('.', null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,11 +5,9 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', '$rootScope','Wait',
|
export default ['$scope', '$rootScope','Wait',
|
||||||
'ClearScope', 'Rest', 'GetBasePath', 'ProcessErrors', 'graphData',
|
'Rest', 'GetBasePath', 'ProcessErrors', 'graphData',
|
||||||
function($scope, $rootScope, Wait,
|
function($scope, $rootScope, Wait,
|
||||||
ClearScope, Rest, GetBasePath, ProcessErrors, graphData) {
|
Rest, GetBasePath, ProcessErrors, graphData) {
|
||||||
|
|
||||||
ClearScope('home');
|
|
||||||
|
|
||||||
var dataCount = 0;
|
var dataCount = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -68,31 +68,6 @@ function HostsList($scope, HostsList, $rootScope, GetBasePath,
|
|||||||
$scope.goToInsights = function(id){
|
$scope.goToInsights = function(id){
|
||||||
$state.go('hosts.edit.insights', {host_id:id});
|
$state.go('hosts.edit.insights', {host_id:id});
|
||||||
};
|
};
|
||||||
$scope.deleteHost = function(id, name){
|
|
||||||
var body = '<div class=\"Prompt-bodyQuery\">Are you sure you want to permanently delete the host below from the inventory?</div><div class=\"Prompt-bodyTarget\">' + $filter('sanitize')(name) + '</div>';
|
|
||||||
var action = function(){
|
|
||||||
delete $rootScope.promptActionBtnClass;
|
|
||||||
Wait('start');
|
|
||||||
HostsService.delete(id).then(() => {
|
|
||||||
$('#prompt-modal').modal('hide');
|
|
||||||
if (parseInt($state.params.host_id) === id) {
|
|
||||||
$state.go("hosts", null, {reload: true});
|
|
||||||
} else {
|
|
||||||
$state.go($state.current.name, null, {reload: true});
|
|
||||||
}
|
|
||||||
Wait('stop');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// Prompt depends on having $rootScope.promptActionBtnClass available...
|
|
||||||
Prompt({
|
|
||||||
hdr: 'Delete Host',
|
|
||||||
body: body,
|
|
||||||
action: action,
|
|
||||||
actionText: 'DELETE',
|
|
||||||
});
|
|
||||||
$rootScope.promptActionBtnClass = 'Modal-errorButton';
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.toggleHost = function(event, host) {
|
$scope.toggleHost = function(event, host) {
|
||||||
try {
|
try {
|
||||||
$(event.target).tooltip('hide');
|
$(event.target).tooltip('hide');
|
||||||
|
|||||||
@@ -70,7 +70,15 @@
|
|||||||
|
|
||||||
$('#host-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
$('#host-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
||||||
$('#host-disassociate-modal').off('hidden.bs.modal');
|
$('#host-disassociate-modal').off('hidden.bs.modal');
|
||||||
$state.go('.', null, {reload: true});
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.groups.length === 1 && $state.params.group_search && !_.isEmpty($state.params.group_search.page) && $state.params.group_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.group_search.page = (parseInt(reloadListStateParams.group_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
GroupsService.disassociateHost(host.id, $scope.disassociateGroup.id).then(() => {
|
GroupsService.disassociateHost(host.id, $scope.disassociateGroup.id).then(() => {
|
||||||
|
|||||||
@@ -11,11 +11,9 @@
|
|||||||
*/
|
*/
|
||||||
function adhocController($q, $scope, $stateParams,
|
function adhocController($q, $scope, $stateParams,
|
||||||
$state, CheckPasswords, PromptForPasswords, CreateLaunchDialog, CreateSelect2, adhocForm,
|
$state, CheckPasswords, PromptForPasswords, CreateLaunchDialog, CreateSelect2, adhocForm,
|
||||||
GenerateForm, Rest, ProcessErrors, ClearScope, GetBasePath, GetChoices,
|
GenerateForm, Rest, ProcessErrors, GetBasePath, GetChoices,
|
||||||
KindChange, Wait, ParseTypeChange) {
|
KindChange, Wait, ParseTypeChange) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
// this is done so that we can access private functions for testing, but
|
// this is done so that we can access private functions for testing, but
|
||||||
// we don't want to populate the "public" scope with these internal
|
// we don't want to populate the "public" scope with these internal
|
||||||
// functions
|
// functions
|
||||||
@@ -302,6 +300,6 @@ function adhocController($q, $scope, $stateParams,
|
|||||||
|
|
||||||
export default ['$q', '$scope', '$stateParams',
|
export default ['$q', '$scope', '$stateParams',
|
||||||
'$state', 'CheckPasswords', 'PromptForPasswords', 'CreateLaunchDialog', 'CreateSelect2',
|
'$state', 'CheckPasswords', 'PromptForPasswords', 'CreateLaunchDialog', 'CreateSelect2',
|
||||||
'adhocForm', 'GenerateForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath',
|
'adhocForm', 'GenerateForm', 'Rest', 'ProcessErrors', 'GetBasePath',
|
||||||
'GetChoices', 'KindChange', 'Wait', 'ParseTypeChange',
|
'GetChoices', 'KindChange', 'Wait', 'ParseTypeChange',
|
||||||
adhocController];
|
adhocController];
|
||||||
|
|||||||
@@ -9,7 +9,12 @@ export default {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
activityStream: true,
|
activityStream: true,
|
||||||
activityStreamTarget: 'inventory'
|
activityStreamTarget: 'inventory',
|
||||||
|
socket: {
|
||||||
|
"groups": {
|
||||||
|
"inventories": ["status_changed"]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
views: {
|
views: {
|
||||||
'@': {
|
'@': {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default ['i18n', function(i18n) {
|
|||||||
hover: true,
|
hover: true,
|
||||||
basePath: 'inventory',
|
basePath: 'inventory',
|
||||||
title: false,
|
title: false,
|
||||||
|
disableRow: "{{ inventory.pending_deletion }}",
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
status: {
|
status: {
|
||||||
@@ -27,7 +28,7 @@ export default ['i18n', function(i18n) {
|
|||||||
ngClick: "null",
|
ngClick: "null",
|
||||||
iconOnly: true,
|
iconOnly: true,
|
||||||
excludeModal: true,
|
excludeModal: true,
|
||||||
template: `<source-summary-popover inventory="inventory" ng-if="inventory.kind === ''"></source-summary-popover><host-summary-popover inventory="inventory" ng-class="{'HostSummaryPopover-noSourceSummary': inventory.kind !== ''}"></host-summary-popover>`,
|
template: `<source-summary-popover inventory="inventory" ng-hide="inventory.pending_deletion" ng-if="inventory.kind === ''"></source-summary-popover><host-summary-popover inventory="inventory" ng-hide="inventory.pending_deletion" ng-class="{'HostSummaryPopover-noSourceSummary': inventory.kind !== ''}"></host-summary-popover>`,
|
||||||
icons: [{
|
icons: [{
|
||||||
icon: "{{ 'icon-cloud-' + inventory.syncStatus }}",
|
icon: "{{ 'icon-cloud-' + inventory.syncStatus }}",
|
||||||
awToolTip: "{{ inventory.syncTip }}",
|
awToolTip: "{{ inventory.syncTip }}",
|
||||||
@@ -97,7 +98,8 @@ export default ['i18n', function(i18n) {
|
|||||||
ngClick: 'editInventory(inventory)',
|
ngClick: 'editInventory(inventory)',
|
||||||
awToolTip: i18n._('Edit inventory'),
|
awToolTip: i18n._('Edit inventory'),
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
ngShow: 'inventory.summary_fields.user_capabilities.edit'
|
ngShow: 'inventory.summary_fields.user_capabilities.edit',
|
||||||
|
ngHide: 'inventory.pending_deletion'
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
label: i18n._('View'),
|
label: i18n._('View'),
|
||||||
@@ -111,7 +113,12 @@ export default ['i18n', function(i18n) {
|
|||||||
ngClick: "deleteInventory(inventory.id, inventory.name)",
|
ngClick: "deleteInventory(inventory.id, inventory.name)",
|
||||||
awToolTip: i18n._('Delete inventory'),
|
awToolTip: i18n._('Delete inventory'),
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
ngShow: 'inventory.summary_fields.user_capabilities.delete'
|
ngShow: 'inventory.summary_fields.user_capabilities.delete',
|
||||||
|
ngHide: 'inventory.pending_deletion'
|
||||||
|
|
||||||
|
},
|
||||||
|
pending_deletion: {
|
||||||
|
label: i18n._('Pending Delete'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};}];
|
};}];
|
||||||
|
|||||||
@@ -86,12 +86,7 @@ function InventoriesList($scope,
|
|||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function () {
|
.success(function () {
|
||||||
if (parseInt($state.params.inventory_id) === id) {
|
Wait('stop');
|
||||||
$state.go("^", null, {reload: true});
|
|
||||||
} else {
|
|
||||||
$state.go('.', null, {reload: true});
|
|
||||||
Wait('stop');
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
ProcessErrors( $scope, data, status, null, { hdr: 'Error!',
|
ProcessErrors( $scope, data, status, null, { hdr: 'Error!',
|
||||||
@@ -102,11 +97,33 @@ function InventoriesList($scope,
|
|||||||
|
|
||||||
Prompt({
|
Prompt({
|
||||||
hdr: 'Delete',
|
hdr: 'Delete',
|
||||||
body: '<div class="Prompt-bodyQuery">Are you sure you want to delete the inventory below?</div><div class="Prompt-bodyTarget">' + $filter('sanitize')(name) + '</div>',
|
body: '<div class="Prompt-bodyQuery">Are you sure you want to delete the inventory below?</div><div class="Prompt-bodyTarget">' + $filter('sanitize')(name) + '</div>' +
|
||||||
|
'<div class="Prompt-bodyNote"><span class="Prompt-bodyNote--emphasis">Note:</span> The inventory will be in a pending status until the final delete is processed.</div>',
|
||||||
action: action,
|
action: action,
|
||||||
actionText: 'DELETE'
|
actionText: 'DELETE'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.$on(`ws-inventories`, function(e, data){
|
||||||
|
let inventory = $scope.inventories.find((inventory) => inventory.id === data.inventory_id);
|
||||||
|
if (data.status === 'pending_deletion') {
|
||||||
|
inventory.pending_deletion = true;
|
||||||
|
}
|
||||||
|
if (data.status === 'deleted') {
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.inventories.length === 1 && $state.params.inventory_search && !_.isEmpty($state.params.inventory_search.page) && $state.params.inventory_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.inventory_search.page = (parseInt(reloadListStateParams.inventory_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseInt($state.params.inventory_id) === data.inventory_id) {
|
||||||
|
$state.go("^", reloadListStateParams, {reload: true});
|
||||||
|
} else {
|
||||||
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ['$scope',
|
export default ['$scope',
|
||||||
|
|||||||
@@ -100,14 +100,21 @@
|
|||||||
$state.go('.', null, {reload: true});
|
$state.go('.', null, {reload: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.groups.length === 1 && $state.params.group_search && !_.isEmpty($state.params.group_search.page) && $state.params.group_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.group_search.page = (parseInt(reloadListStateParams.group_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
switch($scope.deleteOption){
|
switch($scope.deleteOption){
|
||||||
case 'promote':
|
case 'promote':
|
||||||
GroupsService.promote($scope.toDelete.id, $stateParams.inventory_id)
|
GroupsService.promote($scope.toDelete.id, $stateParams.inventory_id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (parseInt($state.params.group_id) === $scope.toDelete.id) {
|
if (parseInt($state.params.group_id) === $scope.toDelete.id) {
|
||||||
$state.go("^", null, {reload: true});
|
$state.go("^", reloadListStateParams, {reload: true});
|
||||||
} else {
|
} else {
|
||||||
$state.go($state.current, null, {reload: true});
|
$state.go($state.current, reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
$('#group-delete-modal').modal('hide');
|
$('#group-delete-modal').modal('hide');
|
||||||
$('body').removeClass('modal-open');
|
$('body').removeClass('modal-open');
|
||||||
@@ -117,9 +124,9 @@
|
|||||||
default:
|
default:
|
||||||
GroupsService.delete($scope.toDelete.id).then(() => {
|
GroupsService.delete($scope.toDelete.id).then(() => {
|
||||||
if (parseInt($state.params.group_id) === $scope.toDelete.id) {
|
if (parseInt($state.params.group_id) === $scope.toDelete.id) {
|
||||||
$state.go("^", null, {reload: true});
|
$state.go("^", reloadListStateParams, {reload: true});
|
||||||
} else {
|
} else {
|
||||||
$state.go($state.current, null, {reload: true});
|
$state.go($state.current, reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
$('#group-delete-modal').modal('hide');
|
$('#group-delete-modal').modal('hide');
|
||||||
$('body').removeClass('modal-open');
|
$('body').removeClass('modal-open');
|
||||||
|
|||||||
@@ -87,8 +87,16 @@
|
|||||||
$('#group-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
$('#group-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
||||||
// Remove the event handler so that we don't end up with multiple bindings
|
// Remove the event handler so that we don't end up with multiple bindings
|
||||||
$('#group-disassociate-modal').off('hidden.bs.modal');
|
$('#group-disassociate-modal').off('hidden.bs.modal');
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.nested_groups.length === 1 && $state.params.nested_group_search && !_.isEmpty($state.params.nested_group_search.page) && $state.params.nested_group_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.nested_group_search.page = (parseInt(reloadListStateParams.nested_group_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
// Reload the inventory manage page and show that the group has been removed
|
// Reload the inventory manage page and show that the group has been removed
|
||||||
$state.go('.', null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
let closeModal = function(){
|
let closeModal = function(){
|
||||||
|
|||||||
@@ -100,8 +100,16 @@ export default ['$scope', 'NestedHostsListDefinition', '$rootScope', 'GetBasePat
|
|||||||
$('#host-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
$('#host-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
||||||
// Remove the event handler so that we don't end up with multiple bindings
|
// Remove the event handler so that we don't end up with multiple bindings
|
||||||
$('#host-disassociate-modal').off('hidden.bs.modal');
|
$('#host-disassociate-modal').off('hidden.bs.modal');
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.nested_hosts.length === 1 && $state.params.nested_host_search && !_.isEmpty($state.params.nested_host_search.page) && $state.params.nested_host_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.nested_host_search.page = (parseInt(reloadListStateParams.nested_host_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
// Reload the inventory manage page and show that the group has been removed
|
// Reload the inventory manage page and show that the group has been removed
|
||||||
$state.go('.', null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
let closeModal = function(){
|
let closeModal = function(){
|
||||||
|
|||||||
@@ -96,10 +96,18 @@ export default ['$scope', 'ListDefinition', '$rootScope', 'GetBasePath',
|
|||||||
Wait('start');
|
Wait('start');
|
||||||
HostsService.delete(id).then(() => {
|
HostsService.delete(id).then(() => {
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.hosts.length === 1 && $state.params.host_search && !_.isEmpty($state.params.host_search.page) && $state.params.host_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.host_search.page = (parseInt(reloadListStateParams.host_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.host_id) === id) {
|
if (parseInt($state.params.host_id) === id) {
|
||||||
$state.go("hosts", null, {reload: true});
|
$state.go('^', reloadListStateParams, {reload: true});
|
||||||
} else {
|
} else {
|
||||||
$state.go($state.current.name, null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -83,8 +83,16 @@
|
|||||||
$('#group-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
$('#group-disassociate-modal').off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
||||||
// Remove the event handler so that we don't end up with multiple bindings
|
// Remove the event handler so that we don't end up with multiple bindings
|
||||||
$('#group-disassociate-modal').off('hidden.bs.modal');
|
$('#group-disassociate-modal').off('hidden.bs.modal');
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.nested_groups.length === 1 && $state.params.nested_group_search && !_.isEmpty($state.params.nested_group_search.page) && $state.params.nested_group_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.nested_group_search.page = (parseInt(reloadListStateParams.nested_group_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
// Reload the inventory manage page and show that the group has been removed
|
// Reload the inventory manage page and show that the group has been removed
|
||||||
$state.go('.', null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
let closeModal = function(){
|
let closeModal = function(){
|
||||||
|
|||||||
@@ -123,10 +123,16 @@
|
|||||||
Wait('start');
|
Wait('start');
|
||||||
SourcesService.delete(inventory_source.id).then(() => {
|
SourcesService.delete(inventory_source.id).then(() => {
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.inventory_sources.length === 1 && $state.params.inventory_source_search && !_.isEmpty($state.params.inventory_source_search.page) && $state.params.inventory_source_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.inventory_source_search.page = (parseInt(reloadListStateParams.inventory_source_search.page)-1).toString();
|
||||||
|
}
|
||||||
if (parseInt($state.params.inventory_source_id) === inventory_source.id) {
|
if (parseInt($state.params.inventory_source_id) === inventory_source.id) {
|
||||||
$state.go("inventories.edit.inventory_sources", {inventory_id: $scope.inventory_id}, {reload: true});
|
$state.go('^', reloadListStateParams, {reload: true});
|
||||||
} else {
|
} else {
|
||||||
$state.go($state.current.name, null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,13 +12,11 @@
|
|||||||
|
|
||||||
function SmartInventoryAdd($scope, $location,
|
function SmartInventoryAdd($scope, $location,
|
||||||
GenerateForm, smartInventoryForm, rbacUiControlService, Rest, Alert, ProcessErrors,
|
GenerateForm, smartInventoryForm, rbacUiControlService, Rest, Alert, ProcessErrors,
|
||||||
ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON,
|
GetBasePath, ParseTypeChange, Wait, ToJSON,
|
||||||
$state, canAdd) {
|
$state, canAdd) {
|
||||||
|
|
||||||
$scope.canAdd = canAdd;
|
$scope.canAdd = canAdd;
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
// Inject dynamic view
|
// Inject dynamic view
|
||||||
var defaultUrl = GetBasePath('inventory'),
|
var defaultUrl = GetBasePath('inventory'),
|
||||||
form = smartInventoryForm;
|
form = smartInventoryForm;
|
||||||
@@ -90,6 +88,6 @@ function SmartInventoryAdd($scope, $location,
|
|||||||
|
|
||||||
export default ['$scope', '$location',
|
export default ['$scope', '$location',
|
||||||
'GenerateForm', 'smartInventoryForm', 'rbacUiControlService', 'Rest', 'Alert',
|
'GenerateForm', 'smartInventoryForm', 'rbacUiControlService', 'Rest', 'Alert',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange',
|
'ProcessErrors', 'GetBasePath', 'ParseTypeChange',
|
||||||
'Wait', 'ToJSON', '$state', 'canAdd', SmartInventoryAdd
|
'Wait', 'ToJSON', '$state', 'canAdd', SmartInventoryAdd
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
function SmartInventoryEdit($scope, $location,
|
function SmartInventoryEdit($scope, $location,
|
||||||
$stateParams, InventoryForm, Rest, ProcessErrors,
|
$stateParams, InventoryForm, Rest, ProcessErrors,
|
||||||
ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON,
|
GetBasePath, ParseTypeChange, Wait, ToJSON,
|
||||||
ParseVariableString, $state, OrgAdminLookup, resourceData, $rootScope) {
|
ParseVariableString, $state, OrgAdminLookup, resourceData, $rootScope) {
|
||||||
|
|
||||||
// Inject dynamic view
|
// Inject dynamic view
|
||||||
@@ -14,12 +14,9 @@ function SmartInventoryEdit($scope, $location,
|
|||||||
form = InventoryForm,
|
form = InventoryForm,
|
||||||
inventory_id = $stateParams.smartinventory_id,
|
inventory_id = $stateParams.smartinventory_id,
|
||||||
inventoryData = resourceData.data;
|
inventoryData = resourceData.data;
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
ClearScope();
|
|
||||||
form.formLabelSize = null;
|
form.formLabelSize = null;
|
||||||
form.formFieldSize = null;
|
form.formFieldSize = null;
|
||||||
$scope.inventory_id = inventory_id;
|
$scope.inventory_id = inventory_id;
|
||||||
@@ -97,7 +94,7 @@ function SmartInventoryEdit($scope, $location,
|
|||||||
|
|
||||||
export default [ '$scope', '$location',
|
export default [ '$scope', '$location',
|
||||||
'$stateParams', 'InventoryForm', 'Rest',
|
'$stateParams', 'InventoryForm', 'Rest',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', 'Wait',
|
'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'Wait',
|
||||||
'ToJSON', 'ParseVariableString',
|
'ToJSON', 'ParseVariableString',
|
||||||
'$state', 'OrgAdminLookup', 'resourceData', '$rootScope', SmartInventoryEdit
|
'$state', 'OrgAdminLookup', 'resourceData', '$rootScope', SmartInventoryEdit
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -12,13 +12,11 @@
|
|||||||
|
|
||||||
function InventoriesAdd($scope, $location,
|
function InventoriesAdd($scope, $location,
|
||||||
GenerateForm, InventoryForm, rbacUiControlService, Rest, Alert, ProcessErrors,
|
GenerateForm, InventoryForm, rbacUiControlService, Rest, Alert, ProcessErrors,
|
||||||
ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON,
|
GetBasePath, ParseTypeChange, Wait, ToJSON,
|
||||||
$state, canAdd, CreateSelect2, InstanceGroupsService) {
|
$state, canAdd, CreateSelect2, InstanceGroupsService) {
|
||||||
|
|
||||||
$scope.canAdd = canAdd;
|
$scope.canAdd = canAdd;
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
// Inject dynamic view
|
// Inject dynamic view
|
||||||
var defaultUrl = GetBasePath('inventory'),
|
var defaultUrl = GetBasePath('inventory'),
|
||||||
form = InventoryForm;
|
form = InventoryForm;
|
||||||
@@ -96,6 +94,6 @@ function InventoriesAdd($scope, $location,
|
|||||||
|
|
||||||
export default ['$scope', '$location',
|
export default ['$scope', '$location',
|
||||||
'GenerateForm', 'InventoryForm', 'rbacUiControlService', 'Rest', 'Alert',
|
'GenerateForm', 'InventoryForm', 'rbacUiControlService', 'Rest', 'Alert',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange',
|
'ProcessErrors', 'GetBasePath', 'ParseTypeChange',
|
||||||
'Wait', 'ToJSON', '$state','canAdd', 'CreateSelect2', 'InstanceGroupsService', InventoriesAdd
|
'Wait', 'ToJSON', '$state','canAdd', 'CreateSelect2', 'InstanceGroupsService', InventoriesAdd
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
function InventoriesEdit($scope, $location,
|
function InventoriesEdit($scope, $location,
|
||||||
$stateParams, InventoryForm, Rest, ProcessErrors,
|
$stateParams, InventoryForm, Rest, ProcessErrors,
|
||||||
ClearScope, GetBasePath, ParseTypeChange, Wait, ToJSON,
|
GetBasePath, ParseTypeChange, Wait, ToJSON,
|
||||||
ParseVariableString, $state, OrgAdminLookup, $rootScope, resourceData, CreateSelect2, InstanceGroupsService, InstanceGroupsData) {
|
ParseVariableString, $state, OrgAdminLookup, $rootScope, resourceData, CreateSelect2, InstanceGroupsService, InstanceGroupsData) {
|
||||||
|
|
||||||
// Inject dynamic view
|
// Inject dynamic view
|
||||||
@@ -111,7 +111,7 @@ function InventoriesEdit($scope, $location,
|
|||||||
|
|
||||||
export default ['$scope', '$location',
|
export default ['$scope', '$location',
|
||||||
'$stateParams', 'InventoryForm', 'Rest',
|
'$stateParams', 'InventoryForm', 'Rest',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ParseTypeChange', 'Wait',
|
'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'Wait',
|
||||||
'ToJSON', 'ParseVariableString',
|
'ToJSON', 'ParseVariableString',
|
||||||
'$state', 'OrgAdminLookup', '$rootScope', 'resourceData', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData', InventoriesEdit,
|
'$state', 'OrgAdminLookup', '$rootScope', 'resourceData', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData', InventoriesEdit,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ function(i18n, InventoryCompletedJobsList) {
|
|||||||
sourceModel: 'insights_credential',
|
sourceModel: 'insights_credential',
|
||||||
sourceField: 'name',
|
sourceField: 'name',
|
||||||
search: {
|
search: {
|
||||||
credential_type: 13 //insights
|
credential_type: '13' //insights
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
instance_groups: {
|
instance_groups: {
|
||||||
@@ -201,7 +201,7 @@ function(i18n, InventoryCompletedJobsList) {
|
|||||||
relatedButtons: {
|
relatedButtons: {
|
||||||
remediate_inventory: {
|
remediate_inventory: {
|
||||||
ngClick: 'remediateInventory(id, name, insights_credential)',
|
ngClick: 'remediateInventory(id, name, insights_credential)',
|
||||||
ngShow: 'insights_credential!==null',
|
ngShow: 'insights_credential!==null && mode !== "add"',
|
||||||
label: i18n._('Remediate Inventory'),
|
label: i18n._('Remediate Inventory'),
|
||||||
class: 'Form-primaryButton'
|
class: 'Form-primaryButton'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,10 +51,18 @@ export default ['$rootScope', '$scope', 'Wait', 'InventoryScriptsList',
|
|||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function() {
|
.success(function() {
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.inventory_scripts.length === 1 && $state.params.inventory_script_search && !_.isEmpty($state.params.inventory_script_search.page) && $state.params.inventory_script_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.inventory_script_search.page = (parseInt(reloadListStateParams.inventory_script_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.inventory_script_id) === id) {
|
if (parseInt($state.params.inventory_script_id) === id) {
|
||||||
$state.go('^', null, { reload: true });
|
$state.go('^', reloadListStateParams, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
$state.go('.', null, { reload: true });
|
$state.go('.', reloadListStateParams, { reload: true });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
|
|||||||
@@ -70,7 +70,14 @@ export default
|
|||||||
scope.$emit(callback, action_label);
|
scope.$emit(callback, action_label);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$state.reload();
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if(scope.jobs.length === 1 && $state.params.job_search && !_.isEmpty($state.params.job_search.page) && $state.params.job_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.job_search.page = (parseInt(reloadListStateParams.job_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,14 +11,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export default ['$state', '$rootScope', '$scope', '$stateParams',
|
export default ['$state', '$rootScope', '$scope', '$stateParams',
|
||||||
'ClearScope', 'Find', 'DeleteJob', 'RelaunchJob',
|
'Find', 'DeleteJob', 'RelaunchJob',
|
||||||
'GetBasePath', 'Dataset', 'QuerySet', 'ListDefinition', '$interpolate',
|
'GetBasePath', 'Dataset', 'QuerySet', 'ListDefinition', '$interpolate',
|
||||||
function($state, $rootScope, $scope, $stateParams,
|
function($state, $rootScope, $scope, $stateParams,
|
||||||
ClearScope, Find, DeleteJob, RelaunchJob,
|
Find, DeleteJob, RelaunchJob,
|
||||||
GetBasePath, Dataset, qs, ListDefinition, $interpolate) {
|
GetBasePath, Dataset, qs, ListDefinition, $interpolate) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var list = ListDefinition;
|
var list = ListDefinition;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ import authenticationController from './loginModal.controller';
|
|||||||
/* jshint unused: vars */
|
/* jshint unused: vars */
|
||||||
export default
|
export default
|
||||||
[ 'templateUrl',
|
[ 'templateUrl',
|
||||||
'ClearScope',
|
|
||||||
'Wait',
|
'Wait',
|
||||||
function(templateUrl, ClearScope, Wait) {
|
function(templateUrl, Wait) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: true,
|
scope: true,
|
||||||
@@ -19,7 +18,6 @@ export default
|
|||||||
link: function(scope, element, attrs) {
|
link: function(scope, element, attrs) {
|
||||||
var setLoginFocus = function () {
|
var setLoginFocus = function () {
|
||||||
// Need to clear out any open dialog windows that might be open when this modal opens.
|
// Need to clear out any open dialog windows that might be open when this modal opens.
|
||||||
ClearScope();
|
|
||||||
$('#login-username').focus();
|
$('#login-username').focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -165,10 +165,18 @@
|
|||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function() {
|
.success(function() {
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.notification_templates.length === 1 && $state.params.notification_template_search && !_.isEmpty($state.params.notification_template_search.page) && $state.params.notification_template_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.notification_template_search.page = (parseInt(reloadListStateParams.notification_template_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.notification_template_id) === id) {
|
if (parseInt($state.params.notification_template_id) === id) {
|
||||||
$state.go("^", null, { reload: true });
|
$state.go("^", reloadListStateParams, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
$state.go('.', null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
export default ['$scope', '$rootScope', '$location', '$stateParams',
|
export default ['$scope', '$rootScope', '$location', '$stateParams',
|
||||||
'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
|
'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', 'CreateSelect2', '$state','InstanceGroupsService',
|
'ProcessErrors', 'GetBasePath', 'Wait', 'CreateSelect2', '$state','InstanceGroupsService',
|
||||||
function($scope, $rootScope, $location, $stateParams, OrganizationForm,
|
function($scope, $rootScope, $location, $stateParams, OrganizationForm,
|
||||||
GenerateForm, Rest, Alert, ProcessErrors, ClearScope, GetBasePath, Wait, CreateSelect2, $state, InstanceGroupsService) {
|
GenerateForm, Rest, Alert, ProcessErrors, GetBasePath, Wait, CreateSelect2, $state, InstanceGroupsService) {
|
||||||
|
|
||||||
Rest.setUrl(GetBasePath('organizations'));
|
Rest.setUrl(GetBasePath('organizations'));
|
||||||
Rest.options()
|
Rest.options()
|
||||||
@@ -19,8 +19,6 @@ export default ['$scope', '$rootScope', '$location', '$stateParams',
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var form = OrganizationForm(),
|
var form = OrganizationForm(),
|
||||||
base = $location.path().replace(/^\//, '').split('/')[0];
|
base = $location.path().replace(/^\//, '').split('/')[0];
|
||||||
init();
|
init();
|
||||||
|
|||||||
@@ -5,14 +5,12 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', '$location', '$stateParams',
|
export default ['$scope', '$location', '$stateParams',
|
||||||
'OrganizationForm', 'Rest', 'ProcessErrors', 'Prompt', 'ClearScope',
|
'OrganizationForm', 'Rest', 'ProcessErrors', 'Prompt',
|
||||||
'GetBasePath', 'Wait', '$state', 'ToggleNotification', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData',
|
'GetBasePath', 'Wait', '$state', 'ToggleNotification', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData',
|
||||||
function($scope, $location, $stateParams,
|
function($scope, $location, $stateParams,
|
||||||
OrganizationForm, Rest, ProcessErrors, Prompt, ClearScope,
|
OrganizationForm, Rest, ProcessErrors, Prompt,
|
||||||
GetBasePath, Wait, $state, ToggleNotification, CreateSelect2, InstanceGroupsService, InstanceGroupsData) {
|
GetBasePath, Wait, $state, ToggleNotification, CreateSelect2, InstanceGroupsService, InstanceGroupsData) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
let form = OrganizationForm(),
|
let form = OrganizationForm(),
|
||||||
defaultUrl = GetBasePath('organizations'),
|
defaultUrl = GetBasePath('organizations'),
|
||||||
base = $location.path().replace(/^\//, '').split('/')[0],
|
base = $location.path().replace(/^\//, '').split('/')[0],
|
||||||
|
|||||||
@@ -6,14 +6,12 @@
|
|||||||
|
|
||||||
|
|
||||||
export default ['$stateParams', '$scope', '$rootScope',
|
export default ['$stateParams', '$scope', '$rootScope',
|
||||||
'Rest', 'OrganizationList', 'Prompt', 'ClearScope',
|
'Rest', 'OrganizationList', 'Prompt',
|
||||||
'ProcessErrors', 'GetBasePath', 'Wait', '$state', 'rbacUiControlService', '$filter', 'Dataset', 'i18n',
|
'ProcessErrors', 'GetBasePath', 'Wait', '$state', 'rbacUiControlService', '$filter', 'Dataset', 'i18n',
|
||||||
function($stateParams, $scope, $rootScope,
|
function($stateParams, $scope, $rootScope,
|
||||||
Rest, OrganizationList, Prompt, ClearScope,
|
Rest, OrganizationList, Prompt,
|
||||||
ProcessErrors, GetBasePath, Wait, $state, rbacUiControlService, $filter, Dataset, i18n) {
|
ProcessErrors, GetBasePath, Wait, $state, rbacUiControlService, $filter, Dataset, i18n) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var defaultUrl = GetBasePath('organizations'),
|
var defaultUrl = GetBasePath('organizations'),
|
||||||
list = OrganizationList;
|
list = OrganizationList;
|
||||||
|
|
||||||
@@ -147,10 +145,18 @@ export default ['$stateParams', '$scope', '$rootScope',
|
|||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function() {
|
.success(function() {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.organizations.length === 1 && $state.params.organization_search && !_.isEmpty($state.params.organization_search.page) && $state.params.organization_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.organization_search.page = (parseInt(reloadListStateParams.organization_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (isDeletedOrganizationBeingEdited(id, parseInt($stateParams.organization_id)) === true) {
|
if (isDeletedOrganizationBeingEdited(id, parseInt($stateParams.organization_id)) === true) {
|
||||||
$state.go('^', null, { reload: true });
|
$state.go('^', reloadListStateParams, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
$state.reload('organizations');
|
$state.go('.', reloadListStateParams, { reload: true });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
|
|||||||
@@ -5,17 +5,15 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest',
|
export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest',
|
||||||
'Alert', 'ProcessErrors', 'GenerateForm', 'Prompt', 'ClearScope',
|
'Alert', 'ProcessErrors', 'GenerateForm', 'Prompt',
|
||||||
'GetBasePath', 'GetProjectPath', 'Authorization', 'GetChoices', 'Empty',
|
'GetBasePath', 'GetProjectPath', 'Authorization', 'GetChoices', 'Empty',
|
||||||
'Wait', 'ProjectUpdate', '$state', 'CreateSelect2', 'ToggleNotification',
|
'Wait', 'ProjectUpdate', '$state', 'CreateSelect2', 'ToggleNotification',
|
||||||
'i18n', 'CredentialTypes',
|
'i18n', 'CredentialTypes',
|
||||||
function($scope, $rootScope, $stateParams, ProjectsForm, Rest, Alert,
|
function($scope, $rootScope, $stateParams, ProjectsForm, Rest, Alert,
|
||||||
ProcessErrors, GenerateForm, Prompt, ClearScope, GetBasePath,
|
ProcessErrors, GenerateForm, Prompt, GetBasePath,
|
||||||
GetProjectPath, Authorization, GetChoices, Empty, Wait, ProjectUpdate,
|
GetProjectPath, Authorization, GetChoices, Empty, Wait, ProjectUpdate,
|
||||||
$state, CreateSelect2, ToggleNotification, i18n, CredentialTypes) {
|
$state, CreateSelect2, ToggleNotification, i18n, CredentialTypes) {
|
||||||
|
|
||||||
ClearScope('htmlTemplate');
|
|
||||||
|
|
||||||
var form = ProjectsForm(),
|
var form = ProjectsForm(),
|
||||||
defaultUrl = GetBasePath('projects') + $stateParams.project_id + '/',
|
defaultUrl = GetBasePath('projects') + $stateParams.project_id + '/',
|
||||||
master = {},
|
master = {},
|
||||||
|
|||||||
@@ -179,10 +179,18 @@ export default ['$scope', '$rootScope', '$log', 'Rest', 'Alert',
|
|||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function() {
|
.success(function() {
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.projects.length === 1 && $state.params.project_search && !_.isEmpty($state.params.project_search.page) && $state.params.project_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.project_search.page = (parseInt(reloadListStateParams.project_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.project_id) === id) {
|
if (parseInt($state.params.project_id) === id) {
|
||||||
$state.go("^", null, { reload: true });
|
$state.go("^", reloadListStateParams, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
$state.go('.', null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
|
|||||||
@@ -25,11 +25,19 @@ export default
|
|||||||
.success(function () {
|
.success(function () {
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
scope.$emit(callback, id);
|
scope.$emit(callback, id);
|
||||||
if (new RegExp('/' + id + '$').test($location.$$url)) {
|
|
||||||
$location.url($location.url().replace(/[/][0-9]+$/, "")); // go to list view
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if(scope.schedules.length === 1 && $state.params.schedule_search && !_.isEmpty($state.params.schedule_search.page) && $state.params.schedule_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.schedule_search.page = (parseInt(reloadListStateParams.schedule_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseInt($state.params.schedule_id) === id) {
|
||||||
|
$state.go('^', reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$state.go('.', null, {reload: true});
|
$state.go('.', reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error(function (data, status) {
|
.error(function (data, status) {
|
||||||
|
|||||||
@@ -13,16 +13,14 @@
|
|||||||
|
|
||||||
export default [
|
export default [
|
||||||
'$scope', '$location', '$stateParams', 'ScheduleList', 'Rest',
|
'$scope', '$location', '$stateParams', 'ScheduleList', 'Rest',
|
||||||
'ClearScope', 'rbacUiControlService',
|
'rbacUiControlService',
|
||||||
'ToggleSchedule', 'DeleteSchedule', '$q', '$state', 'Dataset', 'ParentObject', 'UnifiedJobsOptions',
|
'ToggleSchedule', 'DeleteSchedule', '$q', '$state', 'Dataset', 'ParentObject', 'UnifiedJobsOptions',
|
||||||
function($scope, $location, $stateParams,
|
function($scope, $location, $stateParams,
|
||||||
ScheduleList, Rest, ClearScope,
|
ScheduleList, Rest,
|
||||||
rbacUiControlService,
|
rbacUiControlService,
|
||||||
ToggleSchedule, DeleteSchedule,
|
ToggleSchedule, DeleteSchedule,
|
||||||
$q, $state, Dataset, ParentObject, UnifiedJobsOptions) {
|
$q, $state, Dataset, ParentObject, UnifiedJobsOptions) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var base, scheduleEndpoint,
|
var base, scheduleEndpoint,
|
||||||
list = ScheduleList;
|
list = ScheduleList;
|
||||||
|
|
||||||
|
|||||||
@@ -20,43 +20,6 @@
|
|||||||
export default
|
export default
|
||||||
angular.module('Utilities', ['RestServices', 'Utilities'])
|
angular.module('Utilities', ['RestServices', 'Utilities'])
|
||||||
|
|
||||||
/**
|
|
||||||
* @ngdoc method
|
|
||||||
* @name shared.function:Utilities#ClearScope
|
|
||||||
* @methodOf shared.function:Utilities
|
|
||||||
* @description
|
|
||||||
* Place to remove things that might be lingering from a prior tab or view.
|
|
||||||
* This used to destroy the scope, but that causes issues in angular 1.2.x
|
|
||||||
*/
|
|
||||||
.factory('ClearScope', ['$rootScope', function($rootScope) {
|
|
||||||
return function() {
|
|
||||||
|
|
||||||
$rootScope.flashMessage = null;
|
|
||||||
|
|
||||||
//$('#form-modal .modal-body').empty();
|
|
||||||
$('#form-modal2 .modal-body').empty();
|
|
||||||
|
|
||||||
$('.tooltip').each(function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.popover').each(function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.ui-dialog-content').each(function() {
|
|
||||||
$(this).dialog('close');
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
$('#help-modal').dialog('close');
|
|
||||||
} catch (e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}])
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc method
|
* @ngdoc method
|
||||||
* @name shared.function:Utilities#Empty
|
* @name shared.function:Utilities#Empty
|
||||||
|
|||||||
@@ -272,6 +272,21 @@ function(ConfigurationUtils, i18n, $rootScope) {
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// the disableRow directive disables table row click events
|
||||||
|
.directive('disableRow', function() {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
link: function(scope, element, attrs) {
|
||||||
|
element.bind('click', function(event) {
|
||||||
|
if (attrs.disableRow) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
.directive('awSurveyQuestion', function() {
|
.directive('awSurveyQuestion', function() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ export default ['$compile', 'Attr', 'Icon',
|
|||||||
innerTable += options.mode === 'lookup' ? `<tbody ng-init="selection.${list.iterator} = {id: $parent.${list.iterator}, name: $parent.${list.iterator}_name}">` : `"<tbody>\n"`;
|
innerTable += options.mode === 'lookup' ? `<tbody ng-init="selection.${list.iterator} = {id: $parent.${list.iterator}, name: $parent.${list.iterator}_name}">` : `"<tbody>\n"`;
|
||||||
innerTable += "<tr ng-class=\"[" + list.iterator;
|
innerTable += "<tr ng-class=\"[" + list.iterator;
|
||||||
innerTable += (options.mode === 'lookup' || options.mode === 'select') ? ".success_class" : ".active_class";
|
innerTable += (options.mode === 'lookup' || options.mode === 'select') ? ".success_class" : ".active_class";
|
||||||
|
innerTable += (list.disableRow) ? `, {true: 'List-tableRow--disabled'}[${list.iterator}.pending_deletion]` : "";
|
||||||
|
|
||||||
if (list.multiSelect) {
|
if (list.multiSelect) {
|
||||||
innerTable += ", " + list.iterator + ".isSelected ? 'is-selected-row' : ''";
|
innerTable += ", " + list.iterator + ".isSelected ? 'is-selected-row' : ''";
|
||||||
@@ -300,7 +301,8 @@ export default ['$compile', 'Attr', 'Icon',
|
|||||||
innerTable += "]\" ";
|
innerTable += "]\" ";
|
||||||
innerTable += "id=\"{{ " + list.iterator + ".id }}\" ";
|
innerTable += "id=\"{{ " + list.iterator + ".id }}\" ";
|
||||||
innerTable += "class=\"List-tableRow " + list.iterator + "_class\" ";
|
innerTable += "class=\"List-tableRow " + list.iterator + "_class\" ";
|
||||||
innerTable += "ng-repeat=\"" + list.iterator + " in " + list.name;
|
innerTable += "ng-repeat=\"" + list.iterator + " in " + list.name + "\"";
|
||||||
|
innerTable += (list.disableRow) ? " disable-row=" + list.disableRow + " " : "";
|
||||||
innerTable += (list.trackBy) ? " track by " + list.trackBy : "";
|
innerTable += (list.trackBy) ? " track by " + list.trackBy : "";
|
||||||
innerTable += (list.orderBy) ? " | orderBy:'" + list.orderBy + "'" : "";
|
innerTable += (list.orderBy) ? " | orderBy:'" + list.orderBy + "'" : "";
|
||||||
innerTable += (list.filterBy) ? " | filter: " + list.filterBy : "";
|
innerTable += (list.filterBy) ? " | filter: " + list.filterBy : "";
|
||||||
@@ -379,7 +381,11 @@ export default ['$compile', 'Attr', 'Icon',
|
|||||||
type: 'fieldActions',
|
type: 'fieldActions',
|
||||||
td: false
|
td: false
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
if (field_action === 'pending_deletion') {
|
||||||
|
innerTable += `<a ng-if='${list.iterator}.pending_deletion'>Pending Delete</a>`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
fAction = list.fieldActions[field_action];
|
fAction = list.fieldActions[field_action];
|
||||||
innerTable += "<button id=\"";
|
innerTable += "<button id=\"";
|
||||||
innerTable += (fAction.id) ? fAction.id : field_action + "-action";
|
innerTable += (fAction.id) ? fAction.id : field_action + "-action";
|
||||||
@@ -402,6 +408,7 @@ export default ['$compile', 'Attr', 'Icon',
|
|||||||
innerTable += `ng-class="{'List-editButton--selected' : $stateParams['${list.iterator}_id'] == ${list.iterator}.id}"`;
|
innerTable += `ng-class="{'List-editButton--selected' : $stateParams['${list.iterator}_id'] == ${list.iterator}.id}"`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
innerTable += (fAction.ngDisabled) ? "ng-disabled=\"" + fAction.ngDisabled + "\"" : "";
|
||||||
innerTable += (fAction.awPopOver) ? "aw-pop-over=\"" + fAction.awPopOver + "\" " : "";
|
innerTable += (fAction.awPopOver) ? "aw-pop-over=\"" + fAction.awPopOver + "\" " : "";
|
||||||
innerTable += (fAction.dataPlacement) ? Attr(fAction, 'dataPlacement') : "";
|
innerTable += (fAction.dataPlacement) ? Attr(fAction, 'dataPlacement') : "";
|
||||||
innerTable += (fAction.dataTitle) ? Attr(fAction, 'dataTitle') : "";
|
innerTable += (fAction.dataTitle) ? Attr(fAction, 'dataTitle') : "";
|
||||||
@@ -430,7 +437,6 @@ export default ['$compile', 'Attr', 'Icon',
|
|||||||
}
|
}
|
||||||
|
|
||||||
innerTable += "</tr>\n";
|
innerTable += "</tr>\n";
|
||||||
|
|
||||||
// End List
|
// End List
|
||||||
innerTable += "</tbody>\n";
|
innerTable += "</tbody>\n";
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,16 @@
|
|||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Prompt-bodyNote {
|
||||||
|
margin: 20px 0;
|
||||||
|
color: @default-interface-txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Prompt-bodyNote--emphasis {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: @default-err;
|
||||||
|
}
|
||||||
|
|
||||||
.Prompt-emphasis {
|
.Prompt-emphasis {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|||||||
@@ -11,11 +11,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function JobStdoutController ($rootScope, $scope, $state, $stateParams,
|
export function JobStdoutController ($rootScope, $scope, $state, $stateParams,
|
||||||
ClearScope, GetBasePath, Rest, ProcessErrors, Empty, GetChoices, LookUpName,
|
GetBasePath, Rest, ProcessErrors, Empty, GetChoices, LookUpName,
|
||||||
ParseTypeChange, ParseVariableString, RelaunchJob, DeleteJob, Wait, i18n) {
|
ParseTypeChange, ParseVariableString, RelaunchJob, DeleteJob, Wait, i18n) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var job_id = $stateParams.id,
|
var job_id = $stateParams.id,
|
||||||
jobType = $state.current.data.jobType;
|
jobType = $state.current.data.jobType;
|
||||||
|
|
||||||
@@ -279,6 +277,6 @@ export function JobStdoutController ($rootScope, $scope, $state, $stateParams,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JobStdoutController.$inject = [ '$rootScope', '$scope', '$state',
|
JobStdoutController.$inject = [ '$rootScope', '$scope', '$state',
|
||||||
'$stateParams', 'ClearScope', 'GetBasePath', 'Rest', 'ProcessErrors',
|
'$stateParams', 'GetBasePath', 'Rest', 'ProcessErrors',
|
||||||
'Empty', 'GetChoices', 'LookUpName', 'ParseTypeChange',
|
'Empty', 'GetChoices', 'LookUpName', 'ParseTypeChange',
|
||||||
'ParseVariableString', 'RelaunchJob', 'DeleteJob', 'Wait', 'i18n'];
|
'ParseVariableString', 'RelaunchJob', 'DeleteJob', 'Wait', 'i18n'];
|
||||||
|
|||||||
@@ -5,12 +5,9 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', '$rootScope', 'TeamForm', 'GenerateForm', 'Rest',
|
export default ['$scope', '$rootScope', 'TeamForm', 'GenerateForm', 'Rest',
|
||||||
'Alert', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', '$state',
|
'Alert', 'ProcessErrors', 'GetBasePath', 'Wait', '$state',
|
||||||
function($scope, $rootScope, TeamForm, GenerateForm, Rest, Alert,
|
function($scope, $rootScope, TeamForm, GenerateForm, Rest, Alert,
|
||||||
ProcessErrors, ClearScope, GetBasePath, Wait, $state) {
|
ProcessErrors, GetBasePath, Wait, $state) {
|
||||||
|
|
||||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
|
||||||
//$scope.
|
|
||||||
|
|
||||||
Rest.setUrl(GetBasePath('teams'));
|
Rest.setUrl(GetBasePath('teams'));
|
||||||
Rest.options()
|
Rest.options()
|
||||||
|
|||||||
@@ -5,10 +5,9 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', '$rootScope', '$stateParams', 'TeamForm', 'Rest',
|
export default ['$scope', '$rootScope', '$stateParams', 'TeamForm', 'Rest',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', '$state',
|
'ProcessErrors', 'GetBasePath', 'Wait', '$state',
|
||||||
function($scope, $rootScope, $stateParams, TeamForm, Rest, ProcessErrors,
|
function($scope, $rootScope, $stateParams, TeamForm, Rest, ProcessErrors,
|
||||||
ClearScope, GetBasePath, Wait, $state) {
|
GetBasePath, Wait, $state) {
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var form = TeamForm,
|
var form = TeamForm,
|
||||||
id = $stateParams.team_id,
|
id = $stateParams.team_id,
|
||||||
|
|||||||
@@ -4,14 +4,12 @@
|
|||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', 'Rest', 'TeamList', 'Prompt', 'ClearScope',
|
export default ['$scope', 'Rest', 'TeamList', 'Prompt',
|
||||||
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
|
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
|
||||||
'rbacUiControlService', 'Dataset',
|
'rbacUiControlService', 'Dataset',
|
||||||
function($scope, Rest, TeamList, Prompt, ClearScope, ProcessErrors,
|
function($scope, Rest, TeamList, Prompt, ProcessErrors,
|
||||||
GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset) {
|
GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var list = TeamList,
|
var list = TeamList,
|
||||||
defaultUrl = GetBasePath('teams');
|
defaultUrl = GetBasePath('teams');
|
||||||
|
|
||||||
@@ -53,10 +51,18 @@ export default ['$scope', 'Rest', 'TeamList', 'Prompt', 'ClearScope',
|
|||||||
.success(function() {
|
.success(function() {
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.teams.length === 1 && $state.params.team_search && !_.isEmpty($state.params.team_search.page) && $state.params.team_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.team_search.page = (parseInt(reloadListStateParams.team_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.team_id) === id) {
|
if (parseInt($state.params.team_id) === id) {
|
||||||
$state.go('^', null, { reload: true });
|
$state.go('^', reloadListStateParams, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
$state.go('.', null, { reload: true });
|
$state.go('.', reloadListStateParams, { reload: true });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
|
|||||||
@@ -7,18 +7,17 @@
|
|||||||
export default
|
export default
|
||||||
[ '$filter', '$scope',
|
[ '$filter', '$scope',
|
||||||
'$stateParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert',
|
'$stateParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'Wait',
|
'ProcessErrors', 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'Wait',
|
||||||
'Empty', 'ToJSON', 'CallbackHelpInit', 'GetChoices', '$state', 'availableLabels',
|
'Empty', 'ToJSON', 'CallbackHelpInit', 'GetChoices', '$state', 'availableLabels',
|
||||||
'CreateSelect2', '$q', 'i18n', 'Inventory', 'Project', 'InstanceGroupsService', 'MultiCredentialService',
|
'CreateSelect2', '$q', 'i18n', 'Inventory', 'Project', 'InstanceGroupsService', 'MultiCredentialService',
|
||||||
function(
|
function(
|
||||||
$filter, $scope,
|
$filter, $scope,
|
||||||
$stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
$stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
||||||
ProcessErrors, ClearScope, GetBasePath, md5Setup, ParseTypeChange, Wait,
|
ProcessErrors, GetBasePath, md5Setup, ParseTypeChange, Wait,
|
||||||
Empty, ToJSON, CallbackHelpInit, GetChoices,
|
Empty, ToJSON, CallbackHelpInit, GetChoices,
|
||||||
$state, availableLabels, CreateSelect2, $q, i18n, Inventory, Project, InstanceGroupsService, MultiCredentialService
|
$state, availableLabels, CreateSelect2, $q, i18n, Inventory, Project, InstanceGroupsService, MultiCredentialService
|
||||||
) {
|
) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
// Inject dynamic view
|
// Inject dynamic view
|
||||||
let defaultUrl = GetBasePath('job_templates'),
|
let defaultUrl = GetBasePath('job_templates'),
|
||||||
form = JobTemplateForm(),
|
form = JobTemplateForm(),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
export default
|
export default
|
||||||
[ '$filter', '$scope', '$rootScope',
|
[ '$filter', '$scope', '$rootScope',
|
||||||
'$location', '$stateParams', 'JobTemplateForm', 'GenerateForm',
|
'$location', '$stateParams', 'JobTemplateForm', 'GenerateForm',
|
||||||
'Rest', 'Alert', 'ProcessErrors', 'ClearScope', 'GetBasePath', 'md5Setup',
|
'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'md5Setup',
|
||||||
'ParseTypeChange', 'Wait', 'selectedLabels',
|
'ParseTypeChange', 'Wait', 'selectedLabels',
|
||||||
'Empty', 'Prompt', 'ToJSON', 'GetChoices', 'CallbackHelpInit',
|
'Empty', 'Prompt', 'ToJSON', 'GetChoices', 'CallbackHelpInit',
|
||||||
'InitiatePlaybookRun' , 'initSurvey', '$state', 'CreateSelect2',
|
'InitiatePlaybookRun' , 'initSurvey', '$state', 'CreateSelect2',
|
||||||
@@ -21,14 +21,12 @@ export default
|
|||||||
function(
|
function(
|
||||||
$filter, $scope, $rootScope,
|
$filter, $scope, $rootScope,
|
||||||
$location, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
$location, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert,
|
||||||
ProcessErrors, ClearScope, GetBasePath, md5Setup,
|
ProcessErrors, GetBasePath, md5Setup,
|
||||||
ParseTypeChange, Wait, selectedLabels,
|
ParseTypeChange, Wait, selectedLabels,
|
||||||
Empty, Prompt, ToJSON, GetChoices, CallbackHelpInit, InitiatePlaybookRun, SurveyControllerInit, $state,
|
Empty, Prompt, ToJSON, GetChoices, CallbackHelpInit, InitiatePlaybookRun, SurveyControllerInit, $state,
|
||||||
CreateSelect2, ToggleNotification, $q, InstanceGroupsService, InstanceGroupsData, MultiCredentialService, availableLabels
|
CreateSelect2, ToggleNotification, $q, InstanceGroupsService, InstanceGroupsData, MultiCredentialService, availableLabels
|
||||||
) {
|
) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
$scope.$watch('job_template_obj.summary_fields.user_capabilities.edit', function(val) {
|
$scope.$watch('job_template_obj.summary_fields.user_capabilities.edit', function(val) {
|
||||||
if (val === false) {
|
if (val === false) {
|
||||||
$scope.canAddJobTemplate = false;
|
$scope.canAddJobTemplate = false;
|
||||||
|
|||||||
@@ -5,17 +5,16 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
export default ['$scope', '$rootScope',
|
export default ['$scope', '$rootScope',
|
||||||
'Alert','TemplateList', 'Prompt', 'ClearScope', 'ProcessErrors',
|
'Alert','TemplateList', 'Prompt', 'ProcessErrors',
|
||||||
'GetBasePath', 'InitiatePlaybookRun', 'Wait', '$state', '$filter',
|
'GetBasePath', 'InitiatePlaybookRun', 'Wait', '$state', '$filter',
|
||||||
'Dataset', 'rbacUiControlService', 'TemplatesService','QuerySet',
|
'Dataset', 'rbacUiControlService', 'TemplatesService','QuerySet',
|
||||||
'TemplateCopyService',
|
'TemplateCopyService',
|
||||||
function(
|
function(
|
||||||
$scope, $rootScope, Alert,
|
$scope, $rootScope, Alert,
|
||||||
TemplateList, Prompt, ClearScope, ProcessErrors, GetBasePath,
|
TemplateList, Prompt, ProcessErrors, GetBasePath,
|
||||||
InitiatePlaybookRun, Wait, $state, $filter, Dataset, rbacUiControlService, TemplatesService,
|
InitiatePlaybookRun, Wait, $state, $filter, Dataset, rbacUiControlService, TemplatesService,
|
||||||
qs, TemplateCopyService
|
qs, TemplateCopyService
|
||||||
) {
|
) {
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var list = TemplateList;
|
var list = TemplateList;
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ export default ['$scope', '$rootScope',
|
|||||||
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
|
$scope[list.name] = $scope[`${list.iterator}_dataset`].results;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.editJobTemplate = function(template) {
|
$scope.editJobTemplate = function(template) {
|
||||||
if(template) {
|
if(template) {
|
||||||
if(template.type && (template.type === 'Job Template' || template.type === 'job_template')) {
|
if(template.type && (template.type === 'Job Template' || template.type === 'job_template')) {
|
||||||
@@ -106,11 +105,19 @@ export default ['$scope', '$rootScope',
|
|||||||
|
|
||||||
function handleSuccessfulDelete(isWorkflow) {
|
function handleSuccessfulDelete(isWorkflow) {
|
||||||
let stateParamId = isWorkflow ? $state.params.workflow_job_template_id : $state.params.job_template_id;
|
let stateParamId = isWorkflow ? $state.params.workflow_job_template_id : $state.params.job_template_id;
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.templates.length === 1 && $state.params.template_search && !_.isEmpty($state.params.template_search.page) && $state.params.template_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.template_search.page = (parseInt(reloadListStateParams.template_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt(stateParamId) === template.id) {
|
if (parseInt(stateParamId) === template.id) {
|
||||||
// Move the user back to the templates list
|
// Move the user back to the templates list
|
||||||
$state.go("templates", null, {reload: true});
|
$state.go("templates", reloadListStateParams, {reload: true});
|
||||||
} else {
|
} else {
|
||||||
$state.go(".", null, {reload: true});
|
$state.go(".", reloadListStateParams, {reload: true});
|
||||||
}
|
}
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ function link($timeout, CreateSelect2, scope, element, attrs, ngModel) {
|
|||||||
element: element.find('select'),
|
element: element.find('select'),
|
||||||
multiple: scope.isMultipleSelect(),
|
multiple: scope.isMultipleSelect(),
|
||||||
minimumResultsForSearch: scope.isMultipleSelect() ? Infinity : 10,
|
minimumResultsForSearch: scope.isMultipleSelect() ? Infinity : 10,
|
||||||
customDropdownAdapter: scope.preview ? false : true,
|
customDropdownAdapter: true,
|
||||||
disabledOptions: true
|
disabledOptions: scope.preview ? true : false
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
question="question"
|
question="question"
|
||||||
choices="choices"
|
choices="choices"
|
||||||
ng-required="isRequired === 'true'"
|
ng-required="isRequired === 'true'"
|
||||||
ng-model="defaultValue">
|
ng-model="defaultValue"
|
||||||
|
preview="preview">
|
||||||
</multiple-choice>
|
</multiple-choice>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="question.type === 'password'" class="input_area input-group">
|
<div ng-if="question.type === 'password'" class="input_area input-group">
|
||||||
|
|||||||
@@ -6,13 +6,12 @@
|
|||||||
|
|
||||||
export default [
|
export default [
|
||||||
'$scope', 'WorkflowForm', 'GenerateForm', 'Alert', 'ProcessErrors',
|
'$scope', 'WorkflowForm', 'GenerateForm', 'Alert', 'ProcessErrors',
|
||||||
'ClearScope', 'Wait', '$state', 'CreateSelect2', 'TemplatesService',
|
'Wait', '$state', 'CreateSelect2', 'TemplatesService',
|
||||||
'ToJSON', 'ParseTypeChange', '$q', 'Rest', 'GetBasePath', 'availableLabels',
|
'ToJSON', 'ParseTypeChange', '$q', 'Rest', 'GetBasePath', 'availableLabels',
|
||||||
function($scope, WorkflowForm, GenerateForm, Alert, ProcessErrors,
|
function($scope, WorkflowForm, GenerateForm, Alert, ProcessErrors,
|
||||||
ClearScope, Wait, $state, CreateSelect2, TemplatesService, ToJSON,
|
Wait, $state, CreateSelect2, TemplatesService, ToJSON,
|
||||||
ParseTypeChange, $q, Rest, GetBasePath, availableLabels) {
|
ParseTypeChange, $q, Rest, GetBasePath, availableLabels) {
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
// Inject dynamic view
|
// Inject dynamic view
|
||||||
let form = WorkflowForm(),
|
let form = WorkflowForm(),
|
||||||
generator = GenerateForm;
|
generator = GenerateForm;
|
||||||
|
|||||||
@@ -6,16 +6,15 @@
|
|||||||
|
|
||||||
export default [
|
export default [
|
||||||
'$scope', '$stateParams', 'WorkflowForm', 'GenerateForm', 'Alert',
|
'$scope', '$stateParams', 'WorkflowForm', 'GenerateForm', 'Alert',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', '$q', 'ParseTypeChange',
|
'ProcessErrors', 'GetBasePath', '$q', 'ParseTypeChange',
|
||||||
'Wait', 'Empty', 'ToJSON', 'initSurvey', '$state', 'CreateSelect2',
|
'Wait', 'Empty', 'ToJSON', 'initSurvey', '$state', 'CreateSelect2',
|
||||||
'ParseVariableString', 'TemplatesService', 'Rest', 'ToggleNotification',
|
'ParseVariableString', 'TemplatesService', 'Rest', 'ToggleNotification',
|
||||||
'OrgAdminLookup', 'availableLabels', 'selectedLabels', 'workflowJobTemplateData',
|
'OrgAdminLookup', 'availableLabels', 'selectedLabels', 'workflowJobTemplateData',
|
||||||
function($scope, $stateParams, WorkflowForm, GenerateForm, Alert,
|
function($scope, $stateParams, WorkflowForm, GenerateForm, Alert,
|
||||||
ProcessErrors, ClearScope, GetBasePath, $q, ParseTypeChange, Wait, Empty,
|
ProcessErrors, GetBasePath, $q, ParseTypeChange, Wait, Empty,
|
||||||
ToJSON, SurveyControllerInit, $state, CreateSelect2, ParseVariableString,
|
ToJSON, SurveyControllerInit, $state, CreateSelect2, ParseVariableString,
|
||||||
TemplatesService, Rest, ToggleNotification, OrgAdminLookup, availableLabels, selectedLabels, workflowJobTemplateData) {
|
TemplatesService, Rest, ToggleNotification, OrgAdminLookup, availableLabels, selectedLabels, workflowJobTemplateData) {
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
$scope.$watch('workflow_job_template_obj.summary_fields.user_capabilities.edit', function(val) {
|
$scope.$watch('workflow_job_template_obj.summary_fields.user_capabilities.edit', function(val) {
|
||||||
if (val === false) {
|
if (val === false) {
|
||||||
$scope.canAddWorkflowJobTemplate = false;
|
$scope.canAddWorkflowJobTemplate = false;
|
||||||
|
|||||||
@@ -13,12 +13,11 @@ const user_type_options = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default ['$scope', '$rootScope', 'UserForm', 'GenerateForm', 'Rest',
|
export default ['$scope', '$rootScope', 'UserForm', 'GenerateForm', 'Rest',
|
||||||
'Alert', 'ProcessErrors', 'ReturnToCaller', 'ClearScope', 'GetBasePath',
|
'Alert', 'ProcessErrors', 'ReturnToCaller', 'GetBasePath',
|
||||||
'Wait', 'CreateSelect2', '$state', '$location', 'i18n',
|
'Wait', 'CreateSelect2', '$state', '$location', 'i18n',
|
||||||
function($scope, $rootScope, UserForm, GenerateForm, Rest, Alert,
|
function($scope, $rootScope, UserForm, GenerateForm, Rest, Alert,
|
||||||
ProcessErrors, ReturnToCaller, ClearScope, GetBasePath, Wait, CreateSelect2,
|
ProcessErrors, ReturnToCaller, GetBasePath, Wait, CreateSelect2,
|
||||||
$state, $location, i18n) {
|
$state, $location, i18n) {
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var defaultUrl = GetBasePath('organizations'),
|
var defaultUrl = GetBasePath('organizations'),
|
||||||
form = UserForm;
|
form = UserForm;
|
||||||
|
|||||||
@@ -13,15 +13,14 @@ const user_type_options = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default ['$scope', '$rootScope', '$stateParams', 'UserForm', 'Rest',
|
export default ['$scope', '$rootScope', '$stateParams', 'UserForm', 'Rest',
|
||||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'Wait', 'CreateSelect2',
|
'ProcessErrors', 'GetBasePath', 'Wait', 'CreateSelect2',
|
||||||
'$state', 'i18n',
|
'$state', 'i18n',
|
||||||
function($scope, $rootScope, $stateParams, UserForm, Rest, ProcessErrors,
|
function($scope, $rootScope, $stateParams, UserForm, Rest, ProcessErrors,
|
||||||
ClearScope, GetBasePath, Wait, CreateSelect2, $state, i18n) {
|
GetBasePath, Wait, CreateSelect2, $state, i18n) {
|
||||||
|
|
||||||
for (var i = 0; i < user_type_options.length; i++) {
|
for (var i = 0; i < user_type_options.length; i++) {
|
||||||
user_type_options[i].label = i18n._(user_type_options[i].label);
|
user_type_options[i].label = i18n._(user_type_options[i].label);
|
||||||
}
|
}
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var form = UserForm,
|
var form = UserForm,
|
||||||
master = {},
|
master = {},
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ const user_type_options = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default ['$scope', '$rootScope', 'Rest', 'UserList', 'Prompt',
|
export default ['$scope', '$rootScope', 'Rest', 'UserList', 'Prompt',
|
||||||
'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
|
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
|
||||||
'rbacUiControlService', 'Dataset', 'i18n',
|
'rbacUiControlService', 'Dataset', 'i18n',
|
||||||
function($scope, $rootScope, Rest, UserList, Prompt, ClearScope,
|
function($scope, $rootScope, Rest, UserList, Prompt,
|
||||||
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService,
|
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService,
|
||||||
Dataset, i18n) {
|
Dataset, i18n) {
|
||||||
|
|
||||||
@@ -23,8 +23,6 @@ export default ['$scope', '$rootScope', 'Rest', 'UserList', 'Prompt',
|
|||||||
user_type_options[i].label = i18n._(user_type_options[i].label);
|
user_type_options[i].label = i18n._(user_type_options[i].label);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearScope();
|
|
||||||
|
|
||||||
var list = UserList,
|
var list = UserList,
|
||||||
defaultUrl = GetBasePath('users');
|
defaultUrl = GetBasePath('users');
|
||||||
|
|
||||||
@@ -65,6 +63,14 @@ export default ['$scope', '$rootScope', 'Rest', 'UserList', 'Prompt',
|
|||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success(function() {
|
.success(function() {
|
||||||
|
|
||||||
|
let reloadListStateParams = null;
|
||||||
|
|
||||||
|
if($scope.users.length === 1 && $state.params.user_search && !_.isEmpty($state.params.user_search.page) && $state.params.user_search.page !== '1') {
|
||||||
|
reloadListStateParams = _.cloneDeep($state.params);
|
||||||
|
reloadListStateParams.user_search.page = (parseInt(reloadListStateParams.user_search.page)-1).toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (parseInt($state.params.user_id) === id) {
|
if (parseInt($state.params.user_id) === id) {
|
||||||
$state.go('^', null, { reload: true });
|
$state.go('^', null, { reload: true });
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ describe('Controller: TemplatesList', () => {
|
|||||||
rootScope,
|
rootScope,
|
||||||
state,
|
state,
|
||||||
TemplatesListController,
|
TemplatesListController,
|
||||||
ClearScope,
|
|
||||||
GetChoices,
|
GetChoices,
|
||||||
Alert,
|
Alert,
|
||||||
Prompt,
|
Prompt,
|
||||||
@@ -53,7 +52,6 @@ describe('Controller: TemplatesList', () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ClearScope = jasmine.createSpy('ClearScope');
|
|
||||||
GetChoices = jasmine.createSpy('GetChoices');
|
GetChoices = jasmine.createSpy('GetChoices');
|
||||||
Alert = jasmine.createSpy('Alert');
|
Alert = jasmine.createSpy('Alert');
|
||||||
Prompt = jasmine.createSpy('Prompt').and.callFake(function(args) {
|
Prompt = jasmine.createSpy('Prompt').and.callFake(function(args) {
|
||||||
@@ -61,7 +59,6 @@ describe('Controller: TemplatesList', () => {
|
|||||||
});
|
});
|
||||||
InitiatePlaybookRun = jasmine.createSpy('InitiatePlaybookRun');
|
InitiatePlaybookRun = jasmine.createSpy('InitiatePlaybookRun');
|
||||||
|
|
||||||
$provide.value('ClearScope', ClearScope);
|
|
||||||
$provide.value('GetChoices', GetChoices);
|
$provide.value('GetChoices', GetChoices);
|
||||||
$provide.value('Alert', Alert);
|
$provide.value('Alert', Alert);
|
||||||
$provide.value('Prompt', Prompt);
|
$provide.value('Prompt', Prompt);
|
||||||
@@ -69,12 +66,11 @@ describe('Controller: TemplatesList', () => {
|
|||||||
$provide.value('InitiatePlaybookRun', InitiatePlaybookRun);
|
$provide.value('InitiatePlaybookRun', InitiatePlaybookRun);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(angular.mock.inject( ($rootScope, $controller, $q, _state_, _ConfigService_, _ClearScope_, _GetChoices_, _Alert_, _Prompt_, _InitiatePlaybookRun_) => {
|
beforeEach(angular.mock.inject( ($rootScope, $controller, $q, _state_, _ConfigService_, _GetChoices_, _Alert_, _Prompt_, _InitiatePlaybookRun_) => {
|
||||||
scope = $rootScope.$new();
|
scope = $rootScope.$new();
|
||||||
rootScope = $rootScope;
|
rootScope = $rootScope;
|
||||||
q = $q;
|
q = $q;
|
||||||
state = _state_;
|
state = _state_;
|
||||||
ClearScope = _ClearScope_;
|
|
||||||
GetChoices = _GetChoices_;
|
GetChoices = _GetChoices_;
|
||||||
Alert = _Alert_;
|
Alert = _Alert_;
|
||||||
Prompt = _Prompt_;
|
Prompt = _Prompt_;
|
||||||
@@ -92,7 +88,6 @@ describe('Controller: TemplatesList', () => {
|
|||||||
$scope: scope,
|
$scope: scope,
|
||||||
$rootScope: rootScope,
|
$rootScope: rootScope,
|
||||||
$state: state,
|
$state: state,
|
||||||
ClearScope: ClearScope,
|
|
||||||
GetChoices: GetChoices,
|
GetChoices: GetChoices,
|
||||||
Alert: Alert,
|
Alert: Alert,
|
||||||
Prompt: Prompt,
|
Prompt: Prompt,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ describe('Controller: WorkflowAdd', () => {
|
|||||||
let scope,
|
let scope,
|
||||||
state,
|
state,
|
||||||
WorkflowAdd,
|
WorkflowAdd,
|
||||||
ClearScope,
|
|
||||||
Alert,
|
Alert,
|
||||||
GenerateForm,
|
GenerateForm,
|
||||||
TemplatesService,
|
TemplatesService,
|
||||||
@@ -49,8 +48,7 @@ describe('Controller: WorkflowAdd', () => {
|
|||||||
name: "foo",
|
name: "foo",
|
||||||
id: "1"
|
id: "1"
|
||||||
}];
|
}];
|
||||||
|
|
||||||
ClearScope = jasmine.createSpy('ClearScope');
|
|
||||||
Alert = jasmine.createSpy('Alert');
|
Alert = jasmine.createSpy('Alert');
|
||||||
ProcessErrors = jasmine.createSpy('ProcessErrors');
|
ProcessErrors = jasmine.createSpy('ProcessErrors');
|
||||||
CreateSelect2 = jasmine.createSpy('CreateSelect2');
|
CreateSelect2 = jasmine.createSpy('CreateSelect2');
|
||||||
@@ -58,7 +56,6 @@ describe('Controller: WorkflowAdd', () => {
|
|||||||
ParseTypeChange = jasmine.createSpy('ParseTypeChange');
|
ParseTypeChange = jasmine.createSpy('ParseTypeChange');
|
||||||
ToJSON = jasmine.createSpy('ToJSON');
|
ToJSON = jasmine.createSpy('ToJSON');
|
||||||
|
|
||||||
$provide.value('ClearScope', ClearScope);
|
|
||||||
$provide.value('Alert', Alert);
|
$provide.value('Alert', Alert);
|
||||||
$provide.value('GenerateForm', GenerateForm);
|
$provide.value('GenerateForm', GenerateForm);
|
||||||
$provide.value('state', state);
|
$provide.value('state', state);
|
||||||
@@ -70,11 +67,10 @@ describe('Controller: WorkflowAdd', () => {
|
|||||||
$provide.value('availableLabels', availableLabels);
|
$provide.value('availableLabels', availableLabels);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(angular.mock.inject( ($rootScope, $controller, $q, $httpBackend, _state_, _ConfigService_, _ClearScope_, _GetChoices_, _Alert_, _GenerateForm_, _ProcessErrors_, _CreateSelect2_, _Wait_, _ParseTypeChange_, _ToJSON_, _availableLabels_) => {
|
beforeEach(angular.mock.inject( ($rootScope, $controller, $q, $httpBackend, _state_, _ConfigService_, _GetChoices_, _Alert_, _GenerateForm_, _ProcessErrors_, _CreateSelect2_, _Wait_, _ParseTypeChange_, _ToJSON_, _availableLabels_) => {
|
||||||
scope = $rootScope.$new();
|
scope = $rootScope.$new();
|
||||||
state = _state_;
|
state = _state_;
|
||||||
q = $q;
|
q = $q;
|
||||||
ClearScope = _ClearScope_;
|
|
||||||
Alert = _Alert_;
|
Alert = _Alert_;
|
||||||
GenerateForm = _GenerateForm_;
|
GenerateForm = _GenerateForm_;
|
||||||
httpBackend = $httpBackend;
|
httpBackend = $httpBackend;
|
||||||
@@ -99,7 +95,6 @@ describe('Controller: WorkflowAdd', () => {
|
|||||||
WorkflowAdd = $controller('WorkflowAdd', {
|
WorkflowAdd = $controller('WorkflowAdd', {
|
||||||
$scope: scope,
|
$scope: scope,
|
||||||
$state: state,
|
$state: state,
|
||||||
ClearScope: ClearScope,
|
|
||||||
Alert: Alert,
|
Alert: Alert,
|
||||||
GenerateForm: GenerateForm,
|
GenerateForm: GenerateForm,
|
||||||
TemplatesService: TemplatesService,
|
TemplatesService: TemplatesService,
|
||||||
@@ -112,10 +107,6 @@ describe('Controller: WorkflowAdd', () => {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should call ClearScope', ()=>{
|
|
||||||
expect(ClearScope).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get/set the label options and select2-ify the input', ()=>{
|
it('should get/set the label options and select2-ify the input', ()=>{
|
||||||
// We expect the digest cycle to fire off this call to /static/config.js so we go ahead and handle it
|
// We expect the digest cycle to fire off this call to /static/config.js so we go ahead and handle it
|
||||||
httpBackend.expectGET('/static/config.js').respond(200);
|
httpBackend.expectGET('/static/config.js').respond(200);
|
||||||
|
|||||||
@@ -140,12 +140,11 @@ controller=security
|
|||||||
```
|
```
|
||||||
|
|
||||||
In the isolated rampart model, "controller" instances interact with "isolated"
|
In the isolated rampart model, "controller" instances interact with "isolated"
|
||||||
instances via a series of Ansible playbooks over SSH. As such, all isolated instances
|
instances via a series of Ansible playbooks over SSH. At installation time,
|
||||||
must be preconfigured by the installer with passwordless SSH access from any potential
|
a randomized RSA key is generated and distributed as an authorized key to all
|
||||||
controller instances. In the example above, the `isolatedA` and `isolatedB` hosts
|
"isolated" instances. The private half of the key is encrypted and stored
|
||||||
must be reachable from `towerB` and `towerC` hosts via `ssh
|
within Tower, and is used to authenticate from "controller" instances to
|
||||||
awx@<isolated-hostname>` (meaning, `authorized_keys` must be pre-distributed to
|
"isolated" instances when jobs are run.
|
||||||
the `isolatedA` and `isolatedB` hosts).
|
|
||||||
|
|
||||||
When a job is scheduled to run on an "isolated" instance:
|
When a job is scheduled to run on an "isolated" instance:
|
||||||
|
|
||||||
@@ -185,6 +184,20 @@ Recommendations for system configuration with isolated groups:
|
|||||||
variable - the behavior in this case can not be predicted.
|
variable - the behavior in this case can not be predicted.
|
||||||
- Do not put an isolated instance in more than 1 isolated group.
|
- Do not put an isolated instance in more than 1 isolated group.
|
||||||
|
|
||||||
|
Isolated Node Authentication
|
||||||
|
----------------------------
|
||||||
|
By default - at installation time - a randomized RSA key is generated and
|
||||||
|
distributed as an authorized key to all "isolated" instances. The private half
|
||||||
|
of the key is encrypted and stored within Tower, and is used to authenticate
|
||||||
|
from "controller" instances to "isolated" instances when jobs are run.
|
||||||
|
|
||||||
|
For users who wish to manage SSH authentication from controlling nodes to
|
||||||
|
isolated nodes via some system _outside_ of Tower (such as externally-managed
|
||||||
|
passwordless SSH keys), this behavior can be disabled by unsetting two Tower
|
||||||
|
API settings values:
|
||||||
|
|
||||||
|
`HTTP PATCH /api/v2/settings/jobs/ {'AWX_ISOLATED_PRIVATE_KEY': '', 'AWX_ISOLATED_PUBLIC_KEY': ''}`
|
||||||
|
|
||||||
|
|
||||||
### Provisioning and Deprovisioning Instances and Groups
|
### Provisioning and Deprovisioning Instances and Groups
|
||||||
|
|
||||||
|
|||||||
@@ -40,27 +40,6 @@ and they are structured as follows:
|
|||||||
The `controller` for the group "thepentagon" and all hosts therein is
|
The `controller` for the group "thepentagon" and all hosts therein is
|
||||||
determined by a ForeignKey within the instance group.
|
determined by a ForeignKey within the instance group.
|
||||||
|
|
||||||
## Development Testing Notes
|
|
||||||
|
|
||||||
### Test the SSH connection between containers
|
|
||||||
|
|
||||||
While the environment is running, you can test the connection like so:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker exec -i -t tools_tower_1 /bin/bash
|
|
||||||
```
|
|
||||||
|
|
||||||
Inside the context of that container:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh root@isolated
|
|
||||||
```
|
|
||||||
|
|
||||||
(note: awx user has been deprecated)
|
|
||||||
|
|
||||||
This should give a shell to the `tools_isolated_1` container, as the
|
|
||||||
`tools_tower_1` container sees it.
|
|
||||||
|
|
||||||
### Run a playbook
|
### Run a playbook
|
||||||
|
|
||||||
In order to run an isolated job, associate the instance group `thepentagon` with
|
In order to run an isolated job, associate the instance group `thepentagon` with
|
||||||
|
|||||||
Reference in New Issue
Block a user