[issue #428] Changed attaching advisory to BuildList.
Removed Chosen. Added text field with incremental search.
This commit is contained in:
parent
e4f62ea592
commit
094f25c049
|
@ -3,7 +3,91 @@ Rosa.Models.Advisory = Backbone.Model.extend({
|
||||||
id: null,
|
id: null,
|
||||||
description: null,
|
description: null,
|
||||||
references: null,
|
references: null,
|
||||||
update_type: null
|
update_type: null,
|
||||||
|
found: false
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
_.bindAll(this, 'findByAdvisoryID');
|
||||||
|
|
||||||
|
this.url = '/advisories';
|
||||||
|
},
|
||||||
|
|
||||||
|
findByAdvisoryID: function(id, bl_type, options) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var urlError = function() {
|
||||||
|
throw new Error("A 'url' property or function must be specified");
|
||||||
|
};
|
||||||
|
|
||||||
|
var typeError = function() {
|
||||||
|
throw new Error("A 'bl_type' must be 'security' or 'bugfix'");
|
||||||
|
};
|
||||||
|
|
||||||
|
var idError = function() {
|
||||||
|
throw new Error("A 'id' must be a string at least 4 characters long");
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( (typeof(id) != "string") || (id.length < 4) ) {
|
||||||
|
idError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (bl_type == undefined) || (bl_type == null) || ((bl_type != 'security') && (bl_type != 'bugfix')) ) {
|
||||||
|
typeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
options |= {};
|
||||||
|
var data = _.extend({
|
||||||
|
query: id,
|
||||||
|
bl_type: bl_type
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
var params = _.extend({
|
||||||
|
type: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
beforeSend: function( xhr ) {
|
||||||
|
var token = $('meta[name="csrf-token"]').attr('content');
|
||||||
|
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
|
||||||
|
|
||||||
|
self.trigger('search:start');
|
||||||
|
}
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
if (!params.url) {
|
||||||
|
params.url = ((_.isFunction(this.url) ? this.url() : this.url) + '/search') || urlError();
|
||||||
|
}
|
||||||
|
|
||||||
|
params.data = data;
|
||||||
|
|
||||||
|
var complete = options.complete;
|
||||||
|
params.complete = function(jqXHR, textStatus) {
|
||||||
|
//console.log(jqXHR);
|
||||||
|
|
||||||
|
switch (jqXHR.status) {
|
||||||
|
case 200:
|
||||||
|
self.set(_.extend({
|
||||||
|
found: true
|
||||||
|
}, JSON.parse(jqXHR.responseText)), {silent: true});
|
||||||
|
self.trigger('search:end');
|
||||||
|
break
|
||||||
|
|
||||||
|
case 404:
|
||||||
|
self.set(self.defaults, {silent: true});
|
||||||
|
self.trigger('search:end');
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
self.set(self.defaults, {silent: true});
|
||||||
|
self.trigger('search:failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complete) complete(jqXHR, textStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax(params);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@ Rosa.Routers.BuildListsAdvisoriesRouter = Backbone.Router.extend({
|
||||||
routes: {},
|
routes: {},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.advisoriesCollection = new Rosa.Collections.AdvisoriesCollection(Rosa.bootstrapedData.advisories);
|
this.advisoriesView = new Rosa.Views.BuildListAdvisoriesView({ model: new Rosa.Models.Advisory() });
|
||||||
this.advisoriesView = new Rosa.Views.BuildListAdvisoriesView({ collection: this.advisoriesCollection });
|
|
||||||
|
|
||||||
this.advisoriesView.render();
|
this.advisoriesView.render();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,42 @@
|
||||||
Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({
|
Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
_.bindAll(this, 'popoverTitle', 'popoverDesc', 'showAdvisory',
|
_.bindAll(this, 'showAdvisory', 'showPreview', 'showForm',
|
||||||
'changeAdvisoryList', 'showPreview', 'showForm', 'hideAll');
|
'showSearch', 'hideAll', 'displayStatus', 'processSearch');
|
||||||
$('.chzn-select').chosen();
|
this.$el = $('#advisory_block');
|
||||||
this.$el = $('#advisory_block');
|
this._$type_select = $('#build_list_update_type');
|
||||||
this._$form = this.$('#new_advisory_form');
|
this._$publish_button = $('input[type="submit"][name="publish"]');
|
||||||
this._$preview = this.$('#advisory_preview');
|
|
||||||
this._$type_select = $('#build_list_update_type');
|
this._$form = this.$('#new_advisory_form');
|
||||||
this._$selector = this.$('#attach_advisory');
|
this._$preview = this.$('#advisory_preview');
|
||||||
|
|
||||||
|
this._$search = this.$('#advisory_search_block');
|
||||||
|
this._$search_field = this.$('#advisory_search');
|
||||||
|
this._$not_found = this.$('#advisory_search_block > .advisory_not_found');
|
||||||
|
this._$server_error = this.$('#advisory_search_block > .server_error');
|
||||||
|
this._$continue_input = this.$('#advisory_search_block > .continue_input');
|
||||||
|
this._search_timer = null;
|
||||||
|
|
||||||
|
this._$selector = this.$('#attach_advisory');
|
||||||
|
|
||||||
this._header_text = this._$preview.children('h3').html();
|
this._header_text = this._$preview.children('h3').html();
|
||||||
|
|
||||||
this._$selector.on('change', this.showAdvisory);
|
this._$selector.on('change', this.showAdvisory);
|
||||||
this._$type_select.on('change', this.changeAdvisoryList);
|
this._$search_field.on('input keyup', this.processSearch);
|
||||||
|
var self = this;
|
||||||
|
this._$type_select.on('change', function() {
|
||||||
|
self._$search_field.trigger('input');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.model.on('search:start', function() {
|
||||||
|
this._$publish_button.prop({disabled: true});
|
||||||
|
}, this);
|
||||||
|
this.model.on('search:end', this.showPreview, this);
|
||||||
|
this.model.on('search:failed', this.handleSearchError, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
changeAdvisoryList: function() {
|
showAdvisory: function(ev) {
|
||||||
this.$('.popoverable').hide();
|
|
||||||
this.$('.popoverable.' + this._$type_select.val()).show();
|
|
||||||
this._$selector.val('no').trigger("liszd:updated").trigger('change');
|
|
||||||
},
|
|
||||||
|
|
||||||
popoverTitle: function(el) {
|
|
||||||
console.log(el);
|
|
||||||
console.log(el.html());
|
|
||||||
return el.html();
|
|
||||||
},
|
|
||||||
|
|
||||||
popoverDesc: function(el) {
|
|
||||||
return this.collection.get(el.html()).get('popover_desc');
|
|
||||||
},
|
|
||||||
|
|
||||||
showAdvisory: function(el) {
|
|
||||||
var adv_id = this._$selector.val();
|
var adv_id = this._$selector.val();
|
||||||
|
this._$publish_button.prop({disabled: false});
|
||||||
switch (adv_id) {
|
switch (adv_id) {
|
||||||
case 'no':
|
case 'no':
|
||||||
this.hideAll();
|
this.hideAll();
|
||||||
|
@ -40,21 +45,70 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({
|
||||||
this.showForm();
|
this.showForm();
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
this.showPreview(adv_id);
|
this.showSearch();
|
||||||
|
this._$publish_button.prop({disabled: true});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
processSearch: function(ev) {
|
||||||
|
if (ev.type == "keyup") {
|
||||||
|
if (ev.keyCode != 13) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var TIMER_INTERVAL = 500;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var timerCallback = function() {
|
||||||
|
if (self._$search_field.val().length > 3) {
|
||||||
|
// real search
|
||||||
|
self.model.findByAdvisoryID(self._$search_field.val(), self._$type_select.val());
|
||||||
|
} else {
|
||||||
|
// hide preview if nothing to show
|
||||||
|
if (self._$preview.is(':visible')) {
|
||||||
|
self._$preview.slideUp();
|
||||||
|
}
|
||||||
|
self.displayStatus('found');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.model.get('advisory_id') == this._$search_field.val()) {
|
||||||
|
this.showPreview();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// timeout before real AJAX request
|
||||||
|
clearTimeout(this._search_timer);
|
||||||
|
this._search_timer = setTimeout(timerCallback, TIMER_INTERVAL);
|
||||||
|
},
|
||||||
|
|
||||||
showPreview: function(id) {
|
showPreview: function(id) {
|
||||||
|
this._$publish_button.prop({disabled: false});
|
||||||
if (this._$form.is(':visible')) {
|
if (this._$form.is(':visible')) {
|
||||||
this._$form.slideUp();
|
this._$form.slideUp();
|
||||||
}
|
}
|
||||||
var adv = this.collection.get(id);
|
|
||||||
var prev = this._$preview;
|
var prev = this._$preview;
|
||||||
prev.children('h3').html(this._header_text + ' ' + adv.get('advisory_id'));
|
var adv = this.model;
|
||||||
prev.children('.descr').html(adv.get('description'));
|
if (adv.get('found')) {
|
||||||
prev.children('.refs').html(adv.get('references'));
|
this._$selector.children('option.advisory_id').val(adv.get('advisory_id'));
|
||||||
if (!this._$preview.is(':visible')) {
|
|
||||||
this._$preview.slideDown();
|
prev.children('h3').html(this._header_text + ' ' + adv.get('advisory_id'));
|
||||||
|
prev.children('.descr').html(adv.get('description'));
|
||||||
|
prev.children('.refs').html(adv.get('references'));
|
||||||
|
if (!this._$preview.is(':visible')) {
|
||||||
|
this._$preview.slideDown();
|
||||||
|
}
|
||||||
|
this.displayStatus('found');
|
||||||
|
} else {
|
||||||
|
if (this._$preview.is(':visible')) {
|
||||||
|
this._$preview.slideUp();
|
||||||
|
}
|
||||||
|
this._$publish_button.prop({disabled: true});
|
||||||
|
this.displayStatus('not_found');
|
||||||
|
this._$selector.children('option.advisory_id').val('');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -62,12 +116,27 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({
|
||||||
if (this._$preview.is(':visible')) {
|
if (this._$preview.is(':visible')) {
|
||||||
this._$preview.slideUp();
|
this._$preview.slideUp();
|
||||||
}
|
}
|
||||||
|
if (this._$search.is(':visible')) {
|
||||||
|
this._$search.slideUp();
|
||||||
|
}
|
||||||
if (!this._$form.is(':visible')) {
|
if (!this._$form.is(':visible')) {
|
||||||
this._$form.slideDown();
|
this._$form.slideDown();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
hideAll: function() {
|
showSearch: function() {
|
||||||
|
if (this._$form.is(':visible')) {
|
||||||
|
this._$form.slideUp();
|
||||||
|
}
|
||||||
|
if (!this._$search.is(':visible')) {
|
||||||
|
this._$search.slideDown();
|
||||||
|
this._$search_field.trigger('input');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearchError: function() {
|
||||||
|
this._$publish_button.prop({disabled: true});
|
||||||
|
this.displayStatus('error');
|
||||||
if (this._$preview.is(':visible')) {
|
if (this._$preview.is(':visible')) {
|
||||||
this._$preview.slideUp();
|
this._$preview.slideUp();
|
||||||
}
|
}
|
||||||
|
@ -76,14 +145,33 @@ Rosa.Views.BuildListAdvisoriesView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
hideAll: function() {
|
||||||
|
if (this._$preview.is(':visible')) {
|
||||||
|
this._$preview.slideUp();
|
||||||
|
}
|
||||||
|
if (this._$search.is(':visible')) {
|
||||||
|
this._$search.slideUp();
|
||||||
|
}
|
||||||
|
if (this._$form.is(':visible')) {
|
||||||
|
this._$form.slideUp();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
displayStatus: function(st) {
|
||||||
|
var ELEMS = {
|
||||||
|
'found': this._$continue_input,
|
||||||
|
'not_found': this._$not_found,
|
||||||
|
'error': this._$server_error
|
||||||
|
};
|
||||||
|
|
||||||
|
this._$continue_input.hide();
|
||||||
|
this._$not_found.hide();
|
||||||
|
this._$server_error.hide();
|
||||||
|
|
||||||
|
ELEMS[st].show();
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var title = this.popoverTitle;
|
|
||||||
var description = this.popoverDesc;
|
|
||||||
this.changeAdvisoryList();
|
|
||||||
this.$('.popoverable').popover({
|
|
||||||
title: function() { return title($(this)); },
|
|
||||||
content: function() { return description($(this)); }
|
|
||||||
});
|
|
||||||
this.showAdvisory();
|
this.showAdvisory();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -954,10 +954,55 @@ form.mass_build input[type="checkbox"] {
|
||||||
height: 11px;
|
height: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#new_advisory_form, div#advisory_preview {
|
div#new_advisory_form,
|
||||||
|
div#advisory_preview,
|
||||||
|
div#advisory_search_block,
|
||||||
|
div#advisory_search_block div.info {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#advisory_search_block {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.hint_text {
|
||||||
|
color: #666666;
|
||||||
|
font-size: 0.9em;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#advisory_search_block p.hint_text {
|
||||||
|
display: block;
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#advisory_search_block div.info {
|
||||||
|
width: 565px;
|
||||||
|
border: solid 1px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#advisory_search_block div.info p {
|
||||||
|
text-align: center;
|
||||||
|
margin: 0.5em 2em 0.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#advisory_search_block div.advisory_not_found {
|
||||||
|
background-color: #B7CFFF;
|
||||||
|
border-color: #6666FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#advisory_search_block div.server_error {
|
||||||
|
background-color: #FACFCF;
|
||||||
|
border-color: #FF7777;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#advisory_search_block div.continue_input {
|
||||||
|
background-color: #CFFACF;
|
||||||
|
border-color: #00CF00;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
/*=============== popovers ===============*/
|
/*=============== popovers ===============*/
|
||||||
|
|
||||||
.popover {
|
.popover {
|
||||||
|
|
|
@ -25,4 +25,13 @@ class AdvisoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search
|
||||||
|
puts params[:bl_type]
|
||||||
|
@advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).limit(1).first
|
||||||
|
raise ActionController::RoutingError.new('Not Found') if @advisory.nil?
|
||||||
|
respond_to do |format|
|
||||||
|
format.json { render :json => @advisory }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
# -*- encoding : utf-8 -*-
|
# -*- encoding : utf-8 -*-
|
||||||
module AdvisoriesHelper
|
module AdvisoriesHelper
|
||||||
def advisories_select_options(advisories, opts = {:class => 'popoverable'})
|
def advisories_select_options(advisories, opts = {:class => 'popoverable'})
|
||||||
def_values = [[t("layout.advisories.no_"), 'no'], [t("layout.advisories.new"), 'new']]
|
def_values = [[t("layout.advisories.no_"), 'no'], [t("layout.advisories.new"), 'new'], [t("layout.advisories.existing"), 'existing', {:class => 'advisory_id'}]]
|
||||||
options_for_select(def_values, def_values.first) +
|
options_for_select(def_values, def_values.first)
|
||||||
options_for_select(advisories.map { |a| [a.advisory_id, :class => "#{opts[:class]} #{a.update_type}"] })
|
end
|
||||||
|
|
||||||
|
def advisory_id_for_hint
|
||||||
|
sprintf(Advisory::ID_STRING_TEMPLATE, :type => "{#{Advisory::TYPES.values.join(',')}}",
|
||||||
|
:year => 'YYYY', :id => 'XXXX')
|
||||||
end
|
end
|
||||||
|
|
||||||
def construct_ref_link(ref)
|
def construct_ref_link(ref)
|
||||||
|
|
|
@ -8,11 +8,12 @@ class Advisory < ActiveRecord::Base
|
||||||
after_create :generate_advisory_id
|
after_create :generate_advisory_id
|
||||||
before_save :normalize_references, :if => :references_changed?
|
before_save :normalize_references, :if => :references_changed?
|
||||||
|
|
||||||
ID_TEMPLATE = 'ROSA-%<type>s-%<year>d:%<id>04d'
|
ID_TEMPLATE = 'ROSA-%<type>s-%<year>d:%<id>04d'
|
||||||
|
ID_STRING_TEMPLATE = 'ROSA-%<type>s-%<year>04s:%<id>04s'
|
||||||
TYPES = {'security' => 'SA', 'bugfix' => 'A'}
|
TYPES = {'security' => 'SA', 'bugfix' => 'A'}
|
||||||
|
|
||||||
scope :by_project, lambda {|p| where('project_id' => p.try(:id) || p)}
|
|
||||||
scope :search_by_id, lambda { |aid| where('advisory_id ILIKE ?', "%#{aid.to_s.strip}%") }
|
scope :search_by_id, lambda { |aid| where('advisory_id ILIKE ?', "%#{aid.to_s.strip}%") }
|
||||||
|
scope :by_update_type, lambda { |ut| where(:update_type => ut) }
|
||||||
default_scope order('created_at DESC')
|
default_scope order('created_at DESC')
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
.leftlist= t("activerecord.attributes.build_list.update_type")
|
.leftlist= t("activerecord.attributes.build_list.update_type")
|
||||||
.rightlist
|
.rightlist
|
||||||
- if @build_list.can_publish? and can?(:publish, @build_list)
|
- if @build_list.can_publish? and can?(:publish, @build_list)
|
||||||
= f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type), {}, :class => 'chzn-select'
|
= f.select :update_type, options_for_select(BuildList::RELEASE_UPDATE_TYPES, @build_list.update_type)
|
||||||
- else
|
- else
|
||||||
= @build_list.update_type
|
= @build_list.update_type
|
||||||
.both
|
.both
|
||||||
|
@ -75,9 +75,23 @@
|
||||||
#advisory_block
|
#advisory_block
|
||||||
.leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory")
|
.leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory")
|
||||||
.rightlist
|
.rightlist
|
||||||
= select_tag :attach_advisory, advisories_select_options(@advisories), :class => 'chzn-select'
|
= select_tag :attach_advisory, advisories_select_options(@advisories)
|
||||||
.both
|
.both
|
||||||
|
|
||||||
|
#advisory_search_block
|
||||||
|
%h3= t("layout.advisories.search_by_id")
|
||||||
|
.leftlist= label_tag :advisory_search, t("layout.advisories.search_hint")
|
||||||
|
.rightlist
|
||||||
|
%input#advisory_search{:type => 'text'}
|
||||||
|
%p.hint_text= t("layout.advisories.advisory_id_info", :advisory_format => advisory_id_for_hint)
|
||||||
|
.both
|
||||||
|
.info.advisory_not_found
|
||||||
|
%p= t("layout.advisories.banners.advisory_not_found")
|
||||||
|
.info.server_error
|
||||||
|
%p= t("layout.advisories.banners.server_error")
|
||||||
|
.info.continue_input
|
||||||
|
%p= t("layout.advisories.banners.continue_input")
|
||||||
|
|
||||||
#new_advisory_form
|
#new_advisory_form
|
||||||
= f.fields_for @build_list.build_advisory do |f|
|
= f.fields_for @build_list.build_advisory do |f|
|
||||||
= render :partial => 'advisories/form', :locals => {:f => f}
|
= render :partial => 'advisories/form', :locals => {:f => f}
|
||||||
|
@ -92,11 +106,8 @@
|
||||||
.leftlist= t("activerecord.attributes.advisory.references")
|
.leftlist= t("activerecord.attributes.advisory.references")
|
||||||
.rightlist.refs
|
.rightlist.refs
|
||||||
.both
|
.both
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
$(function() {
|
$(function() {
|
||||||
Rosa.bootstrapedData.advisories = #{ render 'advisories/advisories.json.jbuilder',
|
|
||||||
:advisories => @advisories };
|
|
||||||
var r = new Rosa.Routers.BuildListsAdvisoriesRouter();
|
var r = new Rosa.Routers.BuildListsAdvisoriesRouter();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,7 +119,6 @@
|
||||||
- if @item_groups.blank?
|
- if @item_groups.blank?
|
||||||
%h4.nomargin= t("layout.build_lists.no_items_data")
|
%h4.nomargin= t("layout.build_lists.no_items_data")
|
||||||
- @item_groups.each_with_index do |group, level|
|
- @item_groups.each_with_index do |group, level|
|
||||||
-#%h4.nomargin= "#{group} ##{level}"
|
|
||||||
- group.each do |item|
|
- group.each do |item|
|
||||||
%h4.nomargin= "#{item.name} ##{level}"
|
%h4.nomargin= "#{item.name} ##{level}"
|
||||||
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
|
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
|
||||||
|
|
|
@ -10,7 +10,15 @@ en:
|
||||||
ref_comment: Add links one by row
|
ref_comment: Add links one by row
|
||||||
no_: No
|
no_: No
|
||||||
new: New
|
new: New
|
||||||
|
existing: Existing
|
||||||
search_by_id: Search advisory by it's ID
|
search_by_id: Search advisory by it's ID
|
||||||
|
search_hint: Paste full AdvisoryID into text field or enter there its uniq part.
|
||||||
|
advisory_id_info: AdvisoryID is a string %{advisory_format}, where 'XXXX' (at least 4 symbols) is a uniq part.
|
||||||
|
|
||||||
|
banners:
|
||||||
|
advisory_not_found: Couldn't find advisory with given ID for this type of Build List.
|
||||||
|
server_error: Server problem. Please try again later.
|
||||||
|
continue_input: Continue input while needed Advisory appears in preview.
|
||||||
|
|
||||||
flash:
|
flash:
|
||||||
advisories:
|
advisories:
|
||||||
|
|
|
@ -10,7 +10,15 @@ ru:
|
||||||
ref_comment: Вставляйте ссылки по одной на строку
|
ref_comment: Вставляйте ссылки по одной на строку
|
||||||
no_: Нет
|
no_: Нет
|
||||||
new: Новый
|
new: Новый
|
||||||
|
existing: Существующий
|
||||||
search_by_id: Искать бюллетень по его ID
|
search_by_id: Искать бюллетень по его ID
|
||||||
|
search_hint: Скопируйте в поле ввода полный AdvisoryID или введите его уникальную часть
|
||||||
|
advisory_id_info: AdvisoryID имеет формат %{advisory_format}, где 'XXXX' (минимум 4 символа) - это уникальная часть.
|
||||||
|
|
||||||
|
banners:
|
||||||
|
advisory_not_found: Не удалось найти запрашиваемый бюллетень для сборочного листа этого типа.
|
||||||
|
server_error: Произошла ошибка сервера. Попробуйте позже.
|
||||||
|
continue_input: Продолжайте вводить ID до тех пор, пока не найдется нужный бюллетень.
|
||||||
|
|
||||||
flash:
|
flash:
|
||||||
advisories:
|
advisories:
|
||||||
|
|
|
@ -38,7 +38,9 @@ Rosa::Application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :advisories, :only => [:index, :show]
|
resources :advisories, :only => [:index, :show, :search] do
|
||||||
|
get :search, :on => :collection
|
||||||
|
end
|
||||||
|
|
||||||
scope :module => 'platforms' do
|
scope :module => 'platforms' do
|
||||||
resources :platforms do
|
resources :platforms do
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
//= require bootstrap-modal
|
//= require bootstrap-modal
|
||||||
//= require bootstrap-button
|
//= require bootstrap-button
|
||||||
//= require bootstrap-dropdown
|
//= require bootstrap-dropdown
|
||||||
//= require bootstrap-tooltip
|
// require bootstrap-tooltip
|
||||||
//= require bootstrap-popover
|
// require bootstrap-popover
|
||||||
//= require chosen.jquery
|
//= require chosen.jquery
|
||||||
// require html5shiv
|
// require html5shiv
|
||||||
// require_tree .
|
// require_tree .
|
||||||
|
|
Loading…
Reference in New Issue