radiant-event_calendar-extension 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +0 -0
- data/README.md +198 -0
- data/Rakefile +139 -0
- data/VERSION +1 -0
- data/app/controllers/admin/calendars_controller.rb +18 -0
- data/app/controllers/admin/event_venues_controller.rb +3 -0
- data/app/controllers/admin/events_controller.rb +9 -0
- data/app/controllers/admin/icals_controller.rb +26 -0
- data/app/controllers/events_controller.rb +201 -0
- data/app/models/calendar.rb +57 -0
- data/app/models/event.rb +409 -0
- data/app/models/event_calendar_page.rb +138 -0
- data/app/models/event_occurrence.rb +89 -0
- data/app/models/event_recurrence_rule.rb +85 -0
- data/app/models/event_venue.rb +17 -0
- data/app/models/ical.rb +132 -0
- data/app/views/admin/calendars/_actions.html.haml +6 -0
- data/app/views/admin/calendars/_form.html.haml +56 -0
- data/app/views/admin/calendars/edit.html.haml +11 -0
- data/app/views/admin/calendars/help.html.erb +22 -0
- data/app/views/admin/calendars/index.html.haml +60 -0
- data/app/views/admin/calendars/new.html.haml +10 -0
- data/app/views/admin/calendars/show.html.haml +36 -0
- data/app/views/admin/event_venues/_event_venue.html.haml +18 -0
- data/app/views/admin/event_venues/_form.html.haml +44 -0
- data/app/views/admin/event_venues/edit.html.haml +32 -0
- data/app/views/admin/event_venues/index.html.haml +33 -0
- data/app/views/admin/event_venues/new.html.haml +32 -0
- data/app/views/admin/event_venues/remove.html.haml +17 -0
- data/app/views/admin/events/_event.html.haml +47 -0
- data/app/views/admin/events/_form.html.haml +116 -0
- data/app/views/admin/events/_list_head.html.haml +18 -0
- data/app/views/admin/events/edit.html.haml +6 -0
- data/app/views/admin/events/index.html.haml +23 -0
- data/app/views/admin/events/new.html.haml +6 -0
- data/app/views/admin/events/remove.html.haml +17 -0
- data/app/views/admin/icals/refresh.html.haml +11 -0
- data/app/views/admin/icals/refresh_all.html.haml +0 -0
- data/app/views/events/_defacet.html.haml +2 -0
- data/app/views/events/_event.html.haml +29 -0
- data/app/views/events/_event_postscript.html.haml +0 -0
- data/app/views/events/_faceting.html.haml +27 -0
- data/app/views/events/_minicalendar.html.haml +49 -0
- data/app/views/events/_other_page_parts.html.haml +0 -0
- data/app/views/events/_views.html.haml +6 -0
- data/app/views/events/index.html.haml +56 -0
- data/app/views/events/index.ics.erb +7 -0
- data/app/views/events/index.rss.builder +20 -0
- data/config/routes.rb +13 -0
- data/db/migrate/001_create_calendar_and_events.rb +21 -0
- data/db/migrate/002_calendar_add_ical_url.rb +9 -0
- data/db/migrate/003_add_calendar_category.rb +9 -0
- data/db/migrate/004_add_slug.rb +9 -0
- data/db/migrate/005_add_subscription_refresh_history.rb +11 -0
- data/db/migrate/006_create_icals.rb +13 -0
- data/db/migrate/007_move_subscriptions_to_ical.rb +15 -0
- data/db/migrate/008_clean_out_calendar.rb +12 -0
- data/db/migrate/009_basic_authentication.rb +12 -0
- data/db/migrate/010_refresh_interval.rb +9 -0
- data/db/migrate/011_more_properties.rb +8 -0
- data/db/migrate/20090818133511_simpler_ical_columns.rb +17 -0
- data/db/migrate/20090819130919_ownership.rb +17 -0
- data/db/migrate/20090820073805_site_scope.rb +13 -0
- data/db/migrate/20091118100725_event_status.rb +9 -0
- data/db/migrate/20100216080944_more_event_data.rb +31 -0
- data/db/migrate/20100218131410_recurrence_parts.rb +19 -0
- data/db/migrate/20100219102227_venues_and_categories.rb +23 -0
- data/db/migrate/20100221180539_recurrence_rules.rb +34 -0
- data/db/migrate/20100222182112_occurrences.rb +13 -0
- data/event_calendar_extension.rb +32 -0
- data/lib/calendar_period.rb +151 -0
- data/lib/event_calendar_admin_ui.rb +78 -0
- data/lib/event_calendar_tags.rb +1021 -0
- data/lib/event_search.rb +22 -0
- data/lib/event_statuses.rb +24 -0
- data/lib/tasks/event_calendar_extension_tasks.rake +29 -0
- data/pkg/radiant-event_calendar-extension-1.0.0.gem +0 -0
- data/public/icals/blank +0 -0
- data/public/images/admin/calendar.png +0 -0
- data/public/images/event_calendar/calendarlinkbg.png +0 -0
- data/public/images/event_calendar/event_shadow.png +0 -0
- data/public/images/event_calendar/ical16.png +0 -0
- data/public/images/event_calendar/maplinkbg.png +0 -0
- data/public/images/event_calendar/one_event.png +0 -0
- data/public/images/event_calendar/several_events.png +0 -0
- data/public/javascripts/admin/event_calendar.js +240 -0
- data/public/stylesheets/sass/admin/event_calendar.sass +266 -0
- data/public/stylesheets/sass/admin/modules/_grid.sass +56 -0
- data/public/stylesheets/sass/constants.sass +80 -0
- data/public/stylesheets/sass/event_calendar.sass +203 -0
- data/radiant-event_calendar-extension.gemspec +166 -0
- data/spec/datasets/calendar_events_dataset.rb +43 -0
- data/spec/datasets/calendar_pages_dataset.rb +8 -0
- data/spec/datasets/calendar_sites_dataset.rb +6 -0
- data/spec/datasets/calendars_dataset.rb +34 -0
- data/spec/datasets/recurrence_dataset.rb +7 -0
- data/spec/files/dummy.ics +59 -0
- data/spec/files/ny.ics +36 -0
- data/spec/lib/event_calendar_page_spec.rb +24 -0
- data/spec/models/calendar_spec.rb +11 -0
- data/spec/models/event_spec.rb +98 -0
- data/spec/models/ical_spec.rb +63 -0
- data/spec/models/recurrence_rule_spec.rb +82 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +36 -0
- metadata +238 -0
data/lib/event_search.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class EventSearch
|
2
|
+
attr_accessor :category, :calendars, :slugs, :period
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
Ical.check_refreshments
|
6
|
+
@period = CalendarPeriod.new
|
7
|
+
@slugs = ["all"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def slugs=(new_slugs)
|
11
|
+
unless new_slugs.blank?
|
12
|
+
@slugs = new_slugs.split("|").collect { |s| s.downcase }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
search = Event.between(@period.begin_date, @period.end_date)
|
18
|
+
search = search.in_calendars(slugs) unless slugs == 'all' || slugs.nil?
|
19
|
+
search.find(:all, :include => :calendar, :order => "start_date ASC")
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module EventStatuses
|
2
|
+
def self.included(base)
|
3
|
+
base.class_eval {
|
4
|
+
cattr_accessor :statuses
|
5
|
+
extend ClassMethods
|
6
|
+
include InstanceMethods
|
7
|
+
}
|
8
|
+
|
9
|
+
base.add_status(:id => 5, :name => 'Submitted')
|
10
|
+
base.add_status(:id => 200, :name => 'Imported')
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def add_status(properties)
|
15
|
+
statuses.push(Status.new(properties))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def to_s
|
21
|
+
id
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :event_calendar do
|
4
|
+
|
5
|
+
desc "Runs the migration of the Event Calendar extension"
|
6
|
+
task :migrate => :environment do
|
7
|
+
require 'radiant/extension_migrator'
|
8
|
+
if ENV["VERSION"]
|
9
|
+
EventCalendarExtension.migrator.migrate(ENV["VERSION"].to_i)
|
10
|
+
else
|
11
|
+
EventCalendarExtension.migrator.migrate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Copies public assets of the Event Calendar to the instance public/ directory."
|
16
|
+
task :update => :environment do
|
17
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
18
|
+
Dir[EventCalendarExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
19
|
+
path = file.sub(EventCalendarExtension.root, '')
|
20
|
+
directory = File.dirname(path)
|
21
|
+
puts "Copying #{path}..."
|
22
|
+
mkdir_p RAILS_ROOT + directory
|
23
|
+
cp file, RAILS_ROOT + path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
Binary file
|
data/public/icals/blank
ADDED
File without changes
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,240 @@
|
|
1
|
+
Toggle.SwapperBehavior = Behavior.create(Toggle.LinkBehavior, {
|
2
|
+
initialize: function ($super, options) {
|
3
|
+
$super(options);
|
4
|
+
this.plan_a = this.toggleWrappers.shift();
|
5
|
+
this.plan_b = this.toggleWrappers;
|
6
|
+
this.toggle();
|
7
|
+
},
|
8
|
+
toggle: function() {
|
9
|
+
if (this.plan_a.visible()) {
|
10
|
+
Toggle.hide(this.plan_a, 'none');
|
11
|
+
Toggle.show(this.plan_b, this.effect);
|
12
|
+
} else {
|
13
|
+
Toggle.hide(this.plan_b, 'none');
|
14
|
+
Toggle.show(this.plan_a, this.effect);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
});
|
18
|
+
|
19
|
+
Toggle.RecurrenceSelect = Behavior.create(Toggle.SelectBehavior, {
|
20
|
+
initialize: function($super, options) {
|
21
|
+
var options = options || {};
|
22
|
+
var optionElements = this.element.select('option');
|
23
|
+
this.toggleWrapperIDs = $A();
|
24
|
+
this.toggleWrapperIDsFor = {};
|
25
|
+
|
26
|
+
optionElements.each(function(optionElement) {
|
27
|
+
var eid = 'recurrence_' + optionElement.readAttribute('value');
|
28
|
+
var elements = [$(eid)];
|
29
|
+
var wrapperIDs = elements.map(function(e) { return Toggle.wrapElement(e); }).invoke('identify');
|
30
|
+
this.toggleWrapperIDsFor[optionElement.identify()] = wrapperIDs;
|
31
|
+
this.toggleWrapperIDs.push(wrapperIDs);
|
32
|
+
}.bind(this));
|
33
|
+
this.toggleWrapperIDs = this.toggleWrapperIDs.flatten().uniq();
|
34
|
+
|
35
|
+
this.effect = "none";
|
36
|
+
this.toggle();
|
37
|
+
this.effect = options.effect || Toggle.DefaultEffect;
|
38
|
+
},
|
39
|
+
toggle: function($super) {
|
40
|
+
var combo = this.element;
|
41
|
+
var option = $(combo.options[combo.selectedIndex]);
|
42
|
+
var wrapperIDs = this.toggleWrapperIDsFor[option.identify()];
|
43
|
+
var partitioned = this.toggleWrapperIDs.partition(function(id) { return wrapperIDs.include(id); });
|
44
|
+
|
45
|
+
Toggle.hide(partitioned[1], 'none');
|
46
|
+
Toggle.show(partitioned[0], this.effect);
|
47
|
+
}
|
48
|
+
});
|
49
|
+
|
50
|
+
Toggle.MCE = Behavior.create(Toggle.LinkBehavior, {
|
51
|
+
initialize: function($super, options) {
|
52
|
+
var elements = Toggle.extractToggleObjects(this.element.readAttribute('rel'));
|
53
|
+
this.textarea = elements.shift();
|
54
|
+
},
|
55
|
+
toggle: function() {
|
56
|
+
if (!tinyMCE.get(this.textarea)) {
|
57
|
+
tinyMCE.execCommand('mceAddControl', false, this.textarea);
|
58
|
+
} else {
|
59
|
+
tinyMCE.execCommand('mceRemoveControl', false, this.textarea);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
});
|
63
|
+
|
64
|
+
// We can't rely on padding-right so hard-code the width of the icon instead
|
65
|
+
|
66
|
+
DateInputBehavior.addMethods({
|
67
|
+
_isOverWidget: function(event) {
|
68
|
+
var positionedOverWidget = null;
|
69
|
+
if (Prototype.Browser.IE) {
|
70
|
+
var widgetLeft = this.element.cumulativeOffset().left;
|
71
|
+
var widgetRight = this.element.cumulativeOffset().left + this.element.getDimensions().width;
|
72
|
+
positionedOverWidget = (event.pointerX() >= widgetLeft && event.pointerX() <= widgetRight);
|
73
|
+
} else {
|
74
|
+
var calendarIconWidth = 40;
|
75
|
+
var widgetLeft = this.element.cumulativeOffset().left + this.element.getDimensions().width - calendarIconWidth;
|
76
|
+
positionedOverWidget = (event.pointerX() >= widgetLeft);
|
77
|
+
}
|
78
|
+
return positionedOverWidget;
|
79
|
+
}
|
80
|
+
});
|
81
|
+
|
82
|
+
// Override the usual Calendar to add a time-picker if the input field also has class 'time'
|
83
|
+
// and to tweak the positioning of the calendar
|
84
|
+
|
85
|
+
var calendar_displacement = {x: 16, y: 16};
|
86
|
+
|
87
|
+
DateInputBehavior.Calendar.addMethods({
|
88
|
+
_setDate: function(source) {
|
89
|
+
if (source.innerHTML.strip() != '') {
|
90
|
+
this.date.setDate(parseInt(source.innerHTML, 10)); // nb. only sets the day of month.
|
91
|
+
$A(this.element.getElementsByClassName('selected')).invoke('removeClassName', 'selected');
|
92
|
+
source.parentNode.addClassName('selected');
|
93
|
+
if (this.selector.element.hasClassName('time')) {
|
94
|
+
this._showTime();
|
95
|
+
} else {
|
96
|
+
this.selector.setDate(this.date);
|
97
|
+
}
|
98
|
+
}
|
99
|
+
},
|
100
|
+
_createTimeChooser : function() {
|
101
|
+
this.date_chooser = this.element.select('table.calendar').first();
|
102
|
+
var timer = this.element.select('div.clock_control').first() || $div({'class': 'clock_control'});
|
103
|
+
this.element.insert(timer);
|
104
|
+
timer.clonePosition(this.date_chooser);
|
105
|
+
timer.setStyle({position: 'relative', left: 0, top: 0, width: this.date_chooser.getWidth(), height: 'auto'});
|
106
|
+
this.time_chooser = new DateInputBehavior.Clock(timer, this);
|
107
|
+
},
|
108
|
+
_showTime: function () {
|
109
|
+
this._createTimeChooser();
|
110
|
+
this.date_chooser.hide();
|
111
|
+
this.time_chooser.show();
|
112
|
+
},
|
113
|
+
_hideTime: function () {
|
114
|
+
this.time_chooser.hide();
|
115
|
+
this.date_chooser.show();
|
116
|
+
},
|
117
|
+
_setTime: function (h,m) {
|
118
|
+
this.date.setHours(h);
|
119
|
+
this.date.setMinutes(m);
|
120
|
+
this.date.setSeconds(0);
|
121
|
+
this.selector.setDate(this.date);
|
122
|
+
},
|
123
|
+
show: function() {
|
124
|
+
DateInputBehavior.Calendar.instances.invoke('hide');
|
125
|
+
this.date = this.selector.getDate();
|
126
|
+
this.redraw();
|
127
|
+
this.element.setStyle({
|
128
|
+
'top': this.getVerticalOffset(this.selector.element) + 'px',
|
129
|
+
'left': this.getHorizontalOffset(this.selector.element) + 'px',
|
130
|
+
'z-index': 10001
|
131
|
+
});
|
132
|
+
this.element.show();
|
133
|
+
this.active = true;
|
134
|
+
},
|
135
|
+
getVerticalOffset: function(selector){
|
136
|
+
var defaultOffset = this.selector.element.cumulativeOffset().top + this.selector.element.getHeight() + 2;
|
137
|
+
var height = this.element.getHeight();
|
138
|
+
var top = 0;
|
139
|
+
if (document.viewport.getHeight() > defaultOffset + height) {
|
140
|
+
top = defaultOffset - calendar_displacement.y;
|
141
|
+
} else {
|
142
|
+
top = (defaultOffset - height - selector.getHeight() - 6 + calendar_displacement.y);
|
143
|
+
}
|
144
|
+
if (top < document.viewport.getScrollOffsets().top) {
|
145
|
+
top = document.viewport.getScrollOffsets().top;
|
146
|
+
}
|
147
|
+
|
148
|
+
return top;
|
149
|
+
},
|
150
|
+
getHorizontalOffset: function (element) {
|
151
|
+
return element.cumulativeOffset().left + element.getWidth() - calendar_displacement.x;
|
152
|
+
}
|
153
|
+
});
|
154
|
+
|
155
|
+
Date.prototype.getPaddedMonth = function() {
|
156
|
+
var m = (this.getMonth() + 1).toString();
|
157
|
+
return (m.length > 1) ? m : "0" + m;
|
158
|
+
};
|
159
|
+
|
160
|
+
Date.prototype.getPaddedDate = function() {
|
161
|
+
var d = this.getDate().toString();
|
162
|
+
return (d.length > 1) ? d : "0" + d;
|
163
|
+
};
|
164
|
+
|
165
|
+
Date.prototype.getPaddedHours = function() {
|
166
|
+
var m = this.getHours().toString();
|
167
|
+
return (m.length > 1) ? m : "0" + m;
|
168
|
+
};
|
169
|
+
|
170
|
+
Date.prototype.getPaddedMinutes = function() {
|
171
|
+
var m = this.getMinutes().toString();
|
172
|
+
return (m.length > 1) ? m : "0" + m;
|
173
|
+
};
|
174
|
+
|
175
|
+
Date.prototype.getPaddedSeconds = function() {
|
176
|
+
var s = this.getSeconds().toString();
|
177
|
+
return (s.length > 1) ? s : "0" + s;
|
178
|
+
};
|
179
|
+
|
180
|
+
DateInputBehavior.Clock = Behavior.create({
|
181
|
+
initialize: function(calendar) {
|
182
|
+
this.calendar = calendar;
|
183
|
+
this.date = calendar.date;
|
184
|
+
this.redraw();
|
185
|
+
},
|
186
|
+
redraw: function () {
|
187
|
+
this.form = new Element('form', {'class': 'clock'});
|
188
|
+
this.element.update(this.form);
|
189
|
+
|
190
|
+
this.h = new Element('input', {'type' : 'text', 'class': 'hours', name: 'hours'}).setValue(this.date.getPaddedHours());
|
191
|
+
this.m = new Element('input', {'type' : 'text', 'class': 'minutes', name: 'minutes'}).setValue(this.date.getPaddedMinutes());
|
192
|
+
this.button = new Element('input', {'type' : 'button', 'class': 'set_time', name: 'set'}).setValue('set');
|
193
|
+
this.cancel = new Element('a', {'href': '#', 'class': 'cancel'}).update('change date');
|
194
|
+
|
195
|
+
this.form.insert(new Element('h4', {'class': 'date'}).update(this.date.getDate() + ' ' + DateInputBehavior.Calendar.MONTHS[this.date.getMonth()].label + ', ' + this.date.getFullYear() + ' at:'));
|
196
|
+
this.form.insert(this.h);
|
197
|
+
this.form.insert(new Element('span', {'class': 'colon'}).update(':'));
|
198
|
+
this.form.insert(this.m);
|
199
|
+
this.form.insert(new Element('br'));
|
200
|
+
this.form.insert(this.button);
|
201
|
+
this.form.insert(new Element('br'));
|
202
|
+
this.form.insert(this.cancel);
|
203
|
+
},
|
204
|
+
onclick: function (event) {
|
205
|
+
event.stop();
|
206
|
+
if ($(event.target).hasClassName('set_time')) this.submit();
|
207
|
+
if ($(event.target).hasClassName('cancel')) this.goback();
|
208
|
+
},
|
209
|
+
submit: function () {
|
210
|
+
this.calendar._setTime(this.h.getValue(), this.m.getValue());
|
211
|
+
},
|
212
|
+
goback: function () {
|
213
|
+
this.calendar._hideTime();
|
214
|
+
},
|
215
|
+
show: function () {
|
216
|
+
this.element.show();
|
217
|
+
},
|
218
|
+
hide: function () {
|
219
|
+
this.element.hide();
|
220
|
+
}
|
221
|
+
});
|
222
|
+
|
223
|
+
DateInputBehavior.DEFAULTS = {
|
224
|
+
setter: function(date) {
|
225
|
+
return date.getFullYear() + '-' + date.getPaddedMonth() + '-' + date.getPaddedDate() + ' ' + date.getHours() + ':' + date.getPaddedMinutes() + ':' + date.getPaddedSeconds();
|
226
|
+
},
|
227
|
+
getter: function(value) {
|
228
|
+
var p = value.split(/\D+/g);
|
229
|
+
if (!p[0]) return null;
|
230
|
+
var date = new Date(p[0],p[1]-1,p[2],p[3],p[4],p[5]);
|
231
|
+
return date;
|
232
|
+
}
|
233
|
+
};
|
234
|
+
|
235
|
+
Event.addBehavior({
|
236
|
+
"input.toggle": Toggle.CheckboxBehavior,
|
237
|
+
"a.swapper" : Toggle.SwapperBehavior({effect : 'appear'}),
|
238
|
+
"select.basis" : Toggle.RecurrenceSelect({effect : 'appear'}),
|
239
|
+
"a.toggleMCE" : Toggle.MCE
|
240
|
+
});
|
@@ -0,0 +1,266 @@
|
|
1
|
+
@import modules/rounded.sass
|
2
|
+
@import modules/opacity.sass
|
3
|
+
@import modules/grid.sass
|
4
|
+
|
5
|
+
=standard_input
|
6
|
+
:width 100%
|
7
|
+
:padding 6px 0
|
8
|
+
:font-family Monaco,"Courier New",Courier,monospace
|
9
|
+
:font-size 95%
|
10
|
+
|
11
|
+
=quiet
|
12
|
+
:font-family helvetica, arial, sans-serif
|
13
|
+
:font-weight lighter
|
14
|
+
:font-size 85%
|
15
|
+
:color #ccc
|
16
|
+
:line-height 1.3
|
17
|
+
:text-shadow none
|
18
|
+
|
19
|
+
=flatbottom
|
20
|
+
:margin-bottom 0
|
21
|
+
|
22
|
+
!radiant_red = #c00
|
23
|
+
|
24
|
+
//calendars index
|
25
|
+
|
26
|
+
table.index
|
27
|
+
td.subscription-title
|
28
|
+
:font-size 115%
|
29
|
+
:font-weight bold
|
30
|
+
|
31
|
+
span.calendar_actions
|
32
|
+
img
|
33
|
+
:opacity 0.5
|
34
|
+
a
|
35
|
+
img
|
36
|
+
:opacity 1
|
37
|
+
|
38
|
+
//events index
|
39
|
+
|
40
|
+
table#events
|
41
|
+
tr
|
42
|
+
td.datemark
|
43
|
+
:width 40px
|
44
|
+
:vertical-align top
|
45
|
+
:text-align center
|
46
|
+
:line-height 1
|
47
|
+
a
|
48
|
+
:text-decoration none
|
49
|
+
span.month
|
50
|
+
:display block
|
51
|
+
:margin-top 5px
|
52
|
+
:font-family helvetica, arial, sans-serif
|
53
|
+
:font-weight lighter
|
54
|
+
:font-size 80%
|
55
|
+
:text-transform uppercase
|
56
|
+
span.day
|
57
|
+
:display block
|
58
|
+
:font-family helvetica, arial, sans-serif
|
59
|
+
:font-weight bold
|
60
|
+
:font-size 160%
|
61
|
+
td.event
|
62
|
+
:width 40%
|
63
|
+
:vertical-align top
|
64
|
+
h3
|
65
|
+
:margin 0
|
66
|
+
:line-height 1.2
|
67
|
+
a
|
68
|
+
:text-decoration none
|
69
|
+
p.description
|
70
|
+
:margin 4px 0
|
71
|
+
:font-size 80%
|
72
|
+
:color #999
|
73
|
+
p.keywords
|
74
|
+
:margin 4px 0
|
75
|
+
:font-size 80%
|
76
|
+
td.time, td.location, td.keywords, td.recurrence
|
77
|
+
:font-size 80%
|
78
|
+
:padding-top 28px
|
79
|
+
:vertical-align top
|
80
|
+
td.remove
|
81
|
+
:padding-top 28px
|
82
|
+
:vertical-align top
|
83
|
+
span.ineditable
|
84
|
+
:color #666
|
85
|
+
:font-size 80%
|
86
|
+
:background url(/images/admin/minus.png) no-repeat scroll 4px 0
|
87
|
+
:padding-left 20px
|
88
|
+
:opacity 0.3
|
89
|
+
tr.continuing
|
90
|
+
td.datemark
|
91
|
+
a
|
92
|
+
:color #b2aaa4
|
93
|
+
td.event
|
94
|
+
h3
|
95
|
+
a
|
96
|
+
:color #b2aaa4
|
97
|
+
|
98
|
+
// venues index
|
99
|
+
|
100
|
+
table#event_venues
|
101
|
+
td.event_venue
|
102
|
+
:width 40%
|
103
|
+
:vertical-align top
|
104
|
+
h3
|
105
|
+
:margin 0
|
106
|
+
:line-height 1.2
|
107
|
+
a
|
108
|
+
:text-decoration none
|
109
|
+
p.description
|
110
|
+
:margin 4px 0
|
111
|
+
:font-size 80%
|
112
|
+
:color #999
|
113
|
+
td.location, td.url
|
114
|
+
:font-size 80%
|
115
|
+
:vertical-align top
|
116
|
+
|
117
|
+
// event and calendar forms
|
118
|
+
|
119
|
+
#content
|
120
|
+
#event_form, #calendar_form, #venue_form
|
121
|
+
div
|
122
|
+
p
|
123
|
+
input.textbox, select.textbox, textarea
|
124
|
+
+standard_input
|
125
|
+
:margin-top 0.3em
|
126
|
+
p.note
|
127
|
+
+grid(4)
|
128
|
+
:padding-top 1.7em
|
129
|
+
div.title
|
130
|
+
:clear left
|
131
|
+
p.event_title, p.calendar_title, p.keywords, p.venue_title
|
132
|
+
:margin-bottom 1em
|
133
|
+
input
|
134
|
+
:font-family Georgia,Palatino,"Times New Roman",Times,serif
|
135
|
+
:font-size 200%
|
136
|
+
p.event_title
|
137
|
+
+grid(8)
|
138
|
+
p.keywords
|
139
|
+
+grid(4)
|
140
|
+
input
|
141
|
+
:color = !radiant_red
|
142
|
+
p.calendar_category, p.calendar_slug
|
143
|
+
+grid(4)
|
144
|
+
div.url
|
145
|
+
+grid(12)
|
146
|
+
:clear left
|
147
|
+
|
148
|
+
div.description
|
149
|
+
:clear left
|
150
|
+
p.description
|
151
|
+
+grid(8)
|
152
|
+
textarea
|
153
|
+
:height 16em
|
154
|
+
p.calendar
|
155
|
+
+grid(4)
|
156
|
+
|
157
|
+
div.ical
|
158
|
+
:clear left
|
159
|
+
p.url
|
160
|
+
+grid(8)
|
161
|
+
:margin-top 0
|
162
|
+
p.username, p.password
|
163
|
+
+grid(4)
|
164
|
+
p.username
|
165
|
+
:margin-right 2%
|
166
|
+
|
167
|
+
div.date
|
168
|
+
:clear left
|
169
|
+
p.start_date, p.end_date
|
170
|
+
+grid(4)
|
171
|
+
:margin-bottom 0
|
172
|
+
p.problematic
|
173
|
+
:color = !radiant_red
|
174
|
+
|
175
|
+
div.recurrence
|
176
|
+
:clear left
|
177
|
+
p.recurrence
|
178
|
+
:margin-top 0
|
179
|
+
span.recurrence_detail
|
180
|
+
:display block
|
181
|
+
span#recurrence_interval
|
182
|
+
+grid(2)
|
183
|
+
span#recurrence_period
|
184
|
+
+grid(2)
|
185
|
+
span#recurrence_basis
|
186
|
+
+grid(2)
|
187
|
+
span#recurrence_limit
|
188
|
+
+grid(2)
|
189
|
+
+flush_right
|
190
|
+
span#recurrence_count
|
191
|
+
+grid(2)
|
192
|
+
+flush_right
|
193
|
+
|
194
|
+
div.venue, div.newvenue
|
195
|
+
:overflow auto
|
196
|
+
|
197
|
+
div#venue
|
198
|
+
:clear left
|
199
|
+
p#existing_venue
|
200
|
+
+grid(8)
|
201
|
+
div#new_venue
|
202
|
+
:clear left
|
203
|
+
p.venue_title
|
204
|
+
+grid(8)
|
205
|
+
p.url
|
206
|
+
:clear left
|
207
|
+
+grid(8)
|
208
|
+
p.venue_location
|
209
|
+
+grid(8)
|
210
|
+
textarea
|
211
|
+
:height 5em
|
212
|
+
p.venue_postcode
|
213
|
+
+grid(4)
|
214
|
+
span.note
|
215
|
+
:display block
|
216
|
+
:margin-top 4px
|
217
|
+
p.venue_description
|
218
|
+
+grid(12)
|
219
|
+
:clear both
|
220
|
+
textarea
|
221
|
+
:height 5em
|
222
|
+
.note, label.minor
|
223
|
+
+quiet
|
224
|
+
:display inline
|
225
|
+
label.inline
|
226
|
+
:display inline
|
227
|
+
.hidden
|
228
|
+
:display none
|
229
|
+
|
230
|
+
|
231
|
+
a.toggleMCE
|
232
|
+
:display block
|
233
|
+
:width 24px
|
234
|
+
:height 24px
|
235
|
+
:padding-left 24px
|
236
|
+
:float right
|
237
|
+
|
238
|
+
.calendar_popup
|
239
|
+
div.clock_control
|
240
|
+
:position relative
|
241
|
+
:display block
|
242
|
+
:width 300px
|
243
|
+
:height 200px
|
244
|
+
form
|
245
|
+
:text-align center
|
246
|
+
h4
|
247
|
+
:margin 10px
|
248
|
+
:color #999
|
249
|
+
:font-weight lighter
|
250
|
+
input.hours, input.minutes
|
251
|
+
:width 60px
|
252
|
+
:border 1px solid #ccc
|
253
|
+
:padding 4px
|
254
|
+
:font-size 40px
|
255
|
+
span.colon
|
256
|
+
:padding 4px
|
257
|
+
:font-size 40px
|
258
|
+
:color #333
|
259
|
+
:width 10px
|
260
|
+
input.set_time
|
261
|
+
:font-size 30px
|
262
|
+
:width 114px
|
263
|
+
:margin 20px 0
|
264
|
+
a.cancel
|
265
|
+
:cursor pointer
|
266
|
+
|