[#369] remove angular-busy; add loading-bar

This commit is contained in:
Alexander Machehin 2014-04-04 16:12:25 +06:00
parent c08fd6d569
commit 7644a0f4cc
17 changed files with 658 additions and 458 deletions

View File

@ -68,7 +68,7 @@ gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
# AngularJS related stuff
gem 'underscore-rails'
gem 'angularjs-rails'
gem 'angularjs-rails', '~> 1.2.15'
gem 'ng-rails-csrf'
gem 'momentjs-rails'
gem 'angular-i18n', '0.1.2'
@ -84,8 +84,9 @@ gem 'compass-rails', '~> 1.1.6'
gem 'uglifier', '~> 2.4'
gem 'therubyracer', '~> 0.12.1', platforms: [:mri, :rbx]
gem 'therubyrhino', '~> 1.73.1', platforms: :jruby
gem 'bootstrap-sass', '~> 3.1.1'
gem 'bootstrap-sass', '~> 3.1.1'
gem 'font-awesome-rails'
group :production do
gem "airbrake", '~> 3.1.2'

View File

@ -65,7 +65,7 @@ GEM
activerecord (>= 3.0.0)
angular-i18n (0.1.2)
angular-ui-bootstrap-rails (0.10.0)
angularjs-rails (1.2.14)
angularjs-rails (1.2.15)
arel (4.0.2)
atomic (1.1.16)
attr_encrypted (1.3.2)
@ -141,6 +141,8 @@ GEM
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
ffi (1.9.3)
font-awesome-rails (4.0.3.1)
railties (>= 3.2, < 5.0)
friendly_id (5.0.3)
activerecord (>= 4.0.0)
fssm (0.2.10)
@ -467,7 +469,7 @@ DEPENDENCIES
ancestry (~> 2.0.0)
angular-i18n (= 0.1.2)
angular-ui-bootstrap-rails
angularjs-rails
angularjs-rails (~> 1.2.15)
attr_encrypted (~> 1.3.2)
better_errors
binding_of_caller
@ -485,6 +487,7 @@ DEPENDENCIES
diff-display (~> 0.0.1)
factory_girl_rails (~> 4.4.1)
ffi (~> 1.9.3)
font-awesome-rails
friendly_id (~> 5.0.3)
gemoji (~> 1.2.1)
github-linguist (~> 2.10)

View File

@ -0,0 +1,16 @@
//var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf', 'angular-i18n', 'angularMoment']);
var RosaABF = angular.module('RosaABF', ['ui.bootstrap', 'angular-i18n', 'angularMoment',
'chieffancypants.loadingBar', 'ngAnimate']);
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]);

View File

@ -1,23 +1,41 @@
var RosaABF = angular.module('RosaABF', ['ui.bootstrap', 'cgBusy']);
RosaABF.controller('ActivityCtrl', ['$scope', '$http', '$timeout', '$q',
function($scope, $http, $timeout, $q) {
$scope.activity_tab = { title: 'activity_menu.activity_feed', content: [] , isLoaded: false , active: true };
$scope.tracker_tab = { title: 'activity_menu.tracker', content: [] , isLoaded: false , active: false };
$scope.pull_requests_tab = { title: 'activity_menu.pull_requests', content: [] , isLoaded: false , active: false };
RosaABF.controller('ActivityCtrl', ['$scope', '$http', '$timeout', 'promiseTracker', '$q',
function($scope, $http, $timeout, promiseTracker, $q) {
$scope.tabs = [
{ title:"All", content:[] , isLoaded:false , active:true, filter:'all'},
{ title:"Issues", content:[] , isLoaded:false, filter:'issues' }
];
var today = moment().startOf('day');
$scope.activity_tab.content = [{date: today, test:'adf'}, {date: today.add('days', 1).calendar, test:'fd'}];
$scope.getContent=function(tabIndex){
/* see if we have data already */
if($scope.tabs[tabIndex].isLoaded){
return
$scope.getContent=function(tab){
var cur_tab = $scope.$eval(tab+'_tab');
/* see if we have data already */
if(cur_tab.isLoaded){
return;
}
/* or make request for data */
var path = Routes.root_path({ filter: cur_tab.filter, format: 'json' });
$http.get(path, { tracker: 'activity' }).then(function(res){
//cur_tab.content=res.data;
cur_tab.isLoaded=true;
});
}
$scope.getTimeLinefaClass = function(contentType) {
var template = 'bg-warning fa-question';
switch(contentType) {
case 'build_list_notification':
template = 'bg-danger fa-gear';
break;
case 'new_comment_notification':
template = 'bg-primary fa-comment';
break;
case 'git_new_push_notification':
template = 'bg-success fa-sign-in';
break;
}
return template;
}
/* or make request for data */
var path = Routes.root_path({ filter: $scope.tabs[tabIndex].filter, format: 'json' });
$http.get(path, { tracker: 'activity' }).then(function(res){
$scope.tabs[tabIndex].content=res.data;
$scope.tabs[tabIndex].isLoaded=true;
});
}
}]);

View File

@ -0,0 +1,7 @@
RosaABF.controller('RosaABFController', ['$scope', 'LocalesHelper', function($scope, LocalesHelper) {
$scope.init = function(locale) {
LocalesHelper.setLocale(locale);
moment.lang(locale);
}
}]);

View File

@ -16,7 +16,8 @@ var _locales = {
'autostart_statuses.0': 'Раз в 12 часов',
'autostart_statuses.1': 'Раз в день',
'autostart_statuses.2': 'Раз в неделю',
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>,
<%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>
},
<%I18n.locale = :en%>
'en-us': {
@ -33,6 +34,7 @@ var _locales = {
'autostart_statuses.0': 'Once a 12 hours',
'autostart_statuses.1': 'Once a day',
'autostart_statuses.2': 'Once a week',
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>,
<%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>
}
};

View File

@ -1,10 +1,17 @@
//= require jquery
//= require js-routes
// Loads all Bootstrap javascripts
//= require bootstrap
//= require unstable/angular
// require angular
//= require angular-ui-bootstrap-tpls
//= require angular-i18n
//= require angular-animate
//= require angularjs/locales
//= require moment
//= require angularjs/angular-moment
//= require_tree ./angular-new
//= require angular-busy
//= require promise-tracker
//= require loading-bar

View File

@ -1,5 +1,5 @@
body {
background: $body-bg image-url("bg.png") repeat-x;
//background: $body-bg image-url("bg.png") repeat-x;
}
.top_menu {
@ -16,10 +16,15 @@ a.navbar-brand, .navbar .navbar-right .avatar {
padding-top: ($navbar-height - $logo-mini-height) / 2;
}
.nav a {
cursor: pointer;
}
footer {
padding-top: 20px;
padding-bottom: 20px;
text-align: center;
background-color: $navbar-default-bg;
ul li {
display: inline;
@ -36,3 +41,9 @@ footer {
}
}
}
.offset20 { margin-top: 20px; }
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}

View File

@ -1,4 +1,4 @@
$body-bg: #1F60A1;
//$body-bg: #1F60A1;
$navbar-default-bg: #3E73A2;
$navbar-default-link-color: #FFF;
$navbar-default-link-active-color: #FFF;
@ -7,4 +7,6 @@ $navbar-default-link-hover-color: #CEE7FF;
@import "bootstrap";
@import "custom_bootstrap";
@import "angular-busy";
@import "timeline";
@import "font-awesome";
@import "loading-bar";

View File

@ -1,17 +1,67 @@
-set_meta_tags title: nil
%h3.fix
= t("layout.activity_feed.header")
= link_to image_tag("rss.ico", width: '15px', height: '15px', class: 'atom_icon'), atom_activity_feeds_path(format: 'atom', token: current_user.authentication_token)
/ =#render 'feed_tabs'
/ =render 'list'
.voffset20
.container
/ =#render 'feed_tabs'
/ =render 'list'
/ - content_for :sidebar, render('sidebar')
/ - render 'top_menu'
/ - content_for :sidebar, render('sidebar')
/ - render 'top_menu'
%div{ 'ng-controller' => 'ActivityCtrl', "cg-busy" => "'activity'" }
%tabset
%tab{ 'ng-repeat' => "tab in tabs", 'heading' => "{{tab.title}}", 'active' => "tab.active", 'select' => 'getContent($index)' }
%div{ 'ng-hide' => "!tab.isLoaded" }
%h5 Content 1
%div{ 'ng-repeat' => "item in tab.content" }
{{item}}
%div{ 'ng-controller' => 'ActivityCtrl', 'cg-busy' => "'activity'" }
%tabset
%tab{ 'heading' => "{{activity_tab.title | i18n}}", 'active' => "activity_tab.active", 'select' => "getContent('activity')" }
.row
.col-md-3.offset20
%p
= link_to t('layout.activity_feed.new_project'), new_project_path,
class: 'btn btn-primary btn-small', role: 'button'
%hr
%h5= t('layout.activity_feed.my_last_projects')
%ul.nav.nav-pills.nav-stacked
- current_user.projects.order(updated_at: :desc).limit(5).each do |project|
%li
= link_to project_path(project) do
- image, color = project.public? ? ['unlock-alt', 'text-success'] : ['lock', 'text-danger']
= fa_icon(image, class: color)
= project.name_with_owner
%li
= link_to t('layout.activity_feed.all_my_projects'), projects_path
.col-md-9
%h3
= t("layout.activity_feed.header")
= link_to image_tag("rss.ico", width: '15px', height: '15px', class: 'atom_icon'), atom_activity_feeds_path(format: 'atom', token: current_user.authentication_token)
/ The time line
.row
.col-md-12
%ul.timeline
.timeline-element{ 'ng-repeat' => 'item in activity_tab.content' }
/ timeline time label
%li.time-label
%span{ 'ng-show' => "(item.date | amDateFormat:'ll') != (item[$index-1].date | amDateFormat:'ll')" }
{{item.date | amDateFormat:'ll'}}
/ timeline item
%li
%i.img-circle.bg-primary.fa.fa-comment
.timeline-item
%span.time
%span.glyphicon.glyphicon-time
12:05
%h3.timeline-header
%a{href: "#"} Support Team
sent you and email
.timeline-body
Etsy doostang zoodles disqus groupon greplin oooj voxy zoodles,
weebly ning heekya handango imeem plugg dopplr jibjab, movity
jajah plickers sifteo edmodo ifttt zimbra. Babblely odeo kaboodle
quora plaxo ideeli hulu weebly balihoo...
.timeline-footer
%a.btn.btn-primary.btn-xs Read more
%a.btn.btn-danger.btn-xs Delete
%li
%i.fa.fa-clock-o
/ /.col

View File

@ -7,11 +7,11 @@
- 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' }
%body{ 'ng-app' => 'RosaABF', 'ng-controller' => 'RosaABFController', 'ng-init' => "init('#{I18n.locale}')" }
= render 'layouts/menu/new_top'
%article.container-fluid
.row= yield
= render 'layouts/menu/new_bottom'
= stylesheet_link_tag 'new_application'
= javascript_include_tag 'new_application'
=# javascript_include_tag 'moment/ru.js' if I18n.locale == :ru
= javascript_include_tag 'moment/ru.js' if I18n.locale == :ru

View File

@ -2,7 +2,7 @@
%ul
%li= t('bottom_menu.copyright', year: Date.today.year)
%li ·
%li= image_tag 'flag.png', alt: 'flag', class: 'img-responsive'
%li= image_tag 'flag.png', alt: 'flag'
%li ·
%li= link_to t('bottom_menu.about'), t('bottom_menu.about_url')
%li ·

View File

@ -1,116 +0,0 @@
/* ============================================================
* angular-busy.js v3.0.2
* https://github.com/cgross/angular-busy
* ============================================================
* Copyright 2013 Chris Gross
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ============================================================ */
angular.module('cgBusy',['ajoslin.promise-tracker']);
angular.module('cgBusy').value('cgBusyTemplateName','angular-busy.html');
angular.module('cgBusy').directive('cgBusy',['promiseTracker','$compile','$templateCache','cgBusyTemplateName','$http',
function(promiseTracker,$compile,$templateCache,cgBusyTemplateName,$http){
return {
restrict: 'A',
link: function(scope, element, attrs, fn) {
var options = scope.$eval(attrs.cgBusy);
if (typeof options === 'string'){
options = {tracker:options};
}
if (typeof options === 'undefined' || typeof options.tracker === 'undefined'){
throw new Error('Options for cgBusy directive must be provided (tracker option is required).');
}
if (!scope.$cgBusyTracker){
scope.$cgBusyTracker = {};
}
scope.$cgBusyTracker[options.tracker] = promiseTracker(options.tracker);
var position = element.css('position');
if (position === 'static' || position === '' || typeof position === 'undefined'){
element.css('position','relative');
}
var indicatorTemplateName = options.template ? options.template : cgBusyTemplateName;
$http.get(indicatorTemplateName,{cache: $templateCache}).success(function(indicatorTemplate){
options.backdrop = typeof options.backdrop === 'undefined' ? true : options.backdrop;
var backdrop = options.backdrop ? '<div class="cg-busy cg-busy-backdrop"></div>' : '';
var template = '<div class="cg-busy" ng-show="$cgBusyTracker[\''+options.tracker+'\'].active()" ng-animate="\'cg-busy\'" style="display:none">'+ backdrop + indicatorTemplate+'</div>';
var templateElement = $compile(template)(scope);
angular.element(templateElement.children()[options.backdrop?1:0])
.css('position','absolute')
.css('top',0)
.css('left',0)
.css('right',0)
.css('bottom',0);
element.append(templateElement);
}).error(function(data){
throw new Error('Template specified for cgBusy ('+options.template+') could not be loaded. ' + data);
});
}
};
}
]);
angular.module("cgBusy").run(["$templateCache", function($templateCache) {
$templateCache.put("angular-busy.html",
"<div class=\"cg-busy-default-wrapper\">" +
"" +
" <div class=\"cg-busy-default-sign\">" +
"" +
" <div class=\"cg-busy-default-spinner\">" +
" <div class=\"bar1\"></div>" +
" <div class=\"bar2\"></div>" +
" <div class=\"bar3\"></div>" +
" <div class=\"bar4\"></div>" +
" <div class=\"bar5\"></div>" +
" <div class=\"bar6\"></div>" +
" <div class=\"bar7\"></div>" +
" <div class=\"bar8\"></div>" +
" <div class=\"bar9\"></div>" +
" <div class=\"bar10\"></div>" +
" <div class=\"bar11\"></div>" +
" <div class=\"bar12\"></div>" +
" </div>" +
"" +
" <div class=\"cg-busy-default-text\">Please Wait...</div>" +
"" +
" </div>" +
"" +
"</div>"
);
}]);

295
vendor/assets/javascripts/loading-bar.js vendored Normal file
View File

@ -0,0 +1,295 @@
/*
* angular-loading-bar
* https://github.com/chieffancypants/angular-loading-bar
*
* intercepts XHR requests and creates a loading bar.
* Based on the excellent nprogress work by rstacruz (more info in readme)
*
* (c) 2013 Wes Cruver
* License: MIT
*/
(function() {
'use strict';
// Alias the loading bar so it can be included using a simpler
// (and maybe more professional) module name:
angular.module('angular-loading-bar', ['chieffancypants.loadingBar']);
/**
* loadingBarInterceptor service
*
* Registers itself as an Angular interceptor and listens for XHR requests.
*/
angular.module('chieffancypants.loadingBar', [])
.config(['$httpProvider', function ($httpProvider) {
var interceptor = ['$q', '$cacheFactory', '$timeout', '$rootScope', 'cfpLoadingBar', function ($q, $cacheFactory, $timeout, $rootScope, cfpLoadingBar) {
/**
* The total number of requests made
*/
var reqsTotal = 0;
/**
* The number of requests completed (either successfully or not)
*/
var reqsCompleted = 0;
/**
* The amount of time spent fetching before showing the loading bar
*/
var latencyThreshold = cfpLoadingBar.latencyThreshold;
/**
* $timeout handle for latencyThreshold
*/
var startTimeout;
/**
* calls cfpLoadingBar.complete() which removes the
* loading bar from the DOM.
*/
function setComplete() {
$timeout.cancel(startTimeout);
cfpLoadingBar.complete();
reqsCompleted = 0;
reqsTotal = 0;
}
/**
* Determine if the response has already been cached
* @param {Object} config the config option from the request
* @return {Boolean} retrns true if cached, otherwise false
*/
function isCached(config) {
var cache;
var defaults = $httpProvider.defaults;
if (config.method !== 'GET' || config.cache === false) {
config.cached = false;
return false;
}
if (config.cache === true && defaults.cache === undefined) {
cache = $cacheFactory.get('$http');
} else if (defaults.cache !== undefined) {
cache = defaults.cache;
} else {
cache = config.cache;
}
var cached = cache !== undefined ?
cache.get(config.url) !== undefined : false;
if (config.cached !== undefined && cached !== config.cached) {
return config.cached;
}
config.cached = cached;
return cached;
}
return {
'request': function(config) {
// Check to make sure this request hasn't already been cached and that
// the requester didn't explicitly ask us to ignore this request:
if (!config.ignoreLoadingBar && !isCached(config)) {
$rootScope.$broadcast('cfpLoadingBar:loading', {url: config.url});
if (reqsTotal === 0) {
startTimeout = $timeout(function() {
cfpLoadingBar.start();
}, latencyThreshold);
}
reqsTotal++;
cfpLoadingBar.set(reqsCompleted / reqsTotal);
}
return config;
},
'response': function(response) {
if (!isCached(response.config)) {
reqsCompleted++;
$rootScope.$broadcast('cfpLoadingBar:loaded', {url: response.config.url});
if (reqsCompleted >= reqsTotal) {
setComplete();
} else {
cfpLoadingBar.set(reqsCompleted / reqsTotal);
}
}
return response;
},
'responseError': function(rejection) {
if (!isCached(rejection.config)) {
reqsCompleted++;
$rootScope.$broadcast('cfpLoadingBar:loaded', {url: rejection.config.url});
if (reqsCompleted >= reqsTotal) {
setComplete();
} else {
cfpLoadingBar.set(reqsCompleted / reqsTotal);
}
}
return $q.reject(rejection);
}
};
}];
$httpProvider.interceptors.push(interceptor);
}])
/**
* Loading Bar
*
* This service handles adding and removing the actual element in the DOM.
* Generally, best practices for DOM manipulation is to take place in a
* directive, but because the element itself is injected in the DOM only upon
* XHR requests, and it's likely needed on every view, the best option is to
* use a service.
*/
.provider('cfpLoadingBar', function() {
this.includeSpinner = true;
this.includeBar = true;
this.latencyThreshold = 100;
this.startSize = 0.02;
this.parentSelector = 'body';
this.$get = ['$document', '$timeout', '$animate', '$rootScope', function ($document, $timeout, $animate, $rootScope) {
var $parentSelector = this.parentSelector,
$parent = $document.find($parentSelector),
loadingBarContainer = angular.element('<div id="loading-bar"><div class="bar"><div class="peg"></div></div></div>'),
loadingBar = loadingBarContainer.find('div').eq(0),
spinner = angular.element('<i id="loading-bar-spinner" class="fa fa-spinner fa-spin"></i>');
var incTimeout,
completeTimeout,
started = false,
status = 0;
var includeSpinner = this.includeSpinner;
var includeBar = this.includeBar;
var startSize = this.startSize;
/**
* Inserts the loading bar element into the dom, and sets it to 2%
*/
function _start() {
$timeout.cancel(completeTimeout);
// do not continually broadcast the started event:
if (started) {
return;
}
$rootScope.$broadcast('cfpLoadingBar:started');
started = true;
if (includeBar) {
$animate.enter(loadingBarContainer, $parent);
}
if (includeSpinner) {
$animate.enter(spinner, $parent);
}
_set(startSize);
}
/**
* Set the loading bar's width to a certain percent.
*
* @param n any value between 0 and 1
*/
function _set(n) {
if (!started) {
return;
}
var pct = (n * 100) + '%';
loadingBar.css('width', pct);
status = n;
// increment loadingbar to give the illusion that there is always
// progress but make sure to cancel the previous timeouts so we don't
// have multiple incs running at the same time.
$timeout.cancel(incTimeout);
incTimeout = $timeout(function() {
_inc();
}, 250);
}
/**
* Increments the loading bar by a random amount
* but slows down as it progresses
*/
function _inc() {
if (_status() >= 1) {
return;
}
var rnd = 0;
// TODO: do this mathmatically instead of through conditions
var stat = _status();
if (stat >= 0 && stat < 0.25) {
// Start out between 3 - 6% increments
rnd = (Math.random() * (5 - 3 + 1) + 3) / 100;
} else if (stat >= 0.25 && stat < 0.65) {
// increment between 0 - 3%
rnd = (Math.random() * 3) / 100;
} else if (stat >= 0.65 && stat < 0.9) {
// increment between 0 - 2%
rnd = (Math.random() * 2) / 100;
} else if (stat >= 0.9 && stat < 0.99) {
// finally, increment it .5 %
rnd = 0.005;
} else {
// after 99%, don't increment:
rnd = 0;
}
var pct = _status() + rnd;
_set(pct);
}
function _status() {
return status;
}
function _complete() {
$rootScope.$broadcast('cfpLoadingBar:completed');
_set(1);
// Attempt to aggregate any start/complete calls within 500ms:
completeTimeout = $timeout(function() {
$animate.leave(loadingBarContainer, function() {
status = 0;
started = false;
});
$animate.leave(spinner);
}, 500);
}
return {
start : _start,
set : _set,
status : _status,
inc : _inc,
complete : _complete,
includeSpinner : this.includeSpinner,
latencyThreshold : this.latencyThreshold,
parentSelector : this.parentSelector,
startSize : this.startSize
};
}]; //
}); // wtf javascript. srsly
})(); //

View File

@ -1,295 +0,0 @@
/* ============================================================
* angular-busy.css v3.0.2
* https://github.com/cgross/angular-busy
* ============================================================
* Copyright 2013 Chris Gross
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ============================================================ */
.cg-busy{
position:absolute;
top:0px;
left:0px;
right:0px;
bottom:0px;
}
.cg-busy-animation.ng-hide-add,
.cg-busy-animation.ng-hide-remove {
-webkit-transition:all .3s ease;
-moz-transition:all .3s ease;
-o-transition:all .3s ease;
transition:all .3s ease;
display:block !important;
}
.cg-busy-animation.ng-hide-remove {
opacity:0;
-webkit-transform:translate(0px,-40px);
-moz-transform:translate(0px,-40px);
-ms-transform:translate(0px,-40px);
-o-transform:translate(0px,-40px);
transform:translate(0px,-40px);
}
.cg-busy-animation.ng-hide-remove.ng-hide-remove-active {
opacity:1;
-webkit-transform:translate(0px,0px);
-moz-transform:translate(0px,0px);
-ms-transform:translate(0px,0px);
-o-transform:translate(0px,0px);
transform:translate(0px,0px);
}
.cg-busy-animation.ng-hide-add {
opacity:1;
-webkit-transform:translate(0px,0px);
-moz-transform:translate(0px,0px);
-ms-transform:translate(0px,0px);
-o-transform:translate(0px,0px);
transform:translate(0px,0px);
}
.cg-busy-animation.ng-hide-add.ng-hide-add-active {
opacity:0;
-webkit-transform:translate(0px,-40px);
-moz-transform:translate(0px,-40px);
-ms-transform:translate(0px,-40px);
-o-transform:translate(0px,-40px);
transform:translate(0px,-40px);
}
.cg-busy-backdrop {
background-color:white;
opacity:.7;
}
/* All styles below are for the default template. */
.cg-busy-default-sign{
position:absolute;
top:0;
left:50%;
margin-left:-100px;
width:170px;
height:50px;
color:#333333;
text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);
background-color:#e9eeee;
border:1px solid #dddddd;
border-top-width:0;
-webkit-border-radius:7px;
-moz-border-radius:7px;
border-radius:7px;
border-top-left-radius:0;
border-top-right-radius:0;
-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
}
.cg-busy-default-text{
position:absolute;
left:49px;
top:15px;
font-size:16px;
color:#555;
}
.cg-busy-default-spinner{
position:absolute;
width:25px;
height:25px;
display:inline-block;
top:12px;
left:14px;
}
.cg-busy-default-spinner div{
width:12%;
height:26%;
background:#000;
position:absolute;
left:44.5%;
top:37%;
opacity:0;
-webkit-animation:cg-busy-spinner-anim 1s linear infinite;
-moz-animation:cg-busy-spinner-anim 1s linear infinite;
-ms-animation:cg-busy-spinner-anim 1s linear infinite;
-o-animation:cg-busy-spinner-anim 1s linear infinite;
animation:cg-busy-spinner-anim 1s linear infinite;
-webkit-border-radius:50px;
-moz-border-radius:50px;
border-radius:50px;
-webkit-box-shadow:0 0 3px rgba(0,0,0,0.2);
-moz-box-shadow:0 0 3px rgba(0,0,0,0.2);
box-shadow:0 0 3px rgba(0,0,0,0.2);
}
.cg-busy-default-spinner div.bar1{
-webkit-transform:rotate(0deg) translate(0, -142%);
-moz-transform:rotate(0deg) translate(0, -142%);
-ms-transform:rotate(0deg) translate(0, -142%);
-o-transform:rotate(0deg) translate(0, -142%);
transform:rotate(0deg) translate(0, -142%);
-webkit-animation-delay:0s;
-moz-animation-delay:0s;
-ms-animation-delay:0s;
-o-animation-delay:0s;
animation-delay:0s;
}
.cg-busy-default-spinner div.bar2{
-webkit-transform:rotate(30deg) translate(0, -142%);
-moz-transform:rotate(30deg) translate(0, -142%);
-ms-transform:rotate(30deg) translate(0, -142%);
-o-transform:rotate(30deg) translate(0, -142%);
transform:rotate(30deg) translate(0, -142%);
-webkit-animation-delay:-0.9167s;
-moz-animation-delay:-0.9167s;
-ms-animation-delay:-0.9167s;
-o-animation-delay:-0.9167s;
animation-delay:-0.9167s;
}
.cg-busy-default-spinner div.bar3{
-webkit-transform:rotate(60deg) translate(0, -142%);
-moz-transform:rotate(60deg) translate(0, -142%);
-ms-transform:rotate(60deg) translate(0, -142%);
-o-transform:rotate(60deg) translate(0, -142%);
transform:rotate(60deg) translate(0, -142%);
-webkit-animation-delay:-0.833s;
-moz-animation-delay:-0.833s;
-ms-animation-delay:-0.833s;
-o-animation-delay:-0.833s;
animation-delay:-0.833s;
}
.cg-busy-default-spinner div.bar4{
-webkit-transform:rotate(90deg) translate(0, -142%);
-moz-transform:rotate(90deg) translate(0, -142%);
-ms-transform:rotate(90deg) translate(0, -142%);
-o-transform:rotate(90deg) translate(0, -142%);
transform:rotate(90deg) translate(0, -142%);
-webkit-animation-delay:-0.75s;
-moz-animation-delay:-0.75s;
-ms-animation-delay:-0.75s;
-o-animation-delay:-0.75s;
animation-delay:-0.75s;
}
.cg-busy-default-spinner div.bar5{
-webkit-transform:rotate(120deg) translate(0, -142%);
-moz-transform:rotate(120deg) translate(0, -142%);
-ms-transform:rotate(120deg) translate(0, -142%);
-o-transform:rotate(120deg) translate(0, -142%);
transform:rotate(120deg) translate(0, -142%);
-webkit-animation-delay:-0.667s;
-moz-animation-delay:-0.667s;
-ms-animation-delay:-0.667s;
-o-animation-delay:-0.667s;
animation-delay:-0.667s;
}
.cg-busy-default-spinner div.bar6{
-webkit-transform:rotate(150deg) translate(0, -142%);
-moz-transform:rotate(150deg) translate(0, -142%);
-ms-transform:rotate(150deg) translate(0, -142%);
-o-transform:rotate(150deg) translate(0, -142%);
transform:rotate(150deg) translate(0, -142%);
-webkit-animation-delay:-0.5833s;
-moz-animation-delay:-0.5833s;
-ms-animation-delay:-0.5833s;
-o-animation-delay:-0.5833s;
animation-delay:-0.5833s;
}
.cg-busy-default-spinner div.bar7{
-webkit-transform:rotate(180deg) translate(0, -142%);
-moz-transform:rotate(180deg) translate(0, -142%);
-ms-transform:rotate(180deg) translate(0, -142%);
-o-transform:rotate(180deg) translate(0, -142%);
transform:rotate(180deg) translate(0, -142%);
-webkit-animation-delay:-0.5s;
-moz-animation-delay:-0.5s;
-ms-animation-delay:-0.5s;
-o-animation-delay:-0.5s;
animation-delay:-0.5s;
}
.cg-busy-default-spinner div.bar8{
-webkit-transform:rotate(210deg) translate(0, -142%);
-moz-transform:rotate(210deg) translate(0, -142%);
-ms-transform:rotate(210deg) translate(0, -142%);
-o-transform:rotate(210deg) translate(0, -142%);
transform:rotate(210deg) translate(0, -142%);
-webkit-animation-delay:-0.41667s;
-moz-animation-delay:-0.41667s;
-ms-animation-delay:-0.41667s;
-o-animation-delay:-0.41667s;
animation-delay:-0.41667s;
}
.cg-busy-default-spinner div.bar9{
-webkit-transform:rotate(240deg) translate(0, -142%);
-moz-transform:rotate(240deg) translate(0, -142%);
-ms-transform:rotate(240deg) translate(0, -142%);
-o-transform:rotate(240deg) translate(0, -142%);
transform:rotate(240deg) translate(0, -142%);
-webkit-animation-delay:-0.333s;
-moz-animation-delay:-0.333s;
-ms-animation-delay:-0.333s;
-o-animation-delay:-0.333s;
animation-delay:-0.333s;
}
.cg-busy-default-spinner div.bar10{
-webkit-transform:rotate(270deg) translate(0, -142%);
-moz-transform:rotate(270deg) translate(0, -142%);
-ms-transform:rotate(270deg) translate(0, -142%);
-o-transform:rotate(270deg) translate(0, -142%);
transform:rotate(270deg) translate(0, -142%);
-webkit-animation-delay:-0.25s;
-moz-animation-delay:-0.25s;
-ms-animation-delay:-0.25s;
-o-animation-delay:-0.25s;
animation-delay:-0.25s;
}
.cg-busy-default-spinner div.bar11{
-webkit-transform:rotate(300deg) translate(0, -142%);
-moz-transform:rotate(300deg) translate(0, -142%);
-ms-transform:rotate(300deg) translate(0, -142%);
-o-transform:rotate(300deg) translate(0, -142%);
transform:rotate(300deg) translate(0, -142%);
-webkit-animation-delay:-0.1667s;
-moz-animation-delay:-0.1667s;
-ms-animation-delay:-0.1667s;
-o-animation-delay:-0.1667s;
animation-delay:-0.1667s;
}
.cg-busy-default-spinner div.bar12{
-webkit-transform:rotate(330deg) translate(0, -142%);
-moz-transform:rotate(330deg) translate(0, -142%);
-ms-transform:rotate(330deg) translate(0, -142%);
-o-transform:rotate(330deg) translate(0, -142%);
transform:rotate(330deg) translate(0, -142%);
-webkit-animation-delay:-0.0833s;
-moz-animation-delay:-0.0833s;
-ms-animation-delay:-0.0833s;
-o-animation-delay:-0.0833s;
animation-delay:-0.0833s;
}
@-webkit-keyframes cg-busy-spinner-anim{
from {opacity: 1;}
to {opacity: 0.25;}
}
@-moz-keyframes cg-busy-spinner-anim{
from {opacity: 1;}
to {opacity: 0.25;}
}
@keyframes cg-busy-spinner-anim{
from {opacity: 1;}
to {opacity: 0.25;}
}

View File

@ -0,0 +1,81 @@
/*
* angular-loading-bar
* https://github.com/chieffancypants/angular-loading-bar
*
* intercepts XHR requests and creates a loading bar.
* Based on the excellent nprogress work by rstacruz (more info in readme)
*
* (c) 2013 Wes Cruver
* License: MIT
*/
$loading-bar-bg: #254561; // #dff0d8;
/* Make clicks pass-through */
#loading-bar,
#loading-bar-spinner {
pointer-events: none;
-webkit-pointer-events: none;
-webkit-transition: 350ms linear all;
-moz-transition: 350ms linear all;
-o-transition: 350ms linear all;
transition: 350ms linear all;
}
#loading-bar.ng-enter,
#loading-bar.ng-leave.ng-leave-active,
#loading-bar-spinner.ng-enter,
#loading-bar-spinner.ng-leave.ng-leave-active {
opacity: 0;
}
#loading-bar.ng-enter.ng-enter-active,
#loading-bar.ng-leave,
#loading-bar-spinner.ng-enter.ng-enter-active,
#loading-bar-spinner.ng-leave {
opacity: 1;
}
#loading-bar .bar {
-webkit-transition: width 350ms;
-moz-transition: width 350ms;
-o-transition: width 350ms;
transition: width 350ms;
background: $loading-bar-bg;
position: fixed;
z-index: 2000;
top: 0;
left: 0;
width: 100%;
height: 4px;
border-bottom-right-radius: 1px;
border-top-right-radius: 1px;
}
/* Fancy blur effect */
#loading-bar .peg {
position: absolute;
width: 70px;
right: 0;
top: 0;
height: 2px;
opacity: .45;
-moz-box-shadow: $loading-bar-bg 1px 0 6px 1px;
-ms-box-shadow: $loading-bar-bg 1px 0 6px 1px;
-webkit-box-shadow: $loading-bar-bg 1px 0 6px 1px;
box-shadow: $loading-bar-bg 1px 0 6px 1px;
-moz-border-radius: 100%;
-webkit-border-radius: 100%;
border-radius: 100%;
}
#loading-bar-spinner {
display: block;
position: fixed;
z-index: 2000;
top: 10px;
left: 17px;
font-size: 31px;
color: $loading-bar-bg;
}

118
vendor/assets/stylesheets/timeline.scss vendored Normal file
View File

@ -0,0 +1,118 @@
/* ============================================================
* https://github.com/almasaeed2010/AdminLTE
* AdminLTE v1.1
* ============================================================
* The MIT License (MIT)
* Copyright (c) 2013 almasaeed2010
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
Component: timeline
--------------------
*/
.timeline {
margin: 0 0 30px 0;
padding: 0;
list-style: none;
}
.timeline:before {
content: '';
position: absolute;
top: 0px;
bottom: 0;
width: 5px;
background: #ddd;
left: 45px;
border: 1px solid #eee;
margin: 0;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
}
.timeline > .timeline-element > li {
position: relative;
margin-right: 10px;
margin-bottom: 15px;
}
.timeline > .timeline-element > li:before,
.timeline > .timeline-element > li:after {
display: table;
content: " ";
}
.timeline > .timeline-element > li:after {
clear: both;
}
.timeline > .timeline-element > li > .timeline-item {
margin-top: 10px;
border: 0px solid #dfdfdf;
background: #fff;
color: #555;
margin-left: 60px;
margin-right: 15px;
padding: 5px;
position: relative;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
}
.timeline > .timeline-element > li > .timeline-item > .time {
color: #999;
float: right;
margin: 2px 0 0 0;
}
.timeline > .timeline-element > li > .timeline-item > .timeline-header {
margin: 0;
color: #555;
border-bottom: 1px solid #f4f4f4;
padding: 5px;
font-size: 16px;
line-height: 1.1;
}
.timeline > .timeline-element > li > .timeline-item > .timeline-header > a {
font-weight: 600;
}
.timeline > .timeline-element > li > .timeline-item > .timeline-body,
.timeline > .timeline-element > li > .timeline-item > .timeline-footer {
padding: 10px;
}
.timeline > .timeline-element > li.time-label > span {
font-weight: 600;
padding: 5px;
display: inline-block;
background-color: #fff;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.timeline > .timeline-element > li > .fa,
.timeline > .timeline-element > li > .glyphicon,
.timeline > .timeline-element > li > .ion {
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
width: 30px;
height: 30px;
font-size: 15px;
line-height: 30px;
position: absolute;
color: #fff; //#666;
//background: #00c0ef; //#eee;
text-align: center;
left: 18px;
top: 0;
}