trestle 0.8.5 → 0.8.6
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.
- 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
|
+
}
|