yodel_admin 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|