Create Custom Announcement plugin.
This commit is contained in:
commit
ddf868fb2f
|
@ -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;
|
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