mirror of
https://github.com/ansible/awx.git
synced 2026-01-14 19:30:39 -03:30
move search into feature-level component
This commit is contained in:
parent
1f9b325f38
commit
a5e20117e3
@ -1,9 +1,7 @@
|
||||
let $compile;
|
||||
let $q;
|
||||
let $scope;
|
||||
let $state;
|
||||
let page;
|
||||
let qs;
|
||||
let render;
|
||||
let resource;
|
||||
let scroll;
|
||||
@ -21,8 +19,6 @@ function JobsIndexController (
|
||||
_$scope_,
|
||||
_$compile_,
|
||||
_$q_,
|
||||
_$state_,
|
||||
_qs_,
|
||||
_status_,
|
||||
) {
|
||||
vm = this || {};
|
||||
@ -50,24 +46,6 @@ function JobsIndexController (
|
||||
vm.resource = resource;
|
||||
vm.title = resource.model.get('name');
|
||||
|
||||
// Search
|
||||
$state = _$state_;
|
||||
qs = _qs_;
|
||||
|
||||
vm.search = {
|
||||
clearSearch,
|
||||
searchKeyExamples,
|
||||
searchKeyFields,
|
||||
toggleSearchKey,
|
||||
removeSearchTag,
|
||||
submitSearch,
|
||||
value: '',
|
||||
key: false,
|
||||
rejected: false,
|
||||
disabled: !resource.model.get('finished'),
|
||||
tags: getSearchTags(getCurrentQueryset()),
|
||||
};
|
||||
|
||||
// Stdout Navigation
|
||||
vm.scroll = {
|
||||
showBackToTop: false,
|
||||
@ -111,13 +89,9 @@ function init () {
|
||||
onStart () {
|
||||
status.resetCounts();
|
||||
status.setJobStatus('running');
|
||||
|
||||
vm.search.disabled = true;
|
||||
},
|
||||
onStop () {
|
||||
status.updateStats();
|
||||
|
||||
vm.search.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -346,63 +320,6 @@ function toggle (uuid, menu) {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
|
||||
const searchReloadOptions = { reload: true, inherit: false };
|
||||
const searchKeyExamples = ['id:>1', 'task:set', 'created:>=2000-01-01'];
|
||||
const searchKeyFields = ['changed', 'failed', 'host_name', 'stdout', 'task', 'role', 'playbook', 'play'];
|
||||
|
||||
function toggleSearchKey () {
|
||||
vm.search.key = !vm.search.key;
|
||||
}
|
||||
|
||||
function getCurrentQueryset () {
|
||||
const { job_event_search } = $state.params; // eslint-disable-line camelcase
|
||||
|
||||
return qs.decodeArr(job_event_search);
|
||||
}
|
||||
|
||||
function getSearchTags (queryset) {
|
||||
return qs.createSearchTagsFromQueryset(queryset)
|
||||
.filter(tag => !tag.startsWith('event'))
|
||||
.filter(tag => !tag.startsWith('-event'))
|
||||
.filter(tag => !tag.startsWith('page_size'))
|
||||
.filter(tag => !tag.startsWith('order_by'));
|
||||
}
|
||||
|
||||
function removeSearchTag (index) {
|
||||
const searchTerm = vm.search.tags[index];
|
||||
|
||||
const currentQueryset = getCurrentQueryset();
|
||||
const modifiedQueryset = qs.removeTermsFromQueryset(currentQueryset, searchTerm);
|
||||
|
||||
vm.search.tags = getSearchTags(modifiedQueryset);
|
||||
|
||||
$state.params.job_event_search = qs.encodeArr(modifiedQueryset);
|
||||
$state.transitionTo($state.current, $state.params, searchReloadOptions);
|
||||
}
|
||||
|
||||
function submitSearch () {
|
||||
const searchInputQueryset = qs.getSearchInputQueryset(vm.search.value);
|
||||
|
||||
const currentQueryset = getCurrentQueryset();
|
||||
const modifiedQueryset = qs.mergeQueryset(currentQueryset, searchInputQueryset);
|
||||
|
||||
vm.search.tags = getSearchTags(modifiedQueryset);
|
||||
|
||||
$state.params.job_event_search = qs.encodeArr(modifiedQueryset);
|
||||
$state.transitionTo($state.current, $state.params, searchReloadOptions);
|
||||
}
|
||||
|
||||
function clearSearch () {
|
||||
vm.search.tags = [];
|
||||
|
||||
$state.params.job_event_search = '';
|
||||
$state.transitionTo($state.current, $state.params, searchReloadOptions);
|
||||
}
|
||||
|
||||
JobsIndexController.$inject = [
|
||||
'resource',
|
||||
'JobPageService',
|
||||
@ -412,8 +329,6 @@ JobsIndexController.$inject = [
|
||||
'$scope',
|
||||
'$compile',
|
||||
'$q',
|
||||
'$state',
|
||||
'QuerySet',
|
||||
'JobStatusService',
|
||||
];
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import EngineService from '~features/output/engine.service';
|
||||
import StatusService from '~features/output/status.service';
|
||||
|
||||
import DetailsDirective from '~features/output/details.directive';
|
||||
import SearchKeyDirective from '~features/output/search-key.directive';
|
||||
import SearchDirective from '~features/output/search.directive';
|
||||
import StatsDirective from '~features/output/stats.directive';
|
||||
|
||||
const Template = require('~features/output/index.view.html');
|
||||
@ -220,7 +220,7 @@ angular
|
||||
.service('JobEventEngine', EngineService)
|
||||
.service('JobStatusService', StatusService)
|
||||
.directive('atJobDetails', DetailsDirective)
|
||||
.directive('atSearchKey', SearchKeyDirective)
|
||||
.directive('atJobSearch', SearchDirective)
|
||||
.directive('atJobStats', StatsDirective)
|
||||
.run(JobsRun);
|
||||
|
||||
|
||||
@ -9,55 +9,8 @@
|
||||
<at-panel class="at-Stdout">
|
||||
<div class="at-Panel-headingTitle">{{ vm.title }}</div>
|
||||
<at-job-stats resource="vm.resource"></at-job-stats>
|
||||
<!-- search ===================================================================================== -->
|
||||
<form ng-submit="vm.search.submitSearch()">
|
||||
<div class="input-group">
|
||||
<input type="text"
|
||||
class="form-control at-Input"
|
||||
ng-class="{ 'at-Input--rejected': vm.search.rejected }"
|
||||
ng-model="vm.search.value"
|
||||
ng-attr-placeholder="{{ vm.search.disabled ? 'CANNOT SEARCH RUNNING JOB' : 'SEARCH' }}"
|
||||
ng-disabled="vm.search.disabled">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn at-ButtonHollow--default at-Input-button"
|
||||
ng-click="vm.search.submitSearch()"
|
||||
ng-disabled="vm.search.disabled"
|
||||
type="button">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
<button class="btn jobz-Button-searchKey"
|
||||
ng-if="vm.search.key"
|
||||
ng-disabled="vm.search.disabled"
|
||||
ng-click="vm.search.toggleSearchKey()"
|
||||
type="button"> key
|
||||
</button>
|
||||
<button class="btn at-ButtonHollow--default at-Input-button"
|
||||
ng-if="!vm.search.key"
|
||||
ng-disabled="vm.search.disabled"
|
||||
ng-click="vm.search.toggleSearchKey()"
|
||||
type="button"> key
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<at-job-search></at-job-search>
|
||||
|
||||
<div class="jobz-tagz">
|
||||
<div class="LabelList-tagContainer" ng-repeat="tag in vm.search.tags track by $index">
|
||||
<div class="LabelList-tag LabelList-tag--deletable"><span class="LabelList-name">{{ tag }}</span></div>
|
||||
<div class="LabelList-deleteContainer" ng-click="vm.search.removeSearchTag($index)">
|
||||
<i class="fa fa-times LabelList-tagDelete"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div><a href class="jobz-searchClearAll" ng-click="vm.search.clearSearch()" ng-show="!(vm.search.tags | isEmpty)">CLEAR ALL</a></div>
|
||||
</div>
|
||||
|
||||
<at-search-key
|
||||
ng-show="vm.search.key"
|
||||
fields="vm.search.searchKeyFields"
|
||||
examples="vm.search.searchKeyExamples">
|
||||
</at-search-key>
|
||||
|
||||
<!-- ============================================================================================ -->
|
||||
<div class="at-Stdout-menuTop">
|
||||
<div class="pull-left" ng-click="vm.expand()">
|
||||
<i class="at-Stdout-menuIcon fa"
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const templateUrl = require('~features/output/search-key.partial.html');
|
||||
|
||||
function atSearchKeyLink (scope, el, attrs, controllers) {
|
||||
const [atSearchKeyController] = controllers;
|
||||
|
||||
atSearchKeyController.init(scope);
|
||||
}
|
||||
|
||||
function AtSearchKeyController () {
|
||||
const vm = this || {};
|
||||
|
||||
vm.init = scope => {
|
||||
vm.examples = scope.examples || [];
|
||||
vm.fields = scope.fields || [];
|
||||
vm.relatedFields = scope.relatedFields || [];
|
||||
};
|
||||
}
|
||||
|
||||
AtSearchKeyController.$inject = ['$scope'];
|
||||
|
||||
function atSearchKey () {
|
||||
return {
|
||||
templateUrl,
|
||||
restrict: 'E',
|
||||
require: ['atSearchKey'],
|
||||
controllerAs: 'vm',
|
||||
link: atSearchKeyLink,
|
||||
controller: AtSearchKeyController,
|
||||
scope: {
|
||||
examples: '=',
|
||||
fields: '=',
|
||||
relatedFields: '=',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default atSearchKey;
|
||||
@ -1,20 +0,0 @@
|
||||
<!-- todo: styling, css etc. - disposition according to project lib conventions -->
|
||||
<div class="jobz-searchKeyPaneContainer">
|
||||
<div class="jobz-searchKeyPane">
|
||||
<div class="SmartSearch-keyRow">
|
||||
<div class="SmartSearch-examples">
|
||||
<div class="SmartSearch-examples--title"><b>EXAMPLES:</b></div>
|
||||
<div class="SmartSearch-examples--search" ng-repeat="tag in vm.examples"> {{ tag }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="SmartSearch-keyRow">
|
||||
<b>FIELDS:</b>
|
||||
<span ng-repeat="field in vm.fields">{{ field }}<span ng-if="!$last">, </span></span>
|
||||
</div>
|
||||
<div class="SmartSearch-keyRow">
|
||||
<b>ADDITIONAL INFORMATION:</b>
|
||||
For additional information on advanced search search syntax please see the Ansible Tower
|
||||
<a ng-attr-href="undefined" target="_blank">documentation</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
119
awx/ui/client/features/output/search.directive.js
Normal file
119
awx/ui/client/features/output/search.directive.js
Normal file
@ -0,0 +1,119 @@
|
||||
const templateUrl = require('~features/output/search.partial.html');
|
||||
|
||||
const searchReloadOptions = { reload: true, inherit: false };
|
||||
const searchKeyExamples = ['id:>1', 'task:set', 'created:>=2000-01-01'];
|
||||
const searchKeyFields = ['changed', 'failed', 'host_name', 'stdout', 'task', 'role', 'playbook', 'play'];
|
||||
|
||||
let $state;
|
||||
let status;
|
||||
let qs;
|
||||
|
||||
let vm;
|
||||
|
||||
function toggleSearchKey () {
|
||||
vm.key = !vm.key;
|
||||
}
|
||||
|
||||
function getCurrentQueryset () {
|
||||
const { job_event_search } = $state.params; // eslint-disable-line camelcase
|
||||
|
||||
return qs.decodeArr(job_event_search);
|
||||
}
|
||||
|
||||
function getSearchTags (queryset) {
|
||||
return qs.createSearchTagsFromQueryset(queryset)
|
||||
.filter(tag => !tag.startsWith('event'))
|
||||
.filter(tag => !tag.startsWith('-event'))
|
||||
.filter(tag => !tag.startsWith('page_size'))
|
||||
.filter(tag => !tag.startsWith('order_by'));
|
||||
}
|
||||
|
||||
function removeSearchTag (index) {
|
||||
const searchTerm = vm.tags[index];
|
||||
|
||||
const currentQueryset = getCurrentQueryset();
|
||||
const modifiedQueryset = qs.removeTermsFromQueryset(currentQueryset, searchTerm);
|
||||
|
||||
vm.tags = getSearchTags(modifiedQueryset);
|
||||
|
||||
$state.params.job_event_search = qs.encodeArr(modifiedQueryset);
|
||||
$state.transitionTo($state.current, $state.params, searchReloadOptions);
|
||||
}
|
||||
|
||||
function submitSearch () {
|
||||
const searchInputQueryset = qs.getSearchInputQueryset(vm.value);
|
||||
|
||||
const currentQueryset = getCurrentQueryset();
|
||||
const modifiedQueryset = qs.mergeQueryset(currentQueryset, searchInputQueryset);
|
||||
|
||||
vm.tags = getSearchTags(modifiedQueryset);
|
||||
|
||||
$state.params.job_event_search = qs.encodeArr(modifiedQueryset);
|
||||
$state.transitionTo($state.current, $state.params, searchReloadOptions);
|
||||
}
|
||||
|
||||
function clearSearch () {
|
||||
vm.tags = [];
|
||||
|
||||
$state.params.job_event_search = '';
|
||||
$state.transitionTo($state.current, $state.params, searchReloadOptions);
|
||||
}
|
||||
|
||||
function atJobSearchLink (scope, el, attrs, controllers) {
|
||||
const [atJobSearchController] = controllers;
|
||||
|
||||
atJobSearchController.init(scope);
|
||||
}
|
||||
|
||||
function AtJobSearchController (_$state_, _status_, _qs_) {
|
||||
$state = _$state_;
|
||||
status = _status_;
|
||||
qs = _qs_;
|
||||
|
||||
vm = this || {};
|
||||
|
||||
vm.value = '';
|
||||
vm.key = false;
|
||||
vm.rejected = false;
|
||||
vm.disabled = true;
|
||||
vm.tags = getSearchTags(getCurrentQueryset());
|
||||
|
||||
vm.clearSearch = clearSearch;
|
||||
vm.searchKeyExamples = searchKeyExamples;
|
||||
vm.searchKeyFields = searchKeyFields;
|
||||
vm.toggleSearchKey = toggleSearchKey;
|
||||
vm.removeSearchTag = removeSearchTag;
|
||||
vm.submitSearch = submitSearch;
|
||||
|
||||
vm.init = scope => {
|
||||
vm.examples = scope.examples || searchKeyExamples;
|
||||
vm.fields = scope.fields || searchKeyFields;
|
||||
vm.relatedFields = scope.relatedFields || [];
|
||||
|
||||
scope.$watch(status.isRunning, value => { vm.disabled = value; });
|
||||
};
|
||||
}
|
||||
|
||||
AtJobSearchController.$inject = [
|
||||
'$state',
|
||||
'JobStatusService',
|
||||
'QuerySet',
|
||||
];
|
||||
|
||||
function atJobSearch () {
|
||||
return {
|
||||
templateUrl,
|
||||
restrict: 'E',
|
||||
require: ['atJobSearch'],
|
||||
controllerAs: 'vm',
|
||||
link: atJobSearchLink,
|
||||
controller: AtJobSearchController,
|
||||
scope: {
|
||||
examples: '=',
|
||||
fields: '=',
|
||||
relatedFields: '=',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default atJobSearch;
|
||||
61
awx/ui/client/features/output/search.partial.html
Normal file
61
awx/ui/client/features/output/search.partial.html
Normal file
@ -0,0 +1,61 @@
|
||||
<!-- todo: styling, css etc. - disposition according to project lib conventions -->
|
||||
<form ng-submit="vm.submitSearch()">
|
||||
<div class="input-group">
|
||||
<input type="text"
|
||||
class="form-control at-Input"
|
||||
ng-class="{ 'at-Input--rejected': vm.rejected }"
|
||||
ng-model="vm.value"
|
||||
ng-attr-placeholder="{{ vm.disabled ? 'CANNOT SEARCH RUNNING JOB' : 'SEARCH' }}"
|
||||
ng-disabled="vm.disabled">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn at-ButtonHollow--default at-Input-button"
|
||||
ng-click="vm.submitSearch()"
|
||||
ng-disabled="vm.disabled"
|
||||
type="button">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
<button class="btn jobz-Button-searchKey"
|
||||
ng-if="vm.key"
|
||||
ng-disabled="vm.disabled"
|
||||
ng-click="vm.toggleSearchKey()"
|
||||
type="button"> key
|
||||
</button>
|
||||
<button class="btn at-ButtonHollow--default at-Input-button"
|
||||
ng-if="!vm.key"
|
||||
ng-disabled="vm.disabled"
|
||||
ng-click="vm.toggleSearchKey()"
|
||||
type="button"> key
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="jobz-tagz">
|
||||
<div class="LabelList-tagContainer" ng-repeat="tag in vm.tags track by $index">
|
||||
<div class="LabelList-tag LabelList-tag--deletable"><span class="LabelList-name">{{ tag }}</span></div>
|
||||
<div class="LabelList-deleteContainer" ng-click="vm.removeSearchTag($index)">
|
||||
<i class="fa fa-times LabelList-tagDelete"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div><a href class="jobz-searchClearAll" ng-click="vm.clearSearch()" ng-show="!(vm.tags | isEmpty)">CLEAR ALL</a></div>
|
||||
</div>
|
||||
|
||||
<div class="jobz-searchKeyPaneContainer" ng-show="vm.key">
|
||||
<div class="jobz-searchKeyPane">
|
||||
<div class="SmartSearch-keyRow">
|
||||
<div class="SmartSearch-examples">
|
||||
<div class="SmartSearch-examples--title"><b>EXAMPLES:</b></div>
|
||||
<div class="SmartSearch-examples--search" ng-repeat="tag in vm.examples"> {{ tag }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="SmartSearch-keyRow">
|
||||
<b>FIELDS:</b>
|
||||
<span ng-repeat="field in vm.fields">{{ field }}<span ng-if="!$last">, </span></span>
|
||||
</div>
|
||||
<div class="SmartSearch-keyRow">
|
||||
<b>ADDITIONAL INFORMATION:</b>
|
||||
For additional information on advanced search search syntax please see the Ansible Tower
|
||||
<a ng-attr-href="undefined" target="_blank">documentation</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user