trestle 0.8.5 → 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/trestle/admin.js +11 -10
- data/app/assets/javascripts/trestle/{_confirmation.js → components/_confirmation.js} +1 -1
- data/app/assets/javascripts/trestle/{_datepicker.js → components/_datepicker.js} +4 -4
- data/app/assets/javascripts/trestle/components/_dialog.js +107 -0
- data/app/assets/javascripts/trestle/{_errors.js → components/_errors.js} +2 -2
- data/app/assets/javascripts/trestle/components/_form.js +48 -0
- data/app/assets/javascripts/trestle/{_gallery.js → components/_gallery.js} +3 -3
- data/app/assets/javascripts/trestle/{_select.js → components/_select.js} +2 -2
- data/app/assets/javascripts/trestle/{_sidebar.js → components/_sidebar.js} +3 -1
- data/app/assets/javascripts/trestle/{_table.js → components/_table.js} +1 -1
- data/app/assets/javascripts/trestle/components/_tabs.js +24 -0
- data/app/assets/javascripts/trestle/components/_tooltips.js +3 -0
- data/app/assets/javascripts/trestle/core/_contexts.js +13 -0
- data/app/assets/javascripts/trestle/{_cookies.js → core/_cookies.js} +2 -1
- data/app/assets/javascripts/trestle/core/_events.js +39 -0
- data/app/assets/javascripts/trestle/core/_visit.js +10 -0
- data/app/assets/stylesheets/trestle/components/_buttons.scss +9 -0
- data/app/assets/stylesheets/trestle/components/_modal.scss +92 -0
- data/app/assets/stylesheets/trestle/components/_navigation.scss +47 -12
- data/app/assets/stylesheets/trestle/components/_sidebar.scss +1 -0
- data/app/assets/stylesheets/trestle/core/_defaults.scss +5 -1
- data/app/controllers/trestle/application_controller.rb +5 -1
- data/app/helpers/trestle/dialog_helper.rb +7 -0
- data/app/helpers/trestle/form_helper.rb +7 -0
- data/app/helpers/trestle/url_helper.rb +34 -6
- data/app/views/layouts/trestle/admin.html.erb +1 -1
- data/app/views/trestle/application/_dialog.html.erb +36 -0
- data/app/views/trestle/application/_tabs.html.erb +7 -1
- data/app/views/trestle/resource/edit.html.erb +5 -5
- data/app/views/trestle/resource/index.html.erb +2 -2
- data/app/views/trestle/resource/new.html.erb +2 -2
- data/app/views/trestle/resource/show.html.erb +5 -5
- data/bower.json +1 -1
- data/config/locales/en.yml +25 -21
- data/config/locales/fr.rb +18 -0
- data/config/locales/fr.yml +69 -0
- data/config/locales/nl.yml +14 -14
- data/config/locales/pl.rb +18 -0
- data/config/locales/pl.yml +70 -0
- data/config/locales/pt-BR.yml +22 -22
- data/lib/generators/trestle/resource/templates/admin.rb.erb +1 -1
- data/lib/trestle/admin.rb +14 -1
- data/lib/trestle/admin/builder.rb +10 -2
- data/lib/trestle/breadcrumb.rb +13 -0
- data/lib/trestle/configuration.rb +6 -1
- data/lib/trestle/form.rb +7 -3
- data/lib/trestle/form/automatic.rb +1 -1
- data/lib/trestle/reloader.rb +1 -1
- data/lib/trestle/resource.rb +20 -5
- data/lib/trestle/resource/builder.rb +15 -0
- data/lib/trestle/resource/controller.rb +19 -6
- data/lib/trestle/table.rb +4 -0
- data/lib/trestle/table/actions_column.rb +9 -7
- data/lib/trestle/table/column.rb +3 -2
- data/lib/trestle/table/row.rb +7 -1
- data/lib/trestle/version.rb +1 -1
- data/trestle.gemspec +3 -3
- data/vendor/assets/bower_components/trestle/select2/dist/js/select2.full.js +90 -69
- metadata +30 -19
- data/app/assets/javascripts/trestle/_form.js +0 -6
- data/app/assets/javascripts/trestle/_tabs.js +0 -13
- data/app/assets/javascripts/trestle/_tooltips.js +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f07f2d3328a13c6ac319c7e04b8926a0dc09660
|
4
|
+
data.tar.gz: a8adb65b4c3bd295c5e80397fba9c8968d08febd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d565ea8bd72cca11c5eb2de1ea72332e8980093e5f4147f598f64958ee82b3f1799de37dc7c2c99b68cbb773821454ee62c5230b4ba55bdc50828e516dc347e
|
7
|
+
data.tar.gz: da2e9069173f7fa34f0af87c392af4b00dc9ea5b9b42eb2e6cb3c2df536065bd9648b5482043260c748e919fa735127d3fafb32537e523fe356da52765d7221a
|
@@ -7,17 +7,18 @@
|
|
7
7
|
//= require trestle/select2
|
8
8
|
//
|
9
9
|
//= require_self
|
10
|
+
//
|
11
|
+
//= require_tree ./core
|
12
|
+
//= require_tree ./components
|
13
|
+
//
|
10
14
|
//= require trestle/custom
|
11
|
-
//= require_tree .
|
12
15
|
|
13
|
-
var Trestle =
|
16
|
+
var Trestle = {
|
17
|
+
// Is Turbolinks enabled?
|
18
|
+
turbolinks: typeof(Turbolinks) !== 'undefined' && Turbolinks.supported,
|
14
19
|
|
15
|
-
|
20
|
+
// Store for i18n translations used within JS
|
21
|
+
i18n: {}
|
22
|
+
};
|
16
23
|
|
17
|
-
|
18
|
-
Trestle.ready = function(callback) { $(document).on('turbolinks:load', callback); };
|
19
|
-
Trestle.visit = function(url) { Turbolinks.visit(url); };
|
20
|
-
} else {
|
21
|
-
Trestle.ready = function(callback) { $(callback); };
|
22
|
-
Trestle.visit = function(url) { document.location = url; };
|
23
|
-
}
|
24
|
+
window.Trestle = Trestle;
|
@@ -11,7 +11,7 @@ Trestle.ready(function() {
|
|
11
11
|
selector: '[data-toggle="confirm-delete"]',
|
12
12
|
singleton: true,
|
13
13
|
popout: true,
|
14
|
-
title: Trestle.i18n['admin.confirmation.title'],
|
14
|
+
title: Trestle.i18n['admin.confirmation.title'] || 'Are you sure?',
|
15
15
|
btnOkIcon: '',
|
16
16
|
btnOkClass: 'btn-danger',
|
17
17
|
btnOkLabel: Trestle.i18n['admin.confirmation.delete'] || 'Delete',
|
@@ -1,18 +1,18 @@
|
|
1
|
-
Trestle.
|
2
|
-
$('input[type="date"][data-picker="true"]').flatpickr({
|
1
|
+
Trestle.init(function(e, root) {
|
2
|
+
$(root).find('input[type="date"][data-picker="true"]').flatpickr({
|
3
3
|
allowInput: true,
|
4
4
|
altInput: true,
|
5
5
|
altFormat: "m/d/Y",
|
6
6
|
});
|
7
7
|
|
8
|
-
$('input[type="datetime"][data-picker="true"], input[type="datetime-local"][data-picker="true"]').flatpickr({
|
8
|
+
$(root).find('input[type="datetime"][data-picker="true"], input[type="datetime-local"][data-picker="true"]').flatpickr({
|
9
9
|
enableTime: true,
|
10
10
|
allowInput: true,
|
11
11
|
altInput: true,
|
12
12
|
altFormat: "m/d/Y h:i K",
|
13
13
|
});
|
14
14
|
|
15
|
-
$('input[type="time"][data-picker="true"]').flatpickr({
|
15
|
+
$(root).find('input[type="time"][data-picker="true"]').flatpickr({
|
16
16
|
enableTime: true,
|
17
17
|
noCalendar: true,
|
18
18
|
allowInput: true,
|
@@ -0,0 +1,107 @@
|
|
1
|
+
Trestle.Dialog = function() {
|
2
|
+
this.el = Trestle.Dialog.getElement();
|
3
|
+
};
|
4
|
+
|
5
|
+
Trestle.Dialog.TEMPLATE =
|
6
|
+
'<div id="dialog" class="modal fade" tabindex="-1">' +
|
7
|
+
'<div class="modal-dialog">' +
|
8
|
+
'<div class="modal-content" data-context></div>' +
|
9
|
+
'</div>' +
|
10
|
+
'</div>';
|
11
|
+
|
12
|
+
Trestle.Dialog.getElement = function() {
|
13
|
+
var el = $('#dialog');
|
14
|
+
|
15
|
+
if (el.length == 0) {
|
16
|
+
el = $(Trestle.Dialog.TEMPLATE).appendTo('body');
|
17
|
+
|
18
|
+
el.modal({ show: false });
|
19
|
+
|
20
|
+
// Remove dialog elements once hidden
|
21
|
+
el.on('hidden.bs.modal', function() {
|
22
|
+
el.remove();
|
23
|
+
});
|
24
|
+
|
25
|
+
// Set X-Trestle-Dialog header on AJAX requests initiated from the dialog
|
26
|
+
el.on('ajax:beforeSend', '[data-remote]', function(e, xhr, options) {
|
27
|
+
xhr.setRequestHeader("X-Trestle-Dialog", true);
|
28
|
+
});
|
29
|
+
}
|
30
|
+
|
31
|
+
return el;
|
32
|
+
};
|
33
|
+
|
34
|
+
Trestle.Dialog.prototype.load = function(url) {
|
35
|
+
var dialog = this;
|
36
|
+
|
37
|
+
dialog.show();
|
38
|
+
dialog.setLoading(true);
|
39
|
+
|
40
|
+
$.ajax({
|
41
|
+
url: url,
|
42
|
+
dataType: 'html',
|
43
|
+
headers: {
|
44
|
+
"X-Trestle-Dialog": true
|
45
|
+
},
|
46
|
+
complete: function() {
|
47
|
+
dialog.setLoading(false);
|
48
|
+
},
|
49
|
+
success: function(content) {
|
50
|
+
dialog.setContent(content);
|
51
|
+
},
|
52
|
+
error: function(xhr, status, error) {
|
53
|
+
dialog.showError(error);
|
54
|
+
}
|
55
|
+
});
|
56
|
+
};
|
57
|
+
|
58
|
+
Trestle.Dialog.prototype.setLoading = function(loading) {
|
59
|
+
if (loading) {
|
60
|
+
this.el.addClass('loading');
|
61
|
+
} else {
|
62
|
+
this.el.removeClass('loading');
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
Trestle.Dialog.prototype.setContent = function(content) {
|
67
|
+
this.el.find('.modal-content').html(content);
|
68
|
+
$(Trestle).trigger('init', this.el);
|
69
|
+
};
|
70
|
+
|
71
|
+
Trestle.Dialog.prototype.showError = function(error) {
|
72
|
+
this.el.addClass('error');
|
73
|
+
|
74
|
+
var container = this.el.find('.modal-content').empty();
|
75
|
+
|
76
|
+
var errorMessage = Trestle.i18n['trestle.dialog.error'] || 'The request could not be completed.';
|
77
|
+
|
78
|
+
$('<div class="modal-header">')
|
79
|
+
.append('<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>')
|
80
|
+
.append('<h4 class="modal-title"></h4>').find('h4').text(error || errorMessage).end()
|
81
|
+
.appendTo(container);
|
82
|
+
|
83
|
+
$('<div class="modal-body">')
|
84
|
+
.append('<p>').find('p').text(errorMessage).end()
|
85
|
+
.appendTo(container);
|
86
|
+
|
87
|
+
$('<div class="modal-footer">')
|
88
|
+
.append('<button type="button" class="btn btn-default" data-dismiss="modal" aria-label="OK">').find('button').text(Trestle.i18n['admin.buttons.ok'] || 'OK').end()
|
89
|
+
.appendTo(container);
|
90
|
+
};
|
91
|
+
|
92
|
+
Trestle.Dialog.prototype.show = function() {
|
93
|
+
this.el.modal('show');
|
94
|
+
};
|
95
|
+
|
96
|
+
Trestle.Dialog.prototype.hide = function() {
|
97
|
+
this.el.modal('hide');
|
98
|
+
};
|
99
|
+
|
100
|
+
$(document).on('click', '[data-behavior="dialog"]', function(e) {
|
101
|
+
e.preventDefault();
|
102
|
+
|
103
|
+
var url = $(this).data('url') || $(this).attr('href');
|
104
|
+
|
105
|
+
var dialog = new Trestle.Dialog();
|
106
|
+
dialog.load(url);
|
107
|
+
});
|
@@ -0,0 +1,48 @@
|
|
1
|
+
// Prevent enter key from submitting the form
|
2
|
+
$(document).on('keypress', 'form[data-behavior="trestle-form"] :input:not(textarea):not([type=submit])', function(e) {
|
3
|
+
if (e.keyCode == 13) {
|
4
|
+
e.preventDefault();
|
5
|
+
}
|
6
|
+
});
|
7
|
+
|
8
|
+
Trestle.init(function(e, root) {
|
9
|
+
var form = $(root).find('form[data-behavior="trestle-form"]');
|
10
|
+
|
11
|
+
form
|
12
|
+
.on('ajax:complete', function(e, xhr, status) {
|
13
|
+
// Find the parent context and replace content
|
14
|
+
var context = $(this).closest('[data-context]');
|
15
|
+
context.html(xhr.responseText);
|
16
|
+
|
17
|
+
// Initialize replaced elements within the context
|
18
|
+
$(Trestle).trigger('init', context);
|
19
|
+
|
20
|
+
// Focus the correct tab
|
21
|
+
Trestle.focusActiveTab();
|
22
|
+
})
|
23
|
+
.on('ajax:success', function(e, data, status, xhr) {
|
24
|
+
var context = $(this).closest('[data-context]');
|
25
|
+
var location = xhr.getResponseHeader("X-Trestle-Location");
|
26
|
+
|
27
|
+
if (location) {
|
28
|
+
// Update the URL in the browser and context
|
29
|
+
history.replaceState({}, "", location);
|
30
|
+
context.data('context', location);
|
31
|
+
}
|
32
|
+
|
33
|
+
// Refresh the main context
|
34
|
+
if (!context.hasClass('app-main')) {
|
35
|
+
Trestle.refreshMainContext();
|
36
|
+
}
|
37
|
+
});
|
38
|
+
|
39
|
+
// Loading indicator
|
40
|
+
form.find(':submit').click(function() {
|
41
|
+
var button = $(this);
|
42
|
+
|
43
|
+
// Delay to ensure form is still submitted
|
44
|
+
setTimeout(function() {
|
45
|
+
button.prop('disabled', true).addClass('loading');
|
46
|
+
}, 1);
|
47
|
+
});
|
48
|
+
});
|
@@ -1,5 +1,5 @@
|
|
1
|
-
Trestle.
|
2
|
-
$('[data-behavior~="zoom"]').magnificPopup({
|
1
|
+
Trestle.init(function(e, root) {
|
2
|
+
$(root).find('[data-behavior~="zoom"]').magnificPopup({
|
3
3
|
type: 'image',
|
4
4
|
closeOnContentClick: false,
|
5
5
|
closeBtnInside: false,
|
@@ -10,7 +10,7 @@ Trestle.ready(function() {
|
|
10
10
|
}
|
11
11
|
});
|
12
12
|
|
13
|
-
$('[data-behavior~="gallery"]').magnificPopup({
|
13
|
+
$(root).find('[data-behavior~="gallery"]').magnificPopup({
|
14
14
|
delegate: 'a',
|
15
15
|
type: 'image',
|
16
16
|
closeOnContentClick: false,
|
@@ -69,5 +69,7 @@ Trestle.ready(function() {
|
|
69
69
|
// Scroll sidebar to active item
|
70
70
|
|
71
71
|
var active = sidebar.find('.active');
|
72
|
-
|
72
|
+
if (active.length) {
|
73
|
+
sidebar.find('.app-sidebar-inner').scrollTop(active.offset().top - 100);
|
74
|
+
}
|
73
75
|
});
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Trestle.init(function(e, root) {
|
2
|
+
$(root).find("a[data-toggle='tab']").on('shown.bs.tab', function(e) {
|
3
|
+
var hash = $(this).attr("href");
|
4
|
+
|
5
|
+
if (hash.substr(0, 1) == "#") {
|
6
|
+
history.replaceState({ turbolinks: {} }, "", "#!" + hash.substr(1));
|
7
|
+
}
|
8
|
+
});
|
9
|
+
});
|
10
|
+
|
11
|
+
Trestle.focusActiveTab = function() {
|
12
|
+
if (location.hash.substr(0, 2) == "#!") {
|
13
|
+
// Focus on active tab from URL
|
14
|
+
$("a[data-toggle='tab'][href='#" + location.hash.substr(2) + "']").tab("show");
|
15
|
+
} else if ($(".tab-pane:has(.has-error)").length) {
|
16
|
+
// Focus on first tab with errors
|
17
|
+
var pane = $(".tab-pane:has(.has-error)").first();
|
18
|
+
$("a[data-toggle='tab'][href='#" + pane.attr("id") + "']").tab("show");
|
19
|
+
}
|
20
|
+
};
|
21
|
+
|
22
|
+
Trestle.ready(function() {
|
23
|
+
Trestle.focusActiveTab();
|
24
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Trestle.refreshContext = function(context) {
|
2
|
+
var url = context.data('context');
|
3
|
+
|
4
|
+
$.get(url, function(data) {
|
5
|
+
context.html(data);
|
6
|
+
$(Trestle).trigger('init', context);
|
7
|
+
});
|
8
|
+
};
|
9
|
+
|
10
|
+
Trestle.refreshMainContext = function() {
|
11
|
+
var context = $('.app-main[data-context]');
|
12
|
+
Trestle.refreshContext(context);
|
13
|
+
};
|
@@ -0,0 +1,39 @@
|
|
1
|
+
// The ready function sets up a callback to run on each page load.
|
2
|
+
//
|
3
|
+
// Trestle.ready(function() {
|
4
|
+
// ...
|
5
|
+
// });
|
6
|
+
//
|
7
|
+
Trestle.ready = function(callback) {
|
8
|
+
$(Trestle).on('load', callback);
|
9
|
+
};
|
10
|
+
|
11
|
+
// The init function sets up a callback to run on each page load, as well as when elements are added to the page
|
12
|
+
// dynamically (e.g. via a modal). It is used to initialize dynamic elements such as date pickers, although it is
|
13
|
+
// preferable if they can be set up using event delegation on the document element.
|
14
|
+
//
|
15
|
+
// The callback is triggered with the applicable root/container element as the second argument.
|
16
|
+
//
|
17
|
+
// Trestle.init(function(e, root) {
|
18
|
+
// $(root).find('...');
|
19
|
+
// });
|
20
|
+
//
|
21
|
+
Trestle.init = function(callback) {
|
22
|
+
$(Trestle).on('init', callback);
|
23
|
+
};
|
24
|
+
|
25
|
+
// Initialize all elements within the document on page load.
|
26
|
+
Trestle.ready(function() {
|
27
|
+
$(Trestle).trigger('init', document);
|
28
|
+
});
|
29
|
+
|
30
|
+
// Trigger the page load events.
|
31
|
+
if (Trestle.turbolinks) {
|
32
|
+
$(document).on('turbolinks:load', function() {
|
33
|
+
$(Trestle).trigger("load");
|
34
|
+
});
|
35
|
+
} else {
|
36
|
+
$(document).ready(function() {
|
37
|
+
$(Trestle).trigger("load");
|
38
|
+
});
|
39
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
// The visit function is used to direct the user to the given URL. It is provided as an abstraction as the redirection
|
2
|
+
// is handled differently depending on whether or not Turbolinks is enabled.
|
3
|
+
//
|
4
|
+
// Trestle.visit("/admin/pages");
|
5
|
+
//
|
6
|
+
if (Trestle.turbolinks) {
|
7
|
+
Trestle.visit = function(url) { Turbolinks.visit(url); };
|
8
|
+
} else {
|
9
|
+
Trestle.visit = function(url) { document.location = url; };
|
10
|
+
}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
.modal-content {
|
2
|
+
border: none;
|
3
|
+
border-radius: 0;
|
4
|
+
|
5
|
+
.modal.loading & {
|
6
|
+
min-height: 100px;
|
7
|
+
|
8
|
+
display: flex;
|
9
|
+
align-items: center;
|
10
|
+
justify-content: center;
|
11
|
+
|
12
|
+
&:after {
|
13
|
+
@extend .fa;
|
14
|
+
@extend .fa-spin;
|
15
|
+
content: $fa-var-spinner;
|
16
|
+
|
17
|
+
font-size: 32px;
|
18
|
+
opacity: 0.25;
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
.modal-header {
|
24
|
+
background: $theme-bg;
|
25
|
+
border-bottom: none;
|
26
|
+
|
27
|
+
.close {
|
28
|
+
opacity: 0.75;
|
29
|
+
|
30
|
+
&, &:hover, &:focus {
|
31
|
+
color: white;
|
32
|
+
}
|
33
|
+
|
34
|
+
&:hover, &:focus {
|
35
|
+
opacity: 1;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
.modal.error & {
|
40
|
+
background: $error-bg;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
.modal-title {
|
45
|
+
font-size: 18px;
|
46
|
+
font-weight: 500;
|
47
|
+
text-shadow: rgba(black, 0.5) 0 1px 1px;
|
48
|
+
color: white;
|
49
|
+
}
|
50
|
+
|
51
|
+
.modal-tabs .nav-tabs {
|
52
|
+
background: $body-bg;
|
53
|
+
padding: 10px 15px 0 15px;
|
54
|
+
}
|
55
|
+
|
56
|
+
.modal-flash {
|
57
|
+
.alert {
|
58
|
+
margin-bottom: 0;
|
59
|
+
border-radius: 0;
|
60
|
+
border-width: 0 0 1px 0;
|
61
|
+
|
62
|
+
padding-top: 10px;
|
63
|
+
padding-bottom: 10px;
|
64
|
+
|
65
|
+
.alert-icon {
|
66
|
+
font-size: 40px;
|
67
|
+
margin-right: 15px;
|
68
|
+
}
|
69
|
+
|
70
|
+
h3 {
|
71
|
+
font-size: 18px;
|
72
|
+
}
|
73
|
+
|
74
|
+
p {
|
75
|
+
font-size: 13px;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
.modal-body {
|
81
|
+
@extend .tab-content;
|
82
|
+
}
|
83
|
+
|
84
|
+
.modal-footer {
|
85
|
+
.primary-toolbar {
|
86
|
+
float: right;
|
87
|
+
}
|
88
|
+
|
89
|
+
.secondary-toolbar {
|
90
|
+
float: left;
|
91
|
+
}
|
92
|
+
}
|