diff --git a/app/assets/stylesheets/design/custom.scss b/app/assets/stylesheets/design/custom.scss index 41df6aff6..d1d359adf 100644 --- a/app/assets/stylesheets/design/custom.scss +++ b/app/assets/stylesheets/design/custom.scss @@ -1102,7 +1102,9 @@ div#advisory_search_block div.continue_input { } form.mass_build section.left { - margin-left: 50px; + margin-left: 10px; + width: 350px; + margin-top: 15px; } form.mass_build section.right { diff --git a/app/controllers/platforms/repositories_controller.rb b/app/controllers/platforms/repositories_controller.rb index fcb064849..059a45a53 100644 --- a/app/controllers/platforms/repositories_controller.rb +++ b/app/controllers/platforms/repositories_controller.rb @@ -112,25 +112,29 @@ class Platforms::RepositoriesController < Platforms::BaseController sort_dir = params[:sSortDir_0]=="asc" ? 'asc' : 'desc' order = "#{colName[sort_col.to_i]} #{sort_dir}" - if params[:added] == "true" - @projects = @repository.projects + if params[:text] == 'true' + render :text => @repository.projects.map(&:name).join("\n") else - @projects = Project.joins(owner_subquery).addable_to_repository(@repository.id) - @projects = @projects.by_visibilities('open') if @repository.platform.platform_type == 'main' - end - @projects = @projects.paginate( - :page => (params[:iDisplayStart].to_i/(params[:iDisplayLength].present? ? params[:iDisplayLength] : 25).to_i).to_i + 1, - :per_page => params[:iDisplayLength].present? ? params[:iDisplayLength] : 25 - ) + if params[:added] == "true" + @projects = @repository.projects + else + @projects = Project.joins(owner_subquery).addable_to_repository(@repository.id) + @projects = @projects.by_visibilities('open') if @repository.platform.platform_type == 'main' + end + @projects = @projects.paginate( + :page => (params[:iDisplayStart].to_i/(params[:iDisplayLength].present? ? params[:iDisplayLength] : 25).to_i).to_i + 1, + :per_page => params[:iDisplayLength].present? ? params[:iDisplayLength] : 25 + ) - @total_projects = @projects.count - @projects = @projects.search(params[:sSearch]).search_order if params[:sSearch].present? - @projects = @projects.order(order) + @total_projects = @projects.count + @projects = @projects.search(params[:sSearch]).search_order if params[:sSearch].present? + @projects = @projects.order(order) - respond_to do |format| - format.json { - render :partial => (params[:added] == "true") ? 'project' : 'proj_ajax', :layout => false - } + respond_to do |format| + format.json { + render :partial => (params[:added] == "true") ? 'project' : 'proj_ajax', :layout => false + } + end end end diff --git a/app/views/platforms/mass_builds/_repos_or_list_choice.html.haml b/app/views/platforms/mass_builds/_repos_or_list_choice.html.haml new file mode 100644 index 000000000..37662b8c0 --- /dev/null +++ b/app/views/platforms/mass_builds/_repos_or_list_choice.html.haml @@ -0,0 +1,48 @@ +#repos_or_list.accordion + .accordion-group + .accordion-heading + %a.accordion-toggle{"data-parent" => "#repos_or_list", "data-toggle" => "collapse", :href => "#collapseRepos"} + =t("layout.mass_builds.repositories") + #collapseRepos.accordion-body.collapse.in + .accordion-inner + -@platform.repositories.each do |rep| + .both + =check_box_tag "repositories[]", rep.id, (params[:repositories]||[]).include?(rep.id.to_s), :id => "repositories_#{rep.id}", :href => "#{projects_list_platform_repository_path(@platform, rep)}?text=true" + =label_tag "repositories_#{rep.id}", rep.name + .accordion-group + .accordion-heading + %a.accordion-toggle{"data-parent" => "#repos_or_list", "data-toggle" => "collapse", :href => "#collapseList"} + =t("layout.mass_builds.projects_list") + #collapseList.accordion-body.collapse + .accordion-inner + =text_area_tag :projects_list, nil, :style => 'min-width:315px;' +:javascript + $(document).ready(function() { + var projects_list = $('.form.mass_build #projects_list'); + var repositories = $(".form.mass_build #collapseRepos input:checkbox"); + repositories.click(function(){ + if (this.checked){ + $(this).attr('disabled',true); + $.ajax({ + type: 'GET', + url: $(this).attr('href'), + success: function(data){ + var text = projects_list.val(); + if(text.length > 0 && text.slice(-1) != '\n') {text = text + "\n"} + projects_list.val(text+data); + }, + error: function(data){ + alert('Error :(') // TODO remove + } + }); + } + return true; + }); + + projects_list.keyup(function(){ + if($(this).val().length == 0) { + repositories.attr('disabled',false) + .attr('checked', false); + } + }); + }); diff --git a/app/views/platforms/mass_builds/index.html.haml b/app/views/platforms/mass_builds/index.html.haml index 4967c095d..7cd1eb021 100644 --- a/app/views/platforms/mass_builds/index.html.haml +++ b/app/views/platforms/mass_builds/index.html.haml @@ -3,13 +3,7 @@ = form_for :build, :url => platform_mass_builds_path(@platform), :html => { :class => 'form mass_build', :method => :post } do |f| %section.left - %h3= t("layout.mass_builds.repositories") - - @platform.repositories.each do |rep| - .both - = check_box_tag "repositories[]", rep.id, (params[:repositories]||[]).include?(rep.id.to_s), :id => "repositories_#{rep.id}" - = label_tag "repositories_#{rep.id}", rep.name - %h3= t("layout.mass_builds.projects_list") - = text_area_tag :projects_list, nil + =render 'repos_or_list_choice' %br = f.submit t("layout.projects.build_button") %section.right diff --git a/vendor/assets/javascripts/bootstrap-collapse.js b/vendor/assets/javascripts/bootstrap-collapse.js new file mode 100644 index 000000000..2b0a2baad --- /dev/null +++ b/vendor/assets/javascripts/bootstrap-collapse.js @@ -0,0 +1,156 @@ +/* ============================================================= + * bootstrap-collapse.js v2.2.1 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * 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. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSIBLE PLUGIN DEFINITION + * ============================== */ + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = typeof option == 'object' && option + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSIBLE DATA-API + * ==================== */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.jQuery); \ No newline at end of file diff --git a/vendor/assets/javascripts/vendor.js b/vendor/assets/javascripts/vendor.js index 08fc17f77..2d5b2170d 100644 --- a/vendor/assets/javascripts/vendor.js +++ b/vendor/assets/javascripts/vendor.js @@ -15,6 +15,7 @@ // require bootstrap-popover //= require bootstrap-alert //= require bootstrap-tab +//= require bootstrap-collapse //= require chosen.jquery // require html5shiv // require_tree . diff --git a/vendor/assets/stylesheets/bootstrap.css b/vendor/assets/stylesheets/bootstrap.css index f5b1a58bc..6478473d8 100644 --- a/vendor/assets/stylesheets/bootstrap.css +++ b/vendor/assets/stylesheets/bootstrap.css @@ -815,4 +815,39 @@ a.badge:hover { .badge-inverse[href] { background-color: #1a1a1a; } - +.accordion { + margin-bottom: 20px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +}