Merge pull request #269 from abf/rosa-build:267-automatically-update-build-list-page
#267: BuildList#show && ProductBuildList#show automatically update page
This commit is contained in:
commit
d336d7e746
1
Gemfile
1
Gemfile
|
@ -65,6 +65,7 @@ gem 'ng-rails-csrf'
|
|||
gem 'momentjs-rails'
|
||||
gem 'angular-i18n', '0.1.2'
|
||||
gem 'js-routes'
|
||||
gem 'soundmanager-rails'
|
||||
|
||||
gem 'time_diff'
|
||||
|
||||
|
|
|
@ -372,6 +372,7 @@ GEM
|
|||
skinny (0.2.3)
|
||||
eventmachine (~> 1.0.0)
|
||||
thin (~> 1.5.0)
|
||||
soundmanager-rails (0.1.5)
|
||||
sprockets (2.2.2)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
|
@ -492,6 +493,7 @@ DEPENDENCIES
|
|||
sass-rails (~> 3.2.5)
|
||||
shotgun
|
||||
shoulda
|
||||
soundmanager-rails
|
||||
state_machine
|
||||
therubyracer (~> 0.10.2)
|
||||
therubyrhino (~> 1.73.1)
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf', 'angular-i18n']);
|
||||
|
||||
var DateTimeFormatter = function() {
|
||||
|
||||
var UtcFormatter = function(api_time) {
|
||||
return moment.utc(api_time * 1000).format('YYYY-MM-DD HH:mm:ss UTC');
|
||||
}
|
||||
|
||||
return {
|
||||
utc : UtcFormatter
|
||||
}
|
||||
}
|
||||
RosaABF.factory("DateTimeFormatter", DateTimeFormatter);
|
||||
|
||||
var LocalesHelper = function($locale) {
|
||||
var locales = {
|
||||
'ru' : 'ru-ru',
|
||||
'en' : 'en-us'
|
||||
}
|
||||
return {
|
||||
setLocale: function(locale) {
|
||||
$locale.id = locales[locale];
|
||||
}
|
||||
}
|
||||
}
|
||||
RosaABF.factory("LocalesHelper", ['$locale', LocalesHelper]);
|
|
@ -0,0 +1,48 @@
|
|||
var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf', 'angular-i18n']);
|
||||
|
||||
var DateTimeFormatter = function() {
|
||||
|
||||
var UtcFormatter = function(api_time) {
|
||||
return moment.utc(api_time * 1000).format('YYYY-MM-DD HH:mm:ss UTC');
|
||||
}
|
||||
|
||||
return {
|
||||
utc : UtcFormatter
|
||||
}
|
||||
}
|
||||
RosaABF.factory("DateTimeFormatter", DateTimeFormatter);
|
||||
|
||||
var LocalesHelper = function($locale) {
|
||||
var locales = {
|
||||
'ru' : 'ru-ru',
|
||||
'en' : 'en-us'
|
||||
}
|
||||
return {
|
||||
setLocale: function(locale) {
|
||||
$locale.id = locales[locale];
|
||||
}
|
||||
}
|
||||
}
|
||||
RosaABF.factory("LocalesHelper", ['$locale', LocalesHelper]);
|
||||
|
||||
var SoundNotificationsHelper = function() {
|
||||
var isOn = true;
|
||||
var statusChangedSound = null;
|
||||
soundManager.setup({
|
||||
// url: '/assets/swf/',
|
||||
preferFlash: false,
|
||||
onready: function() {
|
||||
statusChangedSound = soundManager.createSound({url: "<%=asset_path('garbage_shattering.wav')%>"});
|
||||
}
|
||||
});
|
||||
return {
|
||||
buildStatusChanged: function() {
|
||||
if (isOn && statusChangedSound)
|
||||
statusChangedSound.play();
|
||||
},
|
||||
enabled: function(status) {
|
||||
isOn = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
RosaABF.factory('SoundNotificationsHelper', SoundNotificationsHelper);
|
|
@ -1,14 +1,44 @@
|
|||
RosaABF.controller('BuildListController', ['$scope', '$http', function($scope, $http) {
|
||||
RosaABF.controller('BuildListController', ['$scope', '$http', '$timeout', 'SoundNotificationsHelper', function($scope, $http, $timeout, SoundNotificationsHelper) {
|
||||
|
||||
$scope.advisoriable_types = <%=BuildList::RELEASE_UPDATE_TYPES%>;
|
||||
|
||||
$scope.build_list = {};
|
||||
$scope.id = $('#build_list_id').val();
|
||||
$scope.build_list = null;
|
||||
$scope.subject = {}; // See: shared/build_results
|
||||
$scope.attach_advisory = 'no';
|
||||
// Statuses: advisory_not_found, server_error, continue_input
|
||||
$scope.search_status = 'continue_input';
|
||||
$scope.term = '';
|
||||
$scope.advisory = null;
|
||||
|
||||
$scope.getBuildList = function() {
|
||||
$http.get(Routes.build_list_path($scope.id, {format: 'json'})).success(function(results) {
|
||||
var build_list = new BuildList(results.build_list);
|
||||
if ($scope.build_list && $scope.build_list.status != build_list.status)
|
||||
SoundNotificationsHelper.buildStatusChanged();
|
||||
$scope.build_list = $scope.subject = build_list;
|
||||
});
|
||||
}
|
||||
|
||||
$scope.cancelRefresh = null;
|
||||
$scope.refresh = function() {
|
||||
if ( $scope.attach_advisory == 'no' &&
|
||||
(
|
||||
!$scope.build_list ||
|
||||
!(
|
||||
$scope.build_list.status == <%=BuildList::BUILD_PUBLISHED%> ||
|
||||
$scope.build_list.status == <%=BuildList::REJECTED_PUBLISH%> ||
|
||||
$scope.build_list.status == <%=BuildList::FAILED_PUBLISH%> ||
|
||||
$scope.build_list.status == <%=BuildList::BUILD_CANCELED%> ||
|
||||
$scope.build_list.status == <%=BuildList::BUILD_ERROR%>
|
||||
)
|
||||
)
|
||||
) {
|
||||
$scope.getBuildList();
|
||||
}
|
||||
$scope.cancelRefresh = $timeout($scope.refresh, 10000);
|
||||
}
|
||||
$scope.refresh();
|
||||
|
||||
$scope.search = function() {
|
||||
var params = {query: $scope.term, bl_type: $scope.build_list.update_type, format: 'json'};
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
RosaABF.controller('ProductBuildListController', ['$scope', '$http', '$timeout', 'SoundNotificationsHelper', function($scope, $http, $timeout, SoundNotificationsHelper) {
|
||||
|
||||
$scope.id = $('#product_build_list_id').val();
|
||||
$scope.pbl = null;
|
||||
$scope.subject = {}; // See: shared/build_results
|
||||
|
||||
$scope.getProductBuildList = function() {
|
||||
$http.get(Routes.product_build_list_path($scope.id, {format: 'json'})).success(function(results) {
|
||||
var product_build_list = results.product_build_list;
|
||||
if ($scope.pbl && $scope.pbl.status != product_build_list.status)
|
||||
SoundNotificationsHelper.buildStatusChanged();
|
||||
$scope.pbl = $scope.subject = product_build_list;
|
||||
});
|
||||
}
|
||||
|
||||
$scope.cancelRefresh = null;
|
||||
$scope.refresh = function() {
|
||||
if (!$scope.pbl ||
|
||||
!(
|
||||
$scope.pbl.status == <%=ProductBuildList::BUILD_COMPLETED%> ||
|
||||
$scope.pbl.status == <%=ProductBuildList::BUILD_FAILED%> ||
|
||||
$scope.pbl.status == <%=ProductBuildList::BUILD_CANCELED%>
|
||||
)
|
||||
) {
|
||||
$scope.getProductBuildList();
|
||||
}
|
||||
$scope.cancelRefresh = $timeout($scope.refresh, 10000);
|
||||
}
|
||||
$scope.refresh();
|
||||
|
||||
}]);
|
|
@ -1,7 +1,8 @@
|
|||
RosaABF.controller('RosaABFController', ['$scope', 'LocalesHelper', function($scope, LocalesHelper) {
|
||||
RosaABF.controller('RosaABFController', ['$scope', 'LocalesHelper', 'SoundNotificationsHelper', function($scope, LocalesHelper, SoundNotificationsHelper) {
|
||||
|
||||
$scope.init = function(locale) {
|
||||
$scope.init = function(locale, sound_notifications) {
|
||||
LocalesHelper.setLocale(locale);
|
||||
SoundNotificationsHelper.enabled(sound_notifications);
|
||||
}
|
||||
|
||||
}]);
|
|
@ -19,9 +19,11 @@ var BuildList = function(atts, dictionary) {
|
|||
self.save_to_repository = _.find(dictionary.repositories, function(i){ return i.id == self.save_to_repository_id; });
|
||||
}
|
||||
|
||||
self.save_to_repository_name = self.save_to_platform.name + '/' + self.save_to_repository.name;
|
||||
if (self.save_to_platform.personal) {
|
||||
self.save_to_repository_name += ' (' + self.build_for_platform.name + ')'
|
||||
if (self.save_to_platform) {
|
||||
self.save_to_repository_name = self.save_to_platform.name + '/' + self.save_to_repository.name;
|
||||
if (self.save_to_platform.personal) {
|
||||
self.save_to_repository_name += ' (' + self.build_for_platform.name + ')'
|
||||
}
|
||||
}
|
||||
|
||||
if (self.project) {
|
||||
|
@ -36,10 +38,11 @@ var BuildList = function(atts, dictionary) {
|
|||
self.project.name_with_owner = self.project.owner + '/' + self.project.name;
|
||||
}
|
||||
|
||||
self.save_to_repository_url = Routes.platform_repository_path(self.save_to_platform_id, self.save_to_repository_id);
|
||||
self.user.url = Routes.user_path(self.user.uname);
|
||||
self.human_status = 'build_list.status.' + self.status;
|
||||
self.url = Routes.build_list_path(self.id);
|
||||
if (self.save_to_platform_id)
|
||||
self.save_to_repository_url = Routes.platform_repository_path(self.save_to_platform_id, self.save_to_repository_id);
|
||||
if (self.user)
|
||||
self.user.url = Routes.user_path(self.user.uname);
|
||||
self.url = Routes.build_list_path(self.id);
|
||||
|
||||
switch (self.status) { // See: app/helpers/build_lists_helper.rb
|
||||
case <%=BuildList::BUILD_PUBLISHED%>:
|
||||
|
@ -72,6 +75,19 @@ var BuildList = function(atts, dictionary) {
|
|||
self.hasRelated = true;
|
||||
}
|
||||
|
||||
self.itemStatusColor = function(status) {
|
||||
if (status == <%=BuildList::SUCCESS%>)
|
||||
return 'success';
|
||||
else if (status == <%=BuildList::BUILD_ERROR%>)
|
||||
return 'error';
|
||||
else
|
||||
return '';
|
||||
}
|
||||
self.humanStatus = function(status) {
|
||||
return 'build_list.status.' + status;
|
||||
}
|
||||
self.human_status = self.humanStatus(self.status);
|
||||
|
||||
//return the scope-safe instance
|
||||
return self;
|
||||
};
|
|
@ -20,6 +20,9 @@
|
|||
//= require_tree ./angularjs
|
||||
//= require moment
|
||||
|
||||
// require soundmanager2
|
||||
//= require soundmanager2-nodebug-jsmin
|
||||
|
||||
//= require_self
|
||||
|
||||
function disableNotifierCbx(global_cbx) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
class Platforms::ProductBuildListsController < Platforms::BaseController
|
||||
include BuildsHelper
|
||||
|
||||
before_filter :authenticate_user!
|
||||
skip_before_filter :authenticate_user!, :only => [:index, :show, :log] if APP_CONFIG['anonymous_access']
|
||||
before_filter :redirect_to_full_path_if_short_url, :only => :show
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
class Projects::BuildListsController < Projects::BaseController
|
||||
include BuildsHelper
|
||||
|
||||
NESTED_ACTIONS = [:index, :new, :create]
|
||||
|
||||
before_filter :authenticate_user!
|
||||
|
|
|
@ -76,10 +76,12 @@ module BuildListsHelper
|
|||
hash_size=5
|
||||
if item.version =~ /^[\da-z]+$/ && item.name == item.build_list.project.name
|
||||
bl = item.build_list
|
||||
link_to str_version ? "#{shortest_hash_id item.version, hash_size}" : shortest_hash_id(item.version, hash_size),
|
||||
commit_path(bl.project.owner, bl.project, item.version)
|
||||
{
|
||||
:text => str_version ? "#{shortest_hash_id item.version, hash_size}" : shortest_hash_id(item.version, hash_size),
|
||||
:href => commit_path(bl.project.owner, bl.project, item.version)
|
||||
}
|
||||
else
|
||||
''
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
module BuildsHelper
|
||||
|
||||
def file_store_results_url(sha1, file_name)
|
||||
url = "#{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{sha1}"
|
||||
url << '.log?show=true' if file_name =~ /.*\.(log|txt)$/
|
||||
url
|
||||
end
|
||||
|
||||
end
|
|
@ -41,7 +41,7 @@ class User < Avatar
|
|||
validates :language, :inclusion => {:in => LANGUAGES}, :allow_blank => true
|
||||
|
||||
attr_accessible :email, :password, :password_confirmation, :current_password, :remember_me, :login, :name, :uname, :language,
|
||||
:site, :company, :professional_experience, :location
|
||||
:site, :company, :professional_experience, :location, :sound_notifications
|
||||
attr_readonly :uname
|
||||
attr_accessor :login
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
- if user_signed_in?
|
||||
= auto_discovery_link_tag :atom, atom_activity_feeds_path(:format => 'atom', :token => current_user.authentication_token), :title => t("layout.atom_link_tag_title", :nickname => current_user.uname, :app_name => APP_CONFIG['project_name'])
|
||||
|
||||
%body{'ng-app' => 'RosaABF', 'ng-controller' => 'RosaABFController', 'ng-init' => "init('#{I18n.locale}')"}
|
||||
%body{'ng-app' => 'RosaABF', 'ng-controller' => 'RosaABFController', 'ng-init' => "init('#{I18n.locale}', #{!!current_user.try(:sound_notifications)})"}
|
||||
.wrap{:class => content_for?(:sidebar) ? 'columns' : ''}
|
||||
%header
|
||||
.left
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
%h3= subject.class.human_attribute_name(subject.is_a?(BuildList) ? 'logs' : 'results')
|
||||
- unless subject.results.present?
|
||||
%h4.nomargin= t('layout.no_')
|
||||
- else
|
||||
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
|
||||
%thead
|
||||
%tr
|
||||
%th= t("activerecord.attributes.product_build_list/results.file_name")
|
||||
%th= t("activerecord.attributes.product_build_list/results.sha1")
|
||||
%th= t("activerecord.attributes.product_build_list/results.size")
|
||||
%tbody
|
||||
- subject.results.each do |item|
|
||||
%tr
|
||||
- sha1 = item['sha1']
|
||||
- filename = item['file_name']
|
||||
- url = "#{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{sha1}"
|
||||
- url << '.log?show=true' if filename =~ /.*\.(log|txt)$/
|
||||
%td= link_to filename, url
|
||||
%td= sha1
|
||||
%td= item['size']
|
||||
.both
|
|
@ -7,44 +7,49 @@
|
|||
|
||||
%h3= t("layout.product_build_lists.main_data")
|
||||
.both
|
||||
%div{'ng-controller' => 'ProductBuildListController'}
|
||||
= render 'show_field', :key => :id, :value => pbl.id
|
||||
= hidden_field_tag :product_build_list_id, pbl.id
|
||||
= render 'show_field', :key => :status, :value => '{{pbl.human_status}}'
|
||||
- if pbl.user
|
||||
= render 'show_field', :key => :user, :value => link_to(pbl.user.try(:fullname), pbl.user)
|
||||
|
||||
= render 'show_field', :key => :id, :value => pbl.id
|
||||
= render 'show_field', :key => :status, :value => pbl.human_status
|
||||
- if pbl.user
|
||||
= render 'show_field', :key => :user, :value => link_to(pbl.user.try(:fullname), pbl.user)
|
||||
= render 'show_field', :key => :product, :value => link_to(pbl.product.name, platform_product_path(platform, product))
|
||||
|
||||
= render 'show_field', :key => :product, :value => link_to(pbl.product.name, platform_product_path(platform, product))
|
||||
= render 'show_field', :key => :project, :value => link_to(pbl.project.name_with_owner, project_path(pbl.project))
|
||||
|
||||
= render 'show_field', :key => :project, :value => link_to(pbl.project.name_with_owner, project_path(pbl.project))
|
||||
= render 'show_field', :key => :project_version, :value => product_build_list_version_link(pbl, true)
|
||||
|
||||
= render 'show_field', :key => :project_version, :value => product_build_list_version_link(pbl, true)
|
||||
- [:main_script, :params].each do |el|
|
||||
= render 'show_field', :key => el, :value => pbl.send(el)
|
||||
|
||||
- [:main_script, :params].each do |el|
|
||||
= render 'show_field', :key => el, :value => pbl.send(el)
|
||||
= render 'show_field', :key => :time_living, :value => (pbl.time_living / 60)
|
||||
|
||||
= render 'show_field', :key => :time_living, :value => (pbl.time_living / 60)
|
||||
= render 'show_field', :key => :autostarted, :value => t("layout.#{pbl.autostarted}_")
|
||||
|
||||
= render 'show_field', :key => :autostarted, :value => t("layout.#{pbl.autostarted}_")
|
||||
= render 'show_field', :key => :notified_at, :value => '{{pbl.notified_at}}'
|
||||
|
||||
= render 'show_field', :key => :notified_at, :value => l(pbl.updated_at, :format => :long)
|
||||
|
||||
- if pbl.can_cancel? && can?(:cancel, pbl)
|
||||
= link_to t("layout.build_lists.cancel"), cancel_platform_product_product_build_list_path(pbl.product.platform, pbl.product, pbl),
|
||||
:method => :put, :confirm => t("layout.confirm"), :class => 'button'
|
||||
.both
|
||||
%br
|
||||
|
||||
- if pbl.build_completed? && can?(:update, pbl)
|
||||
= form_for pbl, :url => platform_product_product_build_list_path(pbl.product.platform, pbl.product, pbl) do |f|
|
||||
.leftlist= f.label :not_delete
|
||||
.rightlist
|
||||
= f.select :not_delete, [false, true].collect{|status| [t("layout.#{status}_"), status]}, {:selected => pbl.not_delete}
|
||||
.both
|
||||
%br
|
||||
= submit_tag t('layout.update'), :data => {'disable-with' => t('layout.processing')}
|
||||
- if can?(:cancel, pbl)
|
||||
= link_to t("layout.build_lists.cancel"),
|
||||
cancel_platform_product_product_build_list_path(pbl.product.platform, pbl.product, pbl),
|
||||
:method => :put, :confirm => t("layout.confirm"), :class => 'button',
|
||||
'ng-show' => 'pbl.can_cancel'
|
||||
.both
|
||||
- unless pbl.not_delete
|
||||
.flash_notify
|
||||
%br
|
||||
|
||||
- if can?(:update, pbl)
|
||||
= form_for pbl,
|
||||
:url => platform_product_product_build_list_path(pbl.product.platform,pbl.product, pbl),
|
||||
:html => {'ng-show' => "pbl.status == #{ProductBuildList::BUILD_COMPLETED}"} do |f|
|
||||
|
||||
.leftlist= f.label :not_delete
|
||||
.rightlist
|
||||
= f.select :not_delete, [false, true].collect{|status| [t("layout.#{status}_"), status]}, {:selected => pbl.not_delete}
|
||||
.both
|
||||
%br
|
||||
= submit_tag t('layout.update'), :data => {'disable-with' => t('layout.processing')}
|
||||
.both
|
||||
.flash_notify{'ng-hide' => 'pbl.not_delete'}
|
||||
.alert.alert-error
|
||||
- days = pbl.autostarted? ? ProductBuildList::LIVE_TIME : ProductBuildList::MAX_LIVE_TIME
|
||||
- days = (pbl.created_at.to_date - days.ago.to_date).to_i
|
||||
|
@ -54,10 +59,10 @@
|
|||
= t('layout.product_build_lists.will_be_removed_today')
|
||||
.both
|
||||
|
||||
- if pbl.build_started? || pbl.build_canceling?
|
||||
= render 'shared/log', { :build_started => true, :get_log_path => log_platform_product_product_build_list_path(pbl.product.platform, pbl.product, pbl) }
|
||||
%div{'ng-show' => "pbl.status == #{ProductBuildList::BUILD_STARTED}"}
|
||||
= render 'shared/log', { :build_started => true, :get_log_path => log_platform_product_product_build_list_path(pbl.product.platform, pbl.product, pbl) }
|
||||
|
||||
= render 'results', :subject => pbl
|
||||
= render 'shared/build_results', :subject => pbl
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
json.product_build_list do
|
||||
json.(@product_build_list, :id, :status, :human_status, :not_delete)
|
||||
json.notified_at l(@product_build_list.updated_at, :format => :long)
|
||||
|
||||
json.can_cancel @product_build_list.can_cancel?
|
||||
|
||||
json.results @product_build_list.results do |result|
|
||||
json.file_name result['file_name']
|
||||
json.sha1 result['sha1']
|
||||
json.size result['size']
|
||||
json.url file_store_results_url(result['sha1'], result['file_name'])
|
||||
end if @product_build_list.results.present?
|
||||
|
||||
end
|
|
@ -1,36 +1,36 @@
|
|||
-set_meta_tags :title => [title_object(@build_list.project), t('activerecord.models.build_list')]
|
||||
.notify.blue
|
||||
%div{:class => build_list_status_color(@build_list.status)}
|
||||
%p= @build_list.human_status
|
||||
%p= @build_list.updated_at
|
||||
.both
|
||||
%div{'ng-controller' => 'BuildListController'}
|
||||
.notify.blue
|
||||
%div{:class => '{{build_list.status_color}}'}
|
||||
%p {{build_list.human_status | i18n}}
|
||||
%p {{build_list.updated_at}}
|
||||
.both
|
||||
=form_for @build_list, :url => publish_build_list_path(@build_list), :html => { :class => :form } do |f|
|
||||
%h3= t("layout.build_lists.main_data")
|
||||
.leftlist= t("activerecord.attributes.build_list.container_path")
|
||||
.rightlist
|
||||
- if @build_list.container_published?
|
||||
-url = container_url
|
||||
= link_to url, url
|
||||
- elsif @build_list.container_publish?
|
||||
= t("layout.build_lists.creating")
|
||||
.rightlist{'ng-show' => "build_list.container_status == #{BuildList::BUILD_PUBLISHED}"}
|
||||
- url = container_url
|
||||
= link_to url, url
|
||||
.rightlist{'ng-show' => "build_list.container_status == #{BuildList::BUILD_PUBLISH}"}
|
||||
= t("layout.build_lists.creating")
|
||||
.both
|
||||
|
||||
.leftlist= t("activerecord.attributes.build_list.id")
|
||||
.rightlist= @build_list.id
|
||||
.rightlist
|
||||
= @build_list.id
|
||||
= hidden_field_tag :build_list_id, @build_list.id
|
||||
.both
|
||||
.leftlist= t("activerecord.attributes.build_list.user")
|
||||
.rightlist
|
||||
= link_to @build_list.user.try(:fullname), @build_list.user
|
||||
.both
|
||||
.leftlist= t("activerecord.attributes.build_list.publisher")
|
||||
.rightlist
|
||||
= link_to @build_list.publisher.try(:fullname), @build_list.publisher if @build_list.publisher
|
||||
.rightlist{'ng-show' => 'build_list.publisher'}
|
||||
%a{'ng-href' => '{{build_list.publisher.path}}' } {{build_list.publisher.fullname}}
|
||||
.both
|
||||
.leftlist= t("activerecord.attributes.build_list.build_for_platform")
|
||||
.rightlist
|
||||
- bfp = @build_list.build_for_platform
|
||||
- if bfp.present?
|
||||
- if bfp = @build_list.build_for_platform
|
||||
= link_to(bfp.name, bfp)
|
||||
- else
|
||||
= t("layout.build_lists.platform_deleted")
|
||||
|
@ -43,11 +43,11 @@
|
|||
.rightlist= (@build_list.include_repos||[]).map{|r| Repository.find(r).name}.join(', ')
|
||||
.both
|
||||
.leftlist= t("activerecord.attributes.build_list.update_type")
|
||||
.rightlist{'ng-init' => "build_list.update_type = '#{@build_list.update_type}'"}
|
||||
- if can?(:publish, @build_list)
|
||||
= f.select :update_type, options_for_select(build_list_classified_update_types, @build_list.update_type), {}, 'ng-model' => 'build_list.update_type', 'ng-change' => 'updateTypeChanged()'
|
||||
- else
|
||||
= @build_list.update_type
|
||||
.rightlist
|
||||
= f.select :update_type, options_for_select(build_list_classified_update_types,
|
||||
@build_list.update_type), {}, 'ng-model' => 'build_list.update_type',
|
||||
'ng-change' => 'updateTypeChanged()', 'ng-show' => 'build_list.can_publish'
|
||||
%div{'ng-hide' => 'build_list.can_publish'}= @build_list.update_type
|
||||
.both
|
||||
.leftlist= t("activerecord.attributes.build_list.auto_publish")
|
||||
.rightlist= t("layout.#{@build_list.auto_publish}_")
|
||||
|
@ -65,7 +65,7 @@
|
|||
.rightlist= @build_list.arch.name
|
||||
.both
|
||||
.leftlist= t("activerecord.attributes.build_list.updated_at")
|
||||
.rightlist= @build_list.updated_at
|
||||
.rightlist {{build_list.updated_at}}
|
||||
.both
|
||||
.leftlist= t("activerecord.attributes.build_list.is_circle")
|
||||
.rightlist= t("layout.#{@build_list.is_circle?}_")
|
||||
|
@ -73,7 +73,6 @@
|
|||
.leftlist= t("activerecord.attributes.build_list.new_core")
|
||||
.rightlist= t("layout.#{@build_list.new_core?}_")
|
||||
.both
|
||||
|
||||
- if @build_list.extra_build_lists.present? || @build_list.extra_repositories.present?
|
||||
.leftlist= t("activerecord.attributes.build_list.extra_repos")
|
||||
.rightlist
|
||||
|
@ -88,29 +87,21 @@
|
|||
.rightlist= link_to @build_list.mass_build.name, platform_mass_builds_path(@build_list.save_to_platform)
|
||||
.both
|
||||
|
||||
|
||||
- if @build_list.advisory.present?
|
||||
%div{'ng-show' => 'build_list.advisory'}
|
||||
.leftlist= t("layout.build_lists.attached_advisory")
|
||||
.rightlist= link_to @build_list.advisory.advisory_id, advisory_path(@build_list.advisory)
|
||||
.both
|
||||
- if !@build_list.in_work? && @build_list.started_at
|
||||
%br
|
||||
.leftlist
|
||||
.rightlist= @build_list.human_duration
|
||||
.both
|
||||
- if @build_list.in_work?
|
||||
%br
|
||||
.leftlist
|
||||
.rightlist
|
||||
= "#{@build_list.human_current_duration} / #{@build_list.human_average_build_time}"
|
||||
%a{'ng-href' => '{{build_list.advisory.path}}' }
|
||||
{{build_list.advisory.advisory_id}}
|
||||
.both
|
||||
|
||||
- if @build_list.can_cancel? && can?(:cancel, @build_list)
|
||||
= link_to t("layout.build_lists.cancel"), cancel_build_list_path(@build_list),
|
||||
:method => :put, :confirm => t("layout.confirm"), :class => 'button'
|
||||
%div{'ng-show' => 'build_list.human_duration'}
|
||||
%br
|
||||
.leftlist
|
||||
.rightlist {{build_list.human_duration }}
|
||||
.both
|
||||
|
||||
- if @build_list.save_to_platform.released && @build_list.advisory.nil? && can?(:publish, @build_list)
|
||||
#advisory_block
|
||||
- if @build_list.save_to_platform.released
|
||||
#advisory_block{'ng-show' => 'build_list.can_publish && !build_list.advisory'}
|
||||
.leftlist= label_tag :attach_advisory, t("layout.build_lists.attached_advisory")
|
||||
.rightlist
|
||||
= select_tag :attach_advisory, advisories_select_options(@advisories), 'ng-model' => 'attach_advisory', 'ng-change' => 'attachAdvisoryChanged()'
|
||||
|
@ -143,36 +134,49 @@
|
|||
.rightlist.refs {{advisory.references}}
|
||||
.both
|
||||
|
||||
- if @build_list.build_started?
|
||||
= render 'shared/log', { :build_started => true, :get_log_path => log_build_list_path(@build_list) }
|
||||
|
||||
- unless @build_list.extra_build_lists_published?
|
||||
%div{'ng-hide' => 'build_list.extra_build_lists_published'}
|
||||
.flash_notify
|
||||
.alert.alert-error= t('layout.build_lists.publish_with_extra_fail')
|
||||
.both
|
||||
|
||||
- if can?(:publish, @build_list)
|
||||
- if @build_list.build_published?
|
||||
= submit_tag t("layout.publish_again"), :confirm => t("layout.publish_again_warning"), :name => 'publish'
|
||||
- elsif can_publish_in_future?(@build_list) && @build_list.extra_build_lists_published?
|
||||
- confirm = @build_list.tests_failed? ? t('layout.build_lists.tests_failed') : t('layout.confirm')
|
||||
= submit_tag t("layout.publish"), :confirm => confirm, :name => 'publish'
|
||||
- if @build_list.can_reject_publish? && can?(:reject_publish, @build_list)
|
||||
- if can?(:cancel, @build_list)
|
||||
= link_to t("layout.build_lists.cancel"), cancel_build_list_path(@build_list),
|
||||
:method => :put, :confirm => t("layout.confirm"), :class => 'button',
|
||||
'ng-show' => 'build_list.can_cancel'
|
||||
= submit_tag t('layout.publish_again'),
|
||||
:confirm => t("layout.publish_again_warning"),
|
||||
:name => 'publish',
|
||||
'ng-show' => "build_list.can_publish && build_list.status == #{BuildList::BUILD_PUBLISHED}"
|
||||
= submit_tag t("layout.publish"),
|
||||
:confirm => t('layout.build_lists.tests_failed'), :name => 'publish',
|
||||
'ng-show' => "build_list.can_publish && build_list.can_publish_in_future && build_list.extra_build_lists_published && build_list.status == #{BuildList::TESTS_FAILED}"
|
||||
= submit_tag t("layout.publish"),
|
||||
:confirm => t('layout.confirm'), :name => 'publish',
|
||||
'ng-show' => "build_list.can_publish && build_list.can_publish_in_future && build_list.extra_build_lists_published && build_list.status != #{BuildList::TESTS_FAILED} && build_list.status != #{BuildList::BUILD_PUBLISHED}"
|
||||
- if can?(:reject_publish, @build_list)
|
||||
= link_to t('layout.reject_publish'), reject_publish_build_list_path(@build_list),
|
||||
:method => :put, :confirm => t("layout.confirm"), :class => 'button reject_publish'
|
||||
- if @build_list.can_create_container? && can?(:create_container, @build_list)
|
||||
= link_to t("layout.build_lists.create_container"), create_container_build_list_path(@build_list),
|
||||
:method => :put, :confirm => t("layout.confirm"), :class => 'button create_container'
|
||||
:method => :put, :confirm => t("layout.confirm"),
|
||||
:class => 'button reject_publish',
|
||||
'ng-show' => 'build_list.can_reject_publish'
|
||||
- if can?(:create_container, @build_list)
|
||||
= link_to t("layout.build_lists.create_container"),
|
||||
create_container_build_list_path(@build_list),
|
||||
:method => :put, :confirm => t("layout.confirm"),
|
||||
:class => 'button create_container',
|
||||
'ng-show' => 'build_list.can_create_container'
|
||||
- if can? :create, @build_list
|
||||
= link_to t('layout.build_lists.recreate_build_list'), new_project_build_list_path(@build_list.project, :build_list_id => @build_list.id), :class => 'button'
|
||||
|
||||
%div{'ng-show' => "build_list.status == #{BuildList::BUILD_STARTED}"}
|
||||
= render 'shared/log', { :build_started => true, :get_log_path => log_build_list_path(@build_list) }
|
||||
|
||||
.hr
|
||||
%h3= t("layout.build_lists.items_header")
|
||||
- if @item_groups.blank?
|
||||
%h4.nomargin= t("layout.build_lists.no_items_data")
|
||||
- @item_groups.each_with_index do |group, level|
|
||||
- group.each do |item|
|
||||
%h4.nomargin= "#{item.name} ##{level}"
|
||||
%h4.nomargin{'ng-hide' => 'build_list.item_groups'}
|
||||
= t("layout.build_lists.no_items_data")
|
||||
%div{'ng-repeat' => 'group in build_list.item_groups'}
|
||||
%div{'ng-repeat' => 'item in group'}
|
||||
%h4.nomargin {{item.name + ' #' + item.level}}
|
||||
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
|
||||
%thead
|
||||
%tr
|
||||
|
@ -180,13 +184,14 @@
|
|||
%th= t("activerecord.attributes.build_list/item.version")
|
||||
%th= t("activerecord.attributes.build_list/item.status")
|
||||
%tbody
|
||||
%tr{:class => build_list_item_status_color(item.status)}
|
||||
%td= item.name
|
||||
%td= build_list_item_version_link item
|
||||
%td= item.human_status
|
||||
%tr{:class => "{{build_list.itemStatusColor(item.status)}}"}
|
||||
%td {{item.name}}
|
||||
%td
|
||||
%a{'ng-href' => '{{item.path.href}}' } {{item.path.text}}
|
||||
%td {{build_list.humanStatus(item.status) | i18n}}
|
||||
.both
|
||||
|
||||
- if @build_list.packages.present?
|
||||
%div{'ng-show' => 'build_list.packages'}
|
||||
.hr
|
||||
%h3= t("layout.build_lists.packages_header")
|
||||
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
|
||||
|
@ -197,20 +202,18 @@
|
|||
%th= t("activerecord.attributes.build_list/package.version")
|
||||
%th= t("activerecord.attributes.build_list/package.release")
|
||||
%tbody
|
||||
- @build_list.packages.each do |package|
|
||||
%tr
|
||||
- if package.sha1.present?
|
||||
%td= link_to package.fullname, "#{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{package.sha1}"
|
||||
- else
|
||||
%td= package.fullname
|
||||
%td= package.name
|
||||
%td= package.version
|
||||
%td= package.release
|
||||
%tr{'ng-repeat' => 'package in build_list.packages'}
|
||||
%td{'ng-show' => 'package.url'}
|
||||
%a{'ng-href' => "{{package.url}}" } {{package.fullname}}
|
||||
%td{'ng-hide' => 'package.url'} {{package.fullname}}
|
||||
%td {{package.name}}
|
||||
%td {{package.version}}
|
||||
%td {{package.release}}
|
||||
.both
|
||||
|
||||
- if @build_list.new_core?
|
||||
.hr
|
||||
= render 'platforms/product_build_lists/results', :subject => @build_list
|
||||
= render 'shared/build_results', :subject => @build_list
|
||||
|
||||
:javascript
|
||||
$('article .all').addClass('bigpadding');
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
json.build_list do
|
||||
json.(@build_list, :id, :container_status, :status)
|
||||
json.(@build_list, :update_type)
|
||||
json.updated_at @build_list.updated_at.strftime('%Y-%m-%d %H:%M:%S UTC')
|
||||
|
||||
if !@build_list.in_work? && @build_list.started_at
|
||||
json.human_duration @build_list.human_duration
|
||||
elsif @build_list.in_work?
|
||||
json.human_duration "#{@build_list.human_current_duration} / #{@build_list.human_average_build_time}"
|
||||
end
|
||||
|
||||
json.can_publish can?(:publish, @build_list)
|
||||
json.can_cancel @build_list.can_cancel?
|
||||
json.can_create_container @build_list.can_create_container?
|
||||
json.can_reject_publish @build_list.can_reject_publish?
|
||||
|
||||
json.extra_build_lists_published @build_list.extra_build_lists_published?
|
||||
json.can_publish_in_future can_publish_in_future?(@build_list)
|
||||
|
||||
|
||||
json.container_path container_url if @build_list.container_published?
|
||||
|
||||
json.publisher do
|
||||
json.fullname @build_list.publisher.try(:fullname)
|
||||
json.path user_path(@build_list.publisher)
|
||||
end if @build_list.publisher
|
||||
|
||||
json.advisory do
|
||||
json.(@build_list.advisory, :description, :advisory_id)
|
||||
json.path advisory_path(@build_list.advisory)
|
||||
end if @build_list.advisory
|
||||
|
||||
json.results @build_list.results do |result|
|
||||
json.file_name result['file_name']
|
||||
json.sha1 result['sha1']
|
||||
json.size result['size']
|
||||
json.url file_store_results_url(result['sha1'], result['file_name'])
|
||||
end if @build_list.new_core? && @build_list.results.present?
|
||||
|
||||
json.packages @build_list.packages do |package|
|
||||
json.(package, :id, :name, :fullname, :release, :version, :sha1)
|
||||
json.url "#{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{package.sha1}" if package.sha1
|
||||
end if @build_list.packages.present?
|
||||
|
||||
json.item_groups do |group|
|
||||
@item_groups.each_with_index do |group, level|
|
||||
json.group group do |item|
|
||||
json.(item, :name, :status)
|
||||
json.path build_list_item_version_link item
|
||||
json.level level
|
||||
end
|
||||
end
|
||||
end if @item_groups.present?
|
||||
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
%h3= subject.class.human_attribute_name(subject.is_a?(BuildList) ? 'logs' : 'results')
|
||||
%h4.nomargin{'ng-hide' => 'subject.results'}= t('layout.no_')
|
||||
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0", 'ng-show' => 'subject.results'}
|
||||
%thead
|
||||
%tr
|
||||
%th= t("activerecord.attributes.product_build_list/results.file_name")
|
||||
%th= t("activerecord.attributes.product_build_list/results.sha1")
|
||||
%th= t("activerecord.attributes.product_build_list/results.size")
|
||||
%tbody
|
||||
%tr{'ng-repeat' => 'item in subject.results'}
|
||||
%td
|
||||
%a{'ng-href' => '{{item.url}}' } {{item.file_name}}
|
||||
%td {{item.sha1}}
|
||||
%td {{item.size}}
|
||||
.both
|
|
@ -32,6 +32,9 @@
|
|||
.leftlist= f.label :professional_experience, t("activerecord.attributes.user.professional_experience")
|
||||
.rightlist= f.text_area :professional_experience
|
||||
.both
|
||||
.leftlist= f.label :sound_notifications, t("activerecord.attributes.user.sound_notifications")
|
||||
.rightlist= f.check_box :sound_notifications
|
||||
.both
|
||||
.leftlist
|
||||
\
|
||||
.rightlist= submit_tag t('layout.save'), :data => {'disable-with' => t('layout.saving')}
|
||||
|
|
|
@ -42,6 +42,7 @@ en:
|
|||
role: Role
|
||||
created_at: Created
|
||||
updated_at: Updated
|
||||
sound_notifications: Enable sound notifications
|
||||
role: System role
|
||||
language: Language
|
||||
password: Password
|
||||
|
|
|
@ -42,6 +42,7 @@ ru:
|
|||
role: Роль
|
||||
created_at: Создан
|
||||
updated_at: Обновлен
|
||||
sound_notifications: Включить звуковые оповещения
|
||||
role: Роль в системе
|
||||
language: Язык
|
||||
password: Пароль
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddSoundNotificationsToUser < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :sound_notifications, :boolean, :default => true
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20130731130518) do
|
||||
ActiveRecord::Schema.define(:version => 20130820195938) do
|
||||
|
||||
create_table "activity_feeds", :force => true do |t|
|
||||
t.integer "user_id", :null => false
|
||||
|
@ -567,6 +567,7 @@ ActiveRecord::Schema.define(:version => 20130731130518) do
|
|||
t.datetime "confirmation_sent_at"
|
||||
t.string "authentication_token"
|
||||
t.integer "build_priority", :default => 50
|
||||
t.boolean "sound_notifications", :default => true
|
||||
end
|
||||
|
||||
add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token"
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue