[#369] add templates; add codemirror
This commit is contained in:
parent
09b75e4110
commit
1a1838a363
3
Gemfile
3
Gemfile
|
@ -75,6 +75,7 @@ gem 'angular-i18n', '0.1.2'
|
||||||
gem 'js-routes'
|
gem 'js-routes'
|
||||||
gem 'soundmanager-rails'
|
gem 'soundmanager-rails'
|
||||||
gem 'angular-ui-bootstrap-rails'
|
gem 'angular-ui-bootstrap-rails'
|
||||||
|
gem 'angular-rails-templates'
|
||||||
|
|
||||||
gem 'time_diff'
|
gem 'time_diff'
|
||||||
|
|
||||||
|
@ -88,6 +89,8 @@ gem 'therubyrhino', '~> 1.73.1', platforms: :jruby
|
||||||
gem 'bootstrap-sass', '~> 3.1.1'
|
gem 'bootstrap-sass', '~> 3.1.1'
|
||||||
gem 'font-awesome-rails'
|
gem 'font-awesome-rails'
|
||||||
|
|
||||||
|
gem 'codemirror-rails'
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
gem "airbrake", '~> 3.1.2'
|
gem "airbrake", '~> 3.1.2'
|
||||||
gem 'bluepill', '~> 0.0.60', require: false
|
gem 'bluepill', '~> 0.0.60', require: false
|
||||||
|
|
|
@ -64,6 +64,9 @@ GEM
|
||||||
ancestry (2.0.0)
|
ancestry (2.0.0)
|
||||||
activerecord (>= 3.0.0)
|
activerecord (>= 3.0.0)
|
||||||
angular-i18n (0.1.2)
|
angular-i18n (0.1.2)
|
||||||
|
angular-rails-templates (0.0.7)
|
||||||
|
railties (>= 3.1)
|
||||||
|
sprockets
|
||||||
angular-ui-bootstrap-rails (0.10.0)
|
angular-ui-bootstrap-rails (0.10.0)
|
||||||
angularjs-rails (1.2.15)
|
angularjs-rails (1.2.15)
|
||||||
arel (4.0.2)
|
arel (4.0.2)
|
||||||
|
@ -102,6 +105,8 @@ GEM
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
cocaine (0.5.3)
|
cocaine (0.5.3)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
|
codemirror-rails (3.22)
|
||||||
|
railties (>= 3.0, < 5)
|
||||||
coderay (1.1.0)
|
coderay (1.1.0)
|
||||||
coffee-rails (4.0.1)
|
coffee-rails (4.0.1)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
|
@ -468,6 +473,7 @@ DEPENDENCIES
|
||||||
airbrake (~> 3.1.2)
|
airbrake (~> 3.1.2)
|
||||||
ancestry (~> 2.0.0)
|
ancestry (~> 2.0.0)
|
||||||
angular-i18n (= 0.1.2)
|
angular-i18n (= 0.1.2)
|
||||||
|
angular-rails-templates
|
||||||
angular-ui-bootstrap-rails
|
angular-ui-bootstrap-rails
|
||||||
angularjs-rails (~> 1.2.15)
|
angularjs-rails (~> 1.2.15)
|
||||||
attr_encrypted (~> 1.3.2)
|
attr_encrypted (~> 1.3.2)
|
||||||
|
@ -480,6 +486,7 @@ DEPENDENCIES
|
||||||
capistrano
|
capistrano
|
||||||
capistrano_colors
|
capistrano_colors
|
||||||
charlock_holmes (~> 0.6.9)
|
charlock_holmes (~> 0.6.9)
|
||||||
|
codemirror-rails
|
||||||
coffee-rails (~> 4.0.1)
|
coffee-rails (~> 4.0.1)
|
||||||
compass-rails (~> 1.1.6)
|
compass-rails (~> 1.1.6)
|
||||||
creole
|
creole
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf', 'angular-i18n', 'angularMoment']);
|
//var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf', 'angular-i18n', 'angularMoment']);
|
||||||
var RosaABF = angular.module('RosaABF', ['ui.bootstrap', 'angular-i18n', 'angularMoment',
|
var RosaABF = angular.module('RosaABF', ['ui.bootstrap', 'angular-i18n', 'angularMoment',
|
||||||
'chieffancypants.loadingBar', 'ngSanitize']);
|
'chieffancypants.loadingBar', 'ngSanitize', 'templates',
|
||||||
|
'ui.codemirror']);
|
||||||
|
|
||||||
var LocalesHelper = function($locale) {
|
var LocalesHelper = function($locale) {
|
||||||
var locales = {
|
var locales = {
|
||||||
|
|
|
@ -55,4 +55,12 @@ RosaABF.controller('ActivityCtrl', ['$scope', '$http', '$timeout', '$q', '$filte
|
||||||
return content.kind === 'new_comment_notification' ||
|
return content.kind === 'new_comment_notification' ||
|
||||||
content.kind === 'new_comment_commit_notification';
|
content.kind === 'new_comment_commit_notification';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.getTemplate = function(content) {
|
||||||
|
if(content.kind == 'new_commit_notification' || content.kind == 'git_new_push_notification' ||
|
||||||
|
content.kind == 'git_delete_branch_notification' || content.kind == 'new_issue_notification') {
|
||||||
|
return content.kind + '.html';}
|
||||||
|
else return 'new_comment_notification.html';
|
||||||
|
};
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
%i.img-circle.btn-danger.fa.fa-times
|
||||||
|
.timeline-item{ 'ng-cloak' => true }
|
||||||
|
%h3.timeline-header
|
||||||
|
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||||
|
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||||
|
{{item.user.uname}}
|
||||||
|
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||||
|
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||||
|
%span.glyphicon.glyphicon-time
|
||||||
|
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||||
|
.clearfix
|
||||||
|
.timeline-body
|
||||||
|
%p
|
||||||
|
{{'notification.push.delete_branch' | i18n}}
|
||||||
|
{{ item.branch_name + ('notification.in_project' | i18n)}}
|
||||||
|
%a{ 'ng-href' => "{{item.project_link}}" } {{item.project_name_with_owner}}
|
|
@ -0,0 +1,27 @@
|
||||||
|
%i.img-circle.bg-primary.fa.fa-sign-in
|
||||||
|
.timeline-item{ 'ng-cloak' => true }
|
||||||
|
%h3.timeline-header
|
||||||
|
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||||
|
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||||
|
{{item.user.uname}}
|
||||||
|
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||||
|
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||||
|
%span.glyphicon.glyphicon-time
|
||||||
|
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||||
|
.clearfix
|
||||||
|
.timeline-body
|
||||||
|
%p
|
||||||
|
{{'notification.push.' + item.change_type + '_branch' | i18n}}
|
||||||
|
{{ item.branch_name + ('notification.in_project' | i18n)}}
|
||||||
|
%a{ 'ng-href' => "{{item.project_link}}" } {{item.project_name_with_owner}}
|
||||||
|
|
||||||
|
.timeline-footer
|
||||||
|
.row
|
||||||
|
.container-fluid{ 'ng-repeat' => 'commit in item.last_commits' }
|
||||||
|
.col-sm-3.col-md-2
|
||||||
|
%a{ 'ng-href' => "{{commit.commit_path}}" } {{commit.hash}}
|
||||||
|
.col-sm-8.col-md-9{ 'ng-bind-html' => "commit.message" }
|
||||||
|
.clearfix
|
||||||
|
|
||||||
|
%br{ 'ng-if' => "item.other_commits" }
|
||||||
|
%a{ 'ng-if' => "item.other_commits", 'ng-href' => "{{item.other_commits_path}}" } {{item.other_commits}}
|
|
@ -0,0 +1,22 @@
|
||||||
|
%i.img-circle.btn-warning.fa.fa-comment
|
||||||
|
.timeline-item{ 'ng-cloak' => true }
|
||||||
|
%h3.timeline-header
|
||||||
|
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||||
|
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||||
|
{{item.user.uname}}
|
||||||
|
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||||
|
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||||
|
%span.glyphicon.glyphicon-time
|
||||||
|
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||||
|
.clearfix
|
||||||
|
.timeline-body
|
||||||
|
%p
|
||||||
|
{{'notification.new_comment.title' | i18n}}
|
||||||
|
%a{ 'ng-href' => "{{item.issue.link}}" } {{item.issue.title}}
|
||||||
|
|
||||||
|
%blockquote{ 'ng-bind-html' => "item.body" }
|
||||||
|
|
||||||
|
.timeline-footer
|
||||||
|
%a.btn.btn-primary.btn-xs{ 'ng-href' => "{{item.issue.link + '#comment' + item.issue.read_more}}" }
|
||||||
|
{{'read_more' | i18n}}
|
||||||
|
{{item.kind}}
|
|
@ -0,0 +1,16 @@
|
||||||
|
%i.img-circle.btn-success.fa.fa-check
|
||||||
|
.timeline-item{ 'ng-cloak' => true }
|
||||||
|
%h3.timeline-header
|
||||||
|
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||||
|
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||||
|
{{item.user.uname}}
|
||||||
|
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||||
|
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||||
|
%span.glyphicon.glyphicon-time
|
||||||
|
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||||
|
.clearfix
|
||||||
|
.timeline-body
|
||||||
|
%p
|
||||||
|
{{('notification.new_issue' | i18n) + ('notification.in_project' | i18n)}}
|
||||||
|
%a{ 'ng-href' => "{{item.project_link}}" } {{item.project_name_with_owner}}
|
||||||
|
%a{ 'ng-href' => "{{item.issue.link}}" } {{item.issue.title}}
|
|
@ -17,7 +17,19 @@ var _locales = {
|
||||||
'autostart_statuses.1': 'Раз в день',
|
'autostart_statuses.1': 'Раз в день',
|
||||||
'autostart_statuses.2': 'Раз в неделю',
|
'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.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>,
|
||||||
|
|
||||||
|
'notification.new_comment.title': 'добавил новый комментарий к задаче ',
|
||||||
|
'notification.push.delete_branch': 'удалил ветку ',
|
||||||
|
'notification.push.create_branch': 'создал новую ветку ',
|
||||||
|
'notification.push.update_branch': 'внес изменения в ветку ',
|
||||||
|
'notification.in_project': ' в проекте ',
|
||||||
|
'notification.new_issue': 'добавил новую задачу',
|
||||||
|
|
||||||
|
'read_more': 'Читать дальше',
|
||||||
|
|
||||||
},
|
},
|
||||||
<%I18n.locale = :en%>
|
<%I18n.locale = :en%>
|
||||||
'en-us': {
|
'en-us': {
|
||||||
|
@ -35,6 +47,18 @@ var _locales = {
|
||||||
'autostart_statuses.1': 'Once a day',
|
'autostart_statuses.1': 'Once a day',
|
||||||
'autostart_statuses.2': 'Once a week',
|
'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(',') %>
|
|
||||||
|
//
|
||||||
|
<%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>,
|
||||||
|
|
||||||
|
'notification.new_comment.title': 'added a new comment in issue ',
|
||||||
|
'notification.push.delete_branch': 'deleted a branch ',
|
||||||
|
'notification.push.create_branch': 'created a new branch ',
|
||||||
|
'notification.push.update_branch': 'pushed to branch ',
|
||||||
|
'notification.in_project': ' in project ',
|
||||||
|
'notification.new_issue': 'added a new issue ',
|
||||||
|
|
||||||
|
'read_more': 'Read more',
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -1,4 +1,5 @@
|
||||||
//= require jquery
|
//= require jquery
|
||||||
|
//= require jquery_ujs
|
||||||
//= require js-routes
|
//= require js-routes
|
||||||
|
|
||||||
// Loads all Bootstrap javascripts
|
// Loads all Bootstrap javascripts
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
//= require angular
|
//= require angular
|
||||||
//= require angular-sanitize
|
//= require angular-sanitize
|
||||||
//= require angular-ui-bootstrap-tpls
|
//= require angular-ui-bootstrap-tpls
|
||||||
|
//= require ui-codemirror
|
||||||
//= require angular-i18n
|
//= require angular-i18n
|
||||||
//= require angularjs/locales
|
//= require angularjs/locales
|
||||||
|
|
||||||
|
@ -16,3 +18,19 @@
|
||||||
|
|
||||||
//= require_tree ./angular-new
|
//= require_tree ./angular-new
|
||||||
//= require loading-bar
|
//= require loading-bar
|
||||||
|
|
||||||
|
//= require codemirror
|
||||||
|
// ### TODO require all files in codemirror/modes ###
|
||||||
|
//= require codemirror/modes/ruby
|
||||||
|
//= require codemirror/modes/javascript
|
||||||
|
//= require codemirror/modes/markdown
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
window.CodeMirrorRun = function(code) {
|
||||||
|
//CodeMirror.runMode(code.innerHTML.replace(/&/gi, '&').replace(/</gi, '<').replace(/>/gi, '>'), code.className, code);
|
||||||
|
CodeMirror.runMode(code.innerHTML, 'markdown', code);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.md_and_cm').each(function (code) { CodeMirrorRun(this); });
|
||||||
|
|
||||||
|
});
|
||||||
|
|
|
@ -9,4 +9,5 @@ $navbar-default-link-hover-color: #CEE7FF;
|
||||||
@import "custom_bootstrap";
|
@import "custom_bootstrap";
|
||||||
@import "timeline";
|
@import "timeline";
|
||||||
@import "font-awesome";
|
@import "font-awesome";
|
||||||
@import "loading-bar";
|
@import "loading-bar";
|
||||||
|
@import "codemirror";
|
||||||
|
|
|
@ -11,6 +11,7 @@ class HomeController < ApplicationController
|
||||||
@activity_feeds = current_user.activity_feeds
|
@activity_feeds = current_user.activity_feeds
|
||||||
@activity_feeds = @activity_feeds.where(kind: "ActivityFeed::#{@filter.upcase}".constantize) unless @filter == :all
|
@activity_feeds = @activity_feeds.where(kind: "ActivityFeed::#{@filter.upcase}".constantize) unless @filter == :all
|
||||||
@activity_feeds = @activity_feeds.paginate page: params[:page]
|
@activity_feeds = @activity_feeds.paginate page: params[:page]
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { request.xhr? ? render('_list', layout: false) : render('activity') }
|
format.html { request.xhr? ? render('_list', layout: false) : render('activity') }
|
||||||
format.json {}
|
format.json {}
|
||||||
|
|
|
@ -18,30 +18,4 @@ module ActivityFeedsHelper
|
||||||
def user_link(user, user_name, full_url = false)
|
def user_link(user, user_name, full_url = false)
|
||||||
user.persisted? ? link_to(user_name, full_url ? user_url(user) : user_path(user)) : user_name
|
user.persisted? ? link_to(user_name, full_url ? user_url(user) : user_path(user)) : user_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_title_from_activity_item(item, opts = {})
|
|
||||||
case item.kind
|
|
||||||
when 'new_comment_notification'
|
|
||||||
res = t('notifications.bodies.new_comment_notification.title', { user_link: nil })
|
|
||||||
res << ' ' << t('notifications.bodies.new_comment_notification.content',
|
|
||||||
{ issue_link: link_to(item.data[:issue_title], opts[:path]) })
|
|
||||||
when 'git_new_push_notification'
|
|
||||||
res = t("notifications.bodies.#{item.data[:change_type]}_branch",
|
|
||||||
{ branch_name: item.data[:branch_name], user_link: nil })
|
|
||||||
res << ' ' << t('notifications.bodies.project', project_link: link_to(opts[:project_name_with_owner], opts[:path]))
|
|
||||||
else nil
|
|
||||||
end
|
|
||||||
raw res
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_path_from_activity_item(item, opts = {})
|
|
||||||
case item.kind
|
|
||||||
when 'new_comment_notification'
|
|
||||||
project_issue_path(opts[:project_name_with_owner], item.data[:issue_serial_id])
|
|
||||||
when 'git_new_push_notification'
|
|
||||||
project_path(opts[:project_name_with_owner])
|
|
||||||
else
|
|
||||||
'?'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,7 @@ module Feed::Comment
|
||||||
user_name: user.name,
|
user_name: user.name,
|
||||||
user_email: user.email,
|
user_email: user.email,
|
||||||
user_id: user_id,
|
user_id: user_id,
|
||||||
comment_body: truncate(body, length: 1000, omission: '…'),
|
comment_body: truncate(body, length: 100, omission: '…'),
|
||||||
issue_title: commentable.title,
|
issue_title: commentable.title,
|
||||||
issue_serial_id: commentable.serial_id,
|
issue_serial_id: commentable.serial_id,
|
||||||
project_id: commentable.project.id,
|
project_id: commentable.project.id,
|
||||||
|
|
|
@ -43,28 +43,7 @@
|
||||||
%span{ 'ng-show' => "needShowTimeLabel($index)", 'ng-cloak' => true }
|
%span{ 'ng-show' => "needShowTimeLabel($index)", 'ng-cloak' => true }
|
||||||
{{item.date | amDateFormat:'ll'}}
|
{{item.date | amDateFormat:'ll'}}
|
||||||
/ timeline item
|
/ timeline item
|
||||||
%li
|
%li{ 'ng-include' => "getTemplate(item)" }
|
||||||
%i.img-circle.fa{ 'ng-class' => "getTimeLinefaClass(item)" }
|
|
||||||
.timeline-item
|
|
||||||
%h3.timeline-header
|
|
||||||
%a{ 'ng-href' => "{{item.user.link}}" }
|
|
||||||
%img{ 'ng-src' => "{{item.user.image}}" }
|
|
||||||
{{item.user.uname}}
|
|
||||||
%span.time{ 'ng-cloak' => true, popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
|
||||||
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
|
||||||
%span.glyphicon.glyphicon-time
|
|
||||||
%span {{item.date | amDateFormat:'HH:mm'}}
|
|
||||||
.clearfix
|
|
||||||
.timeline-body
|
|
||||||
-#%p{ 'ng-bind-html' => "item.title" }
|
|
||||||
%p{ 'ng-bind-html' => "item.title" }
|
|
||||||
%blockquote{ 'ng-if' => "isComment(item)" }
|
|
||||||
{{item.body}}
|
|
||||||
%p{ 'ng-if' => "!isComment(item)", 'ng-bind-html' => "item.body" }
|
|
||||||
|
|
||||||
.timeline-footer
|
|
||||||
%a.btn.btn-primary.btn-xs{ 'ng-href' => "{{item.read_more}}", 'ng-if' => "isComment(item)" }
|
|
||||||
= t('layout.read_more')
|
|
||||||
.hide{ 'ng-repeat-end' => true }
|
.hide{ 'ng-repeat-end' => true }
|
||||||
%li
|
%li
|
||||||
%i.img-circle.bg-primary.fa.fa-clock-o
|
%i.img-circle.bg-primary.fa.fa-clock-o
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
json.array!(@activity_feeds) do |item|
|
json.array!(@activity_feeds) do |item|
|
||||||
json.cache! item do
|
#json.cache! item, expires_in: 10.minutes do
|
||||||
json.date item.created_at
|
json.date item.created_at
|
||||||
json.kind item.kind
|
json.kind item.kind
|
||||||
user = get_user_from_activity_item(item)
|
user = get_user_from_activity_item(item)
|
||||||
|
@ -8,18 +8,50 @@ json.array!(@activity_feeds) do |item|
|
||||||
json.image avatar_url(user, :small) if user.persisted?
|
json.image avatar_url(user, :small) if user.persisted?
|
||||||
json.uname (user.fullname || user.email)
|
json.uname (user.fullname || user.email)
|
||||||
end if user
|
end if user
|
||||||
|
|
||||||
project_name_with_owner = "#{item.data[:project_owner]}/#{item.data[:project_name]}"
|
project_name_with_owner = "#{item.data[:project_owner]}/#{item.data[:project_name]}"
|
||||||
|
@project = Project.find_by_owner_and_name(item.data[:project_owner], item.data[:project_name])
|
||||||
|
|
||||||
json.project_name_with_owner project_name_with_owner
|
json.project_name_with_owner project_name_with_owner
|
||||||
path = get_path_from_activity_item(item, project_name_with_owner: project_name_with_owner)
|
|
||||||
json.title get_title_from_activity_item(item, user: user, project_name_with_owner: project_name_with_owner, path: path)
|
|
||||||
|
|
||||||
case item.kind
|
case item.kind
|
||||||
when 'new_comment_notification'
|
when 'new_comment_notification'
|
||||||
json.read_more path + "#comment#{item.data[:comment_id]}"
|
json.issue do
|
||||||
json.body short_message(item.data[:comment_body], 1000)
|
json.link project_issue_path(project_name_with_owner, item.data[:issue_serial_id]) if item.data[:issue_serial_id].present?
|
||||||
|
json.title short_message(item.data[:issue_title], 50)
|
||||||
|
json.read_more item.data[:comment_id]
|
||||||
|
end
|
||||||
|
json.body markdown(short_message(item.data[:comment_body], 100))
|
||||||
|
|
||||||
when 'git_new_push_notification'
|
when 'git_new_push_notification'
|
||||||
json.body render('commits_list', item: item, project_name_with_owner: project_name_with_owner).html_safe
|
json.change_type item.data[:change_type]
|
||||||
|
json.project_link project_path(project_name_with_owner)
|
||||||
|
json.branch_name item.data[:branch_name]
|
||||||
|
|
||||||
|
json.last_commits do
|
||||||
|
json.array! item.data[:last_commits] do |commit|
|
||||||
|
json.hash shortest_hash_id(commit[0])
|
||||||
|
json.message markdown(short_message(commit[1], 70))
|
||||||
|
json.commit_path commit_path(project_name_with_owner, commit[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if item.data[:other_commits].present?
|
||||||
|
json.other_commits t('notifications.bodies.more_commits', count: item.data[:other_commits_count], commits: commits_pluralize(item.data[:other_commits_count]))
|
||||||
|
json.other_commits_path diff_path(project_name_with_owner, diff: item.data[:other_commits])
|
||||||
|
end
|
||||||
|
|
||||||
|
when 'git_delete_branch_notification'
|
||||||
|
json.branch_name item.data[:branch_name]
|
||||||
|
json.project_link project_path(project_name_with_owner)
|
||||||
|
|
||||||
|
when 'new_issue_notification'
|
||||||
|
json.project_link project_path(project_name_with_owner)
|
||||||
|
json.issue do
|
||||||
|
json.title item.data[:issue_title]
|
||||||
|
json.link project_issue_path(project_name_with_owner, item.data[:issue_serial_id]) if item.data[:issue_serial_id].present?
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
json.id item.id
|
json.id item.id
|
||||||
end
|
#end
|
||||||
end
|
end
|
|
@ -56,5 +56,7 @@ module Rosa
|
||||||
config.assets.version = '1.0'
|
config.assets.version = '1.0'
|
||||||
|
|
||||||
config.log_redis = false
|
config.log_redis = false
|
||||||
|
|
||||||
|
config.angular_templates.ignore_prefix = 'angular-new/templates/'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* UI.Codemirror directive
|
||||||
|
* https://github.com/angular-ui/ui-codemirror
|
||||||
|
*
|
||||||
|
* This directive allows you to add CodeMirror to your textarea elements.
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 the AngularUI Team, http://angular-ui.github.com
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a CodeMirror widget to a <textarea> element.
|
||||||
|
*/
|
||||||
|
angular.module('ui.codemirror', [])
|
||||||
|
.constant('uiCodemirrorConfig', {})
|
||||||
|
.directive('uiCodemirror', ['uiCodemirrorConfig', function (uiCodemirrorConfig) {
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: 'EA',
|
||||||
|
require: '?ngModel',
|
||||||
|
priority: 1,
|
||||||
|
compile: function compile(tElement) {
|
||||||
|
|
||||||
|
// Require CodeMirror
|
||||||
|
if (angular.isUndefined(window.CodeMirror)) {
|
||||||
|
throw new Error('ui-codemirror need CodeMirror to work... (o rly?)');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a codemirror instance with
|
||||||
|
// - the function that will to place the editor into the document.
|
||||||
|
// - the initial content of the editor.
|
||||||
|
// see http://codemirror.net/doc/manual.html#api_constructor
|
||||||
|
var value = tElement.text();
|
||||||
|
var codeMirror = new window.CodeMirror(function (cm_el) {
|
||||||
|
|
||||||
|
angular.forEach(tElement.prop('attributes'), function (a) {
|
||||||
|
if (a.name === 'ui-codemirror') {
|
||||||
|
cm_el.setAttribute('ui-codemirror-opts', a.textContent);
|
||||||
|
} else {
|
||||||
|
cm_el.setAttribute(a.name, a.textContent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// FIX replaceWith throw not parent Error !
|
||||||
|
if (tElement.parent().length <= 0) {
|
||||||
|
tElement.wrap('<div>');
|
||||||
|
}
|
||||||
|
|
||||||
|
tElement.replaceWith(cm_el);
|
||||||
|
}, {value: value});
|
||||||
|
|
||||||
|
return function postLink(scope, iElement, iAttrs, ngModel) {
|
||||||
|
|
||||||
|
var options, opts;
|
||||||
|
|
||||||
|
options = uiCodemirrorConfig.codemirror || {};
|
||||||
|
opts = angular.extend({}, options, scope.$eval(iAttrs.uiCodemirror), scope.$eval(iAttrs.uiCodemirrorOpts));
|
||||||
|
|
||||||
|
function updateOptions(newValues) {
|
||||||
|
for (var key in newValues) {
|
||||||
|
if (newValues.hasOwnProperty(key)) {
|
||||||
|
codeMirror.setOption(key, newValues[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOptions(opts);
|
||||||
|
|
||||||
|
if (angular.isDefined(scope.$eval(iAttrs.uiCodemirror))) {
|
||||||
|
scope.$watch(iAttrs.uiCodemirror, updateOptions, true);
|
||||||
|
}
|
||||||
|
// Specialize change event
|
||||||
|
codeMirror.on('change', function (instance) {
|
||||||
|
var newValue = instance.getValue();
|
||||||
|
if (ngModel && newValue !== ngModel.$viewValue) {
|
||||||
|
ngModel.$setViewValue(newValue);
|
||||||
|
}
|
||||||
|
if (!scope.$$phase) {
|
||||||
|
scope.$apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (ngModel) {
|
||||||
|
// CodeMirror expects a string, so make sure it gets one.
|
||||||
|
// This does not change the model.
|
||||||
|
ngModel.$formatters.push(function (value) {
|
||||||
|
if (angular.isUndefined(value) || value === null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
else if (angular.isObject(value) || angular.isArray(value)) {
|
||||||
|
throw new Error('ui-codemirror cannot use an object or an array as a model');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Override the ngModelController $render method, which is what gets called when the model is updated.
|
||||||
|
// This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
|
||||||
|
ngModel.$render = function () {
|
||||||
|
//Code mirror expects a string so make sure it gets one
|
||||||
|
//Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive)
|
||||||
|
var safeViewValue = ngModel.$viewValue || '';
|
||||||
|
codeMirror.setValue(safeViewValue);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Watch ui-refresh and refresh the directive
|
||||||
|
if (iAttrs.uiRefresh) {
|
||||||
|
scope.$watch(iAttrs.uiRefresh, function (newVal, oldVal) {
|
||||||
|
// Skip the initial watch firing
|
||||||
|
if (newVal !== oldVal) {
|
||||||
|
codeMirror.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// onLoad callback
|
||||||
|
if (angular.isFunction(opts.onLoad)) {
|
||||||
|
opts.onLoad(codeMirror);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
|
@ -3,9 +3,9 @@
|
||||||
//= require gollum/gollum.placeholder
|
//= require gollum/gollum.placeholder
|
||||||
//= require gollum/editor/gollum.editor
|
//= require gollum/editor/gollum.editor
|
||||||
//= require jquery.dataTables
|
//= require jquery.dataTables
|
||||||
//= require codemirror
|
//= require old-codemirror
|
||||||
//= require codemirror/runmode
|
//= require old-codemirror/runmode
|
||||||
//= require_tree ./codemirror/modes
|
//= require_tree ./old-codemirror/modes
|
||||||
//= require cusel
|
//= require cusel
|
||||||
//= require bootstrap-modal
|
//= require bootstrap-modal
|
||||||
//= require bootstrap-button
|
//= require bootstrap-button
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
//@import "gollum/template";
|
//@import "gollum/template";
|
||||||
@import "gollum/editor";
|
@import "gollum/editor";
|
||||||
|
|
||||||
@import "codemirror";
|
@import "old-codemirror";
|
||||||
@import "codemirror/themes/eclipse";
|
@import "old-codemirror/themes/eclipse";
|
||||||
@import "codemirror/modes/diff";
|
@import "old-codemirror/modes/diff";
|
||||||
@import "codemirror/modes/rpm-spec";
|
@import "old-codemirror/modes/rpm-spec";
|
||||||
@import "codemirror/modes/tiddlywiki";
|
@import "old-codemirror/modes/tiddlywiki";
|
||||||
|
|
||||||
@import "old-bootstrap";
|
@import "old-bootstrap";
|
||||||
@import "chosen.scss";
|
@import "chosen.scss";
|
Loading…
Reference in New Issue