|
|
|
In order to use this with Rails 6 and Webpacker, a few changes have to be made:
|
|
|
|
|
|
|
|
- Create a pack
|
|
|
|
- Change the layout so that the pack is loaded
|
|
|
|
- Update the stylesheet
|
|
|
|
- Delete the javascript-non-pack
|
|
|
|
|
|
|
|
## Create a pack
|
|
|
|
```
|
|
|
|
yarn add flatpickr
|
|
|
|
```
|
|
|
|
|
|
|
|
Create a new pack at `app/javascript/packs/administrate.js`
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
// This file is automatically compiled by Webpack, along with any other files
|
|
|
|
// present in this directory. You're encouraged to place your actual application logic in
|
|
|
|
// a relevant structure within app/javascript and only use these pack files to reference
|
|
|
|
// that code so it'll be compiled.
|
|
|
|
|
|
|
|
require("@rails/ujs").start()
|
|
|
|
require("turbolinks").start()
|
|
|
|
|
|
|
|
// The next line you only need if you want ActiveStorage support
|
|
|
|
require("@rails/activestorage").start()
|
|
|
|
|
|
|
|
// The next line you only need if you need channels in administrate
|
|
|
|
require("channels")
|
|
|
|
|
|
|
|
// The next two lines you only need if you want ActionText support
|
|
|
|
require("trix")
|
|
|
|
require("@rails/actiontext")
|
|
|
|
|
|
|
|
require("../administrate/index")
|
|
|
|
```
|
|
|
|
|
|
|
|
One level up (in `javascript`) create a new folder with one file `administrate/index.js`:
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
import './components/table'
|
|
|
|
import './components/date_time_picker'
|
|
|
|
```
|
|
|
|
|
|
|
|
### Date & Time picker
|
|
|
|
This replaces the component currently bundled and works without JavaScript.
|
|
|
|
|
|
|
|
Create `components/date_time_picker.js`:
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
import flatpickr from 'flatpickr'
|
|
|
|
|
|
|
|
function bindDateTimePickers() {
|
|
|
|
[...document.querySelectorAll('[data-type="time"]')].forEach((time) => {
|
|
|
|
flatpickr(time, {
|
|
|
|
enableTime: true,
|
|
|
|
enableSeconds: true,
|
|
|
|
noCalendar: true,
|
|
|
|
altInput: true,
|
|
|
|
altFormat: ' h:i:S K',
|
|
|
|
dateFormat: 'H:i:S' // H:i
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
[...document.querySelectorAll('[data-type="datetime"]')].forEach((time) => {
|
|
|
|
flatpickr(time, {
|
|
|
|
enableTime: true,
|
|
|
|
altInput: true,
|
|
|
|
altFormat: 'F J (D), Y - h:i:S K',
|
|
|
|
dateFormat: 'Z' // Y-m-d H:i
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
document.addEventListener("turbolinks:load", function () {
|
|
|
|
bindDateTimePickers()
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
|
|
|
### Table row click
|
|
|
|
This replaces the current component table.js and works without jquery or the old ujs.
|
|
|
|
|
|
|
|
Create `components/table.js`
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
function bindTableLinks() {
|
|
|
|
const keycodes = { space: 32, enter: 13 }
|
|
|
|
|
|
|
|
function visitDataUrl(event) {
|
|
|
|
/** @type {HTMLTableRowElement} */
|
|
|
|
const target = event.target.classList.contains("js-table-row")
|
|
|
|
? event.target
|
|
|
|
: event.target.closest('.js-table-row')
|
|
|
|
|
|
|
|
if (!target) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.type === "click" ||
|
|
|
|
event.keyCode === keycodes.space ||
|
|
|
|
event.keyCode === keycodes.enter) {
|
|
|
|
|
|
|
|
if (event.target.href) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const dataUrl = target.getAttribute("data-url")
|
|
|
|
const selection = window.getSelection().toString()
|
|
|
|
if (selection.length === 0 && dataUrl) {
|
|
|
|
const delegate = target.querySelector(`[href="${dataUrl}"]`)
|
|
|
|
if (delegate) {
|
|
|
|
delegate.click()
|
|
|
|
} else {
|
|
|
|
window.location = dataUrl
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const tables = [...document.getElementsByTagName("table")]
|
|
|
|
tables.forEach(
|
|
|
|
/** @type {HTMLTableElement} */ (table) => {
|
|
|
|
table.addEventListener("click", visitDataUrl)
|
|
|
|
table.addEventListener("keydown", visitDataUrl)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
document.addEventListener("turbolinks:load", function() {
|
|
|
|
bindTableLinks()
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
|
|
|
### Select boxes
|
|
|
|
There is currently no recommended replacement for selectize.js
|
|
|
|
|
|
|
|
## Change the layout
|
|
|
|
Now you need to load this pack in the layout, and stop bundling the old assets.
|
|
|
|
|
|
|
|
in `app/views/layouts/admin` create `application.html.erb`:
|
|
|
|
|
|
|
|
```erb
|
|
|
|
<%#
|
|
|
|
# Application Layout
|
|
|
|
|
|
|
|
This view template is used as the layout
|
|
|
|
for every page that Administrate generates.
|
|
|
|
|
|
|
|
By default, it renders:
|
|
|
|
- Navigation
|
|
|
|
- Content for a search bar
|
|
|
|
(if provided by a `content_for` block in a nested page)
|
|
|
|
- Flashes
|
|
|
|
- Links to stylesheets and JavaScripts
|
|
|
|
%>
|
|
|
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="<%= I18n.locale %>">
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<meta name="robots" content="noodp, noydir, index, follow">
|
|
|
|
<meta name="viewport" content="initial-scale=1">
|
|
|
|
<title>
|
|
|
|
<%= content_for(:title) || 'Dashboard' %> - <%= Rails.application.class.parent_name.titlecase %>
|
|
|
|
</title>
|
|
|
|
<%= javascript_pack_tag 'administrate', 'data-turbolinks-track': 'reload' %>
|
|
|
|
|
|
|
|
<%= render "stylesheet" %>
|
|
|
|
<%= csrf_meta_tags %>
|
|
|
|
|
|
|
|
|
|
|
|
<meta name="turbolinks-root" content="/admin">
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="app-container">
|
|
|
|
<%= render "navigation" -%>
|
|
|
|
|
|
|
|
<main class="main-content" role="main">
|
|
|
|
<%= render "flashes" -%>
|
|
|
|
<%= yield %>
|
|
|
|
</main>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div style="display: none; width: 0; height: 0; overflow: hidden; position: absolute">
|
|
|
|
<%= render "icons" %>
|
|
|
|
</div>
|
|
|
|
<%= render "javascript" %>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
```
|
|
|
|
|
|
|
|
And one directory up (`app/views`) create the structure `admin/application/_javascript.html.erb`:
|
|
|
|
|
|
|
|
```erb
|
|
|
|
<%#
|
|
|
|
# Javascript Partial
|
|
|
|
|
|
|
|
This partial imports the necessary javascript on each page.
|
|
|
|
By default, it includes the application JS,
|
|
|
|
but each page can define additional JS sources
|
|
|
|
by providing a `content_for(:javascript)` block.
|
|
|
|
|
|
|
|
Administrate::Engine.javascripts.each do |js_path|
|
|
|
|
<= echo javascript_include_tag js_path
|
|
|
|
<% end
|
|
|
|
%>
|
|
|
|
|
|
|
|
<%= yield :javascript %>
|
|
|
|
|
|
|
|
<% if Rails.env.test? %>
|
|
|
|
<%= javascript_tag do %>
|
|
|
|
$.fx.off = true;
|
|
|
|
$.ajaxSetup({ async: false });
|
|
|
|
<% end %>
|
|
|
|
<% end %>
|
|
|
|
```
|
|
|
|
|
|
|
|
As you can see, all this does is load the correct pack in the head and stop including the administrate scripts.
|
|
|
|
|
|
|
|
## Update stylesheet
|
|
|
|
|
|
|
|
In order to work with the flatpickr css, and potentially actionpicker, generate the stylesheets layout via the generator, then open `app/assets/stylesheets/admininistrate/application.scss`:
|
|
|
|
|
|
|
|
```scss
|
|
|
|
@charset "utf-8";
|
|
|
|
|
|
|
|
@import "reset/normalize";
|
|
|
|
|
|
|
|
@import "library/clearfix";
|
|
|
|
@import "library/data-label";
|
|
|
|
@import "library/variables";
|
|
|
|
|
|
|
|
@import "base/forms";
|
|
|
|
@import "base/layout";
|
|
|
|
@import "base/lists";
|
|
|
|
@import "base/tables";
|
|
|
|
@import "base/typography";
|
|
|
|
|
|
|
|
@import "components/app-container";
|
|
|
|
@import "components/attributes";
|
|
|
|
@import "components/buttons";
|
|
|
|
@import "components/cells";
|
|
|
|
@import "components/field-unit";
|
|
|
|
@import "components/flashes";
|
|
|
|
@import "components/form-actions";
|
|
|
|
@import "components/main-content";
|
|
|
|
@import "components/navigation";
|
|
|
|
@import "components/pagination";
|
|
|
|
@import "components/search";
|
|
|
|
|
|
|
|
@import "utilities/text-color";
|
|
|
|
|
|
|
|
@import "trix/dist/trix";
|
|
|
|
|
|
|
|
// We need to override trix.css’s image gallery styles to accommodate the
|
|
|
|
// <action-text-attachment> element we wrap around attachments. Otherwise,
|
|
|
|
// images in galleries will be squished by the max-width: 33%; rule.
|
|
|
|
.trix-content {
|
|
|
|
.attachment-gallery {
|
|
|
|
> action-text-attachment,
|
|
|
|
> .attachment {
|
|
|
|
flex: 1 0 33%;
|
|
|
|
padding: 0 0.5em;
|
|
|
|
max-width: 33%;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.attachment-gallery--2,
|
|
|
|
&.attachment-gallery--4 {
|
|
|
|
> action-text-attachment,
|
|
|
|
> .attachment {
|
|
|
|
flex-basis: 50%;
|
|
|
|
max-width: 50%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
action-text-attachment {
|
|
|
|
.attachment {
|
|
|
|
padding: 0 !important;
|
|
|
|
max-width: 100% !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.field-unit--rich-text-area-field {
|
|
|
|
.field-unit__field {
|
|
|
|
width: 80%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@import "flatpickr/dist/flatpickr.min";
|
|
|
|
```
|
|
|
|
|
|
|
|
## Remove javascript
|
|
|
|
If done right, the only javascript _asset_ left is the administrate one. If it is still there, remove it from `app/assets/javascripts`. You don't need this because it's all packed.
|
|
|
|
|
|
|
|
## Rejoice
|
|
|
|
|
|
|
|
That's it. |
|
|
|
\ No newline at end of file |