#158: advanced search form (wip)

This commit is contained in:
Benjamin Gamard 2017-11-12 23:24:10 +01:00
parent dca8c28b84
commit 742ff183bf
6 changed files with 136 additions and 40 deletions

View File

@ -422,6 +422,26 @@ angular.module('docs',
Restangular.one('theme').get().then(function(data) { Restangular.one('theme').get().then(function(data) {
$rootScope.appName = data.name; $rootScope.appName = data.name;
}); });
// Languages
$rootScope.acceptedLanguages = [
{ key: 'eng', label: 'English' },
{ key: 'fra', label: 'Français' },
{ key: 'ita', label: 'Italiano' },
{ key: 'deu', label: 'Deutsch' },
{ key: 'spa', label: 'Español' },
{ key: 'por', label: 'Português' },
{ key: 'pol', label: 'Polski' },
{ key: 'rus', label: 'русский' },
{ key: 'ukr', label: 'українська' },
{ key: 'ara', label: 'العربية' },
{ key: 'hin', label: 'हिन्दी' },
{ key: 'chi_sim', label: '简体中文' },
{ key: 'chi_tra', label: '繁体中文' },
{ key: 'jpn', label: '日本語' },
{ key: 'tha', label: 'ภาษาไทย' },
{ key: 'kor', label: '한국어' }
];
}) })
/** /**
* Initialize ngProgress. * Initialize ngProgress.

View File

@ -3,7 +3,7 @@
/** /**
* Document controller. * Document controller.
*/ */
angular.module('docs').controller('Document', function ($scope, $rootScope, $timeout, $state, Restangular) { angular.module('docs').controller('Document', function ($scope, $rootScope, $timeout, $state, Restangular, $q) {
/** /**
* Documents table sort status. * Documents table sort status.
*/ */
@ -13,6 +13,7 @@ angular.module('docs').controller('Document', function ($scope, $rootScope, $tim
$scope.currentPage = 1; $scope.currentPage = 1;
$scope.limit = _.isUndefined(localStorage.documentsPageSize) ? 10 : localStorage.documentsPageSize; $scope.limit = _.isUndefined(localStorage.documentsPageSize) ? 10 : localStorage.documentsPageSize;
$scope.search = $state.params.search ? $state.params.search : ''; $scope.search = $state.params.search ? $state.params.search : '';
$scope.searchOpened = false;
$scope.setSearch = function (search) { $scope.search = search }; $scope.setSearch = function (search) { $scope.search = search };
// A timeout promise is used to slow down search requests to the server // A timeout promise is used to slow down search requests to the server
@ -115,9 +116,9 @@ angular.module('docs').controller('Document', function ($scope, $rootScope, $tim
}; };
// Load tags // Load tags
var tags = []; $scope.tags = [];
Restangular.one('tag/list').get().then(function (data) { Restangular.one('tag/list').get().then(function (data) {
tags = data.tags; $scope.tags = data.tags;
}); });
/** /**
@ -125,11 +126,29 @@ angular.module('docs').controller('Document', function ($scope, $rootScope, $tim
* @param parent * @param parent
*/ */
$scope.getChildrenTags = function(parent) { $scope.getChildrenTags = function(parent) {
return _.filter(tags, function(tag) { return _.filter($scope.tags, function(tag) {
return tag.parent === parent; return tag.parent === parent;
}); });
}; };
/**
* Returns a promise for typeahead user.
*/
$scope.getUserTypeahead = function($viewValue) {
var deferred = $q.defer();
Restangular.one('user/list')
.get({
search: $viewValue,
sort_column: 1,
asc: true
}).then(function(data) {
deferred.resolve(_.pluck(_.filter(data.users, function(user) {
return user.username.indexOf($viewValue) !== -1;
}), 'username'));
});
return deferred.promise;
};
// Hack to reload the pagination directive after language change // Hack to reload the pagination directive after language change
$scope.paginationShown = true; $scope.paginationShown = true;
$rootScope.$on('$translateChangeSuccess', function () { $rootScope.$on('$translateChangeSuccess', function () {
@ -138,4 +157,13 @@ angular.module('docs').controller('Document', function ($scope, $rootScope, $tim
$scope.paginationShown = true; $scope.paginationShown = true;
}); });
}) })
// Advanced search
$scope.searchDropdownAnchor = angular.element(document.querySelector('.search-dropdown-anchor'));
$scope.openSearch = function () {
var opened = $scope.searchOpened;
$timeout(function () {
$scope.searchOpened = !opened;
});
}
}); });

View File

@ -51,22 +51,7 @@
<label class="col-sm-2 control-label" for="inputLanguage">{{ 'document.language' | translate }}</label> <label class="col-sm-2 control-label" for="inputLanguage">{{ 'document.language' | translate }}</label>
<div class="col-sm-10"> <div class="col-sm-10">
<select class="form-control" id="inputLanguage" ng-model="document.language" ng-disabled="fileIsUploading"> <select class="form-control" id="inputLanguage" ng-model="document.language" ng-disabled="fileIsUploading">
<option value="eng">English</option> <option ng-repeat="language in acceptedLanguages" value="{{ language.key }}">{{ language.label }}</option>
<option value="fra">Français</option>
<option value="ita">Italiano</option>
<option value="deu">Deutsch</option>
<option value="spa">Español</option>
<option value="por">Português</option>
<option value="pol">Polski</option>
<option value="rus">русский</option>
<option value="ukr">українська</option>
<option value="ara">العربية</option>
<option value="hin">हिन्दी</option>
<option value="chi_sim">简体中文</option>
<option value="chi_tra">繁体中文</option>
<option value="jpn">日本語</option>
<option value="tha">ภาษาไทย</option>
<option value="kor">한국어</option>
</select> </select>
</div> </div>
</div> </div>

View File

@ -5,38 +5,79 @@
<a href="#/document/add" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span> {{ 'document.add_document' | translate }}</a> <a href="#/document/add" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span> {{ 'document.add_document' | translate }}</a>
</p> </p>
<div class="row"> <div class="row search-dropdown-anchor">
<div class="dropdown col-md-2 tag-tree-dropdown" uib-dropdown> <div class="col-xs-2 tag-tree-dropdown" uib-dropdown>
<button class="btn btn-block btn-default" uib-dropdown-toggle ng-disabled="disabled"> <button class="btn btn-block btn-default" uib-dropdown-toggle ng-disabled="disabled">
{{ 'document.tags' | translate }} <span class="caret"></span> {{ 'document.tags' | translate }} <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu tag-tree"> <ul uib-dropdown-menu class="tag-tree">
<li ng-if="getChildrenTags().length == 0">{{ 'document.no_tags' | translate }}</li> <li ng-if="getChildrenTags().length == 0">{{ 'document.no_tags' | translate }}</li>
<li ng-repeat="tag in getChildrenTags()" ng-include="'tag-tree-item'"></li> <li ng-repeat="tag in getChildrenTags()" ng-include="'tag-tree-item'"></li>
</ul> </ul>
</div> </div>
<div class="col-md-10 input-group"> <div class="col-xs-10 input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon glyphicon-info-sign"
tooltip-placement="bottom"
uib-tooltip-html="'before:2012-05<br/>
after:2012-05<br/>
at:2012-05<br/>
tag:car<br/>
full:led<br/>
shared:yes<br/>
lang:fra<br/>
by:user1'"></span>
</span>
<input type="search" class="form-control" ng-attr-placeholder="{{ 'document.search' | translate }}" ng-model="search" /> <input type="search" class="form-control" ng-attr-placeholder="{{ 'document.search' | translate }}" ng-model="search" />
<span class="input-group-addon"> <span class="input-group-addon pointer" ng-click="openSearch()">
<span class="glyphicon glyphicon-search" ng-show="search.length == 0"></span> <div uib-dropdown
<span class="glyphicon glyphicon-remove" ng-show="search.length > 0" ng-click="search = ''"></span> auto-close="outsideClick" is-open="searchOpened" dropdown-append-to="searchDropdownAnchor">
<span class="btn-open-search">
<span class="glyphicon glyphicon-search"></span>
<span class="caret"></span>
</span>
<div uib-dropdown-menu class="search-dropdown-menu col-xs-12" ng-click="$event.stopPropagation()">
<form class="form-horizontal" name="searchForm" novalidate>
<div class="form-group">
<label class="control-label sr-only" for="inputSearchSimple">{{ 'document.search_simple' | translate }}</label>
<div class="col-sm-12">
<input type="text" id="inputSearchSimple" class="form-control" ng-attr-placeholder="{{ 'document.search_simple' | translate }}" ng-model="advsearch.search_simple" />
</div>
</div>
<div class="form-group">
<label class="control-label sr-only" for="inputSearchFulltext">{{ 'document.search_fulltext' | translate }}</label>
<div class="col-sm-12">
<input type="text" id="inputSearchFulltext" class="form-control" ng-attr-placeholder="{{ 'document.search_fulltext' | translate }}" ng-model="advsearch.search_fulltext" />
</div>
</div>
<div class="form-group">
<label class="control-label sr-only" for="inputSearchCreator">{{ 'document.search_creator' | translate }}</label>
<div class="col-sm-12">
<input type="text" id="inputSearchCreator" class="form-control" ng-model="advsearch.creator"
ng-attr-placeholder="{{ 'document.search_creator' | translate }}"
uib-typeahead="user for user in getUserTypeahead($viewValue)"
typeahead-wait-ms="200" typeahead-editable="false" autocomplete="off" />
</div>
</div>
<div class="form-group">
<label class="control-label sr-only" for="inputSearchLanguage">{{ 'document.search_language' | translate }}</label>
<div class="col-sm-12">
<select class="form-control" id="inputSearchLanguage" ng-model="advsearch.language">
<option value="">{{ 'document.any_language' | translate }}</option>
<option ng-repeat="language in acceptedLanguages" value="{{ language.key }}">{{ language.label }}</option>
</select>
</div>
</div>
<div class="form-group text-center">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-search"></span> {{ 'document.search' | translate }}
</button>
<button class="btn" ng-click="advsearch = {}">
{{ 'document.clear' | translate }}
</button>
</div>
</form>
</div>
</div>
</span> </span>
</div> </div>
</div> </div>
{{advsearch}}
<table class="row table table-hover table-documents"> <table class="row table table-hover table-documents">
<thead> <thead>
<tr> <tr>

View File

@ -2990,7 +2990,7 @@ select[multiple].input-lg {
padding: 6px 12px; padding: 6px 12px;
margin-bottom: 0; margin-bottom: 0;
font-size: 14px; font-size: 14px;
font-weight: normal; font-weight: bold;
line-height: 1.42857143; line-height: 1.42857143;
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;

View File

@ -287,6 +287,28 @@ input[readonly].share-link {
} }
} }
// Advanced search
.btn-open-search > * {
vertical-align: middle;
}
.btn-open-search .glyphicon {
top: 0;
}
.search-dropdown-anchor {
position: relative;
}
.search-dropdown-menu {
left: 0 !important;
top: 34px !important;
padding-top: 15px;
padding-left: 15px;
padding-right: 15px;
padding-bottom: 0;
}
// Vertical alignment // Vertical alignment
.vertical-center { .vertical-center {
min-height: 100vh; min-height: 100vh;