yodel_admin 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/layouts/admin_list_record.html +2 -1
- data/lib/layouts/admin_page.html +11 -0
- data/lib/layouts/admin_page/admin_tree_page.html +1 -1
- data/lib/layouts/admin_record_form.html +58 -22
- data/lib/public/admin/css/admin.css +169 -2
- data/lib/public/admin/js/admin.js +231 -53
- data/lib/yodel_admin.rb +1 -1
- metadata +2 -2
@@ -53,7 +53,7 @@
|
|
53
53
|
$('#save_failure').fadeIn().delay(2000).fadeOut();
|
54
54
|
<% end %>
|
55
55
|
|
56
|
-
<% record.field_sections.each do |section| %>
|
56
|
+
<% record.field_sections.values.each do |section| %>
|
57
57
|
<% if section.display? %>
|
58
58
|
<section>
|
59
59
|
<% if section.name.present? %>
|
@@ -62,6 +62,7 @@
|
|
62
62
|
<div <% if section.name.present? %> style="display: none" <% end %>>
|
63
63
|
<%= form.form_for_section(section) %>
|
64
64
|
</div>
|
65
|
+
<div style="clear: both"></div>
|
65
66
|
</section>
|
66
67
|
<% end %>
|
67
68
|
<% end %>
|
data/lib/layouts/admin_page.html
CHANGED
@@ -45,6 +45,17 @@
|
|
45
45
|
</header>
|
46
46
|
<%= content %>
|
47
47
|
|
48
|
+
|
49
|
+
<div id="alert-background" style="display: none"></div>
|
50
|
+
<div id="alert" style="display: none">
|
51
|
+
<h1>Error</h1>
|
52
|
+
<p>Error text here</p>
|
53
|
+
<menu>
|
54
|
+
<a href="#" class="dismiss">Cancel</a>
|
55
|
+
<a href="#" class="confirm">OK</a>
|
56
|
+
</menu>
|
57
|
+
</div>
|
58
|
+
|
48
59
|
<script src="/admin/js/jquery.tablesorter.min.js"></script>
|
49
60
|
<script src="/admin/chosen/chosen.jquery.min.js"></script>
|
50
61
|
<script src="/admin/js/jquery-ui-1.8.16.custom.min.js"></script>
|
@@ -12,7 +12,7 @@
|
|
12
12
|
<h1>New</h1>
|
13
13
|
<ul>
|
14
14
|
<% site.models.each do |model| %>
|
15
|
-
<% next if model.name.end_with?('_eigenmodel') || model.name.end_with?('Eigenmodel') %>
|
15
|
+
<% next if model.name.end_with?('_eigenmodel') || model.name.end_with?('Eigenmodel') || model.hide_in_admin %>
|
16
16
|
<a href="#" class="model" data-type="<%= model.name %>" data-model-id="<%= model.id %>">
|
17
17
|
<li>
|
18
18
|
<img src="/admin/images/load_spinner.gif" class="spinner">
|
@@ -1,6 +1,7 @@
|
|
1
1
|
<h1><span class="type"><%= @record.model_name.underscore.humanize.titleize %></span> <span id="record_name"><%= @record.name %></span></h1>
|
2
2
|
<% form_for @record, page.path, remote: true, params: {id: 'record_form'} do |form| %>
|
3
3
|
<% form.success do %>
|
4
|
+
// TODO: the form may need to be re-generated: the state of the form may not be the state that was submitted
|
4
5
|
$('#save_success').fadeIn().delay(2000).fadeOut();
|
5
6
|
|
6
7
|
// remove the model and parent id's regardless of whether this was a new or existing record
|
@@ -11,47 +12,82 @@
|
|
11
12
|
$('#record_id').remove();
|
12
13
|
$('#record_form').append('<input type="hidden" id="record_id" name="id" value="' + record.id + '">');
|
13
14
|
|
15
|
+
// update embedded record ids
|
16
|
+
var values = jQuery.parseJSON(record.values);
|
17
|
+
updateEmbeddedRecordIds(values);
|
18
|
+
|
19
|
+
// and image and attachment names
|
20
|
+
updateImageAndAttachmentNames(values);
|
21
|
+
|
14
22
|
// further saves are updates
|
15
23
|
$('#record_form input[name=_method]').val('put');
|
16
24
|
|
17
25
|
// update the UI to reflect any changes in the record
|
18
26
|
$('#record_name').html(record.name)
|
19
27
|
updateRecord(record);
|
20
|
-
var values = jQuery.parseJSON(record.values);
|
21
|
-
if(values) {
|
22
|
-
$('#record_form .field-type-attachment, #record_form .field-type-image').each(function(index, element) {
|
23
|
-
element = jQuery(element);
|
24
|
-
var field_name = element.attr('data-field');
|
25
|
-
|
26
|
-
var file_name = 'none';
|
27
|
-
|
28
|
-
if(values[field_name] && values[field_name].name) {
|
29
|
-
file_name = values[field_name].name;
|
30
|
-
element.find('img').attr('src', '/attachments/' + field_name + '/' + values._id + '/admin_thumb.jpg');
|
31
|
-
element.find('img').show();
|
32
|
-
element.find('.clear').show();
|
33
|
-
element.find('input[type=file]').val('');
|
34
|
-
} else {
|
35
|
-
element.find('.clear').hide();
|
36
|
-
}
|
37
|
-
element.find('p span').html(file_name);
|
38
|
-
});
|
39
|
-
}
|
40
28
|
<% end %>
|
41
29
|
|
42
30
|
<% form.failure do %>
|
43
31
|
$('#save_failure').fadeIn().delay(2000).fadeOut();
|
44
32
|
<% end %>
|
45
33
|
|
46
|
-
<% @record.field_sections.each do |section| %>
|
34
|
+
<% @record.field_sections.values.each do |section| %>
|
47
35
|
<% if section.display? %>
|
36
|
+
|
48
37
|
<section>
|
49
38
|
<% if section.name.present? %>
|
50
39
|
<h1><%= section.name %> <a href="#" class="section_toggle">show</a></h1>
|
51
40
|
<% end %>
|
41
|
+
|
52
42
|
<div <% if section.name.present? %> style="display: none" <% end %>>
|
53
|
-
|
43
|
+
<% section.displayed_fields.each do |field| %>
|
44
|
+
|
45
|
+
<% if field.type == 'many_embedded' %>
|
46
|
+
<div
|
47
|
+
class='contains-field-type-<%= field.type %>'
|
48
|
+
data-field-human-name="<%= field.name.underscore.singularize.humanize.downcase %>"
|
49
|
+
data-field-name="<%= field.name %>">
|
50
|
+
<% if form.prefix %>
|
51
|
+
<input type="hidden" name="<%= form.prefix %>[][<%= field.name %>]" value="">
|
52
|
+
<% else %>
|
53
|
+
<input type="hidden" name="<%= field.name %>[]" value="">
|
54
|
+
<% end %>
|
55
|
+
|
56
|
+
<%= form.label(field.name) %>
|
57
|
+
|
58
|
+
<div>
|
59
|
+
<p class="no-embedded" <% unless @record.get(field.name).empty? %>style="display: none"<% end %>>
|
60
|
+
No <%= field.name.underscore.pluralize.humanize.downcase %>
|
61
|
+
</p>
|
62
|
+
<span class="field-type-many_embedded">
|
63
|
+
<% form.field(field.name, blank_record: true) do |embedded_form| %>
|
64
|
+
<% if embedded_form.record.new? %>
|
65
|
+
<span class="embedded-record blank-record">
|
66
|
+
<input type="hidden" name="<%= field.name %>[][_id]" value="">
|
67
|
+
<%= embedded_form.form_for_section(embedded_form.record.field_sections[nil]) %>
|
68
|
+
<% else %>
|
69
|
+
<span class="embedded-record" id="<%= embedded_form.record.id.to_s %>">
|
70
|
+
<input type="hidden" name="<%= field.name %>[][_id]" value="<%= embedded_form.record.id.to_s %>">
|
71
|
+
<%= embedded_form.form_for_section(embedded_form.record.field_sections[nil]) %>
|
72
|
+
<% end %>
|
73
|
+
<p class="delete-embedded"><a href="#">Delete</a></p>
|
74
|
+
<div style="clear: both"></div>
|
75
|
+
</span>
|
76
|
+
<% end %>
|
77
|
+
</span>
|
78
|
+
|
79
|
+
<%= form.status(field.name) %>
|
80
|
+
<p class="add-embedded"><a href="#">Add <%= field.name.underscore.singularize.humanize.downcase %></a></p>
|
81
|
+
</div>
|
82
|
+
</div>
|
83
|
+
|
84
|
+
<% else %>
|
85
|
+
<%= form.field_row(field.name, field) %>
|
86
|
+
<div style="clear: both"></div>
|
87
|
+
<% end %>
|
88
|
+
<% end %>
|
54
89
|
</div>
|
90
|
+
<div style="clear: both"></div>
|
55
91
|
</section>
|
56
92
|
<% end %>
|
57
93
|
<% end %>
|
@@ -170,6 +170,136 @@ header {
|
|
170
170
|
|
171
171
|
|
172
172
|
|
173
|
+
/* ---------------------------------------------------- */
|
174
|
+
/* alert dialog */
|
175
|
+
/* ---------------------------------------------------- */
|
176
|
+
#alert-background {
|
177
|
+
background-color: black;
|
178
|
+
position: fixed;
|
179
|
+
top: 0px;
|
180
|
+
left: 0px;
|
181
|
+
width: 100%;
|
182
|
+
height: 100%;
|
183
|
+
|
184
|
+
/* rgba is only supported by IE 9 */
|
185
|
+
opacity: 0.2;
|
186
|
+
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
|
187
|
+
filter: alpha(opacity=20);
|
188
|
+
}
|
189
|
+
|
190
|
+
#alert {
|
191
|
+
background-color: white;
|
192
|
+
border: 2px solid #191919;
|
193
|
+
-webkit-border-radius: 6px;
|
194
|
+
-moz-border-radius: 6px;
|
195
|
+
border-radius: 6px;
|
196
|
+
-webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
|
197
|
+
-moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
|
198
|
+
box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
|
199
|
+
|
200
|
+
position: fixed;
|
201
|
+
width: 450px;
|
202
|
+
top: 50%;
|
203
|
+
left: 50%;
|
204
|
+
margin-left: -175px;
|
205
|
+
margin-top: -100px;
|
206
|
+
}
|
207
|
+
|
208
|
+
#alert h1 {
|
209
|
+
background-color: #2a2a2a;
|
210
|
+
padding: 12px 20px 14px 20px;
|
211
|
+
font-size: 18px;
|
212
|
+
margin-bottom: 10px;
|
213
|
+
color: #eee;
|
214
|
+
|
215
|
+
-webkit-border-top-left-radius: 3px;
|
216
|
+
-moz-border-radius-topleft: 3px;
|
217
|
+
border-top-left-radius: 3px;
|
218
|
+
|
219
|
+
-webkit-border-top-right-radius: 3px;
|
220
|
+
-moz-border-radius-topright: 3px;
|
221
|
+
border-top-right-radius: 3px;
|
222
|
+
}
|
223
|
+
|
224
|
+
#alert p {
|
225
|
+
padding: 20px 20px;
|
226
|
+
font-size: 15px;
|
227
|
+
line-height: 20px;
|
228
|
+
}
|
229
|
+
|
230
|
+
#alert menu {
|
231
|
+
background-color: #fdfdfd;
|
232
|
+
border-top: 1px solid #eee;
|
233
|
+
padding: 12px 17px;
|
234
|
+
text-align: right;
|
235
|
+
margin-top: 10px;
|
236
|
+
|
237
|
+
-webkit-border-bottom-left-radius: 3px;
|
238
|
+
-moz-border-radius-bottomleft: 3px;
|
239
|
+
border-bottom-left-radius: 3px;
|
240
|
+
|
241
|
+
-webkit-border-bottom-right-radius: 3px;
|
242
|
+
-moz-border-radius-bottomright: 3px;
|
243
|
+
border-bottom-right-radius: 3px;
|
244
|
+
}
|
245
|
+
|
246
|
+
#alert menu a {
|
247
|
+
cursor: pointer;
|
248
|
+
display: inline-block;
|
249
|
+
background-color: #e6e6e6;
|
250
|
+
background-repeat: no-repeat;
|
251
|
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));
|
252
|
+
background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
|
253
|
+
background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);
|
254
|
+
background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
|
255
|
+
background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
|
256
|
+
background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);
|
257
|
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
|
258
|
+
padding: 5px 14px 6px;
|
259
|
+
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
|
260
|
+
color: #333;
|
261
|
+
font-size: 13px;
|
262
|
+
line-height: normal;
|
263
|
+
border: 1px solid #ccc;
|
264
|
+
border-bottom-color: #bbb;
|
265
|
+
-webkit-border-radius: 4px;
|
266
|
+
-moz-border-radius: 4px;
|
267
|
+
border-radius: 4px;
|
268
|
+
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
|
269
|
+
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
|
270
|
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
|
271
|
+
-webkit-transition: 0.1s linear all;
|
272
|
+
-moz-transition: 0.1s linear all;
|
273
|
+
-ms-transition: 0.1s linear all;
|
274
|
+
-o-transition: 0.1s linear all;
|
275
|
+
transition: 0.1s linear all;
|
276
|
+
}
|
277
|
+
|
278
|
+
#alert menu a:active {
|
279
|
+
background-position: 0 -15px;
|
280
|
+
color: #333;
|
281
|
+
text-decoration: none;
|
282
|
+
}
|
283
|
+
|
284
|
+
#alert menu a.confirm {
|
285
|
+
margin-left: 10px;
|
286
|
+
color: #ffffff !important;
|
287
|
+
background-color: #0064cd;
|
288
|
+
background-repeat: repeat-x;
|
289
|
+
background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));
|
290
|
+
background-image: -moz-linear-gradient(top, #049cdb, #0064cd);
|
291
|
+
background-image: -ms-linear-gradient(top, #049cdb, #0064cd);
|
292
|
+
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));
|
293
|
+
background-image: -webkit-linear-gradient(top, #049cdb, #0064cd);
|
294
|
+
background-image: -o-linear-gradient(top, #049cdb, #0064cd);
|
295
|
+
background-image: linear-gradient(top, #049cdb, #0064cd);
|
296
|
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0);
|
297
|
+
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
298
|
+
border-color: #0064cd #0064cd #003f81;
|
299
|
+
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
300
|
+
}
|
301
|
+
|
302
|
+
|
173
303
|
/* ---------------------------------------------------- */
|
174
304
|
/* main content containers */
|
175
305
|
/* ---------------------------------------------------- */
|
@@ -300,12 +430,17 @@ article {
|
|
300
430
|
float: left;
|
301
431
|
}
|
302
432
|
|
303
|
-
|
433
|
+
|
434
|
+
#record form > section > div > div > div, /* top level, main record field */
|
435
|
+
.field-type-many_embedded > span > div > div, /* field of a many embedded record */
|
436
|
+
.field-type-one_embedded > span > div > div /* field of a single embedded record */
|
437
|
+
{
|
304
438
|
padding-left: 110px;
|
305
439
|
padding-right: 30px;
|
306
440
|
vertical-align: top;
|
307
441
|
}
|
308
442
|
|
443
|
+
|
309
444
|
/* FIXME: html isn't added as a class to the div */
|
310
445
|
#record form div.html {
|
311
446
|
padding-right: 20px;
|
@@ -369,8 +504,13 @@ article {
|
|
369
504
|
display: none;
|
370
505
|
}
|
371
506
|
|
372
|
-
.contains-field-type-image {
|
507
|
+
.contains-field-type-image, .contains-field-type-image + div {
|
373
508
|
clear: both;
|
509
|
+
margin-top: 15px;
|
510
|
+
}
|
511
|
+
|
512
|
+
.contains-field-type-image {
|
513
|
+
min-height: 82px;
|
374
514
|
}
|
375
515
|
|
376
516
|
#record .image_preview {
|
@@ -427,6 +567,33 @@ article {
|
|
427
567
|
width: auto;
|
428
568
|
}
|
429
569
|
|
570
|
+
/* embedded fields */
|
571
|
+
.no-embedded, .add-embedded, .delete-embedded {
|
572
|
+
color: #777;
|
573
|
+
font-size: 13px;
|
574
|
+
}
|
575
|
+
|
576
|
+
.add-embedded, .delete-embedded {
|
577
|
+
text-align: right;
|
578
|
+
padding-right: 20px;
|
579
|
+
margin-top: 20px;
|
580
|
+
}
|
581
|
+
|
582
|
+
.add-embedded a, .delete-embedded a {
|
583
|
+
color: #777;
|
584
|
+
}
|
585
|
+
|
586
|
+
.delete-embedded {
|
587
|
+
clear: both;
|
588
|
+
}
|
589
|
+
|
590
|
+
.field-type-many_embedded > span {
|
591
|
+
display: block;
|
592
|
+
margin-bottom: 10px;
|
593
|
+
border-bottom: 1px solid #ccc;
|
594
|
+
padding-bottom: 10px;
|
595
|
+
}
|
596
|
+
|
430
597
|
/* validations */
|
431
598
|
.yodel-field-status {
|
432
599
|
display: block;
|
@@ -11,11 +11,23 @@ function initialiseWidgets(newRecord) {
|
|
11
11
|
hideModelPanel();
|
12
12
|
initialiseHTMLFields();
|
13
13
|
initialiseMultipleSelectFields();
|
14
|
+
initialiseEmbeddedFields();
|
14
15
|
addClearLinks();
|
15
16
|
if(newRecord)
|
16
17
|
setDateTimeFieldsToNow();
|
17
18
|
}
|
18
19
|
|
20
|
+
var blankRecords = {};
|
21
|
+
function initialiseEmbeddedFields() {
|
22
|
+
blankRecords = {};
|
23
|
+
$('.field-type-many_embedded .blank-record').each(function(index, record) {
|
24
|
+
var blankRecord = $(record);
|
25
|
+
blankRecord.hide();
|
26
|
+
blankRecord.removeClass('blank-record');
|
27
|
+
blankRecords[$(record).closest('.contains-field-type-many_embedded').attr('data-field-name')] = blankRecord.detach();
|
28
|
+
});
|
29
|
+
}
|
30
|
+
|
19
31
|
function setDateTimeFieldsToNow() {
|
20
32
|
// TODO: should check that each field is blank first before setting; a default value may have been set
|
21
33
|
var now = new Date();
|
@@ -161,7 +173,7 @@ function constructRecordList(tree) {
|
|
161
173
|
var navigationPanels = [];
|
162
174
|
|
163
175
|
function dragError(parent, oldIndex, row) {
|
164
|
-
|
176
|
+
showAlert('Update error', 'Sorry, an error occurred updating the position of this record. Please reload the page and try again.');
|
165
177
|
|
166
178
|
// move the row back to its old position; record indexes are 1 based
|
167
179
|
if(oldIndex == 1) {
|
@@ -221,7 +233,7 @@ function pushNavigationPanel(rootName, tree, isPageRoot) {
|
|
221
233
|
if(record && record.parent_id)
|
222
234
|
parent = findRecord(tree, record.parent_id);
|
223
235
|
if(!parent) {
|
224
|
-
|
236
|
+
showAlert('Update error', "Sorry, an error occurred updating the position of this record (the parent record could not be found). Please refresh the page and try again.");
|
225
237
|
return;
|
226
238
|
}
|
227
239
|
|
@@ -350,6 +362,57 @@ function hideChildren(event) {
|
|
350
362
|
}
|
351
363
|
|
352
364
|
|
365
|
+
function updateEmbeddedRecordIds(record, embeddedIdElements) {
|
366
|
+
if(!embeddedIdElements)
|
367
|
+
embeddedIdElements = $.makeArray($('.embedded-record input[name*="_id"]'));
|
368
|
+
|
369
|
+
$.each(record, function(field, value) {
|
370
|
+
if(!value)
|
371
|
+
return;
|
372
|
+
if(value['_id']) {
|
373
|
+
$(embeddedIdElements.shift()).val(value['_id']);
|
374
|
+
} else if($.isArray(value)) {
|
375
|
+
updateEmbeddedRecordIds(value, embeddedIdElements);
|
376
|
+
}
|
377
|
+
});
|
378
|
+
}
|
379
|
+
|
380
|
+
function updateImageAndAttachmentNames(record, fieldElements, idStack) {
|
381
|
+
if(!fieldElements)
|
382
|
+
fieldElements = $.makeArray($('.field-type-attachment, .field-type-image'));
|
383
|
+
if(!idStack)
|
384
|
+
idStack = [record['_id']];
|
385
|
+
|
386
|
+
$.each(record, function(field, value) {
|
387
|
+
if(!value)
|
388
|
+
return;
|
389
|
+
|
390
|
+
if(!(value['name'] === undefined) && !(value['mime'] === undefined)) {
|
391
|
+
var field = $(fieldElements.shift());
|
392
|
+
if(value['name'] != null) {
|
393
|
+
var field_name = field.attr('data-field').replace(/\[\]/g, '').replace(/\[/g, '_').replace(/\]/g, '');
|
394
|
+
field.find('p span').html(value['name']);
|
395
|
+
field.find('img').attr('src', '/attachments/' + field_name + '/' + idStack.join('/') + '/admin_thumb.jpg');
|
396
|
+
field.find('img').show();
|
397
|
+
field.find('.clear').show();
|
398
|
+
field.find('input[type=file]').val('');
|
399
|
+
} else {
|
400
|
+
field.find('p span').html('none');
|
401
|
+
field.find('.clear').hide();
|
402
|
+
}
|
403
|
+
|
404
|
+
} else if(value['_id']) {
|
405
|
+
idStack.push(value['_id']);
|
406
|
+
updateImageAndAttachmentNames(value, fieldElements, idStack);
|
407
|
+
idStack.pop();
|
408
|
+
|
409
|
+
} else if($.isArray(value)) {
|
410
|
+
updateImageAndAttachmentNames(value, fieldElements, idStack);
|
411
|
+
}
|
412
|
+
});
|
413
|
+
}
|
414
|
+
|
415
|
+
|
353
416
|
// update an existing record or add a record to the tree
|
354
417
|
function updateRecord(record) {
|
355
418
|
// either find the parent record by searching from the root of the
|
@@ -367,7 +430,7 @@ function updateRecord(record) {
|
|
367
430
|
parent = findRecord(tree, record.parent_id);
|
368
431
|
|
369
432
|
if(!treeRecord && !parent) {
|
370
|
-
|
433
|
+
showAlert('Create error', "Sorry, an error occurred while creating this record (no parent or record could be found). Please refresh the page and try again.");
|
371
434
|
return;
|
372
435
|
}
|
373
436
|
|
@@ -481,7 +544,9 @@ function deleteButtonPressed(event) {
|
|
481
544
|
var recordTypeName = types[recordRow.attr('data-type')].humanName;
|
482
545
|
var recordID = recordRow.attr('data-record-id');
|
483
546
|
|
484
|
-
|
547
|
+
showAlert('Confirm delete', 'Are you sure you want to delete this ' + recordTypeName + '?', function(ok) {
|
548
|
+
if(!ok)
|
549
|
+
return;
|
485
550
|
showSpinner(recordRow);
|
486
551
|
$.ajax(jsonURL, {
|
487
552
|
data: {id: recordID, _method: 'delete'},
|
@@ -529,10 +594,10 @@ function deleteButtonPressed(event) {
|
|
529
594
|
}, error: function(jqXHR, textStatus, errorThrown) {
|
530
595
|
// FIXME: better error message
|
531
596
|
hideSpinner(recordRow);
|
532
|
-
|
597
|
+
showAlert('Delete error', 'Sorry, an error occurred deleting this record. Please reload the page and try again.');
|
533
598
|
}
|
534
599
|
});
|
535
|
-
}
|
600
|
+
});
|
536
601
|
}
|
537
602
|
|
538
603
|
|
@@ -609,52 +674,58 @@ function toggleSectionVisibility(event) {
|
|
609
674
|
}
|
610
675
|
|
611
676
|
|
612
|
-
// delete an embedded
|
613
|
-
function
|
677
|
+
// delete an embedded record
|
678
|
+
function deleteEmbeddedRecord(event) {
|
614
679
|
event.preventDefault();
|
615
680
|
var target = $(event.target);
|
616
|
-
var
|
617
|
-
var
|
681
|
+
var fieldContainer = target.closest('div.contains-field-type-many_embedded');
|
682
|
+
var records = fieldContainer.find('.field-type-many_embedded');
|
683
|
+
var type = fieldContainer.attr('data-field-human-name');
|
618
684
|
|
619
|
-
|
620
|
-
|
685
|
+
showAlert('Confirm delete', 'Are you sure you want to delete this ' + type + '?', function(ok) {
|
686
|
+
if(!ok)
|
687
|
+
return;
|
688
|
+
|
689
|
+
target.closest('.embedded-record').animate({
|
621
690
|
height: 'hide',
|
622
691
|
opacity: 'hide'
|
623
692
|
}, {
|
624
693
|
complete: function() {
|
625
694
|
// show the 'No TYPE' text if we are removing the last embedded doc in a collection
|
626
|
-
if(
|
627
|
-
|
695
|
+
if(records.find('> span').size() == 1)
|
696
|
+
fieldContainer.find('.no-embedded').animate({height: 'show', opacity: 'show'});
|
628
697
|
$(this).remove();
|
629
698
|
}
|
630
699
|
});
|
631
|
-
}
|
700
|
+
});
|
701
|
+
|
632
702
|
}
|
633
703
|
|
634
|
-
// add a new embedded
|
635
|
-
function
|
704
|
+
// add a new embedded record
|
705
|
+
function addEmbeddedRecord(event) {
|
636
706
|
event.preventDefault();
|
637
707
|
var target = $(event.target);
|
638
|
-
var
|
708
|
+
var fieldContainer = target.closest('div');
|
709
|
+
var records = fieldContainer.find('.field-type-many_embedded');
|
710
|
+
var blankRecord = blankRecords[fieldContainer.closest('.contains-field-type-many_embedded').attr('data-field-name')];
|
639
711
|
|
640
|
-
|
641
|
-
|
642
|
-
$(event.target).before(doc);
|
712
|
+
var newRecord = blankRecord.clone();
|
713
|
+
$(records).append(newRecord);
|
643
714
|
|
644
|
-
//
|
645
|
-
// animate the insertion of the new
|
646
|
-
if(
|
647
|
-
|
715
|
+
//hide the 'No TYPE' text if we are adding a new embedded record in to an empty collection
|
716
|
+
// animate the insertion of the new record after hiding the 'No TYPE' text or immediately
|
717
|
+
if(records.find('> span').size() == 1) {
|
718
|
+
fieldContainer.find('.no-embedded').animate({
|
648
719
|
height: 'hide',
|
649
720
|
opacity: 'hide'
|
650
721
|
}, {
|
651
722
|
duration: 150,
|
652
723
|
complete: function() {
|
653
|
-
|
724
|
+
newRecord.animate({height: 'show', opacity: 'show'});
|
654
725
|
}
|
655
726
|
});
|
656
727
|
} else {
|
657
|
-
|
728
|
+
newRecord.animate({height: 'show', opacity: 'show'});
|
658
729
|
}
|
659
730
|
}
|
660
731
|
|
@@ -668,8 +739,8 @@ $('input[type=file]').live('change', hideClear);
|
|
668
739
|
|
669
740
|
$('a.prev_nav_panel').live('click', showPreviousNavigationPanel);
|
670
741
|
$('a.section_toggle').live('click', toggleSectionVisibility);
|
671
|
-
$('a
|
672
|
-
$('a
|
742
|
+
$('.delete-embedded a').live('click', deleteEmbeddedRecord);
|
743
|
+
$('p.add-embedded a').live('click', addEmbeddedRecord);
|
673
744
|
|
674
745
|
$('h1.new').live('click', showModelPanel);
|
675
746
|
$('div.add_child').live('click', showModelPanel);
|
@@ -715,9 +786,16 @@ function highlightSelectedRow(row) {
|
|
715
786
|
// load an existing record's form
|
716
787
|
function loadRecord(id) {
|
717
788
|
$('#record').load(htmlURL + '?action=show&id=' + id, function(text, status, req) {
|
718
|
-
|
719
|
-
|
720
|
-
|
789
|
+
if(status == 'error') {
|
790
|
+
showAlert('Load error', 'Sorry, an error occurred loading this record. Please refresh the page and try again.');
|
791
|
+
} else {
|
792
|
+
highlightSelectedRow(id);
|
793
|
+
hideModelPanel();
|
794
|
+
initialiseWidgets();
|
795
|
+
setTimeout(function() {
|
796
|
+
$('#record').scrollTop(0);
|
797
|
+
}, 100);
|
798
|
+
}
|
721
799
|
});
|
722
800
|
}
|
723
801
|
|
@@ -752,11 +830,27 @@ function loadNewRecord(modelID, parentID, modelWasSelected) {
|
|
752
830
|
|
753
831
|
// load the blank default record
|
754
832
|
$('#record').load(htmlURL + '?action=new&model=' + modelID + '&parent=' + parentID, function(text, status, req) {
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
833
|
+
if(status == 'error') {
|
834
|
+
// hide spinners from the navigation menu
|
835
|
+
if(parent.children.length == 0)
|
836
|
+
hideSpinner(parentID);
|
837
|
+
else
|
838
|
+
hideSpinner($('.record[data-record-id=' + parentID + '] > .child_elements > li > h1.new'));
|
839
|
+
|
840
|
+
// hide spinners from the new model panel
|
841
|
+
$('a.model .spinner').hide();
|
842
|
+
$('a.model .icon').show();
|
843
|
+
|
844
|
+
showAlert('Unable to load new record', 'Sorry, an error occurred loading a new record. Please refresh the page and try again.')
|
845
|
+
|
846
|
+
} else {
|
847
|
+
initialiseWidgets(true);
|
848
|
+
$('#record').scrollTop(0);
|
849
|
+
if(parent.children.length == 0)
|
850
|
+
highlightSelectedRow(parentID);
|
851
|
+
else
|
852
|
+
highlightSelectedRow($('.record[data-record-id=' + parentID + '] > .child_elements > li > h1.new'));
|
853
|
+
}
|
760
854
|
});
|
761
855
|
}
|
762
856
|
|
@@ -814,17 +908,17 @@ function push(creating) {
|
|
814
908
|
jQuery.ajax(SYNC_URL, {type: 'POST', success: function(data) {
|
815
909
|
if(!data.success) {
|
816
910
|
if(data.reason)
|
817
|
-
|
911
|
+
showAlert('Push failed', errorText + ": " + data.reason);
|
818
912
|
else if(data.conflicts)
|
819
|
-
|
913
|
+
showAlert('Push failed', "The following files are in conflict and need to be resolved before pushing: " + data.conflicts.join(','));
|
820
914
|
else
|
821
|
-
|
915
|
+
showAlert('Push failed', errorText + ".");
|
822
916
|
} else if(creating) {
|
823
917
|
window.open('http://' + data.remoteDomain + '/', 'livesite');
|
824
918
|
window.location.reload()
|
825
919
|
}
|
826
920
|
}, error: function(jqXHR, textStatus, errorThrown) {
|
827
|
-
|
921
|
+
showAlert('Push failed', errorText + ".");
|
828
922
|
}, complete: function(jqXHR, textStatus) {
|
829
923
|
hideSyncStatus();
|
830
924
|
}});
|
@@ -849,11 +943,11 @@ $('.sync.create').live('click', function(event) {
|
|
849
943
|
if(data.success) {
|
850
944
|
push(true);
|
851
945
|
} else {
|
852
|
-
|
946
|
+
showAlert('Create failed', "Sorry, an error occurred while creating this site on the remote server: " + data.reason);
|
853
947
|
hideSyncStatus();
|
854
948
|
}
|
855
949
|
}, error: function(jqXHR, textStatus, errorThrown) {
|
856
|
-
|
950
|
+
showAlert('Create failed', "Sorry, an error occurred while creating this site on the remote server.");
|
857
951
|
hideSyncStatus();
|
858
952
|
}});
|
859
953
|
});
|
@@ -869,16 +963,16 @@ $('.sync.pull').live('click', function(event) {
|
|
869
963
|
jQuery.ajax(SYNC_URL, {type: 'GET', success: function(data) {
|
870
964
|
if(!data.success) {
|
871
965
|
if(data.reason)
|
872
|
-
|
966
|
+
showAlert('Pull failed', errorText + ": " + data.reason);
|
873
967
|
else if(data.requires_push)
|
874
|
-
|
968
|
+
showAlert('Pull failed', errorText + ": No remote server is associated with this site");
|
875
969
|
else if(data.conflicts)
|
876
|
-
|
970
|
+
showAlert('Pull failed', "The following files are in conflict and need to be resolved before pulling: " + data.conflicts.join(','));
|
877
971
|
else
|
878
|
-
|
972
|
+
showAlert('Pull failed', errorText + ".");
|
879
973
|
}
|
880
974
|
}, error: function(jqXHR, textStatus, errorThrown) {
|
881
|
-
|
975
|
+
showAlert('Pull failed', errorText + ".");
|
882
976
|
}, complete: function(jqXHR, textStatus) {
|
883
977
|
hideSyncStatus();
|
884
978
|
}});
|
@@ -960,7 +1054,7 @@ $('#list_items tbody tr').live('click', function() {
|
|
960
1054
|
$('#record').load(htmlURL + '?id=' + recordID, function(text, status, req) {
|
961
1055
|
$('#activity_spinner').fadeOut();
|
962
1056
|
if(status == 'error') {
|
963
|
-
|
1057
|
+
showAlert('Load error', "Sorry, an error occurred loading this record. Please refresh the page and try again.");
|
964
1058
|
} else {
|
965
1059
|
highlightSelectedListRow(row);
|
966
1060
|
initialiseWidgets();
|
@@ -1000,7 +1094,10 @@ $('.list #record .delete').live('click', function(event) {
|
|
1000
1094
|
var recordID = $(event.target).attr('data-record-id');
|
1001
1095
|
var recordTypeName = $(event.target).attr('data-record-type');
|
1002
1096
|
|
1003
|
-
|
1097
|
+
showAlert('Confirm delete', 'Are you sure you want to delete this ' + recordTypeName + '?', function(ok) {
|
1098
|
+
if(!ok)
|
1099
|
+
return;
|
1100
|
+
|
1004
1101
|
$('#delete_spinner').fadeIn();
|
1005
1102
|
$.ajax(jsonURL, {
|
1006
1103
|
data: {id: recordID, _method: 'delete'},
|
@@ -1014,13 +1111,13 @@ $('.list #record .delete').live('click', function(event) {
|
|
1014
1111
|
|
1015
1112
|
}, error: function(jqXHR, textStatus, errorThrown) {
|
1016
1113
|
// FIXME: better error message
|
1017
|
-
|
1114
|
+
showAlert('Delete error', 'Sorry, an error occurred deleting this record. Please reload the page and try again.');
|
1018
1115
|
|
1019
1116
|
}, complete: function() {
|
1020
1117
|
$('#delete_spinner').fadeOut();
|
1021
1118
|
}
|
1022
1119
|
});
|
1023
|
-
}
|
1120
|
+
});
|
1024
1121
|
});
|
1025
1122
|
|
1026
1123
|
$('#new_record').live('click', function(event) {
|
@@ -1031,7 +1128,7 @@ $('#new_record').live('click', function(event) {
|
|
1031
1128
|
$('#record').load(htmlURL + '?new=true', function(text, status, req) {
|
1032
1129
|
$('#activity_spinner').fadeOut();
|
1033
1130
|
if(status == 'error') {
|
1034
|
-
|
1131
|
+
showAlert('Load error', "Sorry, an error occurred loading a new record. Please refresh the page and try again.");
|
1035
1132
|
} else {
|
1036
1133
|
highlightSelectedListRow();
|
1037
1134
|
initialiseWidgets();
|
@@ -1040,3 +1137,84 @@ $('#new_record').live('click', function(event) {
|
|
1040
1137
|
});
|
1041
1138
|
})
|
1042
1139
|
|
1140
|
+
|
1141
|
+
|
1142
|
+
|
1143
|
+
/* alert modal dialog */
|
1144
|
+
var alertShowing = false;
|
1145
|
+
var confirmCallback = null;
|
1146
|
+
|
1147
|
+
// callback is null for simple 'OK' alerts; pass a
|
1148
|
+
// callback for a confirm ('Cancel', 'OK') alert
|
1149
|
+
function showAlert(title, text, callback) {
|
1150
|
+
// TODO: queue alerts in order
|
1151
|
+
if(alertShowing) {
|
1152
|
+
setTimeout(function() {
|
1153
|
+
showAlert(title, text, callback);
|
1154
|
+
}, 500);
|
1155
|
+
return;
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
alertShowing = true;
|
1159
|
+
confirmCallback = callback;
|
1160
|
+
$('#alert h1').html(title);
|
1161
|
+
$('#alert p').html(text);
|
1162
|
+
|
1163
|
+
if(callback) {
|
1164
|
+
$('#alert menu a.confirm').show();
|
1165
|
+
$('#alert menu a.confirm').html('OK');
|
1166
|
+
$('#alert menu a.dismiss').html('Cancel');
|
1167
|
+
} else {
|
1168
|
+
$('#alert menu a.confirm').hide();
|
1169
|
+
$('#alert menu a.dismiss').html('OK');
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
$('#alert-background').fadeIn('fast');
|
1173
|
+
$('#alert').fadeIn('fast');
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
function hideAlert() {
|
1177
|
+
$('#alert-background').fadeOut('fast');
|
1178
|
+
$('#alert').fadeOut('fast');
|
1179
|
+
alertShowing = false;
|
1180
|
+
}
|
1181
|
+
|
1182
|
+
function cancelAlert() {
|
1183
|
+
if(confirmCallback)
|
1184
|
+
confirmCallback(false);
|
1185
|
+
confirmCallback = null;
|
1186
|
+
hideAlert();
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
function confirmAlert() {
|
1190
|
+
if(confirmCallback)
|
1191
|
+
confirmCallback(true);
|
1192
|
+
confirmCallback = null;
|
1193
|
+
hideAlert();
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
$('#alert menu a.dismiss').click(function(event) {
|
1197
|
+
event.preventDefault();
|
1198
|
+
cancelAlert();
|
1199
|
+
});
|
1200
|
+
|
1201
|
+
$('#alert menu a.confirm').click(function(event) {
|
1202
|
+
event.preventDefault();
|
1203
|
+
confirmAlert();
|
1204
|
+
});
|
1205
|
+
|
1206
|
+
$(document).keyup(function(event) {
|
1207
|
+
if(!alertShowing)
|
1208
|
+
return;
|
1209
|
+
|
1210
|
+
// enter/return
|
1211
|
+
if(event.which == 13)
|
1212
|
+
if(confirmCallback)
|
1213
|
+
confirmAlert();
|
1214
|
+
else
|
1215
|
+
cancelAlert();
|
1216
|
+
|
1217
|
+
// escape
|
1218
|
+
else if(event.which == 27)
|
1219
|
+
cancelAlert();
|
1220
|
+
});
|
data/lib/yodel_admin.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yodel_admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-07 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: Yodel CMS Admin Extension
|
15
15
|
email:
|