mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 01:47:35 -02:30
Merge pull request #138 from gconsidine/ui/fix/documentation-link
Ui/fix/documentation link
This commit is contained in:
@@ -6,6 +6,9 @@ function EditCredentialsController (models, $state, $scope, strings) {
|
|||||||
let credentialType = models.credentialType;
|
let credentialType = models.credentialType;
|
||||||
let organization = models.organization;
|
let organization = models.organization;
|
||||||
|
|
||||||
|
let omit = ['user', 'team', 'inputs'];
|
||||||
|
let isEditable = credential.isEditable();
|
||||||
|
|
||||||
vm.mode = 'edit';
|
vm.mode = 'edit';
|
||||||
vm.strings = strings;
|
vm.strings = strings;
|
||||||
vm.panelTitle = credential.get('name');
|
vm.panelTitle = credential.get('name');
|
||||||
@@ -35,11 +38,12 @@ function EditCredentialsController (models, $state, $scope, strings) {
|
|||||||
// Only exists for permissions compatibility
|
// Only exists for permissions compatibility
|
||||||
$scope.credential_obj = credential.get();
|
$scope.credential_obj = credential.get();
|
||||||
|
|
||||||
vm.form = credential.createFormSchema({
|
if (isEditable) {
|
||||||
omit: ['user', 'team', 'inputs']
|
vm.form = credential.createFormSchema('put', { omit });
|
||||||
});
|
} else {
|
||||||
|
vm.form = credential.createFormSchema({ omit });
|
||||||
vm.form.disabled = !credential.isEditable();
|
vm.form.disabled = !isEditable;
|
||||||
|
}
|
||||||
|
|
||||||
vm.form.organization._resource = 'organization';
|
vm.form.organization._resource = 'organization';
|
||||||
vm.form.organization._model = organization;
|
vm.form.organization._model = organization;
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ function AtFormController (eventService, strings) {
|
|||||||
errorMessageSet = true;
|
errorMessageSet = true;
|
||||||
|
|
||||||
component.state._rejected = true;
|
component.state._rejected = true;
|
||||||
component.state._isValid = false;
|
|
||||||
component.state._message = errors[component.state.id].join(' ');
|
component.state._message = errors[component.state.id].join(' ');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<p ng-if="state._rejected && !state._isValid" class="at-InputMessage--rejected">
|
<p ng-if="state._rejected || !state._isValid" class="at-InputMessage--rejected">
|
||||||
{{ state._message }}
|
{{ state._message }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.at-Modal-body {
|
.at-Modal-body {
|
||||||
font-size: @at-font-size;
|
font-size: @at-font-size;
|
||||||
padding: 0;
|
padding: @at-padding-panel 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Modal-dismiss {
|
.at-Modal-dismiss {
|
||||||
|
|||||||
@@ -10,13 +10,15 @@ function atModalLink (scope, el, attrs, controllers) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtModalController (eventService) {
|
function AtModalController (eventService, strings) {
|
||||||
let vm = this;
|
let vm = this;
|
||||||
|
|
||||||
let overlay;
|
let overlay;
|
||||||
let modal;
|
let modal;
|
||||||
let listeners;
|
let listeners;
|
||||||
|
|
||||||
|
vm.strings = strings;
|
||||||
|
|
||||||
vm.init = (scope, el) => {
|
vm.init = (scope, el) => {
|
||||||
overlay = el[0];
|
overlay = el[0];
|
||||||
modal = el.find('.at-Modal-window')[0];
|
modal = el.find('.at-Modal-window')[0];
|
||||||
@@ -67,7 +69,10 @@ function AtModalController (eventService) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
AtModalController.$inject = ['EventService'];
|
AtModalController.$inject = [
|
||||||
|
'EventService',
|
||||||
|
'ComponentsStrings'
|
||||||
|
]
|
||||||
|
|
||||||
function atModal (pathService) {
|
function atModal (pathService) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,28 +1,55 @@
|
|||||||
let $http;
|
let $http;
|
||||||
let $q;
|
let $q;
|
||||||
|
let cache;
|
||||||
|
|
||||||
function request (method, resource) {
|
function request (method, resource) {
|
||||||
if (Array.isArray(method) && Array.isArray(resource)) {
|
if (Array.isArray(method)) {
|
||||||
let promises = method.map((value, i) => this.http[value](resource[i]));
|
let promises = method.map((_method_, i) => {
|
||||||
|
return this.request(_method_, Array.isArray(resource) ? resource[i] : resource);
|
||||||
|
});
|
||||||
|
|
||||||
return $q.all(promises);
|
return $q.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.isCacheable(method, resource)) {
|
||||||
|
return this.requestWithCache(method, resource);
|
||||||
|
}
|
||||||
|
|
||||||
return this.http[method](resource);
|
return this.http[method](resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requestWithCache (method, resource) {
|
||||||
|
let key = cache.createKey(method, this.path, resource);
|
||||||
|
|
||||||
|
return cache.get(key)
|
||||||
|
.then(data => {
|
||||||
|
if (data) {
|
||||||
|
this.model[method.toUpperCase()] = data;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.http[method](resource)
|
||||||
|
.then(res => {
|
||||||
|
cache.put(key, res.data);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intended to be useful in searching and filtering results using params
|
* Intended to be useful in searching and filtering results using params
|
||||||
* supported by the API.
|
* supported by the API.
|
||||||
*
|
*
|
||||||
* @param {object} params - An object of keys and values to to format and
|
* @arg {Object} params - An object of keys and values to to format and
|
||||||
* to the URL as a query string. Refer to the API documentation for the
|
* to the URL as a query string. Refer to the API documentation for the
|
||||||
* resource in use for specifics.
|
* resource in use for specifics.
|
||||||
* @param {object} config - Configuration specific to the UI to accommodate
|
* @arg {Object} config - Configuration specific to the UI to accommodate
|
||||||
* common use cases.
|
* common use cases.
|
||||||
*
|
*
|
||||||
* @returns {Promise} - $http
|
* @yields {boolean} - Indicating a match has been found. If so, the results
|
||||||
* @yields {(Boolean|object)}
|
* are set on the model.
|
||||||
*/
|
*/
|
||||||
function search (params, config) {
|
function search (params, config) {
|
||||||
let req = {
|
let req = {
|
||||||
@@ -279,6 +306,14 @@ function isCreatable () {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCacheable () {
|
||||||
|
if (this.settings.cache === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function graft (id) {
|
function graft (id) {
|
||||||
let item = this.get('results').filter(result => result.id === id);
|
let item = this.get('results').filter(result => result.id === id);
|
||||||
|
|
||||||
@@ -291,12 +326,27 @@ function graft (id) {
|
|||||||
return new this.Constructor('get', item, true);
|
return new this.Constructor('get', item, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function create (method, resource, graft) {
|
/**
|
||||||
|
* `create` is called on instantiation of every model. Models can be
|
||||||
|
* instantiated empty or with `GET` and/or `OPTIONS` requests that yield data.
|
||||||
|
* If model data already exists a new instance can be created (see: `graft`)
|
||||||
|
* with existing data.
|
||||||
|
*
|
||||||
|
* @arg {string=} method - Populate the model with `GET` or `OPTIONS` data.
|
||||||
|
* @arg {(string|Object)=} resource - An `id` reference to a particular
|
||||||
|
* resource or an existing model's data.
|
||||||
|
* @arg {boolean=} graft - Create a new instance from existing model data.
|
||||||
|
*
|
||||||
|
* @returns {(Object|Promise)} - Returns a reference to the model instance
|
||||||
|
* if an empty instance or graft is created. Otherwise, a promise yielding
|
||||||
|
* a model instance is returned.
|
||||||
|
*/
|
||||||
|
function create (method, resource, graft, config) {
|
||||||
if (!method) {
|
if (!method) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.promise = this.request(method, resource);
|
this.promise = this.request(method, resource, config);
|
||||||
|
|
||||||
if (graft) {
|
if (graft) {
|
||||||
return this;
|
return this;
|
||||||
@@ -306,19 +356,30 @@ function create (method, resource, graft) {
|
|||||||
.then(() => this);
|
.then(() => this);
|
||||||
}
|
}
|
||||||
|
|
||||||
function BaseModel (path) {
|
/**
|
||||||
|
* Base functionality for API interaction.
|
||||||
|
*
|
||||||
|
* @arg {string} path - The API resource for the model extending BaseModel to
|
||||||
|
* use.
|
||||||
|
* @arg {Object=} settings - Configuration applied to all instances of the
|
||||||
|
* extending model.
|
||||||
|
* @arg {boolean=} settings.cache - Cache the model data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function BaseModel (path, settings) {
|
||||||
this.create = create;
|
this.create = create;
|
||||||
this.find = find;
|
this.find = find;
|
||||||
this.get = get;
|
this.get = get;
|
||||||
this.graft = graft;
|
this.graft = graft;
|
||||||
this.has = has;
|
this.has = has;
|
||||||
this.isEditable = isEditable;
|
this.isEditable = isEditable;
|
||||||
|
this.isCacheable = isCacheable;
|
||||||
this.isCreatable = isCreatable;
|
this.isCreatable = isCreatable;
|
||||||
this.match = match;
|
this.match = match;
|
||||||
this.model = {};
|
|
||||||
this.normalizePath = normalizePath;
|
this.normalizePath = normalizePath;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.request = request;
|
this.request = request;
|
||||||
|
this.requestWithCache = requestWithCache;
|
||||||
this.search = search;
|
this.search = search;
|
||||||
this.set = set;
|
this.set = set;
|
||||||
this.unset = unset;
|
this.unset = unset;
|
||||||
@@ -330,16 +391,19 @@ function BaseModel (path) {
|
|||||||
put: httpPut.bind(this),
|
put: httpPut.bind(this),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.model = {};
|
||||||
this.path = this.normalizePath(path);
|
this.path = this.normalizePath(path);
|
||||||
|
this.settings = settings || {};
|
||||||
};
|
};
|
||||||
|
|
||||||
function BaseModelLoader (_$http_, _$q_) {
|
function BaseModelLoader (_$http_, _$q_, _cache_) {
|
||||||
$http = _$http_;
|
$http = _$http_;
|
||||||
$q = _$q_;
|
$q = _$q_;
|
||||||
|
cache = _cache_;
|
||||||
|
|
||||||
return BaseModel;
|
return BaseModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseModelLoader.$inject = ['$http', '$q'];
|
BaseModelLoader.$inject = ['$http', '$q', 'CacheService'];
|
||||||
|
|
||||||
export default BaseModelLoader;
|
export default BaseModelLoader;
|
||||||
|
|||||||
37
awx/ui/client/lib/models/Config.js
Normal file
37
awx/ui/client/lib/models/Config.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
let BaseModel;
|
||||||
|
|
||||||
|
function getTruncatedVersion () {
|
||||||
|
let version;
|
||||||
|
|
||||||
|
try {
|
||||||
|
version = this.get('version').split('-')[0];
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOpen () {
|
||||||
|
return this.get('license_info.license_type') === 'open';
|
||||||
|
}
|
||||||
|
|
||||||
|
function ConfigModel (method, resource, graft) {
|
||||||
|
BaseModel.call(this, 'config', { cache: true });
|
||||||
|
|
||||||
|
this.Constructor = ConfigModel;
|
||||||
|
this.getTruncatedVersion = getTruncatedVersion;
|
||||||
|
this.isOpen = isOpen;
|
||||||
|
|
||||||
|
return this.create(method, resource, graft);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ConfigModelLoader (_BaseModel_) {
|
||||||
|
BaseModel = _BaseModel_;
|
||||||
|
|
||||||
|
return ConfigModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigModelLoader.$inject = ['BaseModel'];
|
||||||
|
|
||||||
|
export default ConfigModelLoader;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import Base from './Base';
|
import Base from './Base';
|
||||||
|
import Config from './Config';
|
||||||
import Credential from './Credential';
|
import Credential from './Credential';
|
||||||
import CredentialType from './CredentialType';
|
import CredentialType from './CredentialType';
|
||||||
import Me from './Me';
|
import Me from './Me';
|
||||||
@@ -7,6 +8,7 @@ import Organization from './Organization';
|
|||||||
angular
|
angular
|
||||||
.module('at.lib.models', [])
|
.module('at.lib.models', [])
|
||||||
.service('BaseModel', Base)
|
.service('BaseModel', Base)
|
||||||
|
.service('ConfigModel', Config)
|
||||||
.service('CredentialModel', Credential)
|
.service('CredentialModel', Credential)
|
||||||
.service('CredentialTypeModel', CredentialType)
|
.service('CredentialTypeModel', CredentialType)
|
||||||
.service('MeModel', Me)
|
.service('MeModel', Me)
|
||||||
|
|||||||
37
awx/ui/client/lib/services/cache.service.js
Normal file
37
awx/ui/client/lib/services/cache.service.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
function CacheService ($cacheFactory, $q) {
|
||||||
|
let cache = $cacheFactory('api');
|
||||||
|
|
||||||
|
this.put = (key, data) => {
|
||||||
|
return cache.put(key, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.get = (key) => {
|
||||||
|
return $q.resolve(cache.get(key));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = (key) => {
|
||||||
|
if (!key) {
|
||||||
|
return cache.removeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache.remove(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.createKey = (method, path, resource) => {
|
||||||
|
let key = `${method.toUpperCase()}.${path}`;
|
||||||
|
|
||||||
|
if (resource) {
|
||||||
|
if (resource.id) {
|
||||||
|
key += `${resource.id}/`;
|
||||||
|
} else if (Number(resource)) {
|
||||||
|
key += `${resource}/`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheService.$inject = ['$cacheFactory', '$q'];
|
||||||
|
|
||||||
|
export default CacheService;
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import CacheService from './cache.service';
|
||||||
import EventService from './event.service';
|
import EventService from './event.service';
|
||||||
import PathService from './path.service';
|
import PathService from './path.service';
|
||||||
import BaseStringService from './base-string.service';
|
import BaseStringService from './base-string.service';
|
||||||
@@ -5,7 +6,8 @@ import AppStrings from './app.strings';
|
|||||||
|
|
||||||
angular
|
angular
|
||||||
.module('at.lib.services', [])
|
.module('at.lib.services', [])
|
||||||
.service('EventService', EventService)
|
.service('AppStrings', AppStrings)
|
||||||
.service('PathService', PathService)
|
|
||||||
.service('BaseStringService', BaseStringService)
|
.service('BaseStringService', BaseStringService)
|
||||||
.service('AppStrings', AppStrings);
|
.service('CacheService', CacheService)
|
||||||
|
.service('EventService', EventService)
|
||||||
|
.service('PathService', PathService);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||||
import { N_ } from '../i18n';
|
import { N_ } from '../i18n';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'license',
|
name: 'license',
|
||||||
@@ -17,6 +18,12 @@ export default {
|
|||||||
parent: 'setup',
|
parent: 'setup',
|
||||||
label: N_('LICENSE')
|
label: N_('LICENSE')
|
||||||
},
|
},
|
||||||
|
onEnter: ['$state', 'ConfigService', (state, configService) => {
|
||||||
|
return configService.getConfig()
|
||||||
|
.then(config => {
|
||||||
|
return _.get(config, 'license_info.license_type') === 'open' && state.go('setup');
|
||||||
|
});
|
||||||
|
}],
|
||||||
resolve: {
|
resolve: {
|
||||||
features: ['CheckLicense', '$rootScope',
|
features: ['CheckLicense', '$rootScope',
|
||||||
function(CheckLicense, $rootScope) {
|
function(CheckLicense, $rootScope) {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
View information about this version of Ansible {{BRAND_NAME}}.
|
View information about this version of Ansible {{BRAND_NAME}}.
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
<a ui-sref="license" class="SetupItem">
|
<a ui-sref="license" class="SetupItem" ng-if="!isOpen">
|
||||||
<h4 class="SetupItem-title" translate>View Your License</h4>
|
<h4 class="SetupItem-title" translate>View Your License</h4>
|
||||||
<p class="SetupItem-description" translate>
|
<p class="SetupItem-description" translate>
|
||||||
View and edit your license information.
|
View and edit your license information.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||||
import { N_ } from '../i18n';
|
import { N_ } from '../i18n';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'setup',
|
name: 'setup',
|
||||||
@@ -8,10 +9,12 @@ export default {
|
|||||||
label: N_("SETTINGS")
|
label: N_("SETTINGS")
|
||||||
},
|
},
|
||||||
templateUrl: templateUrl('setup-menu/setup-menu'),
|
templateUrl: templateUrl('setup-menu/setup-menu'),
|
||||||
controller: function(orgAdmin, $scope){
|
controller: function(config, orgAdmin, $scope){
|
||||||
|
$scope.isOpen = _.get(config, 'license_info.license_type') === 'open';
|
||||||
$scope.orgAdmin = orgAdmin;
|
$scope.orgAdmin = orgAdmin;
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
|
config: ['ConfigService', config => config.getConfig()],
|
||||||
orgAdmin:
|
orgAdmin:
|
||||||
['$rootScope', 'ProcessErrors', 'Rest', 'GetBasePath',
|
['$rootScope', 'ProcessErrors', 'Rest', 'GetBasePath',
|
||||||
function($rootScope, ProcessErrors, Rest, GetBasePath){
|
function($rootScope, ProcessErrors, Rest, GetBasePath){
|
||||||
|
|||||||
@@ -1,14 +1,24 @@
|
|||||||
export default ['$stateParams', '$scope', '$state', 'GetBasePath', 'QuerySet', 'SmartSearchService', 'i18n',
|
export default ['$stateParams', '$scope', '$state', 'GetBasePath', 'QuerySet', 'SmartSearchService', 'i18n', 'ConfigService',
|
||||||
function($stateParams, $scope, $state, GetBasePath, qs, SmartSearchService, i18n) {
|
function($stateParams, $scope, $state, GetBasePath, qs, SmartSearchService, i18n, configService) {
|
||||||
|
|
||||||
let path,
|
let path,
|
||||||
defaults,
|
defaults,
|
||||||
queryset,
|
queryset,
|
||||||
stateChangeSuccessListener;
|
stateChangeSuccessListener;
|
||||||
|
|
||||||
init();
|
configService.getConfig()
|
||||||
|
.then(config => init(config));
|
||||||
|
|
||||||
function init() {
|
function init(config) {
|
||||||
|
let version;
|
||||||
|
|
||||||
|
try {
|
||||||
|
version = config.version.split('-')[0];
|
||||||
|
} catch (err) {
|
||||||
|
version = 'latest';
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.documentationLink = `http://docs.ansible.com/ansible-tower/${version}/html/userguide/search_sort.html`;
|
||||||
|
|
||||||
if($scope.defaultParams) {
|
if($scope.defaultParams) {
|
||||||
defaults = $scope.defaultParams;
|
defaults = $scope.defaultParams;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
<div class="SmartSearch-keyRow">
|
<div class="SmartSearch-keyRow">
|
||||||
<b>{{ 'ADDITIONAL INFORMATION' | translate }}:</b>
|
<b>{{ 'ADDITIONAL INFORMATION' | translate }}:</b>
|
||||||
<span>{{ 'For additional information on advanced search search syntax please see the Ansible Tower' | translate }}
|
<span>{{ 'For additional information on advanced search search syntax please see the Ansible Tower' | translate }}
|
||||||
<a href="http://docs.ansible.com/ansible-tower/3.2.0/html/userguide/search_sort.html" target="_blank"> {{ 'documentation' | translate }}</a>.</span>
|
<a ng-attr-href="{{ documentationLink || undefined }}" target="_blank"> {{ 'documentation' | translate }}</a>.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export default function($stateProvider) {
|
|||||||
controllerAs: state.controllerAs,
|
controllerAs: state.controllerAs,
|
||||||
views: state.views,
|
views: state.views,
|
||||||
parent: state.parent,
|
parent: state.parent,
|
||||||
|
redirectTo: state.redirectTo,
|
||||||
// new in uiRouter 1.0
|
// new in uiRouter 1.0
|
||||||
lazyLoad: state.lazyLoad,
|
lazyLoad: state.lazyLoad,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user