Add weekdays setting feature.

Fix bug.
This commit is contained in:
BoHung Chiu 2022-07-25 22:37:02 +08:00
parent 22b451eb63
commit 876434e6a5
15 changed files with 163 additions and 41 deletions

View File

@ -19,6 +19,14 @@ if(!(window.calendar_variable.dayNames)){
window.calendar_variable.dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed','Thu', 'Fri', 'Sat'];
}
}
if(Array.prototype.rotate == undefined){
Array.prototype.rotate = function(n) {
n = n % this.length;
while (this.length && n < 0) n += this.length;
this.push.apply(this, this.splice(0, n));
return this;
}
}
if(window.calendar_variable.is_chinese){
window.calendar_variable.months = [];
for(var i=0;i<12;i++){
@ -729,7 +737,7 @@ var AgendaView = function(calendar){
'<table class="table table-condensed table-bordered">' +
'<tbody>' +
'<tr>' +
calendar_variable.dayNamesShort.map(function(title){
calendar_variable.dayNamesShort.slice(0).rotate(calendar_variable.sunday_first ? 0 : 1).map(function(title){
return '<th class="week_title">'+title+'</th>';
}).join('') +
'</tr>' +
@ -1066,9 +1074,10 @@ var AgendaView = function(calendar){
var row = $("<tr></tr>");
switch (position){
case "first":
var offset = firstDay.getDay() - (window.calendar_variable.sunday_first ? 0 : 1);
for(var i = 0;i < 7;i++){
var td = $("<td></td>");
if(i >= firstDay.getDay()){
if(i >= offset){
td.text(last_inserted_date);
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
last_inserted_date++;
@ -1086,9 +1095,10 @@ var AgendaView = function(calendar){
}
break;
case "last":
var offset = lastDay.getDay() - (window.calendar_variable.sunday_first ? 0 : 1);
for(var i = 0;i < 7;i++){
var td = $("<td></td>");
if(i <= lastDay.getDay()){
if(i <= offset){
td.text(last_inserted_date);
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
last_inserted_date++;

View File

@ -19,6 +19,14 @@ if(!(window.calendar_variable.dayNames)){
window.calendar_variable.dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed','Thu', 'Fri', 'Sat'];
}
}
if(Array.prototype.rotate == undefined){
Array.prototype.rotate = function(n) {
n = n % this.length;
while (this.length && n < 0) n += this.length;
this.push.apply(this, this.splice(0, n));
return this;
}
}
if(window.calendar_variable.is_chinese){
window.calendar_variable.months = [];
for(var i=0;i<12;i++){
@ -560,7 +568,7 @@ var AgendaView = function(calendar){
'<table class="table table-condensed table-bordered">' +
'<tbody>' +
'<tr>' +
calendar_variable.dayNamesShort.map(function(title){
calendar_variable.dayNamesShort.slice(0).rotate(calendar_variable.sunday_first ? 0 : 1).map(function(title){
return '<th class="week_title">'+title+'</th>';
}).join('') +
'</tr>' +
@ -898,9 +906,10 @@ var AgendaView = function(calendar){
var row = $("<tr></tr>");
switch (position){
case "first":
var offset = firstDay.getDay() - (window.calendar_variable.sunday_first ? 0 : 1);
for(var i = 0;i < 7;i++){
var td = $("<td></td>");
if(i >= firstDay.getDay()){
if(i >= offset){
td.text(last_inserted_date);
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
last_inserted_date++;
@ -918,9 +927,10 @@ var AgendaView = function(calendar){
}
break;
case "last":
var offset = lastDay.getDay() - (window.calendar_variable.sunday_first ? 0 : 1);
for(var i = 0;i < 7;i++){
var td = $("<td></td>");
if(i <= lastDay.getDay()){
if(i <= offset){
td.text(last_inserted_date);
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
last_inserted_date++;

View File

@ -326,23 +326,24 @@ var CalendarModuleMonth1 = function(date,dom,subpart,url,index_flag){
var row = $("<tr></tr>");
switch (position){
case "first":
var first_line_first_day = new Date(year,month,firstDay.getDate()-firstDay.getDay())
var offset = firstDay.getDay() - (window.calendar_variable.sunday_first ? 0 : 1);
var first_line_first_day = new Date(year,month,firstDay.getDate() - offset)
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(i >= offset){
if(today != 0 && last_inserted_date == today){
td.addClass("w-calendar-today");
}
td.find('div').html(last_inserted_date<10 ? "&nbsp;"+last_inserted_date+"&nbsp;" : last_inserted_date);
td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear());
last_inserted_date++;
}else{
}else{first_line_first_date
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.attr("data-date-node",(+i)+"-"+first_line_first_month+"-"+first_line_first_year);
td.addClass("w-calendar-other-month")
}
row.append(td);

View File

@ -466,14 +466,15 @@ var CalendarModuleMonth2 = function(date,dom,subpart,url,index_flag){
var row = $("<tr></tr>");
switch (position){
case "first":
var first_line_first_day = new Date(year,month,firstDay.getDate()-firstDay.getDay())
var offset = firstDay.getDay() - (window.calendar_variable.sunday_first ? 0 : 1);
var first_line_first_day = new Date(year,month,firstDay.getDate() - offset)
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(i >= offset){
if(today != 0 && last_inserted_date == today){
td.addClass("w-calendar-today");
}

View File

@ -5,21 +5,20 @@ $(function() {
$.pageslide.loadComplete(function(pageslide, item) {
$('.filter-item').removeClass("active");
item.closest('li').addClass('active');
$('.color-picker').miniColors("destroy");
setForm(item.data('form'));
if(item.data('id') == 'new') {
resetForm();
pageslide.find('form').attr('method', 'post');
$("#update_patch").remove();
}
else {
$('.color-picker').miniColors("destroy");
setForm(item.data('form'));
pageslide.find('form').attr("action",item.data("href"));
if($("#update_patch").length == 0){
pageslide.find("form").append("<input type='hidden' id='update_patch' value='patch' name='_method' />");
}
pageslide.find('input[type="checkbox"]').prop( 'checked', item.data('disable') );
$('.color-picker').miniColors();
$('.miniColors-trigger').addClass('btn');
}
$('.color-picker').miniColors();
$('.miniColors-trigger').addClass('btn');
});
})

View File

@ -49,8 +49,8 @@ class Admin::CalendarsController < OrbitAdminController
end
def agenda
agenda_start = Time.at(params[:unix_start].to_i).to_s
agenda_end = Time.at(params[:unix_end].to_i).to_s
agenda_start = Time.at(params[:unix_start].to_i).utc
agenda_end = Time.at(params[:unix_end].to_i).utc
@events = Event.agenda_events(agenda_start,agenda_end)
# re = Event.recurring_event(Time.at(params[:unix_start].to_i), Time.at(params[:unix_end].to_i))
# @events = @events.inject(re, :<<)

View File

@ -10,7 +10,7 @@ class CalendarsController < ApplicationController
{
"modes_info" => @calendar_setting.get_modes_info.map.with_index{|(trans, mode),i| {trans: trans, mode: mode, active_class: (i ==
2 ? 'active' : '')}},
"week_title" => @calendar_setting.week_title.map{|t| {'week_title'=> t}},
"week_title" => @calendar_setting.week_title.map{|t| {'week_title'=> t}}.rotate(@calendar_setting.sunday_first ? 0 : 1),
"extras" => {
"page_id" => OrbitHelper.params[:page_id],
'widget_title' => page.name,
@ -43,7 +43,7 @@ class CalendarsController < ApplicationController
{
"modes_info" => @calendar_setting.get_modes_info.map.with_index{|(trans, mode),i| {trans: trans, mode: mode, active_class: (i ==
2 ? 'active' : '')}},
"week_title" => @calendar_setting.week_title.map{|t| {'week_title'=> t}},
"week_title" => @calendar_setting.week_title.map{|t| {'week_title'=> t}}.rotate(@calendar_setting.sunday_first ? 0 : 1),
"extras" => {
"subpart-id" => part.id.to_s,
"more_url" => OrbitHelper.widget_more_url,
@ -94,8 +94,8 @@ class CalendarsController < ApplicationController
calendar_types = []
end
if params[:unix_start].present? && params[:unix_end].present?
agenda_start = Time.at(params[:unix_start].to_i).utc.to_s
agenda_end = Time.at(params[:unix_end].to_i).utc.to_s
agenda_start = Time.at(params[:unix_start].to_i).utc
agenda_end = Time.at(params[:unix_end].to_i).utc
event = Event.where("title_translations.#{locale}".to_sym.ne=>"")
events = event.with_categories(calendar_types).agenda_events(agenda_start,agenda_end)
end
@ -115,8 +115,8 @@ class CalendarsController < ApplicationController
calendar_types = []
end
if params[:unix_start].present? && params[:unix_end].present?
agenda_start = Time.at(params[:unix_start].to_i).utc.to_s
agenda_end = Time.at(params[:unix_end].to_i).utc.to_s
agenda_start = Time.at(params[:unix_start].to_i).utc
agenda_end = Time.at(params[:unix_end].to_i).utc
event = Event.where("title_translations.#{locale}".to_sym.ne=>"")
events = event.with_categories(calendar_types).agenda_events(agenda_start,agenda_end)
end

View File

@ -9,24 +9,26 @@ class Event
field :title
field :note
field :title_translations,type: Hash,default: {}
field :note_translations,type: Hash,default: {}
field :title_translations,type: Hash, default: {}
field :note_translations,type: Hash, default: {}
field :start, type: DateTime
field :end, type: DateTime
field :all_day, type: Boolean,default: false
field :recurring, type: Boolean,default: false
field :all_day, type: Boolean, default: false
field :recurring, type: Boolean, default: false
field :frequency
field :period
field :weekdays, type: Array, default: []
field :recurring_end_date, type: DateTime
field :create_user_id
field :update_user_id
field :module_key
field :model_cat
field :model_page_id
field :model_tags,type: Array,default: []
field :model_tags, type: Array, default: []
field :is_weekdays, type: Boolean, default: false
belongs_to :calendar_type
field :url
field :url_translations,type: Hash,default: {}
field :url_translations, type: Hash, default: {}
def get_module_url
page = !self.model_page_id.blank? ? Page.find(self.model_page_id): Page.where(:module => self.module_key).where(:categories.in => Array(self.model_cat)+[[]],:tags.in=>Array(self.model_tags)+[[]]).first
page.nil? ? '' : (page.url+'/'+eval(self.model_class).where(:id=>self.model_id).first.to_calendar_param)
@ -64,6 +66,11 @@ class Event
self['title'] = self.title
self['note'] = self.note
self['url'] = self.url
if self.is_weekdays
self.weekdays = (1..5).to_a #平日
else
self.weekdays = self.weekdays.map{|s| s.to_i}.sort
end
end
########################################
validates_presence_of :title, :message => "Please fill the title of the Event", :if => lambda { self['title_translations'].blank? }
@ -158,6 +165,7 @@ class Event
is_year = false
days = 1
interval = nil
weekdays = nil
if re.period == 'Daily'
period_str = 'day'
interval = 1.day
@ -165,6 +173,8 @@ class Event
period_str = 'week'
days = 7
interval = 1.week
weekdays = re.weekdays
weekdays = nil if weekdays.blank?
elsif re.period == 'Monthly'
period_str = 'month'
is_month = true
@ -195,12 +205,31 @@ class Event
add_interval += (freq - rest)
end
add_interval = add_interval.send(period_str)
need_check_start = false
if weekdays
add_interval -= @start_date.wday.day
need_check_start = true
end
start_date = [start_date, @start_date].max
@start_date += add_interval
@end_date += add_interval
new_end_date = has_recurring_end_date ? [re.recurring_end_date,end_date].min : end_date
while @start_date <= new_end_date do
if @start_date >= start_date && @start_date != org_start
@recurring << data.merge({:start => @start_date.to_json.gsub('"',''), :end => @end_date.to_json.gsub('"','')})
if weekdays
weekdays.each do |w|
new_start = (@start_date + w.day)
if need_check_start && new_start < start_date
next
end
if new_start != org_start
@recurring << data.merge({:start => new_start.to_json.gsub('"',''), :end => (@end_date + w.day).to_json.gsub('"','')})
end
end
need_check_start = false
else
if @start_date != org_start
@recurring << data.merge({:start => @start_date.to_json.gsub('"',''), :end => @end_date.to_json.gsub('"','')})
end
end
@start_date += interval
@end_date += interval

View File

@ -1,6 +1,6 @@
<%= label_tag("color", t("calendar.color")) %>
<div class="input-append">
<%= f.text_field :color, id: "color", :class => "color-picker miniColors input-small", :size => "7", :maxlength => "7", :autocomplete=>"off",:value=>"9100FF" %>
<%= text_field_tag "#{f.object_name}[color]", f.object.color || "#9100FF", id: "color", :class => "color-picker miniColors input-small", :size => "7", :maxlength => "7", :autocomplete=>"off",:value=>"#9100FF" %>
</div>
<%= f.fields_for :title_translations do |f| %>
<% @site_valid_locales.each do |locale| %>

View File

@ -18,7 +18,7 @@
<div class="bottomnav clearfix">
<div class="action pull-right">
<a href="#" class="btn btn-primary open-slide" data-id="new" onclick="return false;">
<a href="#" class="btn btn-primary open-slide" data-id="new" data-title="<%=t(:new_category)%>" data-form="<%=@calendar_type.title_translations.merge(color: "#9100FF").to_json%>" onclick="return false;">
<i class="icons-plus"></i>Add
</a>
</div>

View File

@ -6,7 +6,7 @@
<div class="row-fluid">
<div class="span2">
<%= label_tag("color", t("calendar.color")) %>
<%= f.text_field :color, :class => "color-picker miniColors span5", :size => "7", :maxlength => "7", :autocomplete=>"off",:value=>"9100FF" %>
<%= text_field_tag "#{f.object_name}[color]", "#9100FF", :id=>"color", :class=>"color-picker miniColors span5", :size=>"7", :maxlength=>"7", :autocomplete=>"off" %>
</div>
</div>

View File

@ -124,7 +124,7 @@
</label>
</div>
</div>
<% data_format = @event.all_day ? 'yyyy/MM/dd' : 'yyyy/MM/dd hh:mm' %>
<% data_format = @all_day ? 'yyyy/MM/dd' : 'yyyy/MM/dd hh:mm' %>
<div class="control-group">
<%= f.label t("start_date"), :class=>"control-label" %>
<%#= f.datetime_select :start %>
@ -161,9 +161,9 @@
</div>
<div id="recurring_panel" <%= (@recurring ? '' : "style=display:none;") %> >
<div class="control-group">
<%=f.label :period, t("calendar.repeats"),:class=>"control-label" %>
<%=f.label :period, t("calendar.repeats"),:class=>"control-label", :for => "event_period" %>
<div class="controls">
<%=f.select :period, Event::REPEATS.map{|v| [t("calendar.#{v.downcase}"),v]},{},:class=>"span5" %>
<%=f.select :period, Event::REPEATS.map{|v| [t("calendar.#{v.downcase}"),v]},{},:class=>"span5",:id => "event_period" %>
</div>
</div>
<div class="control-group">
@ -172,6 +172,31 @@
<%=f.select :frequency, (1..30).to_a,{},:class=>"span2" %>
</div>
</div>
<div id="Weekly_panel" class="<%= 'hide' if f.object.period != 'Weekly' %>">
<%=f.label :is_weekdays, t("calendar.type") ,:class=>"control-label", :for => "event_is_weekdays" %>
<div class="controls">
<%=f.select :is_weekdays, options_for_select(['custom', 'weekdays'].map.with_index{|v, i| [t("calendar.#{v}"), i.to_s]}, f.object.is_weekdays ? '1' : '0'),{},:class=>"span5",:id=>"event_is_weekdays" %>
<div id="Weekly_custom_panel" class="<%= 'hide' if f.object.is_weekdays %>">
<%
weekdays = f.object.weekdays
if f.object.new_record? && f.object.start
weekdays = [f.object.start.wday]
end
tmp_html = []
%>
<% (0...7).each do |i| %>
<% tmp = f.check_box_tag "#{f.object_name}[weekdays][]", i, weekdays.include?(i), {:class=>"weekdays-checkbox"}
tmp += t("calendar.short_day.#{i}")
tmp_html << tmp
%>
<% end %>
<% unless (CalendarSetting.first.sunday_first rescue false)
tmp_html.rotate!(1)
end %>
<%= tmp_html.join("\n").html_safe %>
</div>
</div>
</div>
<div class="control-group">
<%= f.label t("calendar.recurring_end_date"), :class=>"control-label" %>
<div class="controls">
@ -294,5 +319,25 @@
$(this).html(($('<div></div>').append(e.originalEvent.clipboardData.getData('text/plain')).text()));
e.preventDefault();
});
$("#event_is_weekdays").change(function(){
if($(this).val() == "0"){
$("#Weekly_custom_panel").removeClass('hide');
}else{
$("#Weekly_custom_panel").addClass('hide');
}
})
$("#event_period").change(function(){
if($(this).val() == "Weekly"){
$("#Weekly_panel").removeClass('hide');
}else{
$("#Weekly_panel").addClass('hide');
}
})
$("#event_start").change(function(){
var _this = $(this);
var date = $.ui_datepicker.parseDate(_this.data('datepicker').settings.dateFormat, _this.val());
$(".weekdays-checkbox").prop("checked", false);
$(".weekdays-checkbox").eq(date.getDay()).prop("checked", true);
})
})
</script>

View File

@ -1,5 +1,8 @@
en:
calendar:
type: Type
custom: Custom
weekdays: Weekdays
recurring_end_date: "Recurring End Date"
"12_hour_clock": "12 hour clock"
"24_hour_clock": "24 hour clock"
@ -17,6 +20,14 @@ en:
month: "Month"
agenda: "Agenda"
day_of_the_week: "Day of the week"
short_day:
"0": "Sun"
"1": "Mon"
"2": "Tue"
"3": "Wed"
"4": "Thu"
"5": "Fri"
"6": "Sat"
day:
"0": "Sunday"
"1": "Monday"

View File

@ -1,5 +1,8 @@
zh_tw:
calendar:
type: 類型
custom: 自訂
weekdays: 平日
recurring_end_date: "週期結束時間"
"12_hour_clock": "12小時制"
"24_hour_clock": "24小時制"
@ -17,6 +20,14 @@ zh_tw:
month: "月曆"
agenda: "日程"
day_of_the_week: "星期幾"
short_day:
"0": "日"
"1": "一"
"2": "二"
"3": "三"
"4": "四"
"5": "五"
"6": "六"
day:
"0": "週日"
"1": "週一"

View File

@ -5,7 +5,7 @@ Rails.application.routes.draw do
Thread.new do
s = Site.first
update_flag = s.respond_to?(:tmp_flags)
need_update = !update_flag || !(s.tmp_flags.include?('cf1'))
need_update = !update_flag || !(s.tmp_flags.include?('cf2'))
calendar_setting = CalendarSetting.first
calendar_setting = CalendarSetting.create if calendar_setting.nil?
if need_update
@ -21,9 +21,14 @@ Rails.application.routes.draw do
e.url_translations = locales.map{|l| [l.to_s, e[:url].to_s]}.to_h
e.save
end
Event.where(:period=>'Weekly',:weekdays=>nil).each do |e|
wday = e.start.wday rescue nil
e.weekdays = [wday]
e.save
end
if update_flag
s = Site.first
s.tmp_flags << 'cf1'
s.tmp_flags << 'cf2'
s.save
end
puts "Calendar fix!"