Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/issues.js.coffee12
-rw-r--r--app/assets/javascripts/jquery.multiawesome.js354
-rw-r--r--app/assets/javascripts/multiawesome.js390
-rw-r--r--app/assets/stylesheets/application.scss5
-rw-r--r--app/assets/stylesheets/multiawesome.css105
-rw-r--r--app/views/shared/issuable/_filter.html.haml13
6 files changed, 873 insertions, 6 deletions
diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee
index ac9e022e727..da22cf2a851 100644
--- a/app/assets/javascripts/issues.js.coffee
+++ b/app/assets/javascripts/issues.js.coffee
@@ -16,12 +16,12 @@
else
$(this).html totalIssues - 1
$("body").on "click", ".issues-other-filters .dropdown-menu a", ->
- $('.issues-list').block(
- message: null,
- overlayCSS:
- backgroundColor: '#DDD'
- opacity: .4
- )
+ # $('.issues-list').block(
+ # message: null,
+ # overlayCSS:
+ # backgroundColor: '#DDD'
+ # opacity: .4
+ # )
reload: ->
Issues.initSelects()
diff --git a/app/assets/javascripts/jquery.multiawesome.js b/app/assets/javascripts/jquery.multiawesome.js
new file mode 100644
index 00000000000..f2253cdd0ad
--- /dev/null
+++ b/app/assets/javascripts/jquery.multiawesome.js
@@ -0,0 +1,354 @@
+//= require sifter.js
+
+/**
+ * multiawesome.js (v0.12.1)
+ * Copyright (c) 2015 Jacob Schatz & contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at:
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ *
+ * @author Jacob Schatz <jschatz@gitlab.com>
+ */
+
+/*jshint curly:false */
+/*jshint browser:true */
+(function ( $ ) {
+ $.fn.multiawesome = function( settings ) {
+ settings = settings || {};
+ var MultiAwesome = {
+ searchTemplate: '<li><div class="input-with-icon"><i class="fa fa-search"></i><input type="text" id="multiawesome-search-input" /></div></li>',
+ itemContainerTemplate: '<li class="dropdown-multi-menu-selections"><ul></ul></li>',
+ itemTemplate: '<li><a href="#" class="item" tabIndex="-1"><input type="checkbox" name="{{name}}" value="{{data}}"/>{{label}}</a></li>',
+ seperatorTemplate: '<li role="separator" class="divider"></li>',
+ titleTemplate: '<li class=dropdown-multi-menu-title><div class=dropdown-multi-menu-title-area><h3>{{title}}</h3></div></li>',
+ categoryContainerTemplate: '<li class=dropdown-multi-menu-category><ul></ul></li>',
+ categoryItemTemplate: '<li><a href="#" class="category" tabIndex="-1"><input type="checkbox" value="{{category}}"/>{{category}}</a></li>',
+ tipTemplate: '<li class=dropdown-multi-menu-tip><div class=dropdown-multi-menu-tip-area><p>{{tip}}</p></div></li>',
+ minSearchLength: 2,
+ };
+
+
+ return this.each(function() {
+ var self = this,
+ categories = [],
+ $self = $(self),
+ $form = $(self).closest('form'),
+ $itemContainer,
+ $itemContainerUL,
+ itemTemplate,
+ itemContainerTemplate,
+ categoriesSet = false,
+ selectedItems = [],
+ selectedCategories = [],
+ $searchInput,
+ multiple = typeof $self.attr('data-multiple') !== 'undefined',
+ currentData = settings.data || $self.data('data'),
+ inputName = $(self).data('name'),
+ sifter,
+ dataObject = {
+ label: 'label',
+ data: 'data',
+ category: 'category'
+ };
+
+ if( self.tagName !== 'UL') {
+ return;
+ }
+
+ var prepareDropdown = function() {
+ var placeholder = $self.data('placeholder');
+ if( typeof settings.searchTemplate !== 'undefined' ) {
+ MultiAwesome.searchTemplate = settings.searchTemplate;
+ }
+
+ $self.prepend(MultiAwesome.searchTemplate);
+ if( placeholder ) {
+ $('#multiawesome-search-input').prop( 'placeholder', placeholder );
+ }
+ };
+
+ var attachBtnListeners = function() {
+ $( 'ul.dropdown-multi-menu' ).on( 'click', 'li.dropdown-multi-menu-category a' , dropdownCategoryLinkClicked );
+ $( 'ul.dropdown-multi-menu' ).on( 'click', 'li.dropdown-multi-menu-selections a', dropdownSelectionLinkClicked );
+ $searchInput = $('#multiawesome-search-input');
+ $searchInput.on( 'keydown keyup update', inputSearched );
+ };
+
+ var parseSearchResults = function(results) {
+ var finalData = [];
+ results.forEach( function( result ) {
+ finalData.push(currentData[result.id]);
+ });
+ renderData( finalData );
+ };
+
+ var inputSearched = function() {
+ var minSearchLength = settings.minSearchLength || MultiAwesome.minSearchLength;
+
+ //remove current hidden inputs
+ $('input[type="hidden"][name="' + inputName + '"]').remove();
+
+ if( $searchInput.val().length > minSearchLength ) {
+ var results = sifter.search($searchInput.val(), {
+ fields: [dataObject.label],
+ sort: [{field: dataObject.label, direction: 'asc'}]
+ });
+ parseSearchResults(results.items);
+ } else {
+ renderData( currentData );
+ }
+ };
+
+ var configureData = function() {
+ if ( typeof settings.itemLabelTitle !== 'undefined' ) {
+ dataObject.label = settings.itemLabelTitle;
+ }
+
+ if ( typeof settings.itemDataTitle !== 'undefined' ) {
+ dataObject.data = settings.itemDataTitle;
+ }
+
+ if ( typeof settings.itemCategoryTitle !== 'undefined' ) {
+ dataObject.category = settings.itemCategoryTitle;
+ }
+ };
+
+ var addCategories = function() {
+ var $categoryContainer;
+ var $categoryContainerUL;
+ if( categories.length ) {
+ if( typeof settings.categoryContainerTemplate !== 'undefined' ) {
+ $categoryContainer = $(settings.categoryContainerTemplate);
+ } else {
+ $categoryContainer = $(MultiAwesome.categoryContainerTemplate);
+ }
+ $categoryContainerUL = $categoryContainer.find('ul');
+ $self.prepend(MultiAwesome.seperatorTemplate);
+ categories.forEach(function( category ) {
+ $categoryContainerUL.prepend( MultiAwesome.categoryItemTemplate
+ .replace( /{{category}}/g, category ) );
+ });
+ $self.prepend($categoryContainer);
+ }
+ };
+
+ var addTitle = function() {
+ var titleTemplate;
+ var titleData = $self.data('title') || settings.title;
+ if( typeof titleData !== 'undefined') {
+ if(typeof settings.titleTemplate !== 'undefined') {
+ titleTemplate = settings.titleTemplate;
+ } else {
+ titleTemplate = MultiAwesome.titleTemplate;
+ }
+ $self.prepend(MultiAwesome.seperatorTemplate);
+ $self.prepend(titleTemplate
+ .replace(/{{title}}/g, titleData)
+ );
+ }
+ };
+
+ var addData = function(callback) {
+ function parseDataWhenReady() {
+ itemTemplate = MultiAwesome.itemTemplate;
+ itemContainerTemplate = MultiAwesome.itemContainerTemplate;
+ if( typeof settings.itemTemplate !== 'undefined' ) {
+ itemTemplate = settings.itemTemplate;
+ }
+ if( typeof settings.itemContainerTemplate !== 'undefined' ) {
+ itemContainerTemplate = settings.itemContainerTemplate;
+ }
+ $itemContainer = $(itemContainerTemplate);
+ $itemContainerUL = $itemContainer.find('ul');
+
+ sifter = new Sifter(currentData);
+ renderData( currentData,callback );
+ }
+ configureData();
+ if ( typeof currentData !== 'undefined' ) {
+ if ( typeof currentData === 'string') {
+ $.getJSON(currentData, function(data) {
+ currentData = data;
+ parseDataWhenReady();
+ });
+ } else if ( typeof currentData === 'object' ) {
+ parseDataWhenReady();
+ }
+ }
+ };
+
+ var renderData = function( data, callback ) {
+ selectedItems = [];
+ $itemContainerUL.empty();
+ var emptyObj = {};
+ var skipMatch = false;
+ if( !data.length ) {
+ emptyObj[dataObject.label] = 'No matches found';
+ emptyObj[dataObject.data] = '';
+ emptyObj[dataObject.category] = '';
+ data.push(emptyObj);
+ skipMatch = true;
+ }
+ data.forEach( function( item ) {
+ if( !categoriesSet && !skipMatch ) {
+ var addCategory = item[dataObject.category];
+ if( item.hasOwnProperty( dataObject.category ) && categories.indexOf( addCategory ) === -1 ) {
+ categories.push( addCategory );
+ }
+ } else {
+ // only do this if the categories are already set... they won't search categories on the first time.
+ if( selectedCategories.length &&
+ selectedCategories.indexOf(item[dataObject.category]) === -1 &&
+ !skipMatch) {
+ return;
+ }
+ }
+
+ $itemContainerUL.append(
+ itemTemplate
+ .replace(/{{data}}/g,item[dataObject.data])
+ .replace(/{{label}}/g,item[dataObject.label])
+ .replace(/{{name}}/g, '_' + inputName)
+ );
+ });
+ if( !categoriesSet ) {
+ $self.append($itemContainer);
+ }
+
+ if( categories.length ){
+ categoriesSet = true;
+ }
+
+ if( callback ) {
+ callback();
+ }
+ };
+
+ var addToForm = function( val ) {
+ $form.prepend('<input type="hidden" name="' + inputName + '" value="' + val + '" />');
+ };
+
+ var removeFromForm = function( val ) {
+ $form
+ .find('input[name="' + inputName + '"][value="' + val + '"]')
+ .remove();
+ };
+
+ /* * * * * * * * * * * * * * * */
+ /* listeners
+ /* * * * * * * * * * * * * * * */
+ var dropdownInputClicked = function( e ) {
+ return false;
+ };
+
+ var dropdownCategoryLinkClicked = function ( e ) {
+ var $target = $( e.currentTarget ),
+ $inp = $target.find( 'input' ),
+ val = $inp.val(),
+ i = selectedCategories.indexOf( val );
+
+ if ( i > -1 ) {
+ var spliced = selectedCategories.splice( i, 1 );
+ $target.removeClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', false );
+ }, 0);
+ } else {
+ selectedCategories.push( val );
+ $target.addClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', true );
+ }, 0);
+ }
+
+ inputSearched();
+
+ $( e.target ).blur();
+ return false;
+ };
+
+ var dropdownSelectionLinkClicked = function ( e ) {
+ var $target = $( e.currentTarget ),
+ $inp = $target.find( 'input' ),
+ val = $inp.val(),
+ i = selectedItems.indexOf( val );
+
+ if ( i > -1 ) {
+ var spliced = selectedItems.splice( i, 1 );
+ if( multiple ) {
+ removeFromForm( spliced );
+ } else {
+ $form
+ .find('input[name="' + inputName + '"]')
+ .remove();
+ }
+
+ $target.removeClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', false );
+ }, 0);
+ } else {
+ if( !multiple ) {
+ selectedItems = [];
+ $form
+ .find('input[name="' + inputName + '"]')
+ .remove();
+ $form
+ .find('input[name="_' + inputName + '"]')
+ .parent()
+ .removeClass('selected');
+ }
+
+ selectedItems.push( val );
+ addToForm( val );
+ $target.addClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', true );
+ }, 0);
+ }
+ $( e.target ).blur();
+ return false;
+
+ };
+
+ var addTip = function() {
+ var tipTemplate;
+ var tipData = $self.data('tip') || settings.tip;
+ if( typeof tipData !== 'undefined') {
+ if(typeof settings.tipTemplate !== 'undefined') {
+ tipTemplate = settings.tipTemplate;
+ } else {
+ tipTemplate = MultiAwesome.tipTemplate;
+ }
+ $self.append(MultiAwesome.seperatorTemplate);
+ $self.append(tipTemplate
+ .replace(/{{tip}}/g, tipData)
+ );
+ }
+ };
+
+ /* * * * * * * * * * * * * * * */
+ /* setup
+ /* * * * * * * * * * * * * * * */
+
+ var setup = function() {
+ addData(function(){
+ addCategories();
+ prepareDropdown();
+ addTitle();
+ attachBtnListeners();
+ addTip();
+ });
+ };
+
+ setup();
+
+ });
+ };
+})( jQuery ); \ No newline at end of file
diff --git a/app/assets/javascripts/multiawesome.js b/app/assets/javascripts/multiawesome.js
new file mode 100644
index 00000000000..7c078e2f8e2
--- /dev/null
+++ b/app/assets/javascripts/multiawesome.js
@@ -0,0 +1,390 @@
+//= require sifter
+/**
+ * multiawesome.js (v0.12.1)
+ * Copyright (c) 2015 Jacob Schatz & contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at:
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ *
+ * @author Jacob Schatz <jschatz@gitlab.com>
+ */
+
+/*jshint curly:false */
+/*jshint browser:true */
+(function ( $ ) {
+ 'use strict';
+ $.fn.multiawesome = function( settings ) {
+ settings = settings || {};
+ var MultiAwesome = {
+ searchTemplate: '<li><div class="input-with-icon"><i class="fa fa-search"></i><input type="text" id="multiawesome-search-input" /></div></li>',
+ itemContainerTemplate: '<li class="dropdown-multi-menu-selections"><ul></ul></li>',
+ itemTemplate: '<li><a href="#" class="item" tabIndex="-1"><input type="checkbox" name="{{name}}" value="{{data}}"/>{{label}}</a></li>',
+ seperatorTemplate: '<li role="separator" class="divider"></li>',
+ titleTemplate: '<li class=dropdown-multi-menu-title><div class=dropdown-multi-menu-title-area><h3>{{title}}</h3></div></li>',
+ categoryContainerTemplate: '<li class=dropdown-multi-menu-category><ul></ul></li>',
+ categoryItemTemplate: '<li><a href="#" class="category" tabIndex="-1"><input type="checkbox" value="{{category}}"/>{{category}}</a></li>',
+ tipTemplate: '<li class=dropdown-multi-menu-tip><div class=dropdown-multi-menu-tip-area><p>{{tip}}</p></div></li>',
+ minSearchLength: 2
+ };
+
+
+ return this.each(function() {
+ var self = this,
+ categories = [],
+ $self = $(self),
+ $form = $(self).closest('form'),
+ $itemContainer,
+ $itemContainerUL,
+ itemTemplate,
+ itemContainerTemplate,
+ categoriesSet = false,
+ selectedItems = [],
+ selectedCategories = [],
+ $searchInput,
+ onChange = settings.onChange || function(){},
+ multiple = typeof $self.attr('data-multiple') !== 'undefined',
+ currentData = settings.data || $self.data('data'),
+ inputName = $(self).data('name'),
+ sifter,
+ alwaysData = settings.always || [],
+ dataObject = {
+ label: 'label',
+ data: 'data',
+ category: 'category'
+ };
+
+ if( self.tagName !== 'UL') {
+ return;
+ }
+
+ var prepareDropdown = function() {
+ var placeholder = $self.data('placeholder');
+ if( typeof settings.searchTemplate !== 'undefined' ) {
+ MultiAwesome.searchTemplate = settings.searchTemplate;
+ }
+
+ $self.prepend(MultiAwesome.searchTemplate);
+ if( placeholder ) {
+ $('#multiawesome-search-input').prop( 'placeholder', placeholder );
+ }
+ };
+
+ var attachBtnListeners = function() {
+ $( 'ul.dropdown-multi-menu' ).on( 'click', 'li.dropdown-multi-menu-category a' , dropdownCategoryLinkClicked );
+ $( 'ul.dropdown-multi-menu' ).on( 'click', 'li.dropdown-multi-menu-selections a', dropdownSelectionLinkClicked );
+ $searchInput = $('#multiawesome-search-input');
+ $searchInput.on( 'keydown keyup update', inputSearched );
+ };
+
+ var parseSearchResults = function(results) {
+ var finalData = [];
+ results.forEach( function( result ) {
+ finalData.push(currentData[result.id]);
+ });
+ renderData( finalData );
+ };
+
+ var inputSearched = function() {
+ var minSearchLength = settings.minSearchLength || MultiAwesome.minSearchLength;
+
+ //remove current hidden inputs
+ $('input[type="hidden"][name="' + inputName + '"]').remove();
+
+ if( $searchInput.val().length > minSearchLength ) {
+ var results = sifter.search($searchInput.val(), {
+ fields: [dataObject.label],
+ sort: [{field: dataObject.label, direction: 'asc'}]
+ });
+ parseSearchResults(results.items);
+ } else {
+ renderData( currentData );
+ }
+ };
+
+ var configureData = function() {
+ if ( typeof settings.itemLabelTitle !== 'undefined' ) {
+ dataObject.label = settings.itemLabelTitle;
+ }
+
+ if ( typeof settings.itemDataTitle !== 'undefined' ) {
+ dataObject.data = settings.itemDataTitle;
+ }
+
+ if ( typeof settings.itemCategoryTitle !== 'undefined' ) {
+ dataObject.category = settings.itemCategoryTitle;
+ }
+ };
+
+ var addCategories = function() {
+ var $categoryContainer;
+ var $categoryContainerUL;
+ if( categories.length ) {
+ if( typeof settings.categoryContainerTemplate !== 'undefined' ) {
+ $categoryContainer = $(settings.categoryContainerTemplate);
+ } else {
+ $categoryContainer = $(MultiAwesome.categoryContainerTemplate);
+ }
+ $categoryContainerUL = $categoryContainer.find('ul');
+ $self.prepend(MultiAwesome.seperatorTemplate);
+ categories.forEach(function( category ) {
+ $categoryContainerUL.prepend( MultiAwesome.categoryItemTemplate
+ .replace( /\{\{category\}\}/g, category ) );
+ });
+ $self.prepend($categoryContainer);
+ }
+ };
+
+ var addTitle = function() {
+ var titleTemplate;
+ var titleData = $self.data('title') || settings.title;
+ if( typeof titleData !== 'undefined') {
+ if(typeof settings.titleTemplate !== 'undefined') {
+ titleTemplate = settings.titleTemplate;
+ } else {
+ titleTemplate = MultiAwesome.titleTemplate;
+ }
+ $self.prepend(MultiAwesome.seperatorTemplate);
+ $self.prepend(titleTemplate
+ .replace(/\{\{title\}\}/g, titleData)
+ );
+ }
+ };
+
+ var addData = function(callback) {
+ function parseDataWhenReady() {
+ itemTemplate = MultiAwesome.itemTemplate;
+ itemContainerTemplate = MultiAwesome.itemContainerTemplate;
+ if( typeof settings.itemTemplate !== 'undefined' ) {
+ itemTemplate = settings.itemTemplate;
+ }
+ if( typeof settings.itemContainerTemplate !== 'undefined' ) {
+ itemContainerTemplate = settings.itemContainerTemplate;
+ }
+ $itemContainer = $(itemContainerTemplate);
+ $itemContainerUL = $itemContainer.find('ul');
+
+ sifter = new Sifter(currentData);
+ renderData( currentData,callback );
+ }
+ configureData();
+ if ( typeof currentData !== 'undefined' ) {
+ if ( typeof currentData === 'string') {
+ $.getJSON(currentData, function(data) {
+ currentData = data;
+ parseDataWhenReady();
+ });
+ } else if ( typeof currentData === 'object' ) {
+ parseDataWhenReady();
+ }
+ }
+ };
+
+ var renderData = function( data, callback ) {
+ selectedItems = [];
+ $itemContainerUL.empty();
+ var emptyObj = {};
+ var skipMatch = false;
+ if( !data.length ) {
+ emptyObj[dataObject.label] = 'No matches found';
+ emptyObj[dataObject.data] = '';
+ emptyObj[dataObject.category] = '';
+ data.push(emptyObj);
+ skipMatch = true;
+ }
+ data = data.concat(alwaysData);
+ data.forEach( function( item ) {
+ if( !categoriesSet && !skipMatch ) {
+ var addCategory = item[dataObject.category];
+ if( item.hasOwnProperty( dataObject.category ) && categories.indexOf( addCategory ) === -1 ) {
+ categories.push( addCategory );
+ }
+ } else {
+ // only do this if the categories are already set... they won't search categories on the first time.
+ if( selectedCategories.length &&
+ selectedCategories.indexOf(item[dataObject.category]) === -1 &&
+ !skipMatch) {
+ return;
+ }
+ }
+
+ $itemContainerUL.append(
+ itemTemplate
+ .replace(/\{\{data\}\}/g,item[dataObject.data])
+ .replace(/\{\{label\}\}/g,item[dataObject.label])
+ .replace(/\{\{name\}\}/g, '_' + inputName)
+ );
+ });
+ if( !categoriesSet ) {
+ $self.append($itemContainer);
+ }
+
+ if( categories.length ){
+ categoriesSet = true;
+ }
+
+ if( callback ) {
+ callback();
+ }
+ };
+
+ var addToForm = function( val ) {
+ $form.prepend('<input type="hidden" name="' + inputName + '" value="' + val + '" />');
+ };
+
+ var removeFromForm = function( val ) {
+ $form
+ .find('input[name="' + inputName + '"][value="' + val + '"]')
+ .remove();
+ };
+
+ /* * * * * * * * * * * * * * * */
+ /* listeners
+ /* * * * * * * * * * * * * * * */
+ var dropdownInputClicked = function( e ) {
+ return false;
+ };
+
+ var dropdownCategoryLinkClicked = function ( e ) {
+ var $target = $( e.currentTarget ),
+ $inp = $target.find( 'input' ),
+ val = $inp.val(),
+ i = selectedCategories.indexOf( val );
+
+ e.preventDefault();
+
+ if ( i > -1 ) {
+ var spliced = selectedCategories.splice( i, 1 );
+ $target.removeClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', false );
+ }, 0);
+ } else {
+ selectedCategories.push( val );
+ $target.addClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', true );
+ }, 0);
+ }
+
+ inputSearched();
+
+ $( e.target ).blur();
+ return false;
+ };
+
+ var findItemWithData = function(searchData, id) {
+ var item = {};
+ for (var i = searchData.length - 1; i >= 0; i--) {
+ item = searchData[i];
+ if( item.hasOwnProperty(dataObject.data) && item[dataObject.data] == id ) {
+ return item;
+ }
+ };
+ return undefined;
+ };
+
+ var dropdownSelectionLinkClicked = function ( e ) {
+ var $target = $( e.currentTarget ),
+ $inp = $target.find( 'input' ),
+ findItemInData,
+ val = $inp.val(),
+ i = selectedItems.indexOf( val );
+
+ e.preventDefault();
+
+ if ( i > -1 ) {
+ var spliced = selectedItems.splice( i, 1 );
+ if( multiple ) {
+ removeFromForm( spliced );
+ } else {
+ $form
+ .find('input[name="' + inputName + '"]')
+ .remove();
+ }
+
+ $target.removeClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', false );
+ }, 0);
+ } else {
+ if( !multiple ) {
+ selectedItems = [];
+ $form
+ .find('input[name="' + inputName + '"]')
+ .remove();
+ $form
+ .find('input[name="_' + inputName + '"]')
+ .parent()
+ .removeClass('selected');
+ }
+ findItemInData = findItemWithData(currentData, val);
+ if( typeof findItemInData === 'undefined' ) {
+ findItemInData = findItemWithData(alwaysData, val)
+ }
+ onChange(findItemInData);
+
+ selectedItems.push( val );
+ addToForm( val );
+ $target.addClass('selected');
+ setTimeout( function() {
+ $inp.prop( 'checked', true );
+ }, 0);
+ }
+ if( multiple ) {
+ // close the dropdown if single selection
+ $( e.target ).blur();
+ return false;
+ } else {
+ var button = $self.prevAll('.dropdown-toggle');
+ $self.prevAll('.dropdown-toggle')
+ .contents()
+ .each(
+ function(){
+ if ( this.nodeType === 3 && this.nodeValue.trim() ) {
+ this.textContent = $target.text();
+ }
+ });
+ }
+ };
+
+ var addTip = function() {
+ var tipTemplate;
+ var tipData = $self.data('tip') || settings.tip;
+ if( typeof tipData !== 'undefined') {
+ if(typeof settings.tipTemplate !== 'undefined') {
+ tipTemplate = settings.tipTemplate;
+ } else {
+ tipTemplate = MultiAwesome.tipTemplate;
+ }
+ $self.append(MultiAwesome.seperatorTemplate);
+ $self.append(tipTemplate
+ .replace(/\{\{tip\}\}/g, tipData)
+ );
+ }
+ };
+
+ /* * * * * * * * * * * * * * * */
+ /* setup
+ /* * * * * * * * * * * * * * * */
+
+ var setup = function() {
+ addData(function(){
+ addCategories();
+ prepareDropdown();
+ addTitle();
+ attachBtnListeners();
+ addTip();
+ });
+ };
+
+ setup();
+
+ });
+ };
+})( jQuery ); \ No newline at end of file
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 0c0451fe4dd..2400782ecf0 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -49,3 +49,8 @@
* Styles for JS behaviors.
*/
@import "behaviors.scss";
+
+/*
+ * Styles for multiawesome
+ */
+@import "multiawesome"; \ No newline at end of file
diff --git a/app/assets/stylesheets/multiawesome.css b/app/assets/stylesheets/multiawesome.css
new file mode 100644
index 00000000000..a0c77a85bfd
--- /dev/null
+++ b/app/assets/stylesheets/multiawesome.css
@@ -0,0 +1,105 @@
+.open>.dropdown-multi-menu {
+ max-width: 320px;
+ border-radius: 0px;
+}
+
+.dropdown-multi-menu input[type='text'] {
+ margin: 0 5px;
+ width: 309px;
+ height: 35px;
+ padding-left: 6px;
+}
+
+.dropdown-multi-menu input[type='checkbox'] {
+ margin: 0 5px;
+ display: none;
+}
+
+.dropdown-multi-menu>li>a {
+ padding-left: 0;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-title-area h3 {
+ font-size: 15px;
+ text-align: center;
+ margin-top: 5px;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-title-area h3::after {
+ content: "";
+ background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAACGUlEQVQ4jZ2VMXbiMBCGf83KKcxzntOmI1VMEyj2BLpD9gRbwQVygeUCpMsdcgKfQaYJqeIu1RYGC/stNjNbJOaBY8hu/lrz69PoH0mJCBaLhVEArqMoxhf0vFgYARBFUawWT08my7KxiMD3/fhmOLz/H7PE2ruyLL8rpRCG4b0WEQjzeVXXxq3X59ba8zAMZ/1+Pz9l9PLyEiyXy0lRFGZb18bTOhYR6GgwiOdJcu3Wa9R1bZxz5r1mespwuVxOnHO/mBla69jv9R6jwSAmALgZDu9934+JCMyMoiiMtfYuTdOgbZSmaWCtvSuKwjAziOigVbpZGIbhDACKojCnSLMsOyTz/bipPTB879nUWgvnnNkjxdnZ2TMAbDab6zbZaDQ62FCjpS5SIgIAMDOOkTVSItLZ9CRJxnmez5gZzRqlFIgIQRBMhkfiRZ1uADzPeyUiiMiOTERARPA87/VY3VHDr+pDDxtVVXXJzLtjAm9HZmZUVXV5rO5DD9M0DbIsmzSXQkQ4dSntifpA2JWzdmxO5XRnuE92KmddOd0n3Rl+NgGNPpsoAoB5koy7yLpenH6/n49Go2l79udJMgaAbz9ub02+Wv2s69poreNer/cQhuHs4uJi0zbbV1mWcxHJt9sttnVtmPmPc+63VkpBEa205z36vh8fm4C2rq6ucgDTxFqUZbkiolwplavmCwDenvB/MWtr/wv5CwCanfXE6iK0AAAAAElFTkSuQmCC');
+ background-repeat: no-repeat;
+ background-size: 11px;
+ width: 12px;
+ height: 12px;
+ display: inline-block;
+ position: absolute;
+ right: 13px;
+ top: 13px;
+ cursor: pointer;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-selections {
+ max-height: 150px;
+ overflow-y: scroll;
+ margin-top: 15px;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-category ul{
+ padding-left: 15px;
+ list-style: none;
+ max-height: 65px;
+ overflow-y: scroll;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-selections ul{
+ padding-left: 15px;
+ list-style: none;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-selections li{
+ margin-bottom: 10px;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-selections ul a, .dropdown-multi-menu .dropdown-multi-menu-category ul a{
+ text-decoration: none;
+ color: #333;
+ display: inline-block;
+ width: 285px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ height: 30px;
+ padding-left: 30px;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-selections ul a.selected, .dropdown-multi-menu .dropdown-multi-menu-category ul a.selected {
+ background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAYCAMAAADat72NAAABtlBMVEX////b29vc29vc3NzZ2dna2dnb2trY19fZ2NjV1dXW1tbT09PU09PV1NTR0dHS0dHS0tLPz8/Qz8/Q0NDNzc3Ozc3Ly8vMy8vMzMzJycnKycnKysrIyMjJyMjKyMjFxcXGxcXGxsbHxcXHxsbEw8PExMTFxMTBwcHBwsLCwcG/v7+9vb2+vr6/vr67u7u8vLy5ubm6ubm7ubm3t7e4t7e4uLi1tbW3tra0s7OysbGysrKzsbGvr6+wr6+urq6vrq6sq6utrKypqamrqqqsqqqop6epp6eqqKimpaWnpaWnpqako6OkpKSlo6OioaGjoqKkoqKgn5+goKChn5+hoKCenp6fnp6cm5ucnJydm5udnJyenJx+fX1/fHx/fX2Afn6Af3+Bf3+BgICCgICCgYGDgYGDgoKEgoKFgoKFg4OGhISGhYWHhYWIh4eJh4eJiIiJiYmKiIiLiYmLioqMioqMi4uNi4uNjIyOjIyPjY2Qjo6Qj4+SkJCSkZGTkZGTkpKUk5OVk5OVlJSWlZWXlZWYlpaYl5eYmJiZmJiZmZmamJibmZmbmpqcm5uenp6fn5+op6erqqouFWZ5AAAAXHRSTlMADw8PFhYWHR0kJCwsLDMzMzo6OkJCSUlJUFBQV1dXX19fX19mZmZtbW11fHx8g4OKioqSkpKZmaCoqKivr7a2vb3FxcXMzMzT09Pb29vi4uLp6enp8PD4+Pj4+E8lS9YAAAEjSURBVCjPY2DACYRtrDhwywralTZL45RldymLb5LEJctkWBOXHiSAS9q8OSOzxRiXrGJPWmqdNTcOWY3ggtQyN15cXvIpTCnxVcIhK+pYnZwZLYdDls22Nj2rywiHLKNeW2p8oxaMK6vGgiKt05edVGXPDOWJB7S6KyPJSgVnxZRb8sC4Co2JJV4icFkJl6KYXB8hOJ8/KiW5wl8TyuN0KonP81BEMs24Iye10A8S+Kwm1bGZESoobtHszkwtDtUGMS0aUjM7TdG8YhRZmJIdLc/IpNqWktpoxonuVeWw3OTC3gkT+/NTK525MINCN6QsNSuvND+93FUGW1CJeZekJiSn5wSKYw9KNc/q9IS8cH1cCYDPoT63XR13ypQwczbAEAQAnkJCZAp/V+QAAAAASUVORK5CYII=');
+ background-repeat: no-repeat;
+ background-size: 16px;
+ background-position: 2px 4px;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-tip-area {
+ margin: 10px;
+ text-align: left;
+ max-height: 40px;
+ overflow-y: scroll;
+}
+
+.dropdown-multi-menu .dropdown-multi-menu-tip-area p {
+ margin-bottom: 0;
+}
+
+.dropdown-multi-menu .input-with-icon {
+ position: relative;
+ margin: 10px 0;
+}
+
+.dropdown-multi-menu .input-with-icon i {
+ position: absolute;
+ right: 0;
+ padding: 10px 12px;
+ color: #817F7F;
+ pointer-events: none;
+}
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index be06738eac9..2acb319b927 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -42,6 +42,11 @@
class: 'select2 trigger-submit', include_blank: true,
data: {placeholder: 'Milestone'})
+ .filter-item.inline.people-filter.btn-group
+ %button.btn.btn-default.dropdown-toggle{ "data-toggle" => 'dropdown' }
+ People
+ %span.caret
+ %ul.dropdown-menu.dropdown-multi-menu
.filter-item.inline.labels-filter
= select_tag('label_name', projects_labels_options,
class: 'select2 trigger-submit', include_blank: true,
@@ -70,3 +75,11 @@
event.preventDefault();
Turbolinks.visit(this.action + '&' + $(this).serialize());
});
+
+ $('ul.dropdown-multi-menu').multiawesome({
+ data: [{label:'milestone',data:1},{label:'no milestone',data:1}],
+ title: "Milestones",
+ onChange: function(item) {
+ console.log("changed",item)
+ }
+ });