move search into feature-level component

This commit is contained in:
Jake McDermott 2018-04-02 23:47:45 -04:00
parent 1f9b325f38
commit a5e20117e3
No known key found for this signature in database
GPG Key ID: 3B02CAD476EECB35
7 changed files with 183 additions and 192 deletions

View File

@ -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',
];

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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>

View 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;

View 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>