forked from spen/seminar
Add custom gallery and announcement dependency.
This commit is contained in:
parent
7886cf317a
commit
19636c7909
|
@ -0,0 +1,8 @@
|
||||||
|
.bundle/
|
||||||
|
log/*.log
|
||||||
|
pkg/
|
||||||
|
test/dummy/db/*.sqlite3
|
||||||
|
test/dummy/db/*.sqlite3-journal
|
||||||
|
test/dummy/log/*.log
|
||||||
|
test/dummy/tmp/
|
||||||
|
test/dummy/.sass-cache
|
|
@ -0,0 +1,14 @@
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
# Declare your gem's dependencies in custom_bulletin.gemspec.
|
||||||
|
# Bundler will treat runtime dependencies like base dependencies, and
|
||||||
|
# development dependencies will be added by default to the :development group.
|
||||||
|
gemspec
|
||||||
|
|
||||||
|
# Declare any dependencies that are still in development here instead of in
|
||||||
|
# your gemspec. These might include edge Rails or gems from your path or
|
||||||
|
# Git. Remember to move these dependencies to your gemspec before releasing
|
||||||
|
# your gem to rubygems.org.
|
||||||
|
|
||||||
|
# To use debugger
|
||||||
|
# gem 'debugger'
|
|
@ -0,0 +1,106 @@
|
||||||
|
PATH
|
||||||
|
remote: .
|
||||||
|
specs:
|
||||||
|
custom_announcement (0.0.1)
|
||||||
|
mongoid (= 4.0.0.beta1)
|
||||||
|
rails (~> 4.1.0.rc2)
|
||||||
|
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
actionmailer (4.1.0.rc2)
|
||||||
|
actionpack (= 4.1.0.rc2)
|
||||||
|
actionview (= 4.1.0.rc2)
|
||||||
|
mail (~> 2.5.4)
|
||||||
|
actionpack (4.1.0.rc2)
|
||||||
|
actionview (= 4.1.0.rc2)
|
||||||
|
activesupport (= 4.1.0.rc2)
|
||||||
|
rack (~> 1.5.2)
|
||||||
|
rack-test (~> 0.6.2)
|
||||||
|
actionview (4.1.0.rc2)
|
||||||
|
activesupport (= 4.1.0.rc2)
|
||||||
|
builder (~> 3.1)
|
||||||
|
erubis (~> 2.7.0)
|
||||||
|
activemodel (4.1.0.rc2)
|
||||||
|
activesupport (= 4.1.0.rc2)
|
||||||
|
builder (~> 3.1)
|
||||||
|
activerecord (4.1.0.rc2)
|
||||||
|
activemodel (= 4.1.0.rc2)
|
||||||
|
activesupport (= 4.1.0.rc2)
|
||||||
|
arel (~> 5.0.0)
|
||||||
|
activesupport (4.1.0.rc2)
|
||||||
|
i18n (~> 0.6, >= 0.6.9)
|
||||||
|
json (~> 1.7, >= 1.7.7)
|
||||||
|
minitest (~> 5.1)
|
||||||
|
thread_safe (~> 0.1)
|
||||||
|
tzinfo (~> 1.1)
|
||||||
|
arel (5.0.0)
|
||||||
|
atomic (1.1.16)
|
||||||
|
bson (2.2.1)
|
||||||
|
builder (3.2.2)
|
||||||
|
connection_pool (2.0.0)
|
||||||
|
erubis (2.7.0)
|
||||||
|
hike (1.2.3)
|
||||||
|
i18n (0.6.9)
|
||||||
|
json (1.8.1)
|
||||||
|
mail (2.5.4)
|
||||||
|
mime-types (~> 1.16)
|
||||||
|
treetop (~> 1.4.8)
|
||||||
|
mime-types (1.25.1)
|
||||||
|
minitest (5.3.1)
|
||||||
|
mongoid (4.0.0.beta1)
|
||||||
|
activemodel (>= 4.0.0)
|
||||||
|
moped (~> 2.0.beta6)
|
||||||
|
origin (~> 2.1)
|
||||||
|
tzinfo (>= 0.3.37)
|
||||||
|
moped (2.0.0.rc1)
|
||||||
|
bson (~> 2.2)
|
||||||
|
connection_pool (~> 2.0)
|
||||||
|
optionable (~> 0.2.0)
|
||||||
|
multi_json (1.9.2)
|
||||||
|
optionable (0.2.0)
|
||||||
|
origin (2.1.1)
|
||||||
|
polyglot (0.3.4)
|
||||||
|
rack (1.5.2)
|
||||||
|
rack-test (0.6.2)
|
||||||
|
rack (>= 1.0)
|
||||||
|
rails (4.1.0.rc2)
|
||||||
|
actionmailer (= 4.1.0.rc2)
|
||||||
|
actionpack (= 4.1.0.rc2)
|
||||||
|
actionview (= 4.1.0.rc2)
|
||||||
|
activemodel (= 4.1.0.rc2)
|
||||||
|
activerecord (= 4.1.0.rc2)
|
||||||
|
activesupport (= 4.1.0.rc2)
|
||||||
|
bundler (>= 1.3.0, < 2.0)
|
||||||
|
railties (= 4.1.0.rc2)
|
||||||
|
sprockets-rails (~> 2.0.0)
|
||||||
|
railties (4.1.0.rc2)
|
||||||
|
actionpack (= 4.1.0.rc2)
|
||||||
|
activesupport (= 4.1.0.rc2)
|
||||||
|
rake (>= 0.8.7)
|
||||||
|
thor (>= 0.18.1, < 2.0)
|
||||||
|
rake (10.2.2)
|
||||||
|
sprockets (2.12.0)
|
||||||
|
hike (~> 1.2)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
rack (~> 1.0)
|
||||||
|
tilt (~> 1.1, != 1.3.0)
|
||||||
|
sprockets-rails (2.0.1)
|
||||||
|
actionpack (>= 3.0)
|
||||||
|
activesupport (>= 3.0)
|
||||||
|
sprockets (~> 2.8)
|
||||||
|
thor (0.19.1)
|
||||||
|
thread_safe (0.3.1)
|
||||||
|
atomic (>= 1.1.7, < 2)
|
||||||
|
tilt (1.4.1)
|
||||||
|
treetop (1.4.15)
|
||||||
|
polyglot
|
||||||
|
polyglot (>= 0.3.1)
|
||||||
|
tzinfo (1.1.0)
|
||||||
|
thread_safe (~> 0.1)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
custom_announcement!
|
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright 2014 YOURNAME
|
||||||
|
|
||||||
|
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.
|
|
@ -0,0 +1,3 @@
|
||||||
|
= CustomBulletin
|
||||||
|
|
||||||
|
This project rocks and uses MIT-LICENSE.
|
|
@ -0,0 +1,32 @@
|
||||||
|
begin
|
||||||
|
require 'bundler/setup'
|
||||||
|
rescue LoadError
|
||||||
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'rdoc/task'
|
||||||
|
|
||||||
|
RDoc::Task.new(:rdoc) do |rdoc|
|
||||||
|
rdoc.rdoc_dir = 'rdoc'
|
||||||
|
rdoc.title = 'CustomAnnouncement'
|
||||||
|
rdoc.options << '--line-numbers'
|
||||||
|
rdoc.rdoc_files.include('README.rdoc')
|
||||||
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Bundler::GemHelper.install_tasks
|
||||||
|
|
||||||
|
require 'rake/testtask'
|
||||||
|
|
||||||
|
Rake::TestTask.new(:test) do |t|
|
||||||
|
t.libs << 'lib'
|
||||||
|
t.libs << 'test'
|
||||||
|
t.pattern = 'test/**/*_test.rb'
|
||||||
|
t.verbose = false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
task default: :test
|
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,2 @@
|
||||||
|
// Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
// All this logic will automatically be available in application.js.
|
|
@ -0,0 +1,9 @@
|
||||||
|
( function( $ ) {
|
||||||
|
'use strict';
|
||||||
|
$( document ).on( 'ready', function() {
|
||||||
|
var $settings = wpexAnimsition;
|
||||||
|
$settings.inDuration = parseInt( $settings.inDuration );
|
||||||
|
$settings.outDuration = parseInt( $settings.outDuration );
|
||||||
|
$( 'body' ).animsition( $settings );
|
||||||
|
} );
|
||||||
|
} ) ( jQuery );
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*!
|
||||||
|
* animsition v4.0.2
|
||||||
|
* A simple and easy jQuery plugin for CSS animated page transitions.
|
||||||
|
* http://blivesta.github.io/animsition
|
||||||
|
* License : MIT
|
||||||
|
* Author : blivesta (http://blivesta.com/)
|
||||||
|
*/
|
||||||
|
!function (t) {
|
||||||
|
"use strict";
|
||||||
|
"function" == typeof define && define.amd ? define(["jquery"], t) : "object" == typeof exports ? module.exports = t(require("jquery")) : t(jQuery)
|
||||||
|
}(function (t) {
|
||||||
|
"use strict";
|
||||||
|
var n = "animsition",
|
||||||
|
i = {
|
||||||
|
init: function (a) {
|
||||||
|
a = t.extend({ inClass: "fade-in",
|
||||||
|
outClass: "fade-out",
|
||||||
|
inDuration: 1500,
|
||||||
|
outDuration: 800,
|
||||||
|
linkElement: ".animsition-link",
|
||||||
|
loading: !0,
|
||||||
|
loadingParentElement: "body",
|
||||||
|
loadingClass: "animsition-loading",
|
||||||
|
loadingInner: "",
|
||||||
|
timeout: !1,
|
||||||
|
timeoutCountdown: 5e3,
|
||||||
|
onLoadEvent: !0,
|
||||||
|
browser: ["animation-duration", "-webkit-animation-duration"],
|
||||||
|
overlay: !1,
|
||||||
|
overlayClass: "animsition-overlay-slide",
|
||||||
|
overlayParentElement: "body",
|
||||||
|
transition: function (t) { window.location.href = t } }, a),
|
||||||
|
i.settings = { timer: !1,
|
||||||
|
data: { inClass: "animsition-in-class",
|
||||||
|
inDuration: "animsition-in-duration",
|
||||||
|
outClass: "animsition-out-class",
|
||||||
|
outDuration: "animsition-out-duration", overlay: "animsition-overlay"
|
||||||
|
},
|
||||||
|
events: { inStart: "animsition.inStart",
|
||||||
|
inEnd: "animsition.inEnd",
|
||||||
|
outStart: "animsition.outStart",
|
||||||
|
outEnd: "animsition.outEnd"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var o = i.supportCheck.call(this, a);
|
||||||
|
if (!o && a.browser.length > 0 && (!o || !this.length))
|
||||||
|
return "console" in window || (window.console = {}, window.console.log = function (t) { return t }), this.length || console.log("Animsition: Element does not exist on page."), o || console.log("Animsition: Does not support this browser."), i.destroy.call(this); var e = i.optionCheck.call(this, a); return e && t("." + a.overlayClass).length <= 0 && i.addOverlay.call(this, a), a.loading && t("." + a.loadingClass).length <= 0 && i.addLoading.call(this, a), this.each(function () { var o = this, e = t(this), s = t(window), r = t(document), l = e.data(n); l || (a = t.extend({}, a), e.data(n, { options: a }), a.timeout && i.addTimer.call(o), a.onLoadEvent && s.on("load." + n, function () { i.settings.timer && clearTimeout(i.settings.timer), i["in"].call(o) }), s.on("pageshow." + n, function (t) { t.originalEvent.persisted && i["in"].call(o) }), s.on("unload." + n, function () { }), r.on("click." + n, a.linkElement, function (n) { n.preventDefault(); var a = t(this), e = a.attr("href"); 2 === n.which || n.metaKey || n.shiftKey || -1 !== navigator.platform.toUpperCase().indexOf("WIN") && n.ctrlKey ? window.open(e, "_blank") : i.out.call(o, a, e) })) })
|
||||||
|
}, addOverlay: function (n) {
|
||||||
|
t(n.overlayParentElement).prepend('<div class="' + n.overlayClass + '"></div>')
|
||||||
|
}, addLoading: function (n) {
|
||||||
|
t(n.loadingParentElement).append('<div class="' + n.loadingClass + '">' + n.loadingInner + "</div>")
|
||||||
|
}, removeLoading: function () {
|
||||||
|
var i = t(this), a = i.data(n).options, o = t(a.loadingParentElement).children("." + a.loadingClass);
|
||||||
|
o.fadeOut().remove()
|
||||||
|
}, addTimer: function () {
|
||||||
|
var a = this, o = t(this),
|
||||||
|
e = o.data(n).options;
|
||||||
|
i.settings.timer = setTimeout(function () {
|
||||||
|
i["in"].call(a), t(window).off("load." + n) }, e.timeoutCountdown)
|
||||||
|
}, supportCheck: function (n) {
|
||||||
|
var i = t(this), a = n.browser, o = a.length, e = !1;
|
||||||
|
0 === o && (e = !0);
|
||||||
|
for (var s = 0; o > s; s++)
|
||||||
|
if ("string" == typeof i.css(a[s])) {
|
||||||
|
e = !0; break
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}, optionCheck: function (n) {
|
||||||
|
var a, o = t(this);
|
||||||
|
return a = n.overlay || o.data(i.settings.data.overlay) ? !0 : !1
|
||||||
|
}, animationCheck: function (i, a, o) {
|
||||||
|
var e = t(this), s = e.data(n).options,
|
||||||
|
r = typeof i, l = !a && "number" === r,
|
||||||
|
d = a && "string" === r && i.length > 0;
|
||||||
|
return l || d ? i = i : a && o ? i = s.inClass : !a && o ? i = s.inDuration : a && !o ? i = s.outClass : a || o || (i = s.outDuration), i
|
||||||
|
}, "in": function () {
|
||||||
|
var a = this, o = t(this), e = o.data(n).options,
|
||||||
|
s = o.data(i.settings.data.inDuration), r = o.data(i.settings.data.inClass),
|
||||||
|
l = i.animationCheck.call(a, s, !1, !0), d = i.animationCheck.call(a, r, !0, !0),
|
||||||
|
u = i.optionCheck.call(a, e), c = o.data(n).outClass;
|
||||||
|
e.loading && i.removeLoading.call(a), c && o.removeClass(c), u ? i.inOverlay.call(a, d, l) : i.inDefault.call(a, d, l)
|
||||||
|
}, inDefault: function (n, a) {
|
||||||
|
var o = t(this); o.css({ "animation-duration": a + "ms" }).addClass(n).trigger(i.settings.events.inStart).animateCallback(function () { o.removeClass(n).css({ opacity: 1 }).trigger(i.settings.events.inEnd) })
|
||||||
|
}, inOverlay: function (a, o) {
|
||||||
|
var e = t(this), s = e.data(n).options;
|
||||||
|
e.css({ opacity: 1 }).trigger(i.settings.events.inStart),
|
||||||
|
t(s.overlayParentElement).children("." + s.overlayClass).css({ "animation-duration": o + "ms" }).addClass(a).animateCallback(function () { e.trigger(i.settings.events.inEnd) })
|
||||||
|
}, out: function (a, o) {
|
||||||
|
var e = this, s = t(this), r = s.data(n).options, l = a.data(i.settings.data.outClass), d = s.data(i.settings.data.outClass), u = a.data(i.settings.data.outDuration), c = s.data(i.settings.data.outDuration), m = l ? l : d, g = u ? u : c, f = i.animationCheck.call(e, m, !0, !1), v = i.animationCheck.call(e, g, !1, !1), h = i.optionCheck.call(e, r); s.data(n).outClass = f, h ? i.outOverlay.call(e, f, v, o) : i.outDefault.call(e, f, v, o)
|
||||||
|
}, outDefault: function (a, o, e) {
|
||||||
|
var s = t(this), r = s.data(n).options;
|
||||||
|
s.css({ "animation-duration": o + 1 + "ms" }).addClass(a).trigger(i.settings.events.outStart).animateCallback(function () {
|
||||||
|
s.trigger(i.settings.events.outEnd), r.transition(e)
|
||||||
|
})
|
||||||
|
}, outOverlay: function (a, o, e) {
|
||||||
|
var s = this, r = t(this), l = r.data(n).options,
|
||||||
|
d = r.data(i.settings.data.inClass), u = i.animationCheck.call(s, d, !0, !0);
|
||||||
|
t(l.overlayParentElement).children("." + l.overlayClass).css({ "animation-duration": o + 1 + "ms" }).removeClass(u).addClass(a).trigger(i.settings.events.outStart).animateCallback(function () {
|
||||||
|
r.trigger(i.settings.events.outEnd), l.transition(e) })
|
||||||
|
}, destroy: function () {
|
||||||
|
return this.each(function () {
|
||||||
|
var i = t(this); t(window).off("." + n), i.css({ opacity: 1 }).removeData(n)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.fn.animateCallback = function (n) {
|
||||||
|
var i = "animationend webkitAnimationEnd";
|
||||||
|
return this.each(function () {
|
||||||
|
var a = t(this); a.on(i, function () { return a.off(i), n.call(this) })
|
||||||
|
})
|
||||||
|
},
|
||||||
|
t.fn.animsition = function (a) {
|
||||||
|
return i[a] ? i[a].apply(this, Array.prototype.slice.call(arguments, 1)) : "object" != typeof a && a ? void t.error("Method " + a + " does not exist on jQuery." + n) : i.init.apply(this, arguments)
|
||||||
|
}
|
||||||
|
});
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,21 @@
|
||||||
|
$(document).ready(function() {
|
||||||
|
var config = {}
|
||||||
|
config.autoGrow_minHeight = 50;
|
||||||
|
config.allowedContent = false;
|
||||||
|
config.disallowedContent = 'img';
|
||||||
|
config.toolbar = [
|
||||||
|
{ name: 'clipboard', items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
|
||||||
|
{ name: 'editing', items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] },
|
||||||
|
|
||||||
|
{ name: 'basicstyles', items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'CopyFormatting', 'RemoveFormat' ] },
|
||||||
|
'/',
|
||||||
|
{ name: 'insert', items: [ 'SpecialChar'] },
|
||||||
|
{ name: 'styles', items: [ 'Font' ] },
|
||||||
|
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] }
|
||||||
|
];
|
||||||
|
|
||||||
|
var ckeditor_reduce = $('.ckeditor_reduce')
|
||||||
|
ckeditor_reduce.each(function(i,v){
|
||||||
|
CKEDITOR.replace(v,config);
|
||||||
|
})
|
||||||
|
});
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
Place all the styles related to the matching controller here.
|
||||||
|
They will automatically be included in application.css.
|
||||||
|
*/
|
||||||
|
.table .expired{
|
||||||
|
color: #BE2E2E;
|
||||||
|
}
|
|
@ -0,0 +1,947 @@
|
||||||
|
//
|
||||||
|
// Mixins
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
// Clearfix
|
||||||
|
// Source: http://nicolasgallagher.com/micro-clearfix-hack/
|
||||||
|
//
|
||||||
|
// For modern browsers
|
||||||
|
// 1. The space content is one way to avoid an Opera bug when the
|
||||||
|
// contenteditable attribute is included anywhere else in the document.
|
||||||
|
// Otherwise it causes space to appear at the top and bottom of elements
|
||||||
|
// that are clearfixed.
|
||||||
|
// 2. The use of `table` rather than `block` is only necessary if using
|
||||||
|
// `:before` to contain the top-margins of child elements.
|
||||||
|
@mixin clearfix() {
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
content: " "; // 1
|
||||||
|
display: table; // 2
|
||||||
|
}
|
||||||
|
&:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebKit-style focus
|
||||||
|
@mixin tab-focus() {
|
||||||
|
// Default
|
||||||
|
outline: thin dotted;
|
||||||
|
// WebKit
|
||||||
|
outline: 5px auto -webkit-focus-ring-color;
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center-align a block level element
|
||||||
|
@mixin center-block() {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sizing shortcuts
|
||||||
|
@mixin size($width, $height) {
|
||||||
|
width: $width;
|
||||||
|
height: $height;
|
||||||
|
}
|
||||||
|
@mixin square($size) {
|
||||||
|
@include size($size, $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder text
|
||||||
|
@mixin placeholder($color: $input-color-placeholder) {
|
||||||
|
&::-moz-placeholder { color: $color; // Firefox
|
||||||
|
opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526
|
||||||
|
&:-ms-input-placeholder { color: $color; } // Internet Explorer 10+
|
||||||
|
&::-webkit-input-placeholder { color: $color; } // Safari and Chrome
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text overflow
|
||||||
|
// Requires inline-block or block for proper styling
|
||||||
|
@mixin text-overflow() {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSS image replacement
|
||||||
|
//
|
||||||
|
// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for
|
||||||
|
// mixins being reused as classes with the same name, this doesn't hold up. As
|
||||||
|
// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note
|
||||||
|
// that we cannot chain the mixins together in Less, so they are repeated.
|
||||||
|
//
|
||||||
|
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
|
||||||
|
|
||||||
|
// Deprecated as of v3.0.1 (will be removed in v4)
|
||||||
|
@mixin hide-text() {
|
||||||
|
font: #{0/0} a;
|
||||||
|
color: transparent;
|
||||||
|
text-shadow: none;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
// New mixin to use as of v3.0.1
|
||||||
|
@mixin text-hide() {
|
||||||
|
@include hide-text();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// CSS3 PROPERTIES
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
// Single side border-radius
|
||||||
|
@mixin border-top-radius($radius) {
|
||||||
|
border-top-right-radius: $radius;
|
||||||
|
border-top-left-radius: $radius;
|
||||||
|
}
|
||||||
|
@mixin border-right-radius($radius) {
|
||||||
|
border-bottom-right-radius: $radius;
|
||||||
|
border-top-right-radius: $radius;
|
||||||
|
}
|
||||||
|
@mixin border-bottom-radius($radius) {
|
||||||
|
border-bottom-right-radius: $radius;
|
||||||
|
border-bottom-left-radius: $radius;
|
||||||
|
}
|
||||||
|
@mixin border-left-radius($radius) {
|
||||||
|
border-bottom-left-radius: $radius;
|
||||||
|
border-top-left-radius: $radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop shadows
|
||||||
|
//
|
||||||
|
// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
|
||||||
|
// supported browsers that have box shadow capabilities now support the
|
||||||
|
// standard `box-shadow` property.
|
||||||
|
@mixin box-shadow($shadow...) {
|
||||||
|
-webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1
|
||||||
|
box-shadow: $shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transitions
|
||||||
|
@mixin transition($transition...) {
|
||||||
|
-webkit-transition: $transition;
|
||||||
|
transition: $transition;
|
||||||
|
}
|
||||||
|
@mixin transition-property($transition-property...) {
|
||||||
|
-webkit-transition-property: $transition-property;
|
||||||
|
transition-property: $transition-property;
|
||||||
|
}
|
||||||
|
@mixin transition-delay($transition-delay) {
|
||||||
|
-webkit-transition-delay: $transition-delay;
|
||||||
|
transition-delay: $transition-delay;
|
||||||
|
}
|
||||||
|
@mixin transition-duration($transition-duration...) {
|
||||||
|
-webkit-transition-duration: $transition-duration;
|
||||||
|
transition-duration: $transition-duration;
|
||||||
|
}
|
||||||
|
@mixin transition-transform($transition...) {
|
||||||
|
-webkit-transition: -webkit-transform $transition;
|
||||||
|
-moz-transition: -moz-transform $transition;
|
||||||
|
-o-transition: -o-transform $transition;
|
||||||
|
transition: transform $transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transformations
|
||||||
|
@mixin rotate($degrees) {
|
||||||
|
-webkit-transform: rotate($degrees);
|
||||||
|
-ms-transform: rotate($degrees); // IE9 only
|
||||||
|
transform: rotate($degrees);
|
||||||
|
}
|
||||||
|
@mixin scale($scale-args...) {
|
||||||
|
-webkit-transform: scale($scale-args);
|
||||||
|
-ms-transform: scale($scale-args); // IE9 only
|
||||||
|
transform: scale($scale-args);
|
||||||
|
}
|
||||||
|
@mixin translate($x, $y) {
|
||||||
|
-webkit-transform: translate($x, $y);
|
||||||
|
-ms-transform: translate($x, $y); // IE9 only
|
||||||
|
transform: translate($x, $y);
|
||||||
|
}
|
||||||
|
@mixin skew($x, $y) {
|
||||||
|
-webkit-transform: skew($x, $y);
|
||||||
|
-ms-transform: skewX($x) skewY($y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
|
||||||
|
transform: skew($x, $y);
|
||||||
|
}
|
||||||
|
@mixin translate3d($x, $y, $z) {
|
||||||
|
-webkit-transform: translate3d($x, $y, $z);
|
||||||
|
transform: translate3d($x, $y, $z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin rotateX($degrees) {
|
||||||
|
-webkit-transform: rotateX($degrees);
|
||||||
|
-ms-transform: rotateX($degrees); // IE9 only
|
||||||
|
transform: rotateX($degrees);
|
||||||
|
}
|
||||||
|
@mixin rotateY($degrees) {
|
||||||
|
-webkit-transform: rotateY($degrees);
|
||||||
|
-ms-transform: rotateY($degrees); // IE9 only
|
||||||
|
transform: rotateY($degrees);
|
||||||
|
}
|
||||||
|
@mixin perspective($perspective) {
|
||||||
|
-webkit-perspective: $perspective;
|
||||||
|
-moz-perspective: $perspective;
|
||||||
|
perspective: $perspective;
|
||||||
|
}
|
||||||
|
@mixin perspective-origin($perspective) {
|
||||||
|
-webkit-perspective-origin: $perspective;
|
||||||
|
-moz-perspective-origin: $perspective;
|
||||||
|
perspective-origin: $perspective;
|
||||||
|
}
|
||||||
|
@mixin transform-origin($origin) {
|
||||||
|
-webkit-transform-origin: $origin;
|
||||||
|
-moz-transform-origin: $origin;
|
||||||
|
-ms-transform-origin: $origin; // IE9 only
|
||||||
|
transform-origin: $origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animations
|
||||||
|
@mixin animation($animation) {
|
||||||
|
-webkit-animation: $animation;
|
||||||
|
animation: $animation;
|
||||||
|
}
|
||||||
|
@mixin animation-name($name) {
|
||||||
|
-webkit-animation-name: $name;
|
||||||
|
animation-name: $name;
|
||||||
|
}
|
||||||
|
@mixin animation-duration($duration) {
|
||||||
|
-webkit-animation-duration: $duration;
|
||||||
|
animation-duration: $duration;
|
||||||
|
}
|
||||||
|
@mixin animation-timing-function($timing-function) {
|
||||||
|
-webkit-animation-timing-function: $timing-function;
|
||||||
|
animation-timing-function: $timing-function;
|
||||||
|
}
|
||||||
|
@mixin animation-delay($delay) {
|
||||||
|
-webkit-animation-delay: $delay;
|
||||||
|
animation-delay: $delay;
|
||||||
|
}
|
||||||
|
@mixin animation-iteration-count($iteration-count) {
|
||||||
|
-webkit-animation-iteration-count: $iteration-count;
|
||||||
|
animation-iteration-count: $iteration-count;
|
||||||
|
}
|
||||||
|
@mixin animation-direction($direction) {
|
||||||
|
-webkit-animation-direction: $direction;
|
||||||
|
animation-direction: $direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backface visibility
|
||||||
|
// Prevent browsers from flickering when using CSS 3D transforms.
|
||||||
|
// Default value is `visible`, but can be changed to `hidden`
|
||||||
|
@mixin backface-visibility($visibility){
|
||||||
|
-webkit-backface-visibility: $visibility;
|
||||||
|
-moz-backface-visibility: $visibility;
|
||||||
|
backface-visibility: $visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Box sizing
|
||||||
|
@mixin box-sizing($boxmodel) {
|
||||||
|
-webkit-box-sizing: $boxmodel;
|
||||||
|
-moz-box-sizing: $boxmodel;
|
||||||
|
box-sizing: $boxmodel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User select
|
||||||
|
// For selecting text on the page
|
||||||
|
@mixin user-select($select) {
|
||||||
|
-webkit-user-select: $select;
|
||||||
|
-moz-user-select: $select;
|
||||||
|
-ms-user-select: $select; // IE10+
|
||||||
|
user-select: $select;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize anything
|
||||||
|
@mixin resizable($direction) {
|
||||||
|
resize: $direction; // Options: horizontal, vertical, both
|
||||||
|
overflow: auto; // Safari fix
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSS3 Content Columns
|
||||||
|
@mixin content-columns($column-count, $column-gap: $grid-gutter-width) {
|
||||||
|
-webkit-column-count: $column-count;
|
||||||
|
-moz-column-count: $column-count;
|
||||||
|
column-count: $column-count;
|
||||||
|
-webkit-column-gap: $column-gap;
|
||||||
|
-moz-column-gap: $column-gap;
|
||||||
|
column-gap: $column-gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional hyphenation
|
||||||
|
@mixin hyphens($mode: auto) {
|
||||||
|
word-wrap: break-word;
|
||||||
|
-webkit-hyphens: $mode;
|
||||||
|
-moz-hyphens: $mode;
|
||||||
|
-ms-hyphens: $mode; // IE10+
|
||||||
|
-o-hyphens: $mode;
|
||||||
|
hyphens: $mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opacity
|
||||||
|
@mixin opacity($opacity) {
|
||||||
|
opacity: $opacity;
|
||||||
|
// IE8 filter
|
||||||
|
$opacity-ie: ($opacity * 100);
|
||||||
|
filter: #{alpha(opacity=$opacity-ie)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// GRADIENTS
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Horizontal gradient, from left to right
|
||||||
|
//
|
||||||
|
// Creates two color stops, start and end, by specifying a color and position for each color stop.
|
||||||
|
// Color stops are not available in IE9 and below.
|
||||||
|
@mixin gradient-horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
|
||||||
|
background-image: -webkit-linear-gradient(left, color-stop($start-color $start-percent), color-stop($end-color $end-percent)); // Safari 5.1-6, Chrome 10+
|
||||||
|
background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertical gradient, from top to bottom
|
||||||
|
//
|
||||||
|
// Creates two color stops, start and end, by specifying a color and position for each color stop.
|
||||||
|
// Color stops are not available in IE9 and below.
|
||||||
|
@mixin gradient-vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
|
||||||
|
background-image: -webkit-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+
|
||||||
|
background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
background-image: -webkit-linear-gradient($deg, $start-color, $end-color); // Safari 5.1-6, Chrome 10+
|
||||||
|
background-image: linear-gradient($deg, $start-color, $end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
|
||||||
|
}
|
||||||
|
@mixin gradient-horizontal-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
|
||||||
|
background-image: -webkit-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color);
|
||||||
|
background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down, gets no color-stop at all for proper fallback
|
||||||
|
}
|
||||||
|
@mixin gradient-vertical-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
|
||||||
|
background-image: -webkit-linear-gradient($start-color, $mid-color $color-stop, $end-color);
|
||||||
|
background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback
|
||||||
|
}
|
||||||
|
@mixin gradient-radial($inner-color: #555, $outer-color: #333) {
|
||||||
|
background-image: -webkit-radial-gradient(circle, $inner-color, $outer-color);
|
||||||
|
background-image: radial-gradient(circle, $inner-color, $outer-color);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
@mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) {
|
||||||
|
background-image: -webkit-linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
|
||||||
|
background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset filters for IE
|
||||||
|
//
|
||||||
|
// When you need to remove a gradient background, do not forget to use this to reset
|
||||||
|
// the IE filter for IE9 and below.
|
||||||
|
@mixin reset-filter() {
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Retina images
|
||||||
|
//
|
||||||
|
// Short retina mixin for setting background-image and -size
|
||||||
|
|
||||||
|
@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
|
||||||
|
background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-1x}"), "#{$file-1x}"));
|
||||||
|
|
||||||
|
@media
|
||||||
|
only screen and (-webkit-min-device-pixel-ratio: 2),
|
||||||
|
only screen and ( min--moz-device-pixel-ratio: 2),
|
||||||
|
only screen and ( -o-min-device-pixel-ratio: 2/1),
|
||||||
|
only screen and ( min-device-pixel-ratio: 2),
|
||||||
|
only screen and ( min-resolution: 192dpi),
|
||||||
|
only screen and ( min-resolution: 2dppx) {
|
||||||
|
background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-2x}"), "#{$file-2x}"));
|
||||||
|
background-size: $width-1x $height-1x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Responsive image
|
||||||
|
//
|
||||||
|
// Keep images from scaling beyond the width of their parents.
|
||||||
|
|
||||||
|
@mixin img-responsive($display: block) {
|
||||||
|
display: $display;
|
||||||
|
max-width: 100%; // Part 1: Set a maximum relative to the parent
|
||||||
|
height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// COMPONENT MIXINS
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
// Horizontal dividers
|
||||||
|
// -------------------------
|
||||||
|
// Dividers (basically an hr) within dropdowns and nav lists
|
||||||
|
@mixin nav-divider($color: #e5e5e5) {
|
||||||
|
height: 1px;
|
||||||
|
margin: (($line-height-computed / 2) - 1) 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panels
|
||||||
|
// -------------------------
|
||||||
|
@mixin panel-variant($border, $heading-text-color, $heading-bg-color, $heading-border) {
|
||||||
|
border-color: $border;
|
||||||
|
|
||||||
|
& > .panel-heading {
|
||||||
|
color: $heading-text-color;
|
||||||
|
background-color: $heading-bg-color;
|
||||||
|
border-color: $heading-border;
|
||||||
|
|
||||||
|
+ .panel-collapse .panel-body {
|
||||||
|
border-top-color: $border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > .panel-footer {
|
||||||
|
+ .panel-collapse .panel-body {
|
||||||
|
border-bottom-color: $border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alerts
|
||||||
|
// -------------------------
|
||||||
|
@mixin alert-variant($background, $border, $text-color) {
|
||||||
|
background-color: $background;
|
||||||
|
border-color: $border;
|
||||||
|
color: $text-color;
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border-top-color: darken($border, 5%);
|
||||||
|
}
|
||||||
|
.alert-link {
|
||||||
|
color: darken($text-color, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tables
|
||||||
|
// -------------------------
|
||||||
|
@mixin table-row-variant($state, $background) {
|
||||||
|
// Exact selectors below required to override `.table-striped` and prevent
|
||||||
|
// inheritance to nested tables.
|
||||||
|
.table > thead > tr,
|
||||||
|
.table > tbody > tr,
|
||||||
|
.table > tfoot > tr {
|
||||||
|
> td.#{$state},
|
||||||
|
> th.#{$state},
|
||||||
|
&.#{$state} > td,
|
||||||
|
&.#{$state} > th {
|
||||||
|
background-color: $background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hover states for `.table-hover`
|
||||||
|
// Note: this is not available for cells or rows within `thead` or `tfoot`.
|
||||||
|
.table-hover > tbody > tr {
|
||||||
|
> td.#{$state}:hover,
|
||||||
|
> th.#{$state}:hover,
|
||||||
|
&.#{$state}:hover > td,
|
||||||
|
&.#{$state}:hover > th {
|
||||||
|
background-color: darken($background, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// List Groups
|
||||||
|
// -------------------------
|
||||||
|
@mixin list-group-item-variant($state, $background, $color) {
|
||||||
|
.list-group-item-#{$state} {
|
||||||
|
color: $color;
|
||||||
|
background-color: $background;
|
||||||
|
|
||||||
|
// [converter] extracted a& to a.list-group-item-#{$state}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.list-group-item-#{$state} {
|
||||||
|
color: $color;
|
||||||
|
|
||||||
|
.list-group-item-heading { color: inherit; }
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: $color;
|
||||||
|
background-color: darken($background, 5%);
|
||||||
|
}
|
||||||
|
&.active,
|
||||||
|
&.active:hover,
|
||||||
|
&.active:focus {
|
||||||
|
color: #fff;
|
||||||
|
background-color: $color;
|
||||||
|
border-color: $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button variants
|
||||||
|
// -------------------------
|
||||||
|
// Easily pump out default styles, as well as :hover, :focus, :active,
|
||||||
|
// and disabled options for all buttons
|
||||||
|
@mixin button-variant($color, $background, $border) {
|
||||||
|
color: $color;
|
||||||
|
background-color: $background;
|
||||||
|
border-color: $border;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
color: $color;
|
||||||
|
background-color: darken($background, 8%);
|
||||||
|
border-color: darken($border, 12%);
|
||||||
|
}
|
||||||
|
.open & { &.dropdown-toggle {
|
||||||
|
color: $color;
|
||||||
|
background-color: darken($background, 8%);
|
||||||
|
border-color: darken($border, 12%);
|
||||||
|
} }
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.open & { &.dropdown-toggle {
|
||||||
|
background-image: none;
|
||||||
|
} }
|
||||||
|
&.disabled,
|
||||||
|
&[disabled],
|
||||||
|
fieldset[disabled] & {
|
||||||
|
&,
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
background-color: $background;
|
||||||
|
border-color: $border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
color: $background;
|
||||||
|
background-color: $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button sizes
|
||||||
|
// -------------------------
|
||||||
|
@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
|
||||||
|
padding: $padding-vertical $padding-horizontal;
|
||||||
|
font-size: $font-size;
|
||||||
|
line-height: $line-height;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pagination
|
||||||
|
// -------------------------
|
||||||
|
@mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $border-radius) {
|
||||||
|
> li {
|
||||||
|
> a,
|
||||||
|
> span {
|
||||||
|
padding: $padding-vertical $padding-horizontal;
|
||||||
|
font-size: $font-size;
|
||||||
|
}
|
||||||
|
&:first-child {
|
||||||
|
> a,
|
||||||
|
> span {
|
||||||
|
@include border-left-radius($border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
> a,
|
||||||
|
> span {
|
||||||
|
@include border-right-radius($border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Labels
|
||||||
|
// -------------------------
|
||||||
|
@mixin label-variant($color) {
|
||||||
|
background-color: $color;
|
||||||
|
&[href] {
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
background-color: darken($color, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contextual backgrounds
|
||||||
|
// -------------------------
|
||||||
|
// [converter] $parent hack
|
||||||
|
@mixin bg-variant($parent, $color) {
|
||||||
|
#{$parent} {
|
||||||
|
background-color: $color;
|
||||||
|
}
|
||||||
|
a#{$parent}:hover {
|
||||||
|
background-color: darken($color, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Typography
|
||||||
|
// -------------------------
|
||||||
|
// [converter] $parent hack
|
||||||
|
@mixin text-emphasis-variant($parent, $color) {
|
||||||
|
#{$parent} {
|
||||||
|
color: $color;
|
||||||
|
}
|
||||||
|
a#{$parent}:hover {
|
||||||
|
color: darken($color, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navbar vertical align
|
||||||
|
// -------------------------
|
||||||
|
// Vertically center elements in the navbar.
|
||||||
|
// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
|
||||||
|
@mixin navbar-vertical-align($element-height) {
|
||||||
|
margin-top: (($navbar-height - $element-height) / 2);
|
||||||
|
margin-bottom: (($navbar-height - $element-height) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Progress bars
|
||||||
|
// -------------------------
|
||||||
|
@mixin progress-bar-variant($color) {
|
||||||
|
background-color: $color;
|
||||||
|
.progress-striped & {
|
||||||
|
@include gradient-striped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Responsive utilities
|
||||||
|
// -------------------------
|
||||||
|
// More easily include all the states for responsive-utilities.less.
|
||||||
|
// [converter] $parent hack
|
||||||
|
@mixin responsive-visibility($parent) {
|
||||||
|
#{$parent} {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
table#{$parent} { display: table; }
|
||||||
|
tr#{$parent} { display: table-row !important; }
|
||||||
|
th#{$parent},
|
||||||
|
td#{$parent} { display: table-cell !important; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// [converter] $parent hack
|
||||||
|
@mixin responsive-invisibility($parent) {
|
||||||
|
#{$parent} {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Grid System
|
||||||
|
// -----------
|
||||||
|
|
||||||
|
// Centered container element
|
||||||
|
@mixin container-fixed() {
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
padding-left: ($grid-gutter-width / 2);
|
||||||
|
padding-right: ($grid-gutter-width / 2);
|
||||||
|
@include clearfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a wrapper for a series of columns
|
||||||
|
@mixin make-row($gutter: $grid-gutter-width) {
|
||||||
|
margin-left: ($gutter / -2);
|
||||||
|
margin-right: ($gutter / -2);
|
||||||
|
@include clearfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the extra small columns
|
||||||
|
@mixin make-xs-column($columns, $gutter: $grid-gutter-width) {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
width: percentage(($columns / $grid-columns));
|
||||||
|
min-height: 1px;
|
||||||
|
padding-left: ($gutter / 2);
|
||||||
|
padding-right: ($gutter / 2);
|
||||||
|
}
|
||||||
|
@mixin make-xs-column-offset($columns) {
|
||||||
|
@media (min-width: $screen-xs-min) {
|
||||||
|
margin-left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-xs-column-push($columns) {
|
||||||
|
@media (min-width: $screen-xs-min) {
|
||||||
|
left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-xs-column-pull($columns) {
|
||||||
|
@media (min-width: $screen-xs-min) {
|
||||||
|
right: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generate the small columns
|
||||||
|
@mixin make-sm-column($columns, $gutter: $grid-gutter-width) {
|
||||||
|
position: relative;
|
||||||
|
min-height: 1px;
|
||||||
|
padding-left: ($gutter / 2);
|
||||||
|
padding-right: ($gutter / 2);
|
||||||
|
|
||||||
|
@media (min-width: $screen-sm-min) {
|
||||||
|
float: left;
|
||||||
|
width: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-sm-column-offset($columns) {
|
||||||
|
@media (min-width: $screen-sm-min) {
|
||||||
|
margin-left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-sm-column-push($columns) {
|
||||||
|
@media (min-width: $screen-sm-min) {
|
||||||
|
left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-sm-column-pull($columns) {
|
||||||
|
@media (min-width: $screen-sm-min) {
|
||||||
|
right: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generate the medium columns
|
||||||
|
@mixin make-md-column($columns, $gutter: $grid-gutter-width) {
|
||||||
|
position: relative;
|
||||||
|
min-height: 1px;
|
||||||
|
padding-left: ($gutter / 2);
|
||||||
|
padding-right: ($gutter / 2);
|
||||||
|
|
||||||
|
@media (min-width: $screen-md-min) {
|
||||||
|
float: left;
|
||||||
|
width: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-md-column-offset($columns) {
|
||||||
|
@media (min-width: $screen-md-min) {
|
||||||
|
margin-left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-md-column-push($columns) {
|
||||||
|
@media (min-width: $screen-md-min) {
|
||||||
|
left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-md-column-pull($columns) {
|
||||||
|
@media (min-width: $screen-md-min) {
|
||||||
|
right: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generate the large columns
|
||||||
|
@mixin make-lg-column($columns, $gutter: $grid-gutter-width) {
|
||||||
|
position: relative;
|
||||||
|
min-height: 1px;
|
||||||
|
padding-left: ($gutter / 2);
|
||||||
|
padding-right: ($gutter / 2);
|
||||||
|
|
||||||
|
@media (min-width: $screen-lg-min) {
|
||||||
|
float: left;
|
||||||
|
width: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-lg-column-offset($columns) {
|
||||||
|
@media (min-width: $screen-lg-min) {
|
||||||
|
margin-left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-lg-column-push($columns) {
|
||||||
|
@media (min-width: $screen-lg-min) {
|
||||||
|
left: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin make-lg-column-pull($columns) {
|
||||||
|
@media (min-width: $screen-lg-min) {
|
||||||
|
right: percentage(($columns / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Framework grid generation
|
||||||
|
//
|
||||||
|
// Used only by Bootstrap to generate the correct number of grid classes given
|
||||||
|
// any value of `$grid-columns`.
|
||||||
|
|
||||||
|
// [converter] This is defined recursively in LESS, but Sass supports real loops
|
||||||
|
@mixin make-grid-columns() {
|
||||||
|
$list: '';
|
||||||
|
$i: 1;
|
||||||
|
$list: ".col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}";
|
||||||
|
@for $i from (1 + 1) through $grid-columns {
|
||||||
|
$list: "#{$list}, .col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}";
|
||||||
|
}
|
||||||
|
#{$list} {
|
||||||
|
position: relative;
|
||||||
|
// Prevent columns from collapsing when empty
|
||||||
|
min-height: 1px;
|
||||||
|
// Inner gutter via padding
|
||||||
|
padding-left: ($grid-gutter-width / 2);
|
||||||
|
padding-right: ($grid-gutter-width / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// [converter] This is defined recursively in LESS, but Sass supports real loops
|
||||||
|
@mixin float-grid-columns($class) {
|
||||||
|
$list: '';
|
||||||
|
$i: 1;
|
||||||
|
$list: ".col-#{$class}-#{$i}";
|
||||||
|
@for $i from (1 + 1) through $grid-columns {
|
||||||
|
$list: "#{$list}, .col-#{$class}-#{$i}";
|
||||||
|
}
|
||||||
|
#{$list} {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin calc-grid-column($index, $class, $type) {
|
||||||
|
@if ($type == width) and ($index > 0) {
|
||||||
|
.col-#{$class}-#{$index} {
|
||||||
|
width: percentage(($index / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if ($type == push) {
|
||||||
|
.col-#{$class}-push-#{$index} {
|
||||||
|
left: percentage(($index / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if ($type == pull) {
|
||||||
|
.col-#{$class}-pull-#{$index} {
|
||||||
|
right: percentage(($index / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if ($type == offset) {
|
||||||
|
.col-#{$class}-offset-#{$index} {
|
||||||
|
margin-left: percentage(($index / $grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// [converter] This is defined recursively in LESS, but Sass supports real loops
|
||||||
|
@mixin loop-grid-columns($columns, $class, $type) {
|
||||||
|
@for $i from 0 through $columns {
|
||||||
|
@include calc-grid-column($i, $class, $type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create grid for specific class
|
||||||
|
@mixin make-grid($class) {
|
||||||
|
@include float-grid-columns($class);
|
||||||
|
@include loop-grid-columns($grid-columns, $class, width);
|
||||||
|
@include loop-grid-columns($grid-columns, $class, pull);
|
||||||
|
@include loop-grid-columns($grid-columns, $class, push);
|
||||||
|
@include loop-grid-columns($grid-columns, $class, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form validation states
|
||||||
|
//
|
||||||
|
// Used in forms.less to generate the form validation CSS for warnings, errors,
|
||||||
|
// and successes.
|
||||||
|
|
||||||
|
@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) {
|
||||||
|
// Color the label and help text
|
||||||
|
.help-block,
|
||||||
|
.control-label,
|
||||||
|
.radio,
|
||||||
|
.checkbox,
|
||||||
|
.radio-inline,
|
||||||
|
.checkbox-inline {
|
||||||
|
color: $text-color;
|
||||||
|
}
|
||||||
|
// Set the border and box shadow on specific inputs to match
|
||||||
|
.form-control {
|
||||||
|
border-color: $border-color;
|
||||||
|
@include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
|
||||||
|
&:focus {
|
||||||
|
border-color: darken($border-color, 10%);
|
||||||
|
$shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%);
|
||||||
|
@include box-shadow($shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set validation states also for addons
|
||||||
|
.input-group-addon {
|
||||||
|
color: $text-color;
|
||||||
|
border-color: $border-color;
|
||||||
|
background-color: $background-color;
|
||||||
|
}
|
||||||
|
// Optional feedback icon
|
||||||
|
.form-control-feedback {
|
||||||
|
color: $text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form control focus state
|
||||||
|
//
|
||||||
|
// Generate a customized focus state and for any input with the specified color,
|
||||||
|
// which defaults to the `$input-focus-border` variable.
|
||||||
|
//
|
||||||
|
// We highly encourage you to not customize the default value, but instead use
|
||||||
|
// this to tweak colors on an as-needed basis. This aesthetic change is based on
|
||||||
|
// WebKit's default styles, but applicable to a wider range of browsers. Its
|
||||||
|
// usability and accessibility should be taken into account with any change.
|
||||||
|
//
|
||||||
|
// Example usage: change the default blue border and shadow to white for better
|
||||||
|
// contrast against a dark gray background.
|
||||||
|
|
||||||
|
@mixin form-control-focus($color: $input-border-focus) {
|
||||||
|
$color-rgba: rgba(red($color), green($color), blue($color), .6);
|
||||||
|
&:focus {
|
||||||
|
border-color: $color;
|
||||||
|
outline: 0;
|
||||||
|
@include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form control sizing
|
||||||
|
//
|
||||||
|
// Relative text size, padding, and border-radii changes for form controls. For
|
||||||
|
// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
|
||||||
|
// element gets special love because it's special, and that's a fact!
|
||||||
|
|
||||||
|
// [converter] $parent hack
|
||||||
|
@mixin input-size($parent, $input-height, $padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
|
||||||
|
#{$parent} {
|
||||||
|
height: $input-height;
|
||||||
|
padding: $padding-vertical $padding-horizontal;
|
||||||
|
font-size: $font-size;
|
||||||
|
line-height: $line-height;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
select#{$parent} {
|
||||||
|
height: $input-height;
|
||||||
|
line-height: $input-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea#{$parent},
|
||||||
|
select[multiple]#{$parent} {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,833 @@
|
||||||
|
// a flag to toggle asset pipeline / compass integration
|
||||||
|
// defaults to true if twbs-font-path function is present (no function => twbs-font-path('') parsed as string == right side)
|
||||||
|
// in Sass 3.3 this can be improved with: function-exists(twbs-font-path)
|
||||||
|
$bootstrap-sass-asset-helper: (twbs-font-path("") != unquote('twbs-font-path("")')) !default;
|
||||||
|
//
|
||||||
|
// Variables
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//== Colors
|
||||||
|
//
|
||||||
|
//## Gray and brand colors for use across Bootstrap.
|
||||||
|
|
||||||
|
$gray-darker: lighten(#000, 13.5%) !default; // #222
|
||||||
|
$gray-dark: lighten(#000, 20%) !default; // #333
|
||||||
|
$gray: lighten(#000, 33.5%) !default; // #555
|
||||||
|
$gray-light: lighten(#000, 60%) !default; // #999
|
||||||
|
$gray-lighter: lighten(#000, 93.5%) !default; // #eee
|
||||||
|
|
||||||
|
$brand-primary: #47bab5 !default;
|
||||||
|
$brand-success: #5cb85c !default;
|
||||||
|
$brand-info: #5bc0de !default;
|
||||||
|
$brand-warning: #f0ad4e !default;
|
||||||
|
$brand-danger: #ed4c43 !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Scaffolding
|
||||||
|
//
|
||||||
|
// ## Settings for some of the most global styles.
|
||||||
|
|
||||||
|
//** Background color for `<body>`.
|
||||||
|
$body-bg: #fff !default;
|
||||||
|
//** Global text color on `<body>`.
|
||||||
|
$text-color: $gray-dark !default;
|
||||||
|
|
||||||
|
//** Global textual link color.
|
||||||
|
$link-color: $brand-primary !default;
|
||||||
|
//** Link hover color set via `darken()` function.
|
||||||
|
$link-hover-color: darken($link-color, 15%) !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Typography
|
||||||
|
//
|
||||||
|
//## Font, line-height, and color for body text, headings, and more.
|
||||||
|
|
||||||
|
$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif !default;
|
||||||
|
$font-family-serif: Georgia, "Times New Roman", Times, serif !default;
|
||||||
|
//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.
|
||||||
|
$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace !default;
|
||||||
|
$font-family-base: $font-family-sans-serif !default;
|
||||||
|
|
||||||
|
$font-size-base: 14px !default;
|
||||||
|
$font-size-large: ceil(($font-size-base * 1.25)) !default; // ~18px
|
||||||
|
$font-size-small: ceil(($font-size-base * 0.85)) !default; // ~12px
|
||||||
|
|
||||||
|
$font-size-h1: floor(($font-size-base * 2.6)) !default; // ~36px
|
||||||
|
$font-size-h2: floor(($font-size-base * 2.15)) !default; // ~30px
|
||||||
|
$font-size-h3: ceil(($font-size-base * 1.7)) !default; // ~24px
|
||||||
|
$font-size-h4: ceil(($font-size-base * 1.25)) !default; // ~18px
|
||||||
|
$font-size-h5: $font-size-base !default;
|
||||||
|
$font-size-h6: ceil(($font-size-base * 0.85)) !default; // ~12px
|
||||||
|
|
||||||
|
//** Unit-less `line-height` for use in components like buttons.
|
||||||
|
$line-height-base: 1.428571429 !default; // 20/14
|
||||||
|
//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
|
||||||
|
$line-height-computed: floor(($font-size-base * $line-height-base)) !default; // ~20px
|
||||||
|
|
||||||
|
//** By default, this inherits from the `<body>`.
|
||||||
|
$headings-font-family: inherit !default;
|
||||||
|
$headings-font-weight: 500 !default;
|
||||||
|
$headings-line-height: 1.1 !default;
|
||||||
|
$headings-color: inherit !default;
|
||||||
|
|
||||||
|
|
||||||
|
//-- Iconography
|
||||||
|
//
|
||||||
|
//## Specify custom locations of the include Glyphicons icon font. Useful for those including Bootstrap via Bower.
|
||||||
|
|
||||||
|
$icon-font-path: "bootstrap/" !default;
|
||||||
|
$icon-font-name: "glyphicons-halflings-regular" !default;
|
||||||
|
$icon-font-svg-id: "glyphicons_halflingsregular" !default;
|
||||||
|
|
||||||
|
//== Components
|
||||||
|
//
|
||||||
|
//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
|
||||||
|
|
||||||
|
$padding-base-vertical: 6px !default;
|
||||||
|
$padding-base-horizontal: 12px !default;
|
||||||
|
|
||||||
|
$padding-large-vertical: 10px !default;
|
||||||
|
$padding-large-horizontal: 16px !default;
|
||||||
|
|
||||||
|
$padding-small-vertical: 5px !default;
|
||||||
|
$padding-small-horizontal: 10px !default;
|
||||||
|
|
||||||
|
$padding-xs-vertical: 1px !default;
|
||||||
|
$padding-xs-horizontal: 5px !default;
|
||||||
|
|
||||||
|
$line-height-large: 1.33 !default;
|
||||||
|
$line-height-small: 1.5 !default;
|
||||||
|
|
||||||
|
$border-radius-base: 4px !default;
|
||||||
|
$border-radius-large: 6px !default;
|
||||||
|
$border-radius-small: 3px !default;
|
||||||
|
|
||||||
|
//** Global color for active items (e.g., navs or dropdowns).
|
||||||
|
$component-active-color: #fff !default;
|
||||||
|
//** Global background color for active items (e.g., navs or dropdowns).
|
||||||
|
$component-active-bg: $brand-primary !default;
|
||||||
|
|
||||||
|
//** Width of the `border` for generating carets that indicator dropdowns.
|
||||||
|
$caret-width-base: 4px !default;
|
||||||
|
//** Carets increase slightly in size for larger components.
|
||||||
|
$caret-width-large: 5px !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Tables
|
||||||
|
//
|
||||||
|
//## Customizes the `.table` component with basic values, each used across all table variations.
|
||||||
|
|
||||||
|
//** Padding for `<th>`s and `<td>`s.
|
||||||
|
$table-cell-padding: 8px !default;
|
||||||
|
//** Padding for cells in `.table-condensed`.
|
||||||
|
$table-condensed-cell-padding: 5px !default;
|
||||||
|
|
||||||
|
//** Default background color used for all tables.
|
||||||
|
$table-bg: transparent !default;
|
||||||
|
//** Background color used for `.table-striped`.
|
||||||
|
$table-bg-accent: #f9f9f9 !default;
|
||||||
|
//** Background color used for `.table-hover`.
|
||||||
|
$table-bg-hover: #f5f5f5 !default;
|
||||||
|
$table-bg-active: $table-bg-hover !default;
|
||||||
|
|
||||||
|
//** Border color for table and cell borders.
|
||||||
|
$table-border-color: #ddd !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Buttons
|
||||||
|
//
|
||||||
|
//## For each of Bootstrap's buttons, define text, background and border color.
|
||||||
|
|
||||||
|
$btn-font-weight: normal !default;
|
||||||
|
|
||||||
|
$btn-default-color: #333 !default;
|
||||||
|
$btn-default-bg: #fff !default;
|
||||||
|
$btn-default-border: #ccc !default;
|
||||||
|
|
||||||
|
$btn-primary-color: #fff !default;
|
||||||
|
$btn-primary-bg: $brand-primary !default;
|
||||||
|
$btn-primary-border: darken($btn-primary-bg, 5%) !default;
|
||||||
|
|
||||||
|
$btn-success-color: #fff !default;
|
||||||
|
$btn-success-bg: $brand-success !default;
|
||||||
|
$btn-success-border: darken($btn-success-bg, 5%) !default;
|
||||||
|
|
||||||
|
$btn-info-color: #fff !default;
|
||||||
|
$btn-info-bg: $brand-info !default;
|
||||||
|
$btn-info-border: darken($btn-info-bg, 5%) !default;
|
||||||
|
|
||||||
|
$btn-warning-color: #fff !default;
|
||||||
|
$btn-warning-bg: $brand-warning !default;
|
||||||
|
$btn-warning-border: darken($btn-warning-bg, 5%) !default;
|
||||||
|
|
||||||
|
$btn-danger-color: #fff !default;
|
||||||
|
$btn-danger-bg: $brand-danger !default;
|
||||||
|
$btn-danger-border: darken($btn-danger-bg, 5%) !default;
|
||||||
|
|
||||||
|
$btn-link-disabled-color: $gray-light !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Forms
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** `<input>` background color
|
||||||
|
$input-bg: #fff !default;
|
||||||
|
//** `<input disabled>` background color
|
||||||
|
$input-bg-disabled: $gray-lighter !default;
|
||||||
|
|
||||||
|
//** Text color for `<input>`s
|
||||||
|
$input-color: $gray !default;
|
||||||
|
//** `<input>` border color
|
||||||
|
$input-border: #ccc !default;
|
||||||
|
//** `<input>` border radius
|
||||||
|
$input-border-radius: $border-radius-base !default;
|
||||||
|
//** Border color for inputs on focus
|
||||||
|
$input-border-focus: #66afe9 !default;
|
||||||
|
|
||||||
|
//** Placeholder text color
|
||||||
|
$input-color-placeholder: $gray-light !default;
|
||||||
|
|
||||||
|
//** Default `.form-control` height
|
||||||
|
$input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
|
||||||
|
//** Large `.form-control` height
|
||||||
|
$input-height-large: (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
|
||||||
|
//** Small `.form-control` height
|
||||||
|
$input-height-small: (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
|
||||||
|
|
||||||
|
$legend-color: $gray-dark !default;
|
||||||
|
$legend-border-color: #e5e5e5 !default;
|
||||||
|
|
||||||
|
//** Background color for textual input addons
|
||||||
|
$input-group-addon-bg: $gray-lighter !default;
|
||||||
|
//** Border color for textual input addons
|
||||||
|
$input-group-addon-border-color: $input-border !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Dropdowns
|
||||||
|
//
|
||||||
|
//## Dropdown menu container and contents.
|
||||||
|
|
||||||
|
//** Background for the dropdown menu.
|
||||||
|
$dropdown-bg: #fff !default;
|
||||||
|
//** Dropdown menu `border-color`.
|
||||||
|
$dropdown-border: rgba(0,0,0,.15) !default;
|
||||||
|
//** Dropdown menu `border-color` **for IE8**.
|
||||||
|
$dropdown-fallback-border: #ccc !default;
|
||||||
|
//** Divider color for between dropdown items.
|
||||||
|
$dropdown-divider-bg: #e5e5e5 !default;
|
||||||
|
|
||||||
|
//** Dropdown link text color.
|
||||||
|
$dropdown-link-color: $gray-dark !default;
|
||||||
|
//** Hover color for dropdown links.
|
||||||
|
$dropdown-link-hover-color: darken($gray-dark, 5%) !default;
|
||||||
|
//** Hover background for dropdown links.
|
||||||
|
$dropdown-link-hover-bg: #f5f5f5 !default;
|
||||||
|
|
||||||
|
//** Active dropdown menu item text color.
|
||||||
|
$dropdown-link-active-color: $component-active-color !default;
|
||||||
|
//** Active dropdown menu item background color.
|
||||||
|
$dropdown-link-active-bg: $component-active-bg !default;
|
||||||
|
|
||||||
|
//** Disabled dropdown menu item background color.
|
||||||
|
$dropdown-link-disabled-color: $gray-light !default;
|
||||||
|
|
||||||
|
//** Text color for headers within dropdown menus.
|
||||||
|
$dropdown-header-color: $gray-light !default;
|
||||||
|
|
||||||
|
// Note: Deprecated $dropdown-caret-color as of v3.1.0
|
||||||
|
$dropdown-caret-color: #000 !default;
|
||||||
|
|
||||||
|
|
||||||
|
//-- Z-index master list
|
||||||
|
//
|
||||||
|
// Warning: Avoid customizing these values. They're used for a bird's eye view
|
||||||
|
// of components dependent on the z-axis and are designed to all work together.
|
||||||
|
//
|
||||||
|
// Note: These variables are not generated into the Customizer.
|
||||||
|
|
||||||
|
$zindex-navbar: 1000 !default;
|
||||||
|
$zindex-dropdown: 1000 !default;
|
||||||
|
$zindex-popover: 1010 !default;
|
||||||
|
$zindex-tooltip: 1030 !default;
|
||||||
|
$zindex-navbar-fixed: 1030 !default;
|
||||||
|
$zindex-modal-background: 1040 !default;
|
||||||
|
$zindex-modal: 1050 !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Media queries breakpoints
|
||||||
|
//
|
||||||
|
//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
|
||||||
|
|
||||||
|
// Extra small screen / phone
|
||||||
|
// Note: Deprecated $screen-xs and $screen-phone as of v3.0.1
|
||||||
|
$screen-xs: 480px !default;
|
||||||
|
$screen-xs-min: $screen-xs !default;
|
||||||
|
$screen-phone: $screen-xs-min !default;
|
||||||
|
|
||||||
|
// Small screen / tablet
|
||||||
|
// Note: Deprecated $screen-sm and $screen-tablet as of v3.0.1
|
||||||
|
$screen-sm: 768px !default;
|
||||||
|
$screen-sm-min: $screen-sm !default;
|
||||||
|
$screen-tablet: $screen-sm-min !default;
|
||||||
|
|
||||||
|
// Medium screen / desktop
|
||||||
|
// Note: Deprecated $screen-md and $screen-desktop as of v3.0.1
|
||||||
|
$screen-md: 992px !default;
|
||||||
|
$screen-md-min: $screen-md !default;
|
||||||
|
$screen-desktop: $screen-md-min !default;
|
||||||
|
|
||||||
|
// Large screen / wide desktop
|
||||||
|
// Note: Deprecated $screen-lg and $screen-lg-desktop as of v3.0.1
|
||||||
|
$screen-lg: 1200px !default;
|
||||||
|
$screen-lg-min: $screen-lg !default;
|
||||||
|
$screen-lg-desktop: $screen-lg-min !default;
|
||||||
|
|
||||||
|
// So media queries don't overlap when required, provide a maximum
|
||||||
|
$screen-xs-max: ($screen-sm-min - 1) !default;
|
||||||
|
$screen-sm-max: ($screen-md-min - 1) !default;
|
||||||
|
$screen-md-max: ($screen-lg-min - 1) !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Grid system
|
||||||
|
//
|
||||||
|
//## Define your custom responsive grid.
|
||||||
|
|
||||||
|
//** Number of columns in the grid.
|
||||||
|
$grid-columns: 12 !default;
|
||||||
|
//** Padding between columns. Gets divided in half for the left and right.
|
||||||
|
$grid-gutter-width: 30px !default;
|
||||||
|
// Navbar collapse
|
||||||
|
//** Point at which the navbar becomes uncollapsed.
|
||||||
|
$grid-float-breakpoint: $screen-sm-min !default;
|
||||||
|
//** Point at which the navbar begins collapsing.
|
||||||
|
$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Container sizes
|
||||||
|
//
|
||||||
|
//## Define the maximum width of `.container` for different screen sizes.
|
||||||
|
|
||||||
|
// Small screen / tablet
|
||||||
|
$container-tablet: ((720px + $grid-gutter-width)) !default;
|
||||||
|
//** For `$screen-sm-min` and up.
|
||||||
|
$container-sm: $container-tablet !default;
|
||||||
|
|
||||||
|
// Medium screen / desktop
|
||||||
|
$container-desktop: ((940px + $grid-gutter-width)) !default;
|
||||||
|
//** For `$screen-md-min` and up.
|
||||||
|
$container-md: $container-desktop !default;
|
||||||
|
|
||||||
|
// Large screen / wide desktop
|
||||||
|
$container-large-desktop: ((1140px + $grid-gutter-width)) !default;
|
||||||
|
//** For `$screen-lg-min` and up.
|
||||||
|
$container-lg: $container-large-desktop !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Navbar
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
// Basics of a navbar
|
||||||
|
$navbar-height: 50px !default;
|
||||||
|
$navbar-margin-bottom: $line-height-computed !default;
|
||||||
|
$navbar-border-radius: $border-radius-base !default;
|
||||||
|
$navbar-padding-horizontal: floor(($grid-gutter-width / 2)) !default;
|
||||||
|
$navbar-padding-vertical: (($navbar-height - $line-height-computed) / 2) !default;
|
||||||
|
$navbar-collapse-max-height: 340px !default;
|
||||||
|
|
||||||
|
$navbar-default-color: #777 !default;
|
||||||
|
$navbar-default-bg: #f8f8f8 !default;
|
||||||
|
$navbar-default-border: darken($navbar-default-bg, 6.5%) !default;
|
||||||
|
|
||||||
|
// Navbar links
|
||||||
|
$navbar-default-link-color: #777 !default;
|
||||||
|
$navbar-default-link-hover-color: #333 !default;
|
||||||
|
$navbar-default-link-hover-bg: transparent !default;
|
||||||
|
$navbar-default-link-active-color: #555 !default;
|
||||||
|
$navbar-default-link-active-bg: darken($navbar-default-bg, 6.5%) !default;
|
||||||
|
$navbar-default-link-disabled-color: #ccc !default;
|
||||||
|
$navbar-default-link-disabled-bg: transparent !default;
|
||||||
|
|
||||||
|
// Navbar brand label
|
||||||
|
$navbar-default-brand-color: $navbar-default-link-color !default;
|
||||||
|
$navbar-default-brand-hover-color: darken($navbar-default-brand-color, 10%) !default;
|
||||||
|
$navbar-default-brand-hover-bg: transparent !default;
|
||||||
|
|
||||||
|
// Navbar toggle
|
||||||
|
$navbar-default-toggle-hover-bg: #ddd !default;
|
||||||
|
$navbar-default-toggle-icon-bar-bg: #888 !default;
|
||||||
|
$navbar-default-toggle-border-color: #ddd !default;
|
||||||
|
|
||||||
|
|
||||||
|
// Inverted navbar
|
||||||
|
// Reset inverted navbar basics
|
||||||
|
$navbar-inverse-color: $gray-light !default;
|
||||||
|
$navbar-inverse-bg: #222 !default;
|
||||||
|
$navbar-inverse-border: darken($navbar-inverse-bg, 10%) !default;
|
||||||
|
|
||||||
|
// Inverted navbar links
|
||||||
|
$navbar-inverse-link-color: $gray-light !default;
|
||||||
|
$navbar-inverse-link-hover-color: #fff !default;
|
||||||
|
$navbar-inverse-link-hover-bg: transparent !default;
|
||||||
|
$navbar-inverse-link-active-color: $navbar-inverse-link-hover-color !default;
|
||||||
|
$navbar-inverse-link-active-bg: darken($navbar-inverse-bg, 10%) !default;
|
||||||
|
$navbar-inverse-link-disabled-color: #444 !default;
|
||||||
|
$navbar-inverse-link-disabled-bg: transparent !default;
|
||||||
|
|
||||||
|
// Inverted navbar brand label
|
||||||
|
$navbar-inverse-brand-color: $navbar-inverse-link-color !default;
|
||||||
|
$navbar-inverse-brand-hover-color: #fff !default;
|
||||||
|
$navbar-inverse-brand-hover-bg: transparent !default;
|
||||||
|
|
||||||
|
// Inverted navbar toggle
|
||||||
|
$navbar-inverse-toggle-hover-bg: #333 !default;
|
||||||
|
$navbar-inverse-toggle-icon-bar-bg: #fff !default;
|
||||||
|
$navbar-inverse-toggle-border-color: #333 !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Navs
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//=== Shared nav styles
|
||||||
|
$nav-link-padding: 10px 15px !default;
|
||||||
|
$nav-link-hover-bg: $gray-lighter !default;
|
||||||
|
|
||||||
|
$nav-disabled-link-color: $gray-light !default;
|
||||||
|
$nav-disabled-link-hover-color: $gray-light !default;
|
||||||
|
|
||||||
|
$nav-open-link-hover-color: #fff !default;
|
||||||
|
|
||||||
|
//== Tabs
|
||||||
|
$nav-tabs-border-color: #ddd !default;
|
||||||
|
|
||||||
|
$nav-tabs-link-hover-border-color: $gray-lighter !default;
|
||||||
|
|
||||||
|
$nav-tabs-active-link-hover-bg: $body-bg !default;
|
||||||
|
$nav-tabs-active-link-hover-color: $gray !default;
|
||||||
|
$nav-tabs-active-link-hover-border-color: #ddd !default;
|
||||||
|
|
||||||
|
$nav-tabs-justified-link-border-color: #ddd !default;
|
||||||
|
$nav-tabs-justified-active-link-border-color: $body-bg !default;
|
||||||
|
|
||||||
|
//== Pills
|
||||||
|
$nav-pills-border-radius: $border-radius-base !default;
|
||||||
|
$nav-pills-active-link-hover-bg: $component-active-bg !default;
|
||||||
|
$nav-pills-active-link-hover-color: $component-active-color !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Pagination
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$pagination-color: $link-color !default;
|
||||||
|
$pagination-bg: #fff !default;
|
||||||
|
$pagination-border: #ddd !default;
|
||||||
|
|
||||||
|
$pagination-hover-color: $link-hover-color !default;
|
||||||
|
$pagination-hover-bg: $gray-lighter !default;
|
||||||
|
$pagination-hover-border: #ddd !default;
|
||||||
|
|
||||||
|
$pagination-active-color: #fff !default;
|
||||||
|
$pagination-active-bg: $brand-primary !default;
|
||||||
|
$pagination-active-border: $brand-primary !default;
|
||||||
|
|
||||||
|
$pagination-disabled-color: $gray-light !default;
|
||||||
|
$pagination-disabled-bg: #fff !default;
|
||||||
|
$pagination-disabled-border: #ddd !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Pager
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$pager-bg: $pagination-bg !default;
|
||||||
|
$pager-border: $pagination-border !default;
|
||||||
|
$pager-border-radius: 15px !default;
|
||||||
|
|
||||||
|
$pager-hover-bg: $pagination-hover-bg !default;
|
||||||
|
|
||||||
|
$pager-active-bg: $pagination-active-bg !default;
|
||||||
|
$pager-active-color: $pagination-active-color !default;
|
||||||
|
|
||||||
|
$pager-disabled-color: $pagination-disabled-color !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Jumbotron
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$jumbotron-padding: 30px !default;
|
||||||
|
$jumbotron-color: inherit !default;
|
||||||
|
$jumbotron-bg: $gray-lighter !default;
|
||||||
|
$jumbotron-heading-color: inherit !default;
|
||||||
|
$jumbotron-font-size: ceil(($font-size-base * 1.5)) !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Form states and alerts
|
||||||
|
//
|
||||||
|
//## Define colors for form feedback states and, by default, alerts.
|
||||||
|
|
||||||
|
$state-success-text: #3c763d !default;
|
||||||
|
$state-success-bg: #dff0d8 !default;
|
||||||
|
$state-success-border: darken(adjust-hue($state-success-bg, -10), 5%) !default;
|
||||||
|
|
||||||
|
$state-info-text: #31708f !default;
|
||||||
|
$state-info-bg: #d9edf7 !default;
|
||||||
|
$state-info-border: darken(adjust-hue($state-info-bg, -10), 7%) !default;
|
||||||
|
|
||||||
|
$state-warning-text: #8a6d3b !default;
|
||||||
|
$state-warning-bg: #fcf8e3 !default;
|
||||||
|
$state-warning-border: darken(adjust-hue($state-warning-bg, -10), 5%) !default;
|
||||||
|
|
||||||
|
$state-danger-text: #a94442 !default;
|
||||||
|
$state-danger-bg: #f2dede !default;
|
||||||
|
$state-danger-border: darken(adjust-hue($state-danger-bg, -10), 5%) !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Tooltips
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Tooltip max width
|
||||||
|
$tooltip-max-width: 200px !default;
|
||||||
|
//** Tooltip text color
|
||||||
|
$tooltip-color: #fff !default;
|
||||||
|
//** Tooltip background color
|
||||||
|
$tooltip-bg: #000 !default;
|
||||||
|
$tooltip-opacity: .9 !default;
|
||||||
|
|
||||||
|
//** Tooltip arrow width
|
||||||
|
$tooltip-arrow-width: 5px !default;
|
||||||
|
//** Tooltip arrow color
|
||||||
|
$tooltip-arrow-color: $tooltip-bg !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Popovers
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Popover body background color
|
||||||
|
$popover-bg: #fff !default;
|
||||||
|
//** Popover maximum width
|
||||||
|
$popover-max-width: 276px !default;
|
||||||
|
//** Popover border color
|
||||||
|
$popover-border-color: rgba(0,0,0,.2) !default;
|
||||||
|
//** Popover fallback border color
|
||||||
|
$popover-fallback-border-color: #ccc !default;
|
||||||
|
|
||||||
|
//** Popover title background color
|
||||||
|
$popover-title-bg: darken($popover-bg, 3%) !default;
|
||||||
|
|
||||||
|
//** Popover arrow width
|
||||||
|
$popover-arrow-width: 10px !default;
|
||||||
|
//** Popover arrow color
|
||||||
|
$popover-arrow-color: #fff !default;
|
||||||
|
|
||||||
|
//** Popover outer arrow width
|
||||||
|
$popover-arrow-outer-width: ($popover-arrow-width + 1) !default;
|
||||||
|
//** Popover outer arrow color
|
||||||
|
$popover-arrow-outer-color: fadein($popover-border-color, 5%) !default;
|
||||||
|
//** Popover outer arrow fallback color
|
||||||
|
$popover-arrow-outer-fallback-color: darken($popover-fallback-border-color, 20%) !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Labels
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Default label background color
|
||||||
|
$label-default-bg: $gray-light !default;
|
||||||
|
//** Primary label background color
|
||||||
|
$label-primary-bg: $brand-primary !default;
|
||||||
|
//** Success label background color
|
||||||
|
$label-success-bg: $brand-success !default;
|
||||||
|
//** Info label background color
|
||||||
|
$label-info-bg: $brand-info !default;
|
||||||
|
//** Warning label background color
|
||||||
|
$label-warning-bg: $brand-warning !default;
|
||||||
|
//** Danger label background color
|
||||||
|
$label-danger-bg: $brand-danger !default;
|
||||||
|
|
||||||
|
//** Default label text color
|
||||||
|
$label-color: #fff !default;
|
||||||
|
//** Default text color of a linked label
|
||||||
|
$label-link-hover-color: #fff !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Modals
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Padding applied to the modal body
|
||||||
|
$modal-inner-padding: 20px !default;
|
||||||
|
|
||||||
|
//** Padding applied to the modal title
|
||||||
|
$modal-title-padding: 15px !default;
|
||||||
|
//** Modal title line-height
|
||||||
|
$modal-title-line-height: $line-height-base !default;
|
||||||
|
|
||||||
|
//** Background color of modal content area
|
||||||
|
$modal-content-bg: #fff !default;
|
||||||
|
//** Modal content border color
|
||||||
|
$modal-content-border-color: rgba(0,0,0,.2) !default;
|
||||||
|
//** Modal content border color **for IE8**
|
||||||
|
$modal-content-fallback-border-color: #999 !default;
|
||||||
|
|
||||||
|
//** Modal backdrop background color
|
||||||
|
$modal-backdrop-bg: #000 !default;
|
||||||
|
//** Modal backdrop opacity
|
||||||
|
$modal-backdrop-opacity: .5 !default;
|
||||||
|
//** Modal header border color
|
||||||
|
$modal-header-border-color: #e5e5e5 !default;
|
||||||
|
//** Modal footer border color
|
||||||
|
$modal-footer-border-color: $modal-header-border-color !default;
|
||||||
|
|
||||||
|
$modal-lg: 900px !default;
|
||||||
|
$modal-md: 600px !default;
|
||||||
|
$modal-sm: 300px !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Alerts
|
||||||
|
//
|
||||||
|
//## Define alert colors, border radius, and padding.
|
||||||
|
|
||||||
|
$alert-padding: 15px !default;
|
||||||
|
$alert-border-radius: $border-radius-base !default;
|
||||||
|
$alert-link-font-weight: bold !default;
|
||||||
|
|
||||||
|
$alert-success-bg: $state-success-bg !default;
|
||||||
|
$alert-success-text: $state-success-text !default;
|
||||||
|
$alert-success-border: $state-success-border !default;
|
||||||
|
|
||||||
|
$alert-info-bg: $state-info-bg !default;
|
||||||
|
$alert-info-text: $state-info-text !default;
|
||||||
|
$alert-info-border: $state-info-border !default;
|
||||||
|
|
||||||
|
$alert-warning-bg: $state-warning-bg !default;
|
||||||
|
$alert-warning-text: $state-warning-text !default;
|
||||||
|
$alert-warning-border: $state-warning-border !default;
|
||||||
|
|
||||||
|
$alert-danger-bg: $state-danger-bg !default;
|
||||||
|
$alert-danger-text: $state-danger-text !default;
|
||||||
|
$alert-danger-border: $state-danger-border !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Progress bars
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Background color of the whole progress component
|
||||||
|
$progress-bg: #f5f5f5 !default;
|
||||||
|
//** Progress bar text color
|
||||||
|
$progress-bar-color: #fff !default;
|
||||||
|
|
||||||
|
//** Default progress bar color
|
||||||
|
$progress-bar-bg: $brand-primary !default;
|
||||||
|
//** Success progress bar color
|
||||||
|
$progress-bar-success-bg: $brand-success !default;
|
||||||
|
//** Warning progress bar color
|
||||||
|
$progress-bar-warning-bg: $brand-warning !default;
|
||||||
|
//** Danger progress bar color
|
||||||
|
$progress-bar-danger-bg: $brand-danger !default;
|
||||||
|
//** Info progress bar color
|
||||||
|
$progress-bar-info-bg: $brand-info !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== List group
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Background color on `.list-group-item`
|
||||||
|
$list-group-bg: #fff !default;
|
||||||
|
//** `.list-group-item` border color
|
||||||
|
$list-group-border: #ddd !default;
|
||||||
|
//** List group border radius
|
||||||
|
$list-group-border-radius: $border-radius-base !default;
|
||||||
|
|
||||||
|
//** Background color of single list elements on hover
|
||||||
|
$list-group-hover-bg: #f5f5f5 !default;
|
||||||
|
//** Text color of active list elements
|
||||||
|
$list-group-active-color: $component-active-color !default;
|
||||||
|
//** Background color of active list elements
|
||||||
|
$list-group-active-bg: $component-active-bg !default;
|
||||||
|
//** Border color of active list elements
|
||||||
|
$list-group-active-border: $list-group-active-bg !default;
|
||||||
|
$list-group-active-text-color: lighten($list-group-active-bg, 40%) !default;
|
||||||
|
|
||||||
|
$list-group-link-color: #555 !default;
|
||||||
|
$list-group-link-heading-color: #333 !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Panels
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$panel-bg: #fff !default;
|
||||||
|
$panel-body-padding: 15px !default;
|
||||||
|
$panel-border-radius: $border-radius-base !default;
|
||||||
|
|
||||||
|
//** Border color for elements within panels
|
||||||
|
$panel-inner-border: #ddd !default;
|
||||||
|
$panel-footer-bg: #f5f5f5 !default;
|
||||||
|
|
||||||
|
$panel-default-text: $gray-dark !default;
|
||||||
|
$panel-default-border: #ddd !default;
|
||||||
|
$panel-default-heading-bg: #f5f5f5 !default;
|
||||||
|
|
||||||
|
$panel-primary-text: #fff !default;
|
||||||
|
$panel-primary-border: $brand-primary !default;
|
||||||
|
$panel-primary-heading-bg: $brand-primary !default;
|
||||||
|
|
||||||
|
$panel-success-text: $state-success-text !default;
|
||||||
|
$panel-success-border: $state-success-border !default;
|
||||||
|
$panel-success-heading-bg: $state-success-bg !default;
|
||||||
|
|
||||||
|
$panel-info-text: $state-info-text !default;
|
||||||
|
$panel-info-border: $state-info-border !default;
|
||||||
|
$panel-info-heading-bg: $state-info-bg !default;
|
||||||
|
|
||||||
|
$panel-warning-text: $state-warning-text !default;
|
||||||
|
$panel-warning-border: $state-warning-border !default;
|
||||||
|
$panel-warning-heading-bg: $state-warning-bg !default;
|
||||||
|
|
||||||
|
$panel-danger-text: $state-danger-text !default;
|
||||||
|
$panel-danger-border: $state-danger-border !default;
|
||||||
|
$panel-danger-heading-bg: $state-danger-bg !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Thumbnails
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Padding around the thumbnail image
|
||||||
|
$thumbnail-padding: 4px !default;
|
||||||
|
//** Thumbnail background color
|
||||||
|
$thumbnail-bg: $body-bg !default;
|
||||||
|
//** Thumbnail border color
|
||||||
|
$thumbnail-border: #ddd !default;
|
||||||
|
//** Thumbnail border radius
|
||||||
|
$thumbnail-border-radius: $border-radius-base !default;
|
||||||
|
|
||||||
|
//** Custom text color for thumbnail captions
|
||||||
|
$thumbnail-caption-color: $text-color !default;
|
||||||
|
//** Padding around the thumbnail caption
|
||||||
|
$thumbnail-caption-padding: 9px !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Wells
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$well-bg: #f5f5f5 !default;
|
||||||
|
$well-border: darken($well-bg, 7%) !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Badges
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$badge-color: #fff !default;
|
||||||
|
//** Linked badge text color on hover
|
||||||
|
$badge-link-hover-color: #fff !default;
|
||||||
|
$badge-bg: $gray-light !default;
|
||||||
|
|
||||||
|
//** Badge text color in active nav link
|
||||||
|
$badge-active-color: $link-color !default;
|
||||||
|
//** Badge background color in active nav link
|
||||||
|
$badge-active-bg: #fff !default;
|
||||||
|
|
||||||
|
$badge-font-weight: bold !default;
|
||||||
|
$badge-line-height: 1 !default;
|
||||||
|
$badge-border-radius: 10px !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Breadcrumbs
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$breadcrumb-padding-vertical: 8px !default;
|
||||||
|
$breadcrumb-padding-horizontal: 15px !default;
|
||||||
|
//** Breadcrumb background color
|
||||||
|
$breadcrumb-bg: #f5f5f5 !default;
|
||||||
|
//** Breadcrumb text color
|
||||||
|
$breadcrumb-color: #ccc !default;
|
||||||
|
//** Text color of current page in the breadcrumb
|
||||||
|
$breadcrumb-active-color: $gray-light !default;
|
||||||
|
//** Textual separator for between breadcrumb elements
|
||||||
|
$breadcrumb-separator: "/" !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Carousel
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6) !default;
|
||||||
|
|
||||||
|
$carousel-control-color: #fff !default;
|
||||||
|
$carousel-control-width: 15% !default;
|
||||||
|
$carousel-control-opacity: .5 !default;
|
||||||
|
$carousel-control-font-size: 20px !default;
|
||||||
|
|
||||||
|
$carousel-indicator-active-bg: #fff !default;
|
||||||
|
$carousel-indicator-border-color: #fff !default;
|
||||||
|
|
||||||
|
$carousel-caption-color: #fff !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Close
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$close-font-weight: bold !default;
|
||||||
|
$close-color: #000 !default;
|
||||||
|
$close-text-shadow: 0 1px 0 #fff !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Code
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
$code-color: #c7254e !default;
|
||||||
|
$code-bg: #f9f2f4 !default;
|
||||||
|
|
||||||
|
$kbd-color: #fff !default;
|
||||||
|
$kbd-bg: #333 !default;
|
||||||
|
|
||||||
|
$pre-bg: #f5f5f5 !default;
|
||||||
|
$pre-color: $gray-dark !default;
|
||||||
|
$pre-border-color: #ccc !default;
|
||||||
|
$pre-scrollable-max-height: 340px !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Type
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Text muted color
|
||||||
|
$text-muted: $gray-light !default;
|
||||||
|
//** Abbreviations and acronyms border color
|
||||||
|
$abbr-border-color: $gray-light !default;
|
||||||
|
//** Headings small color
|
||||||
|
$headings-small-color: $gray-light !default;
|
||||||
|
//** Blockquote small color
|
||||||
|
$blockquote-small-color: $gray-light !default;
|
||||||
|
//** Blockquote font size
|
||||||
|
$blockquote-font-size: ($font-size-base * 1.25) !default;
|
||||||
|
//** Blockquote border color
|
||||||
|
$blockquote-border-color: $gray-lighter !default;
|
||||||
|
//** Page header border color
|
||||||
|
$page-header-border-color: $gray-lighter !default;
|
||||||
|
|
||||||
|
|
||||||
|
//== Miscellaneous
|
||||||
|
//
|
||||||
|
//##
|
||||||
|
|
||||||
|
//** Horizontal line color.
|
||||||
|
$hr-border: $gray-lighter !default;
|
||||||
|
|
||||||
|
//** Horizontal offset for forms and lists.
|
||||||
|
$component-offset-horizontal: 180px !default;
|
6
custom_announcement/app/assets/stylesheets/custom_bulletin/bootstrap/bootstrap.min.css
vendored
Normal file
6
custom_announcement/app/assets/stylesheets/custom_bulletin/bootstrap/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,554 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require 'rubyXL'
|
||||||
|
class Admin::CustomAnnouncementsController < OrbitAdminController
|
||||||
|
include Admin::CustomAnnouncementsHelper
|
||||||
|
before_action ->(module_app = @app_title) { set_variables module_app }
|
||||||
|
before_action :set_custom_bulletin, only: [:edit, :destroy, :comment]
|
||||||
|
before_action :load_access_level, :load_settings
|
||||||
|
before_action :set_module_pages, only: [:edit,:new]
|
||||||
|
def set_module_pages
|
||||||
|
@module_pages = Page.where(:module => 'custom_announcement').collect{|p| [p.name,p.id] }
|
||||||
|
end
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
@app_title = "custom_announcement"
|
||||||
|
end
|
||||||
|
def comment_hidden
|
||||||
|
b = CustomBulletinComment.find(params[:id]) rescue nil
|
||||||
|
if !b.nil?
|
||||||
|
b.is_hidden = !b.is_hidden
|
||||||
|
b.save
|
||||||
|
@table_feed_fields = ["custom_announcement.time", "custom_announcement.comment", "custom_announcement.account","ip","is_hidden"]
|
||||||
|
@comments = b.custom_bulletin.custom_bulletin_comments.reverse rescue []
|
||||||
|
render partial: 'comment'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def comment
|
||||||
|
@table_feed_fields = ["custom_announcement.time", "custom_announcement.comment", "custom_announcement.account","ip","is_hidden"]
|
||||||
|
@comments = @custom_bulletin.custom_bulletin_comments.reverse rescue []
|
||||||
|
end
|
||||||
|
def index
|
||||||
|
@custom_bulletin_configs = CustomBulletinConfig.all
|
||||||
|
CustomBulletin.remove_expired_status
|
||||||
|
@tags = @module_app.tags
|
||||||
|
@table_fields = [:status, :category, :title, :start_date, :end_date, "custom_announcement.comment", :last_modified]
|
||||||
|
@current_user = current_user
|
||||||
|
if CustomAnnouncementSetting.first.is_display_edit_only && !current_user.is_admin? && !current_user.is_manager?(@module_app)
|
||||||
|
current_user_is_sub_manager = !current_user.is_manager?(@module_app) && (current_user.is_sub_manager?(@module_app) || current_user.is_sub_manager_with_role?(@module_app)) rescue false
|
||||||
|
if current_user_is_sub_manager
|
||||||
|
@categories = current_user.approved_categories.select{|c| c.module_app_id == @module_app.id} rescue []
|
||||||
|
@filter_fields = filter_fields(@categories, @tags)
|
||||||
|
@custom_bulletins = CustomBulletin.where(:create_user_id=>current_user.id,:title.ne => "",:is_preview.in=>[false,nil])
|
||||||
|
.order_by(sort)
|
||||||
|
.with_categories(filters("category"))
|
||||||
|
.with_tags(filters("tag"))
|
||||||
|
.with_status(filters("status"))
|
||||||
|
else
|
||||||
|
@custom_bulletins = CustomBulletin.where(:uid=>nil)
|
||||||
|
@categories = @module_app.categories.enabled
|
||||||
|
@filter_fields = filter_fields(@categories, @tags)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@categories = @module_app.categories.enabled
|
||||||
|
@filter_fields = filter_fields(@categories, @tags)
|
||||||
|
@custom_bulletins = CustomBulletin.where(:title.ne => "",:is_preview.in=>[false,nil])
|
||||||
|
.order_by(sort)
|
||||||
|
.with_categories(filters("category"))
|
||||||
|
.with_tags(filters("tag"))
|
||||||
|
.with_status(filters("status"))
|
||||||
|
end
|
||||||
|
if params[:custom_module].present?
|
||||||
|
@custom_bulletins = @custom_bulletins.where(:custom_module=>params[:custom_module])
|
||||||
|
end
|
||||||
|
if params[:bind_uid].present?
|
||||||
|
@custom_bulletins = @custom_bulletins.where(:bind_uid=>params[:bind_uid])
|
||||||
|
end
|
||||||
|
@custom_bulletins = search_data(@custom_bulletins,[:title]).page(params[:page]).per(10)
|
||||||
|
|
||||||
|
if request.xhr?
|
||||||
|
render :partial => "index"
|
||||||
|
elsif params[:custom_module].blank? || params[:bind_uid].blank?
|
||||||
|
render "display_enable_modules"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def feed
|
||||||
|
@table_feed_fields = ["custom_announcement.feed_name", :tags, "custom_announcement.rssfeed", "custom_announcement.jsonfeed"]
|
||||||
|
@feeds = CustomBulletinFeed.all.asc(:created_at)
|
||||||
|
|
||||||
|
end
|
||||||
|
def generate_iframe_url
|
||||||
|
iframe_params = params.require(:iframe).permit!
|
||||||
|
uids = iframe_params['member_ids'].to_a.map{|m_id| MemberProfile.find(m_id).uid rescue nil}.select{|uid| !uid.nil?}
|
||||||
|
url_params = iframe_params.except(:member_ids)
|
||||||
|
url_params['uids'] = uids if uids != []
|
||||||
|
render :text => '/xhr/panel/custom_announcement/widget/sync_data?'+url_params.to_param
|
||||||
|
end
|
||||||
|
def settings
|
||||||
|
@setting = @custom_announcement_setting
|
||||||
|
roles = Role.all
|
||||||
|
@sorted_members = roles.inject({}) do |members,role|
|
||||||
|
members_for_role = role.member_profiles.select{|m| (m.user.nil? ? false : m.user.approved)}
|
||||||
|
members[role] = members_for_role
|
||||||
|
members
|
||||||
|
end
|
||||||
|
@sorted_members['no_role'] = MemberProfile.any_in(:role_ids=>[nil,[]]).select{|m| (m.user.nil? ? false : m.user.approved)}
|
||||||
|
@unapproved_members = User.where(:approved => false).map{|u| u.member_profile}
|
||||||
|
end
|
||||||
|
|
||||||
|
def import
|
||||||
|
end
|
||||||
|
|
||||||
|
def excel_format
|
||||||
|
respond_to do |format|
|
||||||
|
format.xlsx {
|
||||||
|
response.headers['Content-Disposition'] = 'attachment; filename="custom_announcement_import_format.xlsx"'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def export_excel
|
||||||
|
@custom_announcements = CustomBulletin.all.desc(:created_at)
|
||||||
|
respond_to do |format|
|
||||||
|
format.xlsx {
|
||||||
|
response.headers['Content-Disposition'] = 'attachment; filename="custom_announcement_export.xlsx"'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_from_xml
|
||||||
|
download_tmp_xml params["import_xml"]
|
||||||
|
import_from_tmp_xml File.read(File.join(Rails.root, "tmp", "ann_cc_ntu.xml"))
|
||||||
|
redirect_to admin_custom_announcements_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def import
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def import_from_wp
|
||||||
|
import_from_wordpress params["import_xml"].tempfile
|
||||||
|
redirect_to admin_custom_announcements_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def importcustom_anns
|
||||||
|
workbook = RubyXL::Parser.parse(params["import_file"].tempfile)
|
||||||
|
categories = @module_app.categories.asc(:created_at).to_a
|
||||||
|
tags = @module_app.tags.asc(:created_at).to_a
|
||||||
|
sheet = workbook[0]
|
||||||
|
if sheet.count <= 503
|
||||||
|
sheet.each_with_index do |row, i|
|
||||||
|
next if i < 3
|
||||||
|
v = row.cells.first.value rescue nil
|
||||||
|
next if v.blank?
|
||||||
|
import_this_custom_announcement(row, categories, tags)
|
||||||
|
end
|
||||||
|
redirect_to admin_custom_announcements_path
|
||||||
|
else
|
||||||
|
redirect_to admin_custom_announcements_path(:error => "1")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def createsettings
|
||||||
|
setting = CustomAnnouncementSetting.new(settings_params)
|
||||||
|
setting.save
|
||||||
|
redirect_to admin_custom_announcement_settings_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def updatesettings
|
||||||
|
setting = @custom_announcement_setting
|
||||||
|
ids = params['custom_announcement_setting']['custom_anns_status_settings'].to_a.collect do |i,v|
|
||||||
|
v['_id']
|
||||||
|
end.compact
|
||||||
|
CustomAnnsStatusSetting.where(:id.nin=>ids).destroy
|
||||||
|
setting.update_attributes(settings_params)
|
||||||
|
setting.save
|
||||||
|
redirect_to admin_custom_announcement_settings_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def feedform
|
||||||
|
if params[:type] == "new"
|
||||||
|
@custom_announcement_feed = CustomBulletinFeed.new
|
||||||
|
render :partial => "feed_form"
|
||||||
|
else params[:type] == "edit"
|
||||||
|
@custom_announcement_feed = CustomBulletinFeed.find(params[:id])
|
||||||
|
render :partial => "edit_feed_form"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def createfeed
|
||||||
|
custom_announcement_feed = CustomBulletinFeed.new(feed_params)
|
||||||
|
custom_announcement_feed.save
|
||||||
|
create_feed_cache(nil,custom_announcement_feed)
|
||||||
|
feeds = CustomBulletinFeed.all.asc(:created_at)
|
||||||
|
render :partial => "feed", :collection => feeds
|
||||||
|
end
|
||||||
|
|
||||||
|
def updatefeed
|
||||||
|
ann_feed = CustomBulletinFeed.find(params[:id])
|
||||||
|
ann_feed.update_attributes(feed_params)
|
||||||
|
ann_feed.save
|
||||||
|
create_feed_cache(nil,ann_feed)
|
||||||
|
feeds = CustomBulletinFeed.all.asc(:created_at)
|
||||||
|
render :partial => "feed", :collection => feeds
|
||||||
|
end
|
||||||
|
|
||||||
|
def deletefeed
|
||||||
|
ann_feed = CustomBulletinFeed.find(params[:id])
|
||||||
|
ann_feed.destroy
|
||||||
|
feeds = CustomBulletinFeed.all.asc(:created_at)
|
||||||
|
render :partial => "feed", :collection => feeds
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@tags = @module_app.tags
|
||||||
|
@statuses = []
|
||||||
|
@custom_bulletin = CustomBulletin.new
|
||||||
|
@custom_bulletin.email_sentdate = Time.now
|
||||||
|
@reach_limit = @custom_bulletin.check_status_limit(current_user,true)
|
||||||
|
if defined? Calendar
|
||||||
|
categories = user_authenticated_categories rescue ['all']
|
||||||
|
if categories.first == "all"
|
||||||
|
@calendar_categories = CalendarType.all
|
||||||
|
else
|
||||||
|
@calendar_categories = CalendarType.where(:category_id.in => categories) rescue []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
bps = custom_bulletin_params
|
||||||
|
custom_bulletin = CustomBulletin.new(bps)
|
||||||
|
if !bps['custom_bulletin_links_attributes'].nil?
|
||||||
|
bps['custom_bulletin_links_attributes'].each do |idx,link|
|
||||||
|
bps['custom_bulletin_links_attributes'].delete(idx.to_s) if link['url'].blank?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if((!CustomAnnouncementSetting.first.only_manager_can_edit_status) || (CustomAnnouncementSetting.first.only_manager_can_edit_status && (@current_user.is_admin? || @current_user.is_manager?(@module_app))) )
|
||||||
|
if bps[:is_top] == "1" && !CustomAnnouncementSetting.check_limit_for_user(custom_bulletin.create_user_id, custom_bulletin.id)
|
||||||
|
bps[:is_top] = "0"
|
||||||
|
bps[:top_end_date] = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
bps[:is_top] = false
|
||||||
|
bps[:is_hot] = false
|
||||||
|
bps[:is_hidden] = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if !defined?(Calendar).nil?
|
||||||
|
bps = update_calendar(bps,custom_bulletin)
|
||||||
|
end
|
||||||
|
custom_bulletin.create_user_id = current_user.id
|
||||||
|
custom_bulletin.update_user_id = current_user.id
|
||||||
|
if CustomAnnouncementSetting.is_pro?
|
||||||
|
if user_can_approve?
|
||||||
|
custom_bulletin.approved = true
|
||||||
|
else
|
||||||
|
send_notification_mail_to_managers(custom_bulletin,"approval",I18n.locale)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
custom_bulletin.approved = true
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_bulletin.save
|
||||||
|
build_email(custom_bulletin,I18n.locale)
|
||||||
|
create_feed_cache(custom_bulletin)
|
||||||
|
if bps[:custom_module].present?
|
||||||
|
redirect_to admin_custom_announcements_path + "/#{bps[:custom_module]}#{bps[:bind_uid].present? ? ('-'+bps[:bind_uid]) : ''}"
|
||||||
|
else
|
||||||
|
redirect_to admin_custom_announcements_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def approve_custom_bulletin
|
||||||
|
id = params[:id]
|
||||||
|
custom_bulletin = CustomBulletin.find(id)
|
||||||
|
if params["approved"] == "true"
|
||||||
|
custom_bulletin.approved = true
|
||||||
|
custom_bulletin.rejected = false
|
||||||
|
custom_bulletin.reapproval = false
|
||||||
|
else
|
||||||
|
custom_bulletin.rejected = true
|
||||||
|
custom_bulletin.reapproval = false
|
||||||
|
custom_bulletin.rejection_reason = params["reason"]
|
||||||
|
send_rejection_email(custom_bulletin,I18n.locale)
|
||||||
|
end
|
||||||
|
custom_bulletin.save
|
||||||
|
create_feed_cache(custom_bulletin)
|
||||||
|
redirect_to admin_custom_announcements_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
if can_edit_or_delete?(@custom_bulletin)
|
||||||
|
@reach_limit = @custom_bulletin.check_status_limit(current_user,true)
|
||||||
|
@tags = @module_app.tags
|
||||||
|
@categories = @module_app.categories.enabled
|
||||||
|
if defined? Calendar
|
||||||
|
categories = user_authenticated_categories rescue ['all']
|
||||||
|
if categories.first == "all"
|
||||||
|
@calendar_categories = CalendarType.all
|
||||||
|
else
|
||||||
|
@calendar_categories = CalendarType.where(:category_id.in => categories) rescue []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@statuses = []
|
||||||
|
@custom_bulletin.email_sentdate = Time.now if @custom_bulletin.email_sent == false
|
||||||
|
else
|
||||||
|
render_401
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
uid = params[:id].split('-').last
|
||||||
|
custom_bulletin = CustomBulletin.find_by(:uid=>uid)
|
||||||
|
bps = custom_bulletin_params
|
||||||
|
bps[:tags] = bps[:tags].blank? ? [] : bps[:tags]
|
||||||
|
bps[:email_member_ids] = bps[:email_member_ids].blank? ? [] : bps[:email_member_ids]
|
||||||
|
|
||||||
|
if !bps['custom_bulletin_links_attributes'].nil?
|
||||||
|
bps['custom_bulletin_links_attributes'].each do |idx,link|
|
||||||
|
bps['custom_bulletin_links_attributes'].delete(idx.to_s) if link['url'].blank?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if((!CustomAnnouncementSetting.first.only_manager_can_edit_status) || (CustomAnnouncementSetting.first.only_manager_can_edit_status && (@current_user.is_admin? || @current_user.is_manager?(@module_app))) )
|
||||||
|
if bps[:is_top] == "1" && !CustomAnnouncementSetting.check_limit_for_user(custom_bulletin.create_user_id, custom_bulletin.id)
|
||||||
|
bps[:is_top] = "0"
|
||||||
|
bps[:top_end_date] = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
bps[:is_top] = custom_bulletin.is_top
|
||||||
|
bps[:is_hot] = custom_bulletin.is_hot
|
||||||
|
bps[:is_hidden] = custom_bulletin.is_hidden
|
||||||
|
end
|
||||||
|
if !defined?(Calendar).nil?
|
||||||
|
bps = update_calendar(bps,custom_bulletin)
|
||||||
|
end
|
||||||
|
custom_bulletin.update_attributes(bps)
|
||||||
|
custom_bulletin.update_user_id = current_user.id
|
||||||
|
if custom_bulletin.rejected
|
||||||
|
custom_bulletin.reapproval = true
|
||||||
|
custom_bulletin.save
|
||||||
|
send_notification_mail_to_managers(custom_bulletin,"reapproval",I18n.locale)
|
||||||
|
else
|
||||||
|
custom_bulletin.save
|
||||||
|
end
|
||||||
|
build_email(custom_bulletin,I18n.locale)
|
||||||
|
create_feed_cache(custom_bulletin)
|
||||||
|
custom_module = custom_bulletin.custom_module
|
||||||
|
now_custom_bulletin_page = CustomBulletin.where(:custom_module=>custom_module,:title.ne => "",:is_preview.in=>[false,nil])
|
||||||
|
.order_by(sort).map(&:id).map.with_index.select{|v,i| v==custom_bulletin.id}[0][1] rescue nil
|
||||||
|
now_custom_bulletin_page = now_custom_bulletin_page.nil? ? 0 : ((now_custom_bulletin_page+1).to_f/10).ceil
|
||||||
|
bind_uid = custom_bulletin.bind_uid
|
||||||
|
if custom_module.present?
|
||||||
|
redirect_to admin_custom_announcements_path + "/#{custom_module}#{bind_uid.present? ? ('-'+bind_uid) : ''}?page=#{now_custom_bulletin_page}"
|
||||||
|
else
|
||||||
|
redirect_to admin_custom_announcements_path(:page=>now_custom_bulletin_page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
custom_module = @custom_bulletin.custom_module
|
||||||
|
bind_uid = @custom_bulletin.bind_uid
|
||||||
|
@custom_bulletin.destroy
|
||||||
|
if custom_module.present?
|
||||||
|
redirect_to admin_custom_announcements_path + "/#{custom_module}#{bind_uid.present? ? ('-'+bind_uid) : ''}"
|
||||||
|
else
|
||||||
|
redirect_to admin_custom_announcements_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete
|
||||||
|
if params[:ids]
|
||||||
|
CustomBulletin.any_in(:uid => params[:ids]).destroy_all
|
||||||
|
end
|
||||||
|
redirect_to admin_custom_announcements_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def preview
|
||||||
|
if params['preview_type'].eql?('edit')
|
||||||
|
custom_bulletin_data = custom_bulletin_params
|
||||||
|
org_custom_bulletin = CustomBulletin.find(params['custom_bulletin_id'])
|
||||||
|
custom_bulletin = org_custom_bulletin.clone
|
||||||
|
custom_bulletin.generate_uid
|
||||||
|
custom_bulletin.custom_bulletin_files = []
|
||||||
|
custom_bulletin.custom_bulletin_links = []
|
||||||
|
if custom_bulletin_data['image'].blank?
|
||||||
|
custom_bulletin.image = org_custom_bulletin.image
|
||||||
|
end
|
||||||
|
|
||||||
|
if !custom_bulletin_data['custom_bulletin_files_attributes'].blank?
|
||||||
|
custom_bulletin_data['custom_bulletin_files_attributes'].each do |key, custom_bulletin_file|
|
||||||
|
next if !custom_bulletin_file['_destroy'].blank?
|
||||||
|
file = nil
|
||||||
|
if custom_bulletin_file['id'].blank?
|
||||||
|
file = CustomBulletinFile.new(custom_bulletin_file)
|
||||||
|
file.custom_bulletin_id = custom_bulletin.id
|
||||||
|
file.save
|
||||||
|
else
|
||||||
|
org_file = CustomBulletinFile.find(custom_bulletin_file['id'])
|
||||||
|
file = org_file.clone
|
||||||
|
file.custom_bulletin_id = custom_bulletin.id
|
||||||
|
file.file = org_file.file
|
||||||
|
custom_bulletin_file.delete('id')
|
||||||
|
custom_bulletin_file.delete('_destroy')
|
||||||
|
file.update_attributes(custom_bulletin_file)
|
||||||
|
end
|
||||||
|
|
||||||
|
file.save
|
||||||
|
custom_bulletin.custom_bulletin_files << file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if !custom_bulletin_data['custom_bulletin_links_attributes'].blank?
|
||||||
|
custom_bulletin_data['custom_bulletin_links_attributes'].each do |key, custom_bulletin_link|
|
||||||
|
next if !custom_bulletin_link['_destroy'].blank?
|
||||||
|
|
||||||
|
if custom_bulletin_link['id'].blank?
|
||||||
|
link = CustomBulletinLink.new(custom_bulletin_link)
|
||||||
|
link.custom_bulletin_id = custom_bulletin.id
|
||||||
|
else
|
||||||
|
link = CustomBulletinLink.find(custom_bulletin_link['id']).clone
|
||||||
|
link.custom_bulletin_id = custom_bulletin.id
|
||||||
|
custom_bulletin_link.delete('id')
|
||||||
|
custom_bulletin_link.delete('_destroy')
|
||||||
|
link.update_attributes(custom_bulletin_link)
|
||||||
|
end
|
||||||
|
|
||||||
|
link.save
|
||||||
|
custom_bulletin.custom_bulletin_links << link
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_bulletin_data.delete('custom_bulletin_files_attributes')
|
||||||
|
custom_bulletin_data.delete('custom_bulletin_links_attributes')
|
||||||
|
custom_bulletin.update_attributes(custom_bulletin_data)
|
||||||
|
else
|
||||||
|
custom_bulletin = CustomBulletin.new(custom_bulletin_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_bulletin.is_preview = true
|
||||||
|
custom_bulletin.save
|
||||||
|
create_feed_cache(custom_bulletin)
|
||||||
|
render :text=>page_for_custom_bulletin(custom_bulletin) + "?preview=true"
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_preview
|
||||||
|
custom_bulletin = CustomBulletin.find_by(:uid=>params['uid'])
|
||||||
|
if custom_bulletin.is_preview
|
||||||
|
custom_bulletin.destroy
|
||||||
|
end
|
||||||
|
render :json=>{'destroy'=>custom_bulletin.id.to_s}
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_email(custom_bulletin,locale)
|
||||||
|
if custom_bulletin.email_sent and !custom_bulletin.email_addresses.blank?
|
||||||
|
if custom_bulletin.email.nil?
|
||||||
|
email = Email.new
|
||||||
|
email.save
|
||||||
|
email.deliver rescue nil
|
||||||
|
custom_bulletin.email_id = email.id
|
||||||
|
custom_bulletin.save
|
||||||
|
end
|
||||||
|
|
||||||
|
is_sent = custom_bulletin.email.is_sent
|
||||||
|
is_sent = !params[:resend_mail].eql?("true") if !params[:resend_mail].blank?
|
||||||
|
doc = Nokogiri::HTML(custom_bulletin.title_translations[locale])
|
||||||
|
title = doc.text.empty? ? 'no content' : doc.text
|
||||||
|
|
||||||
|
custom_bulletin.email.update_attributes(
|
||||||
|
:create_user=>current_user,
|
||||||
|
:mail_sentdate=>custom_bulletin.email_sentdate,
|
||||||
|
:module_app=>@module_app,
|
||||||
|
:mail_lang => locale,
|
||||||
|
:mail_to=>custom_bulletin.email_addresses,
|
||||||
|
:mail_subject=>title,
|
||||||
|
:template=>'custom_announcements/email',
|
||||||
|
:template_data=>{
|
||||||
|
"host" => request.host_with_port,
|
||||||
|
"title" => title,
|
||||||
|
"url" => page_for_custom_bulletin(custom_bulletin)
|
||||||
|
},
|
||||||
|
:is_sent=>is_sent
|
||||||
|
)
|
||||||
|
custom_bulletin.email.deliver
|
||||||
|
else
|
||||||
|
custom_bulletin.email.destroy if !custom_bulletin.email.nil?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_settings
|
||||||
|
@custom_announcement_setting = CustomAnnouncementSetting.first rescue nil
|
||||||
|
if @custom_announcement_setting.nil?
|
||||||
|
@custom_announcement_setting = CustomAnnouncementSetting.create
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_custom_bulletin
|
||||||
|
@custom_bulletin = CustomBulletin.find(params[:id])
|
||||||
|
end
|
||||||
|
def custom_bulletin_config_params
|
||||||
|
params.require(:custom_bulletin_config).permit!
|
||||||
|
end
|
||||||
|
def custom_bulletin_params
|
||||||
|
params[:custom_bulletin][:email_sent] = params[:custom_bulletin][:email_sent].nil? ? 0 : params[:custom_bulletin][:email_sent]
|
||||||
|
params.require(:custom_bulletin).permit!
|
||||||
|
end
|
||||||
|
|
||||||
|
def feed_params
|
||||||
|
params.require(:custom_bulletin_feed).permit!
|
||||||
|
end
|
||||||
|
|
||||||
|
def settings_params
|
||||||
|
params.require(:custom_announcement_setting).permit!
|
||||||
|
end
|
||||||
|
def update_calendar(bps,custom_bulletin)
|
||||||
|
if bps[:add_to_calendar] == '0' && !bps[:event_id].blank?
|
||||||
|
Event.find(bps[:event_id]).destroy rescue nil
|
||||||
|
bps[:event_id] = nil
|
||||||
|
elsif bps[:add_to_calendar] == '1'
|
||||||
|
event = Event.find(bps[:event_id]) rescue Event.new(create_user_id: current_user.id)
|
||||||
|
e_start = bps[:calendar_start_date].blank? ? bps[:postdate] : bps[:calendar_start_date]
|
||||||
|
e_start = Time.now.to_datetime if e_start.blank?
|
||||||
|
e_end = bps[:calendar_end_date].blank? ? bps[:deadline] : bps[:calendar_end_date]
|
||||||
|
#e_end = Time.now.to_datetime + 1.year if e_end.blank?
|
||||||
|
event.update_attributes(model_class: 'CustomBulletin',
|
||||||
|
module_key: 'custom_announcement',
|
||||||
|
model_cat: bps[:category_id],
|
||||||
|
model_tags: bps[:tags],
|
||||||
|
model_page_id: bps[:page_id],
|
||||||
|
model_id: custom_bulletin.id,start: e_start,
|
||||||
|
end: e_end,update_user_id: current_user.id,
|
||||||
|
all_day: bps[:calendar_all_day],
|
||||||
|
calendar_type_id: bps[:calendar_type_id],
|
||||||
|
title_translations: bps[:title_translations],
|
||||||
|
note_translations: bps[:subtitle_translations])
|
||||||
|
bps[:event_id] = event.id
|
||||||
|
end
|
||||||
|
bps
|
||||||
|
end
|
||||||
|
def create_feed_cache(custom_bulletin=nil,custom_bulletin_feed=nil)
|
||||||
|
if !custom_bulletin.nil?
|
||||||
|
CustomBulletinFeed.where(:tag_ids.in => Array(custom_bulletin.tag_ids).collect{|v| v.to_s}).each do |custom_bulletin_feed|
|
||||||
|
uid = custom_bulletin_feed.uid
|
||||||
|
uri = URI(request.protocol + request.host_with_port + "/xhr/custom_announcements/feed/#{uid}.json")
|
||||||
|
Thread.new do
|
||||||
|
res_net = Net::HTTP.start(uri.host, uri.port,:use_ssl => uri.scheme == 'https',open_timeout: 60,read_timeout: 60) do |http|
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif !custom_bulletin_feed.nil?
|
||||||
|
uid = custom_bulletin_feed.uid
|
||||||
|
uri = URI(request.protocol + request.host_with_port + "/xhr/custom_announcements/feed/#{uid}.json")
|
||||||
|
Thread.new do
|
||||||
|
res_net = Net::HTTP.start(uri.host, uri.port,:use_ssl => uri.scheme == 'https',open_timeout: 60,read_timeout: 60) do |http|
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,159 @@
|
||||||
|
require "rss"
|
||||||
|
class CustomAnnouncementFeedsController < ApplicationController
|
||||||
|
include Admin::CustomAnnouncementsHelper
|
||||||
|
def feed
|
||||||
|
uid = params[:uid]
|
||||||
|
feed_cache = CustomBulletinFeedCache.where(uid: uid).first
|
||||||
|
custom_anns = ''
|
||||||
|
if feed_cache.nil?
|
||||||
|
CustomBulletinFeedCache.create(uid: uid,content: '')
|
||||||
|
Thread.new do
|
||||||
|
custom_anns = get_custom_announcements(uid).to_json
|
||||||
|
feed_cache = CustomBulletinFeedCache.where(uid: uid).first
|
||||||
|
if !feed_cache.nil?
|
||||||
|
feed_cache.update_attributes(content: custom_anns)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
custom_anns = feed_cache.content
|
||||||
|
end
|
||||||
|
render :json => custom_anns
|
||||||
|
end
|
||||||
|
|
||||||
|
def rssfeed
|
||||||
|
uid = params[:uid]
|
||||||
|
@bf = CustomBulletinFeed.find_by(:uid => uid) rescue nil
|
||||||
|
if !@bf.nil?
|
||||||
|
tags = @bf.tag_ids
|
||||||
|
if !tags.empty?
|
||||||
|
@custom_announcements = CustomBulletin.can_display_and_sorted.is_approved.filter_by_tags(tags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
respond_to do |format|
|
||||||
|
format.html {redirect_to "/xhr/custom_announcements/rssfeed/#{@bf.uid}.rss"}
|
||||||
|
format.rss
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def feeds
|
||||||
|
feeds = []
|
||||||
|
CustomBulletinFeed.all.each do |bf|
|
||||||
|
feed = {}
|
||||||
|
feed["title_translations"] = bf.title_translations
|
||||||
|
feed["uid"] = bf.uid
|
||||||
|
feed["url"] = "#{request.base_url}/xhr/custom_announcements/feed/#{bf.uid}"
|
||||||
|
feed["xml_url"] = "#{request.base_url}/xhr/custom_announcements/rssfeed/#{bf.uid}.rss"
|
||||||
|
feed["tags"] = []
|
||||||
|
bf.tag_ids.each do |t|
|
||||||
|
tag = Tag.find(t)
|
||||||
|
d = {}
|
||||||
|
d["name_translations"] = tag.name_translations
|
||||||
|
feed["tags"] << d
|
||||||
|
end
|
||||||
|
feeds << feed
|
||||||
|
end
|
||||||
|
render :json => {"feeds" => feeds}.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def smart_convertor(text)
|
||||||
|
html_string = text
|
||||||
|
url = request.protocol + request.host_with_port
|
||||||
|
html_string = html_string.gsub(/img.*?src="(?=\/)(.*?)|a.*?href="(?=\/)(.*?)/i){|w| w+url}
|
||||||
|
html_string = html_string.gsub(/img.*?src="\.\.(?=\/)(.*?)|a.*?href="\.\.(?=\/)(.*?)/i){|w| w[0...-2]+url}
|
||||||
|
return html_string
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_custom_announcements(uid)
|
||||||
|
bf = CustomBulletinFeed.find_by(:uid => uid) rescue nil
|
||||||
|
startdt = params[:start]
|
||||||
|
enddt = params[:end]
|
||||||
|
dt = params[:date]
|
||||||
|
if !bf.nil?
|
||||||
|
tags = bf.tag_ids
|
||||||
|
if !tags.empty?
|
||||||
|
if !dt.nil?
|
||||||
|
dt = DateTime.parse(dt)
|
||||||
|
dtt = dt + 1.day
|
||||||
|
custom_announcements = CustomBulletin.where(:postdate.gt => dt, :postdate.lt => dtt).can_display_and_sorted.is_approved.filter_by_tags(tags)
|
||||||
|
elsif !startdt.nil? && enddt.nil?
|
||||||
|
startdt = DateTime.parse(startdt)
|
||||||
|
enddt = DateTime.now
|
||||||
|
custom_announcements = CustomBulletin.where(:postdate.gt => startdt, :postdate.lt => enddt).can_display_and_sorted.is_approved.filter_by_tags(tags)
|
||||||
|
elsif !startdt.nil? && !enddt.nil?
|
||||||
|
startdt = DateTime.parse(startdt)
|
||||||
|
enddt = DateTime.parse(enddt) + 1.day
|
||||||
|
custom_announcements = CustomBulletin.where(:postdate.gt => startdt, :postdate.lt => enddt).can_display_and_sorted.is_approved.filter_by_tags(tags)
|
||||||
|
else
|
||||||
|
custom_announcements = CustomBulletin.all.can_display_and_sorted.is_approved.filter_by_tags(tags)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
custom_announcements = []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
all_custom_anns = []
|
||||||
|
tag_names = []
|
||||||
|
tag_ids = []
|
||||||
|
custom_announcements.each do |custom_anns|
|
||||||
|
user = User.find(custom_anns.create_user_id) rescue nil
|
||||||
|
if !user.nil?
|
||||||
|
author = user.member_profile && user.member_profile.name == "" ? user.user_name : user.member_profile.name
|
||||||
|
else
|
||||||
|
author = ""
|
||||||
|
end
|
||||||
|
a = {}
|
||||||
|
a["id"] = custom_anns.uid
|
||||||
|
a["title_translations"] = custom_anns.title_translations
|
||||||
|
a["subtitle_translations"] = custom_anns.subtitle_translations
|
||||||
|
a["text_translations"] = {}
|
||||||
|
a["text_translations"]["en"] = smart_convertor(custom_anns.text_translations["en"]) if !custom_anns.text_translations["en"].blank?
|
||||||
|
a["text_translations"]["zh_tw"] = smart_convertor(custom_anns.text_translations["zh_tw"]) if !custom_anns.text_translations["zh_tw"].blank?
|
||||||
|
a["postdate"] = custom_anns.postdate
|
||||||
|
a["image_description_translations"] = custom_anns.image_description_translations
|
||||||
|
a["image"] = {}
|
||||||
|
a["display_img"] = custom_anns.display_img
|
||||||
|
a["image"]["original"] = ("#{request.base_url}" + custom_anns.image.url rescue "")
|
||||||
|
a["image"]["thumb"] = ("#{request.base_url}" + custom_anns.image.thumb.url rescue "")
|
||||||
|
a["image"]["mobile"] = ("#{request.base_url}" + custom_anns.image.mobile.url rescue "")
|
||||||
|
a["tags"] = []
|
||||||
|
a["author"] = author
|
||||||
|
a["params"] = custom_anns.to_param
|
||||||
|
a["subtitle_ann"] = custom_anns.subtitle if custom_anns.display_subtitle?
|
||||||
|
a["custom_bulletin_links"] = []
|
||||||
|
a["custom_bulletin_files"] = []
|
||||||
|
a["custom_bulletin_carousel_images"] = custom_anns.custom_bulletin_carousel_images.map{|image| {"src"=>"#{request.base_url}" + image.file.url,"description"=>image.description.to_s,"description_text"=>image.description_text }}
|
||||||
|
custom_anns.tags.each do |tag|
|
||||||
|
if !tag_ids.include?(tag.id.to_s)
|
||||||
|
tag_ids << tag.id.to_s
|
||||||
|
tag_names << {"name_translations" => tag.name_translations}
|
||||||
|
end
|
||||||
|
a["tags"] << {"name_translations" => tag.name_translations}
|
||||||
|
end
|
||||||
|
custom_anns.custom_bulletin_links.each do |bl|
|
||||||
|
b = {}
|
||||||
|
b["url"] = bl.url
|
||||||
|
b["title_translations"] = bl.title_translations
|
||||||
|
a["custom_bulletin_links"] << b
|
||||||
|
end
|
||||||
|
custom_anns.custom_bulletin_files.each do |bf|
|
||||||
|
b = {}
|
||||||
|
b["description_translations"] = bf.description_translations
|
||||||
|
b["title_translations"] = bf.title_translations
|
||||||
|
b["url"] = ("#{request.base_url}" + bf.file.url rescue "")
|
||||||
|
a["custom_bulletin_files"] << b
|
||||||
|
end
|
||||||
|
all_custom_anns << a
|
||||||
|
end
|
||||||
|
{
|
||||||
|
"custom_announcements" => all_custom_anns,
|
||||||
|
"tags" => tag_names
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,809 @@
|
||||||
|
class CustomAnnouncementsController < ApplicationController
|
||||||
|
include CustomAnnouncementsHelper
|
||||||
|
def comment
|
||||||
|
@custom_bulletin = CustomBulletin.where(:uid=>params[:uid]).first
|
||||||
|
comment_val = params['comment']
|
||||||
|
if !@custom_bulletin.nil? && @custom_bulletin.open_comment_for_user(OrbitHelper.current_user) && !comment_val.blank?
|
||||||
|
account_id = OrbitHelper.current_user.member_profile.id.to_s rescue 'visitor'
|
||||||
|
b = CustomBulletinComment.new(ip: request.remote_ip,comment: comment_val,account_id: account_id)
|
||||||
|
b.custom_bulletin_id = @custom_bulletin.id
|
||||||
|
b.save
|
||||||
|
render :json => {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def index
|
||||||
|
CustomBulletin.remove_expired_status
|
||||||
|
sorted,total_pages = get_sorted_annc
|
||||||
|
sorted = [] if sorted.nil?
|
||||||
|
custom_anns = sorted.collect do |a|
|
||||||
|
if a["source-site"].blank?
|
||||||
|
statuses = a.statuses_with_classname.collect do |status|
|
||||||
|
{
|
||||||
|
"status" => status["name"],
|
||||||
|
"status-class" => "status-#{status['classname']}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
locale = OrbitHelper.get_site_locale.to_s
|
||||||
|
files = a.custom_bulletin_files.map{|file| { "file_url" => file.file.url + "\" title=\"#{file.file_title}", "file_title" => (file.title.blank? ? File.basename(file.file.path) : file.title rescue '') } if file.enabled_for?(locale) } rescue []
|
||||||
|
files.delete(nil)
|
||||||
|
links = a.custom_bulletin_links.map{|link| { "link_url" => link.url, "link_title" => (link.title.blank? ? link.url : link.title) } } rescue []
|
||||||
|
author = User.find(a.create_user_id).member_profile.name rescue ""
|
||||||
|
desc = a.image_description
|
||||||
|
desc = (desc.blank? ? "custom_announcement image" : desc)
|
||||||
|
link_to_show = a.is_external_link ? a.external_link : OrbitHelper.url_to_show(a.to_param)
|
||||||
|
target = a.is_external_link ? "_blank" : "_self"
|
||||||
|
doc = Nokogiri::HTML(a.title)
|
||||||
|
title = doc.text.empty? ? 'no content' : doc.text
|
||||||
|
{
|
||||||
|
"department" => author,
|
||||||
|
"custom_bulletin_links" => links,
|
||||||
|
"custom_bulletin_files" => files,
|
||||||
|
"title" => a.title,
|
||||||
|
"source-site" => "",
|
||||||
|
"source-site-title" => "",
|
||||||
|
"source-site-link" => "",
|
||||||
|
"subtitle" => a.subtitle,
|
||||||
|
"statuses" => statuses,
|
||||||
|
"category" => (a.category.title rescue ''),
|
||||||
|
"postdate" => a.postdate,
|
||||||
|
"author" => author,
|
||||||
|
"is_top" => (a.is_top? ? 1 : 0),
|
||||||
|
"link_to_show" => link_to_show+"\" title=\"#{title}\"",
|
||||||
|
"target" => target,
|
||||||
|
"img_src" => a.image.thumb.url || "/assets/custom_announcement-default.jpg",
|
||||||
|
"img_description" => desc,
|
||||||
|
"more" => t(:more_plus),
|
||||||
|
"view_count" => a.view_count
|
||||||
|
}
|
||||||
|
else
|
||||||
|
a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
#If no data , hide title&table
|
||||||
|
if sorted.count == 0
|
||||||
|
display = "hide"
|
||||||
|
end
|
||||||
|
# custom_anns = custom_anns.concat(feeds_custom_anns)
|
||||||
|
# total_pages = custom_announcements.total_pages
|
||||||
|
params = OrbitHelper.params
|
||||||
|
page = Page.where(url:params['url']).first
|
||||||
|
@annc_page_title = nil
|
||||||
|
if (params['category'] != page.categories rescue true)
|
||||||
|
@annc_page_title = Category.find(Array(params['category']).first).title rescue nil
|
||||||
|
end
|
||||||
|
if (params["tags"] != page.tags && !params["tags"].blank? && params["tags"].count == 1 && params["tags"][0] != "all" rescue true)
|
||||||
|
@annc_page_title = Tag.find(Array(params['tags']).first).name rescue nil
|
||||||
|
end
|
||||||
|
{
|
||||||
|
"custom_announcements" => custom_anns,
|
||||||
|
"extras" => {
|
||||||
|
"widget-title" =>t('custom_announcement.custom_announcement'),
|
||||||
|
"title-head" => t('custom_announcement.table.title'),
|
||||||
|
"date-head" => t('custom_announcement.table.date'),
|
||||||
|
"status-head" => t('custom_announcement.table.status'),
|
||||||
|
"author-head" => t('custom_announcement.table.author'),
|
||||||
|
"subtitle-head" => t('custom_announcement.table.sub_title'),
|
||||||
|
"category-head" => t('custom_announcement.table.category'),
|
||||||
|
"link-head" => t('custom_announcement.table.link'),
|
||||||
|
"file-head" => t('custom_announcement.table.file'),
|
||||||
|
"view-count-head" => t('custom_announcement.table.view_count'),
|
||||||
|
"display" => display,
|
||||||
|
"department-head" => t('custom_announcement.table.department'),
|
||||||
|
"page-title" => @annc_page_title
|
||||||
|
},
|
||||||
|
"total_pages" => total_pages
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
||||||
|
def self.custom_widget_data
|
||||||
|
@custom_configs = CustomBulletinConfig.all.to_a
|
||||||
|
ac = ActionController::Base.new
|
||||||
|
ac.render_to_string("custom_announcements/custom_widget_data",:locals=>{:@custom_data_field=>@custom_data_field,:@custom_configs=>@custom_configs,:@field_name=>@field_name})
|
||||||
|
end
|
||||||
|
def random_custom_announcement_widget
|
||||||
|
pack_data(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def widget
|
||||||
|
pack_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_cloud
|
||||||
|
ma = ModuleApp.where(:key => "custom_announcement").first
|
||||||
|
temp = []
|
||||||
|
ma.tags.each do |tag|
|
||||||
|
t1 = tag.taggings.collect{|t| t.taggable_id.to_s}
|
||||||
|
count = CustomBulletin.where(:id.in => t1).can_display_and_sorted.count
|
||||||
|
temp << {
|
||||||
|
"tag-name" => tag.name,
|
||||||
|
"count" => count,
|
||||||
|
"tag-url" => OrbitHelper.widget_more_url + "?tags[]=" + tag.id.to_s
|
||||||
|
}
|
||||||
|
end
|
||||||
|
max = temp.max_by{|t| t["count"]}["count"]
|
||||||
|
tags = []
|
||||||
|
temp.each do |tag|
|
||||||
|
if tag["count"] > 0
|
||||||
|
percent = (tag["count"] * 100) / max
|
||||||
|
font_size = ((percent / 10).round) + 16
|
||||||
|
tag["font-size"] = font_size
|
||||||
|
tags << tag
|
||||||
|
end
|
||||||
|
end
|
||||||
|
{
|
||||||
|
"tags" => tags,
|
||||||
|
"extras" => {}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def pack_data(is_random=false)
|
||||||
|
cats = OrbitHelper.widget_categories || []
|
||||||
|
tags = OrbitHelper.widget_tags || []
|
||||||
|
subpart = OrbitHelper.get_current_widget
|
||||||
|
custom_data_field = subpart.custom_data_field
|
||||||
|
get_tabs_option
|
||||||
|
custom_anns = []
|
||||||
|
use_tag = false
|
||||||
|
if @tab_option == 0
|
||||||
|
custom_anns = get_anncs_for_pack_data(cats,tags,nil,is_random)
|
||||||
|
else
|
||||||
|
if cats.count != 1 || tags == ["all"]
|
||||||
|
cats.each do |cat|
|
||||||
|
custom_anns = custom_anns + get_anncs_for_pack_data([cat],tags,'')
|
||||||
|
end
|
||||||
|
else
|
||||||
|
tags.each do |tag|
|
||||||
|
custom_anns = custom_anns + get_anncs_for_pack_data(cats,[tag],tag)
|
||||||
|
end
|
||||||
|
use_tag = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
mp = (custom_anns[0]["img_src"] rescue "")
|
||||||
|
mpd = (custom_anns[0]["img_description"] rescue "")
|
||||||
|
if @tab_option == 1
|
||||||
|
if use_tag
|
||||||
|
tags = ["all"] + tags
|
||||||
|
else
|
||||||
|
cats = ["all"] + cats
|
||||||
|
end
|
||||||
|
custom_anns = custom_anns.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]}
|
||||||
|
end
|
||||||
|
cats = cats.uniq
|
||||||
|
tags = tags.uniq
|
||||||
|
tags_translations = tags.map{|tag_id|
|
||||||
|
if tag_id == "all"
|
||||||
|
t = I18n.t(:all)
|
||||||
|
else
|
||||||
|
t = Tag.find(tag_id).name rescue ""
|
||||||
|
end
|
||||||
|
[tag_id,t]
|
||||||
|
}.to_h
|
||||||
|
cats_translations = cats.map{|cat_id|
|
||||||
|
if cat_id == "all"
|
||||||
|
t = I18n.t(:all)
|
||||||
|
else
|
||||||
|
t = Category.find(cat_id).title rescue ""
|
||||||
|
end
|
||||||
|
[cat_id,t]
|
||||||
|
}.to_h
|
||||||
|
cats_relations = cats_translations.map{|cat_id,t|
|
||||||
|
if cat_id == "all"
|
||||||
|
t = "all"
|
||||||
|
end
|
||||||
|
[cat_id,t]
|
||||||
|
}.to_h
|
||||||
|
page = OrbitHelper.page.find_page(:page_id=> subpart.read_more_page_id).first rescue nil
|
||||||
|
page = OrbitHelper.page.find_page(:module => "custom_announcement").first rescue nil if page.nil?
|
||||||
|
all_cats = cats.dup
|
||||||
|
all_cats.delete "all"
|
||||||
|
if all_cats.count == 0
|
||||||
|
all_cats = ["all"]
|
||||||
|
end
|
||||||
|
all_tags = tags.dup
|
||||||
|
all_tags.delete "all"
|
||||||
|
if all_tags.count == 0
|
||||||
|
all_tags = ["all"]
|
||||||
|
end
|
||||||
|
max_all_count = [OrbitHelper.widget_data_count,custom_anns.count].min
|
||||||
|
if @tab_option != 0
|
||||||
|
OrbitHelper.set_widget_title(OrbitHelper.widget_title +
|
||||||
|
"<div style=\"clear: both;\"></div>" +
|
||||||
|
"<ul class=\"nav_tabs_filter\">" +
|
||||||
|
(use_tag ? tags.map.with_index{|tag,i|
|
||||||
|
read_more_url = "/#{I18n.locale.to_s + page.url}" rescue ""
|
||||||
|
read_more_url = read_more_url + "?" + {"category"=>all_cats,"tags"=>(tag == 'all' ? all_tags : [tag])}.to_param if read_more_url != ""
|
||||||
|
read_more_text = I18n.t("custom_announcement.more")
|
||||||
|
if tag != "all"
|
||||||
|
begin
|
||||||
|
read_more_text = I18n.t("custom_announcement.more_") + tags_translations[tag]
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
"<li class=\"filter_tab#{i == 0 ? ' active' : ''}\" #{(tag == 'all' && @all_setting_option == 0) ? "data-count_limit=\"#{max_all_count}\"" : ''} data-read_more_text=\"#{read_more_text}\" data-read_more=\"#{read_more_url}\" data-tags=\"#{tag}\">#{tags_translations[tag]}</li>"
|
||||||
|
}.join("") : cats.map.with_index{|cat,i|
|
||||||
|
read_more_url = "/#{I18n.locale.to_s + page.url}" rescue ""
|
||||||
|
read_more_url = read_more_url + "?" + {"category"=>(cat == 'all' ? all_cats : cat)}.to_param if read_more_url != ""
|
||||||
|
read_more_text = I18n.t("custom_announcement.more")
|
||||||
|
if cat != "all"
|
||||||
|
begin
|
||||||
|
read_more_text = I18n.t("custom_announcement.more_") + cats_translations[cat]
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
"<li class=\"filter_tab#{i == 0 ? ' active' : ''}\" #{(cat == 'all' && @all_setting_option == 0) ? "data-count_limit=\"#{max_all_count}\"" : ''} data-read_more_text=\"#{read_more_text}\" data-read_more=\"#{read_more_url}\" data-category=\"#{cats_relations[cat]}\">#{cats_translations[cat]}</li>"
|
||||||
|
}.join("")) +
|
||||||
|
"</ul>"
|
||||||
|
)
|
||||||
|
filter_attr = (use_tag ? 'data-tags' : 'data-category')
|
||||||
|
extra_html = '
|
||||||
|
<script>
|
||||||
|
if(typeof(wpexAnimsition) == "undefined"){
|
||||||
|
var wpexAnimsition = {
|
||||||
|
"loading":"1",
|
||||||
|
"inDuration":"400",
|
||||||
|
"outDuration":"400",
|
||||||
|
"inClass":"fade-in",
|
||||||
|
"outClass":"fade-out",
|
||||||
|
"need_fix_containers":".widget-custom_announcement-4,.widget-custom_announcement-15",
|
||||||
|
"linkElement": "[data-list=\"custom_announcements\"] > *",
|
||||||
|
"children_text_block": ".w-annc__content-wrap",
|
||||||
|
"container_block": "[data-subpart-id=\"'+subpart.id.to_s+'\"] [data-list=\"custom_announcements\"]:not(tbody)",
|
||||||
|
"parent_block": "[data-subpart-id=\"'+subpart.id.to_s+'\"]",
|
||||||
|
"filter_bar": ".nav_tabs_filter",
|
||||||
|
"filter_option": "li.filter_tab",
|
||||||
|
"filter_attr": "'+filter_attr+'",
|
||||||
|
"filter_target_attr": "class",
|
||||||
|
"use_attr_filter": true,
|
||||||
|
"equal_height": false
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
var filter_attr = "'+filter_attr+'";
|
||||||
|
wpexAnimsition.parent_block = wpexAnimsition.parent_block + ", [data-subpart-id=\"'+subpart.id.to_s+'\"]";
|
||||||
|
wpexAnimsition.container_block = wpexAnimsition.container_block + ", [data-subpart-id=\"'+subpart.id.to_s+'\"] [data-list=\"custom_announcements\"]:not(tbody)";
|
||||||
|
if( wpexAnimsition.filter_attr.indexOf(filter_attr) == -1 ){
|
||||||
|
wpexAnimsition.filter_attr += ("," + filter_attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var wpexLocalize = {
|
||||||
|
"lightboxType": "iLightbox",
|
||||||
|
"iLightbox": { "auto": false, "skin": "minimal", "path": "horizontal",
|
||||||
|
"infinite": false, "maxScale": 1, "minScale": 0, "width": 1400, "height": "",
|
||||||
|
"slideshow": { "pauseTime": 3000, "startPaused": true },
|
||||||
|
"effects": { "reposition": true, "repositionSpeed": 200, "switchSpeed": 300,
|
||||||
|
"loadedFadeSpeed": 50, "fadeSpeed": 500
|
||||||
|
},
|
||||||
|
"show": { "title": true, "speed": 200 },
|
||||||
|
"hide": { "speed": 200 },
|
||||||
|
"overlay": { "blur": true, "opacity": "0.9" },
|
||||||
|
"slideShow": "Slideshow", "next": "Next", "previous": "Previous" ,
|
||||||
|
"thumbnails": { "maxWidth": 120, "maxHeight": 80 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$(document).ready(function(){
|
||||||
|
var first_filter_tab = $("[data-subpart-id=\"'+subpart.id.to_s+'\"] .filter_tab").eq(0);
|
||||||
|
var read_more_url = first_filter_tab.data("read_more");
|
||||||
|
if(read_more_url.length != 0){
|
||||||
|
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .w-annc__more").attr("href",read_more_url);
|
||||||
|
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .w-annc__more").text(first_filter_tab.data("read_more_text"));
|
||||||
|
}
|
||||||
|
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .filter_tab").click(function(){
|
||||||
|
var read_more_url = $(this).data("read_more");
|
||||||
|
if(read_more_url.length != 0){
|
||||||
|
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .w-annc__more").attr("href",read_more_url);
|
||||||
|
$("[data-subpart-id=\"'+subpart.id.to_s+'\"] .w-annc__more").text($(this).data("read_more_text"));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<script src="/assets/custom_bulletin/wpex.min.js"></script>
|
||||||
|
<style>
|
||||||
|
[data-list="custom_announcements"] {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
'
|
||||||
|
else
|
||||||
|
read_more_text = I18n.t("custom_announcement.more")
|
||||||
|
if cats.count == 1 && cats[0] != "all"
|
||||||
|
begin
|
||||||
|
read_more_text = I18n.t("custom_announcement.more_") + ((all_tags.count == 1 && all_tags[0] != 'all') ? tags_translations[tags[0]] : cats_translations[cats[0]])
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
extra_html = "
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$(\"[data-subpart-id=\\\"#{subpart.id}\\\"] .w-annc__more\").text(\"#{read_more_text}\");
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
"
|
||||||
|
end
|
||||||
|
if (@read_more_option != 0 rescue false)
|
||||||
|
extra_html += "
|
||||||
|
<script>
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
var read_more_position = #{@read_more_option};
|
||||||
|
var read_more_block = $(\"[data-subpart-id=\\\"#{subpart.id}\\\"] .w-annc__more\");
|
||||||
|
if(read_more_position == 1 || read_more_position == 2){
|
||||||
|
read_more_block.addClass(\"pull-left\");
|
||||||
|
}else{
|
||||||
|
read_more_block.addClass(\"pull-right\");
|
||||||
|
}
|
||||||
|
if(read_more_position == 1 || read_more_position == 3){
|
||||||
|
var first_element = $(\"[data-subpart-id=\\\"#{subpart.id}\\\"] > *:eq(0)\");
|
||||||
|
var div_clearfix = $('<div class=\"clearfix\"></div>')
|
||||||
|
if(first_element.height() == 0){
|
||||||
|
read_more_block.appendTo(div_clearfix);
|
||||||
|
}else{
|
||||||
|
div_clearfix = read_more_block;
|
||||||
|
}
|
||||||
|
first_element.before(div_clearfix);
|
||||||
|
}else{
|
||||||
|
var div_clearfix = $('<div class=\"clearfix\"></div>');
|
||||||
|
read_more_block.appendTo(div_clearfix);
|
||||||
|
$(\"[data-subpart-id=\\\"#{subpart.id}\\\"] > *:eq(-1)\").after(div_clearfix);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
"
|
||||||
|
end
|
||||||
|
extra_after_html = ""
|
||||||
|
if @all_setting_option == 0 && @tab_option == 1
|
||||||
|
extra_after_html = "
|
||||||
|
<script>
|
||||||
|
$(\"[data-subpart-id=\\\"#{subpart.id}\\\"] [data-list] [data-category]\").css(\"display\",\"none\");
|
||||||
|
$(\"[data-subpart-id=\\\"#{subpart.id}\\\"] [data-list] [data-category]:lt(#{max_all_count})\").css(\"display\",\"\");
|
||||||
|
</script>
|
||||||
|
"
|
||||||
|
end
|
||||||
|
if @tab_option == 0
|
||||||
|
read_more_url = "/#{I18n.locale.to_s + page.get_url}" rescue ""
|
||||||
|
read_more_url = read_more_url + "?" + {"category"=>all_cats,"tags"=>all_tags}.to_param if read_more_url != ""
|
||||||
|
extra_after_html += "
|
||||||
|
<script>
|
||||||
|
$(\"[data-subpart-id=\\\"#{subpart.id}\\\"] .w-annc__more\").attr(\"href\",\"#{read_more_url}\");
|
||||||
|
</script>
|
||||||
|
"
|
||||||
|
end
|
||||||
|
{
|
||||||
|
"custom_announcements" => custom_anns,
|
||||||
|
"extras" => {
|
||||||
|
"more_url"=>OrbitHelper.widget_more_url,
|
||||||
|
"main_picture" => mp,
|
||||||
|
"main_picture_description" => mpd,
|
||||||
|
"title-head" => t('custom_announcement.table.title'),
|
||||||
|
"date-head" => t('custom_announcement.table.date'),
|
||||||
|
"author-head" => t('custom_announcement.table.author'),
|
||||||
|
"status-head" => t('custom_announcement.table.status'),
|
||||||
|
"subtitle-head" => t('custom_announcement.table.sub_title'),
|
||||||
|
"category-head" => t('custom_announcement.table.category'),
|
||||||
|
"link-head" => t('custom_announcement.table.link'),
|
||||||
|
"file-head" => t('custom_announcement.table.file'),
|
||||||
|
"read_more" => read_more_url,
|
||||||
|
"read_more_text" => "read more",
|
||||||
|
"extra_brefore_html" => extra_html,
|
||||||
|
"extra_after_html" => extra_after_html
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
def get_tabs_option
|
||||||
|
subpart = OrbitHelper.get_current_widget
|
||||||
|
tab_options = ["not_enable_tabs","enable_tabs_with_categories_include_all","enable_tabs_with_categories"]
|
||||||
|
read_more_options = ['default','upper_left','lower_left','upper_right','lower_right']
|
||||||
|
all_setting_options = ['the_same_as_data_count','display_all_in_other_tabs']
|
||||||
|
@tab_option = 0
|
||||||
|
@read_more_option = 0
|
||||||
|
@all_setting_option = 0
|
||||||
|
if subpart.methods.include? 'select_options'.to_sym
|
||||||
|
ModuleApp.all.select{|tmp| tmp.key.to_s=='custom_announcement'}.each do |modile_app|
|
||||||
|
@show_options = modile_app.show_options rescue nil
|
||||||
|
end
|
||||||
|
subpart.select_options.each do |select_option|
|
||||||
|
if !(@show_options.nil?) && select_option.field_name == @show_options.keys[1].to_s
|
||||||
|
value = YAML.load(select_option.value)
|
||||||
|
tmp = value[:en]
|
||||||
|
I18n.with_locale(:en) do
|
||||||
|
tab_options.each_with_index do |option,i|
|
||||||
|
if tmp == t("custom_announcement.#{option}")
|
||||||
|
@tab_option = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !(@show_options.nil?) && select_option.field_name == @show_options.keys[2].to_s
|
||||||
|
value = YAML.load(select_option.value)
|
||||||
|
tmp = value[:en]
|
||||||
|
I18n.with_locale(:en) do
|
||||||
|
read_more_options.each_with_index do |option,i|
|
||||||
|
if tmp == t("custom_announcement.#{option}")
|
||||||
|
@read_more_option = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !(@show_options.nil?) && select_option.field_name == @show_options.keys[3].to_s
|
||||||
|
value = YAML.load(select_option.value)
|
||||||
|
tmp = value[:en]
|
||||||
|
I18n.with_locale(:en) do
|
||||||
|
all_setting_options.each_with_index do |option,i|
|
||||||
|
if tmp == t("custom_announcement.#{option}")
|
||||||
|
@all_setting_option = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def get_anncs_for_pack_data(cats,tags,set_tags=nil,is_random = false)
|
||||||
|
subpart = OrbitHelper.get_current_widget
|
||||||
|
custom_data_field = subpart.custom_data_field
|
||||||
|
widget_data_count = OrbitHelper.widget_data_count
|
||||||
|
custom_anns_cache = CustomAnnsCache.where(parent_id: subpart.id.to_s + cats.to_s + tags.to_s + custom_data_field.to_s + widget_data_count.to_s,locale: I18n.locale.to_s)
|
||||||
|
set_image_version_for_widget()
|
||||||
|
devide_flag = (!(defined? SiteFeed).nil?)
|
||||||
|
if custom_anns_cache.count != 1 || is_random
|
||||||
|
CustomBulletin.remove_expired_status
|
||||||
|
uid = OrbitHelper.params[:uid] rescue ""
|
||||||
|
sorted_custom_anns = CustomBulletin.where(:title.nin => ["",nil],:is_preview.in=>[false,nil], :uid.ne => uid)
|
||||||
|
.can_display_and_sorted.is_approved
|
||||||
|
.filter_by_widget_categories(cats,false).filter_by_tags(tags)
|
||||||
|
if custom_data_field
|
||||||
|
if (custom_data_field[:bind_module_app] rescue false)
|
||||||
|
sorted_custom_anns = sorted_custom_anns.where(:custom_module=>custom_data_field[:bind_module_app])
|
||||||
|
end
|
||||||
|
if (custom_data_field[:bind_uid] rescue false)
|
||||||
|
sorted_custom_anns = sorted_custom_anns.where(:bind_uid=>custom_data_field[:bind_uid])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !is_random
|
||||||
|
sorted_custom_anns = sorted_custom_anns.limit(widget_data_count)
|
||||||
|
if custom_anns_cache.count > 1
|
||||||
|
custom_anns_cache.destroy
|
||||||
|
end
|
||||||
|
if devide_flag
|
||||||
|
now_custom_anns = sorted_custom_anns.to_a
|
||||||
|
top_custom_anns = now_custom_anns.select{|v| v.is_top}.map{|v| data_to_human_type(v,set_tags)}
|
||||||
|
not_top_custom_anns = now_custom_anns.select{|v| !v.is_top}.map{|v| data_to_human_type(v,set_tags)}
|
||||||
|
CustomAnnsCache.create(parent_id: subpart.id.to_s + cats.to_s + tags.to_s + custom_data_field.to_s + widget_data_count.to_s,locale: I18n.locale.to_s,filter_result: {top: top_custom_anns,not_top: not_top_custom_anns})
|
||||||
|
else
|
||||||
|
custom_anns = sorted_custom_anns.map{|v| data_to_human_type(v,set_tags)}
|
||||||
|
CustomAnnsCache.create(parent_id: subpart.id.to_s + cats.to_s + tags.to_s + custom_data_field.to_s + widget_data_count.to_s,locale: I18n.locale.to_s,filter_result: custom_anns)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if devide_flag
|
||||||
|
custom_anns = sorted_custom_anns.sample(widget_data_count)
|
||||||
|
top_custom_anns = custom_anns.select{|v| v.is_top}.map{|v| data_to_human_type(v,set_tags)}
|
||||||
|
not_top_custom_anns = custom_anns.select{|v| !v.is_top}.map{|v| data_to_human_type(v,set_tags)}
|
||||||
|
else
|
||||||
|
custom_anns = sorted_custom_anns.sample(widget_data_count).map{|v| data_to_human_type(v,set_tags)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif devide_flag
|
||||||
|
now_custom_anns = custom_anns_cache.first.filter_result
|
||||||
|
top_custom_anns = now_custom_anns[:top]
|
||||||
|
not_top_custom_anns = now_custom_anns[:not_top]
|
||||||
|
else
|
||||||
|
custom_anns = custom_anns_cache.first.filter_result
|
||||||
|
end
|
||||||
|
if devide_flag
|
||||||
|
rest_count = widget_data_count - top_custom_anns.count
|
||||||
|
if rest_count <= 0
|
||||||
|
custom_anns = top_custom_anns
|
||||||
|
else
|
||||||
|
feeds_custom_anns = get_feed_custom_announcements("widget")
|
||||||
|
top_custom_anns = top_custom_anns + feeds_custom_anns.select{|v| v['is_top']}
|
||||||
|
top_custom_anns = top_custom_anns.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]}
|
||||||
|
rest_all_custom_anns = feeds_custom_anns.select{|v| v['is_top'] != true} + not_top_custom_anns.take(rest_count)
|
||||||
|
rest_custom_anns = rest_all_custom_anns.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]}.take(rest_count)
|
||||||
|
custom_anns = (top_custom_anns + rest_custom_anns).take(widget_data_count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
custom_anns.each{|a| a["postdate"] = a["postdate"].in_time_zone(Time.zone.utc_offset / 3600).strftime('%Y-%m-%d %H:%M') rescue nil }
|
||||||
|
custom_anns
|
||||||
|
end
|
||||||
|
def get_file
|
||||||
|
@url = request.path
|
||||||
|
begin
|
||||||
|
file = CustomBulletinFile.find(params[:id])
|
||||||
|
@url = file.file.url
|
||||||
|
if file.can_access?(OrbitHelper.current_user)
|
||||||
|
@path = file.file.path rescue ""
|
||||||
|
@filename = @path.split("/").last
|
||||||
|
@ext = @path.split("/").last.to_s.split(".").last
|
||||||
|
if @ext == "png" || @ext == "jpg" || @ext == "bmp" || @ext == "pdf"
|
||||||
|
render "archives/download_file.html",:layout=>false
|
||||||
|
else
|
||||||
|
send_file(@path)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
render :file => "#{Rails.root}/app/views/errors/403.html", :layout => false, :status => :not_found, :content_type => 'text/html'
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found, :content_type => 'text/html'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def show_local_custom_announcement(uid, is_preview)
|
||||||
|
locale = OrbitHelper.get_site_locale.to_s
|
||||||
|
if is_preview
|
||||||
|
custom_announcement = CustomBulletin.where(:uid => uid).first
|
||||||
|
else
|
||||||
|
custom_announcement = CustomBulletin.can_display_and_sorted.where(:uid => uid).first
|
||||||
|
end
|
||||||
|
@custom_bulletin = custom_announcement
|
||||||
|
custom_announcement = CustomBulletin.where(:uid => uid).first if custom_announcement.nil?
|
||||||
|
url_to_edit = OrbitHelper.user_can_edit?(custom_announcement) ? "/admin/custom_announcements/#{custom_announcement.id.to_s}/edit" : ""
|
||||||
|
|
||||||
|
access_level = OrbitHelper.user_access_level?
|
||||||
|
|
||||||
|
if !custom_announcement.approved && (access_level != "manager" && access_level != "admin")
|
||||||
|
if CustomAnnouncementSetting.is_pro?
|
||||||
|
if !(access_level == "sub_manager" && CustomAnnouncementSetting.first.approvers.include?(OrbitHelper.current_user.id.to_s))
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
elsif access_level != "sub_manager"
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {} if (custom_announcement.category.disable rescue false)
|
||||||
|
|
||||||
|
tags = custom_announcement.tags.map{|tag| {
|
||||||
|
"tag" => tag.name ,
|
||||||
|
"url" => OrbitHelper.page_for_tag(tag)
|
||||||
|
} } rescue []
|
||||||
|
files = custom_announcement.custom_bulletin_files.map do |file|
|
||||||
|
{ "file_url" => "/xhr/custom_announcements/file/#{file.id}/#{file['file']}" + "\" title=\"#{file.file_title}",
|
||||||
|
"file_title" => (file.title.blank? ? URI.unescape(File.basename(file.file.path)) : file.title rescue '') } rescue nil if file.enabled_for?(locale)
|
||||||
|
end rescue []
|
||||||
|
files.delete(nil)
|
||||||
|
files.each do |file|
|
||||||
|
if file["file_url"] =="" || file["file_url"] == nil
|
||||||
|
files.delete(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
links = custom_announcement.custom_bulletin_links.map{|link| { "link_url" => link.url, "link_title" => (link.title.blank? ? link.url : link.title) } } rescue []
|
||||||
|
update_user = custom_announcement.update_user.member_profile.name rescue ""
|
||||||
|
desc = custom_announcement.image_description
|
||||||
|
desc = (desc.nil? || desc == "" ? "custom_announcement image" : desc)
|
||||||
|
|
||||||
|
request = OrbitHelper.request
|
||||||
|
meta_desc = custom_announcement.subtitle.nil? || custom_announcement.subtitle == "" ? custom_announcement.text[0..200] : custom_announcement.subtitle
|
||||||
|
OrbitHelper.render_meta_tags([{"property" => "og:title", "content" => custom_announcement.title},{"property" => "og:site_name", "content" => Site.first.title},{"property" => "og:url", "content" => request.original_url.split("?").first},{"property" => "og:description", "content" => meta_desc},{"property" => "og:image", "content" => "#{request.base_url}#{custom_announcement.image.url}"},{"property" => "og:type", "content" => "Article"}])
|
||||||
|
|
||||||
|
subtitle_ann = nil
|
||||||
|
img_src = nil
|
||||||
|
img_description = nil
|
||||||
|
subtitle_ann = custom_announcement.subtitle if custom_announcement.display_subtitle?
|
||||||
|
img_src = (custom_announcement.image.thumb.url || "/assets/custom_announcement-default.jpg") if custom_announcement.display_img?
|
||||||
|
img_description = custom_announcement.image_description if (custom_announcement.image_description.present?) && (custom_announcement.display_img?)
|
||||||
|
show_comment_flag = custom_announcement.open_comment_for_user(OrbitHelper.current_user)
|
||||||
|
custom_bulletin_carousel_images = custom_announcement.custom_bulletin_carousel_images.map{|image| {"src"=>image.file.url,"description"=>image.description.to_s,"description_text"=>image.description_text }}
|
||||||
|
resume_btn_title = (I18n.locale.to_s =="zh_tw") ? "繼續播放" : "resume"
|
||||||
|
pause_btn_title = (I18n.locale.to_s =="zh_tw") ? "暫停播放" : "pause"
|
||||||
|
prev_btn_title = (I18n.locale.to_s =="zh_tw") ? "上一張" : "prev"
|
||||||
|
next_btn_title = (I18n.locale.to_s =="zh_tw") ? "下一張" : "next"
|
||||||
|
{
|
||||||
|
"tags" => tags,
|
||||||
|
"custom_bulletin_files" => files,
|
||||||
|
"custom_bulletin_links" => links,
|
||||||
|
"custom_bulletin_carousel_images" => custom_bulletin_carousel_images,
|
||||||
|
"data" => {
|
||||||
|
"title" => custom_announcement.title,
|
||||||
|
"subtitle_ann" => subtitle_ann,
|
||||||
|
"update_user" => update_user,
|
||||||
|
"updated_at" => (custom_announcement.postdate.in_time_zone(Time.zone.utc_offset / 3600).strftime('%Y-%m-%d %H:%M') rescue ""),
|
||||||
|
"body" =>custom_announcement.text,
|
||||||
|
"image" => custom_announcement.image.url,
|
||||||
|
"img_src" => img_src,
|
||||||
|
"img_description" => img_description,
|
||||||
|
"hide_class" => custom_announcement.display_img? ? custom_announcement.image_display_class : ' hide',
|
||||||
|
"alt_title" => desc,
|
||||||
|
"resume_btn_title" => resume_btn_title,
|
||||||
|
"pause_btn_title" => pause_btn_title,
|
||||||
|
"prev_btn_title" => prev_btn_title,
|
||||||
|
"next_btn_title" => next_btn_title,
|
||||||
|
"carousel_display_style" => (custom_bulletin_carousel_images.count == 0 ? 'display: none' : 'width: 50%;margin: auto;'),
|
||||||
|
"carousel_count" => custom_bulletin_carousel_images.count
|
||||||
|
},
|
||||||
|
"comments" => custom_announcement.comments,
|
||||||
|
"show_comment_flag" => show_comment_flag,
|
||||||
|
"impressionist" => (custom_announcement.is_preview ? nil : custom_announcement),
|
||||||
|
"url_to_edit"=>url_to_edit
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_feed_custom_announcement(uid)
|
||||||
|
custom_announcement = OrbitHelper.get_from_feed(uid)
|
||||||
|
locale = OrbitHelper.get_site_locale.to_s
|
||||||
|
url_to_edit = "#"
|
||||||
|
return {} if custom_announcement.blank?
|
||||||
|
tags = []
|
||||||
|
|
||||||
|
custom_announcement["tags"].each{|tag|
|
||||||
|
t = Tag.where(:name => tag["name_translations"][locale]).first rescue nil
|
||||||
|
if t.nil?
|
||||||
|
I18n.locale = (locale == "en" ? :zh_tw : :en)
|
||||||
|
t = Tag.where(:name => tag["name_translations"][locale]).first rescue nil
|
||||||
|
I18n.locale = locale.to_sym
|
||||||
|
end
|
||||||
|
tags << {
|
||||||
|
"tag" => tag["name_translations"][locale],
|
||||||
|
"url" => (t.nil? ? "#" : OrbitHelper.page_for_tag(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
files = custom_announcement["custom_bulletin_files"].map{|file| { "file_url" => file["url"], "file_title" => (file["title_translations"][locale] == "" ? URI.unescape(File.basename(file["url"])) : file["title_translations"][locale] rescue '') } } rescue []
|
||||||
|
|
||||||
|
files.each do |file|
|
||||||
|
if file["file_url"] =="" || file["file_url"] == nil
|
||||||
|
files.delete(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
links = custom_announcement["custom_bulletin_links"].map{|link| { "link_url" => link["url"], "link_title" => (link["title_translations"][locale] == "" ? link["url"] : link["title_translations"][locale]) } } rescue []
|
||||||
|
|
||||||
|
update_user = custom_announcement["author"]
|
||||||
|
desc = custom_announcement["image_description_translations"][locale] rescue ""
|
||||||
|
desc = (desc.nil? || desc == "" ? "custom_announcement image" : desc)
|
||||||
|
img_description = nil
|
||||||
|
img_description = custom_announcement["image_description_translations"][I18n.locale] if custom_announcement['display_img']
|
||||||
|
img_src = nil
|
||||||
|
img_src = (custom_announcement['image']['thumb'] || "/assets/custom_announcement-default.jpg") if custom_announcement['display_img']
|
||||||
|
subtitle_ann = custom_announcement['subtitle_ann']
|
||||||
|
request = OrbitHelper.request
|
||||||
|
if custom_announcement["subtitle_translations"].present?
|
||||||
|
meta_desc = custom_announcement["subtitle_translations"][locale] != "" ? custom_announcement["subtitle_translations"][locale] : custom_announcement["text_translations"][locale][0..200] rescue ""
|
||||||
|
else
|
||||||
|
meta_desc = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
OrbitHelper.render_meta_tags([{"property" => "og:title", "content" => custom_announcement["title_translations"][locale]},{"property" => "og:site_name", "content" => Site.first.title},{"property" => "og:url", "content" => request.original_url.split("?").first},{"property" => "og:description", "content" => meta_desc},{"property" => "og:image", "content" => custom_announcement["image"]["original"]},{"property" => "og:type", "content" => "Article"}])
|
||||||
|
|
||||||
|
datetime = DateTime.parse(custom_announcement["postdate"])
|
||||||
|
|
||||||
|
custom_bulletin_carousel_images = Array(custom_announcement["custom_bulletin_carousel_images"])
|
||||||
|
resume_btn_title = (I18n.locale.to_s =="zh_tw") ? "繼續播放" : "resume"
|
||||||
|
pause_btn_title = (I18n.locale.to_s =="zh_tw") ? "暫停播放" : "pause"
|
||||||
|
prev_btn_title = (I18n.locale.to_s =="zh_tw") ? "上一張" : "prev"
|
||||||
|
next_btn_title = (I18n.locale.to_s =="zh_tw") ? "下一張" : "next"
|
||||||
|
|
||||||
|
{
|
||||||
|
"tags" => tags,
|
||||||
|
"custom_bulletin_files" => files,
|
||||||
|
"custom_bulletin_links" => links,
|
||||||
|
"custom_bulletin_carousel_images" => custom_bulletin_carousel_images,
|
||||||
|
"data" => {
|
||||||
|
"title" => custom_announcement["title_translations"][locale],
|
||||||
|
"subtitle_ann" => subtitle_ann,
|
||||||
|
"update_user" => update_user,
|
||||||
|
"updated_at" => (datetime.in_time_zone(Time.zone.utc_offset / 3600).strftime('%Y-%m-%d %H:%M') rescue ""),
|
||||||
|
"body" => custom_announcement["text_translations"][locale],
|
||||||
|
"image" => custom_announcement["image"]["original"],
|
||||||
|
"img_src" => img_src,
|
||||||
|
"img_description" => img_description,
|
||||||
|
"hide_class" => custom_announcement["display_img"] ? '' : ' hide',
|
||||||
|
"alt_title" => desc,
|
||||||
|
"resume_btn_title" => resume_btn_title,
|
||||||
|
"pause_btn_title" => pause_btn_title,
|
||||||
|
"prev_btn_title" => prev_btn_title,
|
||||||
|
"next_btn_title" => next_btn_title,
|
||||||
|
"carousel_display_style" => (custom_bulletin_carousel_images.count == 0 ? 'display: none' : 'width: 50%;margin: auto;'),
|
||||||
|
"carousel_count" => custom_bulletin_carousel_images.count
|
||||||
|
},
|
||||||
|
"comments" => [],
|
||||||
|
"show_comment_flag" => false,
|
||||||
|
"impressionist" => nil,
|
||||||
|
"url_to_edit" => url_to_edit
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
params = OrbitHelper.params
|
||||||
|
uid = params[:uid]
|
||||||
|
if OrbitHelper.is_object_from_feed?(uid)
|
||||||
|
show_feed_custom_announcement(uid)
|
||||||
|
else
|
||||||
|
show_local_custom_announcement(uid, (params["preview"] == "true" ? true : false))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def show_widget
|
||||||
|
@type = "show_widget"
|
||||||
|
@show_page = params[:show_page]
|
||||||
|
if params[:tags].nil?
|
||||||
|
@tags = ['all']
|
||||||
|
else
|
||||||
|
@tags = params[:tags]
|
||||||
|
end
|
||||||
|
if params[:categories].nil?
|
||||||
|
@categories = ['all']
|
||||||
|
else
|
||||||
|
@categories = params[:categories]
|
||||||
|
end
|
||||||
|
OrbitHelper.set_site_locale(I18n.locale)
|
||||||
|
OrbitHelper.set_current_widget_module("custom_announcement")
|
||||||
|
OrbitHelper.set_params(params,current_user)
|
||||||
|
CustomBulletin.remove_expired_status
|
||||||
|
OrbitHelper.set_page_number(params[:page_no].to_i)
|
||||||
|
OrbitHelper.set_page_data_count((params[:data_count].blank? ? 10 : params[:data_count].to_i))
|
||||||
|
sorted,total_pages = get_sorted_annc
|
||||||
|
custom_anns = sorted.collect do |a|
|
||||||
|
if a["source-site"].blank?
|
||||||
|
statuses = a.statuses_with_classname.collect do |status|
|
||||||
|
{
|
||||||
|
"status" => status["name"],
|
||||||
|
"status-class" => "status-#{status['classname']}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
locale = I18n.locale.to_s
|
||||||
|
files = a.custom_bulletin_files.map{|file| { "file_url" => file.file.url + "\" title=\"#{file.file_title}", "file_title" => (file.title.blank? ? File.basename(file.file.path) : file.title rescue '') } if file.enabled_for?(locale) } rescue []
|
||||||
|
files.delete(nil)
|
||||||
|
links = a.custom_bulletin_links.map{|link| { "link_url" => link.url, "link_title" => (link.title.blank? ? link.url : link.title) } } rescue []
|
||||||
|
author = User.find(a.create_user_id).member_profile.name rescue ""
|
||||||
|
desc = a.image_description
|
||||||
|
desc = (desc.blank? ? "custom_announcement image" : desc)
|
||||||
|
link_to_show = (a.is_external_link ? a.external_link : OrbitHelper.url_to_show(a.to_param)) rescue ""
|
||||||
|
target = a.is_external_link ? "_blank" : "_self"
|
||||||
|
doc = Nokogiri::HTML(a.title)
|
||||||
|
title = doc.text.empty? ? 'no content' : doc.text
|
||||||
|
{
|
||||||
|
"department" => author,
|
||||||
|
"custom_bulletin_links" => links,
|
||||||
|
"custom_bulletin_files" => files,
|
||||||
|
"title" => a.title,
|
||||||
|
"source-site" => "",
|
||||||
|
"source-site-title" => "",
|
||||||
|
"source-site-link" => "",
|
||||||
|
"subtitle" => a.subtitle,
|
||||||
|
"statuses" => statuses,
|
||||||
|
"category" => a.category.title,
|
||||||
|
"postdate" => a.postdate,
|
||||||
|
"author" => author,
|
||||||
|
"is_top" => (a.is_top? ? 1 : 0),
|
||||||
|
"link_to_show" => link_to_show+"\" title=\"#{title}\"",
|
||||||
|
"target" => target,
|
||||||
|
"img_src" => a.image.thumb.url || "/assets/custom_announcement-default.jpg",
|
||||||
|
"img_description" => desc,
|
||||||
|
"more" => t(:more_plus),
|
||||||
|
"view_count" => a.view_count
|
||||||
|
}
|
||||||
|
else
|
||||||
|
a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
#If no data , hide title&table
|
||||||
|
if sorted.count == 0
|
||||||
|
display = "hide"
|
||||||
|
end
|
||||||
|
# custom_anns = custom_anns.concat(feeds_custom_anns)
|
||||||
|
# total_pages = custom_announcements.total_pages
|
||||||
|
|
||||||
|
|
||||||
|
@data = {
|
||||||
|
"custom_announcements" => custom_anns,
|
||||||
|
"extras" => {
|
||||||
|
"widget-title" =>t('custom_announcement.custom_announcement'),
|
||||||
|
"title-head" => t('custom_announcement.table.title'),
|
||||||
|
"date-head" => t('custom_announcement.table.date'),
|
||||||
|
"status-head" => t('custom_announcement.table.status'),
|
||||||
|
"author-head" => t('custom_announcement.table.author'),
|
||||||
|
"subtitle-head" => t('custom_announcement.table.sub_title'),
|
||||||
|
"category-head" => t('custom_announcement.table.category'),
|
||||||
|
"link-head" => t('custom_announcement.table.link'),
|
||||||
|
"file-head" => t('custom_announcement.table.file'),
|
||||||
|
"view-count-head" => t('custom_announcement.table.view_count'),
|
||||||
|
"display" => display,
|
||||||
|
"department-head" => t('custom_announcement.table.department')
|
||||||
|
},
|
||||||
|
"total_pages" => total_pages
|
||||||
|
}
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,128 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
class CustomBulletinsController < ApplicationController
|
||||||
|
before_filter :set_I18n
|
||||||
|
def get_custom_bulletins
|
||||||
|
page = Page.where(:module => "custom_announcement").first rescue nil
|
||||||
|
|
||||||
|
# 頁次
|
||||||
|
page_num = params[:page_num].blank? ? 0 : params[:page_num].to_i
|
||||||
|
# 每頁顯示的則數
|
||||||
|
per_page = params[:per_page].blank? ? 10 : params[:per_page].to_i
|
||||||
|
per_page = per_page > 0 ? per_page : 10
|
||||||
|
|
||||||
|
I18n.locale = :zh_tw
|
||||||
|
if !params[:keyword].blank?
|
||||||
|
keyword = Regexp.new(".*"+params[:keyword]+".*")
|
||||||
|
custom_bulletins = CustomBulletin.any_of({:title=>keyword},{:subtitle=>keyword},{:text=>keyword})
|
||||||
|
else
|
||||||
|
custom_bulletins = CustomBulletin.all
|
||||||
|
end
|
||||||
|
|
||||||
|
if !params[:category].blank?
|
||||||
|
module_id = ModuleApp.where(:key=>"custom_announcement").first.id
|
||||||
|
category = Regexp.new(".*"+params[:category]+".*")
|
||||||
|
category_id = Category.where(:title => category, :module_app_id => module_id).first.id
|
||||||
|
custom_bulletins = custom_bulletins.where(:category_id => category_id)
|
||||||
|
else
|
||||||
|
custom_bulletins = custom_bulletins
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_bulletins = custom_bulletins.where(:is_preview.in=>[false,nil])
|
||||||
|
custom_bulletins = custom_bulletins.where(:approved.ne => false , :rejected.ne => true)
|
||||||
|
custom_bulletins = custom_bulletins.where(:postdate.lt=>Time.now)
|
||||||
|
custom_bulletins = custom_bulletins.desc( :is_top, :postdate).page(page_num).per(per_page)
|
||||||
|
|
||||||
|
custom_bulletins = custom_bulletins.collect do |b|
|
||||||
|
image = request.protocol + request.host_with_port + b.image.url rescue nil
|
||||||
|
|
||||||
|
links = b.custom_bulletin_links.collect do |bl|
|
||||||
|
{
|
||||||
|
"title" => bl.title_translations,
|
||||||
|
"url" => bl.url
|
||||||
|
}
|
||||||
|
end rescue nil
|
||||||
|
|
||||||
|
files = b.custom_bulletin_files.collect do |bf|
|
||||||
|
file = request.protocol + request.host_with_port + bf.file.url rescue nil
|
||||||
|
{
|
||||||
|
"title" => bf.title_translations,
|
||||||
|
"description" => bf.description_translations,
|
||||||
|
"file" => file
|
||||||
|
}
|
||||||
|
end rescue nil
|
||||||
|
|
||||||
|
ts = b.tags.collect do |t|
|
||||||
|
{
|
||||||
|
"name" => t.name_translations
|
||||||
|
}
|
||||||
|
end rescue nil
|
||||||
|
|
||||||
|
text = {"en" => "", "zh_tw" => ""}
|
||||||
|
text["en"] = (b.text_translations["en"].nil? ? "" :smart_convertor(b.text_translations["en"]))
|
||||||
|
text["zh_tw"] = (b.text_translations["zh_tw"].nil? ? "" : smart_convertor(b.text_translations["zh_tw"]))
|
||||||
|
|
||||||
|
author = User.find(b.create_user_id).member_profile.name rescue ""
|
||||||
|
|
||||||
|
{
|
||||||
|
"id" => b.id.to_s,
|
||||||
|
"title" => b.title_translations,
|
||||||
|
"subtitle" => b.subtitle_translations,
|
||||||
|
"text" => text,
|
||||||
|
"postdate" => b.postdate,
|
||||||
|
"deadline" => b.deadline,
|
||||||
|
"category" => b.category.title_translations,
|
||||||
|
"tags" => ts,
|
||||||
|
"image" => image,
|
||||||
|
"links" => links,
|
||||||
|
"files" => files,
|
||||||
|
"author" => author,
|
||||||
|
"url" => "/#{I18n.locale.to_s + page.url}/#{b.to_param}"
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# 計算總筆數 Start
|
||||||
|
if !params[:keyword].blank?
|
||||||
|
keyword = Regexp.new(".*"+params[:keyword]+".*")
|
||||||
|
custom_bulletin_count = CustomBulletin.any_of({:title=>keyword},{:subtitle=>keyword},{:text=>keyword})
|
||||||
|
else
|
||||||
|
custom_bulletin_count = CustomBulletin.all
|
||||||
|
end
|
||||||
|
custom_bulletin_count = custom_bulletin_count.where(:is_preview.in=>[false,nil])
|
||||||
|
custom_bulletin_count = custom_bulletin_count.where(:approved.ne => false , :rejected.ne => true)
|
||||||
|
custom_bulletin_count = custom_bulletin_count.where(:postdate.lt=>Time.now)
|
||||||
|
total_pages = custom_bulletin_count.count
|
||||||
|
# End
|
||||||
|
|
||||||
|
render :json => {
|
||||||
|
"custom_bulletins" => custom_bulletins,
|
||||||
|
"custom_bulletins_count" => custom_bulletins.count,
|
||||||
|
"page_num" => page_num,
|
||||||
|
"total_pages" => total_pages,
|
||||||
|
}.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def smart_convertor(text)
|
||||||
|
html_string = text
|
||||||
|
links = html_string.scan(/img.*?src="(.*?)"/i)
|
||||||
|
links.each do |link|
|
||||||
|
l = link.first
|
||||||
|
new_link = nil
|
||||||
|
if l.starts_with?("/")
|
||||||
|
new_link = request.protocol + request.host_with_port + l
|
||||||
|
elsif l.starts_with?("..")
|
||||||
|
l1 = l.gsub("../","")
|
||||||
|
new_link = request.protocol + request.host_with_port + "/" + l1
|
||||||
|
end
|
||||||
|
html_string = html_string.sub(l,new_link) if !new_link.nil?
|
||||||
|
end
|
||||||
|
return html_string
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def set_I18n
|
||||||
|
I18n.locale = params[:lang] if params[:lang].present?
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,327 @@
|
||||||
|
require "net/http"
|
||||||
|
require "uri"
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
module Admin::CustomAnnouncementsHelper
|
||||||
|
def back_end_breadcrumb
|
||||||
|
if params[:controller] == "admin/custom_announcements"
|
||||||
|
res = ''
|
||||||
|
divider = "<span class='divider'>/</span>"
|
||||||
|
res << "<li><a href='#{admin_dashboards_path}'>#{t(:dashboard_)}</a>#{divider}</li>"
|
||||||
|
if params[:custom_module]
|
||||||
|
trans_name = I18n.t("module_name.#{params[:custom_module]}")
|
||||||
|
if trans_name.include?("translation missing")
|
||||||
|
trans_name = params[:custom_module]
|
||||||
|
end
|
||||||
|
res << "<li><a href='/admin/#{params[:custom_module].pluralize}'>#{trans_name}</a>#{divider}</li>"
|
||||||
|
end
|
||||||
|
if params[:action] != "index"
|
||||||
|
if params[:custom_module]
|
||||||
|
extra_url = "/#{params[:custom_module]}#{params[:bind_uid].present? ? ('-'+params[:bind_uid]) : ''}"
|
||||||
|
end
|
||||||
|
res << "<li><a href='/#{params[:controller]}#{extra_url}'>#{t('module_name.'+@module_app.key)}</a>#{divider}</li>"
|
||||||
|
res << "<li class='active'>#{t(params[:action], scope: 'restful_actions')}</li>"
|
||||||
|
else
|
||||||
|
res << "<li>#{t('module_name.'+@module_app.key)}</li>"
|
||||||
|
end
|
||||||
|
res.html_safe
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def page_for_custom_bulletin(custom_bulletin)
|
||||||
|
ann_page = nil
|
||||||
|
pages = Page.where(:module=>'custom_announcement')
|
||||||
|
|
||||||
|
pages.each do |page|
|
||||||
|
if page.categories.count ==1
|
||||||
|
if page.categories.include?(custom_bulletin.category.id.to_s)
|
||||||
|
ann_page = page
|
||||||
|
end
|
||||||
|
end
|
||||||
|
break if !ann_page.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
if ann_page.nil?
|
||||||
|
pages.each do |page|
|
||||||
|
if (page.categories.include?(custom_bulletin.category.id.to_s) rescue false)
|
||||||
|
ann_page = page
|
||||||
|
end
|
||||||
|
break if !ann_page.nil?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ann_page = pages.first if ann_page.nil?
|
||||||
|
(ann_page.get_url+'/'+custom_bulletin.to_param).gsub('//','/') rescue "#"
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_this_custom_announcement(row,categories,tags)
|
||||||
|
value = {}
|
||||||
|
custom_anns = CustomBulletin.new
|
||||||
|
row.cells.each_with_index do |cell,index|
|
||||||
|
val = cell.value rescue nil
|
||||||
|
if [8,9,10,11,12,13,14,15].exclude?(index)
|
||||||
|
next if val.blank?
|
||||||
|
end
|
||||||
|
case index
|
||||||
|
when 0
|
||||||
|
custom_anns.category = categories[val.to_i]
|
||||||
|
when 1
|
||||||
|
new_tags = []
|
||||||
|
if (val.include?(",") rescue false)
|
||||||
|
ts = val.split(",")
|
||||||
|
ts.each do |t|
|
||||||
|
new_tags << tags[t.to_i]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
new_tags << tags[val.to_i]
|
||||||
|
end
|
||||||
|
custom_anns.tags=new_tags
|
||||||
|
when 2
|
||||||
|
custom_anns.postdate = val
|
||||||
|
when 3
|
||||||
|
custom_anns.deadline = val
|
||||||
|
when 4
|
||||||
|
custom_anns.is_top = (val.to_i == 1 ? true : false)
|
||||||
|
when 5
|
||||||
|
custom_anns.is_hot = (val.to_i == 1 ? true : false)
|
||||||
|
when 6
|
||||||
|
custom_anns.is_hidden = (val.to_i == 1 ? true : false)
|
||||||
|
when 7
|
||||||
|
custom_anns.remote_image_url = val
|
||||||
|
when 8
|
||||||
|
value["en"] = val
|
||||||
|
when 9
|
||||||
|
value["zh_tw"] = val
|
||||||
|
custom_anns.image_description_translations = value
|
||||||
|
value = {}
|
||||||
|
when 10
|
||||||
|
value["en"] = val
|
||||||
|
when 11
|
||||||
|
value["zh_tw"] = val
|
||||||
|
custom_anns.title_translations = value
|
||||||
|
value = {}
|
||||||
|
when 12
|
||||||
|
value["en"] = val
|
||||||
|
when 13
|
||||||
|
value["zh_tw"] = val
|
||||||
|
custom_anns.subtitle_translations = value
|
||||||
|
value = {}
|
||||||
|
when 14
|
||||||
|
value["en"] = val
|
||||||
|
when 15
|
||||||
|
value["zh_tw"] = val
|
||||||
|
custom_anns.text_translations = value
|
||||||
|
value = {}
|
||||||
|
when 16
|
||||||
|
links = val.split(";") rescue []
|
||||||
|
desc_en = row.cells[17].value.split(";") rescue []
|
||||||
|
desc_zh_tw = row.cells[18].value.split(";") rescue []
|
||||||
|
links.each_with_index do |link,i|
|
||||||
|
bl = CustomBulletinLink.new
|
||||||
|
bl.url = link.strip
|
||||||
|
bl.title_translations = {"en" => desc_en[i], "zh_tw" => desc_zh_tw[i]}
|
||||||
|
bl.custom_bulletin_id = custom_anns.id
|
||||||
|
bl.save
|
||||||
|
end
|
||||||
|
when 19
|
||||||
|
files = val.split(";") rescue []
|
||||||
|
desc_en = row.cells[20].value.split(";") rescue []
|
||||||
|
desc_zh_tw = row.cells[21].value.split(";") rescue []
|
||||||
|
alt_en = row.cells[22].value.split(";") rescue []
|
||||||
|
alt_zh_tw = row.cells[23].value.split(";") rescue []
|
||||||
|
files.each_with_index do |file, i|
|
||||||
|
bf = CustomBulletinFile.new
|
||||||
|
bf.remote_file_url = file.strip rescue nil
|
||||||
|
bf.title_translations = {"en" => (desc_en[i] rescue ""), "zh_tw" => (desc_zh_tw[i] rescue "")}
|
||||||
|
bf.description_translations = {"en" => (alt_en[i] rescue ""), "zh_tw" => (alt_zh_tw[i] rescue "")}
|
||||||
|
bf.custom_bulletin_id = custom_anns.id
|
||||||
|
bf.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
custom_anns.create_user_id = current_user.id.to_s
|
||||||
|
custom_anns.update_user_id = current_user.id.to_s
|
||||||
|
custom_anns.approved = true
|
||||||
|
custom_anns.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_rejection_email(custom_announcement,locale)
|
||||||
|
user = User.find(custom_announcement.create_user_id) rescue nil
|
||||||
|
if !user.nil?
|
||||||
|
email = user.member_profile.email
|
||||||
|
if !email.nil? && email != ""
|
||||||
|
url = "http://#{request.host_with_port}/admin/custom_announcements/#{custom_announcement.id}/edit"
|
||||||
|
datatosend = "<h3>Hello #{user.name},</h3><p>#{current_user.name} #{t("custom_announcement.rejected_annoucement")} : #{custom_announcement.rejection_reason} <a href='#{url}'> #{t("custom_announcement.click_here_to_see")}</a></p>"
|
||||||
|
mail = Email.new(:mail_to => email, :mail_subject => "CustomAnnouncement rejected公告未通過 : #{custom_announcement.title_translations[locale]}.", :template => "email/custom_announcement_email.html.erb", :template_data => {"html" => datatosend})
|
||||||
|
mail.save
|
||||||
|
mail.deliver rescue nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_notification_mail_to_managers(custom_announcement, type, locale)
|
||||||
|
users = []
|
||||||
|
if @custom_announcement_setting.email_to.include?("managers")
|
||||||
|
authorizations = Authorization.where(:module_app_id => @module_app.id)
|
||||||
|
users = authorizations.collect do |auth|
|
||||||
|
auth.user
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if @custom_announcement_setting.email_to.include?("admins")
|
||||||
|
wg = Workgroup.where(:key => "admin").first
|
||||||
|
admins = User.where(:workgroup_id => wg.id)
|
||||||
|
users.delete(nil)
|
||||||
|
users = users.concat(admins.to_a)
|
||||||
|
end
|
||||||
|
if @custom_announcement_setting.email_to.include?("approvers")
|
||||||
|
approvers = User.find(@custom_announcement_setting.approvers).to_a rescue []
|
||||||
|
auths = Authorization.where(:category_id => custom_announcement.category_id).collect{|a| a.user}
|
||||||
|
users = users.concat(approvers & auths)
|
||||||
|
end
|
||||||
|
users.each do |user|
|
||||||
|
email = user.member_profile.email
|
||||||
|
if !email.nil? && email != ""
|
||||||
|
send_email(user.name, email, custom_announcement, type, locale)
|
||||||
|
# sleep(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_email(name, useremail, custom_announcement, type, locale)
|
||||||
|
url = "http://#{request.host_with_port}/admin/custom_announcements?url=#{page_for_custom_bulletin(custom_announcement).sub("http://" + request.host_with_port, "")}&id=#{custom_announcement.id}"
|
||||||
|
|
||||||
|
case type
|
||||||
|
when "approval"
|
||||||
|
datatosend = "<h3>#{t("custom_announcement.approval_mail_hi", :name => name)},</h3><p>#{t("custom_announcement.submitted_new_custom_announcement", :poster => current_user.name)}<br /><br />#{t("custom_announcement.approval_custom_announcement_title")} : #{custom_announcement.title_translations[locale]} <br /> #{t("custom_announcement.click_here_to_see")} : <a href='#{url}'> #{url} </a></p>"
|
||||||
|
when "reapproval"
|
||||||
|
datatosend = "<h3>#{t("custom_announcement.approval_mail_hi", :name => name)},</h3><p>#{t("custom_announcement.updated_annoucement", :poster => current_user.name)}<br /><br />#{t("custom_announcement.approval_custom_announcement_title")} : #{custom_announcement.title_translations[locale]} <br /> #{t("custom_announcement.click_here_to_see")} : <a href='#{url}'> #{url} </a></p>"
|
||||||
|
end
|
||||||
|
email = Email.new(:mail_to => useremail, :mail_subject => " #{t("custom_announcement.custom_announcement_subject")} : #{custom_announcement.title_translations[locale]}.", :template => "email/custom_announcement_email.html.erb", :template_data => {"html" => datatosend})
|
||||||
|
email.save
|
||||||
|
email.deliver rescue nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def download_tmp_xml(url)
|
||||||
|
xml = File.join(Rails.root, "tmp", "ann_cc_ntu.xml")
|
||||||
|
open(xml, 'wb') do |fo|
|
||||||
|
fo.print open(url).read
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_from_tmp_xml(file)
|
||||||
|
xml = Nokogiri::XML(file)
|
||||||
|
return if xml.nil?
|
||||||
|
custom_announcements = []
|
||||||
|
xml.xpath("//channel").xpath("//item").each do |custom_anns|
|
||||||
|
custom_announcements << {
|
||||||
|
:title => (custom_anns>"title").text,
|
||||||
|
:category => (custom_anns>"category").text,
|
||||||
|
:postdate => (custom_anns>"pubDate").text,
|
||||||
|
:text => (custom_anns>"description").text,
|
||||||
|
:rss2_sn => (custom_anns>"link").text.split("=").last
|
||||||
|
}
|
||||||
|
end
|
||||||
|
custom_announcements.each do |custom_anns|
|
||||||
|
ma = ModuleApp.where(:key => "custom_announcement").first
|
||||||
|
cat = Category.where(:title => custom_anns[:category]).first rescue nil
|
||||||
|
if cat.nil?
|
||||||
|
cat = Category.create(:title_translations => {"en" => custom_anns[:category], "zh_tw" => custom_anns[:category]}, :module_app_id => ma.id)
|
||||||
|
end
|
||||||
|
ann = CustomBulletin.where(:rss2_sn => custom_anns[:rss2_sn]).first rescue nil
|
||||||
|
if ann.nil?
|
||||||
|
ann = CustomBulletin.new(:title_translations => {"en" => "", "zh_tw" => custom_anns[:title]}, :postdate => custom_anns[:postdate], :subtitle_translations => {"en" => "", "zh_tw" => custom_anns[:title]}, :text_translations => {"en" => "", "zh_tw" => custom_anns[:text]}, :rss2_sn => custom_anns[:rss2_sn], :category_id => cat.id, :approved => true, :create_user_id => current_user.id)
|
||||||
|
else
|
||||||
|
ann.update_attributes(:title_translations => {"en" => "", "zh_tw" => custom_anns[:title]}, :postdate => custom_anns[:postdate], :subtitle_translations => {"en" => "", "zh_tw" => custom_anns[:title]}, :text_translations => {"en" => "", "zh_tw" => custom_anns[:text]})
|
||||||
|
end
|
||||||
|
ann.save
|
||||||
|
end
|
||||||
|
File.delete(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_from_wordpress(xmlfile)
|
||||||
|
xml_file = File.read(xmlfile)
|
||||||
|
doc = Nokogiri::XML.parse(xml_file)
|
||||||
|
|
||||||
|
doc.xpath("//channel").each do|channel_data|
|
||||||
|
channel_data.xpath('//item').each do|itme|
|
||||||
|
|
||||||
|
bu = CustomBulletin.where(:rss2_sn => itme.xpath('wp:post_id').text ).first rescue nil
|
||||||
|
if bu.nil?
|
||||||
|
bu = CustomBulletin.new
|
||||||
|
bu.approved = true
|
||||||
|
bu.rss2_sn = itme.xpath('wp:post_id').text
|
||||||
|
bu.title_translations = {"en" => itme.xpath('title').text, "zh_tw" => itme.xpath('title').text}
|
||||||
|
bu.text_translations = {"en" => itme.xpath('content:encoded').text, "zh_tw" => itme.xpath('content:encoded').text}
|
||||||
|
bu.postdate = itme.xpath('wp:post_date').text
|
||||||
|
|
||||||
|
itme.xpath('category').each do |i_cate|
|
||||||
|
if i_cate["domain"].to_s == "category"
|
||||||
|
|
||||||
|
cat = @module_app.categories.where(:title => i_cate.text.to_s).first rescue nil
|
||||||
|
if cat.nil?
|
||||||
|
cat = Category.new
|
||||||
|
cat.module_app = @module_app
|
||||||
|
cat.title_translations = {"en" => i_cate.text.to_s, "zh_tw" => i_cate.text.to_s}
|
||||||
|
cat.save
|
||||||
|
end
|
||||||
|
bu.category = cat
|
||||||
|
|
||||||
|
elsif i_cate["domain"].to_s == "post_tag"
|
||||||
|
|
||||||
|
tag = Tag.where(:name => i_cate.text.to_s ).first rescue nil
|
||||||
|
if tag.nil?
|
||||||
|
tag = Tag.new
|
||||||
|
tag.name_translations = {"en" => i_cate.text.to_s, "zh_tw" => i_cate.text.to_s}
|
||||||
|
tag.module_app_ids << @module_app.id
|
||||||
|
tag.save
|
||||||
|
end
|
||||||
|
|
||||||
|
bu.tags = tag
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
bu.save
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
File.delete(xmlfile)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_access_level
|
||||||
|
if (current_user.is_admin? rescue false)
|
||||||
|
@access_level = "admin"
|
||||||
|
elsif (current_user.is_manager?(@module_app) rescue false)
|
||||||
|
@access_level = "manager"
|
||||||
|
else
|
||||||
|
@access_level = "users"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_can_approve?(custom_anns=nil)
|
||||||
|
can_approve = false
|
||||||
|
setting = CustomAnnouncementSetting.first
|
||||||
|
case @access_level
|
||||||
|
when "admin"
|
||||||
|
can_approve = true
|
||||||
|
when "manager"
|
||||||
|
can_approve = true
|
||||||
|
else
|
||||||
|
can_approve = false
|
||||||
|
end
|
||||||
|
if !can_approve
|
||||||
|
if !custom_anns.nil?
|
||||||
|
if setting.approvers.include?(current_user.id.to_s)
|
||||||
|
if (current_user.approved_categories_for_module(@module_app).include?(custom_anns.category) rescue false)
|
||||||
|
can_approve = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
can_approve = setting.approvers.include?(current_user.id.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
can_approve
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,488 @@
|
||||||
|
module CustomAnnouncementsHelper
|
||||||
|
def self.complementaryColor(my_hex)
|
||||||
|
if my_hex[0] == '#'
|
||||||
|
my_hex = my_hex[1..-1]
|
||||||
|
end
|
||||||
|
rgb = my_hex.split(//).each_slice(my_hex.length/3).map{|v| v.join}
|
||||||
|
comp = rgb.map{|a| (255 - a.to_i(16)).to_s(16).rjust(2,'0')}
|
||||||
|
'#'+comp.join
|
||||||
|
end
|
||||||
|
def self.lighten_color(my_hex,percent)
|
||||||
|
if my_hex[0] == '#'
|
||||||
|
my_hex = my_hex[1..-1]
|
||||||
|
end
|
||||||
|
rgb = my_hex.split(//).each_slice(my_hex.length/3).map{|v| v.join}
|
||||||
|
comp = rgb.collect do |a|
|
||||||
|
tmp = a.to_i(16)*(1+percent/100.0)
|
||||||
|
tmp = 255 if tmp>255
|
||||||
|
tmp = 0 if tmp < 0
|
||||||
|
tmp.to_i.to_s(16).rjust(2,'0')
|
||||||
|
end
|
||||||
|
'#'+comp.join
|
||||||
|
end
|
||||||
|
def set_image_version_for_widget
|
||||||
|
subpart = OrbitHelper.get_current_widget
|
||||||
|
@image_version = 'thumb'
|
||||||
|
if subpart.methods.include? 'select_options'.to_sym
|
||||||
|
ModuleApp.all.select{|tmp| tmp.key.to_s=='custom_announcement'}.each do |modile_app|
|
||||||
|
@show_options = modile_app.show_options rescue nil
|
||||||
|
end
|
||||||
|
subpart.select_options.each do |select_option|
|
||||||
|
if !(@show_options.nil?) && select_option.field_name == @show_options.keys.first.to_s
|
||||||
|
value = YAML.load(select_option.value)
|
||||||
|
tmp = value[:en]
|
||||||
|
I18n.with_locale(:en) do
|
||||||
|
if tmp == t('custom_announcement.small_size')
|
||||||
|
@image_version = 'thumb'
|
||||||
|
elsif tmp == t('custom_announcement.medium_size')
|
||||||
|
@image_version = 'mobile'
|
||||||
|
elsif tmp == t('custom_announcement.orignal_size')
|
||||||
|
@image_version = 'orignal'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def data_to_human_type(a,set_tag_ids=nil)
|
||||||
|
statuses = a.statuses_with_classname.collect do |status|
|
||||||
|
{
|
||||||
|
"status" => status["name"],
|
||||||
|
"status-class" => "status-#{status['classname']}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
files = a.custom_bulletin_files.map{|file| { "file_url" => file.file.url, "file_title" => (file.title.blank? ? File.basename(file.file.path) : file.title rescue '') } if file.enabled_for?(locale) } rescue []
|
||||||
|
files.delete(nil)
|
||||||
|
links = a.custom_bulletin_links.map{|link| { "link_url" => link.url, "link_title" => (link.title.blank? ? link.url : link.title) } } rescue []
|
||||||
|
author = User.find(a.create_user_id).member_profile.name rescue ""
|
||||||
|
desc = a.image_description
|
||||||
|
desc = (desc.nil? || desc == "" ? "custom_announcement image" : desc)
|
||||||
|
link_to_show = (a.is_external_link? ? a.external_link : OrbitHelper.widget_item_url(a.to_param)) rescue ""
|
||||||
|
target = a.is_external_link ? "_blank" : "_self"
|
||||||
|
if @image_version == 'thumb'
|
||||||
|
image_url = a.image.thumb.url
|
||||||
|
elsif @image_version == 'mobile'
|
||||||
|
image_url = a.image.mobile.url
|
||||||
|
else
|
||||||
|
image_url = a.image.url
|
||||||
|
end
|
||||||
|
{
|
||||||
|
"custom_bulletin_links" => links,
|
||||||
|
"custom_bulletin_files" => files,
|
||||||
|
"title" => a.title,
|
||||||
|
"source-site" => "",
|
||||||
|
"source-site-title" => "",
|
||||||
|
"source-site-link" => "",
|
||||||
|
"subtitle" => a.subtitle,
|
||||||
|
"statuses" => statuses,
|
||||||
|
"category" => (a.category.title rescue ''),
|
||||||
|
"tag_ids" => (set_tag_ids.nil? ? (a.tag_ids.map{|id| id.to_s}.to_s.gsub('"',"'") rescue '[]') : set_tag_ids),
|
||||||
|
"postdate" => a.postdate,
|
||||||
|
"author" => author,
|
||||||
|
"link_to_show" => link_to_show,
|
||||||
|
"target" => target,
|
||||||
|
"img_src" => image_url || "/assets/custom_announcement-default.jpg",
|
||||||
|
"img_description" => desc
|
||||||
|
}
|
||||||
|
end
|
||||||
|
def get_feed_annc(type,site_source,locale)
|
||||||
|
ma_key = 'custom_announcement'
|
||||||
|
if type == "index"
|
||||||
|
categories = Array(OrbitHelper.page_categories)
|
||||||
|
elsif type == "widget"
|
||||||
|
categories = Array(OrbitHelper.widget_categories)
|
||||||
|
else
|
||||||
|
categories = []
|
||||||
|
end
|
||||||
|
if categories.include?("all")
|
||||||
|
feeds = SiteFeedCustomAnnc.where(:channel_key => ma_key)
|
||||||
|
else
|
||||||
|
feeds = SiteFeedCustomAnnc.where(:channel_key => ma_key, :merge_with_category.in => categories)
|
||||||
|
end
|
||||||
|
if feeds.count > 0
|
||||||
|
temp_ids = []
|
||||||
|
data = feeds.collect do |feed|
|
||||||
|
feed.all_contents_for_feed(site_source,locale,type=='widget')
|
||||||
|
end.flatten.compact
|
||||||
|
else
|
||||||
|
data = []
|
||||||
|
end
|
||||||
|
data
|
||||||
|
end
|
||||||
|
def get_feed_custom_announcements(type,site_source=nil)
|
||||||
|
locale = OrbitHelper.get_site_locale.to_s
|
||||||
|
if !(defined? SiteFeedCustomAnnc).nil?
|
||||||
|
fans = get_feed_annc(type,site_source,locale)
|
||||||
|
else
|
||||||
|
feed_custom_anns = OrbitHelper.get_feed_for_module(type)
|
||||||
|
fans = []
|
||||||
|
feed_custom_anns.each do |fa|
|
||||||
|
next if !site_source.nil? && site_source != fa["source-site-title"]
|
||||||
|
status = {
|
||||||
|
"status" => "<a href='#{fa["source-site"]}' target='_blank' class='feed-source'>#{fa["source-site-title"]}</a>",
|
||||||
|
"status-class" => "status-source"
|
||||||
|
}
|
||||||
|
|
||||||
|
files = fa["custom_bulletin_files"].collect{|bf| { "file_url" => bf["url"], "file_title" => (fa["title_translations"][locale].blank? ? File.basename(fa["url"]) : fa["title_translations"][locale] rescue '') }} rescue []
|
||||||
|
links = fa["custom_bulletin_links"].map{|link| { "link_url" => link["url"], "link_title" => (link["title_translations"][locale].blank? ? link["url"] : link["title_translations"][locale]) } } rescue []
|
||||||
|
|
||||||
|
x = {
|
||||||
|
"custom_bulletin_links" => links,
|
||||||
|
"custom_bulletin_files" => files,
|
||||||
|
"custom_bulletin_carousel_images" => fa["custom_bulletin_carousel_images"].to_a,
|
||||||
|
"title" => fa["title_translations"][locale],
|
||||||
|
"subtitle" => fa["subtitle_translations"][locale],
|
||||||
|
"statuses" => [status],
|
||||||
|
"category" => fa["category"],
|
||||||
|
"postdate" => fa["postdate"],
|
||||||
|
"author" => fa["author"],
|
||||||
|
"source-site" => "<a href='#{fa["source-site"]}' target='_blank' class='feed-source'>#{fa["source-site-title"]}</a>",
|
||||||
|
"source-site-title" => fa["source-site-title"],
|
||||||
|
"source-site-link" => fa["source-site"],
|
||||||
|
"link_to_show" => OrbitHelper.url_to_show(fa["params"]),
|
||||||
|
"target" => "_self",
|
||||||
|
"img_src" => fa["image"]["thumb"] || "/assets/custom_announcement-default.jpg",
|
||||||
|
"img_description" => fa["image_description_translations"][locale],
|
||||||
|
"more" => t(:more_plus),
|
||||||
|
"view_count" => ""
|
||||||
|
}
|
||||||
|
if (!x["title"].empty? rescue false)
|
||||||
|
fans << x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fans
|
||||||
|
end
|
||||||
|
def filter_by_keywords(sorted,keywords,stime,etime)
|
||||||
|
kflag = keywords.blank?
|
||||||
|
sflag = stime.blank?
|
||||||
|
eflag = etime.blank?
|
||||||
|
stime = stime.to_s.split('/')
|
||||||
|
stime = Time.zone.local(*stime) rescue nil
|
||||||
|
etime = etime.to_s.split('/')
|
||||||
|
etime = Time.zone.local(*etime) rescue nil
|
||||||
|
if !kflag || !sflag || !eflag
|
||||||
|
sorted.select{|custom_anns|
|
||||||
|
if kflag
|
||||||
|
flag = true
|
||||||
|
else
|
||||||
|
if custom_anns["source-site"].present?
|
||||||
|
title = Nokogiri::HTML(custom_anns["title"].to_s).text
|
||||||
|
else
|
||||||
|
title = Nokogiri::HTML(custom_anns.title.to_s).text
|
||||||
|
end
|
||||||
|
flag = title.include?(keywords.to_s)
|
||||||
|
end
|
||||||
|
if sflag && !eflag
|
||||||
|
flag = flag && (custom_anns.postdate<=etime)
|
||||||
|
elsif !sflag && eflag
|
||||||
|
flag = flag && (custom_anns.postdate>=stime)
|
||||||
|
elsif !sflag && !eflag
|
||||||
|
flag = flag && (custom_anns.postdate>=stime) && (custom_anns.postdate<=etime)
|
||||||
|
end
|
||||||
|
flag
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sorted
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def get_sorted_annc(data_count=nil)
|
||||||
|
params = OrbitHelper.params
|
||||||
|
locale = OrbitHelper.get_site_locale.to_s
|
||||||
|
page_number = OrbitHelper.page_number.to_i
|
||||||
|
page = OrbitHelper.page rescue nil
|
||||||
|
unless page
|
||||||
|
page = Page.where(url:params['url']).first
|
||||||
|
end
|
||||||
|
page_number = 1 if page_number == 0
|
||||||
|
page_data_count = data_count || OrbitHelper.page_data_count.to_i
|
||||||
|
feeds_custom_anns = []
|
||||||
|
custom_data_field = page.custom_data_field rescue nil
|
||||||
|
if custom_data_field.nil?
|
||||||
|
custom_data_field = {}
|
||||||
|
elsif custom_data_field["bind_module_app"]
|
||||||
|
custom_data_field["custom_module"] = custom_data_field["bind_module_app"]
|
||||||
|
custom_data_field.delete('bind_module_app')
|
||||||
|
end
|
||||||
|
if @type == "show_widget"
|
||||||
|
tags = @tags
|
||||||
|
categories = @categories
|
||||||
|
else
|
||||||
|
tags = page.tags
|
||||||
|
tags = params[:tags] if params[:tags].present?
|
||||||
|
categories = params['category']=='all' ? (page.categories || []) : (Array(params['category']) rescue (page.categories || []))
|
||||||
|
if params['category'].present?
|
||||||
|
tags = ["all"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !params["source"].present?
|
||||||
|
if @type == "show_widget"
|
||||||
|
if params[:uids].blank?
|
||||||
|
custom_announcements = CustomBulletin.where(:title.nin => ["",nil],:is_preview.in=>[false,nil]).where(custom_data_field)
|
||||||
|
.can_display_and_sorted.is_approved
|
||||||
|
.filter_by_categories(categories,false).filter_by_tags(tags).to_a
|
||||||
|
else
|
||||||
|
member_prfile = MemberProfile.any_in(:uid=>params[:uids])
|
||||||
|
user_ids = member_prfile.map{|m| m.user.id rescue nil}.select{|id| !id.nil?}
|
||||||
|
custom_announcements = CustomBulletin.where(:title.nin => ["",nil],:is_preview.in=>[false,nil],:create_user_id.in=>user_ids).where(custom_data_field)
|
||||||
|
.can_display_and_sorted.is_approved
|
||||||
|
.filter_by_categories(categories,false).filter_by_tags(tags).to_a
|
||||||
|
end
|
||||||
|
else
|
||||||
|
custom_announcements = CustomBulletin.where(:title.nin => ["",nil],:is_preview.in=>[false,nil]).where(custom_data_field)
|
||||||
|
.can_display_and_sorted.is_approved
|
||||||
|
.filter_by_categories(categories,false).filter_by_tags(tags).to_a
|
||||||
|
end
|
||||||
|
if !(defined? SiteFeed).nil?
|
||||||
|
if @type != "show_widget"
|
||||||
|
feeds_custom_anns = get_feed_custom_announcements("index")
|
||||||
|
else
|
||||||
|
feeds_custom_anns = []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
custom_announcements = []
|
||||||
|
if @type != "show_widget"
|
||||||
|
feeds_custom_anns = get_feed_custom_announcements("index",params["source"])
|
||||||
|
else
|
||||||
|
feeds_custom_anns = []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !feeds_custom_anns.blank?
|
||||||
|
if custom_announcements.count != 0
|
||||||
|
top_custom_anns = custom_announcements.select{|v| v.is_top} + feeds_custom_anns.select{|v| v['is_top']}
|
||||||
|
rest_all_custom_anns = feeds_custom_anns.select{|v| v['is_top'] != true} + custom_announcements.select{|v| !v.is_top}
|
||||||
|
rest_custom_anns = rest_all_custom_anns.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]}
|
||||||
|
all_sorted = top_custom_anns.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]} + rest_custom_anns
|
||||||
|
else
|
||||||
|
all_sorted = feeds_custom_anns.select{|v| v['is_top']}.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]} + feeds_custom_anns.select{|v| v['is_top'] != true}.sort{|v1,v2| v2["postdate"]<=>v1["postdate"]}
|
||||||
|
end
|
||||||
|
all_filter = filter_by_keywords(all_sorted,params[:keywords],params[:stime],params[:etime])
|
||||||
|
else
|
||||||
|
all_filter = filter_by_keywords(custom_announcements,params[:keywords],params[:stime],params[:etime])
|
||||||
|
end
|
||||||
|
if page_data_count != 0
|
||||||
|
sorted = all_filter[(page_number-1)*page_data_count...page_number*page_data_count]
|
||||||
|
else
|
||||||
|
sorted = all_filter
|
||||||
|
end
|
||||||
|
annc_count = all_filter.count
|
||||||
|
total_pages = page_data_count == 0 ? 1 : (annc_count.to_f / page_data_count).ceil
|
||||||
|
[sorted,total_pages]
|
||||||
|
end
|
||||||
|
def render_view_for_annc(overridehtml=nil)
|
||||||
|
@key = Site.first.template
|
||||||
|
def render_link_to_edit(html, url_to_edit)
|
||||||
|
if html.scan("{{link_to_edit}}").length == 0
|
||||||
|
html = url_to_edit.blank? ? html : html + "<p class='admin-edit text-right'><a class='btn btn-primary' href='#{url_to_edit}'><i class='icon-edit'></i> #{t(:edit)}</a></p>"
|
||||||
|
else
|
||||||
|
html = url_to_edit.blank? ? html.gsub("{{link_to_edit}}","") : html.gsub("{{link_to_edit}}","<p class='admin-edit text-right'><a class='btn btn-primary' href='#{url_to_edit}'><i class='icon-edit'></i> #{t(:edit)}</a></p>")
|
||||||
|
end
|
||||||
|
return html
|
||||||
|
end
|
||||||
|
|
||||||
|
def parsing_repeats_again(elements,d,level)
|
||||||
|
newhtml = []
|
||||||
|
oldhtml = []
|
||||||
|
elements.each do |el|
|
||||||
|
html_to_render = ""
|
||||||
|
data_name = el.attr("data-list")
|
||||||
|
wrap_elements = el.css("*[data-list][data-level='#{level}']")
|
||||||
|
if d[data_name]
|
||||||
|
d[data_name].each_with_index do |item,i|
|
||||||
|
element = el.inner_html
|
||||||
|
if wrap_elements.count > 0
|
||||||
|
htmls = parsing_repeats_again(wrap_elements,d[data_name][i], level + 1)
|
||||||
|
htmls[0].each_with_index do |html,i|
|
||||||
|
element = element.gsub(html,htmls[1][i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
item.each do |key,value|
|
||||||
|
if !value.kind_of?(Array)
|
||||||
|
value = value.nil? ? "" : value
|
||||||
|
element = element.gsub("{{#{key}}}",value.to_s.html_safe)
|
||||||
|
element = element.gsub("%7B%7B#{key}%7D%7D",value.to_s.html_safe)
|
||||||
|
element = render_link_to_edit(element, value) if key.eql?("url_to_edit")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
html_to_render = html_to_render + element
|
||||||
|
end
|
||||||
|
temp = el.to_s
|
||||||
|
oldhtml << temp
|
||||||
|
temp = temp.gsub(el.inner_html, html_to_render)
|
||||||
|
newhtml << temp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
[oldhtml,newhtml]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if @target_action == "index"
|
||||||
|
filename = overridehtml.nil? ? params[:layout_type] : overridehtml
|
||||||
|
f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', 'custom_announcement', "#{filename}.html.erb")
|
||||||
|
if !File.exists?f
|
||||||
|
f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', 'custom_announcement', "index.html.erb")
|
||||||
|
if !File.exists?f
|
||||||
|
return "<div class='well'>Maybe the administrator has changed the theme, please select the index page design again from the page settings.</div>".html_safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
file = File.open(f)
|
||||||
|
doc = Nokogiri::HTML(file, nil, "UTF-8")
|
||||||
|
file.close
|
||||||
|
controller = CustomAnnouncementsController.new
|
||||||
|
begin
|
||||||
|
data = @data# rescue nil
|
||||||
|
rescue Exception => e
|
||||||
|
write_debug_file(e,'custom_announcements',@target_action) if Site::DEBUG
|
||||||
|
end
|
||||||
|
if !data.nil?
|
||||||
|
wrap_elements = doc.css("*[data-list][data-level='0']")
|
||||||
|
htmls = parsing_repeats_again(wrap_elements,data,1)
|
||||||
|
html = doc.to_s
|
||||||
|
htmls[0].each_with_index do |h,i|
|
||||||
|
html = html.gsub(h,htmls[1][i])
|
||||||
|
end
|
||||||
|
extras = data["extras"] || {}
|
||||||
|
extras["page-title"] = Page.find_by(:page_id => params[:page_id]).name rescue "" if !extras["page-title"]
|
||||||
|
extras.each do |key,value|
|
||||||
|
value = value.nil? ? "" : value
|
||||||
|
html = html.gsub("{{#{key}}}",value.to_s.html_safe)
|
||||||
|
html = html.gsub("%7B%7B#{key}%7D%7D",value.to_s.html_safe)
|
||||||
|
end
|
||||||
|
total_pages = data['total_pages'].to_i rescue 1
|
||||||
|
if total_pages > 1
|
||||||
|
html = html.gsub("{{pagination_goes_here}}",create_pagination(total_pages))
|
||||||
|
else
|
||||||
|
html = html.gsub("{{pagination_goes_here}}","");
|
||||||
|
end
|
||||||
|
html.html_safe
|
||||||
|
else
|
||||||
|
return "<div class='well'>No content to show.</div>".html_safe
|
||||||
|
end
|
||||||
|
else
|
||||||
|
filename = overridehtml.nil? ? @target_action : overridehtml
|
||||||
|
f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', 'custom_announcement', "#{filename}.html.erb")
|
||||||
|
if File.exists?f
|
||||||
|
file = File.open(f)
|
||||||
|
doc = Nokogiri::HTML(file, nil, "UTF-8")
|
||||||
|
file.close
|
||||||
|
controller = CustomAnnouncementsController.new
|
||||||
|
begin
|
||||||
|
data = @data# rescue nil
|
||||||
|
rescue Exception => e
|
||||||
|
write_debug_file(e,'custom_announcements',@target_action) if Site::DEBUG
|
||||||
|
end
|
||||||
|
if data.nil?
|
||||||
|
return "<div class='well'> No content to show. </div>".html_safe
|
||||||
|
end
|
||||||
|
|
||||||
|
if data.blank? || data.empty?
|
||||||
|
file = File.open("#{Rails.root}/app/views/errors/404.html")
|
||||||
|
doc = Nokogiri::HTML(file, nil, "UTF-8")
|
||||||
|
file.close
|
||||||
|
doc.to_html.html_safe
|
||||||
|
else
|
||||||
|
unless data['impressionist'].blank?
|
||||||
|
Thread.new do
|
||||||
|
impression = data['impressionist'].impressions.create
|
||||||
|
impression.user_id = request.session['user_id']
|
||||||
|
impression.controller_name = 'custom_announcements'
|
||||||
|
impression.action_name = @target_action
|
||||||
|
impression.ip_address = request.remote_ip
|
||||||
|
impression.session_hash = request.session.id
|
||||||
|
impression.request_hash = @impressionist_hash
|
||||||
|
impression.referrer = request.referrer
|
||||||
|
impression.save
|
||||||
|
end
|
||||||
|
data['impressionist'].inc(view_count: 1)
|
||||||
|
data["data"]["view_count"] = data["impressionist"].view_count if data["data"].present?
|
||||||
|
end
|
||||||
|
wrap_elements = doc.css("*[data-list][data-level='0']")
|
||||||
|
if wrap_elements.count == 0
|
||||||
|
wrap_element_html = doc.to_s
|
||||||
|
el = wrap_element_html
|
||||||
|
data.each do |key,value|
|
||||||
|
next if key.eql? 'impressionist'
|
||||||
|
value = value.nil? ? "" : value
|
||||||
|
el = el.gsub("{{#{key}}}",value.to_s.html_safe)
|
||||||
|
el = el.gsub("%7B%7B#{key}%7D%7D",value.to_s.html_safe)
|
||||||
|
end
|
||||||
|
el.html_safe
|
||||||
|
else
|
||||||
|
keys = data.keys
|
||||||
|
not_array_key = nil
|
||||||
|
data.keys.each do |key|
|
||||||
|
not_array_key = key if data["#{key}"].kind_of?(Hash)
|
||||||
|
end
|
||||||
|
htmls = parsing_repeats_again(wrap_elements,data,1)
|
||||||
|
html = doc.to_s
|
||||||
|
htmls[0].each_with_index do |h,i|
|
||||||
|
html = html.gsub(h,htmls[1][i])
|
||||||
|
end
|
||||||
|
extras = data["#{not_array_key}"] || {}
|
||||||
|
extras.each do |key,value|
|
||||||
|
next if key.eql? 'impressionist'
|
||||||
|
value = value.nil? ? "" : value
|
||||||
|
html = html.gsub("{{#{key}}}",value.to_s)
|
||||||
|
html = html.gsub("%7B%7B#{key}%7D%7D",value.to_s)
|
||||||
|
end
|
||||||
|
html = render_link_to_edit(html, data["url_to_edit"]) if !data["url_to_edit"].nil?
|
||||||
|
total_pages = data['total_pages'].to_i rescue 1
|
||||||
|
if @show_page == "false"
|
||||||
|
html = html.gsub("{{pagination_goes_here}}","")
|
||||||
|
else
|
||||||
|
if total_pages > 1
|
||||||
|
html = html.gsub("{{pagination_goes_here}}",create_pagination(total_pages))
|
||||||
|
else
|
||||||
|
html = html.gsub("{{pagination_goes_here}}","")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
html = Nokogiri::HTML.parse(html)
|
||||||
|
html.css('.i-annc__page-title').remove
|
||||||
|
dates = html.css("*[date-format]")
|
||||||
|
if !dates.blank?
|
||||||
|
dates.each do |d|
|
||||||
|
begin
|
||||||
|
format = d.attributes["date-format"].value
|
||||||
|
date = DateTime.parse(d.inner_text)
|
||||||
|
d.inner_html = d.inner_html.gsub(d.inner_text.strip, " " + date.strftime(format))
|
||||||
|
rescue
|
||||||
|
next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
html.css("body")[0].inner_html = html.css("body")[0].inner_html.gsub("{{page-title}}","")
|
||||||
|
html.css("body").to_html.html_safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return "<div class='well'>There is a problem with the design. We will try to fix it as soon as possible. Sorry for the inconvenience!! :(</div>".html_safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def get_layouts(module_app)
|
||||||
|
layout_types = []
|
||||||
|
@key = Site.first.template
|
||||||
|
f = File.join("#{Rails.root}/app/templates/#{@key}/modules/#{module_app}/info.json")
|
||||||
|
if File.exists?f
|
||||||
|
info = File.read(f)
|
||||||
|
hash = JSON.parse(info) rescue {}
|
||||||
|
frontends = hash["frontend"] || []
|
||||||
|
frontends.each do |frontend|
|
||||||
|
frontend["thumbnail"] = "/assets/#{module_app}/thumbs/#{frontend["thumbnail"]}"
|
||||||
|
layout_types << frontend
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if layout_types.empty?
|
||||||
|
Dir.glob("#{Rails.root}/app/templates/#{@key}/modules/#{module_app}/*").each do |w|
|
||||||
|
next if File.ftype(w).eql?("directory")
|
||||||
|
w = File.basename(w, ".*")
|
||||||
|
w = File.basename(w, ".*")
|
||||||
|
if w[0,1] != "_" && w[0,1] != "s" && w != "info"
|
||||||
|
layout_types << w
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
layout_types
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
class CustomAnnouncementSetting
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
field :top_limit, type: Integer, :default => 0
|
||||||
|
field :pro_enabled, type: Boolean, :default => false
|
||||||
|
field :approvers, type: Array, :default => []
|
||||||
|
field :email_to, type: Array, :default => ["admins","managers","approvers"]
|
||||||
|
field :is_display_edit_only, type: Boolean, :default => false
|
||||||
|
field :only_manager_can_edit_status, type: Boolean, :default => false
|
||||||
|
field :top_text , type: String , localize: true
|
||||||
|
field :hot_text , type: String , localize: true
|
||||||
|
field :hidden_text , type: String , localize: true
|
||||||
|
has_many :custom_anns_status_settings, :autosave => true, :dependent => :destroy
|
||||||
|
accepts_nested_attributes_for :custom_anns_status_settings, :allow_destroy => true
|
||||||
|
def self.check_limit_for_user(user_id, b_id = nil)
|
||||||
|
limit = self.first.top_limit rescue 0
|
||||||
|
return true if limit == 0
|
||||||
|
count = CustomBulletin.where(:is_top => true, :create_user_id => user_id, :id.ne => b_id).count
|
||||||
|
return count < limit
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.is_pro?
|
||||||
|
self.first.pro_enabled rescue false
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,6 @@
|
||||||
|
class CustomAnnsCache
|
||||||
|
include Mongoid::Document
|
||||||
|
field :parent_id
|
||||||
|
field :filter_result
|
||||||
|
field :locale,type: String,default: 'zh_tw'
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
class CustomAnnsStatusSetting
|
||||||
|
include Mongoid::Document
|
||||||
|
field :role_id
|
||||||
|
field :status
|
||||||
|
field :top_limit
|
||||||
|
belongs_to :custom_announcement_setting
|
||||||
|
end
|
|
@ -0,0 +1,246 @@
|
||||||
|
class CustomBulletin
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
include OrbitModel::Status
|
||||||
|
include OrbitModel::Impression
|
||||||
|
# encoding: utf-8
|
||||||
|
include OrbitTag::Taggable
|
||||||
|
include OrbitCategory::Categorizable
|
||||||
|
include Slug
|
||||||
|
require 'custom_bulletin_model/cache'
|
||||||
|
include ::CustomBulletinModel::Cache
|
||||||
|
attr_accessor :org_tag_ids
|
||||||
|
def tags=(ids)
|
||||||
|
self.org_tag_ids = self.tag_ids
|
||||||
|
super(ids)
|
||||||
|
end
|
||||||
|
def []=(index,value)
|
||||||
|
if index.to_s=='tags'
|
||||||
|
self.org_tag_ids = self.tag_ids
|
||||||
|
end
|
||||||
|
super(index,value)
|
||||||
|
end
|
||||||
|
SubPart.class_eval { include CustomBulletinModel::Cache }
|
||||||
|
Page.class_eval { include CustomBulletinModel::Cache }
|
||||||
|
before_destroy do
|
||||||
|
CustomAnnsCache.all.destroy
|
||||||
|
end
|
||||||
|
field :custom_module
|
||||||
|
field :bind_uid
|
||||||
|
field :image_display_class, type: String, default: "full-size-img" #3 choices: full-size-img , pull-left , pull-right
|
||||||
|
field :add_to_calendar,type: Boolean,default: false
|
||||||
|
field :calendar_start_date, :type => DateTime
|
||||||
|
field :calendar_end_date, :type => DateTime
|
||||||
|
field :calendar_all_day,type: Boolean,default: false
|
||||||
|
field :calendar_type_id
|
||||||
|
field :event_id
|
||||||
|
field :page_id
|
||||||
|
field :title, type: String, localize: true
|
||||||
|
field :subtitle, localize: true
|
||||||
|
field :text, localize: true
|
||||||
|
field :create_user_id
|
||||||
|
field :update_user_id
|
||||||
|
field :public, :type => Boolean, :default => true
|
||||||
|
field :postdate , :type => DateTime, :default => Time.now
|
||||||
|
field :deadline , :type => DateTime
|
||||||
|
field :rss2_sn
|
||||||
|
field :approved, :type => Boolean, :default => false
|
||||||
|
field :is_preview, :type => Boolean, :default => false
|
||||||
|
field :expirable_created_at, type: DateTime
|
||||||
|
field :rejected, :type => Boolean, :default => false
|
||||||
|
field :reapproval, :type => Boolean, :default => false
|
||||||
|
field :rejection_reason
|
||||||
|
field :is_external_link, :type => Boolean, :default => false
|
||||||
|
field :external_link
|
||||||
|
field :display_subtitle, :type => Boolean, :default => false
|
||||||
|
field :display_img, :type => Boolean, :default => false
|
||||||
|
|
||||||
|
field :email_id
|
||||||
|
field :email_sent, :type => Boolean, :default => false
|
||||||
|
field :email_sentdate , :type => DateTime
|
||||||
|
field :email_member_ids
|
||||||
|
field :other_mailaddress
|
||||||
|
field :image_description, localize: true
|
||||||
|
field :top_end_date, :type => DateTime
|
||||||
|
field :open_comment, :type => Boolean, :default => false
|
||||||
|
field :comment_end_time, :type => DateTime
|
||||||
|
field :comment_role, :type => Array, :default => []
|
||||||
|
|
||||||
|
mount_uploader :image, ImageUploader
|
||||||
|
|
||||||
|
has_many :custom_bulletin_links, :autosave => true, :dependent => :destroy
|
||||||
|
has_many :custom_bulletin_files, :autosave => true, :dependent => :destroy
|
||||||
|
has_many :custom_bulletin_comments, :autosave => true, :dependent => :destroy
|
||||||
|
has_many :custom_bulletin_carousel_images, :autosave => true, :dependent => :destroy
|
||||||
|
accepts_nested_attributes_for :custom_bulletin_files, :allow_destroy => true
|
||||||
|
accepts_nested_attributes_for :custom_bulletin_links, :allow_destroy => true
|
||||||
|
accepts_nested_attributes_for :custom_bulletin_carousel_images, :allow_destroy => true
|
||||||
|
|
||||||
|
before_destroy :destroy_email
|
||||||
|
|
||||||
|
scope :can_display_and_sorted, ->{where(:is_hidden=>false,:is_preview => false).any_of({:postdate.lte=>Time.now, :deadline.gte=>Time.now},{:postdate.lte=>Time.now, :deadline=>nil},{:postdate=>nil}).order(is_top: :desc,postdate: :desc,id: :desc)}
|
||||||
|
scope :is_approved, ->{where(:approved => true)}
|
||||||
|
|
||||||
|
before_create :set_expire
|
||||||
|
before_save :check_limit
|
||||||
|
|
||||||
|
after_create do
|
||||||
|
custom_record_callback(1)
|
||||||
|
end
|
||||||
|
after_destroy do
|
||||||
|
custom_record_callback(-1)
|
||||||
|
end
|
||||||
|
def custom_record_callback(num)
|
||||||
|
if self.custom_module && self.bind_uid.present?
|
||||||
|
custom_bulletin_config = CustomBulletinConfig.where(:module=>self.custom_module).first
|
||||||
|
if custom_bulletin_config && custom_bulletin_config.custom_record_callback.present? && custom_bulletin_config.bind_model.present?
|
||||||
|
target_model = custom_bulletin_config.bind_model.constantize rescue nil
|
||||||
|
if target_model
|
||||||
|
target_record = target_model.where(custom_bulletin_config.uid_field=>self.bind_uid).first
|
||||||
|
target_record.send(custom_bulletin_config.custom_record_callback,num)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def to_calendar_param
|
||||||
|
self.to_param
|
||||||
|
end
|
||||||
|
def calendar_type
|
||||||
|
CalendarType.where(:category_id.in => self.calendar_type_id)
|
||||||
|
end
|
||||||
|
def event
|
||||||
|
if !self.event_id.nil?
|
||||||
|
Event.where(:id => self.event_id).first
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def check_limit
|
||||||
|
check_status_limit(update_user)
|
||||||
|
end
|
||||||
|
def check_status_limit(user,check_only=false)
|
||||||
|
role_ids = user.member_profile.roles.map(&:id) rescue []
|
||||||
|
status_settings = (role_ids.collect do |role_id|
|
||||||
|
CustomAnnouncementSetting.first.custom_anns_status_settings.select{|v| v.role_id.to_s == role_id.to_s}
|
||||||
|
end.flatten rescue [])
|
||||||
|
reach_limit = []
|
||||||
|
if status_settings.count != 0
|
||||||
|
reach_limit = status_settings.collect do |status_setting|
|
||||||
|
status = status_setting.status
|
||||||
|
if status_setting.top_limit.to_i <= CustomBulletin.where(:update_user_id.in => Role.find(status_setting.role_id).member_profiles.collect(&:user).flatten.uniq.map{|v| v.id},status => true).count
|
||||||
|
if !check_only
|
||||||
|
if self[status] && !CustomBulletin.where(id:self.id).first[status]
|
||||||
|
self[status] = false
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
status
|
||||||
|
end
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end.compact
|
||||||
|
reach_limit = reach_limit.group_by{|v| v}.collect do |k,v|
|
||||||
|
if v.count >= user.member_profile.roles.count
|
||||||
|
k
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end.compact
|
||||||
|
end
|
||||||
|
reach_limit
|
||||||
|
end
|
||||||
|
def slug_title
|
||||||
|
doc = Nokogiri::HTML(self.title)
|
||||||
|
title = doc.text.gsub('/','-')
|
||||||
|
end
|
||||||
|
def set_expire
|
||||||
|
self.expirable_created_at = Time.now if self.is_preview
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_user
|
||||||
|
User.find(update_user_id) rescue nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_user=(user)
|
||||||
|
self.update_user_id = user.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def email_members
|
||||||
|
MemberProfile.find(self.email_member_ids) rescue []
|
||||||
|
end
|
||||||
|
|
||||||
|
def email_addresses
|
||||||
|
addresses = self.email_members.collect{|member| member.email} rescue []
|
||||||
|
addresses = addresses +[self.other_mailaddress] if !self.other_mailaddress.blank?
|
||||||
|
addresses.flatten
|
||||||
|
end
|
||||||
|
|
||||||
|
def email
|
||||||
|
mail = Email.find(self.email_id) rescue nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def expired?
|
||||||
|
(self.deadline < Time.now) rescue false
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_email
|
||||||
|
mail = Email.find(self.email_id) rescue nil
|
||||||
|
mail.destroy if !mail.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.remove_expired_status
|
||||||
|
self.where(:is_top => true, :top_end_date.ne => nil, :top_end_date.lt => Time.now).each do |b|
|
||||||
|
b.is_top = false
|
||||||
|
b.top_end_date = nil
|
||||||
|
b.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_subtitle?
|
||||||
|
self.display_subtitle rescue false
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_img?
|
||||||
|
self.display_img rescue false
|
||||||
|
end
|
||||||
|
def comments
|
||||||
|
self.custom_bulletin_comments.select{|v| !v.is_hidden}
|
||||||
|
end
|
||||||
|
def open_comment_for_user(user)
|
||||||
|
role_ids = user.member_profile.roles.collect{|v| v.id.to_s} rescue ['visitor']
|
||||||
|
self.open_comment && (self.comment_end_time.blank? || self.comment_end_time > Time.now) && (self.comment_role.any?{|v| role_ids.include?(v)} || self.comment_role.include?('visitor') || (self.comment_role.include?('all_member') && role_ids[0] != 'visitor'))
|
||||||
|
end
|
||||||
|
def statuses
|
||||||
|
statuses = []
|
||||||
|
statuses << top_text if is_top?
|
||||||
|
statuses << hot_text if is_hot?
|
||||||
|
statuses << hidden_text if is_hidden?
|
||||||
|
statuses
|
||||||
|
end
|
||||||
|
def statuses_with_classname
|
||||||
|
statuses = []
|
||||||
|
statuses << {"name" => top_text, "classname" => "top"} if is_top?
|
||||||
|
statuses << {"name" => hot_text, "classname" => "hot"} if is_hot?
|
||||||
|
statuses << {"name" => hidden_text, "classname" => "hidden"} if is_hidden?
|
||||||
|
statuses
|
||||||
|
end
|
||||||
|
def status_for_table
|
||||||
|
status = ""
|
||||||
|
status << "<span class='label label-success'>#{top_text}</span> " if self.is_top
|
||||||
|
status << "<span class='label label-important'>#{hot_text}</span> " if self.is_hot
|
||||||
|
status << "<span class='label'>#{hidden_text}</span>"if self.is_hidden
|
||||||
|
status.html_safe
|
||||||
|
end
|
||||||
|
def top_text
|
||||||
|
I18n.t("custom_announcement.status.top")
|
||||||
|
end
|
||||||
|
def hot_text
|
||||||
|
I18n.t("custom_announcement.status.hot")
|
||||||
|
end
|
||||||
|
def hidden_text
|
||||||
|
I18n.t("custom_announcement.status.hidden")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
class CustomBulletinCarouselImage
|
||||||
|
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
mount_uploader :file, AssetUploader
|
||||||
|
|
||||||
|
field :description, localize: true
|
||||||
|
|
||||||
|
belongs_to :custom_bulletin
|
||||||
|
def description_text
|
||||||
|
Nokogiri::HTML(self.description.to_s).css("body").text() rescue ""
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
class CustomBulletinComment
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
field :ip
|
||||||
|
field :comment
|
||||||
|
field :account_id
|
||||||
|
field :is_hidden,type: Boolean,default: false
|
||||||
|
def time
|
||||||
|
self.created_at.strftime('%Y/%m/%d %H:%M')
|
||||||
|
end
|
||||||
|
def account
|
||||||
|
tmp = MemberProfile.where(:id => self.account_id).collect{|v| v.name}.join
|
||||||
|
tmp.blank? ? I18n.t('custom_announcement_visitor') : tmp
|
||||||
|
end
|
||||||
|
def roles
|
||||||
|
MemberProfile.where(:id => self.account_id).collect{|v| v.roles}.flatten
|
||||||
|
end
|
||||||
|
belongs_to :custom_bulletin
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
class CustomBulletinConfig
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
field :module
|
||||||
|
field :bind_model , :type => String
|
||||||
|
field :title_field , :type => String , :default => "slug_title"
|
||||||
|
field :uid_field , :type => String , :default => "uid"
|
||||||
|
field :custom_record_callback #if exists, it will call 'custom_record_callback(num)'
|
||||||
|
#where num is 1 when create bulletin, num is -1 when destroy.
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
class CustomBulletinFeed
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
include Slug
|
||||||
|
|
||||||
|
field :title, as: :slug_title, type: String, localize: true
|
||||||
|
field :tag_ids, type: Array, default: []
|
||||||
|
before_save do
|
||||||
|
CustomBulletinFeedCache.where(uid: self.uid).destroy
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
class CustomBulletinFeedCache
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
field :content, type: String, default: ''
|
||||||
|
field :uid
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,38 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
class CustomBulletinFile
|
||||||
|
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
mount_uploader :file, AssetUploader
|
||||||
|
|
||||||
|
field :description, localize: true
|
||||||
|
field :title, localize: true
|
||||||
|
field :choose_lang, :type => Array, :default => ["en","zh_tw"]
|
||||||
|
field :privacy_type, type: String, default: 'public'
|
||||||
|
belongs_to :custom_bulletin
|
||||||
|
|
||||||
|
def file_title
|
||||||
|
if self.description.present?
|
||||||
|
return self.description
|
||||||
|
elsif self.title.present?
|
||||||
|
return self.title
|
||||||
|
else
|
||||||
|
return File.basename(self.file.path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def enabled_for?(lang)
|
||||||
|
if lang.nil?
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return self.choose_lang.include?(lang)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def can_access?(user)
|
||||||
|
if user.nil? && self.privacy_type == 'logged_in'
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
|
class CustomBulletinLink
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
field :url
|
||||||
|
field :title, localize: true
|
||||||
|
|
||||||
|
belongs_to :custom_bulletin
|
||||||
|
|
||||||
|
before_validation :add_http
|
||||||
|
|
||||||
|
#validates :url, :presence => true, :format => /\A(http|https):\/\/(([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5})|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(:[0-9]{1,5})?(\/.*)?\Z/i
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def add_http
|
||||||
|
unless self.url[/^http:\/\//] || self.url[/^https:\/\//]
|
||||||
|
self.url = 'http://' + self.url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,122 @@
|
||||||
|
<style>
|
||||||
|
#approvalModal {
|
||||||
|
width: 90%;
|
||||||
|
height: 600px;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#approvalModal .preview-iframe {
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#approvalModal .modal-body {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0;
|
||||||
|
max-height: none;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#approvalModal .modal-left {
|
||||||
|
overflow: auto;
|
||||||
|
float: left;
|
||||||
|
width: 19.8%;
|
||||||
|
border-right: 1px solid #DFDFDF;
|
||||||
|
height: 100%;
|
||||||
|
padding: 1em;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
#approvalModal .modal-right {
|
||||||
|
float: right;
|
||||||
|
width: 80%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.approvalModal__form {
|
||||||
|
padding: 0 10px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
label.approvalModal__radio {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
label.control-label {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approvalModal__controls {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.approvalModal__group {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.approvalModal__label {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 4px 0 7px;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
.approvalModal__controls .approvalModal__privacy {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
.approvalModal__controls .approvalModal__large {
|
||||||
|
}
|
||||||
|
#approvalModal .modal-footer {
|
||||||
|
text-align: left;
|
||||||
|
padding: 15px 10px 10px;
|
||||||
|
}
|
||||||
|
.approvalModal__group.confirm {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="approvalModal" class="modal hide fade" role="dialog">
|
||||||
|
<div class="modal-header">
|
||||||
|
<a class="close" data-dismiss="modal">×</a>
|
||||||
|
<h3>預覽</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body clearfix">
|
||||||
|
<div class="modal-left">
|
||||||
|
<label for="____">寄送對象</label>
|
||||||
|
</div>
|
||||||
|
<div class="modal-right">
|
||||||
|
<iframe class="preview-iframe"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<%= form_tag "/admin/custom_announcement/approve_custom_bulletin", :class=>"approvalModal__form" do %>
|
||||||
|
<div class="approvalModal__group">
|
||||||
|
<label class="control-label" for="custom_bulletin_approval_stat">審核狀態</label>
|
||||||
|
<div class="approvalModal__controls">
|
||||||
|
<label class="approvalModal__radio">
|
||||||
|
<input class="approvalModal__privacy" id="custom_bulletin_is_checked_true" name="approved" type="radio" value="true">已認可
|
||||||
|
</label>
|
||||||
|
<label class="approvalModal__radio">
|
||||||
|
<input checked="checked" class="approvalModal__privacy" id="custom_bulletin_approved_false" name="approved" type="radio" value="false">拒絕
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="approvalModal__group group--reject">
|
||||||
|
<label class="approvalModal__label" for="is_checked_false_拒絕原因">拒絕原因</label>
|
||||||
|
<div class="approvalModal__controls">
|
||||||
|
<input class="approvalModal__large" id="custom_bulletin_not_checked_reason" name="reason" size="30" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="approvalModal__group confirm">
|
||||||
|
<input class="approvalModal__btn btn btn-primary" name="commit" type="submit" value="送出">
|
||||||
|
<input type="hidden" id="object_id" name="id" />
|
||||||
|
<button class="approvalModal__btn btn" data-dismiss="modal" aria-hidden="true">關閉</button>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<table class="table main-list">
|
||||||
|
<thead>
|
||||||
|
<tr class="sort-header">
|
||||||
|
<% @table_feed_fields.each do |f| %>
|
||||||
|
<%= thead(f) %>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @comments.each do |comment| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= comment.time %></td>
|
||||||
|
<td><%= comment.comment.html_safe %></td>
|
||||||
|
<td>
|
||||||
|
<%= comment.account %>
|
||||||
|
<% comment.roles.each do |role| %>
|
||||||
|
<span class="label"><%= role.title rescue '' %></span>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
<td><%= comment.ip %></td>
|
||||||
|
<td><%= button_tag (comment.is_hidden ? t('show') : t('is_hidden')), type: 'button',"data-href" => "/#{I18n.locale}/admin/annc-comment-hidden/#{comment.id}",:onclick => "update_status(this)" ,class: (comment.is_hidden ? 'btn btn-primary' : 'btn btn-info') %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<%= form_for @custom_announcement_feed, url: admin_custom_announcement_updatefeed_path(:id => @custom_announcement_feed.id), html: {class: "form-horizontal main-forms"} do |f| %>
|
||||||
|
<fieldset>
|
||||||
|
<% @site_in_use_locales.each do |locale| %>
|
||||||
|
<%= f.fields_for :title_translations do |f| %>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted" for="custom_bulletin_feed_title_translations_<%= locale.to_s %>"><%= t(:title) + " (#{t(locale.to_s)})" %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.text_field locale, data: {"fv-validation" => "required;","fv-messages" => "Cannot be empty.;"}, value: (@custom_announcement_feed.title_translations[locale.to_s] rescue nil) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<hr />
|
||||||
|
<div class="tags">
|
||||||
|
<div id="tags-list">
|
||||||
|
<ul class="tags-groups checkbox-card module-tags">
|
||||||
|
<% @module_app.tags.each do |tag| %>
|
||||||
|
<li class="filter-item module">
|
||||||
|
<p class='card pull-left <%= @custom_announcement_feed.tag_ids.include?(tag.id.to_s) ? "active" : "" %>'>
|
||||||
|
<input type="checkbox" <%= @custom_announcement_feed.tag_ids.include?(tag.id.to_s) ? "checked=checked" : "" %> class="tag-checkbox" value="<%= tag.id.to_s %>" name="custom_bulletin_feed[tag_ids][]">
|
||||||
|
</p>
|
||||||
|
<a href="#" onclick="return false;">
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale,index| %>
|
||||||
|
<span class="tag"><%= tag.name_translations[locale] %></span>
|
||||||
|
<% if index < (@site_in_use_locales.count - 1) %>
|
||||||
|
/
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<%= feed.title %>
|
||||||
|
<div class="quick-edit">
|
||||||
|
<ul class="nav nav-pills">
|
||||||
|
<% if can_edit_or_delete?(feed) %>
|
||||||
|
<li><a href="#" class="edit-feed" data-feed-id="<%= feed.id.to_s %>"><%= t(:edit) %></a></li>
|
||||||
|
<li><a href="/admin/custom_announcement/deletefeed?id=<%= feed.id.to_s %>" class="delete-feed text-error" ><%= t(:delete_) %></a></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="tags">
|
||||||
|
<div id="tags-list">
|
||||||
|
<ul class="tags-groups checkbox-card module-tags">
|
||||||
|
<% tags_to_remove = [] %>
|
||||||
|
<% feed.tag_ids.each do |t| %>
|
||||||
|
<% tag = Tag.find(t) rescue nil %>
|
||||||
|
<% if !tag.nil? %>
|
||||||
|
<li class="filter-item module">
|
||||||
|
<a href="#" onclick="return false;">
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale,index| %>
|
||||||
|
<span class="tag"><%= tag.name_translations[locale] %></span>
|
||||||
|
<% if index < (@site_in_use_locales.count - 1) %>
|
||||||
|
/
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<% else %>
|
||||||
|
<% tags_to_remove << t %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<% if !tags_to_remove.blank?
|
||||||
|
tags_to_remove.each do |t|
|
||||||
|
feed.tag_ids.delete(t)
|
||||||
|
end
|
||||||
|
feed.save
|
||||||
|
end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/xhr/custom_announcements/rssfeed/<%= feed.uid %>.rss" target="_blank">RSS Feed</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/xhr/custom_announcements/feed/<%= feed.uid %>.json" target="_blank">JSON Feed</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<%= form_for @custom_announcement_feed, url: admin_custom_announcement_createfeed_path, html: {class: "form-horizontal main-forms"} do |f| %>
|
||||||
|
<fieldset>
|
||||||
|
<% @site_in_use_locales.each do |locale| %>
|
||||||
|
<%= f.fields_for :title_translations do |f| %>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted" for="custom_bulletin_feed_title_translations_<%= locale.to_s %>"><%= t(:title) + " (#{t(locale.to_s)})" %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.text_field locale, data: {"fv-validation" => "required;","fv-messages" => "Cannot be empty.;"}, value: (@custom_announcement_feed.title_translations[locale.to_s] rescue nil) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<hr />
|
||||||
|
<div class="tags">
|
||||||
|
<div id="tags-list">
|
||||||
|
<ul class="tags-groups checkbox-card module-tags">
|
||||||
|
<% @module_app.tags.each do |tag| %>
|
||||||
|
<li class="filter-item module">
|
||||||
|
<p class="card pull-left">
|
||||||
|
<input type="checkbox" class="tag-checkbox" value="<%= tag.id.to_s %>" name="custom_bulletin_feed[tag_ids][]">
|
||||||
|
</p>
|
||||||
|
<a href="#" onclick="return false;">
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale,index| %>
|
||||||
|
<span class="tag"><%= tag.name_translations[locale] %></span>
|
||||||
|
<% if index < (@site_in_use_locales.count - 1) %>
|
||||||
|
/
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,705 @@
|
||||||
|
<% content_for :page_specific_css do %>
|
||||||
|
<%= stylesheet_link_tag "lib/main-forms" %>
|
||||||
|
<%= stylesheet_link_tag "lib/fileupload" %>
|
||||||
|
<%= stylesheet_link_tag "lib/main-list" %>
|
||||||
|
<% end %>
|
||||||
|
<style type="text/css">
|
||||||
|
.reach_limit{
|
||||||
|
background: #a90c0c;
|
||||||
|
color: white;
|
||||||
|
padding: 4px 12px;
|
||||||
|
font-family: 'Varela Round';
|
||||||
|
letter-spacing: -.4px;
|
||||||
|
cursor: default;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.add-on.btn-group .dropdown-menu{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.main-forms fieldset .input-area .controls .input-prepend a:hover{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<% content_for :page_specific_javascript do %>
|
||||||
|
<%= javascript_include_tag "lib/bootstrap-fileupload" %>
|
||||||
|
<%= javascript_include_tag "lib/bootstrap-datetimepicker" %>
|
||||||
|
<%= javascript_include_tag "lib/datetimepicker/datetimepicker.js" %>
|
||||||
|
<%= javascript_include_tag "lib/file-type" %>
|
||||||
|
<%= javascript_include_tag "lib/module-area" %>
|
||||||
|
<%= javascript_include_tag "form" %>
|
||||||
|
<% end %>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function trigger_on_add_calendar(ele){
|
||||||
|
if ($(ele).prop('checked')){
|
||||||
|
$('.trigger_on_add_calendar').show()
|
||||||
|
}else{
|
||||||
|
$('.trigger_on_add_calendar').hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<!-- Input Area -->
|
||||||
|
<div class="input-area">
|
||||||
|
|
||||||
|
<!-- Module Tabs -->
|
||||||
|
<div class="nav-name"><strong><%= t(:module) %></strong></div>
|
||||||
|
<ul class="nav nav-pills module-nav">
|
||||||
|
<li class="active"><a href="#basic" data-toggle="tab"><%= t(:basic) %></a></li>
|
||||||
|
<% if defined? Calendar %>
|
||||||
|
<li><a href="#calendar" data-toggle="tab"><%= t('calendar.calendar') %></a></li>
|
||||||
|
<% end %>
|
||||||
|
<% if((!CustomAnnouncementSetting.first.only_manager_can_edit_status) || (CustomAnnouncementSetting.first.only_manager_can_edit_status && (@current_user.is_admin? || @current_user.is_manager?(@module_app))) ) %>
|
||||||
|
<li><a href="#status" data-toggle="tab"><%= t(:status) %></a></li>
|
||||||
|
<% end %>
|
||||||
|
<li><a href="#tag" data-toggle="tab"><%= t(:tags) %></a></li>
|
||||||
|
<li><a href="#imageupload" data-toggle="tab"><%= t('custom_announcement.image') %></a></li>
|
||||||
|
<li><a href="#carousel_image_upload" data-toggle="tab" title="<%= t('custom_announcement.carousel_image_title') %>"><%= t('custom_announcement.carousel_image') %></a></li>
|
||||||
|
<li><a href="#mail-group" data-toggle="tab"><%= t('custom_announcement.email_reminder')%></a></li>
|
||||||
|
</ul>
|
||||||
|
<!-- Module -->
|
||||||
|
<div class="tab-content module-area">
|
||||||
|
|
||||||
|
<!-- Basic Module -->
|
||||||
|
<div class="tab-pane fade in active" id="basic">
|
||||||
|
|
||||||
|
<!-- Category -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:category) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= select_category(f, @module_app) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Date Time Picker -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:start_date) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.datetime_picker :postdate, :no_label => true, :new_record => @custom_bulletin.new_record?, :data=>{"picker-type" => "range", "range" => "start"} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:end_date) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.datetime_picker :deadline, :no_label => true, :new_record => @custom_bulletin.new_record?, :data=>{"picker-type" => "range", "range" => "end"} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :is_external_link, t("custom_announcement.is_external_link"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :is_external_link %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" style="display: none;" id="external_link_box">
|
||||||
|
<%= f.label :external_link, t("custom_announcement.external_link"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.text_field :external_link %>
|
||||||
|
<div class="hint"><%= t("custom_announcement.external_link_hint") %></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- display subtitle -->
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :display_subtitle, t("custom_announcement.display_subtitle"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :display_subtitle %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- display img src -->
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :display_img, t("custom_announcement.display_img"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :display_img %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Image display setting -->
|
||||||
|
<% image_display_class_relation = {"full_width"=>"full-size-img","up_left_corner"=>"pull-left","up_right_corner"=>"pull-right"} %>
|
||||||
|
<div class="control-group <%='hide' if !f.object.display_img %>" id="image_display_setting">
|
||||||
|
<%= f.label :image_display_class, t("custom_announcement.cover_image_display_setting"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<% image_display_class_relation.each.with_index do |(key,value),i| %>
|
||||||
|
<label>
|
||||||
|
<%= radio_button_tag "#{f.object_name}[image_display_class]", value , (f.object.image_display_class == value) %>
|
||||||
|
<%= t("custom_announcement.#{key}") %>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Calendar Module -->
|
||||||
|
<% if defined? Calendar %>
|
||||||
|
<div class="tab-pane fade" id="calendar">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t('custom_announcement.add_to_calendar') %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :add_to_calendar,onchange: 'trigger_on_add_calendar(this)' %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="trigger_on_add_calendar" <%= "style=display:none;" if !@custom_bulletin.add_to_calendar %>>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t('calendar.calendar') %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.select :calendar_type_id, @calendar_categories.collect{|t| [ t.title, t.id ]} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group" style="display: flex;flex-wrap: wrap;">
|
||||||
|
<div style="display: flex;flex-direction: column;">
|
||||||
|
<label class="control-label muted"><%= t(:start_date) %></label>
|
||||||
|
<label class="control-label muted"><%= t('custom_announcement.blank_to_set') %></label>
|
||||||
|
</div>
|
||||||
|
<div class="controls" style="margin-left: 1.5em;">
|
||||||
|
<%= f.datetime_picker :calendar_start_date, :new_record => @custom_bulletin.new_record?, :no_label => true, :data=>{"picker-type" => "range", "range" => "start"} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group" style="display: flex;flex-wrap: wrap;">
|
||||||
|
<div style="display: flex;flex-direction: column;">
|
||||||
|
<label class="control-label muted"><%= t(:end_date) %></label>
|
||||||
|
<label class="control-label muted"><%= t('custom_announcement.blank_to_set') %></label>
|
||||||
|
</div>
|
||||||
|
<div class="controls" style="margin-left: 1.5em;">
|
||||||
|
<%= f.datetime_picker :calendar_end_date, :new_record => @custom_bulletin.new_record?, :no_label => true, :data=>{"picker-type" => "range", "range" => "end"} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t('calendar.all_day') %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :calendar_all_day %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted">Select Read More Page :</label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.select :page_id,[["----- Select a page -----",nil]]+@module_pages %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%= f.hidden_field :event_id %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<!-- Status Module -->
|
||||||
|
<% if((!CustomAnnouncementSetting.first.only_manager_can_edit_status) || (CustomAnnouncementSetting.first.only_manager_can_edit_status && (@current_user.is_admin? || @current_user.is_manager?(@module_app))) ) %>
|
||||||
|
<div class="tab-pane fade" id="status">
|
||||||
|
<!-- Status -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:status) %></label>
|
||||||
|
<div class="controls" data-toggle="buttons-checkbox">
|
||||||
|
<% if !(@reach_limit.include?('is_top') && @custom_bulletin.is_top != true) || current_user.is_admin? %>
|
||||||
|
<label class="checkbox inline btn <%= 'active' if @custom_bulletin.is_top? || (!@custom_bulletin.top_end_date.nil? && @custom_bulletin.top_end_date > Time.now) %>">
|
||||||
|
<%= f.check_box :is_top %> <%= t(:top) %>
|
||||||
|
</label>
|
||||||
|
<% else %>
|
||||||
|
<label class="reach_limit">
|
||||||
|
<%= t(:top) %>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
<% if !(@reach_limit.include?('is_hot') && @custom_bulletin.is_hot != true) || current_user.is_admin? %>
|
||||||
|
<label class="checkbox inline btn <%= 'active' if @custom_bulletin.is_hot? %>">
|
||||||
|
<%= f.check_box :is_hot %> <%= t(:hot) %>
|
||||||
|
</label>
|
||||||
|
<% else %>
|
||||||
|
<label class="reach_limit">
|
||||||
|
<%= t(:hot) %>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
<label class="checkbox inline btn <%= 'active' if @custom_bulletin.is_hidden? %>">
|
||||||
|
<%= f.check_box :is_hidden %> <%= t(:hide) %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="controls">
|
||||||
|
<% if !@custom_bulletin.is_top? && !CustomAnnouncementSetting.check_limit_for_user((@custom_bulletin.new_record? ? current_user.id : @custom_bulletin.create_user_id)) %>
|
||||||
|
<span>Top limit has been reached. The custom_bulletin wont be marked as top even if you click on it.</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group <%= @custom_bulletin.is_top? || (!@custom_bulletin.top_end_date.nil? && @custom_bulletin.top_end_date > Time.now) ? "" : "hide" %>" data-for="is_top">
|
||||||
|
<label for="" class="control-label muted">Top end time</label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.datetime_picker :top_end_date, :no_label => true, :new_record => @custom_bulletin.new_record? %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t('custom_announcement.open_comment')%></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :open_comment %><%= t('custom_announcement.open') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group <%= @custom_bulletin.open_comment ? "" : "hide" %>" data-for="open_comment">
|
||||||
|
<label for="" class="control-label muted"><%= t('custom_announcement.comment_end_time')%></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.datetime_picker :comment_end_time, :no_label => true, :new_record => @custom_bulletin.new_record? %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group <%= @custom_bulletin.open_comment ? "" : "hide" %>" data-for="open_comment">
|
||||||
|
<label for="" class="control-label muted"><%= t('custom_announcement.comment_role')%></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= check_box_tag 'custom_bulletin[comment_role][]','visitor',@custom_bulletin.comment_role.include?('visitor') %>
|
||||||
|
<%= t('custom_announcement.visitor') %>
|
||||||
|
<br>
|
||||||
|
<%= check_box_tag 'custom_bulletin[comment_role][]','all_member',@custom_bulletin.comment_role.include?('all_member'),class: 'role_all_member' %>
|
||||||
|
<%= t('custom_announcement.all_member') %>
|
||||||
|
<br>
|
||||||
|
<% Role.all.each do |role| %>
|
||||||
|
<%= check_box_tag 'custom_bulletin[comment_role][]',role.id.to_s,@custom_bulletin.comment_role.include?(role.id.to_s),class: 'role' %>
|
||||||
|
<%= role.title %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<!-- Tag Module -->
|
||||||
|
<div class="tab-pane fade" id="tag">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:tags) %></label>
|
||||||
|
<%= select_tags(f, @module_app) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Images Module -->
|
||||||
|
<div class="tab-pane fade" id="imageupload">
|
||||||
|
|
||||||
|
<!-- Images Upload -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:image) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="fileupload fileupload-new clearfix <%= 'fileupload-edit' if @custom_bulletin.image.file %>" data-provides="fileupload">
|
||||||
|
<div class="fileupload-new thumbnail pull-left">
|
||||||
|
<% if @custom_bulletin.image.file %>
|
||||||
|
<%= image_tag @custom_bulletin.image %>
|
||||||
|
<% else %>
|
||||||
|
<img src="http://www.placehold.it/50x50/EFEFEF/AAAAAA" />
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="fileupload-preview fileupload-exists thumbnail pull-left"></div>
|
||||||
|
<span class="btn btn-file">
|
||||||
|
<span class="fileupload-new"><%= t(:select_image) %></span>
|
||||||
|
<span class="fileupload-exists"><%= t(:change) %></span>
|
||||||
|
<%= f.file_field :image %>
|
||||||
|
</span>
|
||||||
|
<a href="#" class="btn fileupload-exists" data-dismiss="fileupload"><%= t(:cancel) %></a>
|
||||||
|
<div class="controls" data-toggle="buttons-checkbox">
|
||||||
|
<label class="checkbox inline btn btn-danger fileupload-remove">
|
||||||
|
<%= f.check_box :remove_image %><%= t(:remove) %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% @site_in_use_locales.each do |locale| %>
|
||||||
|
<%= f.fields_for :image_description_translations do |f| %>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted" for="image_description_<%= locale.to_s %>"><%= t(:description) + " (#{t(locale.to_s)})" %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.text_field locale, value: (@custom_bulletin.image_description_translations[locale.to_s] rescue nil) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- Images Module -->
|
||||||
|
<div class="tab-pane fade" id="carousel_image_upload">
|
||||||
|
<% if @custom_bulletin && !@custom_bulletin.custom_bulletin_carousel_images.blank? %>
|
||||||
|
<div class="exist">
|
||||||
|
<% @custom_bulletin.custom_bulletin_carousel_images.each_with_index do |custom_bulletin_carousel_image, i| %>
|
||||||
|
<%= f.fields_for :custom_bulletin_carousel_images, custom_bulletin_carousel_image do |f| %>
|
||||||
|
<%= render :partial => 'form_image', :object => custom_bulletin_carousel_image, :locals => {:f => f, :i => i} %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<!-- Add -->
|
||||||
|
<div class="add-target">
|
||||||
|
</div>
|
||||||
|
<p class="add-btn controls">
|
||||||
|
<%= hidden_field_tag 'custom_bulletin_carousel_image_count', @custom_bulletin.custom_bulletin_carousel_images.count %>
|
||||||
|
<a id="add_carousel_image" class="trigger btn btn-small btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mail Group Module -->
|
||||||
|
<div class="tab-pane fade" id="mail-group">
|
||||||
|
|
||||||
|
<!-- Mail Group -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t("custom_announcement.email_to") %></label>
|
||||||
|
<div class="controls">
|
||||||
|
|
||||||
|
<label class="checkbox inline">
|
||||||
|
<%= check_box_tag('custom_bulletin[email_sent]', '1', (!@custom_bulletin.email_sent.blank? ? true : false), :id=>'remind-check') %><%= t('custom_announcement.activate_email_reminder')%>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="content-box">
|
||||||
|
<%= render partial: 'admin/member_selects/email_selection_box', locals: {field: 'custom_bulletin[email_member_ids][]', email_members: @custom_bulletin.email_members} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"></label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="content-box">
|
||||||
|
<span class="help-block"><%= "#{t("custom_announcement.other_mailaddress")}(#{t("custom_announcement.other_mailaddress_note")})"%> </span>
|
||||||
|
<%= f.text_area :other_mailaddress, :class=>"span12", :cols=>"25", :rows=>"10" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t("custom_announcement.email_sentdate") %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.datetime_picker :email_sentdate, :no_label => true %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% if (@custom_bulletin.email.is_sent rescue false) %>
|
||||||
|
<div class="content-box">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t("custom_announcement.resend_mail") %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="checkbox" name="resend_mail" value="true">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Language Tabs -->
|
||||||
|
<div class="nav-name"><strong><%= t(:language) %></strong></div>
|
||||||
|
<ul class="nav nav-pills language-nav">
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||||
|
<li class="<%= 'active' if i == 0 %>">
|
||||||
|
<a data-toggle="tab" href=".<%= locale %>"><%= t(locale) %></a>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Language -->
|
||||||
|
<div class="tab-content language-area">
|
||||||
|
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||||
|
|
||||||
|
<div class="<%= locale %> tab-pane fade <%= ( i == 0 ) ? "in active" : '' %>">
|
||||||
|
|
||||||
|
<!-- Title-->
|
||||||
|
<div class="control-group input-title">
|
||||||
|
<label class="control-label muted"><%= t(:title) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.fields_for :title_translations do |f| %>
|
||||||
|
<%= f.text_area locale, class: "ckeditor_reduce input-block-level", placeholder: t(:title), value: (@custom_bulletin.title_translations[locale] rescue nil) %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sub Title -->
|
||||||
|
<div class="control-group input-subtitle">
|
||||||
|
<label class="control-label muted"><%= t(:subtitle) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="textarea">
|
||||||
|
<%= f.fields_for :subtitle_translations do |f| %>
|
||||||
|
<%= f.text_area locale, rows: 2, class: "ckeditor input-block-level", value: (@custom_bulletin.subtitle_translations[locale] rescue nil) %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<div class="control-group input-content">
|
||||||
|
<label class="control-label muted"><%= t(:content) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="textarea">
|
||||||
|
<%= f.fields_for :text_translations do |f| %>
|
||||||
|
<%= f.cktext_area locale, rows: 5, class: "input-block-level", :value => (@custom_bulletin.text_translations[locale] rescue nil) %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<!-- Link -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:link) %></label>
|
||||||
|
<div class="controls add-input">
|
||||||
|
|
||||||
|
<!-- Exist -->
|
||||||
|
<% if @custom_bulletin && !@custom_bulletin.custom_bulletin_links.blank? %>
|
||||||
|
<div class="exist">
|
||||||
|
<% @custom_bulletin.custom_bulletin_links.each_with_index do |custom_bulletin_link, i| %>
|
||||||
|
<%= f.fields_for :custom_bulletin_links, custom_bulletin_link do |f| %>
|
||||||
|
<%= render :partial => 'form_link', :object => custom_bulletin_link, :locals => {:f => f, :i => i} %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<!-- Add -->
|
||||||
|
<div class="add-target">
|
||||||
|
</div>
|
||||||
|
<p class="add-btn">
|
||||||
|
<%= hidden_field_tag 'custom_bulletin_link_field_count', @custom_bulletin.custom_bulletin_links.count %>
|
||||||
|
<a id="add_link" class="trigger btn btn-small btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- File -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:file_) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<div id="file_description_hint"><%= t("custom_announcement.file_description_hint") %></div>
|
||||||
|
<!-- Exist -->
|
||||||
|
<% if @custom_bulletin && !@custom_bulletin.custom_bulletin_files.blank? %>
|
||||||
|
<div class="exist">
|
||||||
|
<% @custom_bulletin.custom_bulletin_files.each_with_index do |custom_bulletin_file, i| %>
|
||||||
|
<%= f.fields_for :custom_bulletin_files, custom_bulletin_file do |f| %>
|
||||||
|
<%= render :partial => 'form_file', :object => custom_bulletin_file, :locals => {:f => f, :i => i} %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<!-- Add -->
|
||||||
|
<div class="add-target">
|
||||||
|
</div>
|
||||||
|
<p class="add-btn">
|
||||||
|
<%= hidden_field_tag 'custom_bulletin_file_field_count', @custom_bulletin.custom_bulletin_files.count %>
|
||||||
|
<a id="add_file" class="trigger btn btn-small btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Form Actions -->
|
||||||
|
<div class="form-actions">
|
||||||
|
<%= get_referer_url[:action] rescue "" %>
|
||||||
|
<%= f.submit t('submit'), class: 'btn btn-primary' %>
|
||||||
|
<input type="hidden" name="referer_url" value="<%= get_referer_url %>">
|
||||||
|
<%= button_tag t("preview"), id: "button_for_preview", name: "commit", class: 'btn', type: :button %>
|
||||||
|
<%= link_to t('cancel'), admin_custom_announcements_path + (params[:custom_module].blank? ? '' : "/#{params[:custom_module]}#{(params[:bind_uid].blank? ? '' : ('-'+params[:bind_uid]))}"), :class=>"btn" %>
|
||||||
|
<% if params[:custom_module].present? %>
|
||||||
|
<%= f.hidden_field :custom_module, :value=> params[:custom_module] %>
|
||||||
|
<% if params[:bind_uid].present? %>
|
||||||
|
<%= f.hidden_field :bind_uid, :value=> params[:bind_uid] %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span id='show_preview'>
|
||||||
|
<div class="modal hide fade in banner-preview" id="">
|
||||||
|
<div class="modal-header">
|
||||||
|
<a class="close" data-dismiss="modal">×</a>
|
||||||
|
<h3><%= t(:preview) %></h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<iframe id="preview-iframe" src=""></iframe>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a href="#" class="btn" data-dismiss="modal"><%= t(:close) %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<% if !@module_app.tags.empty? %>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$("form.previewable").on("submit", function(){
|
||||||
|
if(!$("input[name='custom_bulletin[tags][]']").is(":checked")){
|
||||||
|
if(!confirm("You have selected no tag, do you wish to continue?")){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<% end %>
|
||||||
|
<style type="text/css">
|
||||||
|
[aria-describedby] ul.dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
[aria-describedby] .checkbox input{
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
$("#custom_bulletin_display_img").click(function(){$("#image_display_setting").toggleClass("hide")})
|
||||||
|
function Appendzero(obj)
|
||||||
|
{
|
||||||
|
if(obj<10) return "0" +""+ obj;
|
||||||
|
else return obj;
|
||||||
|
}
|
||||||
|
function add_click_for_privacy()
|
||||||
|
{
|
||||||
|
$('.add-on.btn-group').off('show.bs.tooltip').on('show.bs.tooltip',function(){$(this).find('ul').toggleClass('show')});
|
||||||
|
$(".privacy-changer-btn").off('click')
|
||||||
|
$(".privacy-changer-btn").click(function(){
|
||||||
|
var val = $(this).attr('for')
|
||||||
|
var parent_node = $(this).parents('.add-on.btn-group').eq(0)
|
||||||
|
parent_node.find('.privacy_type').val(val)
|
||||||
|
parent_node.find('i').eq(0).attr('class',$(this).find('i').attr('class'))
|
||||||
|
parent_node.find('.dropdown-menu').hide()
|
||||||
|
window.setTimeout(function(){
|
||||||
|
parent_node.find('.dropdown-menu').css('display','')
|
||||||
|
},1000)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$(function() {
|
||||||
|
$('#custom_bulletin_open_comment').change(function(){
|
||||||
|
$(this).prop('checked') ? $('div[data-for="open_comment"]').removeClass('hide') : $('div[data-for="open_comment"]').addClass('hide')
|
||||||
|
})
|
||||||
|
$('.role_all_member').change(function(){
|
||||||
|
if ($(this).prop('checked')){
|
||||||
|
$('.role').each(function() {
|
||||||
|
$(this).prop("checked", true);
|
||||||
|
})
|
||||||
|
} else{
|
||||||
|
$('.role').each(function() {
|
||||||
|
$(this).prop("checked", false);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$('.role').change(function(){
|
||||||
|
if (!$(this).prop('checked') && $('.role_all_member').prop('checked')){
|
||||||
|
$('.role_all_member').prop('checked',false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (location.pathname.substr(-3)=='new'){
|
||||||
|
var getDate = new Date();
|
||||||
|
var toDay = getDate.getFullYear()+"/"+ (Appendzero(getDate.getMonth()+1))+"/"+Appendzero(getDate.getDate())+" "+Appendzero(getDate.getHours())+":"+Appendzero(getDate.getMinutes());
|
||||||
|
$('input[name="custom_bulletin[postdate]"]').val(toDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#main-wrap").after("");
|
||||||
|
|
||||||
|
$(document).on('click', '#add_link', function(){
|
||||||
|
var new_id = $(this).prev().attr('value');
|
||||||
|
var old_id = new RegExp("new_custom_bulletin_links", "g");
|
||||||
|
var on = $('.language-nav li.active').index();
|
||||||
|
var le = $(this).parent('.add-btn').prev('.add-target').children('.start-line').length;
|
||||||
|
$(this).prev().attr('value', parseInt(new_id) + 1);
|
||||||
|
$(this).parent().siblings('.add-target').append(("<%= escape_javascript(add_attribute 'form_link', f, :custom_bulletin_links) %>").replace(old_id, new_id));
|
||||||
|
$(this).parent('.add-btn').prev('.add-target').children('.start-line').eq(le).children('.tab-content').children('.tab-pane').eq(on).addClass('in active').siblings().removeClass('in active');
|
||||||
|
formTip();
|
||||||
|
});
|
||||||
|
$(document).on('click', '#add_file', function(){
|
||||||
|
var new_id = $(this).prev().attr('value');
|
||||||
|
var old_id = new RegExp("new_custom_bulletin_files", "g");
|
||||||
|
var on = $('.language-nav li.active').index();
|
||||||
|
var le = $(this).parent('.add-btn').prev('.add-target').children('.start-line').length;
|
||||||
|
$(this).prev().attr('value', parseInt(new_id) + 1);
|
||||||
|
$(this).parent().siblings('.add-target').append(("<%= escape_javascript(add_attribute 'form_file', f, :custom_bulletin_files) %>").replace(old_id, new_id));
|
||||||
|
$(this).parent('.add-btn').prev('.add-target').children('.start-line').eq(le).children('.input-append').find('.tab-content').each(function() {
|
||||||
|
$(this).children('.tab-pane').eq(on).addClass('in active').siblings().removeClass('in active');
|
||||||
|
});
|
||||||
|
formTip();
|
||||||
|
add_click_for_privacy();
|
||||||
|
});
|
||||||
|
$(document).on('click', '#add_carousel_image', function(){
|
||||||
|
var new_id = $(this).prev().attr('value');
|
||||||
|
var old_id = new RegExp("new_custom_bulletin_carousel_images", "g");
|
||||||
|
var on = $('.language-nav li.active').index();
|
||||||
|
var le = $(this).parent('.add-btn').prev('.add-target').children('.start-line').length;
|
||||||
|
$(this).prev().attr('value', parseInt(new_id) + 1);
|
||||||
|
$(this).parent().siblings('.add-target').append(("<%= escape_javascript(add_attribute 'form_image', f, :custom_bulletin_carousel_images) %>").replace(old_id, new_id));
|
||||||
|
$(this).parent('.add-btn').prev('.add-target').children('.start-line').eq(le).children('.input-append').find('.tab-content').each(function() {
|
||||||
|
$(this).children('.tab-pane').eq(on).addClass('in active').siblings().removeClass('in active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$(document).on('click', '.fileupload-remove', function(){
|
||||||
|
if($(this).find(".delete_image").length != 0){
|
||||||
|
$(this).parents('.image_group').remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$(document).on('click', '.delete_link', function(){
|
||||||
|
$(this).parents('.input-prepend').remove();
|
||||||
|
});
|
||||||
|
$(document).on('click', '.delete_file', function(){
|
||||||
|
$(this).parents('.input-prepend').remove();
|
||||||
|
});
|
||||||
|
$(document).on('click', '.remove_existing_record', function(){
|
||||||
|
if(confirm("<%= I18n.t(:sure?)%>")){
|
||||||
|
$(this).children('.should_destroy').attr('value', 1);
|
||||||
|
$(this).parents('.start-line').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#remind-check').prop('checked') ? '':$('.content-box').addClass('hide')
|
||||||
|
$('#remind-check').on('change', function() {
|
||||||
|
$(this).prop('checked') ? $('.content-box').removeClass('hide'):$('.content-box').addClass('hide')
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#button_for_preview').click(function(){
|
||||||
|
var method = $('.main-forms input[name="_method"]').val();
|
||||||
|
$('.main-forms input[name="_method"]').val("post");
|
||||||
|
|
||||||
|
for ( instance in CKEDITOR.instances )
|
||||||
|
CKEDITOR.instances[instance].updateElement();
|
||||||
|
|
||||||
|
var formData = new FormData( $('.main-forms')[0] );
|
||||||
|
formData.append("preview_type", ( (method==undefined) ? "new" : "edit" ));
|
||||||
|
formData.append("custom_bulletin_id", '<%= @custom_bulletin.id.to_s %>');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "post",
|
||||||
|
url: '<%= admin_custom_announcement_preview_path %>',
|
||||||
|
data : formData,
|
||||||
|
processData: false,
|
||||||
|
contentType: false
|
||||||
|
}).done(function(data){
|
||||||
|
if(window.location.protocol === "https:"){
|
||||||
|
data = data.replace("http:","https:");
|
||||||
|
}
|
||||||
|
$('.modal-body iframe').attr('src',data);
|
||||||
|
$('#show_preview .modal').modal();
|
||||||
|
$('#show_preview .modal').height(function() {
|
||||||
|
return $(window).height() * 0.7;
|
||||||
|
});
|
||||||
|
|
||||||
|
var slug = data.split('/')[(data.split('/').length-1)];
|
||||||
|
// $('#preview-iframe').on('load', function(){
|
||||||
|
// $.get('/admin/custom_announcement/destroy_preview/'+slug,function(data){
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
$('.main-forms input[name="_method"]').val(method);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#custom_bulletin_is_top").parent().on("click",function(){
|
||||||
|
setTimeout(function(){
|
||||||
|
if($("#custom_bulletin_is_top").parent().hasClass("active")){
|
||||||
|
$("div[data-for=is_top]").removeClass("hide");
|
||||||
|
}else{
|
||||||
|
$("div[data-for=is_top]").addClass("hide");
|
||||||
|
$("div[data-for=is_top]").find("input[type=text]").val("");
|
||||||
|
}
|
||||||
|
},100)
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#custom_bulletin_is_external_link").on("click",function(){
|
||||||
|
if($(this).is(":checked")){
|
||||||
|
$("#external_link_box").show();
|
||||||
|
}else{
|
||||||
|
$("#external_link_box").hide();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
add_click_for_privacy()
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,89 @@
|
||||||
|
<% if form_file.new_record? %>
|
||||||
|
<div class="fileupload fileupload-new start-line" data-provides="fileupload">
|
||||||
|
<% else %>
|
||||||
|
<div class="fileupload fileupload-exists start-line" data-provides="fileupload">
|
||||||
|
<% if form_file.file.blank? %>
|
||||||
|
<%= t(:no_file) %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to content_tag(:i) + form_file.file_identifier, form_file.file.url, {:class => 'file-link file-type', :target => '_blank', :title => form_file.file_identifier} %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<div class="input-prepend input-append">
|
||||||
|
<label>
|
||||||
|
<span class="add-on btn btn-file" title='<%= t(:file_) %>'>
|
||||||
|
<i class="icons-paperclip"></i>
|
||||||
|
<%= f.file_field :file %>
|
||||||
|
</span>
|
||||||
|
<div class="uneditable-input input-medium">
|
||||||
|
<i class="icon-file fileupload-exists"></i>
|
||||||
|
<span class="fileupload-preview"><%= (form_file.new_record? || form_file.file.blank?) ? t(:select_file) : t(:change_file) %></span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<span class="add-on icons-pencil" title='<%= t(:alternative) %>'></span>
|
||||||
|
<span class="tab-content">
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||||
|
<span class="tab-pane fade <%= ( i == 0 ) ? "in active" : '' %> <%= locale %>">
|
||||||
|
<%= f.fields_for :title_translations do |f| %>
|
||||||
|
<%= f.text_field locale, :class => "input-medium", placeholder: t(:alternative), :value => (form_file.title_translations[locale] rescue nil) %>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
<span class="add-on icons-pencil" title='<%= t(:description) %>'></span>
|
||||||
|
<span class="tab-content">
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||||
|
<span class="tab-pane fade <%= ( i == 0 ) ? "in active" : '' %> <%= locale %>">
|
||||||
|
<%= f.fields_for :description_translations do |f| %>
|
||||||
|
<%= f.text_field locale, :class => "input-medium", placeholder: t(:description), :value => (form_file.description_translations[locale] rescue nil) %>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="add-on btn-group btn" title="<%= t('archive.show_lang') %>">
|
||||||
|
<i class="icons-earth"></i> <span class="caret"></span>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<% @site_in_use_locales.each do |locale| %>
|
||||||
|
<li>
|
||||||
|
<label class="checkbox">
|
||||||
|
<%= check_box_tag "custom_bulletin[custom_bulletin_files_attributes][#{( form_file.new_record? ? 'new_custom_bulletin_files' : "#{i}" )}][choose_lang][]", locale, form_file.choose_lang.include?(locale.to_s) %>
|
||||||
|
<%= t(locale.to_s) %>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<%= hidden_field_tag 'custom_bulletin[custom_bulletin_files_attributes][0][choose_lang][]', '' %>
|
||||||
|
</span>
|
||||||
|
<% if form_file.new_record? %>
|
||||||
|
<span class="delete_file add-on btn" title="<%= t(:delete_) %>">
|
||||||
|
<a class="icon-trash"></a>
|
||||||
|
</span>
|
||||||
|
<% else %>
|
||||||
|
<span class="remove_existing_record add-on btn" title="<%= t(:remove) %>">
|
||||||
|
<%= f.hidden_field :id %>
|
||||||
|
<a class="icon-remove"></a>
|
||||||
|
<%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
<span class="add-on btn-group btn" style="background: white;border: 0;margin-left: 1em;" title="<%=t('site.edit_members.privacy_setting')%>">
|
||||||
|
<% case form_file.privacy_type
|
||||||
|
when "public"
|
||||||
|
icon = "icons-earth"
|
||||||
|
when "logged_in"
|
||||||
|
icon = "icons-users"
|
||||||
|
end
|
||||||
|
%>
|
||||||
|
<i class="<%= icon %>"></i> <span class="caret"></span>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li>
|
||||||
|
<a class="privacy-changer-btn" for="public"><i class="icons-earth"></i><%= t('privacy_type.public') %></a>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li>
|
||||||
|
<a class="privacy-changer-btn" for="logged_in"><i class="icons-users"></i><%= t('privacy_type.logged_in') %></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<%= f.hidden_field :privacy_type, class: 'privacy_type' %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,49 @@
|
||||||
|
<!-- Images Upload -->
|
||||||
|
<div class="image_group">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted"><%= t(:image) %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="fileupload fileupload-new clearfix <%= 'fileupload-edit' if @custom_bulletin.image.file %>" data-provides="fileupload">
|
||||||
|
<div class="fileupload-new thumbnail pull-left">
|
||||||
|
<% if form_image.file.file %>
|
||||||
|
<%= image_tag form_image.file %>
|
||||||
|
<% else %>
|
||||||
|
<img src="http://www.placehold.it/50x50/EFEFEF/AAAAAA" />
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="fileupload-preview fileupload-exists thumbnail pull-left"></div>
|
||||||
|
<span class="btn btn-file">
|
||||||
|
<span class="fileupload-new"><%= t(:select_image) %></span>
|
||||||
|
<span class="fileupload-exists"><%= t(:change) %></span>
|
||||||
|
<%= f.file_field :file %>
|
||||||
|
</span>
|
||||||
|
<a href="#" class="btn fileupload-exists" data-dismiss="fileupload"><%= t(:cancel) %></a>
|
||||||
|
<div class="controls" data-toggle="buttons-checkbox">
|
||||||
|
<label class="checkbox inline btn btn-danger fileupload-remove">
|
||||||
|
<% if form_image.new_record? %>
|
||||||
|
<span class="delete_file delete_image add-on" title="<%= t(:delete_) %>">
|
||||||
|
<%= t(:delete_) %>
|
||||||
|
</span>
|
||||||
|
<% else %>
|
||||||
|
<span class="remove_existing_record add-on" title="<%= t(:remove) %>">
|
||||||
|
<%= f.hidden_field :id %>
|
||||||
|
<%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %>
|
||||||
|
<%= t(:remove) %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% @site_in_use_locales.each do |locale| %>
|
||||||
|
<%= f.fields_for :description_translations do |f| %>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted" for="image_description_<%= locale.to_s %>"><%= t(:description) + " (#{t(locale.to_s)})" %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.text_field locale, value: (form_image.description_translations[locale.to_s] rescue nil) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<div class="input-prepend input-append start-line">
|
||||||
|
<span class="add-on icons-link" title="<%= t(:url) %>"></span>
|
||||||
|
<%= f.text_field :url, class: "input-large", placeholder: t(:url) %>
|
||||||
|
<span class="add-on icons-pencil" title="<%= t(:url_alt) %>"></span>
|
||||||
|
<span class="tab-content">
|
||||||
|
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||||
|
<span class="tab-pane fade <%= ( i == 0 ) ? "in active" : '' %> <%= locale %>">
|
||||||
|
<%= f.fields_for :title_translations do |f| %>
|
||||||
|
<%= f.text_field locale, :class => "input-large", placeholder: t(:url_alt), :value => (form_link.title_translations[locale] rescue nil) %>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<% if form_link.new_record? %>
|
||||||
|
<span class="delete_link add-on btn" title="<%= t(:delete_) %>">
|
||||||
|
<a class="icon-trash"></a>
|
||||||
|
</span>
|
||||||
|
<% else %>
|
||||||
|
<span class="remove_existing_record add-on btn" title="<%= t(:remove) %>">
|
||||||
|
<%= f.hidden_field :id %>
|
||||||
|
<a class="icon-remove"></a>
|
||||||
|
<%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -0,0 +1,98 @@
|
||||||
|
<script>
|
||||||
|
if(document.querySelectorAll("#orbit-bar").length==0) location.reload();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<table class="table main-list">
|
||||||
|
<thead>
|
||||||
|
<tr class="sort-header">
|
||||||
|
<% @table_fields.each do |f| %>
|
||||||
|
<%= thead(f) %>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @custom_bulletins.each do |b| %>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<%= b.status_for_table %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= b.category.title rescue "" %>
|
||||||
|
<% if (b.category.disable rescue false) %>
|
||||||
|
<span class='label'><%= t(:disabled) %></span>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<% if b.expired? || (b.category.disable rescue false)%>
|
||||||
|
<%= b.title.to_s.html_safe %>
|
||||||
|
<% else %>
|
||||||
|
<a href="<%= page_for_custom_bulletin(b) %>" target="_blank"><%= b.title.to_s.html_safe %></a>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if b.expired? %>
|
||||||
|
<span class='label'><%= t(:expired) %></span>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if b.reapproval %>
|
||||||
|
<span class='label'><%= t("custom_announcement.reapproval") + " " + t(:pending) %></span>
|
||||||
|
<% end %>
|
||||||
|
<% if b.rejected %>
|
||||||
|
<span class='label'><%= t(:rejected) %> : <%= b.rejection_reason rescue "" %></span>
|
||||||
|
<% end %>
|
||||||
|
<% if !b.approved? && !b.rejected %>
|
||||||
|
<span class='label'><%= t(:pending) %></span>
|
||||||
|
<% end %>
|
||||||
|
<div class="quick-edit">
|
||||||
|
<ul class="nav nav-pills">
|
||||||
|
<li><a href="#" class="detail-row" onclick="$('#<%= "#{b.id.to_s}-detail" %>').slideToggle(300); return false;"><%= t(:detail) %></a></li>
|
||||||
|
<% if can_edit_or_delete?(b) %>
|
||||||
|
<li><a href="/admin/custom_announcements<%=params[:custom_module].blank? ? '' : "/#{params[:custom_module]}#{params[:bind_uid].present? ? ('-'+params[:bind_uid]) : ''}"%>/<%=b.id.to_s%>/edit"><%= t(:edit) %></a></li>
|
||||||
|
<li><a href="#" class="delete text-error" rel="/admin/custom_announcements/<%=b.id.to_s%>"><%= t(:delete_) %></a></li>
|
||||||
|
<% end %>
|
||||||
|
<% if ((!b.approved && !b.rejected && !b.reapproval) || (b.rejected && b.reapproval)) && user_can_approve?(b) %>
|
||||||
|
<li><a href="<%= page_for_custom_bulletin(b) %>" class="approval_button" data-id="<%= b.id.to_s %>" ><%= t("custom_announcement.approval_waiting") %></a></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td><%= format_value b.postdate %></td>
|
||||||
|
<td class="<%= b.expired? ? "expired" : "" %>"><%= format_value b.deadline %></td>
|
||||||
|
<td><%= link_to b.custom_bulletin_comments.count.to_s,"/#{I18n.locale}/admin/custom_announcements/#{params[:custom_module]}#{params[:bind_uid].present? ? ('-'+params[:bind_uid]) : ''}/#{b.id}/comment" %></td>
|
||||||
|
<td><%= b.update_user.user_name rescue ""%></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="footable-row-detail">
|
||||||
|
<td class="footable-cell-detail" colspan="6">
|
||||||
|
<div id="<%= "#{b.id.to_s}-detail" %>" class="footable-row-detail-inner" style="display: none;">
|
||||||
|
<div>
|
||||||
|
<strong><%= t(:view_count) %></strong> :
|
||||||
|
<span class="label label-info"><%= b.view_count %></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong><%= t(:tags) %></strong> :
|
||||||
|
<% b.tags.each do |tag| %>
|
||||||
|
<span class="label label-warning"><%= tag.name %></span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong><%= t("custom_announcement.email_to") %></strong> :
|
||||||
|
<% b.email_members.each do |member| %>
|
||||||
|
<span class="label"><%= member.name %></span>
|
||||||
|
<% end %>
|
||||||
|
<% unless b.other_mailaddress.nil? %>
|
||||||
|
<% b.other_mailaddress.split(',').each do |mailaddress| %>
|
||||||
|
<span class="label"><%= mailaddress %></span>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<%=
|
||||||
|
content_tag :div, class: "bottomnav clearfix" do
|
||||||
|
content_tag(:div, paginate(@custom_bulletins), class: "pagination pagination-centered") +
|
||||||
|
content_tag(:div, link_to(t(:new_),(params[:custom_module].blank? ? "#{@module_app.key.pluralize}/new" : "#{params[:custom_module]}#{params[:bind_uid].present? ? ('-'+params[:bind_uid]) : ''}/new"), :class=>"btn btn-primary"), class: "pull-right")
|
||||||
|
end
|
||||||
|
%>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<% content_for :page_specific_css do %>
|
||||||
|
<%= stylesheet_link_tag("admin/tags") %>
|
||||||
|
<% end %>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function update_status(ele) {
|
||||||
|
$.get($(ele).data('href'),function(data){
|
||||||
|
$('table').html(data)
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<%= render 'comment' %>
|
|
@ -0,0 +1,74 @@
|
||||||
|
<% if params[:custom_module].blank? %>
|
||||||
|
<div class="bind_modules_list">
|
||||||
|
<ul>
|
||||||
|
<% @custom_bulletin_configs.each do |c|%>
|
||||||
|
<% target_model = c.bind_model.constantize rescue nil %>
|
||||||
|
<% next if target_model.nil? %>
|
||||||
|
<li>
|
||||||
|
<a href="<%= admin_custom_announcements_path + "/#{c.module}" %>">
|
||||||
|
<% icon_class = OrbitApp::Module::SideBarRegistration.all.select{|r| r.get_module_app_key == c.module}.first.get_icon_class rescue '' %>
|
||||||
|
<i class="<%= icon_class %> icon_big"></i>
|
||||||
|
<%= t("module_name.#{c.module}") %>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<% config = @custom_bulletin_configs.where(:module=>params[:custom_module]).first %>
|
||||||
|
<% target_model = config.bind_model.constantize %>
|
||||||
|
<% page_num = params[:page] || 1 %>
|
||||||
|
<% target_records = target_model.where(config.title_field.to_sym.nin=>[nil,""]).page(page_num).per(10) %>
|
||||||
|
<% if params[:search_title].present?
|
||||||
|
target_records = target_records.where(config.title_field.to_sym=>/#{params[:search_title].gsub(/(\[|\]|\(|\)|\.)/){|f| "\\"+f}}/)
|
||||||
|
end %>
|
||||||
|
<h3><%= t("module_name.#{config.module}") %></h3>
|
||||||
|
<form>
|
||||||
|
<input id="search_title" type="text" name="search_title" placeholder="<%= t(:title) %>" value="<%=params[:search_title]%>"><button><%= t(:search_) %></button>
|
||||||
|
</form>
|
||||||
|
<table class="table main-list footable-loaded tablet">
|
||||||
|
<thead>
|
||||||
|
<th class="span5"><%= t(:title) %></th>
|
||||||
|
<th class="span2"><%= t("custom_announcement.total_amount") %></th>
|
||||||
|
</thead>
|
||||||
|
<% target_records.each do |record| %>
|
||||||
|
<tr>
|
||||||
|
<% uid = record.send(config.uid_field) %>
|
||||||
|
<td>
|
||||||
|
<a href="<%= admin_custom_announcements_path + "/#{config.module}-#{uid}" %>" title="<%=record.send(config.title_field)%>"><%= record.send(config.title_field) %></a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= CustomBulletin.where(:custom_module=>params[:custom_module],:bind_uid=>uid).count %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
<%=
|
||||||
|
content_tag :div, class: "bottomnav clearfix" do
|
||||||
|
content_tag :div, paginate(target_records), class: "pagination pagination-centered"
|
||||||
|
end
|
||||||
|
%>
|
||||||
|
<% end %>
|
||||||
|
<style type="text/css">
|
||||||
|
i.icon_big{
|
||||||
|
font-size: 3em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.bind_modules_list li{
|
||||||
|
font-size: 1.3em;
|
||||||
|
list-style: none;
|
||||||
|
float: left;
|
||||||
|
margin: 0.8em;
|
||||||
|
}
|
||||||
|
.bind_modules_list a{
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.bind_modules_list a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #403f3f;
|
||||||
|
}
|
||||||
|
#search_title{
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<%= form_for @custom_bulletin, url: admin_custom_announcement_path(@custom_bulletin), html: {class: "form-horizontal main-forms previewable"} do |f| %>
|
||||||
|
<fieldset>
|
||||||
|
<%= render :partial => 'form', locals: {f: f} %>
|
||||||
|
</fieldset>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,125 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
wb = xlsx_package.workbook
|
||||||
|
|
||||||
|
wb.add_worksheet(name: "CustomAnnoucement") do |sheet|
|
||||||
|
|
||||||
|
heading = sheet.styles.add_style(:b => true, :locked => true)
|
||||||
|
example = sheet.styles.add_style(:i => true)
|
||||||
|
row = []
|
||||||
|
row1 = []
|
||||||
|
row2 = []
|
||||||
|
|
||||||
|
row << t("category")
|
||||||
|
row1 << "select"
|
||||||
|
t = ""
|
||||||
|
@module_app.categories.asc(:created_at).each_with_index do |cat,i|
|
||||||
|
t = t + "#{i}" + " -> " + cat.title + ", "
|
||||||
|
end
|
||||||
|
if @module_app.categories.count > 0
|
||||||
|
t = t + " Example : 0"
|
||||||
|
else
|
||||||
|
t = "Leave this field blank"
|
||||||
|
end
|
||||||
|
row2 << t
|
||||||
|
|
||||||
|
row << t("tags")
|
||||||
|
row1 << "select"
|
||||||
|
t = ""
|
||||||
|
@module_app.tags.asc(:created_at).each_with_index do |tag,i|
|
||||||
|
t = t + "#{i}" + " -> " + tag.name + ", "
|
||||||
|
end
|
||||||
|
if @module_app.tags.count > 0
|
||||||
|
t = t + " Example : 0,1,2"
|
||||||
|
else
|
||||||
|
t = "Leave this field blank"
|
||||||
|
end
|
||||||
|
row2 << t
|
||||||
|
|
||||||
|
row << t("start_date")
|
||||||
|
row1 << "date"
|
||||||
|
row2 << "Format: YYYY/MM/DD, Example: 2015/12/10"
|
||||||
|
|
||||||
|
row << t("end_date")
|
||||||
|
row1 << "date"
|
||||||
|
row2 << "Format: YYYY/MM/DD, Example: 2015/12/12"
|
||||||
|
|
||||||
|
row << t("top")
|
||||||
|
row1 << "boolean"
|
||||||
|
row2 << "0 for false, 1 for true"
|
||||||
|
|
||||||
|
row << t("hot")
|
||||||
|
row1 << "boolean"
|
||||||
|
row2 << "0 for false, 1 for true"
|
||||||
|
|
||||||
|
row << t("hide")
|
||||||
|
row1 << "boolean"
|
||||||
|
row2 << "0 for false, 1 for true "
|
||||||
|
|
||||||
|
row << t("image")
|
||||||
|
row1 << "url"
|
||||||
|
row2 << "http://www.example.com/images/example.png"
|
||||||
|
|
||||||
|
row << t("image") + " " + t("description") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
row << t("image") + " " + t("description") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("title") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
row << t("title") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("subtitle") + " - " + t("en")
|
||||||
|
row1 << "textarea"
|
||||||
|
row2 << ""
|
||||||
|
row << t("subtitle") + " - " + t("zh_tw")
|
||||||
|
row1 << "textarea"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("content") + " - " + t("en")
|
||||||
|
row1 << "editor"
|
||||||
|
row2 << ""
|
||||||
|
row << t("content") + " - " + t("zh_tw")
|
||||||
|
row1 << "editor"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("link")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';'. Example: http://rulingcom.com; http://google.com"
|
||||||
|
|
||||||
|
row << t("link") + " " + t("url_alt") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Rulingcom official site; Google search engine"
|
||||||
|
row << t("link") + " " + t("url_alt") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Rulingcom official site; Google search engine"
|
||||||
|
|
||||||
|
row << t("file_")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';'. Example: http://www.example.com/images/example.png; http://www.example.com/images/example2.png"
|
||||||
|
|
||||||
|
row << t("file_") + " " + t("description") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Great view; Nice potrait"
|
||||||
|
row << t("file_") + " " + t("description") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Great view; Nice potrait"
|
||||||
|
|
||||||
|
row << t("file_") + " " + t("alternative") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : example1; example2"
|
||||||
|
row << t("file_") + " " + t("alternative") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : example1; example2"
|
||||||
|
|
||||||
|
|
||||||
|
sheet.add_row row, :style => heading
|
||||||
|
sheet.add_row row1
|
||||||
|
sheet.add_row row2, :style => example
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,177 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
wb = xlsx_package.workbook
|
||||||
|
|
||||||
|
wb.add_worksheet(name: "CustomAnnoucement") do |sheet|
|
||||||
|
|
||||||
|
heading = sheet.styles.add_style(:b => true, :locked => true)
|
||||||
|
example = sheet.styles.add_style(:i => true)
|
||||||
|
row = []
|
||||||
|
row1 = []
|
||||||
|
row2 = []
|
||||||
|
|
||||||
|
row << t("category")
|
||||||
|
row1 << "select"
|
||||||
|
t = ""
|
||||||
|
categories = @module_app.categories.asc(:created_at)
|
||||||
|
categories.each_with_index do |cat,i|
|
||||||
|
t = t + "#{i}" + " -> " + cat.title + ", "
|
||||||
|
end
|
||||||
|
if categories.count > 0
|
||||||
|
t = t + " Example : 0"
|
||||||
|
else
|
||||||
|
t = "Leave this field blank"
|
||||||
|
end
|
||||||
|
row2 << t
|
||||||
|
|
||||||
|
row << t("tags")
|
||||||
|
row1 << "select"
|
||||||
|
t = ""
|
||||||
|
tags = @module_app.tags.asc(:created_at)
|
||||||
|
tags.each_with_index do |tag,i|
|
||||||
|
t = t + "#{i}" + " -> " + tag.name + ", "
|
||||||
|
end
|
||||||
|
if tags.count > 0
|
||||||
|
t = t + " Example : 0,1,2"
|
||||||
|
else
|
||||||
|
t = "Leave this field blank"
|
||||||
|
end
|
||||||
|
row2 << t
|
||||||
|
|
||||||
|
row << t("start_date")
|
||||||
|
row1 << "date"
|
||||||
|
row2 << "Format: YYYY/MM/DD, Example: 2015/12/10"
|
||||||
|
|
||||||
|
row << t("end_date")
|
||||||
|
row1 << "date"
|
||||||
|
row2 << "Format: YYYY/MM/DD, Example: 2015/12/12"
|
||||||
|
|
||||||
|
row << t("top")
|
||||||
|
row1 << "boolean"
|
||||||
|
row2 << "0 for false, 1 for true"
|
||||||
|
|
||||||
|
row << t("hot")
|
||||||
|
row1 << "boolean"
|
||||||
|
row2 << "0 for false, 1 for true"
|
||||||
|
|
||||||
|
row << t("hide")
|
||||||
|
row1 << "boolean"
|
||||||
|
row2 << "0 for false, 1 for true "
|
||||||
|
|
||||||
|
row << t("image")
|
||||||
|
row1 << "url"
|
||||||
|
row2 << "http://www.example.com/images/example.png"
|
||||||
|
|
||||||
|
row << t("image") + " " + t("description") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
row << t("image") + " " + t("description") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("title") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
row << t("title") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("subtitle") + " - " + t("en")
|
||||||
|
row1 << "textarea"
|
||||||
|
row2 << ""
|
||||||
|
row << t("subtitle") + " - " + t("zh_tw")
|
||||||
|
row1 << "textarea"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("content") + " - " + t("en")
|
||||||
|
row1 << "editor"
|
||||||
|
row2 << ""
|
||||||
|
row << t("content") + " - " + t("zh_tw")
|
||||||
|
row1 << "editor"
|
||||||
|
row2 << ""
|
||||||
|
|
||||||
|
row << t("link")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';'. Example: http://rulingcom.com; http://google.com"
|
||||||
|
|
||||||
|
row << t("link") + " " + t("url_alt") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Rulingcom official site; Google search engine"
|
||||||
|
row << t("link") + " " + t("url_alt") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Rulingcom official site; Google search engine"
|
||||||
|
|
||||||
|
row << t("file_")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';'. Example: http://www.example.com/images/example.png; http://www.example.com/images/example2.png"
|
||||||
|
|
||||||
|
row << t("file_") + " " + t("description") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Great view; Nice potrait"
|
||||||
|
row << t("file_") + " " + t("description") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Great view; Nice potrait"
|
||||||
|
|
||||||
|
row << t("file_") + " " + t("alternative") + " - " + t("en")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : example1; example2"
|
||||||
|
row << t("file_") + " " + t("alternative") + " - " + t("zh_tw")
|
||||||
|
row1 << "textfield"
|
||||||
|
row2 << "Seperate with ';' with respective to the links in the link columns. Example : example1; example2"
|
||||||
|
|
||||||
|
|
||||||
|
sheet.add_row row, :style => heading
|
||||||
|
sheet.add_row row1
|
||||||
|
sheet.add_row row2, :style => example
|
||||||
|
|
||||||
|
@custom_announcements.each do |custom_anns|
|
||||||
|
row = []
|
||||||
|
row << categories.to_a.index(custom_anns.category)
|
||||||
|
t = []
|
||||||
|
custom_anns.tags.each do |tag|
|
||||||
|
t << tags.to_a.index(tag)
|
||||||
|
end
|
||||||
|
row << t.join(",")
|
||||||
|
row << (custom_anns.postdate.strftime("%Y/%m/%d") rescue "")
|
||||||
|
row << (custom_anns.deadline.strftime("%Y/%m/%d") rescue "")
|
||||||
|
row << (custom_anns.is_top? ? 1 : 0)
|
||||||
|
row << (custom_anns.is_hot? ? 1 : 0)
|
||||||
|
row << (custom_anns.is_hidden? ? 1 : 0)
|
||||||
|
row << ("http://" + request.host_with_port + custom_anns.image.url rescue "")
|
||||||
|
row << custom_anns.image_description_translations["en"]
|
||||||
|
row << custom_anns.image_description_translations["zh_tw"]
|
||||||
|
row << custom_anns.title_translations["en"]
|
||||||
|
row << custom_anns.title_translations["zh_tw"]
|
||||||
|
row << custom_anns.subtitle_translations["en"]
|
||||||
|
row << custom_anns.subtitle_translations["zh_tw"]
|
||||||
|
row << custom_anns.text_translations["en"]
|
||||||
|
row << custom_anns.text_translations["zh_tw"]
|
||||||
|
|
||||||
|
links = custom_anns.custom_bulletin_links.asc(:created_at)
|
||||||
|
t = links.collect{|l|l.url}
|
||||||
|
row << t.join(";")
|
||||||
|
t = links.collect{|l|l.title_translations["en"]}
|
||||||
|
row << t.join(";")
|
||||||
|
t = links.collect{|l|l.title_translations["zh_tw"]}
|
||||||
|
row << t.join(";")
|
||||||
|
|
||||||
|
files = custom_anns.custom_bulletin_files.asc(:created_at)
|
||||||
|
t = files.collect{|f|("http://" + request.host_with_port + f.file.url rescue nil)}
|
||||||
|
t.delete(nil)
|
||||||
|
row << t.join(";")
|
||||||
|
t = files.collect{|l|l.description_translations["en"]}
|
||||||
|
row << t.join(";")
|
||||||
|
t = files.collect{|l|l.description_translations["zh_tw"]}
|
||||||
|
row << t.join(";")
|
||||||
|
t = files.collect{|l|l.title_translations["en"]}
|
||||||
|
row << t.join(";")
|
||||||
|
t = files.collect{|l|l.title_translations["zh_tw"]}
|
||||||
|
row << t.join(";")
|
||||||
|
sheet.add_row row
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,124 @@
|
||||||
|
<% content_for :page_specific_css do %>
|
||||||
|
<%= stylesheet_link_tag("admin/tags") %>
|
||||||
|
<% end %>
|
||||||
|
<% content_for :page_specific_javascript do %>
|
||||||
|
<%= javascript_include_tag "validator" %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<table class="table main-list">
|
||||||
|
<thead>
|
||||||
|
<tr class="sort-header">
|
||||||
|
<% @table_feed_fields.each do |f| %>
|
||||||
|
<%= thead(f) %>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<%= render :partial => "feed", :collection => @feeds %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% if current_user.is_admin? or current_user.is_manager?(@module_app) %>
|
||||||
|
|
||||||
|
<div class="bottomnav clearfix" style="left: 81px;">
|
||||||
|
<div class="action pull-right">
|
||||||
|
<a class="btn btn-primary new-feed" href="#">
|
||||||
|
<i class="icon-plus"></i> <%= t(:new_) %>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="pagination pagination-centered"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="newFeedModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="newFeedModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h3 id="newFeedModalLabel">Create New Feed</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<%#= render :partial => "feed_form" %>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-primary" id="save_new_feed">Save changes</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
$(".new-feed").on("click",function(){
|
||||||
|
var modal = $("#newFeedModal");
|
||||||
|
modal.find("#newFeedModalLabel").text("Create New Feed");
|
||||||
|
modal.modal("show");
|
||||||
|
openFeedModal("new",null);
|
||||||
|
})
|
||||||
|
|
||||||
|
var bindEditButtons = function(){
|
||||||
|
$(".edit-feed").on("click",function(){
|
||||||
|
var modal = $("#newFeedModal");
|
||||||
|
modal.find("#newFeedModalLabel").text("Edit Feed");
|
||||||
|
modal.modal("show");
|
||||||
|
openFeedModal("edit",$(this).data("feed-id"));
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
$(".delete-feed").on("click",function(){
|
||||||
|
if(confirm("Are you sure?")){
|
||||||
|
var el = $(this);
|
||||||
|
$.ajax({
|
||||||
|
url : el.attr("href"),
|
||||||
|
type : "delete",
|
||||||
|
dataType : "html"
|
||||||
|
}).done(function(data){
|
||||||
|
$("table.main-list tbody").html(data);
|
||||||
|
bindEditButtons();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
bindEditButtons();
|
||||||
|
var openFeedModal = function(type,feed_id){
|
||||||
|
$.ajax({
|
||||||
|
url : "/admin/custom_announcements/feedform",
|
||||||
|
type : "get",
|
||||||
|
data : {"type" : type, "id" : feed_id},
|
||||||
|
dataType : "html"
|
||||||
|
}).done(function(form){
|
||||||
|
$("#newFeedModal .modal-body").html(form);
|
||||||
|
bindHandlers();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindHandlers = function(){
|
||||||
|
$(".tag-checkbox").on("click",function(){
|
||||||
|
if($(this).is(":checked")){
|
||||||
|
$(this).parent().addClass("active");
|
||||||
|
}else{
|
||||||
|
$(this).parent().removeClass("active");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var fv = new FormValidator($("#newFeedModal form"));
|
||||||
|
fv.form.on("submit",function(){
|
||||||
|
$.ajax({
|
||||||
|
url : fv.form.attr("action"),
|
||||||
|
data : fv.form.serializeArray(),
|
||||||
|
type : "post",
|
||||||
|
dataType : "html"
|
||||||
|
}).done(function(data){
|
||||||
|
$("table.main-list tbody").html(data);
|
||||||
|
bindEditButtons();
|
||||||
|
$("#newFeedModal").modal("hide");
|
||||||
|
fv.form.resetForm();
|
||||||
|
fv.form.find("ul.tags-groups p.active").removeClass("active");
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
$("#save_new_feed").on("click",function(){
|
||||||
|
if(fv.isFormValidated()){
|
||||||
|
fv.form.submit();
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</br>
|
|
@ -0,0 +1,87 @@
|
||||||
|
<% content_for :page_specific_javascript do %>
|
||||||
|
<script type="text/javascript" src="/assets/validator.js"></script>
|
||||||
|
<% end %>
|
||||||
|
<form action="<%= admin_custom_announcement_importcustom_anns_path %>" method="post" class="form-horizontal main-forms" id="import-custom_anns-xls" enctype="multipart/form-data">
|
||||||
|
<h3 style="padding-left: 30px;"><%= t("custom_announcement.export_to_excel") %></h3>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<a href="<%= admin_custom_announcement_export_excel_path(:format => "xlsx") %>"><%= t("custom_announcement.export_all_custom_anns") %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 style="padding-left: 30px;"><%= t("custom_announcement.import_from_excel") %></h3>
|
||||||
|
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
||||||
|
<div class="input-area">
|
||||||
|
<% if @module_app.categories.count > 0 %>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<a href="<%= admin_custom_announcement_excel_format_path(:format => "xlsx") %>"><%= t("custom_announcement.download_example_sheet_here") %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="import-custom_anns" class="control-label muted"><%= t("upload") %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="file" id="import-custom_anns" name="import_file" data-fv-validation="required;mustbexls;" data-fv-messages="Cannot be empty; Must be an excel file.;" />
|
||||||
|
<span class="help-block"><%= t("custom_announcement.please_create_tags_cats") %></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<h4><%= t("custom_announcement.create_atleast_one_cat") %></h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% if @module_app.categories.count > 0 %>
|
||||||
|
<div class="form-actions">
|
||||||
|
<input type="submit" value="<%= t("restful_actions.import") %>" class="btn btn-primary">
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- import from wp xml -->
|
||||||
|
<form action="<%= admin_custom_announcement_import_from_wp_path %>" method="post" class="form-horizontal main-forms" id="import-custom_anns-wp-xml" enctype="multipart/form-data">
|
||||||
|
<h3 style="padding-left: 30px;"><%= t("custom_announcement.import_from_wp_xml") %></h3>
|
||||||
|
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
||||||
|
<div class="input-area">
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="import-custom_anns-wp-xml" class="control-label muted"><%= t("upload") %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="file" id="import-custom_anns-wp-xml" name="import_xml" data-fv-validation="required;mustbexml;" data-fv-messages="Cannot be empty; Must be an XML file.;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-actions">
|
||||||
|
<input type="submit" value="<%= t("restful_actions.import") %>" class="btn btn-primary">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<!-- <form action="<%#= admin_custom_announcement_import_from_xml_path %>" method="post" class="form-horizontal main-forms" id="import-custom_anns-xml" enctype="multipart/form-data">
|
||||||
|
<h3 style="padding-left: 30px;">Import from XML</h3>
|
||||||
|
<%#= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
||||||
|
<div class="input-area">
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="import-custom_anns" class="control-label muted">URL :</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="import-custom_anns" name="import_xml" data-fv-validation="required;url;" data-fv-messages="Cannot be empty; Must be an URL.;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-actions">
|
||||||
|
<input type="submit" value="Import" class="btn btn-primary">
|
||||||
|
</div>
|
||||||
|
</form> -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
var form = new FormValidator($("#import-custom_anns-xls"));
|
||||||
|
form.validate_functions.mustbexls = function(val){
|
||||||
|
var t = val.split("."),
|
||||||
|
ext = t[t.length - 1];
|
||||||
|
return (ext == "xls" || ext == "xlsx")
|
||||||
|
}
|
||||||
|
var form = new FormValidator($("#import-custom_anns-wp-xml"));
|
||||||
|
form.validate_functions.mustbexml = function(val){
|
||||||
|
var t = val.split("."),
|
||||||
|
ext = t[t.length - 1];
|
||||||
|
return (ext == "xml")
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<%= render_filter @filter_fields, "index_table" %>
|
||||||
|
<% custom_config = CustomBulletinConfig.where(:module=>params[:custom_module]).first %>
|
||||||
|
<% target_model = custom_config.bind_model.constantize %>
|
||||||
|
<h3><%= target_model.where(custom_config.uid_field=>params[:bind_uid]).first.send(custom_config.title_field) %></h3>
|
||||||
|
<span id="index_table">
|
||||||
|
<%= render 'index'%>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<%= render 'layouts/delete_modal', delete_options: @delete_options %>
|
||||||
|
|
||||||
|
<% if CustomAnnouncementSetting.is_pro? && user_can_approve? %>
|
||||||
|
<%= render :partial=> "approval_modal" %>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
var modal = $("#approvalModal");
|
||||||
|
$(document).on("click", ".approval_button",function(){
|
||||||
|
var url = $(this).attr("href");
|
||||||
|
if(window.location.protocol === "https:"){
|
||||||
|
url = url.replace("http:","https:");
|
||||||
|
}
|
||||||
|
modal.find("iframe").attr("src", url);
|
||||||
|
modal.find("#object_id").val($(this).data("id"));
|
||||||
|
modal.modal("show");
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
|
||||||
|
var params = getUrlVars();
|
||||||
|
console.log(params["url"])
|
||||||
|
if(typeof params["url"] != "undefined"){
|
||||||
|
modal.find("iframe").attr("src", params["url"]);
|
||||||
|
modal.find("#object_id").val(params["id"]);
|
||||||
|
modal.modal("show");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<%= form_for @custom_bulletin, url: admin_custom_announcements_path, html: {class: "form-horizontal main-forms previewable"} do |f| %>
|
||||||
|
<fieldset>
|
||||||
|
<%= render :partial => 'form', locals: {f: f} %>
|
||||||
|
</fieldset>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,390 @@
|
||||||
|
<%= stylesheet_link_tag "select2/select2" %>
|
||||||
|
<%= javascript_include_tag 'validator' %>
|
||||||
|
<%= javascript_include_tag "select2/select2.min" %>
|
||||||
|
<% content_for :page_specific_css do %>
|
||||||
|
<%= stylesheet_link_tag "lib/main-forms" %>
|
||||||
|
<% end %>
|
||||||
|
<style type="text/css">
|
||||||
|
#notification{
|
||||||
|
background-color: #ececec;
|
||||||
|
font-size: 14px;
|
||||||
|
left: 40%;
|
||||||
|
padding: 10px;
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
top: 40px;
|
||||||
|
width: auto;
|
||||||
|
z-index: 1200;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.badge-info{
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
#approver-list{
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
#approver-list li {
|
||||||
|
border-bottom: 1px solid #efefef;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
#approver-list .approver-avatar{
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
#approver-list .approver-check{
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
#approver-list .approver-check input{
|
||||||
|
margin-right: 5px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
#approver-list .approver-check label{
|
||||||
|
display: inline;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
#approver-list .approver-title{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.table{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.table-row,.role_limit_tr,.role_limit_add {
|
||||||
|
width: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.td{
|
||||||
|
width: 30%;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.table{
|
||||||
|
border: #2d4cd0 0.1em solid;
|
||||||
|
}
|
||||||
|
.td-3{
|
||||||
|
width: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.td>*{
|
||||||
|
max-width: 95%;
|
||||||
|
}
|
||||||
|
.td-delete{
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<%
|
||||||
|
sub_managers = @module_app.sub_managers
|
||||||
|
sub_managers.delete(nil)
|
||||||
|
all_statuses = [[t('top'),'is_top'],[t('hot'),'is_hot']]
|
||||||
|
tp1 = select_tag("custom_announcement_setting[custom_anns_status_settings][-1][status]",options_for_select(all_statuses))
|
||||||
|
tp2 = select_tag("custom_announcement_setting[custom_anns_status_settings][-1][role_id]",options_for_select(Role.all.map{|r| [r.title,r.id]}))
|
||||||
|
tp3 = number_field_tag("custom_announcement_setting[custom_anns_status_settings][-1][top_limit]",nil, min: 0,required: true)
|
||||||
|
tp4 = "<button type='button' onclick='delete_limit_role(this)'' class='btn'>#{t('delete_')}</button>"
|
||||||
|
all_tp = "<div class='role_limit_tr'><div class='td'>#{tp1}</div><div class='td'>#{tp2}</div><div class='td'>#{tp3}</div><div class='td-delete'>#{tp4}</div></div>"
|
||||||
|
%>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function add_limit_role(){
|
||||||
|
var role_limit_l = $('.role_limit_tr').length
|
||||||
|
var role_limit_tp = '<%= all_tp.inspect %>'
|
||||||
|
role_limit_tp = role_limit_tp.replace(/-1/g,role_limit_l)
|
||||||
|
$('.role_limit_add').before($('<div/>').html(role_limit_tp).text().slice(1,-2))
|
||||||
|
}
|
||||||
|
function delete_limit_role(ele){
|
||||||
|
var now_index = $(ele).parents('.role_limit_tr').index('.role_limit_tr')
|
||||||
|
console.log(now_index)
|
||||||
|
$(ele).parents('.role_limit_tr').remove()
|
||||||
|
$('.role_limit_tr').each(function(i,v){
|
||||||
|
if (i >= now_index){
|
||||||
|
$(v).find('[name^="custom_announcement_setting[custom_anns_status_settings]"]').each(function(i1,v1){
|
||||||
|
console.log($(v1).attr('name'))
|
||||||
|
$(v1).attr('name',$(v1).attr('name').replace(/\d+/g,i.toString()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$(document).ready(function(){
|
||||||
|
var approverList = $(".hidden-approver-list");
|
||||||
|
$(".approver-check input").on("click",function(){
|
||||||
|
var el = $(this);
|
||||||
|
if(el.is(":checked")){
|
||||||
|
var t = $("<input type='hidden'>");
|
||||||
|
t.val(el.val());
|
||||||
|
t.attr("name", "custom_announcement_setting[approvers][]");
|
||||||
|
t.attr("id", "check_" + el.val());
|
||||||
|
approverList.append(t);
|
||||||
|
}else{
|
||||||
|
approverList.find("#check_" + el.val()).remove();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<div id="notification"><%= t("custom_announcement.click_on_submit") %></div>
|
||||||
|
<%= form_for @setting, url: (@setting.new_record? ? admin_custom_announcement_createsettings_path : admin_custom_announcement_updatesettings_path), html: {class: "form-horizontal main-forms"} do |f| %>
|
||||||
|
<div class="input-area">
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :only_manager_can_edit_status, t("custom_announcement.only_manager_can_edit_status"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :only_manager_can_edit_status %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :is_display_edit_only, t("custom_announcement.is_display_edit_only"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.check_box :is_display_edit_only %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :top_limit, t("custom_announcement.top_limit"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= f.number_field :top_limit, :min => "0" %>
|
||||||
|
<span class="help-block"><%= t("custom_announcement.for_unlimited") %></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="table">
|
||||||
|
<div class="table-row">
|
||||||
|
<div class="td">
|
||||||
|
<%= t('status') %>
|
||||||
|
</div>
|
||||||
|
<div class="td">
|
||||||
|
<%= t('role') %>
|
||||||
|
</div>
|
||||||
|
<div class="td">
|
||||||
|
<%= t('custom_announcement.top_limit') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% (CustomAnnouncementSetting.first.custom_anns_status_settings rescue []).each_with_index do |v,i| %>
|
||||||
|
<div class="role_limit_tr">
|
||||||
|
<%= hidden_field_tag("custom_announcement_setting[custom_anns_status_settings][#{i}][_id]",v.id) %>
|
||||||
|
<div class="td">
|
||||||
|
<%= select_tag("custom_announcement_setting[custom_anns_status_settings][#{i}][status]",options_for_select(all_statuses,:selected => v['status'])) %>
|
||||||
|
</div>
|
||||||
|
<div class="td">
|
||||||
|
<%= select_tag("custom_announcement_setting[custom_anns_status_settings][#{i}][role_id]",options_for_select(Role.all.map{|r| [r.title,r.id]},:selected => v['role_id'])) %>
|
||||||
|
</div>
|
||||||
|
<div class="td">
|
||||||
|
<%= number_field_tag("custom_announcement_setting[custom_anns_status_settings][#{i}][top_limit]",v['top_limit'], min: 0,required: true) %>
|
||||||
|
</div>
|
||||||
|
<div class="td-delete">
|
||||||
|
<button type="button" onclick="delete_limit_role(this)" class="btn">
|
||||||
|
<%= t('delete_') %>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<div class="role_limit_add">
|
||||||
|
<div class="td-3">
|
||||||
|
<button type="button" onclick="add_limit_role()" class="btn">
|
||||||
|
<%= t('add') %>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% if CustomAnnouncementSetting.is_pro? %>
|
||||||
|
<% if !sub_managers.blank? %>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label "Approver Setting", :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<a href="#approverModal" role="button" class="btn" data-toggle="modal"><%= t("custom_announcement.approvers_list") %></a>
|
||||||
|
<span class="badge badge-info"><%= @setting.approvers.count %></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="control-group">
|
||||||
|
<a href="/admin/authorizations/custom_announcement"><%= t("custom_announcement.click_set_sub_manager") %></a>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label "Send emails to", :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="checkbox" name="custom_announcement_setting[email_to][]" value="admins" <%= @setting.email_to.include?("admins") ? "checked=checked" : "" %>> <%= t("admin") %>
|
||||||
|
<input type="checkbox" name="custom_announcement_setting[email_to][]" value="managers" <%= @setting.email_to.include?("managers") ? "checked=checked" : "" %>> <%= t("manager") %>
|
||||||
|
<input type="checkbox" name="custom_announcement_setting[email_to][]" value="approvers" <%= @setting.email_to.include?("approvers") ? "checked=checked" : "" %>> <%= t("custom_announcement.approver") %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hidden-approver-list">
|
||||||
|
<% sub_managers.each do |sm| %>
|
||||||
|
<% if @setting.approvers.include?(sm.id.to_s) %>
|
||||||
|
<input type="hidden" id="check_<%= sm.id.to_s %>" value="<%= sm.id.to_s %>" name="custom_announcement_setting[approvers][]">
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<div class="form-actions">
|
||||||
|
<%= f.submit t('submit'), class: 'btn btn-primary' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% if CustomAnnouncementSetting.is_pro? %>
|
||||||
|
<div id="approverModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="approverModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h3 id="approverModalLabel"><%= t("sub_manager") %></h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<ul id="approver-list">
|
||||||
|
<% sub_managers.each do |sm| %>
|
||||||
|
<li>
|
||||||
|
<%= image_tag sm.member_profile.avatar.thumb, :class => "approver-avatar" %>
|
||||||
|
<span class="approver-title"><%= sm.name %></span>
|
||||||
|
<span class="pull-right approver-check">
|
||||||
|
<input id="checkbox_<%= sm.id %>" type="checkbox" value="<%= sm.id %>" <%= @setting.approvers.include?(sm.id.to_s) ? "checked=checked" : "" %>>
|
||||||
|
<label for="checkbox_<%= sm.id %>"><%= t("custom_announcement.approver") %></label>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">Ok</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$("#approverModal").on("hidden",function(){
|
||||||
|
$("#notification").slideDown();
|
||||||
|
$(".badge-info").text($(".hidden-approver-list input").length);
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<% end %>
|
||||||
|
<%= fields_for :iframe do |f| %>
|
||||||
|
<div class="form-horizontal input-area">
|
||||||
|
<fieldset id="iframe_settings">
|
||||||
|
<legend><%=t('custom_announcement.custom_announcement_setting_for_iframe')%></legend>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :layout_type, t("custom_announcement.layout_type"), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<% @layout_types = get_layouts(@module_app.key) %>
|
||||||
|
<% if @layout_types.first.kind_of?(Hash) %>
|
||||||
|
<select name="iframe[layout_type]" id="page_layout" class="select2">
|
||||||
|
<% @layout_types.each do |lt| %>
|
||||||
|
<option value="<%= lt["filename"] %>" data-image="<%= lt["thumbnail"] %>"><%= (lt["name"].kind_of?(Hash) ? (lt["name"][I18n.locale.to_s] || lt["name"]['en']) : lt["name"]) %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$("select.select2").select2({
|
||||||
|
formatResult: function(el){
|
||||||
|
var $element = $(el.element),
|
||||||
|
image = $element.data("image");
|
||||||
|
return "<img class='thumbnail' src='" + image + "'/><span class='thumbnail-text'>" + el.text + "</span>";
|
||||||
|
},
|
||||||
|
minimumResultsForSearch: -1,
|
||||||
|
width : 250
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<% else %>
|
||||||
|
<%= f.select(:layout, @layout_types) %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :tags, t(:tags), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<% @module_app.tags.each_with_index do |t,index| %>
|
||||||
|
<label class="checkbox inline btn" for="<%="tags_#{index}"%>">
|
||||||
|
<input id="<%="tags_#{index}"%>" name="iframe[tags][]" type="checkbox" value="<%=t.id%>" style="opacity: 0;">
|
||||||
|
<%=t.name%>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label muted" ><%=t(:categories)%></label>
|
||||||
|
<div class="controls">
|
||||||
|
<% @module_app.categories.each_with_index do |c,index| %>
|
||||||
|
<label class="checkbox inline btn" for="<%="categories_#{index}"%>">
|
||||||
|
<input id="<%="categories_#{index}"%>" name="iframe[categories][]" type="checkbox" value="<%=c.id%>" style="opacity: 0;">
|
||||||
|
<%=c.title%>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :authors, t('custom_announcement.table.author'), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%= render partial: 'admin/members/generate_modal_select' , locals: { :@sorted_members => @sorted_members ,:member_form_id => "card-list-members",:member_field_name=>"iframe[member_ids][]" } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :show_page, t('custom_announcement.show_page'), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%=f.check_box :show_page ,{:checked=>'checked'},'true','false'%>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<%= f.label :data_count, t(:data_count), :class => "control-label muted" %>
|
||||||
|
<div class="controls">
|
||||||
|
<%=f.number_field :data_count, {min: 0,:value=> 10} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<a class="btn btn-primary" title="<%= t("custom_announcement.url_generate") %>" id="url_generate"><%= t("custom_announcement.url_generate") %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function getparams(id){
|
||||||
|
var params_array = $("#"+id).serializeArray();
|
||||||
|
var params = {};
|
||||||
|
params_array.forEach(function(dict){
|
||||||
|
if(params[dict.name] == undefined)
|
||||||
|
if(dict.name.substr(dict.name.length-2,2) == "[]")
|
||||||
|
params[dict.name] = [dict.value]
|
||||||
|
else
|
||||||
|
params[dict.name] = dict.value
|
||||||
|
else
|
||||||
|
if(dict.name.substr(dict.name.length-2,2) == "[]")
|
||||||
|
params[dict.name].push(dict.value)
|
||||||
|
else
|
||||||
|
params[dict.name] = dict.value
|
||||||
|
})
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('label.checkbox input').click(function(){
|
||||||
|
if($(this).parent().hasClass('active'))
|
||||||
|
$(this).parent().removeClass('active');
|
||||||
|
else
|
||||||
|
$(this).parent().addClass('active');
|
||||||
|
})
|
||||||
|
$('#url_generate').off('click').on('click',function(){
|
||||||
|
var params = getparams('iframe_settings');
|
||||||
|
$.post("<%=admin_custom_announcement_generate_iframe_url_path%>",params).done(function(url){
|
||||||
|
var real_url = '/annc_url?url='+window.location.href.split('/')[0]+"//"+window.location.host+url;
|
||||||
|
if($("#dialog-confirm").length == 0){
|
||||||
|
$("#url_generate").before("<div id='dialog-confirm' title='<%="iframe "+t('custom_announcement.URL')%>'>"+
|
||||||
|
"<div style='clear:both;'></div><div id='info_texts'>"+"<label style='float:left;margin-right: 0.2em; line-height: 2em;' for='iframe_url'><%="iframe "+t('custom_announcement.URL') %>:</label><input id= 'iframe_url' style='float:left;cursor:text;' type='text' readyonly value='"+real_url+"'><a class='btn btn-primary copy_text' style='color: white;'><%=t('custom_announcement.copy')%></a>"+"</div>"+
|
||||||
|
"</div>");
|
||||||
|
}
|
||||||
|
$( "#dialog-confirm" ).dialog({
|
||||||
|
resizable: true,
|
||||||
|
minHeight: 100,
|
||||||
|
maxHeight: 400,
|
||||||
|
width: '80%',
|
||||||
|
modal: true,
|
||||||
|
buttons: {
|
||||||
|
"<%= t(:close) %>": function(){$( this ).dialog( "close" );}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('.copy_text').off('click').on('click',function(){
|
||||||
|
var copyText = document.getElementById("iframe_url");
|
||||||
|
copyText.select();
|
||||||
|
copyText.setSelectionRange(0, 99999);
|
||||||
|
document.execCommand("copy");
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,16 @@
|
||||||
|
xml.instruct! :xml, :version => "1.0"
|
||||||
|
xml.rss :version => "2.0" do
|
||||||
|
xml.channel do
|
||||||
|
xml.title @bf.title
|
||||||
|
xml.link "/xhr/custom_announcements/rssfeed/73999228.rss"
|
||||||
|
|
||||||
|
for custom_announcement in @custom_announcements
|
||||||
|
xml.item do
|
||||||
|
xml.title custom_announcement.title
|
||||||
|
xml.description custom_announcement.subtitle
|
||||||
|
xml.pubDate custom_announcement.created_at.to_s(:rfc822)
|
||||||
|
xml.link page_for_custom_bulletin(custom_announcement)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,39 @@
|
||||||
|
<% active_module = @custom_data_field[:bind_module_app] rescue nil %>
|
||||||
|
<% active_uid = @custom_data_field[:bind_uid] rescue nil %>
|
||||||
|
<% active_module = @custom_configs.first.module if active_module.nil? %>
|
||||||
|
<div class="control-group input-content">
|
||||||
|
<label class="control-label muted" for="custom_bind_module_app"><%=t("custom_announcement.use_module")%> :</label>
|
||||||
|
<div class="controls">
|
||||||
|
<%= select_tag("#{@field_name}[custom_data_field][bind_module_app]", options_for_select(@custom_configs.map{|c| [t("module_name.#{c.module}"),c.module]},active_module),{:id=>"custom_bind_module_app"})%>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group input-content">
|
||||||
|
<label class="control-label muted" for="custom_bind_uid"><%=t("custom_announcement.use_content")%> :</label>
|
||||||
|
<div class="controls">
|
||||||
|
<% @custom_configs.each do |c| %>
|
||||||
|
<% title_field = c.title_field
|
||||||
|
uid_field = c.uid_field
|
||||||
|
bind_model = c.bind_model.constantize rescue nil
|
||||||
|
%>
|
||||||
|
<% if bind_model %>
|
||||||
|
<div class="<%=(c.module == active_module) ? "show bind_modules" : "hide bind_modules" %>" data-module="<%= c.module %>">
|
||||||
|
<%= select_tag("#{@field_name}[custom_data_field][bind_uid]", options_for_select(bind_model.where(title_field.to_sym.nin=>[nil,""]).map{|target_model| [target_model.send(title_field),target_model.send(uid_field)]},active_uid),{:id=>"custom_bind_uid"})%>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
if($(".bind_modules.hide").length != 0){
|
||||||
|
$(".bind_modules.hide").eq(-1).after($(".bind_modules.show"));
|
||||||
|
}
|
||||||
|
$("#custom_bind_module_app").change(function(){
|
||||||
|
var value = $(this).val();
|
||||||
|
console.log(value)
|
||||||
|
$(".bind_modules").removeClass("show").addClass("hide");
|
||||||
|
$("[data-module=\""+value+"\"]").removeClass("hide").addClass("show");
|
||||||
|
if($(".bind_modules.hide").length != 0){
|
||||||
|
$(".bind_modules.hide").eq(-1).after($(".bind_modules.show"));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#FFFFFF">
|
||||||
|
<div style="text-ident:20px"></div>
|
||||||
|
|
||||||
|
<%= t('custom_announcement.mail_hi') %> <br /><br />
|
||||||
|
<%= t('custom_announcement.mail_url_view') %> <br /><br />
|
||||||
|
<a href="<%= @data["url"] %>" target="_blank"> <%= @data["title"] %> </a> <br /><br />
|
||||||
|
|
||||||
|
<span style="color:#555">--<br />
|
||||||
|
<%= t('custom_announcement.mail_source') %> :<a href="http://<%= @data["host"] %>" target="_blank"> <%= Site.first.title %> </a><br />
|
||||||
|
<%= t('custom_announcement.mail_time') %> <%= DateTime.now.strftime('%Y/%m/%d %H:%M:%S') %>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,85 @@
|
||||||
|
<% params = OrbitHelper.params
|
||||||
|
page = Page.where(url:params['url']).first
|
||||||
|
enable_search_flag = false
|
||||||
|
if page.methods.include? 'select_option_items'.to_sym
|
||||||
|
ModuleApp.all.select{|tmp| tmp.key.to_s=='custom_announcement'}.each do |modile_app|
|
||||||
|
@show_option_items = modile_app.show_option_items rescue nil
|
||||||
|
end
|
||||||
|
page.select_option_items.each do |select_option_item|
|
||||||
|
if !(@show_option_items.nil?) && select_option_item.field_name == @show_option_items.keys[1].to_s
|
||||||
|
value = YAML.load(select_option_item.value)
|
||||||
|
if value[I18n.locale] == t('custom_announcement.yes')
|
||||||
|
enable_search_flag = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%>
|
||||||
|
<% if enable_search_flag %>
|
||||||
|
<style type="text/css">
|
||||||
|
#category_select_box{
|
||||||
|
margin: 0;
|
||||||
|
background: linear-gradient(0deg, #515fff, #ff3e3e);
|
||||||
|
color: white;
|
||||||
|
outline: 0;
|
||||||
|
border-radius: 0.9em;
|
||||||
|
}
|
||||||
|
#category_select_box>option{
|
||||||
|
background: #5640dd;
|
||||||
|
}
|
||||||
|
input.search_box{
|
||||||
|
margin: 0;
|
||||||
|
background: #a2c3df;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #00008b;
|
||||||
|
border-radius: 0.7em;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
input.search_box[type='submit']:hover{
|
||||||
|
background: #9100ff;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
input.search_box[type='submit']:active{
|
||||||
|
background: #7201ff;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
input.search_box::-webkit-input-placeholder {
|
||||||
|
color: #aa58e8;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
input.search_box:-moz-placeholder {
|
||||||
|
color: #aa58e8;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
input.search_box::-moz-placeholder {
|
||||||
|
color: #aa58e8;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<form>
|
||||||
|
<% cats = Array(page.categories)
|
||||||
|
if cats.include? 'all'
|
||||||
|
cats = ModuleApp.where(key: 'custom_announcement').first.categories
|
||||||
|
else
|
||||||
|
cats = cats.map{|v| Category.where(id: v).first}.compact
|
||||||
|
end
|
||||||
|
all_cat = [[t('custom_announcement.all'),'all']]
|
||||||
|
%>
|
||||||
|
<div class="search_widget" style="display: flex;flex-wrap: wrap;font-size: 1.1em;">
|
||||||
|
<%= select_tag('category',options_for_select(all_cat.concat(cats.map{|v| [v.title,v.id.to_s]}),:selected => params['category'].to_s),:id=>"category_select_box",:prompt => t('custom_announcement.select_prompt')) %>
|
||||||
|
<input class="search_box" type="text" name="keywords" value="<%= params['keywords'].to_s.gsub(/\"/,'') %>" placeholder="<%= t('custom_announcement.keywords') %>">
|
||||||
|
<div style="display: flex;flex-wrap: wrap;">
|
||||||
|
<div class="default_picker">
|
||||||
|
<input class="search_box" type="text" name="stime" value="<%= params['stime'].to_s.gsub(/\"/,'') %>" placeholder="<%= t('custom_announcement.stime') %>" data-format="yyyy/mm/dd">
|
||||||
|
</div>
|
||||||
|
~
|
||||||
|
<div class="default_picker">
|
||||||
|
<input class="search_box" type="text" name="etime" value="<%= params['etime'].to_s.gsub(/\"/,'') %>" placeholder="<%= t('custom_announcement.etime') %>" data-format="yyyy/mm/dd">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="authenticity_token" value="<%= (0...46).map { ('a'..'z').to_a[rand(26)] }.join %>">
|
||||||
|
<input class="search_box" type="submit" value="<%= t('custom_announcement.search') %>">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<% end %>
|
||||||
|
<%= render_view %>
|
|
@ -0,0 +1,180 @@
|
||||||
|
<%
|
||||||
|
params = OrbitHelper.params
|
||||||
|
page = Page.where(url:params['url']).first
|
||||||
|
@show_back_and_next_flag = 0
|
||||||
|
if page.methods.include? 'select_option_items'.to_sym
|
||||||
|
ModuleApp.all.select{|tmp| tmp.key.to_s=='custom_announcement'}.each do |modile_app|
|
||||||
|
@show_option_items = modile_app.show_option_items rescue nil
|
||||||
|
end
|
||||||
|
page.select_option_items.each do |select_option_item|
|
||||||
|
if !(@show_option_items.nil?) && select_option_item.field_name == @show_option_items.keys.first.to_s
|
||||||
|
value = YAML.load(select_option_item.value)
|
||||||
|
tmp = value[:en]
|
||||||
|
I18n.with_locale(:en) do
|
||||||
|
if tmp == t('custom_announcement.not_show')
|
||||||
|
@show_back_and_next_flag = 0
|
||||||
|
elsif tmp == t('custom_announcement.show_top')
|
||||||
|
@show_back_and_next_flag = 1
|
||||||
|
elsif tmp == t('custom_announcement.show_bottom')
|
||||||
|
@show_back_and_next_flag = 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if @show_back_and_next_flag != 0
|
||||||
|
uid = params['uid']
|
||||||
|
sorted,total_pages = get_sorted_annc(0)
|
||||||
|
now_index = sorted.to_enum.with_index.select{|v| v[0].uid==uid}[0][1] rescue nil
|
||||||
|
if !now_index.nil?
|
||||||
|
if now_index != 0
|
||||||
|
prev_result = sorted[now_index-1]
|
||||||
|
prev_url = params['url'] + '/' + prev_result.to_param
|
||||||
|
prev_content = "<a href='#{prev_url}' title='#{t('custom_announcement.prev')}' class='prev'><b>#{t('custom_announcement.prev')}</b><p>#{prev_result['title'][I18n.locale]}</p></a>"
|
||||||
|
end
|
||||||
|
if now_index != sorted.length-1
|
||||||
|
next_result = sorted[now_index+1]
|
||||||
|
next_url = params['url'] + '/' + next_result.to_param
|
||||||
|
next_content = "<a href='#{next_url}' title='#{t('custom_announcement.next')}' class='next'><b>#{t('custom_announcement.next')}</b><p>#{next_result['title'][I18n.locale]}</p></a>"
|
||||||
|
end
|
||||||
|
content = "<div class='see_more_boxTitle'>#{prev_content}#{next_content}</div>".html_safe
|
||||||
|
else
|
||||||
|
content = ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%>
|
||||||
|
<% if @show_back_and_next_flag!=0 %>
|
||||||
|
<style type="text/css">
|
||||||
|
.see_more_boxTitle{
|
||||||
|
display: flex;
|
||||||
|
margin: 1em 0em;
|
||||||
|
padding: 1em;
|
||||||
|
border: 0.2em solid;
|
||||||
|
}
|
||||||
|
a.prev, a.next{
|
||||||
|
width: 50%;
|
||||||
|
border: 0.2em solid;
|
||||||
|
padding: 1em;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
a.next{
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
a.prev{
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if @show_back_and_next_flag==1 %>
|
||||||
|
<%= content %>
|
||||||
|
<% end %>
|
||||||
|
<%= render_view %>
|
||||||
|
<% if @show_back_and_next_flag==2 %>
|
||||||
|
<%= content %>
|
||||||
|
<% end %>
|
||||||
|
<% site = Site.first
|
||||||
|
hover_color = site.orbit_bar_background_hover_color rescue nil
|
||||||
|
hover_color = '#0095CF' if hover_color.blank?
|
||||||
|
bg_color = site.orbit_bar_background_color rescue nil
|
||||||
|
bg_color = bg_color.blank? ? '#3a3b3c' : CustomAnnouncementsHelper.lighten_color(bg_color,-40)
|
||||||
|
color1 = CustomAnnouncementsHelper.lighten_color(bg_color,-40)
|
||||||
|
color2 = CustomAnnouncementsHelper.lighten_color(CustomAnnouncementsHelper.complementaryColor(bg_color),40)
|
||||||
|
%>
|
||||||
|
<style type="text/css">
|
||||||
|
div[contentEditable=true]:empty:before{
|
||||||
|
content: attr(data-ph);
|
||||||
|
color: <%= color1 %>;
|
||||||
|
padding-left: 3%;
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: serif;
|
||||||
|
}
|
||||||
|
.custom_announcement-comment {
|
||||||
|
margin-top: 1em;
|
||||||
|
border: solid 0.2em <%= bg_color %>;
|
||||||
|
background: <%= color2 %>;
|
||||||
|
color: <%= bg_color %>;
|
||||||
|
font-size: 1.15em;
|
||||||
|
padding: 0.3em 0 0.3em 3%;
|
||||||
|
border-radius: 0.7em;
|
||||||
|
display: inline-block;
|
||||||
|
width: 80%;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.annc-comment-div,.annc-comments{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.btn-comment{
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-left: 3%;
|
||||||
|
color: <%= color2 %>;
|
||||||
|
font-size: 1em;
|
||||||
|
background: <%= bg_color %>;
|
||||||
|
margin-left: 3%;
|
||||||
|
}
|
||||||
|
.btn.btn-comment:focus{
|
||||||
|
color: <%= color2 %>;
|
||||||
|
}
|
||||||
|
.btn-comment:hover{
|
||||||
|
color: <%= color2 %>;
|
||||||
|
background-color: <%= hover_color %>;
|
||||||
|
}
|
||||||
|
.annc-comments-nickname {
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-left: 3%;
|
||||||
|
color: <%= bg_color %>;
|
||||||
|
}
|
||||||
|
.comment-time{
|
||||||
|
padding-left: 1em;
|
||||||
|
width: 100%;
|
||||||
|
color: <%= bg_color %>;
|
||||||
|
}
|
||||||
|
.annc-comments{
|
||||||
|
margin: 1.5em 0;
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.annc-comment-div,.annc-comments{
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.custom_announcement-comment {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$('.annc-comment-div .btn-comment').click(function(){
|
||||||
|
$.ajax({
|
||||||
|
url: "<%= "/xhr/custom_announcements/#{params[:slug]}-#{params[:uid]}/comment" %>",
|
||||||
|
data : {"comment" : $(this).parents('.annc-comment-div').find('.custom_announcement-comment').html()},
|
||||||
|
dataType : "json",
|
||||||
|
type : "get",
|
||||||
|
success : function(data){
|
||||||
|
window.location.href = window.location.href
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<% action_data['comments'].reverse.each do |comment| %>
|
||||||
|
<div class="annc-comments">
|
||||||
|
<div class="comment-time">
|
||||||
|
<%= comment.time %>
|
||||||
|
</div>
|
||||||
|
<div class="custom_announcement-comment">
|
||||||
|
<%= comment.comment.html_safe %>
|
||||||
|
</div>
|
||||||
|
<div class="annc-comments-nickname">by <%= comment.account %></div>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% if action_data['show_comment_flag'] %>
|
||||||
|
<div class="annc-comment-div">
|
||||||
|
<div data-ph="<%= t('custom_announcement.comment') %>" contenteditable="true" class="custom_announcement-comment"></div>
|
||||||
|
<button class="btn btn-comment">
|
||||||
|
<%= t('custom_announcement.send_comment') %>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><%= render_site_title %></title>
|
||||||
|
<%= stylesheet_link_tag "//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css"%>
|
||||||
|
<%= stylesheet_link_tag "custom_bulletin/bootstrap/bootstrap.min.css"%>
|
||||||
|
<%= stylesheet_link_tag "template/template"%>
|
||||||
|
<%= javascript_include_tag "jquery.min"%>
|
||||||
|
<%= javascript_include_tag "bootstrap.min"%>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<% @target_action = "show_widget" %>
|
||||||
|
<%=render_view_for_annc((!params[:layout_type].blank? ? params[:layout_type] : 'annc_index1'))%>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
<%= @data["html"].html_safe %>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<h3>Hello <%= @data["name"] %>,</h3>
|
||||||
|
<p><%= @data["submitter"] %> <%= t("custom_announcement.updated_annoucement") %>
|
||||||
|
<a href="<%= @data['url'] %>" ><%= t("custom_announcement.click_here_to_see") %></a>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<h3>Hello <%= @data["name"] %>,</h3>
|
||||||
|
<p><%= @data["rejector"] %> <%= t("annoucement.rejected_annoucement") %> : <%= @data["reason"].nil? || @data["reason"] == "" ? "" : "#{@data["reason"]}" %></p>
|
||||||
|
<a href="<%= @data['url'] %>" ><%= t("custom_announcement.click_here_to_see") %></a>
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
# This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
|
||||||
|
|
||||||
|
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
||||||
|
ENGINE_PATH = File.expand_path('../../lib/custom_announcement/engine', __FILE__)
|
||||||
|
|
||||||
|
# Set up gems listed in the Gemfile.
|
||||||
|
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||||
|
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
||||||
|
|
||||||
|
# require 'rails/all'
|
||||||
|
# require 'rails/engine/commands'
|
||||||
|
require "action_controller/railtie"
|
||||||
|
require "action_mailer/railtie"
|
||||||
|
require "sprockets/railtie"
|
||||||
|
require "rails/test_unit/railtie"
|
||||||
|
require 'rails/engine/commands'
|
||||||
|
require "mongoid/railtie"
|
|
@ -0,0 +1,9 @@
|
||||||
|
require 'rufus-scheduler'
|
||||||
|
|
||||||
|
scheduler = Rufus::Scheduler.new
|
||||||
|
|
||||||
|
#return if defined?(Rails::Console) || Rails.env.test? || File.split($0).last == 'rake'
|
||||||
|
|
||||||
|
scheduler.cron '43 2 * * *' do
|
||||||
|
system('bundle exec rake custom_bulletin:remove_preview_custom_bulletins')
|
||||||
|
end
|
|
@ -0,0 +1,169 @@
|
||||||
|
en:
|
||||||
|
module_name:
|
||||||
|
custom_announcement: CustomAnnouncement
|
||||||
|
restful_actions:
|
||||||
|
feed: Feed
|
||||||
|
import: Import
|
||||||
|
custom_announcement:
|
||||||
|
total_amount: Total amount
|
||||||
|
use_module: Use Module
|
||||||
|
use_content: Use Content
|
||||||
|
cover_image_display_setting: Cover Image display setting
|
||||||
|
full_width: Full width
|
||||||
|
up_left_corner: Up-left corner
|
||||||
|
up_right_corner: Up-right corner
|
||||||
|
all_tabs_setting: '"All" tab setting'
|
||||||
|
the_same_as_data_count: The same as data count
|
||||||
|
display_all_in_other_tabs: Display all contents in other tabs
|
||||||
|
read_more_position_options: '"read more" button position'
|
||||||
|
default: Default
|
||||||
|
upper_left: Upper left
|
||||||
|
lower_left: Lower left
|
||||||
|
upper_right: Upper right
|
||||||
|
lower_right: Lower right
|
||||||
|
tabs_options: Tabs options
|
||||||
|
not_enable_tabs: Not enable tabs
|
||||||
|
enable_tabs_with_categories_include_all: Enable tabs with categories(include all)
|
||||||
|
enable_tabs_with_categories: Enable tabs with categories
|
||||||
|
time: Time
|
||||||
|
send_comment: Send Comment
|
||||||
|
comment: Comment
|
||||||
|
account: Account
|
||||||
|
open_comment: Open for Comment
|
||||||
|
open: Open
|
||||||
|
comment_end_time: Comment End Time
|
||||||
|
comment_role: Comment Role
|
||||||
|
visitor: Visitor
|
||||||
|
all_member: All Member
|
||||||
|
add_to_calendar: Add to calendar
|
||||||
|
blank_to_set: (blank to use custom_announcement setting)
|
||||||
|
stime: start time
|
||||||
|
etime: end time
|
||||||
|
select_prompt: --select category--
|
||||||
|
all: All
|
||||||
|
keywords: Keywords
|
||||||
|
enable_search: Enable search feature
|
||||||
|
'yes': 'Yes'
|
||||||
|
'no': 'No'
|
||||||
|
image: Cover Image
|
||||||
|
carousel_image: Carousel Image
|
||||||
|
carousel_image_title: Carousel Image(display at the bottom of show page)
|
||||||
|
picture_showing_size: Picture Showing Size
|
||||||
|
orignal_size: Original Size
|
||||||
|
small_size: Small Size
|
||||||
|
medium_size: Medium Size
|
||||||
|
showing_back_and_next: Show back and next
|
||||||
|
not_show: Not show
|
||||||
|
show_top: Show at top
|
||||||
|
show_bottom: Show at bottom
|
||||||
|
prev: previous
|
||||||
|
next: next
|
||||||
|
table:
|
||||||
|
title : Title
|
||||||
|
date : Date
|
||||||
|
status : Status
|
||||||
|
sub_title: Sub Title
|
||||||
|
category: Category
|
||||||
|
author: Author
|
||||||
|
link: Link
|
||||||
|
file: File
|
||||||
|
view_count: View Count
|
||||||
|
department: Department
|
||||||
|
add_new: Add New
|
||||||
|
export_to_excel: Export to Excel
|
||||||
|
export_all_custom_anns: Export all CustomAnnouncement
|
||||||
|
import_from_excel: Import from Excel
|
||||||
|
download_example_sheet_here: Download example sheet here
|
||||||
|
please_create_tags_cats: Please create all the tags and categories before hand. Only excel file is allowed
|
||||||
|
create_atleast_one_cat: Please create atleast one category before importing.
|
||||||
|
import_from_wp_xml: Import from WordPress XML
|
||||||
|
click_on_submit: Click on Submit to save the changes
|
||||||
|
approvers_list: Approvers List
|
||||||
|
click_set_sub_manager: Click here to set Sub Managers for this module
|
||||||
|
approver: Approver
|
||||||
|
top_limit: Top Limit
|
||||||
|
for_unlimited: Put 0 for unlimited
|
||||||
|
feed_name: Feed Name
|
||||||
|
rssfeed: RSS Feed Link
|
||||||
|
jsonfeed: JSON Feed Link
|
||||||
|
feed_list: Feed List
|
||||||
|
approve: Approve
|
||||||
|
all_articles: All Articles
|
||||||
|
settings: Settings
|
||||||
|
import: Import / Export
|
||||||
|
custom_announcement: CustomAnnouncement
|
||||||
|
approval_setting: Approval Setting
|
||||||
|
approve_custom_bulletin_fail: Approval Fail
|
||||||
|
approve_custom_bulletin_success: Approve Successfully
|
||||||
|
approval_waiting: Approval
|
||||||
|
submitted_new_custom_announcement: "%{poster} submitted a new custom_announcement waiting for your approval."
|
||||||
|
click_here_to_see: Please click the link below to view the custom_announcement.
|
||||||
|
rejected_annoucement: has rejected your custom_announcement, because
|
||||||
|
updated_annoucement: "%{poster} updated the rejected custom_announcement."
|
||||||
|
custom_announcement_subject: New custom_announcement waiting for approval
|
||||||
|
approval_site: Site
|
||||||
|
approval_mail_hi: Hello %{name},
|
||||||
|
approval_custom_announcement_title: CustomAnnouncement Title
|
||||||
|
custom_bulletins: CustomBulletins
|
||||||
|
categories: Categories
|
||||||
|
create_custom_bulletin_success: Create CustomBulletin Successfully
|
||||||
|
create_custom_bulletin_category_success: Create Category Successfully
|
||||||
|
date: CustomAnnouncement Date
|
||||||
|
default_widget:
|
||||||
|
custom_bulletin_category_with_title: CustomBulletin Category with Title
|
||||||
|
postdate: Post Date
|
||||||
|
subtitle: Subtitle
|
||||||
|
title: Title
|
||||||
|
editing_custom_announcement: Edit CustomAnnouncement
|
||||||
|
editing_custom_announcement_category: Edit Category
|
||||||
|
file: Attachment
|
||||||
|
file_description: File Description
|
||||||
|
file_description_hint: 'File Description will display in the title of file link.(When placing mouse on the link,the title will display)'
|
||||||
|
file_name: File Name
|
||||||
|
frontend:
|
||||||
|
custom_bulletins: CustomAnnouncement front-end
|
||||||
|
search_result: Search result
|
||||||
|
link_name: Link Name
|
||||||
|
new_custom_bulletin_category: New CustomBulletin Category
|
||||||
|
picture: Cover Picture
|
||||||
|
search: Search
|
||||||
|
selected_file: Select File
|
||||||
|
update_custom_bulletin_category_success: Update Category Successfully
|
||||||
|
url: URL
|
||||||
|
widget:
|
||||||
|
custom_bulletins_and_web_links: Differential Nav.
|
||||||
|
index: Index
|
||||||
|
search: Search
|
||||||
|
more: More
|
||||||
|
more_: 'More '
|
||||||
|
email_reminder: Email Reminder
|
||||||
|
activate_email_reminder: Activate Email Reminder
|
||||||
|
email_sentdate: Email Time
|
||||||
|
email_to: Email To
|
||||||
|
mail_subject: this is an custom_announcement reminder from【%{site_title}】
|
||||||
|
view_count: View Counts
|
||||||
|
other_mailaddress: Other Email
|
||||||
|
other_mailaddress_note: Divide different email accounts with ","
|
||||||
|
mail_hi: Hi
|
||||||
|
mail_url_view: This email is the reminder of an custom_announcement, please click the link for the details
|
||||||
|
mail_source: Source
|
||||||
|
mail_time: Time
|
||||||
|
image_upload_size_note: The following recommendations %{image_upload_size} upload size
|
||||||
|
resend_mail: Re-send Email
|
||||||
|
is_external_link: Enable External Link
|
||||||
|
external_link: External Link
|
||||||
|
external_link_hint: "Make sure URL starts with http://"
|
||||||
|
display_subtitle: Display Subtitle in Content Page
|
||||||
|
display_img: Display Cover Image in Content Page
|
||||||
|
is_display_edit_only: Only display editable custom_announcements
|
||||||
|
only_manager_can_edit_status: Only manager can edit status of custom_announcements
|
||||||
|
layout_type: Layout type
|
||||||
|
custom_announcement_setting_for_iframe: CustomAnnouncement settings for iframe
|
||||||
|
url_generate: Url Generate
|
||||||
|
show_page: Show pagination
|
||||||
|
URL: URL
|
||||||
|
copy: Copy
|
||||||
|
status:
|
||||||
|
top: Important
|
||||||
|
hot: Hot
|
||||||
|
hidden: Hidden
|
|
@ -0,0 +1,172 @@
|
||||||
|
zh_tw:
|
||||||
|
module_name:
|
||||||
|
custom_announcement: 客製公告
|
||||||
|
restful_actions:
|
||||||
|
feed: 供給
|
||||||
|
import: 匯入
|
||||||
|
custom_announcement:
|
||||||
|
total_amount: 總數
|
||||||
|
use_module: 使用模組
|
||||||
|
use_content: 使用內容
|
||||||
|
cover_image_display_setting: 封面圖片顯示設定
|
||||||
|
full_width: 滿版呈現
|
||||||
|
up_left_corner: 左上角
|
||||||
|
up_right_corner: 右上角
|
||||||
|
all_tabs_setting: '"全部"頁籤設定'
|
||||||
|
the_same_as_data_count: 與Data count相同
|
||||||
|
display_all_in_other_tabs: 顯示在其他頁籤的全部內容
|
||||||
|
read_more_position_options: '"更多"按鈕的位置'
|
||||||
|
default: 預設
|
||||||
|
upper_left: 左上
|
||||||
|
lower_left: 左下
|
||||||
|
upper_right: 右上
|
||||||
|
lower_right: 右下
|
||||||
|
tabs_options: 頁籤選項
|
||||||
|
not_enable_tabs: 無頁籤
|
||||||
|
enable_tabs_with_categories_include_all: 開啟頁籤(依類別,並包含全部所選類別之頁籤)
|
||||||
|
enable_tabs_with_categories: 開啟頁籤(依類別)
|
||||||
|
time: 時間
|
||||||
|
send_comment: 送出留言
|
||||||
|
comment: 留言內容
|
||||||
|
account: 帳號
|
||||||
|
open_comment: 開放評論
|
||||||
|
open: 開放
|
||||||
|
comment_end_time: 停止開放時間
|
||||||
|
comment_role: 留言身分
|
||||||
|
visitor: 訪客
|
||||||
|
all_member: 全部會員
|
||||||
|
add_to_calendar: 加入行事曆
|
||||||
|
blank_to_set: (留白則使用公告設定)
|
||||||
|
stime: 開始時間
|
||||||
|
etime: 結束時間
|
||||||
|
select_prompt: --選取類別--
|
||||||
|
all: 全部
|
||||||
|
keywords: 關鍵字
|
||||||
|
enable_search: 開啟搜尋功能
|
||||||
|
'yes': 是
|
||||||
|
'no': 否
|
||||||
|
image: 封面圖片
|
||||||
|
carousel_image: 輪播圖片
|
||||||
|
carousel_image_title: 輪播圖片(在show頁面底部顯示)
|
||||||
|
picture_showing_size: 圖片顯示大小
|
||||||
|
orignal_size: 原圖大小
|
||||||
|
small_size: 小張縮圖
|
||||||
|
medium_size: 中等縮圖
|
||||||
|
showing_back_and_next: 顯示上下則
|
||||||
|
not_show: 不顯示
|
||||||
|
show_top: 顯示在最上面
|
||||||
|
show_bottom: 顯示在最下面
|
||||||
|
prev: 上一則
|
||||||
|
next: 下一則
|
||||||
|
table:
|
||||||
|
title : 標題
|
||||||
|
date : 張貼日期
|
||||||
|
status : 標籤
|
||||||
|
sub_title: 副標題
|
||||||
|
category: 類別
|
||||||
|
author: 張貼人
|
||||||
|
link: 超連結
|
||||||
|
file: 檔案下載
|
||||||
|
view_count: 瀏覽人次
|
||||||
|
department: 單位
|
||||||
|
add_new: 新建
|
||||||
|
import: 匯入
|
||||||
|
export_to_excel: 匯出至Excel檔
|
||||||
|
export_all_custom_anns: 匯出所有公告
|
||||||
|
import_from_excel: 從Excel檔匯入
|
||||||
|
download_example_sheet_here: 在此下載範例
|
||||||
|
please_create_tags_cats: 甲、 請事先建立所有標籤及分類。 僅限Excel檔。
|
||||||
|
create_atleast_one_cat: 匯入前, 請先建立至少一個類別
|
||||||
|
import_from_wp_xml: 從WordPress XML檔匯入
|
||||||
|
top_limit: 最高設限
|
||||||
|
for_unlimited: 歸零不設限
|
||||||
|
click_on_submit: 點"提交"儲存變更
|
||||||
|
approvers_list: 審核人名單
|
||||||
|
click_set_sub_manager: 點這邊來設定這個模組的副管理者
|
||||||
|
approver: 審核人
|
||||||
|
approve: 通過
|
||||||
|
feed_name: Feed 標題
|
||||||
|
settings: 設定
|
||||||
|
import: 匯入 / 匯出
|
||||||
|
rssfeed: RSS 供給連結
|
||||||
|
jsonfeed: JSON 供給連結
|
||||||
|
feed_list: 訂閱清單
|
||||||
|
all_articles: 文章列表
|
||||||
|
custom_announcement: 客製公告
|
||||||
|
approval_setting: 審核設定
|
||||||
|
approve_custom_bulletin_fail: 審核失敗
|
||||||
|
approve_custom_bulletin_success: 審核成功
|
||||||
|
approval_waiting: 審核
|
||||||
|
submitted_new_custom_announcement: 貴單位於全球資訊網有一則 %{poster} 張貼的最新消息待您審核發布,
|
||||||
|
click_here_to_see: 請您點擊以下網址,前往審核
|
||||||
|
rejected_annoucement: 未通過您的公告審核,原因為
|
||||||
|
updated_annoucement: 貴單位於全球資訊網有一則 %{poster} 被拒絕的最新消息已重新編輯待您審核發布,
|
||||||
|
custom_announcement_subject: 系統訊息 - 最新消息內容審核通知
|
||||||
|
approval_mail_hi: 親愛的 %{name} 主管您好
|
||||||
|
approval_site: 網址
|
||||||
|
approval_custom_announcement_title: 消息標題
|
||||||
|
custom_bulletins: 公告
|
||||||
|
categories: 類別
|
||||||
|
create_custom_bulletin_success: 建立公告成功
|
||||||
|
create_custom_bulletin_category_success: 建立類別成功
|
||||||
|
date: 起迄日期
|
||||||
|
default_widget:
|
||||||
|
custom_bulletin_category_with_title: 公告類別及標題
|
||||||
|
postdate: 張貼日期
|
||||||
|
subtitle: 副標題
|
||||||
|
title: 標題
|
||||||
|
editing_custom_announcement: 編輯類別
|
||||||
|
editing_custom_announcement_category: 編輯類別
|
||||||
|
error:
|
||||||
|
no_avilb_cate_for_posting: 沒有可以張貼的類別
|
||||||
|
file: 附加檔案
|
||||||
|
file_description: 檔案描述
|
||||||
|
file_description_hint: '檔案描述將會顯示在前台檔案連結的title(把滑鼠放在連結上會出現的文字)'
|
||||||
|
file_name: 檔案名稱
|
||||||
|
frontend:
|
||||||
|
custom_bulletins: 公告前台
|
||||||
|
search_result: 搜尋結果頁
|
||||||
|
link_name: 連結名稱
|
||||||
|
new_custom_bulletin_category: 新增公告類別
|
||||||
|
picture: 刊頭圖片
|
||||||
|
search: 搜尋
|
||||||
|
selected_file: 選擇檔案
|
||||||
|
update_custom_bulletin_category_success: 更新類別成功
|
||||||
|
url: 連結位置
|
||||||
|
widget:
|
||||||
|
custom_bulletins_and_web_links: 分眾頁籤
|
||||||
|
index: 索引
|
||||||
|
search: 搜尋
|
||||||
|
more: 更多+
|
||||||
|
more_: 更多
|
||||||
|
email_reminder: 寄送提醒
|
||||||
|
activate_email_reminder: 開啟寄送提醒
|
||||||
|
email_sentdate: 寄送時間
|
||||||
|
email_to: 寄送對象
|
||||||
|
view_count: 瀏覽人次
|
||||||
|
other_mailaddress: 其他Mail
|
||||||
|
other_mailaddress_note: 輸入多組mail時,請用","逗號隔開
|
||||||
|
mail_subject: 來自【%{site_title}】的公告事件提醒
|
||||||
|
mail_hi: 您好
|
||||||
|
mail_url_view: 此封信件為公告事件提醒,請點選以下連結詳細觀看
|
||||||
|
mail_source: 來源
|
||||||
|
mail_time: 時間
|
||||||
|
image_upload_size_note: 建議檔案小於%{image_upload_size}
|
||||||
|
resend_mail: 重新寄送提醒
|
||||||
|
is_external_link: 連結外部網址
|
||||||
|
external_link: 外部連結
|
||||||
|
external_link_hint: "確定連結開頭為http://"
|
||||||
|
display_subtitle: 內容頁顯示副標題
|
||||||
|
display_img: 內容頁顯示封面圖片
|
||||||
|
is_display_edit_only: 只顯示可更新的公告
|
||||||
|
only_manager_can_edit_status: 只有管理者可更新公告狀態
|
||||||
|
layout_type: 頁面樣式
|
||||||
|
custom_announcement_setting_for_iframe: 公告iframe設定
|
||||||
|
url_generate: 網址生成
|
||||||
|
show_page: 顯示頁碼
|
||||||
|
URL: 網址
|
||||||
|
copy: 複製
|
||||||
|
status:
|
||||||
|
top: 重要
|
||||||
|
hot: 熱門
|
||||||
|
hidden: 隱藏
|
|
@ -0,0 +1,59 @@
|
||||||
|
Rails.application.routes.draw do
|
||||||
|
|
||||||
|
locales = Site.first.in_use_locales rescue I18n.available_locales
|
||||||
|
|
||||||
|
scope "(:locale)", locale: Regexp.new(locales.join("|")) do
|
||||||
|
namespace :admin do
|
||||||
|
post 'custom_announcement/preview', to: 'custom_announcements#preview'
|
||||||
|
post 'custom_announcement/createfeed', to: 'custom_announcements#createfeed'
|
||||||
|
post 'custom_announcement/importcustom_anns', to: 'custom_announcements#importcustom_anns'
|
||||||
|
post 'custom_announcement/import_from_xml', to: 'custom_announcements#import_from_xml'
|
||||||
|
get 'custom_announcement/excel_format', to: 'custom_announcements#excel_format'
|
||||||
|
get 'custom_announcement/export_excel', to: 'custom_announcements#export_excel'
|
||||||
|
patch 'custom_announcement/updatefeed', to: 'custom_announcements#updatefeed'
|
||||||
|
delete 'custom_announcement/deletefeed', to: 'custom_announcements#deletefeed'
|
||||||
|
get 'custom_announcement/destroy_preview/:slug_title-:uid', to: 'custom_announcements#destroy_preview'
|
||||||
|
post 'custom_announcement/approve_custom_bulletin', to: 'custom_announcements#approve_custom_bulletin'
|
||||||
|
get 'custom_announcement/feed', to: 'custom_announcements#feed'
|
||||||
|
get 'custom_announcements/feedform', to: 'custom_announcements#feedform'
|
||||||
|
get 'custom_announcement/settings', to: 'custom_announcements#settings'
|
||||||
|
get 'custom_announcement/import', to: 'custom_announcements#import'
|
||||||
|
post 'custom_announcement/createsettings', to: 'custom_announcements#createsettings'
|
||||||
|
patch 'custom_announcement/updatesettings', to: 'custom_announcements#updatesettings'
|
||||||
|
post 'custom_announcement/import_from_wp', to: 'custom_announcements#import_from_wp'
|
||||||
|
post 'custom_announcement/generate_iframe_url' => 'custom_announcements#generate_iframe_url'
|
||||||
|
resources :custom_announcements do
|
||||||
|
collection do
|
||||||
|
get "/:custom_module-:bind_uid" => "custom_announcements#index"
|
||||||
|
get "/:custom_module-:bind_uid/new" => "custom_announcements#new"
|
||||||
|
get "/:custom_module-:bind_uid/:id/edit" => "custom_announcements#edit"
|
||||||
|
delete "/:custom_module-:bind_uid/:id/destroy" => "custom_announcements#destroy"
|
||||||
|
get '/:custom_module-:bind_uid/:id/comment'=> 'custom_announcements#comment'
|
||||||
|
|
||||||
|
get "/:custom_module" => "custom_announcements#index"
|
||||||
|
get "/:custom_module/new" => "custom_announcements#new"
|
||||||
|
get "/:custom_module/:id/edit" => "custom_announcements#edit"
|
||||||
|
delete "/:custom_module/:id/destroy" => "custom_announcements#destroy"
|
||||||
|
get '/:custom_module/:id/comment'=> 'custom_announcements#comment'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
get 'custom_announcements/:id/comment'=> 'custom_announcements#comment'
|
||||||
|
get 'annc-comment-hidden/:id' => 'custom_announcements#comment_hidden'
|
||||||
|
end
|
||||||
|
|
||||||
|
resources :custom_announcements do
|
||||||
|
collection do
|
||||||
|
get ':slug_title-:uid', to: 'custom_announcements#show', as: :display
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
get "/xhr/custom_announcements/feed/:uid" => "custom_announcement_feeds#feed"
|
||||||
|
get "/xhr/custom_announcements/rssfeed/:uid" => "custom_announcement_feeds#rssfeed"
|
||||||
|
get "/xhr/custom_announcements/feeds" => "custom_announcement_feeds#feeds"
|
||||||
|
get '/xhr/custom_announcements/custom_announcement.json', to: 'custom_bulletins#get_custom_bulletins'
|
||||||
|
get '/xhr/panel/custom_announcement/widget/sync_data' => 'custom_announcements#show_widget'
|
||||||
|
get '/xhr/custom_announcements/:slug_title-:uid/comment', to: 'custom_announcements#comment'
|
||||||
|
get '/xhr/custom_announcements/file/:id/*f_name' => 'custom_announcements#get_file'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,37 @@
|
||||||
|
# encoding: UTF-8
|
||||||
|
$:.push File.expand_path("../lib", __FILE__)
|
||||||
|
|
||||||
|
# Maintain your gem's version:
|
||||||
|
require "custom_announcement/version"
|
||||||
|
require 'json'
|
||||||
|
bundle_update_flag = ARGV[0]=='update' || ARGV[0]=='install'
|
||||||
|
if bundle_update_flag
|
||||||
|
env_pwd = ENV['PWD']
|
||||||
|
app_path = File.expand_path(__dir__)
|
||||||
|
template_path = env_pwd + '/app/templates'
|
||||||
|
all_template = Dir.glob(template_path+'/*/')
|
||||||
|
all_template.each do |folder|
|
||||||
|
if !folder.include?('mobile')
|
||||||
|
if Dir.exist?("#{folder}modules/")
|
||||||
|
Bundler.with_clean_env{system ('cp -r '+ app_path + '/modules/ ' + folder)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Describe your gem and declare its dependencies:
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = "custom_announcement"
|
||||||
|
s.version = CustomAnnouncement::VERSION
|
||||||
|
s.authors = ["RulingDigital"]
|
||||||
|
s.email = ["bohung@rulingcom.com"]
|
||||||
|
s.homepage = "http://www.rulingcom.com"
|
||||||
|
s.summary = "CustomAnnouncements for Orbit"
|
||||||
|
s.description = "CustomAnnouncements for Orbit"
|
||||||
|
s.license = "MIT"
|
||||||
|
|
||||||
|
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"]
|
||||||
|
s.test_files = Dir["test/**/*"]
|
||||||
|
|
||||||
|
s.add_dependency "rufus-scheduler", "~> 3.6.0"
|
||||||
|
s.add_dependency "mimemagic" , "0.3.9"
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
require "custom_announcement/engine"
|
||||||
|
module CustomAnnouncement
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,153 @@
|
||||||
|
require "yaml"
|
||||||
|
module CustomAnnouncement
|
||||||
|
class Engine < ::Rails::Engine
|
||||||
|
initializer "custom_announcement" do
|
||||||
|
begin
|
||||||
|
translate_data = Dir["#{CustomAnnouncement::Engine.root}/config/locales/*.yml"] .map{|yaml_file| YAML.load(File.read(yaml_file))}
|
||||||
|
data = {}
|
||||||
|
key1 = {}
|
||||||
|
key2 = {}
|
||||||
|
key3 = {}
|
||||||
|
key4 = {}
|
||||||
|
key1_attr = []
|
||||||
|
key2_attr = []
|
||||||
|
key3_attr = []
|
||||||
|
key4_attr = []
|
||||||
|
data_item = {}
|
||||||
|
key_item1 = {}
|
||||||
|
key_item2 = {}
|
||||||
|
key_item3 = {}
|
||||||
|
value_item1 = {}
|
||||||
|
value_item2 = {}
|
||||||
|
value_item3 = {}
|
||||||
|
value2_item1 = {}
|
||||||
|
value2_item2 = {}
|
||||||
|
key1_options = ['small_size','medium_size','orignal_size']
|
||||||
|
key2_options = ['not_enable_tabs','enable_tabs_with_categories_include_all','enable_tabs_with_categories']
|
||||||
|
key3_options = ['default','upper_left','lower_left','upper_right','lower_right']
|
||||||
|
key4_options = ['the_same_as_data_count','display_all_in_other_tabs']
|
||||||
|
key1_options.each_with_index do |k,i|
|
||||||
|
key1_attr[i] = {}
|
||||||
|
end
|
||||||
|
key2_options.each_with_index do |k,i|
|
||||||
|
key2_attr[i] = {}
|
||||||
|
end
|
||||||
|
key3_options.each_with_index do |k,i|
|
||||||
|
key3_attr[i] = {}
|
||||||
|
end
|
||||||
|
key4_options.each_with_index do |k,i|
|
||||||
|
key4_attr[i] = {}
|
||||||
|
end
|
||||||
|
translate_data.each do |t_data|
|
||||||
|
v = t_data.values
|
||||||
|
k = t_data.keys[0]
|
||||||
|
key1[k] = v[0]['custom_announcement']['picture_showing_size']
|
||||||
|
key2[k] = v[0]['custom_announcement']['tabs_options']
|
||||||
|
key3[k] = v[0]['custom_announcement']['read_more_position_options']
|
||||||
|
key4[k] = v[0]['custom_announcement']['all_tabs_setting']
|
||||||
|
key1_options.each_with_index do |kk,i|
|
||||||
|
key1_attr[i][k] = v[0]['custom_announcement'][kk]
|
||||||
|
end
|
||||||
|
key2_options.each_with_index do |kk,i|
|
||||||
|
key2_attr[i][k] = v[0]['custom_announcement'][kk]
|
||||||
|
end
|
||||||
|
key3_options.each_with_index do |kk,i|
|
||||||
|
key3_attr[i][k] = v[0]['custom_announcement'][kk]
|
||||||
|
end
|
||||||
|
key4_options.each_with_index do |kk,i|
|
||||||
|
key4_attr[i][k] = v[0]['custom_announcement'][kk]
|
||||||
|
end
|
||||||
|
key_item1[k] = v[0]['custom_announcement']['showing_back_and_next']
|
||||||
|
key_item2[k] = v[0]['custom_announcement']['enable_search']
|
||||||
|
value_item1[k] = v[0]['custom_announcement']['not_show']
|
||||||
|
value_item2[k] = v[0]['custom_announcement']['show_bottom']
|
||||||
|
value_item3[k] = v[0]['custom_announcement']['show_top']
|
||||||
|
value2_item1[k] = v[0]['custom_announcement']['no']
|
||||||
|
value2_item2[k] = v[0]['custom_announcement']['yes']
|
||||||
|
end
|
||||||
|
data[key1] = key1_attr
|
||||||
|
data[key2] = key2_attr
|
||||||
|
data[key3] = key3_attr
|
||||||
|
data[key4] = key4_attr
|
||||||
|
data_item[key_item1] = [value_item1,value_item2,value_item3]
|
||||||
|
data_item[key_item2] = [value2_item1,value2_item2]
|
||||||
|
require File.expand_path('../../../app/models/custom_anns_cache', __FILE__)
|
||||||
|
if defined? CustomAnnsCache
|
||||||
|
CustomAnnsCache.destroy_all
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
puts ['error in custom_announcement',e]
|
||||||
|
end
|
||||||
|
OrbitApp.registration "CustomAnnouncement", :type => "ModuleApp" do
|
||||||
|
module_label "custom_announcement.custom_announcement"
|
||||||
|
base_url File.expand_path File.dirname(__FILE__)
|
||||||
|
widget_methods ["widget","random_custom_announcement_widget", "tag_cloud"]
|
||||||
|
widget_settings [{"data_count"=>30,"enable_custom_widget_data"=>true}]
|
||||||
|
taggable "CustomBulletin"
|
||||||
|
categorizable
|
||||||
|
authorizable
|
||||||
|
frontend_enabled
|
||||||
|
feeds_url "/xhr/custom_announcements/feeds"
|
||||||
|
data_count 1..30
|
||||||
|
begin
|
||||||
|
show_options data
|
||||||
|
show_option_items data_item
|
||||||
|
rescue => e
|
||||||
|
puts ['there_was_no_show_option_method',e]
|
||||||
|
end
|
||||||
|
side_bar do
|
||||||
|
head_label_i18n 'custom_announcement.custom_announcement', icon_class: "icons-megaphone"
|
||||||
|
available_for "users"
|
||||||
|
active_for_controllers (['admin/custom_announcements'])
|
||||||
|
head_link_path "admin_custom_announcements_path"
|
||||||
|
|
||||||
|
context_link 'custom_announcement.all_articles',
|
||||||
|
:link_path=>"admin_custom_announcements_path" ,
|
||||||
|
:priority=>1,
|
||||||
|
:active_for_action=>{'admin/custom_announcements'=>'index'},
|
||||||
|
:available_for => 'users'
|
||||||
|
# context_link 'new_',
|
||||||
|
# :link_path=>"new_admin_custom_announcement_path" ,
|
||||||
|
# :priority=>2,
|
||||||
|
# :active_for_action=>{'admin/custom_announcements'=>'new'},
|
||||||
|
# :available_for => 'sub_managers'
|
||||||
|
context_link 'categories',
|
||||||
|
:link_path=>"admin_module_app_categories_path" ,
|
||||||
|
:link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'custom_announcement').id}",
|
||||||
|
:priority=>3,
|
||||||
|
:active_for_action=>{'admin/custom_announcements'=>'categories'},
|
||||||
|
:active_for_category => 'CustomAnnouncement',
|
||||||
|
:available_for => 'managers'
|
||||||
|
context_link 'tags',
|
||||||
|
:link_path=>"admin_module_app_tags_path" ,
|
||||||
|
:link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'custom_announcement').id}",
|
||||||
|
:priority=>4,
|
||||||
|
:active_for_action=>{'admin/custom_announcements'=>'tags'},
|
||||||
|
:active_for_tag => 'CustomAnnouncement',
|
||||||
|
:available_for => 'managers'
|
||||||
|
context_link 'custom_announcement.feed_list',
|
||||||
|
:link_path=>"admin_custom_announcement_feed_path" ,
|
||||||
|
:priority=>5,
|
||||||
|
:active_for_action=>{'admin/custom_announcements'=>'feed'},
|
||||||
|
:available_for => 'managers'
|
||||||
|
context_link 'custom_announcement.import',
|
||||||
|
:link_path=>"admin_custom_announcement_import_path" ,
|
||||||
|
:priority=>6,
|
||||||
|
:active_for_action=>{'admin/custom_announcements'=>'import'},
|
||||||
|
:available_for => 'managers'
|
||||||
|
context_link 'custom_announcement.settings',
|
||||||
|
:link_path=>"admin_custom_announcement_settings_path" ,
|
||||||
|
:priority=>6,
|
||||||
|
:active_for_action=>{'admin/custom_announcements'=>'settings'},
|
||||||
|
:available_for => 'managers'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
# temp = YAML.load_file(File.join(Rails.root,"config","mongoid.yml"))
|
||||||
|
# dbsettings = temp["production"]["sessions"]["default"]
|
||||||
|
# s = Moped::Session.new(dbsettings["hosts"])
|
||||||
|
# s.use dbsettings["database"]
|
||||||
|
# s[:custom_bulletins].indexes.create({expirable_created_at: 1},{ expireAfterSeconds: 180 })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
module CustomAnnouncement
|
||||||
|
VERSION = "0.0.1"
|
||||||
|
end
|
|
@ -0,0 +1,20 @@
|
||||||
|
module CustomBulletinModel
|
||||||
|
module Cache
|
||||||
|
require 'active_support/concern'
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
included do
|
||||||
|
before_save :do_before_save
|
||||||
|
end
|
||||||
|
def do_before_save
|
||||||
|
if self.class == SubPart
|
||||||
|
CustomAnnsCache.where(parent_id:self.id).destroy
|
||||||
|
elsif self.class == CustomBulletin || (self.class == Page && self.module == "custom_announcement")
|
||||||
|
if self.class == CustomBulletin
|
||||||
|
tmp_tag_ids = (Array(self.tag_ids) + Array(self.org_tag_ids)).uniq
|
||||||
|
CustomBulletinFeedCache.where(:uid.in => CustomBulletinFeed.where(:tag_ids.in => tmp_tag_ids.collect{|v| v.to_s}).pluck(:uid)).destroy
|
||||||
|
end
|
||||||
|
CustomAnnsCache.all.destroy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
desc 'Remove duplicated custom_bulletins (custom_announcements) created by preview'
|
||||||
|
|
||||||
|
namespace :custom_bulletin do
|
||||||
|
task :remove_preview_custom_bulletins => [:environment] do
|
||||||
|
custom_bulletins = CustomBulletin.where(is_preview: true)
|
||||||
|
custom_bulletins.destroy_all
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,32 @@
|
||||||
|
<div class="w-annc widget-announcement-1">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item">
|
||||||
|
<div class="w-annc__img-wrap bullseye">
|
||||||
|
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__meta">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__category-wrap">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<p class="w-annc__subtitle">{{subtitle}}</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<div class="w-annc widget-announcement-10">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item row">
|
||||||
|
<h4 class="w-annc__entry-title col-sm-9">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<span class="w-annc__postdate-wrap col-sm-3" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,21 @@
|
||||||
|
<div class="w-annc widget-announcement-11">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item row">
|
||||||
|
<span class="w-annc__postdate-wrap col-sm-3" date-format="%Y-%m-%d">
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<h4 class="w-annc__entry-title col-sm-9">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<div class="w-annc widget-announcement-12">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<table class="w-annc__table table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-annc__th w-annc__th--title">{{title-head}}</th>
|
||||||
|
<th class="w-annc__th w-annc__th--date">{{date-head}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-level="0" data-list="custom_announcements">
|
||||||
|
<tr>
|
||||||
|
<td class="w-annc_content">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</td>
|
||||||
|
<td class="w-annc__postdate" date-format="%Y-%m-%d">{{postdate}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<div class="w-annc widget-announcement-13">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<table class="w-annc__table table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-annc__th w-annc__th--date">{{date-head}}</th>
|
||||||
|
<th class="w-annc__th w-annc__th--title">{{title-head}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-level="0" data-list="custom_announcements">
|
||||||
|
<tr>
|
||||||
|
<td class="w-annc__postdate" date-format="%Y-%m-%d">{{postdate}}</td>
|
||||||
|
<td class="w-annc_content">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<div class="w-annc widget-announcement-14">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<div class="w-annc__inner row">
|
||||||
|
<div class="w-annc__img-wrap col-xs-4 bullseye">
|
||||||
|
<img class="w-annc__img" src="{{main_picture}}" alt="{{main_picture_description}}" title="{{main_picture_description}}">
|
||||||
|
</div>
|
||||||
|
<ul class="w-annc__list col-xs-8" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item">
|
||||||
|
<div class="w-annc__content row">
|
||||||
|
<h4 class="w-annc__entry-title col-xs-9">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<span class="w-annc__postdate-wrap col-xs-3" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,162 @@
|
||||||
|
<div class="w-annc widget-announcement-4 w-annc widget-announcement-15" style="position:relative;">
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<h2 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h2>
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute;top: 50%;bottom: 50%;width:100%;">
|
||||||
|
<button class="btn-left" title = "<%= (I18n.locale.to_s =="zh_tw") ? "上一張" : "prev" %>" style="float: left;height: 2.5em; width: 2.5em;background: url(/assets/left-01.png) no-repeat;border: 0;background-size: contain;position: absolute;transition:.3s; left: 0.6%;"></button>
|
||||||
|
<button class="btn-right" title = "<%= (I18n.locale.to_s =="zh_tw") ? "下一張" : "next" %>" style="float: right;;height: 2.5em; width: 2.5em;background: url(/assets/right-01.png) no-repeat;background-size: contain;border: 0;position: absolute;transition:.3s;right: 0.6%;"></button>
|
||||||
|
</div>
|
||||||
|
<ul class="w-annc__list row" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item col-md-4">
|
||||||
|
<div class="w-annc__img-wrap bullseye">
|
||||||
|
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__content-wrap">
|
||||||
|
<div class="w-annc__meta">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__category-wrap">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<p class="w-annc__subtitle">{{subtitle}}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||||
|
<script>
|
||||||
|
function combineul(){
|
||||||
|
var parents = $('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').parent();
|
||||||
|
parents.each(function(i,v){
|
||||||
|
for(var i=1;i<$(v).find('ul.w-annc__list').length;i++)
|
||||||
|
$(v).find('ul.w-annc__list').eq(0).find('>li').eq(-1).after($(v).find('ul.w-annc__list').eq(i).html());
|
||||||
|
var ullength = $(v).find('ul.w-annc__list').length;
|
||||||
|
for(var i = 1;i < ullength;i++)
|
||||||
|
$(v).find('ul.w-annc__list').eq(-1).remove();
|
||||||
|
})
|
||||||
|
};
|
||||||
|
var num;
|
||||||
|
var lilength = $('[data-subpart-id=\"{{subpart-id}}\"] li.w-annc__item').length;
|
||||||
|
function reorganize(num){
|
||||||
|
var uls = $('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').toArray();
|
||||||
|
var currentul = uls.findIndex(function(v){
|
||||||
|
return $(v).hasClass("active") && !$(v).hasClass("hidden_item");
|
||||||
|
})
|
||||||
|
if(currentul == -1)
|
||||||
|
currentul = 0;
|
||||||
|
var li_active_idx = 0;
|
||||||
|
if(currentul != 0)
|
||||||
|
li_active_idx = $(uls[currentul]).find("li.w-annc__item").eq(0).index("li.w-annc__item");
|
||||||
|
combineul();
|
||||||
|
var parents = $('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').parent();
|
||||||
|
parents.each(function(i,v){
|
||||||
|
var lilength = $(v).find('li.w-annc__item').length;
|
||||||
|
var ul_length = Math.ceil(lilength/num);
|
||||||
|
for(var ii=1;ii< ul_length;ii++){
|
||||||
|
var clone_ul = $(v).find('ul.w-annc__list').eq(-1).clone();
|
||||||
|
clone_ul.empty();
|
||||||
|
clone_ul.removeClass("active");
|
||||||
|
clone_ul.css("display","");
|
||||||
|
$(v).find('ul.w-annc__list').eq(-1).after(clone_ul.prop("outerHTML"));
|
||||||
|
var lihtml="";
|
||||||
|
if(ii != (ul_length-1)){
|
||||||
|
for(var j=0;j<num;j++){
|
||||||
|
lihtml += $(v).find('li.w-annc__item').eq(ii*num+j).prop("outerHTML");
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
for(var j=0;j< lilength - num *(ul_length-1) ;j++){
|
||||||
|
lihtml += $(v).find('li.w-annc__item').eq(ii*num+j).prop("outerHTML");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
$(v).find('ul.w-annc__list').eq(-1).html(lihtml);
|
||||||
|
}
|
||||||
|
if(ul_length != 1 )
|
||||||
|
for(var i=0;i< lilength -num ; i++)
|
||||||
|
$(v).find('ul.w-annc__list').eq(0).find("li.w-annc__item").eq(num).remove();
|
||||||
|
})
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').css("display","none");
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').css('padding','0 1.125em');
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] button').css('z-index','10');
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list >li').css('width','calc('+100/num+'% - '+20/16+'em)'); //20px=>li的margin
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list >li').css('float','left');
|
||||||
|
var active_ul = $("[data-subpart-id=\"{{subpart-id}}\"] li.w-annc__item").eq(li_active_idx).parents("ul.w-annc__list");
|
||||||
|
active_ul.addClass("active");
|
||||||
|
active_ul.removeClass("hidden_item");
|
||||||
|
active_ul.css("display","");
|
||||||
|
};
|
||||||
|
$(window).resize(function(){
|
||||||
|
if($(window).width()>1024){
|
||||||
|
reorganize(3);
|
||||||
|
num=3;
|
||||||
|
}else if($(window).width()>576){
|
||||||
|
reorganize(2);
|
||||||
|
num=2;
|
||||||
|
}else{
|
||||||
|
reorganize(1);
|
||||||
|
num=1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$(document).ready(function(){
|
||||||
|
if($(window).width()>1024){
|
||||||
|
reorganize(3);
|
||||||
|
num=3;
|
||||||
|
}else if($(window).width()>576){
|
||||||
|
reorganize(2);
|
||||||
|
num=2;
|
||||||
|
}else{
|
||||||
|
reorganize(1);
|
||||||
|
num=1;
|
||||||
|
}
|
||||||
|
var flag=false;
|
||||||
|
$('.btn-left').click(function(){
|
||||||
|
if(!flag){
|
||||||
|
var uls = $('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list:not(.hidden_item)').toArray();
|
||||||
|
var ul_length = uls.length;
|
||||||
|
var currentul = uls.findIndex(function(v){
|
||||||
|
return $(v).hasClass("active");
|
||||||
|
})
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').css('display','none');
|
||||||
|
if(currentul - 1 < 0)
|
||||||
|
currentul += ul_length;
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list:not(.hidden_item)').removeClass("active");
|
||||||
|
var active_item = $(uls[currentul-1]);
|
||||||
|
active_item.addClass("active");
|
||||||
|
active_item.find("li").css("display","block");
|
||||||
|
flag=true;
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list.active').eq(0).effect("slide", { direction: "left", mode: 'show', duration: 500},function(){flag=false;});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
$('.btn-right').click(function(){
|
||||||
|
var lilength = $('[data-subpart-id=\"{{subpart-id}}\"] li.w-annc__item').length;
|
||||||
|
if(!flag){
|
||||||
|
var uls = $('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list:not(.hidden_item)').toArray();
|
||||||
|
var ul_length = uls.length;
|
||||||
|
var currentul = uls.findIndex(function(v){
|
||||||
|
return $(v).hasClass("active");
|
||||||
|
})
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').css('display','none');
|
||||||
|
if(currentul + 1 > ul_length - 1)
|
||||||
|
currentul -= ul_length;
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list:not(.hidden_item)').removeClass("active");
|
||||||
|
var active_item = $(uls[currentul+1]);
|
||||||
|
active_item.addClass("active");
|
||||||
|
active_item.find("li").css("display","block");
|
||||||
|
flag=true;
|
||||||
|
$('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list.active').eq(0).effect("slide", { direction: "left", mode: 'show', duration: 500},function(){flag=false;});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<div class="w-annc widget-announcement-16">
|
||||||
|
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div class="slide-button">
|
||||||
|
<button class="cycle-prev btn btn-warning"> <i class="fa fa-angle-left"></i></button>
|
||||||
|
<button class="cycle-next btn btn-warning"> <i class="fa fa-angle-right"></i></button>
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多+" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-annc__wrap cycle-slideshow"
|
||||||
|
data-level="0"
|
||||||
|
data-list="custom_announcements"
|
||||||
|
data-cycle-slides=".w-annc__item"
|
||||||
|
data-cycle-fx="carousel"
|
||||||
|
data-cycle-carousel-fluid=true
|
||||||
|
data-cycle-pause-on-hover="true"
|
||||||
|
data-cycle-speed="200"
|
||||||
|
data-cycle-carousel-visible="1"
|
||||||
|
data-cycle-prev=".cycle-prev"
|
||||||
|
data-cycle-next=".cycle-next"
|
||||||
|
data-cycle-swipe=true
|
||||||
|
data-cycle-swipe-fx="carousel"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="w-annc__item">
|
||||||
|
<div class="w-annc__img-wrap">
|
||||||
|
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__content-wrap">
|
||||||
|
<div class="w-annc__meta">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<div class="w-annc widget-announcement-17">
|
||||||
|
<div class="search_block">
|
||||||
|
<p>Search</p>
|
||||||
|
<form accept-charset="UTF-8" action="{{more_url}}" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
||||||
|
<p>
|
||||||
|
<input id="search_query" name="keywords" placeholder="搜尋" type="text">
|
||||||
|
<input type="submit" value="搜尋">
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item row">
|
||||||
|
<span class="w-annc__postdate-wrap col-sm-3" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<h4 class="w-annc__entry-title col-sm-9">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,86 @@
|
||||||
|
<div class="w-annc widget-announcement-18">
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<h2 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h2>
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
<ul class="w-annc__list row" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item col-md-4">
|
||||||
|
<div class="w-annc__img-wrap">
|
||||||
|
<a href="{{link_to_show}}" title="{{title}}">
|
||||||
|
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__content-wrap">
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<div class="w-annc__subtitle">{{subtitle}}</div>
|
||||||
|
<div class="w-annc_read_more"><a href="{{link_to_show}}" title="{{title}}">{{read_more_text}}</a></div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<style type="text/css">
|
||||||
|
.widget-announcement-18 [data-list="custom_announcements"] li > *{
|
||||||
|
background: #ffffff;
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.widget-announcement-18 [data-list="custom_announcements"] .w-annc__img{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.widget-announcement-18 [data-list="custom_announcements"] .w-annc__content-wrap{
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
.widget-announcement-18 .w-annc__title {
|
||||||
|
line-height: 1.3;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
.widget-announcement-18 .w-annc__widget-title {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.widget-announcement-18 .w-annc__more {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
.widget-announcement-18 .w-annc__list > .w-annc__item:nth-child(3n+1) {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.widget-announcement-18 li.w-annc__item{
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget-announcement-18 .w-annc__img-wrap {
|
||||||
|
padding: 0 0 1em 0;
|
||||||
|
}
|
||||||
|
.w-annc_read_more{
|
||||||
|
display: inline-block;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
.w-annc_read_more a{
|
||||||
|
float: left;
|
||||||
|
background: #4a97c2;
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
border-radius: 0.3em;
|
||||||
|
border: 0.5em solid #4a97c2;
|
||||||
|
}
|
||||||
|
.w-annc__subtitle {
|
||||||
|
padding-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
.w-annc_read_more a:hover{
|
||||||
|
background: #327397;
|
||||||
|
border: 0.5em solid #327397;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("[data-subpart-id=\"{{subpart-id}}\"] .w-annc__subtitle").each(function(i,v){
|
||||||
|
var subtitle = $(v).text();
|
||||||
|
if(subtitle.length > 15){
|
||||||
|
$(v).text(subtitle.slice(0,15) + "...");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<div class="w-annc widget-announcement-2">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item row">
|
||||||
|
<div class="w-annc__img-wrap col-sm-4 bullseye">
|
||||||
|
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__content-wrap col-sm-8">
|
||||||
|
<div class="w-annc__meta">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__category-wrap">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<p class="w-annc__subtitle">{{subtitle}}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<div class="w-annc widget-announcement-3">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item row">
|
||||||
|
<div class="w-annc__content-wrap col-sm-8">
|
||||||
|
<div class="w-annc__meta">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__category-wrap">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<p class="w-annc__subtitle">{{subtitle}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__img-wrap col-sm-4 bullseye">
|
||||||
|
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,107 @@
|
||||||
|
<div class="w-annc widget-announcement-4">
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<h2 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h2>
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
<ul class="w-annc__list row" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item col-md-4">
|
||||||
|
<div class="w-annc__img-wrap bullseye">
|
||||||
|
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
|
</div>
|
||||||
|
<div class="w-annc__content-wrap">
|
||||||
|
<div class="w-annc__meta">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__category-wrap">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<p class="w-annc__subtitle">{{subtitle}}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<style type="text/css">
|
||||||
|
[data-subpart-id="{{subpart-id}}"] .bullseye{
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function combineul(){
|
||||||
|
var parents = $('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').parent();
|
||||||
|
parents.each(function(i,v){
|
||||||
|
for(var i=1;i<$(v).find('ul.w-annc__list').length;i++)
|
||||||
|
$(v).find('ul.w-annc__list').eq(0).find('>li').eq(-1).after($(v).find('ul.w-annc__list').eq(i).html());
|
||||||
|
var ullength = $(v).find('ul.w-annc__list').length;
|
||||||
|
for(var i = 1;i < ullength;i++)
|
||||||
|
$(v).find('ul.w-annc__list').eq(-1).remove();
|
||||||
|
})
|
||||||
|
};
|
||||||
|
var num;
|
||||||
|
var lilength = $('[data-subpart-id=\"{{subpart-id}}\"] li.w-annc__item').length;
|
||||||
|
function reorganize(num){
|
||||||
|
combineul();
|
||||||
|
var parents = $('[data-subpart-id=\"{{subpart-id}}\"] ul.w-annc__list').parent();
|
||||||
|
parents.each(function(i,v){
|
||||||
|
var lilength = $(v).find('li.w-annc__item').length;
|
||||||
|
var ul_length = Math.ceil(lilength/num);
|
||||||
|
for(var ii=1;ii< ul_length;ii++){
|
||||||
|
var clone_ul = $(v).find('ul.w-annc__list').eq(-1).clone();
|
||||||
|
clone_ul.empty();
|
||||||
|
clone_ul.removeClass("active");
|
||||||
|
clone_ul.css("display","");
|
||||||
|
$(v).find('ul.w-annc__list').eq(-1).after(clone_ul.prop("outerHTML"));
|
||||||
|
var lihtml="";
|
||||||
|
if(ii != (ul_length-1)){
|
||||||
|
for(var j=0;j<num;j++){
|
||||||
|
lihtml += $(v).find('li.w-annc__item').eq(ii*num+j).prop("outerHTML");
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
for(var j=0;j< lilength - num *(ul_length-1) ;j++){
|
||||||
|
lihtml += $(v).find('li.w-annc__item').eq(ii*num+j).prop("outerHTML");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
$(v).find('ul.w-annc__list').eq(-1).html(lihtml);
|
||||||
|
}
|
||||||
|
if(ul_length != 1 )
|
||||||
|
for(var i=0;i< lilength -num ; i++)
|
||||||
|
$(v).find('ul.w-annc__list').eq(0).find("li.w-annc__item").eq(num).remove();
|
||||||
|
})
|
||||||
|
$('.widget-announcement-4 ul.w-annc__list >li').css('width','calc('+100/num+'% - '+20/16+'em)'); //20px=>li的margin
|
||||||
|
};
|
||||||
|
$(window).resize(function(){
|
||||||
|
if($(window).width()>1024){
|
||||||
|
reorganize(3);
|
||||||
|
num=3;
|
||||||
|
}else if($(window).width()>576){
|
||||||
|
reorganize(2);
|
||||||
|
num=2;
|
||||||
|
}else{
|
||||||
|
reorganize(1);
|
||||||
|
num=1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$(document).ready(function(){
|
||||||
|
if($(window).width()>1024){
|
||||||
|
reorganize(3);
|
||||||
|
num=3;
|
||||||
|
}else if($(window).width()>576){
|
||||||
|
reorganize(2);
|
||||||
|
num=2;
|
||||||
|
}else{
|
||||||
|
reorganize(1);
|
||||||
|
num=1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<div class="w-annc widget-announcement-5">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list row" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item">
|
||||||
|
<div class="w-annc__content-wrap">
|
||||||
|
<div class="w-annc__meta">
|
||||||
|
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__category-wrap">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h4 class="w-annc__entry-title">
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<p class="w-annc__subtitle">{{subtitle}}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<div class="w-annc widget-announcement-6">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item row">
|
||||||
|
<span class="w-annc__category-wrap col-sm-2">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
<h4 class="w-annc__entry-title col-sm-8">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<span class="w-annc__postdate-wrap col-sm-2" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<div class="w-annc widget-announcement-7">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<ul class="w-annc__list" data-level="0" data-list="custom_announcements">
|
||||||
|
<li class="w-annc__item row">
|
||||||
|
<span class="w-annc__postdate-wrap col-sm-2" date-format="%Y-%m-%d">
|
||||||
|
<i class="fa fa-calendar-o"></i>
|
||||||
|
<span class="w-annc__postdate">{{postdate}}</span>
|
||||||
|
</span>
|
||||||
|
<h4 class="w-annc__entry-title col-sm-8">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</h4>
|
||||||
|
<span class="w-annc__category-wrap col-sm-2">
|
||||||
|
<i class="fa fa-tasks"></i>
|
||||||
|
<span class="w-annc__category">{{category}}</span>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<div class="w-annc widget-announcement-8">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<table class="w-annc__table table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-annc__th w-annc__th--category">{{category-head}}</th>
|
||||||
|
<th class="w-annc__th w-annc__th--title">{{title-head}}</th>
|
||||||
|
<th class="w-annc__th w-annc__th--date">{{date-head}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-level="0" data-list="custom_announcements">
|
||||||
|
<tr>
|
||||||
|
<td class="w-annc__category">{{category}}</td>
|
||||||
|
<td class="w-annc_content">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</td>
|
||||||
|
<td class="w-annc__postdate" date-format="%Y-%m-%d">{{postdate}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<div class="w-annc widget-announcement-9">
|
||||||
|
<h3 class="w-annc__widget-title">
|
||||||
|
<span>{{widget-title}}</span>
|
||||||
|
</h3>
|
||||||
|
<table class="w-annc__table table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-annc__th w-annc__th--date">{{date-head}}</th>
|
||||||
|
<th class="w-annc__th w-annc__th--title">{{title-head}}</th>
|
||||||
|
<th class="w-annc__th w-annc__th--category">{{category-head}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-level="0" data-list="custom_announcements">
|
||||||
|
<tr>
|
||||||
|
<td class="w-annc__postdate" date-format="%Y-%m-%d">{{postdate}}</td>
|
||||||
|
<td class="w-annc_content">
|
||||||
|
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="w-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</td>
|
||||||
|
<td class="w-annc__category">{{category}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="w-annc__more-wrap clearfix">
|
||||||
|
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多最新消息" : "More NEWS" %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<div class="i-annc index-announcement-1 {{display}}">
|
||||||
|
<h1 class="i-annc__page-title">{{page-title}}</h1>
|
||||||
|
<table class="i-annc__table table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="i-annc__th i-annc__th--category">{{category-head}}</th>
|
||||||
|
<th class="i-annc__th i-annc__th--title">{{title-head}}</th>
|
||||||
|
<th class="i-annc__th i-annc__th--date">{{date-head}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-level="0" data-list="custom_announcements">
|
||||||
|
<tr>
|
||||||
|
<td class="i-annc__category">{{category}}</td>
|
||||||
|
<td class="i-annc__content">
|
||||||
|
<span class="i-annc__status-wrap" data-list="statuses" data-level="1">
|
||||||
|
<span class="i-annc__status label status {{status-class}}">{{status}}</span>
|
||||||
|
</span>
|
||||||
|
<a class="i-annc__title" href="{{link_to_show}}">{{title}}</a>
|
||||||
|
</td>
|
||||||
|
<td class="i-annc__postdate"><span class="i-annc__postdate-content" date-format="%Y-%m-%d">{{postdate}}</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{pagination_goes_here}}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue