Add hide recurring event feature.

This commit is contained in:
BoHung Chiu 2022-07-28 14:41:27 +08:00
parent 9ea1b5b81a
commit f47b8126ab
6 changed files with 185 additions and 59 deletions

View File

@ -634,6 +634,7 @@ var EventDialog = function(calendar,event){
template += '<div class="modal-footer">' + template += '<div class="modal-footer">' +
'<a href="'+ _event.delete_url +'" class="delete btn btn-primary">Delete</a>' + '<a href="'+ _event.delete_url +'" class="delete btn btn-primary">Delete</a>' +
'<a href="'+ _event.edit_url +'" class="edit btn btn-primary" >Edit</a>' + '<a href="'+ _event.edit_url +'" class="edit btn btn-primary" >Edit</a>' +
(_event.recurring ? '<a href="'+ _event.edit_url +'?start='+getDateString(_event._start, "yy-MM-dd")+'" class="hide_event btn '+(_event.hide ? 'btn-success' : 'btn-danger')+'" data-new-hide="'+(_event.hide ? 'false' : 'true')+'">' + (_event.hide ? 'Show' : 'Hide') + '</a>' : '')
'</div>'; '</div>';
} }
} }
@ -654,6 +655,40 @@ var EventDialog = function(calendar,event){
event_quick_view.find(".event-close-btn").one("click",function(){_t.dismiss();}); event_quick_view.find(".event-close-btn").one("click",function(){_t.dismiss();});
event_quick_view.find("a.delete").one("click",function(){calendar.deleteEvent(_this_event.delete_url,_this_event._id);return false;}); event_quick_view.find("a.delete").one("click",function(){calendar.deleteEvent(_this_event.delete_url,_this_event._id);return false;});
event_quick_view.find("a.edit").one("click",function(){calendar.editEvent(_this_event.edit_url,_this_event.allDay);return false;}); event_quick_view.find("a.edit").one("click",function(){calendar.editEvent(_this_event.edit_url,_this_event.allDay);return false;});
event_quick_view.find("a.hide_event").off("click").on("click", function(){
var _this = $(this);
var new_hide = _this.attr('data-new-hide');
if(new_hide == "true"){
if(!(window.confirm(I18n.locale == 'zh_tw' ? "您確定要隱藏該事件嗎?" : "Are you sure to hide event?"))){
return false;
}
}
$.get(_this.attr('href') + "&hide="+ new_hide).done(function(data){
if(data["success"]){
if(new_hide == "true"){
if($('#display_hide').length != 0 && $('#display_hide').prop('checked')){
_this.removeClass('btn-danger').addClass('btn-success');
_this.text("Show");
_this.attr('data-new-hide', "false");
_this_event.event.setProp('color', _this_event.hide_color);
_this_event.event.setExtendedProp('hide', true);
}else{
_this_event.event.remove();
}
}else{
_this.removeClass('btn-success').addClass('btn-danger');
_this.text("Hide");
_this.attr('data-new-hide', "true");
_this_event.event.setProp('color', _this_event.org_color);
_this_event.event.setExtendedProp('hide', false);
}
event_quick_view.remove();
}else{
alert("Something went wrong!")
}
})
return false;
})
var window_width = $(window).width(), var window_width = $(window).width(),
window_height = $(window).height(); window_height = $(window).height();
var dialog_width = event_quick_view.width(), var dialog_width = event_quick_view.width(),

View File

@ -15,15 +15,12 @@ class Admin::CalendarsController < OrbitAdminController
if params[:start].present? && params[:end].present? if params[:start].present? && params[:end].present?
sdt = Time.at(params[:start].to_i) sdt = Time.at(params[:start].to_i)
edt = Time.at(params[:end].to_i) edt = Time.at(params[:end].to_i)
@monthly_events = Event.monthly_event(sdt,edt).with_categories(filters("category")) allevents = Event.with_categories(filters("category"))
.with_tags(filters("tag")).convert_front .with_tags(filters("tag")).agenda_events(sdt,edt, params[:display_hide] == 'true')
@re = Event.with_categories(filters("category")).with_tags(filters("tag")).recurring_event(sdt,edt) allevents.each do |e|
allevents = @monthly_events.inject(@re, :<<).sort_by{|e| e[:start]} event_json = e.as_json
events = allevents.to_json event_json["can_edit"] = can_edit_or_delete_event?(e)
events = JSON.parse(events) @events << event_json
events.each_with_index do |e,i|
e["can_edit"] = can_edit_or_delete_event?(allevents[i])
@events << e
end end
end end
if request.xhr? if request.xhr?
@ -94,17 +91,29 @@ class Admin::CalendarsController < OrbitAdminController
# GET /events/1/edit # GET /events/1/edit
def edit def edit
@event = Event.find(params[:id]) @event = Event.find(params[:id])
categories = user_authenticated_categories rescue [] if params[:hide]
if categories.first == "all" hide_mode = (params[:hide] == 'true')
@categories = CalendarType.all start = params[:start]
if hide_mode
@event.hide_start << start
else
@event.hide_start.delete(start)
end
@event.save
render :json => {:success=>true}.to_json
else else
@categories = CalendarType.where(:category_id.in => categories) rescue [] categories = user_authenticated_categories rescue []
if categories.first == "all"
@categories = CalendarType.all
else
@categories = CalendarType.where(:category_id.in => categories) rescue []
end
@end_d_t = @event.end.strftime("%Y/%m/%d %H:%M").to_s
@start_d_t = @event.start.strftime("%Y/%m/%d %H:%M").to_s
@all_day = @event.all_day
@recurring = @event.recurring
render :layout => false
end end
@end_d_t = @event.end.strftime("%Y/%m/%d %H:%M").to_s
@start_d_t = @event.start.strftime("%Y/%m/%d %H:%M").to_s
@all_day = @event.all_day
@recurring = @event.recurring
render :layout => false
end end
# POST /events # POST /events
@ -138,8 +147,7 @@ class Admin::CalendarsController < OrbitAdminController
bulletin.update_attributes(calendar_start_date: p1[:start],calendar_end_date: p1[:end],calendar_all_day: p1[:all_day],calendar_type_id: p1[:calendar_type_id]) bulletin.update_attributes(calendar_start_date: p1[:start],calendar_end_date: p1[:end],calendar_all_day: p1[:all_day],calendar_type_id: p1[:calendar_type_id])
end end
if @event.update_attributes(p1) if @event.update_attributes(p1)
e = @event.to_json e = @event.as_json({}, true)
e = JSON.parse(e)
e["can_edit"] = true e["can_edit"] = true
render json: e.to_json render json: e.to_json
else else

View File

@ -29,6 +29,7 @@ class Event
belongs_to :calendar_type belongs_to :calendar_type
field :url field :url
field :url_translations, type: Hash, default: {} field :url_translations, type: Hash, default: {}
field :hide_start, type: Array, default: [] # store date string, ex: ["2022-07-29"]
def get_module_url 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 = !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) page.nil? ? '' : (page.url+'/'+eval(self.model_class).where(:id=>self.model_id).first.to_calendar_param)
@ -66,11 +67,15 @@ class Event
self['title'] = self.title self['title'] = self.title
self['note'] = self.note self['note'] = self.note
self['url'] = self.url self['url'] = self.url
if self.hide_start_changed?
self.hide_start.sort!
end
if self.is_weekdays if self.is_weekdays
self.weekdays = (1..5).to_a #平日 self.weekdays = (1..5).to_a #平日
else else
self.weekdays = self.weekdays.map{|s| s.to_i}.sort self.weekdays = self.weekdays.map{|s| s.to_i}.sort
end end
true
end end
######################################## ########################################
validates_presence_of :title, :message => "Please fill the title of the Event", :if => lambda { self['title_translations'].blank? } validates_presence_of :title, :message => "Please fill the title of the Event", :if => lambda { self['title_translations'].blank? }
@ -108,7 +113,7 @@ class Event
"Yearly" "Yearly"
] ]
def as_json(options = {}) def as_json(options = {}, preserve_hide = false)
tmp_note = self.note || "" tmp_note = self.note || ""
if self.recurring if self.recurring
freq = self.frequency.to_i freq = self.frequency.to_i
@ -149,55 +154,72 @@ class Event
tmp_note = I18n.t("calendar.every_year_day", {:every_n_years=>every_n_years,:date=>date}) + "<br>" + tmp_note tmp_note = I18n.t("calendar.every_year_day", {:every_n_years=>every_n_years,:date=>date}) + "<br>" + tmp_note
end end
end end
hide = false
if options["frontend"] if options["frontend"]
{ if (self.recurring && self.hide_start.include?(self.start))
:id => self.id.to_s, hide = true
:title => self.title, nil
:note => tmp_note, else
:start => self.start.to_json.gsub('"',''), {
:end => (self.all_day ? [self.start, self.end - 1.day].max : self.end).to_json.gsub('"',''), :id => self.id.to_s,
:allDay => self.all_day, :title => self.title,
:recurring => self.recurring, :note => tmp_note,
:calendar => self.calendar_type_id.to_s, :start => self.start.to_json.gsub('"',''),
:color => (self.calendar_type.color rescue nil), :end => (self.all_day ? [self.start, self.end - 1.day].max : self.end).to_json.gsub('"',''),
:diff_day => self.all_day :allDay => self.all_day,
} :recurring => self.recurring,
:calendar => self.calendar_type_id.to_s,
:color => (self.calendar_type.color rescue nil),
:diff_day => self.all_day
}
end
else else
{ need_hide = (self.recurring && self.hide_start.include?(self.start.strftime("%Y-%m-%d")))
:id => self.id.to_s, unless preserve_hide
:title => self.title, hide = need_hide
:note => tmp_note, end
:start => self.start.to_json.gsub('"',''), if hide
:end => (self.all_day ? [self.start, self.end - 1.day].max : self.end).to_json.gsub('"',''), nil
:allDay => self.all_day, else
:recurring => self.recurring, org_color = (self.calendar_type.color rescue nil)
:calendar => self.calendar_type_id.to_s, {
:color => (self.calendar_type.color rescue nil), :id => self.id.to_s,
:diff_day => self.all_day, :title => self.title,
:edit_url => Rails.application.routes.url_helpers.edit_admin_calendar_path(:locale=>I18n.locale, :id=>self.id), :note => tmp_note,
:delete_url => Rails.application.routes.url_helpers.admin_calendar_path(:locale=>I18n.locale, :id=>self.id) :start => self.start.to_json.gsub('"',''),
} :end => (self.all_day ? [self.start, self.end - 1.day].max : self.end).to_json.gsub('"',''),
:allDay => self.all_day,
:recurring => self.recurring,
:calendar => self.calendar_type_id.to_s,
:color => (need_hide ? "#c0c0c0" : org_color),
:diff_day => self.all_day,
:edit_url => Rails.application.routes.url_helpers.edit_admin_calendar_path(:locale=>I18n.locale, :id=>self.id),
:delete_url => Rails.application.routes.url_helpers.admin_calendar_path(:locale=>I18n.locale, :id=>self.id),
:hide => need_hide,
:org_color => org_color,
:hide_color => "#c0c0c0"
}
end
end end
end end
def self.monthly_event(start_date,end_date) def self.monthly_event(start_date,end_date)
self.any_of({:start.lte => start_date,:end.gte => start_date},{:start.gte => start_date,:end.lte => end_date},{:start.lte => end_date,:end.gte => end_date}).asc(:start) self.any_of({:start.lte => start_date,:end.gte => start_date},{:start.gte => start_date,:end.lte => end_date},{:start.lte => end_date,:end.gte => end_date}).asc(:start)
end end
def self.convert_front def self.convert_front(preserve_hide=false)
self.all.collect do |re| self.all.collect do |re|
re.as_json re.as_json({}, preserve_hide)
end end.compact
end end
def self.get_diff_month(date1,date2) def self.get_diff_month(date1,date2)
(date2.year-date1.year)*12+(date2.month-date1.month) (date2.year-date1.year)*12+(date2.month-date1.month)
end end
def self.recurring_event(start_date,end_date) def self.recurring_event(start_date, end_date, preserve_hide=false)
@recurring_events = self.where(:recurring => true).any_of({:recurring_end_date=>nil}, {:recurring_end_date.gte=>start_date.utc}) @recurring_events = self.where(:recurring => true).any_of({:recurring_end_date=>nil}, {:recurring_end_date.gte=>start_date.utc})
@recurring = [] @recurring = []
@recurring_events.each do |re| @recurring_events.each do |re|
has_recurring_end_date = re.recurring_end_date.present? has_recurring_end_date = re.recurring_end_date.present?
data = re.as_json data = re.as_json({}, true)
period_str = nil period_str = nil
is_month = false is_month = false
is_year = false is_year = false
@ -228,6 +250,7 @@ class Event
@end_date = (re.all_day ? [re.start, re.end - 1.day].max : re.end) @end_date = (re.all_day ? [re.start, re.end - 1.day].max : re.end)
freq = re.frequency.to_i freq = re.frequency.to_i
interval = freq.send(period_str) interval = freq.send(period_str)
tmp_hide_start = re.hide_start.clone
if is_month if is_month
add_interval = ((start_date.year * 12 + start_date.month) - (@start_date.year * 12 + @start_date.month) - 1) add_interval = ((start_date.year * 12 + start_date.month) - (@start_date.year * 12 + @start_date.month) - 1)
elsif is_year elsif is_year
@ -252,21 +275,60 @@ class Event
@start_date += add_interval @start_date += add_interval
@end_date += add_interval @end_date += add_interval
new_end_date = has_recurring_end_date ? [re.recurring_end_date,end_date].min : end_date new_end_date = has_recurring_end_date ? [re.recurring_end_date,end_date].min : end_date
need_check_hide = false
if tmp_hide_start.count != 0
tmp = @start_date.strftime("%Y-%m-%d")
st_idx = tmp_hide_start.index{|s| s >= tmp}
if st_idx.nil?
tmp_hide_start = []
else
tmp_hide_start = tmp_hide_start[st_idx..-1]
end
need_check_hide = true
else
need_check_hide = false
end
while @start_date <= new_end_date do while @start_date <= new_end_date do
if weekdays if weekdays
if need_check_hide
tmp_hide_start2 = tmp_hide_start[0..-1] #clone array
end_check = (@start_date + 6.day).strftime("%Y-%m-%d")
last_idx = tmp_hide_start2.index{|s| s > end_check}
if last_idx
tmp_hide_start2 = tmp_hide_start2[0...last_idx]
tmp_hide_start = tmp_hide_start[last_idx..-1]
need_check_hide = tmp_hide_start.count != 0
end
else
tmp_hide_start2 = []
end
weekdays.each do |w| weekdays.each do |w|
new_start = (@start_date + w.day) new_start = (@start_date + w.day)
if need_check_start && new_start < start_date if need_check_start && new_start < start_date
next next
end end
if new_start != org_start if new_start != org_start
@recurring << data.merge({:start => new_start.to_json.gsub('"',''), :end => (@end_date + w.day).to_json.gsub('"','')}) hide = need_check_hide && tmp_hide_start2.include?(new_start.strftime("%Y-%m-%d"))
if hide
if preserve_hide
@recurring << data.merge({:start => new_start.to_json.gsub('"',''), :end => (@end_date + w.day).to_json.gsub('"',''), :hide=>true, :color=>"#c0c0c0"})
end
else
@recurring << data.merge({:start => new_start.to_json.gsub('"',''), :end => (@end_date + w.day).to_json.gsub('"',''), :hide=>false, :color => data[:org_color]})
end
end end
end end
need_check_start = false need_check_start = false
else else
if @start_date != org_start if @start_date != org_start
@recurring << data.merge({:start => @start_date.to_json.gsub('"',''), :end => @end_date.to_json.gsub('"','')}) hide = need_check_hide && tmp_hide_start.include?(@start_date.strftime("%Y-%m-%d"))
if hide
if preserve_hide
@recurring << data.merge({:start => @start_date.to_json.gsub('"',''), :end => @end_date.to_json.gsub('"',''), :hide=>true, :color=>"#c0c0c0"})
end
else
@recurring << data.merge({:start => @start_date.to_json.gsub('"',''), :end => @end_date.to_json.gsub('"',''), :hide=>false, :color => data[:org_color]})
end
end end
end end
@start_date += interval @start_date += interval
@ -280,9 +342,9 @@ class Event
@recurring @recurring
end end
def self.agenda_events(agenda_start, agenda_end) def self.agenda_events(agenda_start, agenda_end, preserve_hide=false)
recurring = self.recurring_event(agenda_start,agenda_end) recurring = self.recurring_event(agenda_start,agenda_end, preserve_hide)
events = self.monthly_event(agenda_start, agenda_end).convert_front events = self.monthly_event(agenda_start, agenda_end).convert_front(preserve_hide)
recurring = recurring.concat(events) recurring = recurring.concat(events)
recurring recurring
end end

View File

@ -15,6 +15,20 @@
margin-left: 0; margin-left: 0;
} }
</style> </style>
<form action="<%= "#{request.path}" %>" method="get">
<% CGI.parse(request.query_string).each do |k,v| %>
<% if k != 'display_hide' %>
<% if v.class == Array %>
<% v.each do |vv| %>
<input type="hidden" name="<%=k%>" value="<%=vv%>">
<% end %>
<% else %>
<input type="hidden" name="<%=k%>" value="<%=v%>">
<% end %>
<% end %>
<% end %>
<input type="checkbox" id="display_hide" name="display_hide" value="true" <%='checked=checked' if params[:display_hide] == 'true' %>><%= t('calendar.display_hide_events') %>
</form>
<div id="orbit_calendar" class="month_view"> <div id="orbit_calendar" class="month_view">
<div class="clearfix cal-fn"> <div class="clearfix cal-fn">
<div id='sec2'> <div id='sec2'>
@ -61,4 +75,9 @@
<div id="calendar-loading"></div> <div id="calendar-loading"></div>
<div class="calendar-form-actions form-actions text-right"> <div class="calendar-form-actions form-actions text-right">
<%= link_to "Add", new_admin_calendar_path, :class => "btn btn-primary", :id=>"create_event_btn", :ref=>"add-btn" %> <%= link_to "Add", new_admin_calendar_path, :class => "btn btn-primary", :id=>"create_event_btn", :ref=>"add-btn" %>
</div> </div>
<script>
$('#display_hide').click(function(){
$(this).parent('form').submit();
});
</script>

View File

@ -1,5 +1,6 @@
en: en:
calendar: calendar:
display_hide_events: Display hide events
conj: ", " conj: ", "
and: " and " and: " and "
every_n_years: "Every %{num} years" every_n_years: "Every %{num} years"

View File

@ -1,5 +1,6 @@
zh_tw: zh_tw:
calendar: calendar:
display_hide_events: 顯示隱藏事件
conj: "、" conj: "、"
and: "與" and: "與"
every_n_years: "每%{num}年" every_n_years: "每%{num}年"