First commit
This commit is contained in:
commit
44acbae2a0
|
|
@ -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 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:
|
||||
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
|
||||
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 @@
|
|||
= Event News
|
||||
|
||||
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 = 'Announcement'
|
||||
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 |
Binary file not shown.
|
After Width: | Height: | Size: 182 B |
|
|
@ -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,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);
|
||||
})
|
||||
});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,605 @@
|
|||
var EventCalendarModuleMonth2 = function(date,dom,subpart,url,index_flag){
|
||||
_this = this;
|
||||
var events = {}
|
||||
var template = dom.find(".month_template"),
|
||||
month_names = ["Jan","Feb","March","April","May","June","July","Aug","Sep","Oct","Nov","Dec"],
|
||||
monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
||||
initialDate = date,
|
||||
subpartid = subpart,
|
||||
index_url = url,
|
||||
fetchInterval = null,
|
||||
month = date.getMonth(),
|
||||
year = date.getFullYear(),
|
||||
first_target_day = new Date(Date.UTC(year,month,1)),
|
||||
last_target_day = new Date(Date.UTC(year,month+1,0)),
|
||||
firstDay = new Date(Date.UTC(year,month,1)),
|
||||
lastDay = new Date(Date.UTC(year,month+1,0)),
|
||||
today = date.getDate(),
|
||||
last_inserted_date = 1,
|
||||
monthDom = $("<div class=\"height100\" data-year='"+year+"' data-month='"+month+"'></div>"),
|
||||
eventHTML = dom.find('div.calendar-events')[0],
|
||||
event_template = dom.find('div.calendar-events .event').prop('outerHTML'),
|
||||
prevMonthFunc,
|
||||
nextMonthFunc,
|
||||
toggle_data,
|
||||
hover_step=10,
|
||||
hover_step_max=10,
|
||||
hover_max_height=13,
|
||||
toggling=false,
|
||||
switching=false,
|
||||
tp1,
|
||||
tp2;
|
||||
monthDom.html(template);
|
||||
var format_time = function(date){
|
||||
var hours = date.getHours(),
|
||||
minutes = date.getMinutes();
|
||||
if (hours < 10) {hours = "0"+hours}
|
||||
if (minutes < 10) {minutes = "0"+minutes}
|
||||
return hours+':'+minutes;
|
||||
}
|
||||
function rgb2hex(rgb) {
|
||||
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
||||
function hex(x) {
|
||||
return ("0" + parseInt(x).toString(16)).slice(-2);
|
||||
}
|
||||
if (rgb){
|
||||
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
|
||||
}else{
|
||||
return "#000000";
|
||||
}
|
||||
}
|
||||
function hexToRGB(hex, alpha) {
|
||||
if (hex){
|
||||
var r = parseInt(hex.slice(1, 3), 16),
|
||||
g = parseInt(hex.slice(3, 5), 16),
|
||||
b = parseInt(hex.slice(5, 7), 16);
|
||||
|
||||
if (alpha) {
|
||||
return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
|
||||
} else {
|
||||
return "rgb(" + r + ", " + g + ", " + b + ")";
|
||||
}
|
||||
}else{
|
||||
return ''
|
||||
}
|
||||
}
|
||||
function lighten_color(my_hex,percent){
|
||||
if (my_hex[0] == '#'){
|
||||
my_hex = my_hex.slice(1)
|
||||
}
|
||||
var comp = ''
|
||||
var rgb = []
|
||||
var batch_size = Math.ceil(my_hex.length/3)
|
||||
for (var i=0;i<3;i++){
|
||||
rgb.push(my_hex.slice(batch_size*i,batch_size*(i+1)))
|
||||
}
|
||||
$.each(rgb,function(){
|
||||
var a = this
|
||||
var tmp
|
||||
tmp = Math.ceil(parseInt(a,16)*(1+percent/100))
|
||||
if (tmp>255) tmp = 255
|
||||
if (tmp < 0) tmp = 0
|
||||
tmp = tmp.toString(16)
|
||||
for (var i=0;i<2-tmp.length;i++){
|
||||
tmp = '0' + tmp
|
||||
}
|
||||
comp = comp + tmp
|
||||
})
|
||||
return '#'+comp
|
||||
}
|
||||
var format_date = function(date){
|
||||
var y = date.getFullYear(),
|
||||
m = date.getMonth() + 1,
|
||||
d = date.getDate();
|
||||
if (m < 10) {m = "0"+m}
|
||||
if (d < 10) {d = "0"+d}
|
||||
return y+'/'+m+'/'+d;
|
||||
}
|
||||
var formate_datetime = function(date){
|
||||
date = new Date(date)
|
||||
return [format_date(date),format_time(date)]
|
||||
}
|
||||
$(window).resize(function(){
|
||||
var window_w = $(window).width()
|
||||
var this_w = dom.width()
|
||||
var event_doc = dom.find('.calendar-events');
|
||||
if (this_w>=728 && window_w>=768){
|
||||
if (!event_doc.hasClass('width-50')){
|
||||
event_doc.removeClass('width-100')
|
||||
event_doc.addClass('width-50')
|
||||
event_doc.css('width','50%')
|
||||
event_doc.parents('div.w-calendar').find('div').eq(0).css('width','50%')
|
||||
}
|
||||
}else{
|
||||
if (!event_doc.hasClass('width-100')){
|
||||
event_doc.addClass('width-100')
|
||||
event_doc.removeClass('width-50')
|
||||
event_doc.css('width','100%')
|
||||
event_doc.parents('div.w-calendar').find('div').eq(0).css('width','100%')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
var show_event = function(date,ele){
|
||||
var event_div = $(ele).parents('div.w-calendar').find('div.calendar-events')
|
||||
$(ele).parents('.w-calendar').find('td.shown').removeClass('shown')
|
||||
$(ele).addClass('shown')
|
||||
function set_event(date,active_flag){
|
||||
var date_split = date.split('-')
|
||||
var event_temp = $(event_template)
|
||||
var read_more_text = $('html').attr('lang')=='zh_tw' ? '查看詳情' : 'Read more'
|
||||
event_temp.find('.event-header .date .month').text(month_names[parseInt(date_split[1])])
|
||||
event_temp.find('.event-header .date .day').text(parseInt(date_split[0]))
|
||||
|
||||
$.each(events[date],function(k,v){
|
||||
var tp
|
||||
if (v.url_linked==''){
|
||||
var time_string = ''
|
||||
if(v.allDay) {
|
||||
var end_time
|
||||
var start_time = formate_datetime(v.start)[0]
|
||||
if(v.end)
|
||||
end_time = formate_datetime(v.end)[0]
|
||||
else
|
||||
end_time = start_time
|
||||
time_string = (start_time==end_time ? "<p class='start-date'><i class='icons-calendar' /> " + start_time + "</p>" : "<i class='icons-calendar' /> " + start_time + " <i class='icons-arrow-right-5' /> " + end_time + "")
|
||||
}else{
|
||||
var st = formate_datetime(v.start),
|
||||
et = formate_datetime(v.end),
|
||||
start_time = st[0],
|
||||
end_time = et[0],
|
||||
same = (start_time==end_time),
|
||||
etime = et[1],
|
||||
stime = st[1]
|
||||
time_string = (same ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
|
||||
}
|
||||
var modal_tp = ('<div class="dialog_event" style="display: none;">' +
|
||||
'<div class="modal-header">' +
|
||||
'<h3>' + v.title + '</h3>' +
|
||||
'</div>' +
|
||||
'<div class="modal-body">' +
|
||||
'<div class="event_summary">' + time_string + '</div>' +
|
||||
v.note +
|
||||
'</div>' +
|
||||
'</div>')
|
||||
tp = $('<div class="event-container-one has-dialog"><div class="title_temp"></div><div class="duration_temp"></div><div class="event-content"></div>'+modal_tp+'</div>')
|
||||
}else{
|
||||
tp = $('<a class="event-container-one"><div class="title_temp"></div><div class="duration_temp"></div><div class="event-content"></div></a>')
|
||||
}
|
||||
var sd = formate_datetime(v.start),
|
||||
ed = formate_datetime(v.end),
|
||||
duration = '';
|
||||
if(v.allDay){
|
||||
if (sd[0]!=ed[0]){
|
||||
duration = sd[0]+'>'+ed[0] +'<br>'
|
||||
}
|
||||
}else if (sd[0]==ed[0]){
|
||||
duration = sd[1]+'>'+ed[1] +'<br>'
|
||||
}else{
|
||||
duration = sd[0]+' '+sd[1]+'>'+ed[0]+' '+ed[1] +'<br>'
|
||||
}
|
||||
tp.css('color',hexToRGB(v.color,0.45))
|
||||
tp.find('.event-content').html(v.note || read_more_text)
|
||||
tp.find('.title_temp').html(v.title)
|
||||
tp.find('.duration_temp').html(duration)
|
||||
if (k==0){
|
||||
tp.addClass('active')
|
||||
event_temp.find('.event-header .event-inner-title').html(v.title)
|
||||
event_temp.find('.event-header .duration').html(duration)
|
||||
}
|
||||
event_temp.find('.event-containers').append(tp)
|
||||
if(v.url_linked != ''){
|
||||
tp.attr('href',v.url_linked)
|
||||
}
|
||||
})
|
||||
if (active_flag){
|
||||
event_temp.addClass('active')
|
||||
}
|
||||
if (events[date] && events[date].length>1){
|
||||
var switch_button_wraper = $("<div class=\"switch_button_wraper\"> <button class=\"switch_button\" for=\"prev\" type=\"button\"><</button>"
|
||||
+"<button class=\"switch_button\" for=\"next\" type=\"button\">></button>"
|
||||
+"</div>")
|
||||
switch_button_wraper.find('button').click(function(){
|
||||
if (!switching){
|
||||
var showing_event = $(this).parents('.event-wraper').find('.event-container-one.active')
|
||||
var next_event
|
||||
showing_event.css('position','')
|
||||
showing_event.css('right','0')
|
||||
showing_event.removeClass('active')
|
||||
if ($(this).attr('for')=='prev'){
|
||||
next_event = showing_event.prev('.event-container-one')
|
||||
if (next_event.length==0){
|
||||
next_event = $(this).parents('.event-wraper').find('.event-container-one').eq(-1)
|
||||
}
|
||||
next_event.addClass('active')
|
||||
next_event.css('right','100%')
|
||||
switching = true
|
||||
next_event.animate({'right': '0%'},function(){
|
||||
$(this).css('right','')
|
||||
if ($(this).find('.event-content').height()>$(this).height()){
|
||||
$(this).css('position','relative')
|
||||
}
|
||||
})
|
||||
showing_event.animate({'right': '-100%'},function(){
|
||||
switching = false
|
||||
})
|
||||
}else{
|
||||
next_event = showing_event.next('.event-container-one')
|
||||
if (next_event.length==0){
|
||||
next_event = $(this).parents('.event-wraper').find('.event-container-one').eq(0)
|
||||
}
|
||||
next_event.addClass('active')
|
||||
next_event.css('right','-100%')
|
||||
switching = true
|
||||
next_event.animate({'right': '0%'},function(){
|
||||
$(this).css('right','')
|
||||
if ($(this).find('.event-content').height()>$(this).height()){
|
||||
$(this).css('position','relative')
|
||||
}
|
||||
})
|
||||
showing_event.animate({'right': '100%'},function(){
|
||||
switching = false
|
||||
})
|
||||
}
|
||||
$(this).parents('.event').eq(0).find('.event-header .event-inner-title').html(next_event.find('.title_temp').html())
|
||||
$(this).parents('.event').eq(0).find('.event-header .duration').html(next_event.find('.duration_temp').html())
|
||||
}
|
||||
})
|
||||
event_temp.find('.event-wraper').eq(0).append(switch_button_wraper)
|
||||
}
|
||||
event_div.append(event_temp)
|
||||
}
|
||||
event_div.html('')
|
||||
set_event(date,true)
|
||||
var all_event_in_table = $(ele).parents('table').eq(0).find('td.w-calendar-event')
|
||||
var ele_index = all_event_in_table.index(ele)
|
||||
var next_ele = all_event_in_table.eq(ele_index+1)
|
||||
if (next_ele.length){
|
||||
set_event(next_ele.data('date-node'),false)
|
||||
}
|
||||
event_div.find('.has-dialog').click(function(){
|
||||
var tmp=$(this).find('.dialog_event').clone().dialog({dialogClass: 'calendar-dialog'});
|
||||
$('.ui-dialog button').blur();
|
||||
})
|
||||
function event_hover(){
|
||||
var event_doc = $(this).parents('.event').eq(0);
|
||||
if (!event_doc.hasClass('active')){
|
||||
tp1 = event_doc.parents('.calendar-events').eq(0).find('.event.active .event-containers');
|
||||
tp2 = event_doc.find('.event-containers');
|
||||
if (!toggling){
|
||||
tp2.css('height','0');
|
||||
tp2.css('min-height','0');
|
||||
hover_step = hover_step_max;
|
||||
}else{
|
||||
hover_step = hover_step_max - hover_step;
|
||||
}
|
||||
event_doc.addClass('active');
|
||||
function toggle_height(){
|
||||
tp1.css('height',(hover_step*hover_max_height/hover_step_max)+'em');
|
||||
tp2.css('height',(hover_max_height-hover_step*hover_max_height/hover_step_max)+'em');
|
||||
hover_step = hover_step-1;
|
||||
if (hover_step>=0){
|
||||
setTimeout(toggle_height,50);
|
||||
}else{
|
||||
tp1.css('min-height','');
|
||||
tp2.css('min-height','');
|
||||
tp1.css('height','');
|
||||
tp2.css('height','');
|
||||
toggling = false;
|
||||
}
|
||||
}
|
||||
if (!toggling){
|
||||
setTimeout(toggle_height,50);
|
||||
}
|
||||
tp1.css('height',tp1.height());
|
||||
tp1.css('min-height','0');
|
||||
tp1.parents('.event').removeClass('active');
|
||||
toggling = true;
|
||||
}
|
||||
}
|
||||
event_div.find('.event .event-header').hover(event_hover);
|
||||
event_div.find('.event .event-header').click(event_hover);
|
||||
$(ele).parents('div.w-calendar').css('display','flex');
|
||||
if ($(ele).parents('div.w-calendar').width()>=728 && $(window).width()>=768){
|
||||
event_div.css('width','50%')
|
||||
event_div.addClass('width-50')
|
||||
event_div.removeClass('width-100')
|
||||
$(ele).parents('div.w-calendar').find('div').eq(0).css('width','50%')
|
||||
}else{
|
||||
event_div.css('width','100%')
|
||||
event_div.addClass('width-100')
|
||||
event_div.removeClass('width-50')
|
||||
$(ele).parents('div.w-calendar').find('div').eq(0).css('width','100%')
|
||||
}
|
||||
event_div.show()
|
||||
}
|
||||
var hide_event = function(ele){
|
||||
$(ele).parents('.w-calendar').find('td.shown').removeClass('shown')
|
||||
var event_div = $(ele).parents('div.w-calendar').find('div.calendar-events')
|
||||
$(ele).parents('div.w-calendar').css('display','block')
|
||||
$(ele).parents('div.w-calendar').find('div').eq(0).css('width','')
|
||||
event_div.hide()
|
||||
//$(ele).parents('div.w-calendar').find('td.w-calendar-toggle').removeClass('w-calendar-toggle')
|
||||
event_div.find('.event-container-one').remove()
|
||||
}
|
||||
var renderMonth = function(){
|
||||
var num_of_rows = getNumberOfRows(),
|
||||
head_title = monthDom.find("h4 span.text"),
|
||||
table_body = monthDom.find("table.table tbody");
|
||||
table_body.html("");
|
||||
|
||||
for(var i = 0; i < num_of_rows; i++){
|
||||
var tr = null;
|
||||
if(i == 0){
|
||||
tr = makeRow("first");
|
||||
}else if(i == (num_of_rows - 1)){
|
||||
tr = makeRow("last");
|
||||
}else{
|
||||
tr = makeRow("middle");
|
||||
}
|
||||
if(tr == null){
|
||||
break;
|
||||
}
|
||||
table_body.append(tr);
|
||||
head_title.text(monthNames[firstDay.getMonth()] + " " + firstDay.getFullYear());
|
||||
}
|
||||
}
|
||||
|
||||
var getNumberOfRows = function() {
|
||||
var day = 1,
|
||||
sat_counter = 0,
|
||||
sunday_counter = 0,
|
||||
date = new Date(year, month, day);
|
||||
|
||||
while(date.getMonth() === month) {
|
||||
if(date.getDay() === 0) {
|
||||
sunday_counter++;
|
||||
}else if(date.getDay() === 6) {
|
||||
sat_counter++;
|
||||
}
|
||||
day++;
|
||||
date = new Date(year, month, day);
|
||||
}
|
||||
return (sunday_counter == 5 && sat_counter == 5 ? 6 : 5);
|
||||
}
|
||||
|
||||
var makeRow = function(position){
|
||||
if(last_inserted_date <= lastDay.getDate()){
|
||||
var row = $("<tr></tr>");
|
||||
switch (position){
|
||||
case "first":
|
||||
var first_line_first_day = new Date(year,month,firstDay.getDate()-firstDay.getDay())
|
||||
var first_line_first_date = first_line_first_day.getDate()
|
||||
var first_line_first_month = first_line_first_day.getMonth()
|
||||
var first_line_first_year = first_line_first_day.getFullYear()
|
||||
first_target_day = new Date(first_line_first_year,first_line_first_month,first_line_first_date)
|
||||
for(var i = 0;i < 7;i++){
|
||||
var td = $("<td><div></div></td>");
|
||||
if(i >= firstDay.getDay()){
|
||||
if(today != 0 && last_inserted_date == today){
|
||||
td.addClass("w-calendar-today");
|
||||
}
|
||||
td.find('div').html(last_inserted_date<10 ? " "+last_inserted_date+" " : last_inserted_date);
|
||||
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
|
||||
last_inserted_date++;
|
||||
}else{
|
||||
td.find('div').text(first_line_first_date+i)
|
||||
td.attr("data-date-node",(first_line_first_date+i)+"-"+first_line_first_month+"-"+first_line_first_year);
|
||||
td.addClass("w-calendar-other-month")
|
||||
}
|
||||
row.append(td);
|
||||
}
|
||||
break;
|
||||
case "middle":
|
||||
for(var i = 0;i < 7;i++){
|
||||
var td = $("<td><div></div></td>");
|
||||
if(today != 0 && last_inserted_date == today){
|
||||
td.attr("class","w-calendar-today");
|
||||
}
|
||||
td.find('div').html(last_inserted_date<10 ? " "+last_inserted_date+" " : last_inserted_date);
|
||||
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
|
||||
last_inserted_date++;
|
||||
row.append(td);
|
||||
}
|
||||
break;
|
||||
case "last":
|
||||
var next_month = month+1,
|
||||
next_year = year;
|
||||
if (next_month==12){
|
||||
next_month = 0;
|
||||
next_year = next_year + 1;
|
||||
}
|
||||
last_target_day = new Date(next_year,next_month,6-lastDay.getDay())
|
||||
for(var i = 0;i < 7;i++){
|
||||
var td = $("<td><div></div></td>");
|
||||
if(i <= lastDay.getDay()){
|
||||
if(today != 0 && last_inserted_date == today){
|
||||
td.attr("class","w-calendar-today");
|
||||
}
|
||||
td.find('div').html(last_inserted_date<10 ? " "+last_inserted_date+" " : last_inserted_date);
|
||||
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
|
||||
last_inserted_date++;
|
||||
}else{
|
||||
td.find('div').text(i-lastDay.getDay())
|
||||
td.attr("data-date-node",(i-lastDay.getDay())+"-"+next_month+"-"+next_year);
|
||||
td.addClass("w-calendar-other-month")
|
||||
}
|
||||
row.append(td);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
var row = null;
|
||||
}
|
||||
return row;
|
||||
}
|
||||
function toggle_event(ele,type){
|
||||
$(ele).parents('.month_template').find('td').removeClass('w-calendar-toggle')
|
||||
var toggle_month
|
||||
if ($(ele).length==1){
|
||||
$(ele).addClass('w-calendar-toggle')
|
||||
toggle_data = $(ele).data('date-node')
|
||||
toggle_month = $(ele).data('date-node').split('-')[1]
|
||||
}
|
||||
if (toggle_month==month || $(ele).length!=1){
|
||||
if (type=='show'){
|
||||
show_event($(ele).data('date-node'),ele)
|
||||
}else{
|
||||
hide_event(ele)
|
||||
}
|
||||
}
|
||||
else if(toggle_month==month+1 || toggle_month==0){
|
||||
nextMonthFunc(toggle_data)
|
||||
}else{
|
||||
prevMonthFunc(toggle_data)
|
||||
}
|
||||
}
|
||||
var fetchEvents = function(){
|
||||
var usd = Math.round(firstDay/1000),
|
||||
usd_target = Math.round(first_target_day/1000),
|
||||
ued_target = Math.round(last_target_day/1000);
|
||||
$.ajax({
|
||||
url : "/xhr/recruit_news/agenda",
|
||||
data : {"month_start" : usd,"unix_start" : usd_target, "unix_end" : ued_target, "subpart_id" : subpartid, "locale" : $('html').attr('lang')},
|
||||
dataType : "json",
|
||||
type : "get"
|
||||
}).done(function(data){
|
||||
events = {}
|
||||
$(dom).find('.w-calendar-title span').eq(0).html(data['calendar_title'])
|
||||
$.each(data.events,function(index,eve){
|
||||
var sd = new Date(eve.start),
|
||||
ed = new Date(eve.end),
|
||||
sd_date = new Date(formate_datetime(eve.start)[0]),
|
||||
ed_date = new Date(formate_datetime(eve.end)[0]),
|
||||
timeDiff = ed_date.getTime() - sd_date.getTime(),
|
||||
dayDiff = Math.round(timeDiff / (1000 * 3600 * 24));
|
||||
if(eve.allDay && dayDiff < 1){
|
||||
dayDiff = 1
|
||||
}
|
||||
if(dayDiff > 0){
|
||||
var inserting_date = sd.getDate();
|
||||
for(var i = 0;i < dayDiff; i++){
|
||||
var dt = inserting_date + "-" + sd.getMonth() + "-" + sd.getFullYear(),
|
||||
td = dom.find("td[data-date-node=" + dt + "]");
|
||||
if (events[dt]==undefined){
|
||||
events[dt]=[]
|
||||
}
|
||||
events[dt].push(eve)
|
||||
td.addClass("w-calendar-event");
|
||||
if(events[dt] && events[dt].length==1){
|
||||
td.click(function(){
|
||||
toggle_event(this,'show')
|
||||
})
|
||||
}
|
||||
inserting_date++;
|
||||
if(inserting_date > lastDay.getDate() || (ed.getMonth() == month && inserting_date > ed.getDate())){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
var dt = sd.getDate() + "-" + sd.getMonth() + "-" + sd.getFullYear();
|
||||
td = dom.find("td[data-date-node=" + dt + "]");
|
||||
if (events[dt]==undefined){
|
||||
events[dt]=[]
|
||||
}
|
||||
events[dt].push(eve)
|
||||
if(events[dt] && events[dt].length==1){
|
||||
td.click(function(){
|
||||
toggle_event(this,'show')
|
||||
})
|
||||
}
|
||||
td.addClass("w-calendar-event");
|
||||
}
|
||||
})
|
||||
if (!toggle_data){
|
||||
if (dom.find('td.w-calendar-today').length != 0){
|
||||
toggle_event(dom.find('td.w-calendar-today'),'show')
|
||||
}else{
|
||||
toggle_event(dom.find('td'),'hide')
|
||||
}
|
||||
}
|
||||
dom.find('td:not(td.w-calendar-event)').click(function(){
|
||||
toggle_event(this,'hide')
|
||||
})
|
||||
var clicked_color = dom.find('.w-calendar-event').css('background-color')
|
||||
if (clicked_color){
|
||||
var hex_color = rgb2hex(clicked_color)
|
||||
if (hex_color != '#000000'){
|
||||
clicked_color = lighten_color(hex_color,-45)
|
||||
dom.find('table').append($('<style>.widget-calendar-2 table.w-calendar-table .w-calendar-toggle{ background-color:'+clicked_color+';color: white;}</style>'))
|
||||
}
|
||||
}
|
||||
monthDom.find("i.loading").addClass("hide");
|
||||
})
|
||||
}
|
||||
|
||||
this.currentMonth = function(){
|
||||
renderMonth();
|
||||
var div_tag = $('<div class="height100"></div>')
|
||||
var widge_title = dom.find('.w-calendar-title').eq(0)
|
||||
div_tag.html(monthDom)
|
||||
div_tag.prepend(widge_title)
|
||||
dom.html(div_tag);
|
||||
monthDom.find("i.loading").removeClass("hide");
|
||||
fetchInterval = setTimeout(fetchEvents,300);
|
||||
dom.find('div').eq(0).after(eventHTML)
|
||||
}
|
||||
|
||||
this.nextMonth = function(toggle_flag){
|
||||
clearTimeout(fetchInterval);
|
||||
monthDom.find("i.loading").removeClass("hide");
|
||||
month++;
|
||||
if(month == 12){
|
||||
year++;
|
||||
month = 0;
|
||||
}
|
||||
firstDay = new Date(Date.UTC(year,month,1));
|
||||
lastDay =new Date(Date.UTC(year,month+1,0));
|
||||
today = (initialDate.getMonth() == month && initialDate.getFullYear() == year ? initialDate.getDate() : 0);
|
||||
last_inserted_date = 1;
|
||||
var toggle_type,ele;
|
||||
if (toggle_data && toggle_flag){
|
||||
ele = dom.find('td[data-date-node="'+toggle_data+'"]')
|
||||
toggle_type = (ele.hasClass('w-calendar-event') ? 'show' : 'hide')
|
||||
}else{
|
||||
toggle_data = undefined
|
||||
}
|
||||
renderMonth();
|
||||
dom.find("table.w-calendar-table tbody").html(monthDom.find("tbody").html());
|
||||
if (ele){
|
||||
ele = dom.find('td[data-date-node="'+toggle_data+'"]')
|
||||
toggle_event(ele,toggle_type)
|
||||
}
|
||||
fetchInterval = setTimeout(fetchEvents,300);
|
||||
}
|
||||
nextMonthFunc = this.nextMonth;
|
||||
this.prevMonth = function(toggle_flag){
|
||||
clearTimeout(fetchInterval);
|
||||
monthDom.find("i.loading").removeClass("hide");
|
||||
month--;
|
||||
if(month == -1){
|
||||
year--;
|
||||
month = 11;
|
||||
}
|
||||
firstDay = new Date(Date.UTC(year,month,1));
|
||||
lastDay = new Date(Date.UTC(year,month+1,0));
|
||||
today = (initialDate.getMonth() == month && initialDate.getFullYear() == year ? initialDate.getDate() : 0);
|
||||
last_inserted_date = 1;
|
||||
var toggle_type,ele;
|
||||
if (toggle_data && toggle_flag){
|
||||
ele = dom.find('td[data-date-node="'+toggle_data+'"]')
|
||||
toggle_type = (ele.hasClass('w-calendar-event') ? 'show' : 'hide')
|
||||
}else{
|
||||
toggle_data = undefined
|
||||
}
|
||||
renderMonth();
|
||||
dom.find("table.w-calendar-table tbody").html(monthDom.find("tbody").html());
|
||||
if (ele){
|
||||
ele = dom.find('td[data-date-node="'+toggle_data+'"]')
|
||||
toggle_event(ele,toggle_type)
|
||||
}
|
||||
fetchInterval = setTimeout(fetchEvents,300);
|
||||
}
|
||||
prevMonthFunc = this.prevMonth;
|
||||
}
|
||||
|
|
@ -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,259 @@
|
|||
.widget-event-news-calendar-2.w-calendar{
|
||||
.w-calendar-table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
.height100 {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
a.event-container-one{
|
||||
color: inherit;
|
||||
}
|
||||
.close_box{
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
float: right;
|
||||
padding: 0.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
.close_box:hover{
|
||||
color: red;
|
||||
}
|
||||
.event-bullet-event {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.event-bullet-event {
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
.event-header{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 1.7em;
|
||||
font-weight: bold;
|
||||
padding: 0.35em 0;
|
||||
}
|
||||
.event-info{
|
||||
padding-left: 15%;
|
||||
}
|
||||
.calendar-events{
|
||||
position: relative;
|
||||
background: #fbfbfb;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.month_template{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
flex-wrap: wrap;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 1em;
|
||||
.w-calendar-table td:hover {
|
||||
background-color: #eaeaea;
|
||||
color: #333;
|
||||
}
|
||||
.w-calendar-table td {
|
||||
background: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.w-calendar-table td div{
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: auto;
|
||||
padding: 10%;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.w-calendar-table th {
|
||||
background: unset;
|
||||
color: unset;
|
||||
border: 0;
|
||||
padding: 1.5% 0.5%;
|
||||
}
|
||||
.widget-title {
|
||||
padding: 0.2em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
table.w-calendar-table td.w-calendar-toggle div, table.w-calendar-table td.w-calendar-toggle div{
|
||||
background: #6f0007;
|
||||
border-radius: 50%;
|
||||
color: white;
|
||||
}
|
||||
.w-calendar-table td.w-calendar-event div{
|
||||
border: 1px #6f0007 solid;
|
||||
border-radius: 50%;
|
||||
background: #eee;
|
||||
}
|
||||
.w-calendar-title{
|
||||
background: rgb(146, 8, 17);
|
||||
color: rgb(255, 255, 255);
|
||||
padding: 0px 10%;
|
||||
display: flex;
|
||||
line-height: 2em;
|
||||
justify-content: space-between;
|
||||
font-size: 1.85em;
|
||||
width: 100%;
|
||||
.w-calendar-title span:last-child{
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.w-calendar-title.center{
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.calendar-dialog div.ui-dialog-content {
|
||||
max-height: 20em !important;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
table td.w-calendar-other-month {
|
||||
color: #999797;
|
||||
}
|
||||
.event-header{
|
||||
display: flex;
|
||||
background: #dadada;
|
||||
cursor: default;
|
||||
}
|
||||
.event-header .date{
|
||||
width: 30%;
|
||||
}
|
||||
.event.active .event-header .day{
|
||||
color: #bf1f1f;
|
||||
}
|
||||
.event.active .event-header .date{
|
||||
color: #202427;
|
||||
}
|
||||
.event .event-header .day{
|
||||
font-size: 1.4em;
|
||||
}
|
||||
.event .event-header .month{
|
||||
font-size: 0.7em;
|
||||
}
|
||||
.event .event-header .date{
|
||||
color: #a08a70;
|
||||
}
|
||||
.event-title{
|
||||
width: 70%;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.event-title .duration{
|
||||
font-size: 0.7em;
|
||||
text-align: left;
|
||||
color: #a0a1a1;
|
||||
}
|
||||
.duration_temp,.title_temp{
|
||||
display: none;
|
||||
}
|
||||
.event-inner-title{
|
||||
line-height: 2em;
|
||||
text-align: left;
|
||||
}
|
||||
.event-containers{
|
||||
height: 0;
|
||||
min-height: unset;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 0 10%;
|
||||
}
|
||||
.event-container-one {
|
||||
position: absolute;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
width: calc(100% - 0.7em);;
|
||||
height: calc(100% - 0.7em);
|
||||
flex-wrap: wrap;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 1em;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: rgba(50, 50, 50, 0.45);
|
||||
}
|
||||
.event-container-one:hover {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0.1em 0.7em 0em;
|
||||
}
|
||||
.event-container-one .event-content{
|
||||
color: #000000;
|
||||
}
|
||||
button.switch_button {
|
||||
margin: 10%;
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
border-radius: 1.25em;
|
||||
border: 0;
|
||||
background: #96231a;
|
||||
color: white;
|
||||
outline: 0;
|
||||
}
|
||||
.switch_button:hover {
|
||||
background: #c07b76;
|
||||
}
|
||||
.switch_button_wraper{
|
||||
position: absolute;
|
||||
right: 0%;
|
||||
margin-right: 2%;
|
||||
width: 3em;
|
||||
margin-bottom: 2%;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.event-wraper{
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
.event-container-one:not(.active) {
|
||||
right: -100%;
|
||||
}
|
||||
.event.active .event-containers{
|
||||
min-height: 13em;
|
||||
height: 100%;
|
||||
}
|
||||
.calendar-events.width-100 .switch_button_wraper{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.calendar-events.width-100 .switch_button{
|
||||
margin: 2%;
|
||||
}
|
||||
.calendar-events.width-100 .event-containers{
|
||||
z-index: 3;
|
||||
}
|
||||
.month_template .widget-title {
|
||||
border: 0;
|
||||
border-bottom: 0.0625em solid #ddd;
|
||||
}
|
||||
&>div:first-child {
|
||||
box-shadow: 0em 0.1em 0.3em 0em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
.event{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
.full-size-img img {
|
||||
width: 100%;
|
||||
}
|
||||
.full-size-img {
|
||||
width: 100%;
|
||||
}
|
||||
.s-annc__sub-img.pull-right {
|
||||
margin-left: 2em;
|
||||
}
|
||||
.s-annc__sub-img.pull-left {
|
||||
margin-right: 2em;
|
||||
}
|
||||
strong.carousel__description {
|
||||
color: white;
|
||||
}
|
||||
@media (max-width: 767px){
|
||||
.carousel_images{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.carousel_img_item{
|
||||
display: none;
|
||||
float: left;
|
||||
}
|
||||
.controlplay {
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 3%;
|
||||
z-index: 200;
|
||||
}
|
||||
.controlplay a {
|
||||
display: inline-block;
|
||||
margin-right: 0.25em;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid rgba(255,255,255,0.5);
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.controlplay a i {
|
||||
font-family: FontAwesome;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
color: #FFF;
|
||||
vertical-align: middle;
|
||||
font-style: unset;
|
||||
}
|
||||
.controlplay .resume-slide i::before {
|
||||
content: "\f04b";
|
||||
}
|
||||
.controlplay .pause-slide i::before {
|
||||
content: "\f04c";
|
||||
}
|
||||
ul.button-mid .prev-button {
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
float: left;
|
||||
left: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
ul.button-mid .next-button {
|
||||
float: right;
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
right: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #fff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
.carousel_images_slide{
|
||||
padding: 3em;
|
||||
}
|
||||
.carousel_img_item img{
|
||||
cursor: pointer;
|
||||
}
|
||||
@media (max-width: 479px){
|
||||
.carousel_img_item:nth-child(-n+1){
|
||||
display: block;
|
||||
width: 100%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 480px){
|
||||
.carousel_img_item:nth-child(-n+2){
|
||||
display: block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px){
|
||||
.carousel_img_item:nth-child(-n+3){
|
||||
display: block;
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px){
|
||||
.carousel_img_item:nth-child(-n+4){
|
||||
display: block;
|
||||
width: 25%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
.w-ba-banner .controlplay .resume-slide.active i{
|
||||
color: #32D9C3;
|
||||
}
|
||||
.w-ba-banner .controlplay .pause-slide.active i{
|
||||
color: #ff4500;
|
||||
}
|
||||
.w-ba-banner .controlplay{
|
||||
width: auto;
|
||||
}
|
||||
.w-ba-banner .button-mid{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.next-button,.prev-button{
|
||||
cursor: pointer;
|
||||
}
|
||||
a.orbit-hash-tag {
|
||||
list-style: none;
|
||||
background: #e0edff;
|
||||
color: #0a84ff;
|
||||
margin-right: 0.5em;
|
||||
border-radius: 0.5em;
|
||||
padding: 0.2em 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
display: inline-block;
|
||||
&:hover{
|
||||
background: #0a84ff;
|
||||
transform: translatey(-2px);
|
||||
transition: transform 0.4s;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,694 @@
|
|||
@charset "utf-8";
|
||||
|
||||
@import "../initial";
|
||||
|
||||
//
|
||||
// Widget
|
||||
//
|
||||
|
||||
// RecruitNews widget
|
||||
// ## Gerneral styles for widgets
|
||||
.w-recruit_news {
|
||||
.w-recruit_news__widget-title {
|
||||
@extend .unity-title;
|
||||
}
|
||||
|
||||
.w-recruit_news__list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.w-recruit_news__item {
|
||||
margin-bottom: 1.875em;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.w-recruit_news__meta {
|
||||
.w-recruit_news__status-wrap,
|
||||
.w-recruit_news__postdate-wrap,
|
||||
.w-recruit_news__category-wrap {
|
||||
display: inline-block;
|
||||
margin-right: 0.2em;
|
||||
font-size: 0.8125em;
|
||||
color: $theme-gray;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
i {
|
||||
color: $theme-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.w-recruit_news__subtitle {
|
||||
font-size: 0.8125em;
|
||||
color: $theme-gray;
|
||||
}
|
||||
|
||||
.w-recruit_news__entry-title {
|
||||
margin-bottom: 0.625em;
|
||||
}
|
||||
|
||||
.w-recruit_news__title {
|
||||
font-family: $sub-font;
|
||||
color: $theme-color-main;
|
||||
text-decoration: none;
|
||||
font-size: 0.8125rem;
|
||||
|
||||
&:hover {
|
||||
color: darken($theme-color-main, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-1
|
||||
.widget-recruit_news-1 {
|
||||
.w-recruit_news__img-wrap {
|
||||
height: 12.5em;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
.w-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
line-height: 1.3;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-2
|
||||
.widget-recruit_news-2 {
|
||||
.w-recruit_news__img-wrap {
|
||||
height: 12.5em;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
.w-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
line-height: 1.3;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-3
|
||||
.widget-recruit_news-3 {
|
||||
.w-recruit_news__img-wrap {
|
||||
height: 12.5em;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
.w-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
line-height: 1.3;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-4
|
||||
.widget-recruit_news-4 {
|
||||
.w-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
line-height: 1.3;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.w-recruit_news__list > .w-recruit_news__item:nth-child(3n+1) {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.w-recruit_news__img-wrap {
|
||||
height: 12.5em;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-5
|
||||
.widget-recruit_news-5 {
|
||||
.w-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
line-height: 1.3;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.w-recruit_news__item {
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
padding-bottom: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-6
|
||||
.widget-recruit_news-6 {
|
||||
.w-recruit_news__item {
|
||||
margin-bottom: 0.8em;
|
||||
padding-bottom: 0.8em;
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
}
|
||||
|
||||
.w-recruit_news__entry-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.w-recruit_news__category-wrap,
|
||||
.w-recruit_news__status,
|
||||
.w-recruit_news__title,
|
||||
.w-recruit_news__postdate-wrap {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-7
|
||||
.widget-recruit_news-7 {
|
||||
.w-recruit_news__item {
|
||||
margin-bottom: 0.8em;
|
||||
padding-bottom: 0.8em;
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
}
|
||||
|
||||
.w-recruit_news__entry-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.w-recruit_news__category-wrap,
|
||||
.w-recruit_news__status,
|
||||
.w-recruit_news__title,
|
||||
.w-recruit_news__postdate-wrap {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
// ## Gerneral styles for table widgets
|
||||
|
||||
.w-recruit_news__postdate,
|
||||
.w-recruit_news__category {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Widget-8
|
||||
// ## Table
|
||||
.widget-recruit_news-8 {
|
||||
.w-recruit_news__th {
|
||||
color: #fff;
|
||||
background: $theme-color-main;
|
||||
font-size: 0.8125em;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
td {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-9
|
||||
// ## Table
|
||||
.widget-recruit_news-9 {
|
||||
.w-recruit_news__th {
|
||||
color: #fff;
|
||||
background: $theme-color-main;
|
||||
font-size: 0.8125em;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
td {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-10
|
||||
.widget-recruit_news-10 {
|
||||
.w-recruit_news__item {
|
||||
margin-bottom: 0.8em;
|
||||
padding-bottom: 0.8em;
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
}
|
||||
|
||||
.w-recruit_news__entry-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.w-recruit_news__postdate-wrap {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-11
|
||||
.widget-recruit_news-11 {
|
||||
.w-recruit_news__item {
|
||||
margin-bottom: 0.8em;
|
||||
padding-bottom: 0.8em;
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
}
|
||||
|
||||
.w-recruit_news__entry-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.w-recruit_news__postdate-wrap {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-12
|
||||
// ## Table
|
||||
.widget-recruit_news-12 {
|
||||
.w-recruit_news__th {
|
||||
color: #fff;
|
||||
background: $theme-color-main;
|
||||
font-size: 0.8125em;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
td {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-13
|
||||
// ## Table
|
||||
.widget-recruit_news-13 {
|
||||
.w-recruit_news__th {
|
||||
color: #fff;
|
||||
background: $theme-color-main;
|
||||
font-size: 0.8125em;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
td {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Widget-14
|
||||
.widget-recruit_news-14 {
|
||||
.w-recruit_news__list {
|
||||
padding: 0 0.9375em;
|
||||
}
|
||||
|
||||
.w-recruit_news__img-wrap {
|
||||
height: 18.75em;
|
||||
margin-bottom: 0.9375em;
|
||||
|
||||
@media (min-width: $screen-md) {
|
||||
height: 12.5em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.w-recruit_news__item {
|
||||
margin-bottom: 0.8em;
|
||||
padding-bottom: 0.8em;
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
}
|
||||
|
||||
.w-recruit_news__entry-title {
|
||||
margin: 0 0 0.625em 0;
|
||||
|
||||
@media (min-width: $screen-md) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.w-recruit_news__postdate-wrap {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
.w-recruit_news__status {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.w-recruit_news__postdate {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
}
|
||||
|
||||
// RecruitNews index
|
||||
// ## General style for index pages
|
||||
.i-recruit_news {
|
||||
.i-recruit_news__page-title {
|
||||
@extend .unity-title;
|
||||
}
|
||||
|
||||
.i-recruit_news__list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.i-recruit_news__widget-title {
|
||||
@extend .unity-title;
|
||||
}
|
||||
|
||||
.i-recruit_news__item {
|
||||
margin-bottom: 1.875em;
|
||||
}
|
||||
|
||||
.i-recruit_news__img {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.i-recruit_news__th {
|
||||
color: $theme-white;
|
||||
background: $theme-color-main;
|
||||
font-size: 0.8125em;
|
||||
border: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.i-recruit_news__postdate,
|
||||
.i-recruit_news__category,
|
||||
.i-recruit_news__view-count {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.i-recruit_news__status-wrap {
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: .2em .6em .3em;
|
||||
|
||||
&:last-child {
|
||||
margin: 0 0.3125em 0.1875em 0;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.i-recruit_news__title:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.i-recruit_news__meta {
|
||||
.i-recruit_news__status-wrap,
|
||||
.i-recruit_news__postdate-wrap,
|
||||
.i-recruit_news__category-wrap {
|
||||
display: inline-block;
|
||||
margin-right: 0.2em;
|
||||
font-size: 0.8125em;
|
||||
color: $theme-gray;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
i {
|
||||
color: $theme-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.i-recruit_news__subtitle {
|
||||
font-size: 0.8125em;
|
||||
color: $theme-gray;
|
||||
}
|
||||
|
||||
.i-recruit_news__entry-title {
|
||||
margin-bottom: 0.625em;
|
||||
}
|
||||
|
||||
.i-recruit_news__title {
|
||||
font-family: $sub-font;
|
||||
color: $theme-color-main;
|
||||
text-decoration: none;
|
||||
font-size: 0.8125rem;
|
||||
|
||||
&:hover {
|
||||
color: darken($theme-color-main, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Index-1
|
||||
.index-recruit_news-1 {}
|
||||
|
||||
// Index-5
|
||||
// Index-6
|
||||
.index-recruit_news-5,
|
||||
.index-recruit_news-6 {
|
||||
.i-recruit_news__img-wrap {
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
|
||||
.i-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
|
||||
// Index-7
|
||||
.index-recruit_news-7 {
|
||||
.i-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
line-height: 1.3;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.i-recruit_news__list > .i-recruit_news__item:nth-child(3n+1) {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.i-recruit_news__img-wrap {
|
||||
height: 12.5em;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Index-8
|
||||
.index-recruit_news-8 {
|
||||
.i-recruit_news__title {
|
||||
font-family: $main-font;
|
||||
line-height: 1.3;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.i-recruit_news__item {
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
padding-bottom: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
// Index-9
|
||||
// Index-10
|
||||
.index-recruit_news-9,
|
||||
.index-recruit_news-10 {
|
||||
.i-recruit_news__item {
|
||||
margin-bottom: 0.8em;
|
||||
padding-bottom: 0.8em;
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
}
|
||||
|
||||
.i-recruit_news__entry-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.i-recruit_news__category-wrap,
|
||||
.i-recruit_news__status,
|
||||
.i-recruit_news__title,
|
||||
.i-recruit_news__postdate-wrap {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.i-recruit_news__status {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
// Index-11
|
||||
// Index-12
|
||||
.index-recruit_news-11,
|
||||
.index-recruit_news-12 {
|
||||
.i-recruit_news__item {
|
||||
margin-bottom: 0.8em;
|
||||
padding-bottom: 0.8em;
|
||||
border-bottom: 0.0625em dashed lighten($theme-gray, 65%);
|
||||
}
|
||||
|
||||
.i-recruit_news__entry-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.i-recruit_news__postdate-wrap {
|
||||
font-size: 0.8125em;
|
||||
}
|
||||
|
||||
.i-recruit_news__status {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Index-16
|
||||
.index-recruit_news-16 {
|
||||
td ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
|
||||
// RecruitNews show
|
||||
.s-recruit_news {
|
||||
.s-recruit_news__show-title {
|
||||
@extend .unity-title;
|
||||
}
|
||||
|
||||
.s-recruit_news__meta-wrap {
|
||||
border-bottom: 0.0625em solid $theme-gray-light;
|
||||
|
||||
@include clearfix;
|
||||
|
||||
.s-recruit_news__meta--item {
|
||||
font-size: 0.875rem;
|
||||
margin-right: 1em;
|
||||
margin-bottom: 0.6em;
|
||||
float: left;
|
||||
|
||||
i {
|
||||
color: darken($theme-gray-light, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.s-recruit_news__tag-wrap {
|
||||
position: relative;
|
||||
margin-right: 0;
|
||||
padding-left: 1.6em;
|
||||
clear: both;
|
||||
float: none;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 0.4375em;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.s-recruit_news__tag-wrap {
|
||||
.s-recruit_news__tag {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-recruit_news__post-wrap {
|
||||
@include clearfix;
|
||||
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.s-recruit_news__related-wrap {
|
||||
padding-top: 1em;
|
||||
border-top: 0.0625em dotted $theme-gray-light;
|
||||
}
|
||||
|
||||
.s-recruit_news__related-file {
|
||||
margin-bottom: 0.9375em;
|
||||
}
|
||||
|
||||
.s-recruit_news__related-file,
|
||||
.s-recruit_news__related-link {
|
||||
padding-bottom: 0.375em;
|
||||
padding-left: 1.6em;
|
||||
|
||||
i {
|
||||
margin: 0.5em 0 0 -1.6em;
|
||||
float: left;
|
||||
color: darken($theme-gray-light, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.s-recruit_news__related-link-list,
|
||||
.s-recruit_news__related-file-list {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.s-recruit_news__flie-title {
|
||||
max-width: 9.375rem;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.s-recruit_news__social > * {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.s-recruit_news__social .print-button {
|
||||
color: #fff;
|
||||
font-size: 0.688em;
|
||||
border-radius: 0.25em;
|
||||
padding: 0.125em 0.375em;
|
||||
background-color: $theme-color-main;
|
||||
}
|
||||
|
||||
.s-recruit_news__social .print-button:hover {
|
||||
background-color: lighten($theme-color-main, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
module ActionDispatch
|
||||
class Request
|
||||
def original_url
|
||||
original_fullpath
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,596 @@
|
|||
# encoding: utf-8
|
||||
require 'rubyXL'
|
||||
class Admin::RecruitNewsController < OrbitAdminController
|
||||
include Admin::RecruitNewsHelper
|
||||
before_action ->(module_app = @app_title) { set_variables module_app }
|
||||
before_action :set_recruit_news, only: [:edit, :destroy]
|
||||
before_action :load_access_level, :load_settings
|
||||
|
||||
def initialize
|
||||
super
|
||||
@app_title = "recruit_news_mod"
|
||||
end
|
||||
def update_sort
|
||||
ids = params[:ids]
|
||||
ids.each_with_index do |id,i|
|
||||
RecruitNews.where(id: id).update(sort_number: i)
|
||||
end
|
||||
RecruitNewsCache.all.delete
|
||||
edit_sort
|
||||
render 'update_sort',layout: false
|
||||
|
||||
end
|
||||
|
||||
def update_sort_setting
|
||||
setting = @recruit_news_setting
|
||||
setting.update_attributes(settings_params)
|
||||
update_enable_manually_sort(setting)
|
||||
redirect_to edit_sort_admin_recruit_news_index_path
|
||||
end
|
||||
|
||||
def edit_sort
|
||||
@setting = @recruit_news_setting
|
||||
@recruit_news = RecruitNews.where(is_top: true).order_by({is_top: -1,sort_number: 1,postdate: -1, _id: -1})
|
||||
@table_fields = ['recruit_news.table.sort_number','recruit_news.table.title','recruit_news.event_date','recruit_news.start_date']
|
||||
end
|
||||
|
||||
def index
|
||||
RecruitNews.remove_expired_status
|
||||
@tags = @module_app.tags
|
||||
@table_fields = [:status, :category, :title, "recruit_news.event_date", "recruit_news.start_date", "recruit_news.end_date", :last_modified]
|
||||
@current_user = current_user
|
||||
if params[:sort].blank?
|
||||
params[:sort] = 'event_date'
|
||||
params[:order] = 'desc'
|
||||
end
|
||||
if RecruitNewsSetting.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)
|
||||
@recruit_news = RecruitNews.where(:category_id.ne=>nil, :create_user_id=>current_user.id,:is_preview.in=>[false,nil])
|
||||
.order_by(sort)
|
||||
.with_categories(filters("category"))
|
||||
.with_tags(filters("tag"))
|
||||
.with_status(filters("status"))
|
||||
else
|
||||
@recruit_news = RecruitNews.where(:category_id.ne=>nil, :uid=>nil).order_by(sort)
|
||||
@categories = @module_app.categories.enabled
|
||||
@filter_fields = filter_fields(@categories, @tags)
|
||||
end
|
||||
else
|
||||
@categories = @module_app.categories.enabled
|
||||
@filter_fields = filter_fields(@categories, @tags)
|
||||
@recruit_news = RecruitNews.where(:category_id.ne=>nil, :is_preview.in=>[false,nil])
|
||||
.order_by(sort)
|
||||
.with_categories(filters("category"))
|
||||
.with_tags(filters("tag"))
|
||||
.with_status(filters("status"))
|
||||
end
|
||||
@recruit_news = search_data(@recruit_news,[:title]).page(params[:page]).per(10)
|
||||
|
||||
if request.xhr?
|
||||
render :partial => "index"
|
||||
end
|
||||
end
|
||||
|
||||
def feed
|
||||
@table_feed_fields = ["recruit_news.feed_name", :tags, :categories, "recruit_news.rssfeed", "recruit_news.jsonfeed"]
|
||||
@feeds = RecruitNewsFeed.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/recruit_news/widget/sync_data?'+url_params.to_param
|
||||
end
|
||||
def settings
|
||||
@setting = @recruit_news_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="recruit_news_import_format.xlsx"'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def export_excel
|
||||
@thread = Multithread.where(:key=>'export_recruit_news').first
|
||||
update_flag = true
|
||||
if @thread.nil?
|
||||
@thread = Multithread.create(:key=>'export_recruit_news',:status=>{:status=>'Processing'})
|
||||
else
|
||||
update_flag = false if @thread.status[:status] == 'Processing' && @thread.respond_to?(:updated_at) && (@thread.updated_at > DateTime.now - 1.minute rescue false)
|
||||
if update_flag
|
||||
@thread.update(:status=>{:status=>'Processing'})
|
||||
end
|
||||
end
|
||||
if update_flag
|
||||
Thread.new do
|
||||
begin
|
||||
@recruit_news = RecruitNews.where(:category_id.ne=>nil).desc(:created_at)
|
||||
last_updated = RecruitNews.max(:updated_at).to_i
|
||||
filename = "public/recruit_news_export_#{last_updated}.xlsx"
|
||||
if File.exist?(filename)
|
||||
@thread.update(:status=>{:status=>'finish','finish_percent'=>100,'info'=>I18n.t('recruit_news.read_from_cache')})
|
||||
else
|
||||
excel_contents = render_to_string( handlers: [:axlsx], formats: [:xlsx] , layout: false, template: 'admin/recruit_news/export_excel.xlsx', locals: {:@recruit_news=>@recruit_news,:@thread=>@thread} )
|
||||
File.open(filename, 'w') do |f|
|
||||
f.write excel_contents
|
||||
end
|
||||
end
|
||||
@thread.status[:file] = filename
|
||||
@thread.status[:filename] = "recruit_news_export_#{DateTime.now.in_time_zone(Time.zone.utc_offset / 3600).strftime('%Y_%m_%d_%H%M')}.xlsx"
|
||||
@thread.save
|
||||
rescue => e
|
||||
@thread.status[:status] = 'error'
|
||||
# @thread.status[:info] = [e.to_s, e.backtrace]
|
||||
puts [e.to_s, e.backtrace]
|
||||
@thread.save
|
||||
end
|
||||
end
|
||||
end
|
||||
redirect_to admin_recruit_news_import_path(:thread_id=>@thread.id.to_s)
|
||||
end
|
||||
def render_404
|
||||
render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => 404, :formats => [:html]
|
||||
end
|
||||
def download_file_from_thread
|
||||
@thread = Multithread.where(:id=>params[:id]).first if params[:id].present?
|
||||
if @thread && @thread.status[:file]
|
||||
send_file(@thread.status[:file],:filename=>@thread.status[:filename])
|
||||
else
|
||||
render_404
|
||||
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_recruit_news_index_path
|
||||
end
|
||||
|
||||
def import
|
||||
@thread = Multithread.where(:id=>params[:thread_id]).first if params[:thread_id].present?
|
||||
end
|
||||
|
||||
|
||||
def import_from_wp
|
||||
import_from_wordpress params["import_xml"].tempfile
|
||||
redirect_to admin_recruit_news_index_path
|
||||
end
|
||||
|
||||
def importanns
|
||||
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 == "" || v.nil?
|
||||
import_this_recruit_news(row, categories, tags)
|
||||
end
|
||||
redirect_to admin_recruit_news_index_path
|
||||
else
|
||||
redirect_to admin_recruit_news_index_path(:error => "1")
|
||||
end
|
||||
end
|
||||
|
||||
def createsettings
|
||||
setting = RecruitNewsSetting.new(settings_params)
|
||||
setting.save
|
||||
update_is_postdate_sort_first(setting)
|
||||
redirect_to admin_recruit_news_settings_path
|
||||
end
|
||||
|
||||
def updatesettings
|
||||
setting = @recruit_news_setting
|
||||
ids = params['recruit_news_setting']['anns_status_settings'].to_a.collect do |i,v|
|
||||
v['_id']
|
||||
end.compact
|
||||
RecruitNewsStatusSetting.where(:id.nin=>ids).destroy
|
||||
setting.update_attributes(settings_params)
|
||||
setting.save
|
||||
update_is_postdate_sort_first(setting)
|
||||
redirect_to admin_recruit_news_settings_path
|
||||
end
|
||||
|
||||
def feedform
|
||||
if params[:type] == "new"
|
||||
@recruit_news_feed = RecruitNewsFeed.new
|
||||
render :partial => "feed_form"
|
||||
else params[:type] == "edit"
|
||||
@recruit_news_feed = RecruitNewsFeed.find(params[:id])
|
||||
render :partial => "edit_feed_form"
|
||||
end
|
||||
end
|
||||
|
||||
def createfeed
|
||||
recruit_news_feed = RecruitNewsFeed.new(feed_params)
|
||||
recruit_news_feed.save
|
||||
feeds = RecruitNewsFeed.all.asc(:created_at)
|
||||
render :partial => "feed", :collection => feeds
|
||||
end
|
||||
|
||||
def updatefeed
|
||||
ann_feed = RecruitNewsFeed.find(params[:id])
|
||||
ann_feed.update_attributes(feed_params)
|
||||
ann_feed.save
|
||||
feeds = RecruitNewsFeed.all.asc(:created_at)
|
||||
render :partial => "feed", :collection => feeds
|
||||
end
|
||||
|
||||
def deletefeed
|
||||
ann_feed = RecruitNewsFeed.find(params[:id])
|
||||
ann_feed.destroy
|
||||
feeds = RecruitNewsFeed.all.asc(:created_at)
|
||||
render :partial => "feed", :collection => feeds
|
||||
end
|
||||
|
||||
def new
|
||||
@tags = @module_app.tags
|
||||
@statuses = []
|
||||
@recruit_news = RecruitNews.new
|
||||
@recruit_news.email_sentdate = Time.now
|
||||
@reach_limit = @recruit_news.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 = recruit_news_params
|
||||
recruit_news = RecruitNews.new(bps)
|
||||
if !bps['recruit_news_links_attributes'].nil?
|
||||
bps['recruit_news_links_attributes'].each do |idx,link|
|
||||
bps['recruit_news_links_attributes'].delete(idx.to_s) if link['url'].blank?
|
||||
end
|
||||
end
|
||||
if((!RecruitNewsSetting.first.only_manager_can_edit_status) || (RecruitNewsSetting.first.only_manager_can_edit_status && (@current_user.is_admin? || @current_user.is_manager?(@module_app))) )
|
||||
if bps[:is_top] == "1" && !RecruitNewsSetting.check_limit_for_user(recruit_news.create_user_id, recruit_news.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?
|
||||
# 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(recruit_news_id: recruit_news.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: bps[:title_translations][I18n.locale],note: bps[:subtitle_translations][I18n.locale])
|
||||
# bps[:event_id] = event.id
|
||||
# end
|
||||
# end
|
||||
recruit_news.create_user_id = current_user.id
|
||||
recruit_news.update_user_id = current_user.id
|
||||
if RecruitNewsSetting.is_pro?
|
||||
if user_can_approve?
|
||||
recruit_news.approved = true
|
||||
else
|
||||
send_notification_mail_to_managers(recruit_news,"approval",I18n.locale)
|
||||
end
|
||||
else
|
||||
recruit_news.approved = true
|
||||
end
|
||||
|
||||
recruit_news.save
|
||||
build_email(recruit_news,I18n.locale)
|
||||
Thread.new do
|
||||
recruit_news.notify_feed("create")
|
||||
end
|
||||
redirect_to params['referer_url']
|
||||
end
|
||||
|
||||
def approve_recruit_news
|
||||
id = params[:id]
|
||||
recruit_news = RecruitNews.find(id)
|
||||
if params["approved"] == "true"
|
||||
recruit_news.approved = true
|
||||
recruit_news.rejected = false
|
||||
recruit_news.reapproval = false
|
||||
else
|
||||
recruit_news.rejected = true
|
||||
recruit_news.reapproval = false
|
||||
recruit_news.rejection_reason = params["reason"]
|
||||
send_rejection_email(recruit_news,I18n.locale)
|
||||
end
|
||||
recruit_news.save
|
||||
redirect_to admin_recruit_news_index_path
|
||||
end
|
||||
|
||||
def edit
|
||||
if can_edit_or_delete?(@recruit_news)
|
||||
@reach_limit = @recruit_news.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 = []
|
||||
@recruit_news.email_sentdate = Time.now if @recruit_news.email_sent == false
|
||||
else
|
||||
render_401
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
uid = params[:id].split('-').last
|
||||
recruit_news = RecruitNews.find_by(:uid=>uid)
|
||||
bps = recruit_news_params
|
||||
bps[:tags] = bps[:tags].blank? ? [] : bps[:tags]
|
||||
bps[:email_member_ids] = bps[:email_member_ids].blank? ? [] : bps[:email_member_ids]
|
||||
|
||||
if !bps['recruit_news_links_attributes'].nil?
|
||||
bps['recruit_news_links_attributes'].each do |idx,link|
|
||||
bps['recruit_news_links_attributes'].delete(idx.to_s) if link['url'].blank?
|
||||
end
|
||||
end
|
||||
if((!RecruitNewsSetting.first.only_manager_can_edit_status) || (RecruitNewsSetting.first.only_manager_can_edit_status && (@current_user.is_admin? || @current_user.is_manager?(@module_app))) )
|
||||
if bps[:is_top] == "1" && !RecruitNewsSetting.check_limit_for_user(recruit_news.create_user_id, recruit_news.id)
|
||||
bps[:is_top] = "0"
|
||||
bps[:top_end_date] = nil
|
||||
end
|
||||
else
|
||||
bps[:is_top] = recruit_news.is_top
|
||||
bps[:is_hot] = recruit_news.is_hot
|
||||
bps[:is_hidden] = recruit_news.is_hidden
|
||||
end
|
||||
# if !defined?(Calendar).nil?
|
||||
# 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(recruit_news_id: recruit_news.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: bps[:title_translations][I18n.locale],note: bps[:subtitle_translations][I18n.locale])
|
||||
# bps[:event_id] = event.id
|
||||
# end
|
||||
# end
|
||||
recruit_news.update_attributes(bps)
|
||||
recruit_news.update_user_id = current_user.id
|
||||
if recruit_news.rejected
|
||||
recruit_news.reapproval = true
|
||||
recruit_news.save
|
||||
send_notification_mail_to_managers(recruit_news,"reapproval",I18n.locale)
|
||||
else
|
||||
recruit_news.save
|
||||
end
|
||||
build_email(recruit_news,I18n.locale)
|
||||
Thread.new do
|
||||
recruit_news.notify_feed("update")
|
||||
end
|
||||
now_recruit_news_page = RecruitNews.where(:title.ne => "",:is_preview.in=>[false,nil])
|
||||
.order_by(sort).map(&:id).map.with_index.select{|v,i| v==recruit_news.id}[0][1] rescue nil
|
||||
now_recruit_news_page = now_recruit_news_page.nil? ? 0 : ((now_recruit_news_page+1).to_f/10).ceil
|
||||
redirect_to admin_recruit_news_index_path(:page=>now_recruit_news_page)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@recruit_news.destroy
|
||||
Thread.new do
|
||||
@recruit_news.notify_feed("destroy")
|
||||
end
|
||||
redirect_to "/admin/recruit_news"
|
||||
end
|
||||
|
||||
def delete
|
||||
if params[:ids]
|
||||
RecruitNews.any_in(:uid => params[:ids]).destroy_all
|
||||
Thread.new do
|
||||
RecruitNews.notify_feed_delete(params[:ids])
|
||||
end
|
||||
end
|
||||
redirect_to "/admin/recruit_news"
|
||||
end
|
||||
|
||||
def preview
|
||||
if params['preview_type'].eql?('edit')
|
||||
recruit_news_data = recruit_news_params
|
||||
org_recruit_news = RecruitNews.find(params['recruit_news_id'])
|
||||
recruit_news = org_recruit_news.clone
|
||||
recruit_news.generate_uid
|
||||
recruit_news.recruit_news_files = []
|
||||
recruit_news.recruit_news_links = []
|
||||
if recruit_news_data['image'].blank?
|
||||
recruit_news.image = org_recruit_news.image
|
||||
end
|
||||
|
||||
if !recruit_news_data['recruit_news_files_attributes'].blank?
|
||||
recruit_news_data['recruit_news_files_attributes'].each do |key, recruit_news_file|
|
||||
next if !recruit_news_file['_destroy'].blank?
|
||||
file = nil
|
||||
if recruit_news_file['id'].blank?
|
||||
file = RecruitNewsFile.new(recruit_news_file)
|
||||
file.recruit_news_id = recruit_news.id
|
||||
file.save
|
||||
else
|
||||
org_file = RecruitNewsFile.find(recruit_news_file['id'])
|
||||
file = org_file.clone
|
||||
file.recruit_news_id = recruit_news.id
|
||||
file.file = org_file.file
|
||||
recruit_news_file.delete('id')
|
||||
recruit_news_file.delete('_destroy')
|
||||
file.update_attributes(recruit_news_file)
|
||||
end
|
||||
|
||||
file.save
|
||||
recruit_news.recruit_news_files << file
|
||||
end
|
||||
end
|
||||
|
||||
if !recruit_news_data['recruit_news_links_attributes'].blank?
|
||||
recruit_news_data['recruit_news_links_attributes'].each do |key, recruit_news_link|
|
||||
next if !recruit_news_link['_destroy'].blank?
|
||||
|
||||
if recruit_news_link['id'].blank?
|
||||
link = RecruitNewsLink.new(recruit_news_link)
|
||||
link.recruit_news_id = recruit_news.id
|
||||
else
|
||||
link = RecruitNewsLink.find(recruit_news_link['id']).clone
|
||||
link.recruit_news_id = recruit_news.id
|
||||
recruit_news_link.delete('id')
|
||||
recruit_news_link.delete('_destroy')
|
||||
link.update_attributes(recruit_news_link)
|
||||
end
|
||||
|
||||
link.save
|
||||
recruit_news.recruit_news_links << link
|
||||
end
|
||||
end
|
||||
|
||||
recruit_news_data.delete('recruit_news_files_attributes')
|
||||
recruit_news_data.delete('recruit_news_links_attributes')
|
||||
recruit_news.update_attributes(recruit_news_data)
|
||||
else
|
||||
recruit_news = RecruitNews.new(recruit_news_params)
|
||||
end
|
||||
|
||||
recruit_news.is_preview = true
|
||||
recruit_news.save
|
||||
render :text=>page_for_recruit_news(recruit_news) + "?preview=true"
|
||||
end
|
||||
|
||||
def destroy_preview
|
||||
recruit_news = RecruitNews.find_by(:uid=>params['uid'])
|
||||
if recruit_news.is_preview
|
||||
recruit_news.destroy
|
||||
end
|
||||
render :json=>{'destroy'=>recruit_news.id.to_s}
|
||||
end
|
||||
|
||||
def build_email(recruit_news,locale)
|
||||
if recruit_news.email_sent and !recruit_news.email_addresses.blank?
|
||||
if recruit_news.email.nil?
|
||||
email = Email.new
|
||||
email.save
|
||||
email.deliver rescue nil
|
||||
recruit_news.email_id = email.id
|
||||
recruit_news.save
|
||||
end
|
||||
|
||||
is_sent = recruit_news.email.is_sent
|
||||
is_sent = !params[:resend_mail].eql?("true") if !params[:resend_mail].blank?
|
||||
doc = Nokogiri::HTML(recruit_news.title_translations[locale])
|
||||
title = doc.text.empty? ? 'no content' : doc.text
|
||||
|
||||
recruit_news.email.update_attributes(
|
||||
:create_user=>current_user,
|
||||
:mail_sentdate=>recruit_news.email_sentdate,
|
||||
:module_app=>@module_app,
|
||||
:mail_lang => locale,
|
||||
:mail_to=>recruit_news.email_addresses,
|
||||
:mail_subject=>title,
|
||||
:template=>'recruit_news/email',
|
||||
:template_data=>{
|
||||
"host" => request.host_with_port,
|
||||
"title" => title,
|
||||
"url" => page_for_recruit_news(recruit_news)
|
||||
},
|
||||
:is_sent=>is_sent
|
||||
)
|
||||
recruit_news.email.deliver
|
||||
else
|
||||
recruit_news.email.destroy if !recruit_news.email.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def custom_fields_title
|
||||
@recruit_news_custom_titles = RecruitNewsCustomTitle.get_map
|
||||
end
|
||||
|
||||
def update_custom_title
|
||||
recruit_news_custom_title_params = params.require(:recruit_news_custom_title).permit!
|
||||
recruit_news_custom_title_params.each do |k,recruit_news_custom_title_param|
|
||||
RecruitNewsCustomTitle.find(recruit_news_custom_title_param['id']).update_attributes(recruit_news_custom_title_param)
|
||||
end
|
||||
Thread.new do
|
||||
content = "UNICORN_PID=\"`fuser tmp/pids/unicorn.sock tmp/sockets/unicorn.sock tmp/unicorn.sock` `cat tmp/pids/unicorn.pid `\" && kill -s USR2 $UNICORN_PID ; n=20; while (kill -0 $UNICORN_PID > /dev/null 2>&1) && test $n -ge 0; do printf '.' && sleep 1 && n=$(( $n - 1 )); done ; if test $n -lt 0; then kill -s TERM $UNICORN_PID; sleep 3; bundle exec unicorn_rails -c config/unicorn.rb -D -E #{Rails.env}; else kill -s QUIT $UNICORN_PID; fi"
|
||||
system(content)
|
||||
end
|
||||
redirect_to admin_recruit_news_index_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_settings
|
||||
@recruit_news_setting = RecruitNewsSetting.first rescue nil
|
||||
if @recruit_news_setting.nil?
|
||||
@recruit_news_setting = RecruitNewsSetting.create
|
||||
end
|
||||
end
|
||||
|
||||
def set_recruit_news
|
||||
@recruit_news = RecruitNews.find(params[:id])
|
||||
end
|
||||
|
||||
def recruit_news_params
|
||||
params[:recruit_news][:email_sent] = params[:recruit_news][:email_sent].nil? ? 0 : params[:recruit_news][:email_sent]
|
||||
params.require(:recruit_news).permit!
|
||||
end
|
||||
|
||||
def feed_params
|
||||
params.require(:recruit_news_feed).permit!
|
||||
end
|
||||
|
||||
def settings_params
|
||||
params.require(:recruit_news_setting).permit!
|
||||
end
|
||||
|
||||
def update_enable_manually_sort(setting)
|
||||
if defined?(OrbitHelper::SharedHash) && OrbitHelper::SharedHash
|
||||
OrbitHelper::SharedHash['recruit_news_mod'][:enable_manually_sort] = setting.enable_manually_sort
|
||||
end
|
||||
end
|
||||
|
||||
def update_is_postdate_sort_first(setting)
|
||||
if defined?(OrbitHelper::SharedHash) && OrbitHelper::SharedHash
|
||||
OrbitHelper::SharedHash['recruit_news_mod'][:is_postdate_sort_first] = setting.is_postdate_sort_first
|
||||
feeds_time_field = (RecruitNewsHelper.is_postdate_sort_first ? ['postdate', 'event_date'] : ['event_date', 'postdate'])
|
||||
@module_app.feeds_time_field = feeds_time_field
|
||||
@module_app.save
|
||||
if defined?(Feeds)
|
||||
Feeds::Migrate.sync_module_apps
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
require "rss"
|
||||
class RecruitNewsFeedsController < ApplicationController
|
||||
include Admin::RecruitNewsHelper
|
||||
def feed_add_remote
|
||||
if params[:url].present?
|
||||
uid = params[:uid].to_s
|
||||
recruit_news_feed = RecruitNewsFeed.where(uid: uid).first
|
||||
if !(recruit_news_feed.remote_urls.include?(params[:url]))
|
||||
recruit_news_feed.remote_urls << params[:url]
|
||||
recruit_news_feed.save
|
||||
end
|
||||
end
|
||||
render :json => {success: true}
|
||||
end
|
||||
def feed_remove_remote
|
||||
if params[:url].present?
|
||||
uid = params[:uid].to_s
|
||||
recruit_news_feed = RecruitNewsFeed.where(uid: uid).first
|
||||
if recruit_news_feed.remote_urls.delete(params[:url])
|
||||
recruit_news_feed.save
|
||||
end
|
||||
end
|
||||
render :json => {success: true}
|
||||
end
|
||||
def feed
|
||||
uid = params[:uid].to_s
|
||||
startdt = params[:start].blank? ? nil : params[:start]
|
||||
enddt = params[:end].blank? ? nil : params[:end]
|
||||
dt = params[:date].blank? ? nil : params[:date]
|
||||
feed_cache = RecruitNewsFeedCache.where(uid: uid, start: startdt, end: enddt, date: dt)
|
||||
feed_cache_old = feed_cache.all_of([{:invalid_date.ne=>nil},{:invalid_date.lte => Time.now}]).last
|
||||
feed_cache.all_of([{:invalid_date.ne=>nil},{:invalid_date.lte => Time.now}]).destroy
|
||||
count = feed_cache.count
|
||||
if count > 1
|
||||
feed_cache.limit(count-1).destroy
|
||||
end
|
||||
feed_cache = feed_cache.first
|
||||
anns = ''
|
||||
if feed_cache.nil?
|
||||
anns = RecruitNewsFeed.where(uid: uid).first.generate_one_cache_timeout(startdt: startdt,enddt: enddt,dt: dt,base_url: request.base_url,timeout: 20)
|
||||
anns = (feed_cache_old.content rescue "") if anns.nil?
|
||||
else
|
||||
anns = feed_cache.content
|
||||
end
|
||||
render :json => anns
|
||||
end
|
||||
|
||||
def rssfeed
|
||||
uid = params[:uid].to_s
|
||||
@bf = RecruitNewsFeed.find_by(:uid => uid) rescue nil
|
||||
if !@bf.nil?
|
||||
tags = @bf.tag_ids
|
||||
if !tags.empty?
|
||||
@recruit_news = RecruitNews.can_display_and_sorted.filter_by_tags(tags)
|
||||
else
|
||||
@recruit_news = RecruitNews.can_display_and_sorted
|
||||
end
|
||||
categories = @bf.category_ids
|
||||
if !categories.empty?
|
||||
@recruit_news = @recruit_news.filter_by_categories(categories)
|
||||
end
|
||||
else
|
||||
@recruit_news = []
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html {redirect_to "/xhr/recruit_news/rssfeed/#{@bf.uid}.rss"}
|
||||
format.rss
|
||||
end
|
||||
end
|
||||
|
||||
def feeds
|
||||
feeds = []
|
||||
RecruitNewsFeed.all.each do |bf|
|
||||
feed = {}
|
||||
feed["title_translations"] = bf.title_translations
|
||||
feed["uid"] = bf.uid
|
||||
feed["url"] = "#{request.base_url}/xhr/recruit_news/feed/#{bf.uid}"
|
||||
feed["xml_url"] = "#{request.base_url}/xhr/recruit_news/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
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,129 @@
|
|||
# encoding: utf-8
|
||||
class RecruitNewsModuleController < ApplicationController
|
||||
before_filter :set_I18n
|
||||
|
||||
def get_recruit_news
|
||||
page = Page.where(:module => "recruit_news").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]+".*")
|
||||
recruit_news = RecruitNews.any_of({:title=>keyword},{:subtitle=>keyword},{:text=>keyword})
|
||||
else
|
||||
recruit_news = RecruitNews.all
|
||||
end
|
||||
|
||||
if !params[:category].blank?
|
||||
module_id = ModuleApp.where(:key=>"recruit_news").first.id
|
||||
category = Regexp.new(".*"+params[:category]+".*")
|
||||
category_id = Category.where(:title => category, :module_app_id => module_id).first.id
|
||||
recruit_news = recruit_news.where(:category_id => category_id)
|
||||
else
|
||||
recruit_news = recruit_news
|
||||
end
|
||||
|
||||
recruit_news = recruit_news.where(:is_preview.in=>[false,nil])
|
||||
recruit_news = recruit_news.where(:approved.ne => false , :rejected.ne => true)
|
||||
recruit_news = recruit_news.where(:postdate.lt=>Time.now)
|
||||
recruit_news = recruit_news.desc( :is_top, :postdate).page(page_num).per(per_page)
|
||||
|
||||
recruit_news = recruit_news.collect do |b|
|
||||
image = request.protocol + request.host_with_port + b.image.url rescue nil
|
||||
|
||||
links = b.recruit_news_links.collect do |bl|
|
||||
{
|
||||
"title" => bl.title_translations,
|
||||
"url" => bl.url
|
||||
}
|
||||
end rescue nil
|
||||
|
||||
files = b.recruit_news_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]+".*")
|
||||
recruit_news = RecruitNews.any_of({:title=>keyword},{:subtitle=>keyword},{:text=>keyword})
|
||||
else
|
||||
recruit_news = RecruitNews.all
|
||||
end
|
||||
recruit_news = recruit_news.where(:is_preview.in=>[false,nil])
|
||||
recruit_news = recruit_news.where(:approved.ne => false , :rejected.ne => true)
|
||||
recruit_news = recruit_news.where(:postdate.lt=>Time.now)
|
||||
total_pages = recruit_news.count
|
||||
# End
|
||||
|
||||
render :json => {
|
||||
"recruit_news" => recruit_news,
|
||||
"recruit_news_count" => recruit_news.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,424 @@
|
|||
require "net/http"
|
||||
require "uri"
|
||||
require 'json'
|
||||
|
||||
module Admin::RecruitNewsHelper
|
||||
module FormHelper
|
||||
extend self
|
||||
extend ActionView::Helpers::FormTagHelper
|
||||
extend ActionView::Helpers::FormOptionsHelper
|
||||
extend ActionView::Helpers::DateHelper
|
||||
extend ActionView::Helpers::TagHelper
|
||||
extend ActionView::Helpers::RenderingHelper
|
||||
extend ActionView::Context
|
||||
extend OrbitBasis::RenderAnywhere
|
||||
extend ActionView::Helpers::UrlHelper
|
||||
extend OrbitFormHelper
|
||||
extend Ckeditor::Helpers::FormHelper
|
||||
def available_locales
|
||||
@available_locales = @available_locales || Site.first.in_use_locales || I18n.available_locales
|
||||
end
|
||||
def set_input_name(input_name)
|
||||
@input_name = input_name
|
||||
end
|
||||
|
||||
def get_input_name
|
||||
@input_name.to_s
|
||||
end
|
||||
def create_lang_panel(field)
|
||||
tmp2 = content_tag(:div,:class => 'btn-group', :data=>{:toggle=>"buttons-radio"}) do
|
||||
available_locales.collect do |key|
|
||||
link_entry_ary = ["##{field}","_#{key}"]
|
||||
link_entry = link_entry_ary.join
|
||||
link_to(I18n.t(key),link_entry,:data=>{:toggle=>"tab"},:class=>"btn #{(key == I18n.locale ? "active" : nil)}",:for=>key)
|
||||
end.join.html_safe
|
||||
end
|
||||
end
|
||||
def multiple_lang_tag(index1,type_of_tag,field,value=nil,custom_options={},combine_element='',exteral_options={},sortable=false)
|
||||
if !index1.nil?
|
||||
all_field = (get_input_name + "[#{index1}][#{field}][parant]").gsub(/\[/,'_').gsub(/\]/,'')
|
||||
else
|
||||
all_field = (get_input_name + "[#{field}][parant]").gsub(/\[/,'_').gsub(/\]/,'')
|
||||
end
|
||||
tmp = (available_locales.collect do |locale|
|
||||
active_flag = ((locale == I18n.locale) ? ' in active' : '')
|
||||
content_tag(:div,:class => "tab-content fade#{active_flag}",:id=>"#{all_field}_#{locale}") do
|
||||
value_locale = value[locale.to_s] rescue nil
|
||||
if !index1.nil?
|
||||
self.__send__("#{type_of_tag}_tag","#{get_input_name}[#{index1}][#{field}][#{locale}]",value_locale,custom_options)
|
||||
else
|
||||
self.__send__("#{type_of_tag}_tag","#{get_input_name}[#{field}][#{locale}]",value_locale,custom_options)
|
||||
end
|
||||
end
|
||||
end.join + create_lang_panel(all_field)).html_safe + combine_element
|
||||
|
||||
if sortable
|
||||
if exteral_options['style'].nil?
|
||||
exteral_options['style'] = 'display: flex;align-items: center;flex-wrap: nowrap;'
|
||||
else
|
||||
exteral_options['style'] = exteral_options['style'] + 'display: flex;align-items: center;flex-wrap: nowrap;'
|
||||
end
|
||||
content_tag(:div,{:class => "tab-panel border"}.merge(exteral_options)) do
|
||||
("<i class=\"icons-list-2\" style=\"cursor: grab;font-size: x-large;\"></i>" +content_tag(:div) do
|
||||
tmp
|
||||
end).html_safe
|
||||
end
|
||||
else
|
||||
content_tag(:div,{:class => "tab-panel"}.merge(exteral_options)) do
|
||||
tmp
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.thead(field,center=false,enable_sort=true)
|
||||
sort = field.to_s.include?('.') ? field.to_s.split('.')[1] : field.to_s
|
||||
active = OrbitHelper.params[:sort].eql? sort
|
||||
order = active ? (["asc", "desc"]-[OrbitHelper.params[:order]]).first : "asc"
|
||||
arrow = (order.eql? "desc") ? "<b class='icons-arrow-up-3'></b>" : "<b class='icons-arrow-down-4'></b>"
|
||||
klass = field.eql?(:title) ? "span5" : "span2"
|
||||
th_data = (sort=="preview" || !enable_sort) ? RecruitNewsCustomTitle.get_trans(field) : "<a href='?sort=#{sort}&order=#{order}'>#{RecruitNewsCustomTitle.get_trans(field)} #{active ? arrow : ""}</a>"
|
||||
"<th class='#{klass} #{active ? "active" : ""}' style='#{center ? "text-align:center" : ""}'>#{th_data}</th>".html_safe
|
||||
end
|
||||
|
||||
def page_for_recruit_news(recruit_news)
|
||||
ann_page = nil
|
||||
pages = Page.where(:module=>'recruit_news_mod')
|
||||
|
||||
pages.each do |page|
|
||||
if page.categories.count ==1
|
||||
if page.categories.include?(recruit_news.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?(recruit_news.category.id.to_s)
|
||||
ann_page = page
|
||||
end
|
||||
break if !ann_page.nil?
|
||||
end
|
||||
end
|
||||
|
||||
ann_page = pages.first if ann_page.nil?
|
||||
request.protocol+(request.host_with_port+ann_page.url+'/'+recruit_news.to_param).gsub('//','/') rescue "/"
|
||||
end
|
||||
|
||||
def import_this_recruit_news(row,categories,tags)
|
||||
value = {}
|
||||
anns = RecruitNews.new
|
||||
row.cells.each_with_index do |cell,index|
|
||||
val = cell.nil? ? nil : cell.value
|
||||
next if val.nil? || val == ""
|
||||
case index
|
||||
when 0
|
||||
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
|
||||
anns.tags=new_tags
|
||||
when 2
|
||||
anns.event_date = val
|
||||
when 3
|
||||
anns.postdate = val
|
||||
when 4
|
||||
anns.deadline = val
|
||||
when 5
|
||||
anns.is_top = (val.to_i == 1 ? true : false)
|
||||
when 6
|
||||
anns.is_hot = (val.to_i == 1 ? true : false)
|
||||
when 7
|
||||
anns.is_hidden = (val.to_i == 1 ? true : false)
|
||||
when 8
|
||||
anns.remote_image_url = val
|
||||
when 9
|
||||
value["en"] = val
|
||||
anns.image_description_translations = value.clone
|
||||
when 10
|
||||
value["zh_tw"] = val
|
||||
anns.image_description_translations = value.clone
|
||||
value = {}
|
||||
when 11
|
||||
value["en"] = val
|
||||
anns.title_translations = value.clone
|
||||
when 12
|
||||
value["zh_tw"] = val
|
||||
anns.title_translations = value.clone
|
||||
value = {}
|
||||
when 13
|
||||
value["en"] = val
|
||||
anns.speaker_translations = value.clone
|
||||
when 14
|
||||
value["zh_tw"] = val
|
||||
anns.speaker_translations = value.clone
|
||||
value = {}
|
||||
when 15
|
||||
value["en"] = val
|
||||
anns.host_translations = value.clone
|
||||
when 16
|
||||
value["zh_tw"] = val
|
||||
anns.host_translations = value.clone
|
||||
value = {}
|
||||
when 17
|
||||
value["en"] = val
|
||||
anns.subtitle_translations = value.clone
|
||||
when 18
|
||||
value["zh_tw"] = val
|
||||
anns.subtitle_translations = value.clone
|
||||
value = {}
|
||||
when 19
|
||||
value["en"] = val
|
||||
anns.text_translations = value.clone
|
||||
when 20
|
||||
value["zh_tw"] = val
|
||||
anns.text_translations = value.clone
|
||||
value = {}
|
||||
when 21
|
||||
value["en"] = val
|
||||
anns.notes_translations = value.clone
|
||||
when 22
|
||||
value["zh_tw"] = val
|
||||
anns.notes_translations = value.clone
|
||||
value = {}
|
||||
when 23
|
||||
links = val.split(";") rescue []
|
||||
desc_en = row.cells[24].value.split(";") rescue []
|
||||
desc_zh_tw = row.cells[25].value.split(";") rescue []
|
||||
links.each_with_index do |link,i|
|
||||
bl = RecruitNewsLink.new
|
||||
bl.url = link.strip
|
||||
bl.title_translations = {"en" => desc_en[i], "zh_tw" => desc_zh_tw[i]}
|
||||
bl.recruit_news_id = anns.id
|
||||
bl.save
|
||||
end
|
||||
when 26
|
||||
files = val.split(";") rescue []
|
||||
desc_en = row.cells[27].value.split(";") rescue []
|
||||
desc_zh_tw = row.cells[28].value.split(";") rescue []
|
||||
alt_en = row.cells[29].value.split(";") rescue []
|
||||
alt_zh_tw = row.cells[30].value.split(";") rescue []
|
||||
files.each_with_index do |file, i|
|
||||
bf = RecruitNewsFile.new
|
||||
bf.remote_file_url = file.strip rescue nil
|
||||
bf.title_translations = {"en" => (alt_en[i] rescue ""), "zh_tw" => (alt_zh_tw[i] rescue "")}
|
||||
bf.description_translations = {"en" => (desc_en[i] rescue ""), "zh_tw" => (desc_zh_tw[i] rescue "")}
|
||||
bf.recruit_news_id = anns.id
|
||||
bf.save
|
||||
end
|
||||
when 31
|
||||
value["en"] = val
|
||||
anns.place_translations = value.clone
|
||||
when 32
|
||||
value["zh_tw"] = val
|
||||
anns.place_translations = value.clone
|
||||
value = {}
|
||||
when 33
|
||||
anns.event_end_date = val
|
||||
when 34
|
||||
carousel_images = val.split(";") rescue []
|
||||
desc_en = row.cells[35].value.split(";") rescue []
|
||||
desc_zh_tw = row.cells[36].value.split(";") rescue []
|
||||
carousel_images.each_with_index do |image, i|
|
||||
bc = EventCarouselImage.new
|
||||
bc.remote_file_url = image.strip rescue nil
|
||||
bc.description_translations = {"en" => (desc_en[i] rescue ""), "zh_tw" => (desc_zh_tw[i] rescue "")}
|
||||
bc.recruit_news_id = anns.id
|
||||
bc.save
|
||||
end
|
||||
end
|
||||
end
|
||||
anns.create_user_id = current_user.id.to_s
|
||||
anns.update_user_id = current_user.id.to_s
|
||||
anns.approved = true
|
||||
anns.save
|
||||
end
|
||||
|
||||
def send_rejection_email(recruit_news,locale)
|
||||
user = User.find(recruit_news.create_user_id) rescue nil
|
||||
if !user.nil?
|
||||
email = user.member_profile.email
|
||||
if !email.nil? && email != ""
|
||||
url = "http://#{request.host_with_port}/admin/recruit_news/#{recruit_news.id}/edit"
|
||||
datatosend = "<h3>Hello #{user.name},</h3><p>#{current_user.name} #{t("recruit_news.rejected_recruit_news")} : #{recruit_news.rejection_reason} <a href='#{url}'> #{t("recruit_news.click_here_to_see")}</a></p>"
|
||||
mail = Email.new(:mail_to => email, :mail_subject => "RecruitNews rejected公告未通過 : #{recruit_news.title_translations[locale]}.", :template => "email/recruit_news_email.html.erb", :template_data => {"html" => datatosend})
|
||||
mail.save
|
||||
mail.deliver rescue nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def send_notification_mail_to_managers(recruit_news, type, locale)
|
||||
users = []
|
||||
if @recruit_news_setting.email_to.include?("managers")
|
||||
authorizations = Authorization.where(:module_app_id => @module_app.id)
|
||||
users = authorizations.collect do |auth|
|
||||
auth.user
|
||||
end
|
||||
end
|
||||
if @recruit_news_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 @recruit_news_setting.email_to.include?("approvers")
|
||||
approvers = User.find(@recruit_news_setting.approvers).to_a rescue []
|
||||
auths = Authorization.where(:category_id => recruit_news.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, recruit_news, type, locale)
|
||||
# sleep(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def send_email(name, useremail, recruit_news, type, locale)
|
||||
url = "http://#{request.host_with_port}/admin/recruit_news?url=#{page_for_recruit_news(recruit_news).sub("http://" + request.host_with_port, "")}&id=#{recruit_news.id}"
|
||||
|
||||
case type
|
||||
when "approval"
|
||||
datatosend = "<h3>#{t("recruit_news.approval_mail_hi", :name => name)},</h3><p>#{t("recruit_news.submitted_new_recruit_news", :poster => current_user.name)}<br /><br />#{t("recruit_news.approval_recruit_news_title")} : #{recruit_news.title_translations[locale]} <br /> #{t("recruit_news.click_here_to_see")} : <a href='#{url}'> #{url} </a></p>"
|
||||
when "reapproval"
|
||||
datatosend = "<h3>#{t("recruit_news.approval_mail_hi", :name => name)},</h3><p>#{t("recruit_news.updated_recruit_news", :poster => current_user.name)}<br /><br />#{t("recruit_news.approval_recruit_news_title")} : #{recruit_news.title_translations[locale]} <br /> #{t("recruit_news.click_here_to_see")} : <a href='#{url}'> #{url} </a></p>"
|
||||
end
|
||||
email = Email.new(:mail_to => useremail, :mail_subject => " #{t("recruit_news.recruit_news_subject")} : #{recruit_news.title_translations[locale]}.", :template => "email/recruit_news_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?
|
||||
recruit_news = []
|
||||
xml.xpath("//channel").xpath("//item").each do |anns|
|
||||
recruit_news << {
|
||||
:title => (anns>"title").text,
|
||||
:category => (anns>"category").text,
|
||||
:postdate => (anns>"pubDate").text,
|
||||
:text => (anns>"description").text,
|
||||
:rss2_sn => (anns>"link").text.split("=").last
|
||||
}
|
||||
end
|
||||
recruit_news.each do |anns|
|
||||
ma = ModuleApp.where(:key => "recruit_news").first
|
||||
cat = Category.where(:title => anns[:category]).first rescue nil
|
||||
if cat.nil?
|
||||
cat = Category.create(:title_translations => {"en" => anns[:category], "zh_tw" => anns[:category]}, :module_app_id => ma.id)
|
||||
end
|
||||
ann = RecruitNews.where(:rss2_sn => anns[:rss2_sn]).first rescue nil
|
||||
if ann.nil?
|
||||
ann = RecruitNews.new(:title_translations => {"en" => "", "zh_tw" => anns[:title]}, :postdate => anns[:postdate], :subtitle_translations => {"en" => "", "zh_tw" => anns[:title]}, :text_translations => {"en" => "", "zh_tw" => anns[:text]}, :rss2_sn => anns[:rss2_sn], :category_id => cat.id, :approved => true, :create_user_id => current_user.id)
|
||||
else
|
||||
ann.update_attributes(:title_translations => {"en" => "", "zh_tw" => anns[:title]}, :postdate => anns[:postdate], :subtitle_translations => {"en" => "", "zh_tw" => anns[:title]}, :text_translations => {"en" => "", "zh_tw" => 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 = RecruitNews.where(:rss2_sn => itme.xpath('wp:post_id').text ).first rescue nil
|
||||
if bu.nil?
|
||||
bu = RecruitNews.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?(anns=nil)
|
||||
can_approve = false
|
||||
setting = RecruitNewsSetting.first
|
||||
case @access_level
|
||||
when "admin"
|
||||
can_approve = true
|
||||
when "manager"
|
||||
can_approve = true
|
||||
else
|
||||
can_approve = false
|
||||
end
|
||||
if !can_approve
|
||||
if !anns.nil?
|
||||
if setting.approvers.include?(current_user.id.to_s)
|
||||
if (current_user.approved_categories_for_module(@module_app).include?(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,599 @@
|
|||
module RecruitNewsHelper
|
||||
extend self
|
||||
|
||||
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.recruit_news_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.recruit_news_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 == "" ? "recruit_news 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
|
||||
event_time_formated = a.event_time_formated
|
||||
{
|
||||
"recruit_news_links" => links,
|
||||
"recruit_news_files" => files,
|
||||
"title" => a.title,
|
||||
"speaker-css" => (a.speaker.blank? ? "display: none;" : ""),
|
||||
"host-css" => (a.host.blank? ? "display: none;" : ""),
|
||||
"place-css" => (a.place.blank? ? "display: none;" : ""),
|
||||
"event-time-css" => (event_time_formated.blank? ? "display: none;" : ""),
|
||||
"notes-css" => (a.notes.blank? ? "display: none;" : ""),
|
||||
"event-time-formated" => event_time_formated,
|
||||
"speaker" => a.speaker,
|
||||
"place" => a.place,
|
||||
"host" => a.host,
|
||||
"notes" => a.notes,
|
||||
"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" => event_time_formated,
|
||||
"event_start_date" => a.event_date_frontend,
|
||||
"event_end_date" => a.event_end_date_frontend,
|
||||
"event_date" => event_time_formated,
|
||||
"author" => author,
|
||||
"link_to_show" => link_to_show,
|
||||
"target" => target,
|
||||
"img_src" => image_url || "/assets/announcement-default.jpg",
|
||||
"img_description" => desc
|
||||
}
|
||||
end
|
||||
def get_feed_annc(type,site_source,locale,categories=nil,max_len=nil,sort_maps=nil,extra_match_cond=nil)
|
||||
ma_key = 'recruit_news_mod'
|
||||
if categories.nil?
|
||||
if type == "index"
|
||||
categories = Array(OrbitHelper.page_categories)
|
||||
elsif type == "widget"
|
||||
categories = Array(OrbitHelper.widget_categories)
|
||||
else
|
||||
categories = []
|
||||
end
|
||||
end
|
||||
categories = ["all"] if categories.length==0
|
||||
data = SiteFeedAnnc.get_feed_cache(
|
||||
ma_key,
|
||||
categories,
|
||||
site_source,
|
||||
locale,
|
||||
type=='widget',
|
||||
max_len,
|
||||
sort_maps,
|
||||
extra_match_cond
|
||||
)
|
||||
data
|
||||
end
|
||||
def get_feed_recruit_news(type,site_source=nil,categories=nil,max_len=nil,extra_match_cond=[])
|
||||
locale = OrbitHelper.get_site_locale.to_s
|
||||
feeds = []
|
||||
feeds_count = 0
|
||||
if !(defined? SiteFeedAnnc).nil?
|
||||
sort_maps = nil
|
||||
if @show_today_data_first
|
||||
sort_maps = {event_date: :asc, is_top: :desc, postdate: :asc, id: :asc}
|
||||
else
|
||||
sort_maps = {is_top: :desc}
|
||||
if is_postdate_sort_first
|
||||
sort_maps = sort_maps.merge({postdate: :desc, event_date: :desc, id: :desc})
|
||||
else
|
||||
sort_maps = sort_maps.merge({event_date: :desc, postdate: :desc, id: :desc})
|
||||
end
|
||||
end
|
||||
match_cond = {
|
||||
"is_hidden" => {"$ne" => true},
|
||||
"$and" => [
|
||||
{"postdate" => {"$lte"=> Time.now}},
|
||||
{
|
||||
"$or" => [
|
||||
{"deadline" => {"$gte"=> Time.now}},
|
||||
{"deadline" => nil}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title" => {"$gt"=>""}
|
||||
}
|
||||
if !extra_match_cond.empty?
|
||||
match_cond["$and"] += extra_match_cond
|
||||
end
|
||||
if @show_today_data_first
|
||||
match_cond["event_date"] = {"$gte" => Date.today.to_time}
|
||||
end
|
||||
feeds, feeds_count = get_feed_annc(type,site_source,locale,categories,max_len,sort_maps,match_cond)
|
||||
end
|
||||
return feeds, feeds_count
|
||||
end
|
||||
|
||||
def get_sorted_recruit_news(data_count=nil)
|
||||
params = OrbitHelper.params
|
||||
locale = OrbitHelper.get_site_locale.to_s
|
||||
page_number = OrbitHelper.page_number.to_i
|
||||
page_number = 1 if page_number == 0
|
||||
page_data_count = data_count || OrbitHelper.page_data_count.to_i
|
||||
feeds_anns = []
|
||||
if @type == "show_widget"
|
||||
tags = @tags
|
||||
categories = @categories
|
||||
else
|
||||
page = OrbitHelper.page
|
||||
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.blank?
|
||||
tags = ["all"]
|
||||
end
|
||||
|
||||
module_app = ModuleApp.where(key: 'recruit_news_mod').first
|
||||
@enable_search_flag = false
|
||||
@show_option_items = nil
|
||||
@show_today_data_first = false
|
||||
if module_app && page.respond_to?(:select_option_items)
|
||||
@show_option_items = module_app.show_option_items
|
||||
if !@show_option_items.nil?
|
||||
page.select_option_items.each do |select_option_item|
|
||||
value = YAML.load(select_option_item.value)[I18n.locale]
|
||||
case select_option_item.field_name
|
||||
when @show_option_items.keys[1].to_s
|
||||
if value == I18n.t('yes_')
|
||||
@enable_search_flag = true
|
||||
end
|
||||
when @show_option_items.keys[3].to_s
|
||||
if value == I18n.t('yes_')
|
||||
@show_today_data_first = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if @enable_search_flag
|
||||
if categories.include? 'all'
|
||||
@categories = module_app.categories
|
||||
else
|
||||
cat_maps = Category.where(:id.in => categories).collect{|cat| [cat.id.to_s, cat]}.to_h
|
||||
@categories = categories.map{|v| cat_maps[v.to_s]}.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
recruit_news_list = []
|
||||
recruit_news = []
|
||||
feeds_count = 0
|
||||
extra_match_cond = []
|
||||
if !params[:keywords].blank?
|
||||
extra_match_cond << {
|
||||
"title_plain_text" => OrbitHelper.get_keyword_regex(params[:keywords])
|
||||
}
|
||||
end
|
||||
if !params[:stime].blank?
|
||||
stime = OrbitHelper.get_time_from_str(params[:stime])
|
||||
extra_match_cond << {
|
||||
"event_date" => {"$gte" => stime}
|
||||
}
|
||||
end
|
||||
if !params[:etime].blank?
|
||||
etime = OrbitHelper.get_time_from_str(params[:etime]) + 1.days
|
||||
extra_match_cond << {
|
||||
"event_date" => {"$lt" => etime}
|
||||
}
|
||||
end
|
||||
if !extra_match_cond.empty?
|
||||
recruit_news = recruit_news.and(extra_match_cond)
|
||||
end
|
||||
if !params["source"].present?
|
||||
recruit_news = @show_today_data_first ?
|
||||
RecruitNews.can_display_and_sorted_according_today :
|
||||
RecruitNews.can_display_and_sorted
|
||||
if params["orbithashtag"].present?
|
||||
recruit_news = recruit_news
|
||||
.filter_by_categories(categories, false).filter_by_hashtag(OrbitHelper.page_hashtag_id)
|
||||
.where(:title.nin => ["",nil])
|
||||
else
|
||||
recruit_news = recruit_news
|
||||
.filter_by_categories(categories, false).filter_by_tags(tags)
|
||||
.where(:title.nin => ["",nil])
|
||||
end
|
||||
if @type == "show_widget"
|
||||
if !params[:uids].blank?
|
||||
member_profile = MemberProfile.any_in(:uid=>params[:uids])
|
||||
user_ids = member_profile.map{|m| m.user.id rescue nil}.select{|id| !id.nil?}
|
||||
recruit_news = recruit_news.where(:create_user_id.in=>user_ids)
|
||||
end
|
||||
end
|
||||
recruit_news = recruit_news.limit(page_number*page_data_count)
|
||||
recruit_news_list = recruit_news.to_a
|
||||
if !(defined? SiteFeed).nil? && @type != "show_widget"
|
||||
feeds_anns, feeds_count = get_feed_recruit_news("index",nil,nil,page_number*page_data_count, extra_match_cond)
|
||||
end
|
||||
elsif @type != "show_widget"
|
||||
feeds_anns, feeds_count = get_feed_recruit_news("index",params["source"],nil,page_number*page_data_count, extra_match_cond)
|
||||
end
|
||||
if !feeds_anns.blank?
|
||||
top_anns = recruit_news_list.select{|v| v.is_top} + feeds_anns.select{|v| v['is_top']}
|
||||
rest_all_anns = recruit_news_list.select{|v| !v.is_top} + feeds_anns.select{|v| v['is_top'] != true}
|
||||
all_filter = sort_recruit_news(top_anns) + sort_recruit_news(rest_all_anns)
|
||||
else
|
||||
all_filter = recruit_news_list
|
||||
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 = recruit_news.count + feeds_count
|
||||
total_pages = page_data_count == 0 ? 1 : (annc_count.to_f / page_data_count).ceil
|
||||
[sorted,total_pages]
|
||||
end
|
||||
|
||||
def sort_recruit_news(recruit_news_list)
|
||||
if @show_today_data_first || !is_postdate_sort_first
|
||||
if enable_manually_sort
|
||||
recruit_news_list = recruit_news_list.sort_by { |recruit_news|
|
||||
tmp1 = recruit_news["event_date"].blank?
|
||||
tmp2 = recruit_news["postdate"].blank?
|
||||
[
|
||||
(@show_today_data_first ? recruit_news['sort_number'].to_i : -recruit_news['sort_number'].to_i),
|
||||
tmp1 ? 0 : 1, tmp1 ? nil : recruit_news["event_date"].to_time,
|
||||
tmp2 ? 0 : 1, tmp2 ? nil : recruit_news["postdate"].to_time
|
||||
]
|
||||
}
|
||||
else
|
||||
recruit_news_list = recruit_news_list.sort_by { |recruit_news|
|
||||
tmp1 = recruit_news["event_date"].blank?
|
||||
tmp2 = recruit_news["postdate"].blank?
|
||||
[
|
||||
tmp1 ? 0 : 1, tmp1 ? nil : recruit_news["event_date"].to_time,
|
||||
tmp2 ? 0 : 1, tmp2 ? nil : recruit_news["postdate"].to_time
|
||||
]
|
||||
}
|
||||
end
|
||||
if !@show_today_data_first
|
||||
recruit_news_list = recruit_news_list.reverse
|
||||
end
|
||||
else
|
||||
if enable_manually_sort
|
||||
recruit_news_list = recruit_news_list.sort_by { |recruit_news|
|
||||
tmp1 = recruit_news["event_date"].blank?
|
||||
tmp2 = recruit_news["postdate"].blank?
|
||||
[
|
||||
-a['sort_number'].to_i,
|
||||
tmp2 ? 0 : 1, tmp2 ? nil : recruit_news["postdate"].to_time,
|
||||
tmp1 ? 0 : 1, tmp1 ? nil : recruit_news["event_date"].to_time
|
||||
]
|
||||
}.reverse
|
||||
else
|
||||
recruit_news_list = recruit_news_list.sort_by { |recruit_news|
|
||||
tmp1 = recruit_news["event_date"].blank?
|
||||
tmp2 = recruit_news["postdate"].blank?
|
||||
[
|
||||
tmp2 ? 0 : 1, tmp2 ? nil : recruit_news["postdate"].to_time,
|
||||
tmp1 ? 0 : 1, tmp1 ? nil : recruit_news["event_date"].to_time
|
||||
]
|
||||
}.reverse
|
||||
end
|
||||
end
|
||||
return recruit_news_list
|
||||
end
|
||||
|
||||
def render_view_for_recruit_news(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 = File.basename(overridehtml.nil? ? params[:layout_type] : overridehtml)
|
||||
f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', 'recruit_news_mod', "#{filename}.html.erb")
|
||||
if !File.exist?(f)
|
||||
f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', 'recruit_news_mod', "index.html.erb")
|
||||
if !File.exist?(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 = RecruitNewsController.new
|
||||
begin
|
||||
data = @data# rescue nil
|
||||
rescue Exception => e
|
||||
write_debug_file(e,'recruit_news_mod',@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', 'recruit_news_mod', "#{filename}.html.erb")
|
||||
if File.exist?(f)
|
||||
file = File.open(f)
|
||||
doc = Nokogiri::HTML(file, nil, "UTF-8")
|
||||
file.close
|
||||
controller = RecruitNewsController.new
|
||||
begin
|
||||
data = @data# rescue nil
|
||||
rescue Exception => e
|
||||
write_debug_file(e,'recruit_news_mod',@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 = 'recruit_news'
|
||||
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-recruit_news__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.exist?(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
|
||||
def render_ad_banner(event_carousel_images,data)
|
||||
("<div class=\"carousel_images\">
|
||||
<div class=\"w-ba-banner ba-banner-widget-1\">
|
||||
<div class=\"w-ba-banner__wrap cycle-slideshow\"
|
||||
data-list=\"event_carousel_images\"
|
||||
data-level=\"0\"
|
||||
data-cycle-slides=\".event_carousel_slide\"
|
||||
data-cycle-log=\"false\"
|
||||
data-cycle-auto-height=\"0\"
|
||||
data-cycle-speed=\"300\"
|
||||
data-cycle-timeout=\"5000\"
|
||||
data-cycle-fx=\"fade\"
|
||||
data-pager-active-class=\"active-slide\"
|
||||
data-cycle-swipe=true
|
||||
data-cycle-swipe-fx=\"scrollHorz\"
|
||||
>" +
|
||||
event_carousel_images.collect do |e|
|
||||
"<div class=\"w-ba-banner__slide event_carousel_slide\"
|
||||
data-cycle-title=\"#{e['description_text']}\"
|
||||
>
|
||||
<img class=\"w-ba-banner__image banner-responsive\" src=\"#{e['src']}\" alt=\"#{e['description_text']}\">
|
||||
<div class=\"ad-overlay w-ad-banner__overlay event_carousel__overlay\">
|
||||
<p><strong class=\"carousel__description\">#{e['description']}</strong></p>
|
||||
</div>
|
||||
<div class=\"transitionfade\"></div>
|
||||
</div>"
|
||||
end.join+
|
||||
"</div>
|
||||
<ul class=\"controlplay\"><a class=\"resume-slide\" title = \"#{data['resume_btn_title']}\"><i></i></a><a class=\"pause-slide\" title = \"#{data['pause_btn_title']}\"><i></i></a></ul>
|
||||
<ul class=\"button-mid\">
|
||||
<i class=\"fa fa-angle-left prev-button\" aria-hidden=\"true\" title = \"#{data['prev_btn_title']}\"></i>
|
||||
<i class=\"fa fa-angle-right next-button\" aria-hidden=\"true\" title = \"#{data['next_btn_title']}\"></i>
|
||||
</ul>
|
||||
</div>
|
||||
<div style=\"position: relative;\">
|
||||
<h4><span class=\"active_slide\">1</span>/#{data['carousel_count']}</h4>
|
||||
<ul class=\"carousel_images_slide w-annc__list row list-unstyled\" data-level=\"0\" data-list=\"event_carousel_images\">" +
|
||||
event_carousel_images.collect do |e|
|
||||
"<li class=\"carousel_img_item col-sm-3\">
|
||||
<div class=\"carousel_img-wrap\">
|
||||
<img class=\"carousel_img\" src=\"#{e['src']}\" alt=\"#{e['description_text']}\">
|
||||
</div>
|
||||
</li>"
|
||||
end.join +
|
||||
"</ul>
|
||||
<ul class=\"button-mid\">
|
||||
<i class=\"fa fa-angle-left prev-button prev_img\" aria-hidden=\"true\" title = \"#{data['prev_btn_title']}\"></i>
|
||||
<i class=\"fa fa-angle-right next-button next_img\" aria-hidden=\"true\" title = \"#{data['next_btn_title']}\"></i>
|
||||
</ul>
|
||||
</div>
|
||||
</div>").html_safe
|
||||
end
|
||||
|
||||
def 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 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 enable_manually_sort
|
||||
if defined?(OrbitHelper::SharedHash) && OrbitHelper::SharedHash
|
||||
OrbitHelper::SharedHash['recruit_news_mod'][:enable_manually_sort]
|
||||
else
|
||||
RecruitNewsSetting.first.enable_manually_sort rescue false
|
||||
end
|
||||
end
|
||||
|
||||
def is_postdate_sort_first
|
||||
if defined?(OrbitHelper::SharedHash) && OrbitHelper::SharedHash
|
||||
OrbitHelper::SharedHash['recruit_news_mod'][:is_postdate_sort_first]
|
||||
else
|
||||
RecruitNewsSetting.first.is_postdate_sort_first rescue false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# encoding: utf-8
|
||||
class EventCarouselImage
|
||||
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
mount_uploader :file, AssetUploader
|
||||
|
||||
field :description, localize: true
|
||||
|
||||
belongs_to :recruit_news
|
||||
def description_text
|
||||
Nokogiri::HTML(self.description.to_s).css("body").text() rescue ""
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,658 @@
|
|||
class RecruitNews
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
include OrbitModel::Status
|
||||
include OrbitModel::Impression
|
||||
# encoding: utf-8
|
||||
include OrbitTag::Taggable
|
||||
include OrbitHashtag::Hashtaggable
|
||||
include OrbitCategory::Categorizable
|
||||
include Slug
|
||||
require 'recruit_news_mod/cache'
|
||||
include RecruitNewsMod::Cache
|
||||
attr_accessor :org_tag_ids, :org_category_id
|
||||
def tags=(ids)
|
||||
self.org_tag_ids = self.tag_ids
|
||||
super(ids)
|
||||
end
|
||||
def category=(cat)
|
||||
self.org_category_id = self.category_id
|
||||
super(cat)
|
||||
end
|
||||
def tag_ids=(ids)
|
||||
self.org_tag_ids = self.tag_ids
|
||||
super(ids)
|
||||
end
|
||||
def category_id=(cat_id)
|
||||
self.org_category_id = self.category_id
|
||||
super(cat_id)
|
||||
end
|
||||
def tags=(ids)
|
||||
self.org_tag_ids = self.tag_ids
|
||||
super(ids)
|
||||
end
|
||||
def []=(index,value)
|
||||
if index.to_s=='tags' || index.to_s=='tag_ids'
|
||||
self.org_tag_ids = self.tag_ids
|
||||
elsif index.to_s=='category' || index.to_s=='category_id'
|
||||
self.org_category_id = self.category_id
|
||||
end
|
||||
super(index,value)
|
||||
end
|
||||
SubPart.class_eval { include RecruitNewsMod::Cache }
|
||||
Page.class_eval { include RecruitNewsMod::Cache }
|
||||
before_destroy do
|
||||
RecruitNewsCache.all.destroy
|
||||
end
|
||||
Week_day_trans = {:en=>["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
|
||||
:zh_tw=>["(日)","(一)","(二)","(三)","(四)","(五)","(六)"]}
|
||||
field :event_date_use_default_setting, type: Boolean, default: true
|
||||
field :including_day_of_the_week, type: Boolean, default: true
|
||||
field :including_time, type: Boolean, default: true
|
||||
field :hour_clock_24, type: Boolean, default: true
|
||||
field :is_edit, type: Boolean, default: false #use to check whether the preview record changed
|
||||
field :copy_id
|
||||
field :custom_carousel_image_type, :type => Integer, :default => 0 # 0: default, 1: carousel, 2: album
|
||||
field :custom_carousel_image_width, type: String, default: ""
|
||||
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 :all_day,type: Boolean,default: false #old field
|
||||
field :calendar_type_id
|
||||
field :event_id
|
||||
field :place, type: String, localize: true
|
||||
field :title, as: :slug_title, type: String, localize: true
|
||||
field :title_plain_text, type: String, localize: true
|
||||
field :speaker, type: String, localize: true
|
||||
field :host, type: String, localize: true
|
||||
field :subtitle, localize: true
|
||||
field :text, localize: true, default: ''
|
||||
field :notes, localize: true
|
||||
field :create_user_id
|
||||
field :update_user_id
|
||||
field :public, :type => Boolean, :default => true
|
||||
field :event_date , :type => DateTime, :default => Time.now
|
||||
field :event_end_date , :type => DateTime
|
||||
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 :other_member_profiles, :type => Array, :default => []
|
||||
|
||||
mount_uploader :image, ImageUploader
|
||||
|
||||
has_many :recruit_news_links, :autosave => true, :dependent => :destroy
|
||||
has_many :recruit_news_files, :autosave => true, :dependent => :destroy
|
||||
has_many :event_carousel_images, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :recruit_news_files, :allow_destroy => true
|
||||
accepts_nested_attributes_for :recruit_news_links, :allow_destroy => true
|
||||
accepts_nested_attributes_for :event_carousel_images, :allow_destroy => true
|
||||
before_destroy :destroy_email
|
||||
|
||||
scope :open_in_future, ->{where(:is_hidden.ne=>true,:is_preview.ne => true,:postdate.gt=>Time.now).order(postdate: :asc)}
|
||||
scope :can_display_and_sorted, ->{
|
||||
is_approved_and_show
|
||||
.valid_time_range
|
||||
.order(
|
||||
RecruitNewsHelper.is_postdate_sort_first ?
|
||||
{postdate: :desc, event_date: :desc, id: :desc} :
|
||||
{event_date: :desc, postdate: :desc, id: :desc}
|
||||
)
|
||||
}
|
||||
scope :can_display_and_sorted_according_today, ->{
|
||||
is_approved_and_show
|
||||
.order(event_date: :asc).valid_time_range.order({postdate: :asc, id: :asc}).where(:event_date.gte => Date.today.to_time)
|
||||
}
|
||||
scope :valid_time_range, ->{
|
||||
and_any_of([
|
||||
{"postdate"=>{"$lte"=> Time.now}, "deadline"=>{"$gte"=> Time.now}},
|
||||
{"postdate"=>{"$lte"=> Time.now}, "deadline"=>nil}
|
||||
])
|
||||
.order(
|
||||
RecruitNewsHelper.enable_manually_sort ?
|
||||
{is_top: :desc, sort_number: :asc} :
|
||||
{is_top: :desc}
|
||||
)
|
||||
}
|
||||
scope :is_approved, ->{where(:approved => true)}
|
||||
scope :is_approved_and_show, ->{where(:approved => true,:is_hidden.ne=>true,:is_preview.ne => true)}
|
||||
scope :filter_cats_and_tags, ->(cats,tags) {filter_by_widget_categories(cats,false).filter_by_tags(tags)}
|
||||
before_create :set_expire
|
||||
before_save :check_limit
|
||||
before_save do
|
||||
if @is_hidden_changed.nil? || @is_hidden_changed != true
|
||||
@is_hidden_changed = self.is_hidden_changed?
|
||||
end
|
||||
if self.is_top_changed? && !self.is_top
|
||||
self.sort_number = nil
|
||||
end
|
||||
self.migrate_title_plain_text
|
||||
end
|
||||
index({postdate: 1}, { unique: false, background: true })
|
||||
index({is_top: -1, postdate: -1, event_date: -1, _id: -1}, { unique: false, background: true })
|
||||
index({is_top: -1, event_date: 1, postdate: -1, _id: -1}, { unique: false, background: true })
|
||||
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, postdate: -1, event_date: -1, _id: -1, deadline: -1}, { unique: false, background: true })
|
||||
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, event_date: 1, postdate: -1, event_date: -1, _id: -1, deadline: -1}, { unique: false, background: true })
|
||||
if RecruitNewsSetting.pluck(:enable_manually_sort).first == true
|
||||
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, sort_number: 1, postdate: -1, event_date: -1, _id: -1, deadline: -1}, { unique: false, background: true })
|
||||
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, sort_number: 1, event_date: 1, postdate: -1, _id: -1, deadline: -1}, { unique: false, background: true })
|
||||
end
|
||||
field :sort_number, type: Integer
|
||||
def get_org_model
|
||||
if self.is_preview
|
||||
org_model = nil
|
||||
if self.copy_id
|
||||
org_model = self.class.find(self.copy_id) rescue nil
|
||||
else
|
||||
org_model = self.class.where(:title=>self.title,:is_preview.ne=>true).desc(:updated_at).first
|
||||
end
|
||||
org_model.nil? ? self : org_model
|
||||
else
|
||||
self
|
||||
end
|
||||
end
|
||||
def date_parse_format
|
||||
#all_day ? '%Y-%m-%d' : '%Y-%m-%d %H:%M'
|
||||
event_date_format
|
||||
end
|
||||
def get_weekday(w)
|
||||
trans = self.class::Week_day_trans
|
||||
if trans.keys.include?(I18n.locale)
|
||||
trans[I18n.locale][w]
|
||||
else
|
||||
trans[:en][w]
|
||||
end
|
||||
end
|
||||
def event_date_format
|
||||
@event_date_format ||= (self.event_date_use_default_setting ? RecruitNewsSetting.event_date_default_format : self.event_date_custom_format)
|
||||
end
|
||||
def event_date_custom_format
|
||||
datetime_format = "%Y-%m-%d"
|
||||
if self.including_day_of_the_week
|
||||
datetime_format += " %a"
|
||||
end
|
||||
if self.including_time
|
||||
if self.hour_clock_24
|
||||
datetime_format += " %H:%M"
|
||||
else
|
||||
datetime_format += " %I:%M %P"
|
||||
end
|
||||
end
|
||||
datetime_format
|
||||
end
|
||||
def custom_strftime(dt, datetime_format)
|
||||
if dt
|
||||
dt.strftime(datetime_format.sub("%a","%%a")).sub("%a",get_weekday(dt.wday))
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
def event_time_formated_for_frontend
|
||||
st,ed = self.event_time_formated.split("~")
|
||||
if st.nil?
|
||||
st = ""
|
||||
else
|
||||
st = "<span class=\"start_date\">#{st}</span>"
|
||||
end
|
||||
if ed.nil?
|
||||
st
|
||||
else
|
||||
ed = "<span class=\"start_date\">#{ed}</span>"
|
||||
"#{st} ~ #{ed}"
|
||||
end
|
||||
end
|
||||
def event_date_frontend
|
||||
s = self.event_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
|
||||
if s.blank?
|
||||
""
|
||||
else
|
||||
parse_format = self.date_parse_format
|
||||
custom_strftime(s, self.date_parse_format)
|
||||
end
|
||||
end
|
||||
def event_end_date_frontend
|
||||
e = self.event_end_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
|
||||
if e.blank?
|
||||
""
|
||||
else
|
||||
parse_format = self.date_parse_format
|
||||
custom_strftime(e, self.date_parse_format)
|
||||
end
|
||||
end
|
||||
def event_time_formated
|
||||
s = self.event_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
|
||||
e = self.event_end_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
|
||||
if s.blank? && e.blank?
|
||||
""
|
||||
elsif e.blank?
|
||||
custom_strftime(s, self.date_parse_format)
|
||||
elsif s.blank?
|
||||
"~ " + custom_strftime(e, self.date_parse_format)
|
||||
else
|
||||
parse_format = self.date_parse_format
|
||||
if s.to_date == e.to_date
|
||||
parse_format_arr = parse_format.split(/(%d %a|%d) /)
|
||||
if parse_format_arr.count > 1
|
||||
parse_format_arr = parse_format_arr[0..-2].join(""), parse_format_arr[-1]
|
||||
end
|
||||
date_str = custom_strftime(s, parse_format_arr[0])
|
||||
s_time = s.strftime(parse_format_arr[1].to_s)
|
||||
e_time = e.strftime(parse_format_arr[1].to_s)
|
||||
if e_time.present?
|
||||
if s_time != e_time
|
||||
"#{date_str} #{s_time} ~ #{e_time}"
|
||||
else
|
||||
"#{date_str} #{s_time}"
|
||||
end
|
||||
else
|
||||
date_str
|
||||
end
|
||||
else
|
||||
custom_strftime(s, self.date_parse_format) + " ~ " + custom_strftime(e, self.date_parse_format)
|
||||
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|
|
||||
RecruitNewsSetting.first.recruit_news_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 <= self.class.where(:is_preview.ne=>true,: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] && !self.class.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 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 get_other_member_profiles_names_for_frontend
|
||||
MemberProfile.find(self.other_member_profiles).map{|m,n| {"name" => m.name}} 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 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("announcement.status.top")
|
||||
end
|
||||
def hot_text
|
||||
I18n.t("announcement.status.hot")
|
||||
end
|
||||
def hidden_text
|
||||
I18n.t("announcement.status.hidden")
|
||||
end
|
||||
def carousel_image_type
|
||||
(self.custom_carousel_image_type == 0 ? RecruitNewsSetting.last.carousel_image_type : self.custom_carousel_image_type - 1) rescue 0
|
||||
end
|
||||
def carousel_image_width
|
||||
(self.custom_carousel_image_width.blank? ? RecruitNewsSetting.last.carousel_image_width : self.custom_carousel_image_width)
|
||||
end
|
||||
|
||||
def self.agenda_events(agenda_start, agenda_end,read_more_url)
|
||||
events = self.monthly_event(agenda_start, agenda_end).convert_front(read_more_url)
|
||||
end
|
||||
def self.monthly_event(start_date,end_date)
|
||||
self.any_of({:event_date.lte => start_date,:event_end_date.gte => start_date},{:event_date.gte => start_date,:event_end_date.lte => end_date},{:event_date.lte => end_date,:event_end_date.gte => end_date}).asc(:event_date)
|
||||
end
|
||||
def self.convert_front(read_more_url)
|
||||
self.all.collect do |re|
|
||||
{:id => re.id.to_s,
|
||||
:title=>re.title,
|
||||
:note=>re.subtitle || "",
|
||||
:allDay => false,
|
||||
:color => nil,
|
||||
:url_linked => (re.is_external_link ? re.external_link : "#{read_more_url}/#{re.to_param}" rescue ""),
|
||||
:start => re.event_date,
|
||||
:end => re.event_end_date}
|
||||
end
|
||||
end
|
||||
def self.smart_convertor(text,url)
|
||||
html_string = text
|
||||
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_data(more_url=nil, base_url=nil, cat_ids=nil, tag_ids=nil, locale=nil)
|
||||
locale = I18n.locale if locale.nil?
|
||||
base_url = Site.first.root_url if base_url.nil?
|
||||
user = User.find(self.create_user_id) rescue nil
|
||||
if !user.nil?
|
||||
author = user.member_name || user.user_name
|
||||
else
|
||||
author = ""
|
||||
end
|
||||
a = {}
|
||||
if more_url.nil?
|
||||
if cat_ids.nil?
|
||||
cat_ids = [self.category_id]
|
||||
end
|
||||
if tag_ids.nil?
|
||||
tag_ids = self.tag_ids
|
||||
end
|
||||
basic_query = {:module => 'recruit_news_mod',:enabled_for=>locale}
|
||||
if !cat_ids.blank?
|
||||
query = basic_query.merge({:categories.all => cat_ids})
|
||||
else
|
||||
query = basic_query.clone
|
||||
end
|
||||
if !tag_ids.blank?
|
||||
query = query.merge({:tags.all => tag_ids})
|
||||
end
|
||||
page = Page.where(query).first || Page.where(basic_query).first
|
||||
more_url = page ? page.get_url : nil
|
||||
end
|
||||
if more_url
|
||||
a['show_url'] = "#{more_url}/#{self.to_param}"
|
||||
end
|
||||
a["org_is_top"] = (self.is_top ? 1 : 0)
|
||||
a["id"] = self.uid
|
||||
a["title_translations"] = self.title_translations
|
||||
a["subtitle_translations"] = self.subtitle_translations
|
||||
a["speaker_translations"] = self.speaker_translations
|
||||
a["host_translations"] = self.host_translations
|
||||
a["place_translations"] = self.place_translations
|
||||
a["notes_translations"] = self.notes_translations
|
||||
a["text_translations"] = {}
|
||||
text_translations = self.text_translations
|
||||
text_translations.each do |l, text|
|
||||
a["text_translations"][l] = self.class.smart_convertor(text,base_url)
|
||||
end
|
||||
a["event_date"] = self.event_date
|
||||
a["event_end_date"] = self.event_end_date
|
||||
a["postdate"] = self.postdate
|
||||
a["img_description_translations"] = self.image_description_translations
|
||||
a["image"] = {}
|
||||
a["display_img"] = self.display_img
|
||||
if self.image.present?
|
||||
a["image"]["original"] = base_url + self.image.url
|
||||
a["image"]["thumb"] = base_url + self.image.thumb.url
|
||||
a["image"]["mobile"] = base_url + self.image.mobile.url
|
||||
a["img_src"] = a["image"]["thumb"] || "/assets/recruit_news-default.jpg"
|
||||
image = MiniMagick::Image.open(self.image.path) rescue nil
|
||||
if image
|
||||
a["image"]["width"] = image[:width]
|
||||
a["image"]["height"] = image[:height]
|
||||
end
|
||||
end
|
||||
a["tags"] = []
|
||||
a["category"] = {}
|
||||
a["author"] = author
|
||||
a["params"] = self.to_param
|
||||
a["subtitle_ann"] = self.subtitle if self.display_subtitle?
|
||||
a["recruit_news_links"] = []
|
||||
a["recruit_news_files"] = []
|
||||
a["event_carousel_images"] = self.event_carousel_images.map{|image| {"src"=> base_url + image.file.url,"description"=>image.description.to_s,"description_text"=>image.description_text }}
|
||||
a["external_link"] = self["is_external_link"] ? self.external_link : nil
|
||||
self.tags.each do |tag|
|
||||
a["tags"] << {"name_translations" => tag.name_translations}
|
||||
end
|
||||
cat = self.category
|
||||
a["category"] = cat ? {"title_translations" => cat.title_translations} : {"title_translations" => {}}
|
||||
self.recruit_news_links.each do |bl|
|
||||
b = {}
|
||||
b["link_url"] = bl.url
|
||||
b["link_title_translations"] = bl.title_translations.map{|k,v| [k, (v.blank? ? b["link_url"] : v)]}.to_h
|
||||
a["recruit_news_links"] << b
|
||||
end
|
||||
self.recruit_news_files.each do |bf|
|
||||
next if bf.file.blank?
|
||||
b = {}
|
||||
b["description_translations"] = bf.description_translations
|
||||
b["file_url"] = base_url + bf.file.url
|
||||
b["file_title_translations"] = bf.title_translations.map{|k,v| [k, (v.blank? ? File.basename(b["file_url"]) : v)]}.to_h
|
||||
a["recruit_news_files"] << b
|
||||
end
|
||||
return a
|
||||
end
|
||||
def get_related_feeds
|
||||
@category_id ||= self.category_id
|
||||
@tag_ids ||= self.tag_ids
|
||||
related_feeds = RecruitNewsFeed.any_of({:category_ids=>@category_id.to_s}, {:tag_ids.in=>@tag_ids.map(&:to_s)}).to_a
|
||||
end
|
||||
def notify_feed(type="create")
|
||||
if @is_hidden_changed
|
||||
if self.is_hidden
|
||||
if type == 'create'
|
||||
return []
|
||||
else
|
||||
type = 'destroy'
|
||||
end
|
||||
else
|
||||
type = 'create'
|
||||
end
|
||||
elsif self.is_hidden
|
||||
return []
|
||||
end
|
||||
related_feeds = self.get_related_feeds.select{|feed| feed.remote_urls.count != 0}
|
||||
if related_feeds.count != 0
|
||||
bulletin_data = self.get_data
|
||||
if type == "destroy"
|
||||
tmp_data = {'type'=>'destroy', 'data'=>[self.uid]}
|
||||
else
|
||||
tmp_data = {'type'=>type, 'data'=>[bulletin_data.to_json]}
|
||||
end
|
||||
request = Net::HTTP::Post.new('/xhr/feeds/notify_change', 'Content-Type' => 'application/json')
|
||||
related_feeds.each do |feed|
|
||||
tmp_data['uid'] = feed.uid
|
||||
request.body = tmp_data.to_json
|
||||
feed.remote_urls.each do |remote_url|
|
||||
uri = URI(remote_url)
|
||||
http_req = Net::HTTP.new(uri.host, uri.port)
|
||||
if remote_url.include?('https')
|
||||
http_req.use_ssl = true
|
||||
end
|
||||
response = self.class.http_request( http_req , request )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def migrate_title_plain_text
|
||||
self.title_plain_text_translations = OrbitHelper.get_plain_text_translations(self.title_translations)
|
||||
end
|
||||
|
||||
def self.notify_all_feed(force_update=false)
|
||||
related_feeds = RecruitNewsFeed.where(:remote_urls.nin=>[nil, []]).to_a
|
||||
related_feeds.each do |feed|
|
||||
uid = feed.uid
|
||||
startdt = nil
|
||||
enddt = nil
|
||||
dt = nil
|
||||
feed_cache = RecruitNewsFeedCache.where(uid: uid, start: startdt, end: enddt, date: dt)
|
||||
if force_update
|
||||
feed_cache = nil
|
||||
else
|
||||
feed_cache_old = feed_cache.all_of([{:invalid_date.ne=>nil},{:invalid_date.lte => Time.now}]).last
|
||||
feed_cache.all_of([{:invalid_date.ne=>nil},{:invalid_date.lte => Time.now}]).destroy
|
||||
count = feed_cache.count
|
||||
if count > 1
|
||||
feed_cache.limit(count-1).destroy
|
||||
end
|
||||
feed_cache = feed_cache.first
|
||||
anns = ''
|
||||
end
|
||||
if feed_cache.nil?
|
||||
anns = feed.generate_one_cache_timeout(startdt: startdt,enddt: enddt,dt: dt,timeout: 20)
|
||||
anns = (feed_cache_old.content rescue "") if anns.nil?
|
||||
else
|
||||
anns = feed_cache.content
|
||||
end
|
||||
request = Net::HTTP::Post.new('/xhr/feeds/notify_change', 'Content-Type' => 'application/json')
|
||||
tmp_data = {'type'=>'update_all', 'uid'=> uid, 'data'=>anns}
|
||||
request.body = tmp_data.to_json
|
||||
feed.remote_urls.each do |remote_url|
|
||||
uri = URI(remote_url)
|
||||
http_req = Net::HTTP.new(uri.host, uri.port)
|
||||
if remote_url.include?('https')
|
||||
http_req.use_ssl = true
|
||||
end
|
||||
response = self.http_request( http_req , request )
|
||||
end
|
||||
end
|
||||
end
|
||||
def self.notify_feed_delete(ids)
|
||||
all_feeds = RecruitNewsFeed.all.select{|feed| feed.remote_urls.count != 0}
|
||||
if all_feeds.count != 0
|
||||
tmp_data = {'type'=>'destroy'}
|
||||
request = Net::HTTP::Post.new('/xhr/feeds/notify_change', 'Content-Type' => 'application/json')
|
||||
all_feeds.each do |feed|
|
||||
feed_uid = feed.uid
|
||||
feed_cache = RecruitNewsFeedCache.where(:uid=>feed_uid).first
|
||||
if feed_cache
|
||||
tmp_data['uid'] = feed_uid
|
||||
tmp_data['data'] = ids & JSON.parse(feed_cache.content)["announcements"].map{|a| a["id"]}
|
||||
request.body = tmp_data.to_json
|
||||
if tmp_data['data'].count != 0
|
||||
feed.remote_urls.each do |remote_url|
|
||||
uri = URI(remote_url)
|
||||
http_req = Net::HTTP.new(uri.host, uri.port)
|
||||
if remote_url.include?('https')
|
||||
http_req.use_ssl = true
|
||||
end
|
||||
response = self.http_request( http_req , request )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
def self.http_request(http, request)
|
||||
response = http.request(request)
|
||||
if response.code.to_i == 301 || response.code.to_i == 302
|
||||
location = response["location"]
|
||||
new_uri = URI(location)
|
||||
http = Net::HTTP.new(new_uri.host, new_uri.port)
|
||||
if location.include?('https')
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||
end
|
||||
request.instance_variable_set(:@path, new_uri.path)
|
||||
response = self.http_request(http, request)
|
||||
end
|
||||
response
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
class RecruitNewsCache
|
||||
include Mongoid::Document
|
||||
field :parent_id
|
||||
field :filter_result
|
||||
field :locale,type: String,default: 'zh_tw'
|
||||
field :invalid_date, type: DateTime
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
class RecruitNewsCustomTitle
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
field :key
|
||||
field :title, type: String, localize: true
|
||||
KEYS = ['category', 'title','speaker','host','event_date','place','notes']
|
||||
def self.get_map
|
||||
KEYS.map do |k|
|
||||
s = self.where(key: k).first || self.create(key: k,title_translations: I18n.available_locales.map{|l| [l,I18n.with_locale(l){I18n.t("recruit_news.#{k}")}]}.to_h)
|
||||
if s.title_translations.select{|k,v| v.include?("translation missing")}.length>0
|
||||
s.update_attributes(title_translations: I18n.available_locales.map{|l| [l,I18n.with_locale(l){I18n.t("recruit_news.#{k}")}]}.to_h)
|
||||
end
|
||||
s
|
||||
end
|
||||
end
|
||||
def default_title
|
||||
I18n.t("recruit_news.#{self.key}")
|
||||
end
|
||||
def self.get_trans(key)
|
||||
tmp = TitleMap[key][I18n.locale] rescue I18n.t("recruit_news.#{key}")
|
||||
tmp.blank? ? I18n.t("recruit_news.#{key}") : tmp
|
||||
end
|
||||
TitleMap = self.get_map.map{|v| [v.key,v.title_translations]}.to_h
|
||||
end
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
class RecruitNewsFeed
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
include Slug
|
||||
|
||||
field :title, as: :slug_title, type: String, localize: true
|
||||
field :tag_ids, type: Array, default: []
|
||||
field :category_ids, type: Array, default: []
|
||||
field :remote_urls, type: Array, default: []
|
||||
before_save do
|
||||
RecruitNewsFeedCache.where(uid: self.uid).each do |cache|
|
||||
cache.regenerate
|
||||
end
|
||||
end
|
||||
def self.create_feed_cache(recruit_news=nil,recruit_news_feed=nil)
|
||||
Thread.new do
|
||||
if !recruit_news.nil?
|
||||
self.where(:tag_ids.in => Array(recruit_news.tag_ids).collect{|v| v.to_s}).each do |recruit_news_feed|
|
||||
uid = recruit_news_feed.uid
|
||||
RecruitNewsFeedCache.where(:uid => uid).each do |cache|
|
||||
cache.regenerate
|
||||
end
|
||||
end
|
||||
elsif !recruit_news_feed.nil?
|
||||
uid = recruit_news_feed.uid
|
||||
RecruitNewsFeedCache.where(:uid => uid).each do |cache|
|
||||
cache.regenerate
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
def generate_one_cache_timeout(startdt: nil,enddt: nil,dt: nil, base_url: nil, timeout: nil)
|
||||
timeout = 100000 if timeout.nil?
|
||||
begin
|
||||
Timeout::timeout(timeout) {
|
||||
feed_cache = nil
|
||||
Thread.new do
|
||||
feed_cache = self.generate_one_cache(startdt: startdt,enddt: enddt,dt: dt,base_url: base_url)
|
||||
end
|
||||
(1..(timeout.to_i+1)).each do
|
||||
sleep(1)
|
||||
break if !feed_cache.nil?
|
||||
end
|
||||
feed_cache.content
|
||||
}
|
||||
rescue=> e
|
||||
puts [e,e.backtrace]
|
||||
""
|
||||
end
|
||||
end
|
||||
def generate_one_cache(startdt: nil,enddt: nil,dt: nil, base_url: nil)
|
||||
base_url = Site.first.root_url if base_url.nil?
|
||||
uid = self.uid
|
||||
bf = self
|
||||
if !bf.nil?
|
||||
tags = bf.tag_ids
|
||||
categories = bf.category_ids
|
||||
if !(categories.empty? && tags.empty?)
|
||||
anns_before_filter = RecruitNews.any_of(I18n.available_locales.map{|v| {"title.#{v}"=>{"$nin"=>["", nil]}}}).is_approved_and_show
|
||||
if !dt.nil?
|
||||
dt = DateTime.parse(dt)
|
||||
dtt = dt + 1.day
|
||||
anns_before_filter = anns_before_filter.where(:postdate.gt => dt, :postdate.lt => dtt)
|
||||
elsif !startdt.blank? && enddt.blank?
|
||||
startdt = DateTime.parse(startdt)
|
||||
enddt = DateTime.now
|
||||
anns_before_filter = anns_before_filter.where(:postdate.gt => startdt, :postdate.lt => enddt)
|
||||
elsif !startdt.blank? && !enddt.blank?
|
||||
startdt = DateTime.parse(startdt)
|
||||
enddt = DateTime.parse(enddt) + 1.day
|
||||
anns_before_filter = anns_before_filter.where(:postdate.gt => startdt, :postdate.lt => enddt)
|
||||
end
|
||||
anns_before_filter = anns_before_filter.can_display_and_sorted
|
||||
if !tags.empty?
|
||||
anns_before_filter = anns_before_filter.filter_by_tags(tags)
|
||||
end
|
||||
if !categories.empty?
|
||||
anns_before_filter = anns_before_filter.filter_by_categories(categories)
|
||||
end
|
||||
announcements = anns_before_filter.can_display_and_sorted
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
all_anns = []
|
||||
|
||||
first_postdate = anns_before_filter.open_in_future.limit(1).pluck(:postdate)[0]
|
||||
first_deadline = nil
|
||||
cat_ids = announcements.collect{|a| a.category_id.blank? ? nil : a.category_id.to_s}.compact.uniq
|
||||
tag_ids = announcements.collect{|a| a.tag_ids.collect{|v| v.blank? ? nil : v.to_s}}.flatten.compact.uniq
|
||||
tag_names = tag_ids.map{|tag_id| Tag.find(tag_id).name_translations rescue nil}.compact
|
||||
category_titles = cat_ids.map{|cat_id| Category.find(cat_id).title_translations rescue nil}.compact
|
||||
basic_query = {:module => 'recruit_news_mod',:enabled_for=>I18n.locale}
|
||||
if !cat_ids.blank?
|
||||
query = basic_query.merge({:categories.all => cat_ids})
|
||||
else
|
||||
query = basic_query.clone
|
||||
end
|
||||
if !tag_ids.blank?
|
||||
query = query.merge({:tags.all => tag_ids})
|
||||
end
|
||||
page = Page.where(query).first || Page.where(basic_query).first
|
||||
more_url = page ? page.get_url : nil
|
||||
|
||||
announcements.each do |anns|
|
||||
deadline = anns.deadline
|
||||
if !deadline.blank?
|
||||
if first_deadline.nil? || first_deadline>deadline
|
||||
first_deadline = deadline
|
||||
end
|
||||
end
|
||||
a = anns.get_data(more_url, base_url, cat_ids, tag_ids)
|
||||
all_anns << a
|
||||
end
|
||||
invalid_date = [first_postdate,first_deadline].compact.sort[0]
|
||||
anns = {
|
||||
"recruit_news_mods" => all_anns,
|
||||
"tags" => tag_names,
|
||||
"categories" => category_titles
|
||||
}.to_json
|
||||
feed_cache = RecruitNewsFeedCache.create(uid: uid,content: anns,start: startdt,end: enddt,date: dt,invalid_date: invalid_date)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
class RecruitNewsFeedCache
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
field :content, type: String, default: ''
|
||||
field :uid
|
||||
field :start
|
||||
field :end
|
||||
field :date
|
||||
field :invalid_date, type: DateTime
|
||||
def self.regenerate_all
|
||||
caches = self.all.to_a
|
||||
time_now = Time.now
|
||||
caches.each do |cache|
|
||||
if cache.invalid_date && cache.invalid_date <= time_now
|
||||
cache.destroy
|
||||
else
|
||||
cache.regenerate
|
||||
end
|
||||
end
|
||||
uids = RecruitNewsFeed.all.pluck(:uid) - caches.collect(&:uid)
|
||||
RecruitNewsFeed.where(:uid.in=> uids).each do |feed|
|
||||
feed.generate_one_cache()
|
||||
end
|
||||
end
|
||||
def regenerate
|
||||
st = self.start
|
||||
et = self.end
|
||||
dt = self.date
|
||||
uid = self.uid
|
||||
RecruitNewsFeed.where(uid: uid).each{|v| v.generate_one_cache(startdt: st,enddt: et,dt: dt)} rescue nil
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# encoding: utf-8
|
||||
class RecruitNewsFile
|
||||
|
||||
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'
|
||||
field :position, type: Integer, default: 0
|
||||
default_scope ->{ order_by(position: :asc) }
|
||||
belongs_to :recruit_news
|
||||
def self.to_fronted(locale=I18n.locale)
|
||||
self.all.map{|file| file.to_fronted(locale)}.compact rescue []
|
||||
end
|
||||
def to_fronted(locale=I18n.locale)
|
||||
file = self
|
||||
(file.enabled_for?(locale) && !file[:file].blank?) ? { "file_url" => "/xhr/recruit_news/file/#{file.id}/#{file['file']}" + "\" title=\"#{file.file_title}",
|
||||
"file_title" => (file.title.blank? ? URI.unescape(File.basename(file.file.path)) : file.title rescue '')
|
||||
} : nil rescue nil
|
||||
end
|
||||
|
||||
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 RecruitNewsLink
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
field :url
|
||||
field :title, localize: true
|
||||
|
||||
belongs_to :recruit_news
|
||||
|
||||
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,131 @@
|
|||
class RecruitNewsSetting
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
field :carousel_image_type, :type => Integer, :default => 0 # 0: carousel, 1: album
|
||||
field :carousel_image_width, type: String, :default => "75%"
|
||||
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 :including_day_of_the_week, type: Boolean, default: true
|
||||
field :including_time, type: Boolean, default: true
|
||||
field :hour_clock_24, type: Boolean, default: true
|
||||
field :enable_manually_sort, type: Boolean, default: false
|
||||
field :is_postdate_sort_first, type: Boolean, default: false
|
||||
|
||||
field :migrate_flag, type: Array, default: []
|
||||
|
||||
has_many :recruit_news_status_settings, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :recruit_news_status_settings, :allow_destroy => true
|
||||
|
||||
before_save do
|
||||
can_update_shared_hash = (defined?(OrbitHelper::SharedHash) && OrbitHelper::SharedHash)
|
||||
if self.including_day_of_the_week_changed? || self.including_time_changed? || self.hour_clock_24_changed?
|
||||
@need_update_recruit_news = true
|
||||
end
|
||||
if self.enable_manually_sort_changed? && self.enable_manually_sort
|
||||
RecruitNews.index({approved: -1,is_hidden: 1,is_preview: 1, is_top: -1,sort_number: 1,postdate: -1,_id: -1,deadline: -1}, { unique: false, background: true })
|
||||
RecruitNews.create_indexes
|
||||
if can_update_shared_hash
|
||||
OrbitHelper::SharedMutex.synchronize do
|
||||
OrbitHelper::SharedHash["recruit_news_mod"][:enable_manually_sort] = self.enable_manually_sort
|
||||
end
|
||||
end
|
||||
@need_update_recruit_news = true
|
||||
end
|
||||
end
|
||||
after_save do
|
||||
if @need_update_recruit_news
|
||||
@need_update_recruit_news = false
|
||||
Thread.new do
|
||||
RecruitNewsCache.all.delete
|
||||
end
|
||||
end
|
||||
end
|
||||
def self.check_limit_for_user(user_id, b_id = nil)
|
||||
limit = self.first.top_limit rescue 0
|
||||
return true if limit == 0
|
||||
count = Bulletin.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
|
||||
def self.event_date_default_format
|
||||
setting = self.first
|
||||
setting.event_date_default_format
|
||||
end
|
||||
def event_date_default_format
|
||||
datetime_format = "%Y-%m-%d"
|
||||
if self.including_day_of_the_week
|
||||
datetime_format += " %a"
|
||||
end
|
||||
if self.including_time
|
||||
if self.hour_clock_24
|
||||
datetime_format += " %H:%M"
|
||||
else
|
||||
datetime_format += " %I:%M %P"
|
||||
end
|
||||
end
|
||||
datetime_format
|
||||
end
|
||||
def get_weekday(w)
|
||||
trans = RecruitNews::Week_day_trans
|
||||
if trans.keys.include?(I18n.locale)
|
||||
trans[I18n.locale][w]
|
||||
else
|
||||
trans[:en][w]
|
||||
end
|
||||
end
|
||||
def custom_strftime(dt, datetime_format)
|
||||
if dt
|
||||
dt.strftime(datetime_format.sub("%a","%%a")).sub("%a",get_weekday(dt.wday))
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
def event_date_format
|
||||
@event_date_format ||= self.event_date_default_format
|
||||
end
|
||||
def self.event_time_formated_for_frontend(st,ed)
|
||||
self.first.event_time_formated_for_frontend(st,ed)
|
||||
end
|
||||
def event_time_formated_for_frontend(st,ed)
|
||||
st,ed = self.event_time_formated(st,ed).split("~")
|
||||
if st.blank?
|
||||
st = "<span class=\"start_date\">#{st}</span>"
|
||||
end
|
||||
if ed.nil?
|
||||
st
|
||||
else
|
||||
ed = "<span class=\"start_date\">#{ed}</span>"
|
||||
"#{st} ~ #{ed}"
|
||||
end
|
||||
end
|
||||
def event_time_formated(st,ed)
|
||||
s = st
|
||||
e = ed
|
||||
if s.blank? && e.blank?
|
||||
""
|
||||
elsif e.blank?
|
||||
custom_strftime(s, self.event_date_format)
|
||||
elsif s.blank?
|
||||
"~ " + custom_strftime(e, self.event_date_format)
|
||||
else
|
||||
parse_format = self.event_date_format
|
||||
if s.to_date == e.to_date
|
||||
parse_format_arr = parse_format.split(/(%d %a|%d) /)
|
||||
parse_format_arr = parse_format_arr[0..-2].join(""), parse_format_arr[-1]
|
||||
date_str = custom_strftime(s, parse_format_arr[0])
|
||||
s_time = s.strftime(parse_format_arr[1])
|
||||
e_time = e.strftime(parse_format_arr[1])
|
||||
"#{date_str} #{s_time} ~ #{e_time}"
|
||||
else
|
||||
custom_strftime(s, self.event_date_format) + " ~ " + custom_strftime(e, self.event_date_format)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
class RecruitNewsStatusSetting
|
||||
include Mongoid::Document
|
||||
field :role_id
|
||||
field :status
|
||||
field :top_limit
|
||||
belongs_to :recruit_news_setting
|
||||
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/recruit_news/approve_recruit_news", :class=>"approvalModal__form" do %>
|
||||
<div class="approvalModal__group">
|
||||
<label class="control-label" for="recruit_news_approval_stat">審核狀態</label>
|
||||
<div class="approvalModal__controls">
|
||||
<label class="approvalModal__radio">
|
||||
<input class="approvalModal__privacy" id="recruit_news_is_checked_true" name="approved" type="radio" value="true">已認可
|
||||
</label>
|
||||
<label class="approvalModal__radio">
|
||||
<input checked="checked" class="approvalModal__privacy" id="recruit_news_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="recruit_news_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,61 @@
|
|||
<%= form_for @recruit_news_feed, url: admin_recruit_news_updatefeed_path(:id => @recruit_news_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="recruit_news_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: (@recruit_news_feed.title_translations[locale.to_s] rescue nil) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<hr />
|
||||
<div class="tags">
|
||||
<h4><%=t(:tags)%></h4>
|
||||
<div id="tags-list">
|
||||
<div class="tags-groups checkbox-card module-tags">
|
||||
<% @module_app.tags.each do |tag| %>
|
||||
<label class="filter-item module <%= @recruit_news_feed.tag_ids.include?(tag.id.to_s) ? "active" : "" %>">
|
||||
<p class='card pull-left <%= @recruit_news_feed.tag_ids.include?(tag.id.to_s) ? "active" : "" %>'>
|
||||
<input type="checkbox" <%= @recruit_news_feed.tag_ids.include?(tag.id.to_s) ? "checked=checked" : "" %> class="tag-checkbox" value="<%= tag.id.to_s %>" name="recruit_news_feed[tag_ids][]">
|
||||
</p>
|
||||
<div>
|
||||
<% @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 %>
|
||||
</div>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="categories">
|
||||
<h4><%=t(:category)%></h4>
|
||||
<div id="categories-list">
|
||||
<div class="tags-groups checkbox-card module-categories">
|
||||
<% @module_app.categories.each do |category| %>
|
||||
<label class="filter-item module <%= @recruit_news_feed.category_ids.include?(category.id.to_s) ? "active" : "" %>">
|
||||
<p class="card pull-left <%= @recruit_news_feed.category_ids.include?(category.id.to_s) ? "active" : "" %>">
|
||||
<input type="checkbox" class="tag-checkbox" <%= @recruit_news_feed.category_ids.include?(category.id.to_s) ? "checked=checked" : "" %> value="<%= category.id.to_s %>" name="recruit_news_feed[category_ids][]">
|
||||
</p>
|
||||
<div>
|
||||
<% @site_in_use_locales.each_with_index do |locale,index| %>
|
||||
<span class="tag"><%= category.title_translations[locale] %></span>
|
||||
<% if index < (@site_in_use_locales.count - 1) %>
|
||||
/
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<div id="data-table" class="ut-table">
|
||||
<table class="table main-list">
|
||||
<thead>
|
||||
<tr class="sort-header">
|
||||
<% @table_fields.each do |field| %>
|
||||
<%
|
||||
field_text = field.to_s.include?('.') ? t(field.to_s) : field.to_s
|
||||
sort = field.to_s.split('.')[-1]
|
||||
active = params[:sort].eql? sort
|
||||
order = active ? (["asc", "desc"]-[params[:order]]).first : "asc"
|
||||
arrow = (order.eql? "desc") ? "<b class='icons-arrow-up-3'></b>" : "<b class='icons-arrow-down-4'></b>"
|
||||
klass = sort.eql?(:title) ? "span5" : "span2"
|
||||
th_data = "<a href='?sort=#{sort}&order=#{order}'>#{field_text} #{active ? arrow : ""}</a>"
|
||||
%>
|
||||
<th class='<%= klass %> <%= active ? "active" : "" %>'><%= th_data.html_safe %></th>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="sortable">
|
||||
<% @recruit_news.each do |ev| %>
|
||||
<tr data-id="<%= ev.id %>">
|
||||
<td>
|
||||
<%= number_field_tag nil,ev.sort_number,class: 'sort_number',step: 1 %>
|
||||
</td>
|
||||
<td>
|
||||
<%= ev.title.html_safe %>
|
||||
</td>
|
||||
<td>
|
||||
<%= format_value ev.event_date %>
|
||||
</td>
|
||||
<td>
|
||||
<%= format_value ev.postdate %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<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/recruit_news/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>
|
||||
<div class="categories">
|
||||
<div id="categories-list">
|
||||
<ul class="tags-groups checkbox-card module-categories">
|
||||
<% categories_to_remove = [] %>
|
||||
<% feed.category_ids.each do |c| %>
|
||||
<% category = Category.find(c) rescue nil %>
|
||||
<% if !category.nil? %>
|
||||
<li class="filter-item module">
|
||||
<a href="#" onclick="return false;">
|
||||
<% @site_in_use_locales.each_with_index do |locale,index| %>
|
||||
<span class="tag"><%= category.title_translations[locale] %></span>
|
||||
<% if index < (@site_in_use_locales.count - 1) %>
|
||||
/
|
||||
<% end %>
|
||||
<% end %>
|
||||
</a>
|
||||
</li>
|
||||
<% else %>
|
||||
<% categories_to_remove << c %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if !categories_to_remove.blank?
|
||||
categories_to_remove.each do |c|
|
||||
feed.category_ids.delete(c)
|
||||
end
|
||||
feed.save
|
||||
end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/xhr/recruit_news/rssfeed/<%= feed.uid %>.rss" target="_blank">RSS Feed</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/xhr/recruit_news/feed/<%= feed.uid %>.json" target="_blank">JSON Feed</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<%= form_for @recruit_news_feed, url: admin_recruit_news_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="recruit_news_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: (@recruit_news_feed.title_translations[locale.to_s] rescue nil) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<hr />
|
||||
<div class="tags">
|
||||
<h4><%=t(:tags)%></h4>
|
||||
<div id="tags-list">
|
||||
<div class="tags-groups checkbox-card module-tags">
|
||||
<% @module_app.tags.each do |tag| %>
|
||||
<label class="filter-item module">
|
||||
<p class="card pull-left">
|
||||
<input type="checkbox" class="tag-checkbox" value="<%= tag.id.to_s %>" name="recruit_news_feed[tag_ids][]">
|
||||
</p>
|
||||
<div>
|
||||
<% @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 %>
|
||||
</div>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="categories">
|
||||
<h4><%=t(:category)%></h4>
|
||||
<div id="categories-list">
|
||||
<div class="tags-groups checkbox-card module-categories">
|
||||
<% @module_app.categories.each do |category| %>
|
||||
<label class="filter-item module">
|
||||
<p class="card pull-left">
|
||||
<input type="checkbox" class="tag-checkbox" value="<%= category.id.to_s %>" name="recruit_news_feed[category_ids][]">
|
||||
</p>
|
||||
<div>
|
||||
<% @site_in_use_locales.each_with_index do |locale,index| %>
|
||||
<span class="tag"><%= category.title_translations[locale] %></span>
|
||||
<% if index < (@site_in_use_locales.count - 1) %>
|
||||
/
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,780 @@
|
|||
<% 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">
|
||||
.sort-order-icon {
|
||||
font-size: 25px;
|
||||
}
|
||||
.ui-state-highlight {
|
||||
height: 40px;
|
||||
background-color: #fcf8e3;
|
||||
border: 1px dashed #fbeed5;
|
||||
margin-bottom: 10px;
|
||||
list-style: none;
|
||||
}
|
||||
.exist .file-link {
|
||||
cursor: grab;
|
||||
}
|
||||
.icons-list-2 {
|
||||
cursor: all-scroll;
|
||||
}
|
||||
[aria-describedby] ul.dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
[aria-describedby] .checkbox input{
|
||||
margin-left: 0;
|
||||
}
|
||||
.reach_limit{
|
||||
background: #a90c0c;
|
||||
color: white;
|
||||
padding: 4px 12px;
|
||||
font-family: 'Varela Round';
|
||||
letter-spacing: -.4px;
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
}
|
||||
legend {
|
||||
background: white;
|
||||
}
|
||||
</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((!RecruitNewsSetting.first.only_manager_can_edit_status) || (RecruitNewsSetting.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="#hashtag" data-toggle="tab"><%= t(:hashtags) %></a></li>
|
||||
<li><a href="#imageupload" data-toggle="tab"><%= t('recruit_news.image') %></a></li>
|
||||
<li><a href="#carousel_image_upload" data-toggle="tab" title="<%= t('recruit_news.carousel_image_title') %>"><%= t('recruit_news.carousel_image') %></a></li>
|
||||
<li><a href="#mail-group" data-toggle="tab"><%= t('recruit_news.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"><%= RecruitNewsCustomTitle.get_trans('event_date') %></label>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :event_date, :no_label => true, :new_record => @recruit_news.new_record?, :data=>{"picker-type" => "range", "range" => "start"} %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= I18n.t("recruit_news.event_date_use_default_setting") %></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :event_date_use_default_setting, :id=>"event_date_use_default_setting" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t("recruit_news.event_end_date") %></label>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :event_end_date, :no_label => true, :new_record => @recruit_news.new_record?, :data=>{"picker-type" => "range", "range" => "start"} %>
|
||||
</div>
|
||||
</div>
|
||||
<fieldset id="event_date_setting" class="<%='hide' if f.object.event_date_use_default_setting %>">
|
||||
<legend><%=t("recruit_news.event_date_setting")%></legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= I18n.t("recruit_news.including_day_of_the_week") %></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :including_day_of_the_week %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= I18n.t("recruit_news.including_time") %></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :including_time, :id=>"including_time" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hour_clock_24_block control-group <%= 'hide' if !(f.object.including_time) %>">
|
||||
<label class="control-label muted"><%= I18n.t("recruit_news.hour_clock_24") %></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :hour_clock_24 %>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t("recruit_news.start_date") %></label>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :postdate, :no_label => true, :new_record => @recruit_news.new_record?, :data=>{"picker-type" => "range", "range" => "start"} %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t("recruit_news.end_date") %></label>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :deadline, :no_label => true, :new_record => @recruit_news.new_record?, :data=>{"picker-type" => "range", "range" => "end"} %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<%= f.label :is_external_link, t("recruit_news.is_external_link"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :is_external_link %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group" style="<%=@recruit_news.is_external_link ? '' : 'display: none;'%>" id="external_link_box">
|
||||
<%= f.label :external_link, t("recruit_news.external_link"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.text_field :external_link %>
|
||||
<div class="hint"><%= t("recruit_news.external_link_hint") %></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- display subtitle -->
|
||||
<div class="control-group">
|
||||
<%= f.label :display_subtitle, t("recruit_news.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("recruit_news.display_img"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :display_img, :id=> "recruit_news_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("recruit_news.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("recruit_news.#{key}") %>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group big-group">
|
||||
<label class="control-label muted"><%= t("recruit_news.members") %></label>
|
||||
<div class="controls">
|
||||
<%= render partial: 'admin/member_selects/email_selection_box', locals: {field: 'recruit_news[other_member_profiles][]', email_members: MemberProfile.find(@recruit_news.other_member_profiles), select_name: "author_members", index: 'author_members', extra_class: 'custom-class'} %>
|
||||
</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('recruit_news.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 !@recruit_news.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("recruit_news.start_date") %></label>
|
||||
<label class="control-label muted"><%= t('recruit_news.blank_to_set') %></label>
|
||||
</div>
|
||||
<div class="controls" style="margin-left: 1.5em;">
|
||||
<%= f.datetime_picker :calendar_start_date, :new_record => @recruit_news.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("recruit_news.end_date") %></label>
|
||||
<label class="control-label muted"><%= t('recruit_news.blank_to_set') %></label>
|
||||
</div>
|
||||
<div class="controls" style="margin-left: 1.5em;">
|
||||
<%= f.datetime_picker :calendar_end_date, :new_record => @recruit_news.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>
|
||||
<%= f.hidden_field :event_id %>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- Status Module -->
|
||||
<% if((!RecruitNewsSetting.first.only_manager_can_edit_status) || (RecruitNewsSetting.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') && @recruit_news.is_top != true) || current_user.is_admin? %>
|
||||
<label class="checkbox inline btn <%= 'active' if @recruit_news.is_top? || (!@recruit_news.top_end_date.nil? && @recruit_news.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') && @recruit_news.is_hot != true) || current_user.is_admin? %>
|
||||
<label class="checkbox inline btn <%= 'active' if @recruit_news.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 @recruit_news.is_hidden? %>">
|
||||
<%= f.check_box :is_hidden %> <%= t(:hide) %>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<% if !@recruit_news.is_top? && !RecruitNewsSetting.check_limit_for_user((@recruit_news.new_record? ? current_user.id : @recruit_news.create_user_id)) %>
|
||||
<span>Top limit has been reached. The recruit_news wont be marked as top even if you click on it.</span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group <%= @recruit_news.is_top? || (!@recruit_news.top_end_date.nil? && @recruit_news.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 => @recruit_news.new_record? %>
|
||||
</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>
|
||||
|
||||
<!-- Hashtag Module -->
|
||||
<div class="tab-pane fade" id="hashtag">
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:hashtags) %></label>
|
||||
<%= select_hashtags(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 @recruit_news.image.file %>" data-provides="fileupload">
|
||||
<div class="fileupload-new thumbnail pull-left">
|
||||
<% if @recruit_news.image.file %>
|
||||
<%= image_tag @recruit_news.image %>
|
||||
<% else %>
|
||||
<img src="/assets/recruit_news/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: (@recruit_news.image_description_translations[locale.to_s] rescue nil) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Images Module -->
|
||||
<div class="tab-pane fade" id="carousel_image_upload">
|
||||
<div class="control-group">
|
||||
<%= f.label :custom_carousel_image_type, t("recruit_news.default_carousel_image_type"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<% carousel_image_types = ["default","carousel","album"] %>
|
||||
<%= f.select :custom_carousel_image_type, options_for_select(carousel_image_types.map.with_index{|type,i| [t("recruit_news.carousel_image_types.#{type}"),i]}.to_h,:selected => f.object.custom_carousel_image_type) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="carousel_image_width"><%= t("recruit_news.carousel_image_width") %></label>
|
||||
<div class="controls">
|
||||
<%= f.text_field :custom_carousel_image_width, :placeholder => t("recruit_news.custom_carousel_image_width_hint") %>
|
||||
</div>
|
||||
</div>
|
||||
<% if (!f.object.event_carousel_images.blank? rescue false) %>
|
||||
<div class="exist">
|
||||
<% f.object.event_carousel_images.each_with_index do |event_carousel_image, i| %>
|
||||
<%= f.fields_for :event_carousel_images, event_carousel_image do |f| %>
|
||||
<%= render :partial => 'form_image', :object => event_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 'bulletin_carousel_image_count', f.object.event_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("recruit_news.email_to") %></label>
|
||||
<div class="controls">
|
||||
|
||||
<label class="checkbox inline">
|
||||
<%= check_box_tag('recruit_news[email_sent]', '1', (!@recruit_news.email_sent.blank? ? true : false), :id=>'remind-check') %><%= t('recruit_news.activate_email_reminder')%>
|
||||
</label>
|
||||
|
||||
<div class="content-box">
|
||||
<%= render partial: 'admin/member_selects/email_selection_box', locals: {field: 'recruit_news[email_member_ids][]', email_members: @recruit_news.email_members, select_name: "mail_members", index: 'mail_members', extra_class: 'custom-class'} %>
|
||||
</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("recruit_news.other_mailaddress")}(#{t("recruit_news.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("recruit_news.email_sentdate") %></label>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :email_sentdate, :no_label => true %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if (@recruit_news.email.is_sent rescue false) %>
|
||||
<div class="content-box">
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t("recruit_news.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: (@recruit_news.title_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Speaker-->
|
||||
<div class="control-group input-speaker">
|
||||
<label class="control-label muted"><%= RecruitNewsCustomTitle.get_trans('speaker') %></label>
|
||||
<div class="controls">
|
||||
<%= f.fields_for :speaker_translations do |f| %>
|
||||
<%= f.text_field locale, class: "input-block-level", placeholder: t("recruit_news.speaker"), value: (@recruit_news.speaker_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Place-->
|
||||
<div class="control-group input-speaker">
|
||||
<label class="control-label muted"><%= RecruitNewsCustomTitle.get_trans('place') %></label>
|
||||
<div class="controls">
|
||||
<%= f.fields_for :place_translations do |f| %>
|
||||
<%= f.text_field locale, class: "input-block-level", placeholder: t("recruit_news.place"), value: (@recruit_news.place_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Host-->
|
||||
<div class="control-group input-host">
|
||||
<label class="control-label muted"><%= RecruitNewsCustomTitle.get_trans('host') %></label>
|
||||
<div class="controls">
|
||||
<%= f.fields_for :host_translations do |f| %>
|
||||
<%= f.text_field locale, class: "input-block-level", placeholder: t("recruit_news.host"), value: (@recruit_news.host_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: (@recruit_news.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 => (@recruit_news.text_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Notes -->
|
||||
<div class="control-group input-notes">
|
||||
<label class="control-label muted"><%= t("recruit_news.notes") %></label>
|
||||
<div class="controls">
|
||||
<div class="textarea">
|
||||
<%= f.fields_for :notes_translations do |f| %>
|
||||
<%= f.cktext_area locale, rows: 5, class: "input-block-level", :value => (@recruit_news.notes_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 @recruit_news && !@recruit_news.recruit_news_links.blank? %>
|
||||
<div class="exist">
|
||||
<% @recruit_news.recruit_news_links.each_with_index do |recruit_news_link, i| %>
|
||||
<%= f.fields_for :recruit_news_links, recruit_news_link do |f| %>
|
||||
<%= render :partial => 'form_link', :object => recruit_news_link, :locals => {:f => f, :i => i} %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Add -->
|
||||
<div class="add-target">
|
||||
</div>
|
||||
<p class="add-btn">
|
||||
<%= hidden_field_tag 'recruit_news_link_field_count', @recruit_news.recruit_news_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">
|
||||
|
||||
<!-- Exist -->
|
||||
<% if @recruit_news && !@recruit_news.recruit_news_files.blank? %>
|
||||
<div class="exist">
|
||||
<% @recruit_news.recruit_news_files.each_with_index do |recruit_news_file, i| %>
|
||||
<div class="file-sort-item">
|
||||
<%= f.fields_for :recruit_news_files, recruit_news_file do |ff| %>
|
||||
<%= ff.hidden_field :position, class: "file-position" %>
|
||||
<%= render :partial => 'form_file', :object => recruit_news_file, :locals => {:f => ff, :i => i} %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Add -->
|
||||
<div class="add-target">
|
||||
</div>
|
||||
<p class="add-btn">
|
||||
<%= hidden_field_tag 'recruit_news_file_field_count', @recruit_news.recruit_news_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_recruit_news_index_path, :class=>"btn" %>
|
||||
</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='recruit_news[tags][]']").is(":checked")){
|
||||
if(!confirm("You have selected no tag, do you wish to continue?")){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<% end %>
|
||||
<script>
|
||||
$("#event_date_use_default_setting").click(function(){$("#event_date_setting").toggleClass("hide")})
|
||||
$("#including_time").click(function(){$(".hour_clock_24_block").toggleClass("hide")})
|
||||
$("#recruit_news_display_img").click(function(){$("#image_display_setting").toggleClass("hide")})
|
||||
function Appendzero(obj)
|
||||
{
|
||||
if(obj<10) return "0" +""+ obj;
|
||||
else return obj;
|
||||
}
|
||||
|
||||
$(function() {
|
||||
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="recruit_news[event_date]"]').val(toDay);
|
||||
$('input[name="recruit_news[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_recruit_news_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, :recruit_news_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_recruit_news_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, :recruit_news_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();
|
||||
});
|
||||
$(document).on('click', '#add_carousel_image', function(){
|
||||
var new_id = $(this).prev().attr('value');
|
||||
var old_id = new RegExp("new_event_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, :event_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("recruit_news_id", '<%= @recruit_news.id.to_s %>');
|
||||
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: '<%= admin_recruit_news_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/recruit_news/destroy_preview/'+slug,function(data){
|
||||
// });
|
||||
// });
|
||||
});
|
||||
$('.main-forms input[name="_method"]').val(method);
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#recruit_news_is_top").parent().on("click",function(){
|
||||
setTimeout(function(){
|
||||
if($("#recruit_news_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)
|
||||
})
|
||||
|
||||
$("#recruit_news_is_external_link").on("click",function(){
|
||||
if($(this).is(":checked")){
|
||||
$("#external_link_box").show();
|
||||
}else{
|
||||
$("#external_link_box").hide();
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
$(function() {
|
||||
function init_exist_sortable() {
|
||||
var $container = $(".exist");
|
||||
if ($container.data("ui-sortable")) {
|
||||
$container.sortable("destroy");
|
||||
}
|
||||
$container.sortable({
|
||||
items: ".file-sort-item",
|
||||
handle: ".sort-order-icon, .file-link",
|
||||
axis: "y",
|
||||
placeholder: "ui-state-highlight",
|
||||
forcePlaceholderSize: true,
|
||||
update: function(event, ui) {
|
||||
$(".exist .file-sort-item").each(function(index) {
|
||||
$(this).find("input.file-position").val(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
init_exist_sortable();
|
||||
|
||||
$(document).on('click', '#add_file', function() {
|
||||
setTimeout(init_exist_sortable, 100);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<% 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">
|
||||
<i class="icons-list-2 sort-order-icon"></i>
|
||||
<% 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 "recruit_news[recruit_news_files_attributes][#{( form_file.new_record? ? 'new_recruit_news_files' : "#{i}" )}][choose_lang][]", locale, form_file.choose_lang.include?(locale.to_s), style: "float: inherit;" %>
|
||||
<%= t(locale.to_s) %>
|
||||
</label>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<%= hidden_field_tag "recruit_news[recruit_news_files_attributes][#{( form_file.new_record? ? 'new_recruit_news_files' : "#{i}" )}][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 %>
|
||||
</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 form_image.file.present? %>" data-provides="fileupload">
|
||||
<div class="fileupload-new thumbnail pull-left">
|
||||
<% if form_image.file.file %>
|
||||
<%= image_tag form_image.file %>
|
||||
<% else %>
|
||||
<img src="/assets/recruit_news/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,99 @@
|
|||
<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| %>
|
||||
<%= tmp = f.to_s.split('.')[-1]; RecruitNewsCustomTitle::KEYS.include?(tmp) ? Admin::RecruitNewsHelper.thead(tmp): thead(f) %>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @recruit_news.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_recruit_news(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("recruit_news.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/recruit_news/<%=b.id.to_s%>/edit"><%= t(:edit) %></a></li>
|
||||
<li><a href="#" class="delete text-error" rel="/admin/recruit_news/<%=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_recruit_news(b) %>" class="approval_button" data-id="<%= b.id.to_s %>" ><%= t("recruit_news.approval_waiting") %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
<td><%= format_value b.event_date %></td>
|
||||
<td><%= format_value b.postdate %></td>
|
||||
<td class="<%= b.expired? ? "expired" : "" %>"><%= format_value b.deadline %></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("recruit_news.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(@recruit_news), class: "pagination pagination-centered") +
|
||||
content_tag(:div, link_to(t(:new_),new_admin_recruit_news_path, :class=>"btn btn-primary"), class: "pull-right")
|
||||
end
|
||||
%>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<style type="text/css">
|
||||
.tab-panel .tab-content{
|
||||
display: none;
|
||||
}
|
||||
.tab-panel .tab-content.active{
|
||||
display: block;
|
||||
}
|
||||
.tab-panel .tab-content,.tab-panel .btn-group{
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
<%= form_tag({action: 'update_custom_title',method: 'post'}, {class: "form-horizontal main-forms previewable"}) do %>
|
||||
<% Admin::RecruitNewsHelper::FormHelper.set_input_name("recruit_news_custom_title") %>
|
||||
<% @recruit_news_custom_titles.each_with_index do |v,i| %>
|
||||
<div class="control-group">
|
||||
<%= label_tag :title , v.default_title, :class=>"control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= hidden_field_tag "recruit_news_custom_title[#{i}][id]", v.id %>
|
||||
<%= Admin::RecruitNewsHelper::FormHelper.multiple_lang_tag(i,'text_field','title_translations',v.title_translations,{placeholder: v.default_title}) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="form-actions">
|
||||
<%= submit_tag t(:submit),class: 'btn btn-primary' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<%= form_for @recruit_news, url: admin_recruit_news_path(@recruit_news), html: {class: "form-horizontal main-forms previewable"} do |f| %>
|
||||
<fieldset>
|
||||
<%= render :partial => 'form', locals: {f: f} %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<% content_for :page_specific_css do %>
|
||||
<%= stylesheet_link_tag "lib/main-forms" %>
|
||||
<%= stylesheet_link_tag "lib/fileupload" %>
|
||||
<%= stylesheet_link_tag "lib/main-list" %>
|
||||
<% end %>
|
||||
<%= form_for @setting, url: update_sort_setting_admin_recruit_news_index_path, html: {class: "form-horizontal main-forms"}, method: 'post' do |f| %>
|
||||
<div class="input-area">
|
||||
<div class="control-group">
|
||||
<%= f.label :maull, t("recruit_news.enable_manually_sort"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :enable_manually_sort,:id=>'enable_manually_sort' %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div style="margin-bottom: 1em;">
|
||||
<button type="button" class="btn btn-primary" id="update_sort_button"><%= t('recruit_news.manual_update_sort') %></button>
|
||||
</div>
|
||||
<%= render partial: 'edit_sort' %>
|
||||
<script type="text/javascript">
|
||||
function parse_val(val){
|
||||
return (val == '') ? 0 : parseFloat(val);
|
||||
}
|
||||
function update_sort(){
|
||||
var ids = $.map($('#sortable>tr'),function(v){return $(v).data('id')});
|
||||
$.ajax({
|
||||
url: "<%= update_sort_admin_recruit_news_index_path %>",
|
||||
type: 'POST',
|
||||
dataType: 'text',
|
||||
data: {ids: ids},
|
||||
success: function(data){
|
||||
$('#data-table').replaceWith(data);
|
||||
sortable();
|
||||
}
|
||||
});
|
||||
}
|
||||
function sortable(){
|
||||
$( "#sortable" ).sortable({
|
||||
update: function( event, ui ) {
|
||||
update_sort();
|
||||
}
|
||||
});
|
||||
$('.sort_number').change(function(){
|
||||
$(this).data('changed', true);
|
||||
});
|
||||
$('.sort_number').on('blur', function(){
|
||||
if(!$(this).data('changed')) {
|
||||
return;
|
||||
}
|
||||
var new_sort_number = parse_val($(this).val());
|
||||
var min_number = 0;
|
||||
var max_number = $('.sort_number').length;
|
||||
var pool = $('.sort_number').not(this);
|
||||
var same_order = pool.filter(function(){
|
||||
var tmp_sort = parse_val($(this).val());
|
||||
if (tmp_sort<min_number){
|
||||
min_number = tmp_sort;
|
||||
}
|
||||
if (tmp_sort>max_number){
|
||||
max_number = tmp_sort;
|
||||
}
|
||||
return tmp_sort==new_sort_number
|
||||
});
|
||||
var tmp_same_order = $();
|
||||
if (same_order.length>0) {
|
||||
tmp_same_order = same_order.eq(0);
|
||||
tmp_same_order.parents('tr').eq(0).before($(this).parents('tr').eq(0));
|
||||
} else if (new_sort_number>=max_number) {
|
||||
tmp_same_order = pool.eq(-1);
|
||||
tmp_same_order.parents('tr').eq(0).after($(this).parents('tr').eq(0));
|
||||
} else if (new_sort_number<=min_number) {
|
||||
tmp_same_order = pool.eq(0);
|
||||
tmp_same_order.parents('tr').eq(0).before($(this).parents('tr').eq(0));
|
||||
}
|
||||
update_sort();
|
||||
$(this).data('changed', false);
|
||||
});
|
||||
}
|
||||
$(document).ready(function(){
|
||||
$('#update_sort_button').click(update_sort);
|
||||
$('#enable_manually_sort').change(function(){
|
||||
$(this).parents('form').submit();
|
||||
})
|
||||
sortable();
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
# encoding: utf-8
|
||||
|
||||
wb = xlsx_package.workbook
|
||||
|
||||
wb.add_worksheet(name: "EventNewsModule") 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("event_news.event_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/10 15:20"
|
||||
|
||||
row << t("event_news.start_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/10 15:30"
|
||||
|
||||
row << t("event_news.end_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/12 17:30"
|
||||
|
||||
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("event_news.speaker") + " - " + t("en")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.speaker") + " - " + t("zh_tw")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
|
||||
row << t("event_news.host") + " - " + t("en")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.host") + " - " + 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("event_news.notes") + " - " + t("en")
|
||||
row1 << "editor"
|
||||
row2 << ""
|
||||
row << t("event_news.notes") + " - " + 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"
|
||||
|
||||
row << t("event_news.place") + "-" + t("en")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.place") + "-" + t("zh_tw")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.event_end_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/10 15:20"
|
||||
row << t("event_news.carousel_image") + "-" + t("image")
|
||||
row1 << "url"
|
||||
row2 << "Seperate with ';'. Example: http://www.example.com/images/example.png; http://www.example.com/images/example2.png"
|
||||
row << t("event_news.carousel_image") + "-" + 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("event_news.carousel_image") + "-" + t("description") + " - " + t("zh_tw")
|
||||
row1 << "textfield"
|
||||
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Great view; Nice potrait"
|
||||
sheet.add_row row, :style => heading
|
||||
sheet.add_row row1
|
||||
sheet.add_row row2, :style => example
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
# encoding: utf-8
|
||||
|
||||
wb = xlsx_package.workbook
|
||||
|
||||
wb.add_worksheet(name: "EventNewsModule") 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("event_news.event_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/10 15:20"
|
||||
|
||||
row << t("event_news.start_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/10 15:30"
|
||||
|
||||
row << t("event_news.end_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/12 17:30"
|
||||
|
||||
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("event_news.speaker") + " - " + t("en")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.speaker") + " - " + t("zh_tw")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
|
||||
row << t("event_news.host") + " - " + t("en")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.host") + " - " + 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("event_news.notes") + " - " + t("en")
|
||||
row1 << "editor"
|
||||
row2 << ""
|
||||
row << t("event_news.notes") + " - " + 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"
|
||||
|
||||
row << t("event_news.place") + "-" + t("en")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.place") + "-" + t("zh_tw")
|
||||
row1 << "textfield"
|
||||
row2 << ""
|
||||
row << t("event_news.event_end_date")
|
||||
row1 << "datetime"
|
||||
row2 << "Format: YYYY/MM/DD HH:mm, Example: 2015/12/10 15:20"
|
||||
row << t("event_news.carousel_image") + "-" + t("image")
|
||||
row1 << "url"
|
||||
row2 << "Seperate with ';'. Example: http://www.example.com/images/example.png; http://www.example.com/images/example2.png"
|
||||
row << t("event_news.carousel_image") + "-" + 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("event_news.carousel_image") + "-" + t("description") + " - " + t("zh_tw")
|
||||
row1 << "textfield"
|
||||
row2 << "Seperate with ';' with respective to the links in the link columns. Example : Great view; Nice potrait"
|
||||
sheet.add_row row, :style => heading
|
||||
sheet.add_row row1
|
||||
sheet.add_row row2, :style => example
|
||||
if @thread
|
||||
all_count = @event_news.count
|
||||
puts_every_count = [all_count * 3 / 100, 1].max
|
||||
current_count = 0
|
||||
finish_percent = 0
|
||||
@thread.update(:status=>{:status=>'Processing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||
end
|
||||
@event_news.each do |anns|
|
||||
row = []
|
||||
row << categories.to_a.index(anns.category)
|
||||
t = []
|
||||
anns.tags.each do |tag|
|
||||
t << tags.to_a.index(tag)
|
||||
end
|
||||
row << t.join(",")
|
||||
row << (anns.event_date.strftime("%Y/%m/%d %H:%M") rescue "")
|
||||
row << (anns.postdate.strftime("%Y/%m/%d %H:%M") rescue "")
|
||||
row << (anns.deadline.strftime("%Y/%m/%d %H:%M") rescue "")
|
||||
row << (anns.is_top? ? 1 : 0)
|
||||
row << (anns.is_hot? ? 1 : 0)
|
||||
row << (anns.is_hidden? ? 1 : 0)
|
||||
row << ("http://" + request.host_with_port + anns.image.url rescue "")
|
||||
row << anns.image_description_translations["en"]
|
||||
row << anns.image_description_translations["zh_tw"]
|
||||
row << anns.title_translations["en"]
|
||||
row << anns.title_translations["zh_tw"]
|
||||
row << anns.speaker_translations["en"]
|
||||
row << anns.speaker_translations["zh_tw"]
|
||||
row << anns.host_translations["en"]
|
||||
row << anns.host_translations["zh_tw"]
|
||||
row << anns.subtitle_translations["en"]
|
||||
row << anns.subtitle_translations["zh_tw"]
|
||||
row << anns.text_translations["en"]
|
||||
row << anns.text_translations["zh_tw"]
|
||||
row << anns.notes_translations["en"]
|
||||
row << anns.notes_translations["zh_tw"]
|
||||
|
||||
links = anns.event_news_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 = anns.event_news_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(";")
|
||||
row << anns.place_translations["en"]
|
||||
row << anns.place_translations["zh_tw"]
|
||||
|
||||
row << (anns.event_end_date.strftime("%Y/%m/%d %H:%M") rescue "")
|
||||
|
||||
carousel_images = anns.event_carousel_images.asc(:created_at)
|
||||
t = carousel_images.collect{|f|("http://" + request.host_with_port + f.file.url rescue nil)}
|
||||
t.delete(nil)
|
||||
row << t.join(";")
|
||||
t = carousel_images.collect{|l|l.description_translations["en"]}
|
||||
row << t.join(";")
|
||||
t = carousel_images.collect{|l|l.description_translations["zh_tw"]}
|
||||
row << t.join(";")
|
||||
sheet.add_row row
|
||||
if @thread
|
||||
current_count += 1
|
||||
if current_count % puts_every_count == 0
|
||||
finish_percent = (current_count * 100.0 / all_count).round(1)
|
||||
@thread.update(:status=>{:status=>'Processing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||
end
|
||||
end
|
||||
end
|
||||
if @thread
|
||||
finish_percent = 100
|
||||
@thread.update(:status=>{:status=>'finish','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||
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/recruit_news/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,170 @@
|
|||
<% content_for :page_specific_javascript do %>
|
||||
<script type="text/javascript" src="/assets/validator.js"></script>
|
||||
<% end %>
|
||||
<% if @thread %>
|
||||
<div id="threadModal" class="modal hide fade in" tabindex="-1" role="dialog" aria-labelledby="threadModal" aria-hidden="false">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="threadModal"><%=t("e_paper.#{@thread.key}")%></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="thread-status"><%= @thread.status[:status] %></div>
|
||||
<div class="thread-count-zone <%= 'hide' unless @thread.status[:current_count]%>">
|
||||
<span class="thread-current-count"><%= @thread.status[:current_count].to_i %></span>/<span class="thread-all-count"><%= @thread.status[:all_count].to_i %></span>
|
||||
</div>
|
||||
<span class="thread-finish_percent"><%= @thread.status[:finish_percent].to_i %></span> % finished
|
||||
<br>
|
||||
<span class="thread-info"><%= @thread.status[:info].to_s.html_safe %></span>
|
||||
<br>
|
||||
<span class="thread-file">
|
||||
<% if @thread.status[:filename] %>
|
||||
<a href="<%=admin_recruit_news_download_file_from_thread_path(:id=>@thread.id.to_s) %>" title="<%= @thread.status[:filename] %>"><%= @thread.status[:filename] %></a>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" id="modal-close-btn" style="width: 4em;" data-dismiss="modal" aria-hidden="true"><%=t('close')%></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<form action="<%= admin_recruit_news_importanns_path %>" method="post" class="form-horizontal main-forms" id="import-anns-xls" enctype="multipart/form-data">
|
||||
<h3 style="padding-left: 30px;"><%= t("recruit_news.export_to_excel") %></h3>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<a href="<%= admin_recruit_news_export_excel_path %>"><%= t("recruit_news.export_all_anns") %></a>
|
||||
</div>
|
||||
</div>
|
||||
<h3 style="padding-left: 30px;"><%= t("recruit_news.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_recruit_news_excel_format_path(:format => "xlsx") %>"><%= t("recruit_news.download_example_sheet_here") %></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="import-anns" class="control-label muted"><%= t("upload") %></label>
|
||||
<div class="controls">
|
||||
<input type="file" id="import-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("recruit_news.please_create_tags_cats") %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<h4><%= t("recruit_news.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_recruit_news_import_from_wp_path %>" method="post" class="form-horizontal main-forms" id="import-anns-wp-xml" enctype="multipart/form-data">
|
||||
<h3 style="padding-left: 30px;"><%= t("recruit_news.import_from_wp_xml") %></h3>
|
||||
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
||||
<div class="input-area">
|
||||
<div class="control-group">
|
||||
<label for="import-anns-wp-xml" class="control-label muted"><%= t("upload") %></label>
|
||||
<div class="controls">
|
||||
<input type="file" id="import-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_recruit_news_import_from_xml_path %>" method="post" class="form-horizontal main-forms" id="import-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-anns" class="control-label muted">URL :</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="import-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-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-anns-wp-xml"));
|
||||
form.validate_functions.mustbexml = function(val){
|
||||
var t = val.split("."),
|
||||
ext = t[t.length - 1];
|
||||
return (ext == "xml")
|
||||
}
|
||||
$(document).ready(function(){
|
||||
function update_thread(){
|
||||
$.post("<%=admin_threads_get_status_path%>",{"id": "<%=params[:thread_id]%>"}).done(function(data){
|
||||
var finish_percent = data["finish_percent"];
|
||||
var current_count = data["current_count"];
|
||||
var all_count = data["all_count"];
|
||||
var is_finish = (data["status"] == "finish" || data["status"] == "error");
|
||||
var info = data["info"]
|
||||
if(finish_percent){
|
||||
$("#threadModal .modal-body .thread-status").text(data["status"]);
|
||||
if(data["current_count"]){
|
||||
$("#threadModal .modal-body .thread-count-zone").removeClass('hide');
|
||||
$("#threadModal .modal-body .thread-current-count").text(current_count);
|
||||
$("#threadModal .modal-body .thread-all-count").text(all_count);
|
||||
}else{
|
||||
$("#threadModal .modal-body .thread-count-zone").addClass('hide');
|
||||
}
|
||||
$("#threadModal .modal-body .thread-finish_percent").text(finish_percent);
|
||||
if(info){
|
||||
$("#threadModal .modal-body .thread-info").text(info);
|
||||
}
|
||||
}
|
||||
if(!is_finish){
|
||||
window.time_out_id = window.setTimeout(update_thread, 1000);
|
||||
}else{
|
||||
var id = "<%=@thread.id if @thread%>";
|
||||
var filename = data["filename"];
|
||||
if(filename){
|
||||
$("#threadModal .modal-body .thread-file").html(`<a href="<%=admin_recruit_news_download_file_from_thread_path%>?id=${id}" title="${filename}">${filename}</a>`);
|
||||
}
|
||||
if(window.time_out_id)
|
||||
window.clearTimeout(window.time_out_id);
|
||||
// window.setTimeout(function(){
|
||||
// $("#threadModal").modal("hide");
|
||||
// alert(data["status"]);
|
||||
// }, 3000);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
if($("#threadModal").length != 0){
|
||||
$("#threadModal").on('hidden.bs.modal',function(){
|
||||
window.clearTimeout(window.time_out_id);
|
||||
window.history.replaceState(null,$('title').text(),window.location.pathname);
|
||||
})
|
||||
$("#threadModal").on('shown.bs.modal',function(){
|
||||
window.time_out_id = window.setTimeout(update_thread, 1000);
|
||||
})
|
||||
$("#threadModal").modal("show");
|
||||
$(".show_progress").click(function(){
|
||||
$("#threadModal").modal("show");
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<%= render_filter @filter_fields, "index_table" %>
|
||||
<span id="index_table">
|
||||
<%= render 'index'%>
|
||||
</span>
|
||||
|
||||
<%= render 'layouts/delete_modal', delete_options: @delete_options %>
|
||||
|
||||
<% if 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 @recruit_news, url: admin_recruit_news_index_path, html: {class: "form-horizontal main-forms previewable"} do |f| %>
|
||||
<fieldset>
|
||||
<%= render :partial => 'form', locals: {f: f} %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
|
@ -0,0 +1,431 @@
|
|||
<%= 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%;
|
||||
}
|
||||
legend {
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
<%
|
||||
sub_managers = @module_app.sub_managers
|
||||
sub_managers.delete(nil)
|
||||
all_statuses = [[t('top'),'is_top'],[t('hot'),'is_hot']]
|
||||
tp1 = select_tag("recruit_news_setting[anns_status_settings][-1][status]",options_for_select(all_statuses))
|
||||
tp2 = select_tag("recruit_news_setting[anns_status_settings][-1][role_id]",options_for_select(Role.all.map{|r| [r.title,r.id]}))
|
||||
tp3 = number_field_tag("recruit_news_setting[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^="recruit_news_setting[anns_status_settings]"]').each(function(i1,v1){
|
||||
console.log($(v1).attr('name'))
|
||||
$(v1).attr('name',$(v1).attr('name').replace(/\d+/g,i.toString()))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
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", "recruit_news_setting[approvers][]");
|
||||
t.attr("id", "check_" + el.val());
|
||||
approverList.append(t);
|
||||
}else{
|
||||
approverList.find("#check_" + el.val()).remove();
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<div id="notification"><%= t("recruit_news.click_on_submit") %></div>
|
||||
<%= form_for @setting, url: (@setting.new_record? ? admin_recruit_news_createsettings_path : admin_recruit_news_updatesettings_path), html: {class: "form-horizontal main-forms"} do |f| %>
|
||||
<div class="input-area">
|
||||
<div class="control-group">
|
||||
<%= f.label :carousel_image_type, t("recruit_news.default_carousel_image_type"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<% carousel_image_types = ["carousel","album"] %>
|
||||
<%= f.select :carousel_image_type, options_for_select(carousel_image_types.map.with_index{|type,i| [t("recruit_news.carousel_image_types.#{type}"),i]}.to_h,:selected => f.object.carousel_image_type) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :carousel_image_width, t("recruit_news.default_carousel_image_width"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.text_field :carousel_image_width %>
|
||||
</div>
|
||||
</div>
|
||||
<fieldset id="event_date_setting">
|
||||
<legend><%=t("recruit_news.event_date_setting")%></legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= I18n.t("recruit_news.including_day_of_the_week") %></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :including_day_of_the_week %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= I18n.t("recruit_news.including_time") %></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :including_time, :id=>"including_time" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hour_clock_24_block control-group <%= 'hide' if !(f.object.including_time) %>">
|
||||
<label class="control-label muted"><%= I18n.t("recruit_news.hour_clock_24") %></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :hour_clock_24 %>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="control-group">
|
||||
<%= f.label :only_manager_can_edit_status, t("recruit_news.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("recruit_news.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 :is_postdate_sort_first, t("recruit_news.is_postdate_sort_first"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :is_postdate_sort_first %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :top_limit, t("recruit_news.top_limit"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.number_field :top_limit, :min => "0" %>
|
||||
<span class="help-block"><%= t("recruit_news.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('recruit_news.top_limit') %>
|
||||
</div>
|
||||
</div>
|
||||
<% (RecruitNewsSetting.first.anns_status_settings rescue []).each_with_index do |v,i| %>
|
||||
<div class="role_limit_tr">
|
||||
<%= hidden_field_tag("recruit_news_setting[anns_status_settings][#{i}][_id]",v.id) %>
|
||||
<div class="td">
|
||||
<%= select_tag("recruit_news_setting[anns_status_settings][#{i}][status]",options_for_select(all_statuses,:selected => v['status'])) %>
|
||||
</div>
|
||||
<div class="td">
|
||||
<%= select_tag("recruit_news_setting[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("recruit_news_setting[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 RecruitNewsSetting.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("recruit_news.approvers_list") %></a>
|
||||
<span class="badge badge-info"><%= @setting.approvers.count %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="control-group">
|
||||
<a href="/admin/authorizations/recruit_news"><%= t("recruit_news.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="recruit_news_setting[email_to][]" value="admins" <%= @setting.email_to.include?("admins") ? "checked=checked" : "" %>> <%= t("admin") %>
|
||||
<input type="checkbox" name="recruit_news_setting[email_to][]" value="managers" <%= @setting.email_to.include?("managers") ? "checked=checked" : "" %>> <%= t("manager") %>
|
||||
<input type="checkbox" name="recruit_news_setting[email_to][]" value="approvers" <%= @setting.email_to.include?("approvers") ? "checked=checked" : "" %>> <%= t("recruit_news.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="recruit_news_setting[approvers][]">
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="form-actions">
|
||||
<%= f.submit t('submit'), class: 'btn btn-primary' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if RecruitNewsSetting.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("recruit_news.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('recruit_news.recruit_news_setting_for_iframe')%></legend>
|
||||
<div class="control-group">
|
||||
<%= f.label :layout_type, t("recruit_news.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('recruit_news.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('recruit_news.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("recruit_news.url_generate") %>" id="url_generate"><%= t("recruit_news.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_recruit_news_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('recruit_news.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('recruit_news.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('recruit_news.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 @@
|
|||
<%= render partial: 'edit_sort' %>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<h3>Hello <%= @data["name"] %>,</h3>
|
||||
<p><%= @data["submitter"] %> <%= t("recruit_news.updated_annoucement") %>
|
||||
<a href="<%= @data['url'] %>" ><%= t("recruit_news.click_here_to_see") %></a>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<%= @data["html"].html_safe %>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<h3>Hello <%= @data["name"] %>,</h3>
|
||||
<p><%= @data["rejector"] %> <%= t("recruit_news.rejected_recruit_news") %> : <%= @data["reason"].nil? || @data["reason"] == "" ? "" : "#{@data["reason"]}" %></p>
|
||||
<a href="<%= @data['url'] %>" ><%= t("recruit_news.click_here_to_see") %></a>
|
||||
|
|
@ -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/recruit_news/rssfeed/#{params[:uid]}.rss"
|
||||
|
||||
for e in @recruit_news
|
||||
xml.item do
|
||||
xml.title e.title
|
||||
xml.description e.subtitle
|
||||
xml.pubDate e.created_at.to_s(:rfc822)
|
||||
xml.link page_for_recruit_news(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
<%= render(:partial=>"recruit_news_mods/carousels#{carousel_image_type}", :locals=>{:data=>data}) %>
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
<style type="text/css">
|
||||
strong.carousel__description {
|
||||
color: white;
|
||||
}
|
||||
.carousel_images{
|
||||
<%=data["carousel_display_style"]%>
|
||||
}
|
||||
@media (max-width: 767px){
|
||||
.carousel_images{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="carousel_images">
|
||||
<div class="w-ba-banner ba-banner-widget-1">
|
||||
<div class="w-ba-banner__wrap cycle-slideshow"
|
||||
data-cycle-slides=".event_carousel_slide"
|
||||
data-cycle-log="false"
|
||||
data-cycle-auto-height="0"
|
||||
data-cycle-speed="300"
|
||||
data-cycle-timeout="5000"
|
||||
data-cycle-fx="fade"
|
||||
data-pager-active-class="active-slide"
|
||||
data-cycle-swipe=true
|
||||
data-cycle-swipe-fx="scrollHorz"
|
||||
>
|
||||
<%data["event_carousel_images"].each do |event_carousel_image|%>
|
||||
<div class="w-ba-banner__slide event_carousel_slide"
|
||||
data-cycle-title="<%=event_carousel_image["description_text"]%>"
|
||||
>
|
||||
<img class="w-ba-banner__image banner-responsive" src="<%=event_carousel_image["src"]%>" alt="<%=event_carousel_image["description_text"]%>">
|
||||
<div class="ad-overlay w-ad-banner__overlay event_carousel__overlay">
|
||||
<p><strong class="carousel__description"><%=event_carousel_image["description"]%></strong></p>
|
||||
</div>
|
||||
<div class="transitionfade"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<ul class="controlplay"><a class="resume-slide" title = "<%=data["resume_btn_title"]%>"><i></i></a><a class="pause-slide" title = "<%=data["pause_btn_title"]%>"><i></i></a></ul>
|
||||
<ul class="button-mid">
|
||||
<i class="fa fa-angle-left prev-button" aria-hidden="true" title = "<%=data["prev_btn_title"]%>"></i>
|
||||
<i class="fa fa-angle-right next-button" aria-hidden="true" title = "<%=data["next_btn_title"]%>"></i>
|
||||
</ul>
|
||||
</div>
|
||||
<div style="position: relative;">
|
||||
<h4><span class="active_slide">1</span>/<%=data["carousel_count"]%></h4>
|
||||
<ul class="carousel_images_slide w-annc__list row list-unstyled">
|
||||
<%data["event_carousel_images"].each do |event_carousel_image|%>
|
||||
<li class="carousel_img_item col-sm-3">
|
||||
<div class="carousel_img-wrap">
|
||||
<img class="carousel_img" src="<%=event_carousel_image["src"]%>" alt="<%=event_carousel_image["description_text"]%>">
|
||||
</div>
|
||||
</li>
|
||||
<%end%>
|
||||
</ul>
|
||||
<ul class="button-mid">
|
||||
<i class="fa fa-angle-left prev-button prev_img" aria-hidden="true" title="<%=data["prev_btn_title"]%>"></i>
|
||||
<i class="fa fa-angle-right next-button next_img" aria-hidden="true" title="<%=data["next_btn_title"]%>"></i>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<style type="text/css">
|
||||
.carousel_img_item{
|
||||
display: none;
|
||||
float: left;
|
||||
}
|
||||
.controlplay {
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 3%;
|
||||
z-index: 200;
|
||||
}
|
||||
.controlplay a {
|
||||
display: inline-block;
|
||||
margin-right: 0.25em;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid rgba(255,255,255,0.5);
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.controlplay a i {
|
||||
font-family: FontAwesome;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
color: #FFF;
|
||||
vertical-align: middle;
|
||||
font-style: unset;
|
||||
}
|
||||
.controlplay .resume-slide i::before {
|
||||
content: "\f04b";
|
||||
}
|
||||
.controlplay .pause-slide i::before {
|
||||
content: "\f04c";
|
||||
}
|
||||
ul.button-mid .prev-button {
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
float: left;
|
||||
left: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
ul.button-mid .next-button {
|
||||
float: right;
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
right: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #fff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
.carousel_images_slide{
|
||||
padding: 3em;
|
||||
}
|
||||
.carousel_img_item img{
|
||||
cursor: pointer;
|
||||
}
|
||||
@media (max-width: 479px){
|
||||
.carousel_img_item:nth-child(-n+1){
|
||||
display: block;
|
||||
width: 100%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 480px){
|
||||
.carousel_img_item:nth-child(-n+2){
|
||||
display: block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px){
|
||||
.carousel_img_item:nth-child(-n+3){
|
||||
display: block;
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px){
|
||||
.carousel_img_item:nth-child(-n+4){
|
||||
display: block;
|
||||
width: 25%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
(function($) {
|
||||
$('.pause-slide').click(function(){
|
||||
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle('pause');
|
||||
});
|
||||
$('.resume-slide').click(function(){
|
||||
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle('resume');
|
||||
});
|
||||
$('.next-button').off('click').on('click',function(){
|
||||
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle("next");
|
||||
})
|
||||
$('.prev-button').off('click').on('click',function(){
|
||||
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle("prev");
|
||||
})
|
||||
window.active_slide = 0;
|
||||
$('.prev_img').off('click').on('click',function(){
|
||||
var carousel_images_slide = $('.carousel_images_slide');
|
||||
var carousel_images_slide_first_child = carousel_images_slide.find(">li").eq(active_slide);
|
||||
if(carousel_images_slide_first_child.length > 0){
|
||||
var content_size = Math.floor((carousel_images_slide.outerWidth() - Number.parseInt(carousel_images_slide.css('font-size')) * 3) / carousel_images_slide_first_child.outerWidth(true));
|
||||
content_size = Math.max(content_size,1);
|
||||
if(carousel_images_slide.find(">li").length > content_size && active_slide > 0){
|
||||
active_slide -= content_size;
|
||||
carousel_images_slide.find(">li").css("display","none");
|
||||
for(var i = active_slide; i < active_slide + content_size;i++){
|
||||
carousel_images_slide.find(">li").eq(i).css("display","block");
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
$('.next_img').off('click').on('click',function(){
|
||||
var carousel_images_slide = $('.carousel_images_slide');
|
||||
var carousel_images_slide_first_child = carousel_images_slide.find(">li").eq(active_slide);
|
||||
if(carousel_images_slide_first_child.length > 0){
|
||||
var content_size = Math.floor((carousel_images_slide.outerWidth() - Number.parseInt(carousel_images_slide.css('font-size')) * 3) / carousel_images_slide_first_child.outerWidth(true));
|
||||
content_size = Math.max(content_size,1);
|
||||
var li_length = carousel_images_slide.find(">li").length;
|
||||
if(li_length > content_size){
|
||||
active_slide += content_size;
|
||||
active_slide = Math.min(active_slide,li_length - 1);
|
||||
carousel_images_slide.find(">li").css("display","none");
|
||||
for(var i = active_slide; i < active_slide + content_size;i++){
|
||||
carousel_images_slide.find(">li").eq(i).css("display","block");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
$(".carousel_img_item img").off("click").on("click",function(){
|
||||
$(".carousel_images .cycle-slideshow").cycle($(this).index(".carousel_img_item img"));
|
||||
})
|
||||
$(document).ready(function(){
|
||||
$(".carousel_images .cycle-slideshow").cycle('pause');
|
||||
var carousel_image_block_width = $('.carousel_images').width();
|
||||
var heights = $(".event_carousel_slide").map(function(i,v){
|
||||
return $(v).height() * carousel_image_block_width / $(v).width();
|
||||
})
|
||||
var max_height = Math.max.apply(null,heights);
|
||||
$(".event_carousel_slide").each(function(i,v){
|
||||
$(v).height(max_height);
|
||||
})
|
||||
$(".carousel_images .cycle-slideshow").cycle('resume');
|
||||
$('.cycle-slideshow').on('cycle-after',function(){
|
||||
$(".active_slide").text($('.event_carousel_slide.cycle-slide-active').index());
|
||||
})
|
||||
})
|
||||
$(window).on("load",function(){
|
||||
$(".carousel_images .cycle-slideshow").cycle('pause');
|
||||
var carousel_image_block_width = $('.carousel_images').width();
|
||||
var heights = $(".event_carousel_slide").map(function(i,v){
|
||||
return $(v).height() * carousel_image_block_width / $(v).width();
|
||||
})
|
||||
var max_height = Math.max.apply(null,heights);
|
||||
$(".event_carousel_slide").each(function(i,v){
|
||||
$(v).height(max_height);
|
||||
})
|
||||
$(".carousel_images .cycle-slideshow").cycle('resume');
|
||||
})
|
||||
$(window).resize(function(){
|
||||
var carousel_images_slide = $('.carousel_images_slide');
|
||||
var carousel_images_slide_first_child = carousel_images_slide.find(">li").eq(active_slide);
|
||||
if(carousel_images_slide_first_child.length > 0){
|
||||
var content_size = Math.floor((carousel_images_slide.outerWidth() - Number.parseInt(carousel_images_slide.css('font-size')) * 3) / carousel_images_slide_first_child.outerWidth(true));
|
||||
content_size = Math.max(content_size,1);
|
||||
carousel_images_slide.find(">li").css("display","none");
|
||||
var active_count = carousel_images_slide.find(">li").length - active_slide;
|
||||
if(active_count < content_size){
|
||||
active_slide -= (content_size - active_count);
|
||||
}
|
||||
active_slide = Math.max(active_slide,0);
|
||||
console.log(content_size)
|
||||
for(var i = active_slide; i < active_slide + content_size;i++){
|
||||
carousel_images_slide.find(">li").eq(i).css("display","block");
|
||||
}
|
||||
}
|
||||
var carousel_image_block_width = $('.carousel_images').width();
|
||||
$(".event_carousel_slide").css("height",'');
|
||||
var heights = $(".event_carousel_slide").map(function(i,v){
|
||||
return $(v).height() * carousel_image_block_width / $(v).width();
|
||||
})
|
||||
var max_height = Math.max.apply(null,heights);
|
||||
$(".event_carousel_slide").each(function(i,v){
|
||||
$(v).height(max_height);
|
||||
})
|
||||
})
|
||||
}(jQuery));
|
||||
</script>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<style>
|
||||
.carousel_image p{
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<div class="carousel_images">
|
||||
<%data["event_carousel_images"].each do |event_carousel_image|%>
|
||||
<div class="carousel_image col-sm-6">
|
||||
<a href="<%=event_carousel_image["src"]%>" title="<%=event_carousel_image["description_text"]%>"><img src="<%=event_carousel_image["src"]%>" alt="<%=event_carousel_image["description_text"]%>"></a>
|
||||
<p><strong class="carousel__description"><%=event_carousel_image["description"]%></strong></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
@ -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('recruit_news.mail_hi') %> <br /><br />
|
||||
<%= t('recruit_news.mail_url_view') %> <br /><br />
|
||||
<a href="<%= @data["url"] %>" target="_blank"> <%= @data["title"] %> </a> <br /><br />
|
||||
|
||||
<span style="color:#555">--<br />
|
||||
<%= t('recruit_news.mail_source') %> :<a href="http://<%= @data["host"] %>" target="_blank"> <%= Site.first.title %> </a><br />
|
||||
<%= t('recruit_news.mail_time') %> <%= DateTime.now %>
|
||||
</span>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<%
|
||||
params = OrbitHelper.params
|
||||
%>
|
||||
<% 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>
|
||||
<%
|
||||
all_cat = [[t('recruit_news.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(@categories.map{|v| [v.title,v.id.to_s]}),:selected => params['category'].to_s),:id=>"category_select_box",:prompt => t('recruit_news.select_prompt')) %>
|
||||
<input class="search_box" type="text" name="keywords" value="<%= params['keywords'].to_s.gsub(/\"/,'') %>" placeholder="<%= t('recruit_news.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('recruit_news.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('recruit_news.etime') %>" data-format="yyyy/mm/dd">
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
|
||||
<input class="search_box" type="submit" value="<%= t('recruit_news.search') %>">
|
||||
</div>
|
||||
</form>
|
||||
<% end %>
|
||||
<%= render_view %>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<%
|
||||
require 'recruit_news_helper'
|
||||
data = action_data
|
||||
params = OrbitHelper.params
|
||||
page = @page || Page.where(url:params['url']).first
|
||||
@ad_banner_location = 2
|
||||
@show_back_and_next_flag = 0
|
||||
if Page.instance_methods.include?(:select_option_items) && ModuleApp.instance_methods.include?(:show_option_items)
|
||||
@show_option_items = nil
|
||||
ModuleApp.all.select{|tmp| tmp.key.to_s=='recruit_news_mod'}.each do |module_app|
|
||||
@show_option_items = module_app.show_option_items
|
||||
end
|
||||
page.select_option_items.each do |select_option_item|
|
||||
unless @show_option_items.nil?
|
||||
if 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('recruit_news.not_show')
|
||||
@show_back_and_next_flag = 0
|
||||
elsif tmp == t('recruit_news.show_top')
|
||||
@show_back_and_next_flag = 1
|
||||
elsif tmp == t('recruit_news.show_bottom')
|
||||
@show_back_and_next_flag = 2
|
||||
end
|
||||
end
|
||||
elsif select_option_item.field_name == @show_option_items.keys[2].to_s
|
||||
value = YAML.load(select_option_item.value)
|
||||
tmp = value[:en]
|
||||
I18n.with_locale(:en) do
|
||||
if tmp == t('recruit_news.show_top')
|
||||
@ad_banner_location = 1
|
||||
elsif tmp == t('recruit_news.show_bottom')
|
||||
@ad_banner_location = 2
|
||||
end
|
||||
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('recruit_news.prev')}' class='prev'><b>#{t('recruit_news.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('recruit_news.next')}' class='next'><b>#{t('recruit_news.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
|
||||
%>
|
||||
<%= stylesheet_link_tag 'recruit_news_front.css' %>
|
||||
<% 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 %>
|
||||
|
||||
<% if @ad_banner_location==1 %>
|
||||
<%= data["data"]["carousel_html"] %>
|
||||
<% end %>
|
||||
|
||||
<%= render_view %>
|
||||
|
||||
<% if @ad_banner_location==2 %>
|
||||
<%= data["data"]["carousel_html"] %>
|
||||
<% end %>
|
||||
|
||||
<% if @show_back_and_next_flag==2 %>
|
||||
<%= content %>
|
||||
<% end %>
|
||||
|
||||
<script>
|
||||
(function($) {
|
||||
|
||||
function hideEmptyEl(el, elParent) {
|
||||
if( el.length === 0) {
|
||||
elParent.addClass('hide');
|
||||
}
|
||||
}
|
||||
|
||||
// Hiding parent element when children elements are not present
|
||||
// Tags
|
||||
hideEmptyEl($('.s-annc__tag'), $('.s-annc__tag-wrap'));
|
||||
|
||||
// Attachments
|
||||
hideEmptyEl($('.s-annc__flie-title'), $('.s-annc__related-file'));
|
||||
|
||||
// Links
|
||||
hideEmptyEl($('.s-annc__link-title'), $('.s-annc__related-link'));
|
||||
$("img[src='']").remove();
|
||||
}(jQuery));
|
||||
</script>
|
||||
|
|
@ -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 "recruit_news/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_recruit_news((!params[:layout_type].blank? ? params[:layout_type] : 'recruit_news_index1'))%>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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/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 recruit_news:remove_preview_recruit_news')
|
||||
end
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
en:
|
||||
module_name:
|
||||
recruit_news_mod: Event News
|
||||
recruit_news_mod:
|
||||
recruit_news_mod: Event News
|
||||
recruit_news:
|
||||
carousel_image_types:
|
||||
default: Default
|
||||
carousel: Carousel
|
||||
album: Album
|
||||
default_carousel_image_type: Default carousel image type
|
||||
carousel_image_type: Carousel image type
|
||||
read_from_cache: "Read from cache!"
|
||||
manually_sort: Manually Sort
|
||||
enable_manually_sort: Enable Manually Sort
|
||||
manual_update_sort: Manually Update Sort
|
||||
category: Category
|
||||
event_date_setting: "Event date setting"
|
||||
event_date_use_default_setting: "Event date use default setting"
|
||||
including_day_of_the_week: "Including day of the week"
|
||||
including_time: "Including time"
|
||||
hour_clock_24: "24 hour clock"
|
||||
title: Title
|
||||
all_day: All Day
|
||||
show_today_data_first: Show today data first
|
||||
custom_fields_title: Custom Fields Title
|
||||
custom_carousel_image_width_hint: "If blank, width will be default value."
|
||||
carousel_image_width: Carousel Image Width
|
||||
default_carousel_image_width: Default Carousel Image Width
|
||||
place: Place
|
||||
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
|
||||
notes: Notes
|
||||
speaker: Speaker
|
||||
host: Host
|
||||
unit: Unit
|
||||
employer: Employer
|
||||
event_date: Event Date
|
||||
event_end_date: Event End Date
|
||||
start_date: Start date
|
||||
end_date: End date
|
||||
add_to_calendar: Add to calendar
|
||||
blank_to_set: (blank to use event news 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
|
||||
sort_number: Sort Number
|
||||
add_new: Add New
|
||||
export_to_excel: Export to Excel
|
||||
export_all_anns: Export all Event News
|
||||
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
|
||||
recruit_news_module: Event News
|
||||
approval_setting: Approval Setting
|
||||
approve_recruit_news_fail: Approval Fail
|
||||
approve_recruit_news_success: Approve Successfully
|
||||
approval_waiting: Approval
|
||||
submitted_new_recruit_news: "%{poster} submitted a new event news waiting for your approval."
|
||||
click_here_to_see: Please click the link below to view the event news.
|
||||
rejected_annoucement: has rejected your event news, because
|
||||
updated_annoucement: "%{poster} updated the rejected event news."
|
||||
recruit_news_subject: New event news waiting for approval
|
||||
approval_site: Site
|
||||
approval_mail_hi: Hello %{name},
|
||||
approval_recruit_news_title: Event News Title
|
||||
recruit_news: Event News
|
||||
categories: Categories
|
||||
create_recruit_news_success: Create Bulletin Successfully
|
||||
create_recruit_news_category_success: Create Category Successfully
|
||||
date: Event News Date
|
||||
default_widget:
|
||||
recruit_news_category_with_title: Bulletin Category with Title
|
||||
postdate: Post Date
|
||||
subtitle: Subtitle
|
||||
title: Title
|
||||
editing_recruit_news: Edit event news
|
||||
editing_recruit_news_category: Edit Category
|
||||
file: Attachment
|
||||
file_description: File Description
|
||||
file_name: File Name
|
||||
frontend:
|
||||
recruit_news: Event News front-end
|
||||
search_result: Search result
|
||||
link_name: Link Name
|
||||
new_recruit_news_category: New Bulletin Category
|
||||
picture: Cover Picture
|
||||
search: Search
|
||||
selected_file: Select File
|
||||
update_recruit_news_category_success: Update Category Successfully
|
||||
url: URL
|
||||
widget:
|
||||
recruit_news_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 event news 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 event news, 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 event news
|
||||
is_postdate_sort_first: Sort by Post Date first (Sort by Event Date first as Default)
|
||||
only_manager_can_edit_status: Only manager can edit status of event news
|
||||
layout_type: Layout type
|
||||
recruit_news_setting_for_iframe: Event News settings for iframe
|
||||
url_generate: Url Generate
|
||||
show_page: Show pagination
|
||||
URL: URL
|
||||
copy: Copy
|
||||
month_name:
|
||||
'1': 'January'
|
||||
'2': 'February'
|
||||
'3': 'March'
|
||||
'4': 'April'
|
||||
'5': 'May'
|
||||
'6': 'June'
|
||||
'7': 'July'
|
||||
'8': 'August'
|
||||
'9': 'September'
|
||||
'10': 'October'
|
||||
'11': 'November'
|
||||
'12': 'December'
|
||||
calendar_title: "%{month} %{year}"
|
||||
ad_banner_location: Ad Banner Location(Need to Upload in Edit Page)
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
zh_tw:
|
||||
module_name:
|
||||
recruit_news_mod: 徵才公告
|
||||
recruit_news_mod:
|
||||
recruit_news_mod: 徵才公告
|
||||
recruit_news:
|
||||
carousel_image_types:
|
||||
default: 預設
|
||||
carousel: 輪播
|
||||
album: 相本排版
|
||||
default_carousel_image_type: 預設輪播樣式
|
||||
carousel_image_type: 預設輪播樣式
|
||||
read_from_cache: "從暫存中讀取!"
|
||||
manually_sort: 手動排序
|
||||
enable_manually_sort: 開啟手動排序
|
||||
manual_update_sort: 手動更新排序
|
||||
category: 類別
|
||||
event_date_setting: "事件日期設定"
|
||||
event_date_use_default_setting: "使用預設的事件日期設定"
|
||||
including_day_of_the_week: "包含星期幾"
|
||||
including_time: "包含時間"
|
||||
hour_clock_24: "24小時制"
|
||||
title: 講題
|
||||
all_day: 全天
|
||||
show_today_data_first: 優先顯示當日資料
|
||||
custom_fields_title: 欄位名稱設定
|
||||
custom_carousel_image_width_hint: "未填寫,則使用預設寬度"
|
||||
carousel_image_width: 輪播圖片寬度
|
||||
default_carousel_image_width: 預設輪播圖片寬度
|
||||
place: 地點
|
||||
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: 開啟頁籤(依類別)
|
||||
notes: 備註
|
||||
speaker: 演講者
|
||||
host: 主持人
|
||||
unit: 公告單位
|
||||
employer: 徵求單位
|
||||
event_date: 事件日期
|
||||
event_end_date: 事件結束日期
|
||||
start_date: 公告日期
|
||||
end_date: 截止日期
|
||||
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: 單位
|
||||
sort_number: 排序值
|
||||
add_new: 新建
|
||||
import: 匯入
|
||||
export_to_excel: 匯出至Excel檔
|
||||
export_all_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: 文章列表
|
||||
recruit_news_module: 徵才公告
|
||||
approval_setting: 審核設定
|
||||
approve_recruit_news_fail: 審核失敗
|
||||
approve_recruit_news_success: 審核成功
|
||||
approval_waiting: 審核
|
||||
submitted_new_announcement: 貴單位於全球資訊網有一則 %{poster} 張貼的最新消息待您審核發布,
|
||||
click_here_to_see: 請您點擊以下網址,前往審核
|
||||
rejected_annoucement: 未通過您的公告審核,原因為
|
||||
updated_annoucement: 貴單位於全球資訊網有一則 %{poster} 被拒絕的最新消息已重新編輯待您審核發布,
|
||||
announcement_subject: 系統訊息 - 最新消息內容審核通知
|
||||
approval_mail_hi: 親愛的 %{name} 主管您好
|
||||
approval_site: 網址
|
||||
approval_announcement_title: 消息標題
|
||||
recruit_news: 徵才公告
|
||||
categories: 類別
|
||||
create_recruit_news_success: 建立公告成功
|
||||
create_recruit_news_category_success: 建立類別成功
|
||||
date: 起迄日期
|
||||
default_widget:
|
||||
recruit_news_category_with_title: 公告類別及標題
|
||||
postdate: 張貼日期
|
||||
subtitle: 副標題
|
||||
title: 標題
|
||||
editing_announcement: 編輯類別
|
||||
editing_announcement_category: 編輯類別
|
||||
error:
|
||||
no_avilb_cate_for_posting: 沒有可以張貼的類別
|
||||
file: 附加檔案
|
||||
file_description: 檔案描述
|
||||
file_name: 檔案名稱
|
||||
frontend:
|
||||
recruit_news: 公告前台
|
||||
search_result: 搜尋結果頁
|
||||
link_name: 連結名稱
|
||||
new_recruit_news_category: 新增公告類別
|
||||
picture: 刊頭圖片
|
||||
search: 搜尋
|
||||
selected_file: 選擇檔案
|
||||
update_recruit_news_category_success: 更新類別成功
|
||||
url: 連結位置
|
||||
widget:
|
||||
recruit_news_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: 只顯示可更新的徵才公告
|
||||
is_postdate_sort_first: 優先使用公告日期排序(預設優先使用事件日期)
|
||||
only_manager_can_edit_status: 只有管理者可更新徵才公告狀態
|
||||
layout_type: 頁面樣式
|
||||
recruit_news_setting_for_iframe: 徵才公告iframe設定
|
||||
url_generate: 網址生成
|
||||
show_page: 顯示頁碼
|
||||
URL: 網址
|
||||
copy: 複製
|
||||
calendar_title: "%{year}年%{month}月"
|
||||
ad_banner_location: 廣告輪播位置(需於編輯頁面上傳)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
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 'recruit_news/preview', to: 'recruit_news#preview'
|
||||
post 'recruit_news/createfeed', to: 'recruit_news#createfeed'
|
||||
post 'recruit_news/importanns', to: 'recruit_news#importanns'
|
||||
post 'recruit_news/import_from_xml', to: 'recruit_news#import_from_xml'
|
||||
get 'recruit_news/excel_format', to: 'recruit_news#excel_format'
|
||||
get 'recruit_news/export_excel', to: 'recruit_news#export_excel'
|
||||
patch 'recruit_news/updatefeed', to: 'recruit_news#updatefeed'
|
||||
delete 'recruit_news/deletefeed', to: 'recruit_news#deletefeed'
|
||||
get 'recruit_news/destroy_preview/:slug_title-:uid', to: 'recruit_news#destroy_preview'
|
||||
post 'recruit_news/approve_recruit_news', to: 'recruit_news#approve_recruit_news'
|
||||
get 'recruit_news/feed', to: 'recruit_news#feed'
|
||||
get 'recruit_news/feedform', to: 'recruit_news#feedform'
|
||||
get 'recruit_news/settings', to: 'recruit_news#settings'
|
||||
get 'recruit_news/import', to: 'recruit_news#import'
|
||||
get 'recruit_news/download_file_from_thread', to: 'recruit_news#download_file_from_thread'
|
||||
post 'recruit_news/createsettings', to: 'recruit_news#createsettings'
|
||||
patch 'recruit_news/updatesettings', to: 'recruit_news#updatesettings'
|
||||
post 'recruit_news/import_from_wp', to: 'recruit_news#import_from_wp'
|
||||
post 'recruit_news/generate_iframe_url' => 'recruit_news#generate_iframe_url'
|
||||
resources :recruit_news do
|
||||
collection do
|
||||
get 'custom_fields_title'
|
||||
post 'update_custom_title'
|
||||
get "edit_sort"
|
||||
post "update_sort_setting", to: 'recruit_news#update_sort_setting'
|
||||
post "update_sort", to: 'recruit_news#update_sort'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
resources :recruit_news do
|
||||
collection do
|
||||
get ':slug_title-:uid', to: 'recruit_news_mods#show', as: :display
|
||||
end
|
||||
end
|
||||
post "/xhr/recruit_news_mods/feed_add_remote/:uid" => "recruit_news_feeds#feed_add_remote"
|
||||
post "/xhr/recruit_news_mods/feed_remove_remote/:uid" => "recruit_news_feeds#feed_remove_remote"
|
||||
get '/xhr/recruit_news/agenda' => 'recruit_news_mods#agenda'
|
||||
get "/xhr/recruit_news/feed/:uid" => "recruit_news_feeds#feed"
|
||||
get "/xhr/recruit_news/rssfeed/:uid" => "recruit_news_feeds#rssfeed"
|
||||
get "/xhr/recruit_news/feeds" => "recruit_news_feeds#feeds"
|
||||
get '/xhr/recruit_news/recruit_news.json', to: 'recruit_news_module#get_recruit_news'
|
||||
get '/xhr/panel/recruit_news/widget/sync_data' => 'recruit_news_mods#show_widget'
|
||||
get '/xhr/recruit_news/file/:id/*f_name', to: 'recruit_news_mods#get_file', format: false
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
require "recruit_news_mod/engine"
|
||||
require "recruit_news_mod/cache"
|
||||
require "recruit_news_mod/migrate"
|
||||
module RecruitNewsMod
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
module RecruitNewsMod
|
||||
module Cache
|
||||
require 'active_support/concern'
|
||||
extend ActiveSupport::Concern
|
||||
included do
|
||||
after_save :cache_tag_ids, :do_before_save
|
||||
after_destroy :do_before_save
|
||||
before_destroy :cache_tag_ids
|
||||
end
|
||||
def cache_tag_ids
|
||||
if self.class == ::RecruitNews
|
||||
@tag_ids = self.tag_ids
|
||||
@org_tag_ids = self.org_tag_ids
|
||||
@category_id = self.category_id
|
||||
@org_category_id = self.org_category_id
|
||||
end
|
||||
end
|
||||
def do_before_save
|
||||
if self.class == SubPart
|
||||
::RecruitNewsCache.where(parent_id:self.id).destroy
|
||||
elsif self.class == ::RecruitNews || (self.class == Page && self.module == "recruit_news_mod")
|
||||
if self.class == ::RecruitNews
|
||||
tmp_tag_ids = (Array(@tag_ids) + Array(@org_tag_ids)).uniq
|
||||
tmp_cat_ids = (Array(@category_id) + Array(@org_category_id)).uniq
|
||||
Thread.new do
|
||||
::RecruitNewsFeedCache.where(:uid.in => ::RecruitNewsFeed.any_of([{:tag_ids.in => tmp_tag_ids.collect{|v| v.to_s}},{:category_ids.in => tmp_cat_ids.collect{|v| v.to_s}}]).pluck(:uid)).to_a.each do |cache|
|
||||
cache.regenerate
|
||||
end
|
||||
end
|
||||
end
|
||||
::RecruitNewsCache.all.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
module RecruitNewsMod
|
||||
class Engine < ::Rails::Engine
|
||||
initializer "recruit_news_mod" do
|
||||
Rails.application.config.to_prepare do
|
||||
require "yaml"
|
||||
begin
|
||||
translate_data = Dir["#{RecruitNewsMod::Engine.root}/config/locales/*.yml"] .map{|yaml_file| YAML.load(File.read(yaml_file))}
|
||||
data = {}
|
||||
key1 = {}
|
||||
key2 = {}
|
||||
key3 = {}
|
||||
key4 = {}
|
||||
key5 = {}
|
||||
key1_attr = []
|
||||
key2_attr = []
|
||||
key3_attr = []
|
||||
key4_attr = []
|
||||
data_item = {}
|
||||
key_item1 = {}
|
||||
key_item2 = {}
|
||||
key_item3 = {}
|
||||
key_item4 = {}
|
||||
value_item1 = {}
|
||||
value_item2 = {}
|
||||
value_item3 = {}
|
||||
value_item4 = {}
|
||||
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']
|
||||
#After fix I18n.load_path, translation can work there
|
||||
yes_no_options = ['no_','yes_'].map{|v| I18n.available_locales.map{|k| I18n.with_locale(k){[k,I18n.t(v)]}}.to_h}
|
||||
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]['recruit_news']['picture_showing_size']
|
||||
key2[k] = v[0]['recruit_news']['tabs_options']
|
||||
key3[k] = v[0]['recruit_news']['read_more_position_options']
|
||||
key4[k] = v[0]['recruit_news']['all_tabs_setting']
|
||||
key5[k] = v[0]['recruit_news']['show_today_data_first']
|
||||
key1_options.each_with_index do |kk,i|
|
||||
key1_attr[i][k] = v[0]['recruit_news'][kk]
|
||||
end
|
||||
key2_options.each_with_index do |kk,i|
|
||||
key2_attr[i][k] = v[0]['recruit_news'][kk]
|
||||
end
|
||||
key3_options.each_with_index do |kk,i|
|
||||
key3_attr[i][k] = v[0]['recruit_news'][kk]
|
||||
end
|
||||
key4_options.each_with_index do |kk,i|
|
||||
key4_attr[i][k] = v[0]['recruit_news'][kk]
|
||||
end
|
||||
key_item1[k] = v[0]['recruit_news']['showing_back_and_next']
|
||||
key_item2[k] = v[0]['recruit_news']['enable_search']
|
||||
key_item3[k] = v[0]['recruit_news']['ad_banner_location']
|
||||
value_item1[k] = v[0]['recruit_news']['not_show']
|
||||
value_item2[k] = v[0]['recruit_news']['show_bottom']
|
||||
value_item3[k] = v[0]['recruit_news']['show_top']
|
||||
end
|
||||
key_item4 = key5
|
||||
data[key1] = key1_attr
|
||||
data[key2] = key2_attr
|
||||
data[key3] = key3_attr
|
||||
data[key4] = key4_attr
|
||||
data[key5] = yes_no_options
|
||||
data_item[key_item1] = [value_item1,value_item2,value_item3]
|
||||
data_item[key_item2] = yes_no_options
|
||||
data_item[key_item3] = [value_item2,value_item3]
|
||||
data_item[key_item4] = yes_no_options
|
||||
data_item[key1] = key1_attr
|
||||
if ENV['worker_num']=='0' && File.basename($0) != 'rake' && !Rails.const_defined?('Console')
|
||||
require File.expand_path('../../../app/models/recruit_news_cache', __FILE__)
|
||||
if defined?(RecruitNewsCache)
|
||||
RecruitNewsCache.destroy_all
|
||||
end
|
||||
require File.expand_path('../../../app/models/recruit_news_custom_title', __FILE__)
|
||||
if defined? RecruitNewsCustomTitle
|
||||
RecruitNewsCustomTitle.get_map
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
puts ['error in recruit_news',e,e.backtrace]
|
||||
end
|
||||
|
||||
if ENV['worker_num']=='0' && File.basename($0) != 'rake' && !Rails.const_defined?('Console')
|
||||
Thread.new do
|
||||
begin
|
||||
Migrate.call
|
||||
rescue => e
|
||||
puts ['recruit_news_mod',e, e.backtrace]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
OrbitApp.registration "recruit_news_mod", :type => "ModuleApp" do
|
||||
db = ::Mongoid::Sessions.default
|
||||
collection = db[:module_apps]
|
||||
update_results = collection.update_many({key: 'recruit_news'},'$set'=>{key: 'recruit_news_mod', title: 'recruit_news_mod'})
|
||||
if update_results.n != 0
|
||||
puts "Updating recruit_news to recruit_news_mod!"
|
||||
collection = db[:pages]
|
||||
collection.update_many({:module=> 'recruit_news'},'$set'=>{:module=> 'recruit_news_mod'})
|
||||
collection = db[:sub_parts]
|
||||
collection.update_many({:module=> 'recruit_news'},'$set'=>{:module=> 'recruit_news_mod'})
|
||||
template_path = Rails.root.to_s + '/app/templates'
|
||||
all_template = Dir.glob(template_path+'/*/')
|
||||
all_template.each do |folder|
|
||||
Bundler.with_clean_env{system ("mkdir -p #{folder}modules/recruit_news_mod; cp -rf #{folder}modules/recruit_news/* #{folder}modules/recruit_news_mod/. && rm -rf #{folder}modules/recruit_news_mod/recruit_news")}
|
||||
end
|
||||
end
|
||||
module_label "recruit_news.recruit_news"
|
||||
base_url File.expand_path File.dirname(__FILE__)
|
||||
widget_methods ["widget","random_recruit_news_widget", "tag_cloud"]
|
||||
widget_settings [{"data_count"=>30}]
|
||||
taggable "RecruitNews"
|
||||
hashtaggable "RecruitNews"
|
||||
categorizable
|
||||
authorizable
|
||||
frontend_enabled
|
||||
feeds_url "/xhr/recruit_news/feeds"
|
||||
feeds_time_field (::RecruitNewsHelper.is_postdate_sort_first ? ['postdate', 'event_date'] : ['event_date', 'postdate'])
|
||||
data_count 1..30
|
||||
begin
|
||||
show_options data
|
||||
show_option_items data_item
|
||||
rescue => e
|
||||
puts ['there_was_no_show_option_method',e]
|
||||
end
|
||||
if File.basename($0) != 'rake'
|
||||
begin
|
||||
avoid_page_cache RecruitNewsCache
|
||||
avoid_page_cache RecruitNewsFeedCache
|
||||
avoid_page_cache RecruitNewsFeed
|
||||
rescue => e
|
||||
puts ["avoid_page_cache", e.to_s]
|
||||
end
|
||||
end
|
||||
side_bar do
|
||||
head_label_i18n 'recruit_news.recruit_news', icon_class: "icons-megaphone"
|
||||
available_for "users"
|
||||
active_for_controllers (['admin/recruit_news'])
|
||||
head_link_path "admin_recruit_news_index_path"
|
||||
|
||||
context_link 'recruit_news.all_articles',
|
||||
:link_path=>"admin_recruit_news_index_path" ,
|
||||
:priority=>1,
|
||||
:active_for_action=>{'admin/recruit_news'=>'index'},
|
||||
:available_for => 'users'
|
||||
context_link 'recruit_news.manually_sort',
|
||||
:link_path=>"edit_sort_admin_recruit_news_index_path" ,
|
||||
:priority=>2,
|
||||
:active_for_action=>{'admin/recruit_news'=>'edit_sort'},
|
||||
:available_for => 'managers'
|
||||
context_link 'new_',
|
||||
:link_path=>"new_admin_recruit_news_path" ,
|
||||
:priority=>2,
|
||||
:active_for_action=>{'admin/recruit_news'=>'new'},
|
||||
:available_for => 'sub_managers'
|
||||
context_link 'categories',
|
||||
:link_path=>"admin_module_app_categories_path" ,
|
||||
:link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'recruit_news_mod').id}",
|
||||
:priority=>3,
|
||||
:active_for_action=>{'admin/recruit_news'=>'categories'},
|
||||
:active_for_category => 'RecruitNewsModule',
|
||||
:available_for => 'managers'
|
||||
context_link 'tags',
|
||||
:link_path=>"admin_module_app_tags_path" ,
|
||||
:link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'recruit_news_mod').id}",
|
||||
:priority=>4,
|
||||
:active_for_action=>{'admin/recruit_news'=>'tags'},
|
||||
:active_for_tag => 'RecruitNewsModule',
|
||||
:available_for => 'managers'
|
||||
context_link 'recruit_news.custom_fields_title',
|
||||
:link_path=>"custom_fields_title_admin_recruit_news_index_path" ,
|
||||
:priority=>5,
|
||||
:active_for_action=>{'admin/recruit_news'=>'custom_fields_title'},
|
||||
:available_for => 'managers'
|
||||
|
||||
context_link 'recruit_news.feed_list',
|
||||
:link_path=>"admin_recruit_news_feed_path" ,
|
||||
:priority=>6,
|
||||
:active_for_action=>{'admin/recruit_news'=>'feed'},
|
||||
:available_for => 'managers'
|
||||
context_link 'recruit_news.import',
|
||||
:link_path=>"admin_recruit_news_import_path" ,
|
||||
:priority=>7,
|
||||
:active_for_action=>{'admin/recruit_news'=>'import'},
|
||||
:available_for => 'managers'
|
||||
context_link 'recruit_news.settings',
|
||||
:link_path=>"admin_recruit_news_settings_path" ,
|
||||
:priority=>8,
|
||||
:active_for_action=>{'admin/recruit_news'=>'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[:bulletins].indexes.create({expirable_created_at: 1},{ expireAfterSeconds: 180 })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
module RecruitNewsMod
|
||||
module Migrate
|
||||
def self.call
|
||||
puts ['event news migrate start']
|
||||
gem_root = RecruitNewsMod::Engine.root
|
||||
require File.join(gem_root, 'app/models/recruit_news_setting')
|
||||
require File.join(gem_root, 'app/models/recruit_news')
|
||||
require File.join(gem_root, 'app/models/recruit_news_feed')
|
||||
require File.join(gem_root, 'app/models/recruit_news_feed_cache')
|
||||
|
||||
setting = RecruitNewsSetting.first
|
||||
|
||||
if !setting.migrate_flag.include?("v1")
|
||||
RecruitNews.all.pluck(:id, :title).each do |id, title_translations|
|
||||
if title_translations.nil?
|
||||
next
|
||||
end
|
||||
RecruitNews.where(id: id).view.update_many({
|
||||
"$set" => {
|
||||
title_plain_text: OrbitHelper.get_plain_text_translations(title_translations)
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
setting.migrate_flag << "v1"
|
||||
setting.save
|
||||
end
|
||||
|
||||
#solve bug for thousands of generated feed cache
|
||||
if RecruitNewsFeedCache.count > RecruitNewsFeed.count*5
|
||||
RecruitNewsFeedCache.collection.drop
|
||||
end
|
||||
RecruitNewsFeedCache.regenerate_all
|
||||
|
||||
puts ['event news migrate end']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module RecruitNewsMod
|
||||
VERSION = "0.0.1"
|
||||
end
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
desc 'Remove duplicated RecruitNews created by preview'
|
||||
|
||||
namespace :recruit_news do
|
||||
task :remove_preview_recruit_news => [:environment] do
|
||||
recruit_news = RecruitNews.where(is_preview: true)
|
||||
recruit_news.destroy_all
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<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="recruit_news">
|
||||
<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>
|
||||
<div class="w-annc__subtitle">{{subtitle}}</div>
|
||||
<div class="w-annc__speaker" style="{{speaker-css}}">【{{speaker-head}}】 {{speaker}}</div>
|
||||
<div class="w-annc__host" style="{{host-css}}">【{{host-head}}】 {{host}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="w-annc__more-wrap clearfix">
|
||||
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= t("recruit_news.more") %></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="recruit_news">
|
||||
<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}}"><%= t("recruit_news.more") %></a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<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="recruit_news">
|
||||
<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}}"><%= t("recruit_news.more") %></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="recruit_news">
|
||||
<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}}"><%= t("recruit_news.more") %></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="recruit_news">
|
||||
<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}}"><%= t("recruit_news.more") %></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="recruit_news">
|
||||
<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}}"><%= t("recruit_news.more") %></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}}"><%= t("recruit_news.more") %></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="recruit_news">
|
||||
<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_{{subpart-id}}(){
|
||||
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_{{subpart-id}}(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_{{subpart-id}}();
|
||||
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_{{subpart-id}}(3);
|
||||
num=3;
|
||||
}else if($(window).width()>576){
|
||||
reorganize_{{subpart-id}}(2);
|
||||
num=2;
|
||||
}else{
|
||||
reorganize_{{subpart-id}}(1);
|
||||
num=1;
|
||||
}
|
||||
})
|
||||
$(document).ready(function(){
|
||||
if($(window).width()>1024){
|
||||
reorganize_{{subpart-id}}(3);
|
||||
num=3;
|
||||
}else if($(window).width()>576){
|
||||
reorganize_{{subpart-id}}(2);
|
||||
num=2;
|
||||
}else{
|
||||
reorganize_{{subpart-id}}(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: "right", mode: 'show', duration: 500},function(){flag=false;});
|
||||
};
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<div class="w-annc widget-announcement-13">
|
||||
<table class="w-annc__table table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-annc__th w-annc__th--date">{{event_date-head}}</th>
|
||||
<th class="w-annc__th w-annc__th--date">{{speaker-head}}</th>
|
||||
<th class="w-annc__th w-annc__th--title">{{title-head}}</th>
|
||||
<th class="w-annc__th w-annc__th--title">{{subtitle-head}}</th>
|
||||
<th class="w-annc__th w-annc__th--title">{{host-head}}</th>
|
||||
<th class="w-annc__th w-annc__th--title">{{notes-head}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-level="0" data-list="recruit_news">
|
||||
<tr>
|
||||
<td class="w-annc__postdate" date-format="%Y-%m-%d">{{postdate}}</td>
|
||||
<td class="w-annc__speaker">{{speaker}}</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_subtitle">{{subtitle}}</td>
|
||||
<td class="w-annc__host">{{host}}</td>
|
||||
<td class="w-annc__notes">{{notes}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="w-annc__more-wrap clearfix">
|
||||
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= t("recruit_news.more") %></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">
|
||||
<tbody data-level="0" data-list="recruit_news">
|
||||
<tr>
|
||||
<td class="w-annc__postdate">{{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-head}}{{title}}</a>
|
||||
</td>
|
||||
<td style="{{speaker-css}}" class="w-annc__speaker">{{speaker-head}}{{speaker}}</td>
|
||||
<td style="{{host-css}}" class="w-annc__host">{{host-head}}{{host}}</td>
|
||||
<td style="{{place-css}}" class="w-annc__host">{{place-head}}{{place}}</td>
|
||||
<td style="{{event-time-css}}" class="w-annc__host">{{event_date-head}}{{event-time-formated}}</td>
|
||||
<td class="w-annc__subtitle">{{subtitle}}</td>
|
||||
<td style="{{notes-css}}" class="w-annc__notes">{{notes-head}}{{notes}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="w-annc__more-wrap clearfix">
|
||||
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= t("recruit_news.more") %></a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<div class="w-calendar widget-calendar-2 widget-event-news-calendar-2" data-module="recruit_news">
|
||||
<div class="w-calendar-title {{widget_title_class}}">
|
||||
<span>{{calendar_title}}</span>
|
||||
<span>{{widget_title}}</span>
|
||||
</div>
|
||||
<div class='month_template'>
|
||||
<h4 class="widget-title ">
|
||||
<span class="text"><span style="display: none;">placeholder</span></span>
|
||||
<i class="fa fa-circle-o-notch fa-spin fa-fw loading hide"></i>
|
||||
</h4>
|
||||
<div class="w-calendar-nav">
|
||||
<a href="#" class="w-calendar-nav-prev">
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
<span class="w-calendar-nav-prev-text hide">Prev</span>
|
||||
</a>
|
||||
<a href="#" class="w-calendar-nav-next">
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
<span class="w-calendar-nav-next-text hide">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
<table class="table table-condensed w-calendar-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Sun</th>
|
||||
<th>Mon</th>
|
||||
<th>Tue</th>
|
||||
<th>Wed</th>
|
||||
<th>Thu</th>
|
||||
<th>Fri</th>
|
||||
<th>Sat</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="calendar-events" style="display: none;">
|
||||
<div class="event">
|
||||
<div class="event-header">
|
||||
<div class="date">
|
||||
<div class="day"></div>
|
||||
<div class="month"></div>
|
||||
</div>
|
||||
<div class="event-title">
|
||||
<div class="event-inner-title"></div>
|
||||
<div class="duration"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="event-wraper">
|
||||
<div class="event-containers">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%= stylesheet_link_tag "recruit_news_calendar_widget2" %>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
if(document.getElementById("event-news-calendar-widget_module2") == null){
|
||||
var tag = document.createElement('script');
|
||||
tag.setAttribute("id", "event-news-calendar-widget_module2");
|
||||
tag.src = "<%= asset_path('recruit_news_calendar_widget2.js') %>";
|
||||
tag.onload = function(){
|
||||
$("div.widget-calendar-2[data-module=recruit_news]").each(function(index){
|
||||
var calendar = $(this),
|
||||
cmi = new EventCalendarModuleMonth2(new Date(), calendar,calendar.data("subpart-id"),"{{more_url}}",false);
|
||||
cmi.currentMonth();
|
||||
calendar.find("div.w-calendar-nav a").on("click",function(){
|
||||
var el = $(this);
|
||||
if(el.hasClass("w-calendar-nav-prev")){
|
||||
cmi.prevMonth();
|
||||
}else if(el.hasClass("w-calendar-nav-next")){
|
||||
cmi.nextMonth();
|
||||
}
|
||||
return false;
|
||||
})
|
||||
})
|
||||
}
|
||||
var head = document.getElementsByTagName("head");
|
||||
head[0].appendChild(tag);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<div class="i-annc index-announcement-12s w-annc widget-announcement-19">
|
||||
<h3 class="w-annc__widget-title">
|
||||
<span>{{widget-title}}</span>
|
||||
</h3>
|
||||
<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--speaker">{{speaker-head}}</th>
|
||||
<th class="i-annc__th i-annc__th--event_start_date">{{event_start_date-head}}</th>
|
||||
<th class="i-annc__th i-annc__th--title">{{title-head}}</th>
|
||||
<th class="i-annc__th i-annc__th--event_end_date">{{event_end_date-head}}</th>
|
||||
<th class="i-annc__th i-annc__th--view-count">{{view-count-head}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-level="0" data-list="recruit_news">
|
||||
<tr>
|
||||
<td class="i-annc__category">{{category}}</td>
|
||||
<td class="i-annc__speaker">{{speaker}}</td>
|
||||
<td class="i-annc__event_start_date"><span class="i-annc__event_start_date-content" date-format="%Y-%m-%d">{{event_start_date}}</span></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__event_end_date"><span class="i-annc__event_end_date-content" date-format="%Y-%m-%d">{{event_end_date}}</span></td>
|
||||
<td class="i-annc__view-count">{{view_count}}</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