headmin 0.2.2 → 0.2.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/.nvmrc +1 -1
- data/Gemfile.lock +3 -3
- data/README.md +17 -7
- data/app/helpers/headmin/admin_helper.rb +3 -59
- data/app/helpers/headmin/bootstrap_helper.rb +9 -0
- data/app/helpers/headmin/filter_helper.rb +7 -3
- data/app/helpers/headmin/form_helper.rb +36 -0
- data/app/helpers/headmin/request_helper.rb +39 -0
- data/app/models/concerns/headmin/fieldable.rb +53 -23
- data/app/services/block_service.rb +8 -4
- data/app/views/headmin/_blocks.html.erb +1 -1
- data/app/views/headmin/_filters.html.erb +1 -1
- data/app/views/headmin/_pagination.html.erb +4 -1
- data/app/views/headmin/dropdown/_devise.html.erb +20 -10
- data/app/views/headmin/dropdown/_list.html.erb +17 -7
- data/app/views/headmin/filters/_select.html.erb +3 -2
- data/app/views/headmin/filters/filter/_button.html.erb +0 -1
- data/app/views/headmin/forms/_blocks.html.erb +11 -4
- data/app/views/headmin/forms/_date.html.erb +1 -1
- data/app/views/headmin/forms/_label.html.erb +2 -2
- data/app/views/headmin/forms/_repeater.html.erb +6 -10
- data/app/views/headmin/table/_actions.html.erb +37 -11
- data/app/views/headmin/views/devise/confirmations/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/passwords/_edit.html.erb +2 -2
- data/app/views/headmin/views/devise/passwords/_new.html.erb +1 -1
- data/app/views/headmin/views/devise/registrations/_edit.html.erb +4 -4
- data/app/views/headmin/views/devise/registrations/_new.html.erb +3 -3
- data/app/views/headmin/views/devise/shared/_links.html.erb +7 -7
- data/app/views/headmin/views/devise/unlocks/_new.html.erb +1 -1
- data/config/locales/activerecord/en.yml +9 -0
- data/config/locales/activerecord/nl.yml +9 -0
- data/config/locales/headmin/table/en.yml +5 -1
- data/config/locales/headmin/table/nl.yml +5 -1
- data/config/locales/headmin/views/en.yml +1 -1
- data/config/locales/headmin/views/nl.yml +14 -14
- data/dist/css/headmin.css +54 -13
- data/dist/js/headmin.js +45 -513
- data/docs/blocks-and-fields.md +54 -0
- data/docs/blocks.md +1 -54
- data/docs/devise.md +40 -2
- data/docs/fields.md +31 -9
- data/headmin.gemspec +1 -1
- data/lib/generators/headmin/blocks_generator.rb +4 -1
- data/lib/generators/headmin/devise_generator.rb +16 -0
- data/lib/generators/headmin/fields_generator.rb +5 -1
- data/lib/generators/templates/controllers/auth/confirmations_controller.rb +31 -0
- data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +31 -0
- data/lib/generators/templates/controllers/auth/passwords_controller.rb +35 -0
- data/lib/generators/templates/controllers/auth/registrations_controller.rb +63 -0
- data/lib/generators/templates/controllers/auth/sessions_controller.rb +28 -0
- data/lib/generators/templates/controllers/auth/unlocks_controller.rb +31 -0
- data/lib/generators/templates/migrations/create_field_hierarchies.rb +16 -0
- data/lib/generators/templates/views/auth/confirmations/new.html.erb +1 -0
- data/lib/generators/templates/views/auth/mailer/confirmation_instructions.html.erb +1 -0
- data/lib/generators/templates/views/auth/mailer/email_changed.html.erb +1 -0
- data/lib/generators/templates/views/auth/mailer/password_change.html.erb +1 -0
- data/lib/generators/templates/views/auth/mailer/reset_password_instructions.html.erb +1 -0
- data/lib/generators/templates/views/auth/mailer/unlock_instructions.html.erb +1 -0
- data/lib/generators/templates/views/auth/passwords/edit.html.erb +1 -0
- data/lib/generators/templates/views/auth/passwords/new.html.erb +1 -0
- data/lib/generators/templates/views/auth/registrations/edit.html.erb +1 -0
- data/lib/generators/templates/views/auth/registrations/new.html.erb +1 -0
- data/lib/generators/templates/views/auth/sessions/new.html.erb +1 -0
- data/lib/generators/templates/views/auth/unlocks/new.html.erb +1 -0
- data/lib/generators/templates/views/layouts/auth.html.erb +20 -0
- data/lib/headmin/engine.rb +2 -0
- data/lib/headmin/version.rb +1 -1
- data/package.json +4 -3
- data/src/js/headmin/controllers/blocks_controller.js +1 -1
- data/src/js/headmin/controllers/filter_controller.js +1 -1
- data/src/js/headmin/controllers/filters_controller.js +1 -1
- data/src/js/headmin/controllers/popup_controller.js +1 -1
- data/src/js/headmin/controllers/repeater_controller.js +9 -10
- data/src/js/headmin/controllers/table_actions_controller.js +104 -9
- data/src/js/headmin/controllers/table_controller.js +28 -57
- data/src/js/headmin/headmin.js +2 -2
- data/src/scss/headmin/table.scss +1 -0
- data/yarn.lock +1159 -1237
- metadata +33 -7
- data/docs/README.md +0 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Controller} from "stimulus"
|
|
1
|
+
import {Controller} from "@hotwired/stimulus"
|
|
2
2
|
import Sortable from "sortablejs";
|
|
3
3
|
|
|
4
4
|
export default class extends Controller {
|
|
@@ -38,7 +38,6 @@ export default class extends Controller {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
updatePopupButtonIndices(index) {
|
|
41
|
-
console.log(index)
|
|
42
41
|
const popup = document.querySelector(`[data-popup-target="popup"][data-popup-id="repeater-buttons-${this.idValue}"]`)
|
|
43
42
|
const buttons = popup.querySelectorAll('a')
|
|
44
43
|
buttons.forEach((button) => {
|
|
@@ -53,8 +52,8 @@ export default class extends Controller {
|
|
|
53
52
|
let rowIndex = button.dataset.rowIndex
|
|
54
53
|
|
|
55
54
|
// Prepare html from template
|
|
56
|
-
|
|
57
|
-
html = this.replaceIdsWithTimestamps(
|
|
55
|
+
const template = this.getTemplate(templateName)
|
|
56
|
+
const html = this.replaceIdsWithTimestamps(template)
|
|
58
57
|
|
|
59
58
|
// Fallback to last row if no index is set
|
|
60
59
|
if (rowIndex) {
|
|
@@ -93,16 +92,16 @@ export default class extends Controller {
|
|
|
93
92
|
this.toggleEmpty()
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
getTemplate(name) {
|
|
96
|
+
return this.templateTargets.filter((template) => {
|
|
98
97
|
return template.dataset.templateName === name
|
|
99
98
|
})[0]
|
|
100
|
-
return template.innerHTML
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
replaceIdsWithTimestamps(
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
replaceIdsWithTimestamps(template) {
|
|
102
|
+
console.log(template)
|
|
103
|
+
const regex = new RegExp(template.dataset.templateIdRegex, "g")
|
|
104
|
+
return template.innerHTML.replace(regex, new Date().getTime())
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
visibleRowsCount() {
|
|
@@ -1,33 +1,128 @@
|
|
|
1
|
-
import {Controller} from "stimulus"
|
|
1
|
+
import {Controller} from "@hotwired/stimulus"
|
|
2
2
|
|
|
3
3
|
export default class extends Controller {
|
|
4
|
+
static get values() {
|
|
5
|
+
return {
|
|
6
|
+
count: {type: Number, default: 0}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
static get targets() {
|
|
5
|
-
return ["form", "select", "method", "button"]
|
|
11
|
+
return ["wrapper", "form", "select", "method", "button", "idInputTemplate", "id", "counter"]
|
|
6
12
|
}
|
|
7
13
|
|
|
8
14
|
connect() {
|
|
9
|
-
this.
|
|
15
|
+
this.wrapperTarget.addEventListener('idSelectionChanged', (event) => {
|
|
16
|
+
const ids = event.detail.ids
|
|
17
|
+
this.updateIdFields(ids)
|
|
18
|
+
this.updateCountValueWithIds(ids)
|
|
19
|
+
})
|
|
20
|
+
|
|
10
21
|
}
|
|
11
22
|
|
|
12
23
|
update(event) {
|
|
13
24
|
event.preventDefault()
|
|
14
|
-
|
|
25
|
+
this.updateFormAction()
|
|
26
|
+
this.updateFormMethod()
|
|
27
|
+
this.updateButton()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
updateIdFields(ids) {
|
|
31
|
+
this.removeIds()
|
|
32
|
+
if (ids instanceof Array) {
|
|
33
|
+
this.countValue = ids.length
|
|
34
|
+
ids.forEach((id) => {
|
|
35
|
+
this.addId(id)
|
|
36
|
+
})
|
|
37
|
+
} else {
|
|
38
|
+
this.countValue = Infinity
|
|
39
|
+
this.addId('')
|
|
40
|
+
}
|
|
41
|
+
}
|
|
15
42
|
|
|
16
|
-
|
|
43
|
+
updateCounter() {
|
|
44
|
+
let htmlString = ''
|
|
45
|
+
switch (this.countValue) {
|
|
46
|
+
case 0:
|
|
47
|
+
htmlString = this.counterTarget.getAttribute('data-items-zero')
|
|
48
|
+
break;
|
|
49
|
+
case 1:
|
|
50
|
+
htmlString = this.counterTarget.getAttribute('data-items-one')
|
|
51
|
+
break;
|
|
52
|
+
case Infinity:
|
|
53
|
+
htmlString = this.counterTarget.getAttribute('data-items-other')
|
|
54
|
+
htmlString = htmlString.replace(/<b>[\s\S]*?<\/b>/, '<b>' + this.totalCount() + '<\/b>');
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
htmlString = this.counterTarget.getAttribute('data-items-other')
|
|
58
|
+
let count = this.countValue === Infinity ? this.totalCount() : this.countValue
|
|
59
|
+
htmlString = htmlString.replace(/<b>[\s\S]*?<\/b>/, `<b>${count}<\/b>`);
|
|
60
|
+
}
|
|
61
|
+
this.counterTarget.innerHTML = htmlString;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
totalCount() {
|
|
65
|
+
return this.counterTarget.getAttribute('data-total-count')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
updateCountValueWithIds(ids) {
|
|
69
|
+
if (ids instanceof Array) {
|
|
70
|
+
this.countValue = ids.length
|
|
71
|
+
} else {
|
|
72
|
+
this.countValue = Infinity
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
countValueChanged() {
|
|
77
|
+
this.updateCounter()
|
|
78
|
+
this.toggle()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
toggle() {
|
|
82
|
+
if (this.countValue > 0) {
|
|
83
|
+
this.wrapperTarget.classList.remove('d-none')
|
|
84
|
+
} else {
|
|
85
|
+
this.wrapperTarget.classList.add('d-none')
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
updateFormAction() {
|
|
17
90
|
this.formTarget.action = this.selectTarget.value
|
|
91
|
+
}
|
|
18
92
|
|
|
19
|
-
|
|
93
|
+
updateFormMethod() {
|
|
94
|
+
const option = this.selectedOption()
|
|
20
95
|
this.methodTarget.value = option.dataset.method
|
|
96
|
+
}
|
|
21
97
|
|
|
22
|
-
|
|
98
|
+
updateButton() {
|
|
99
|
+
const option = this.selectedOption()
|
|
23
100
|
const confirm = option.dataset.confirm
|
|
24
|
-
if(confirm) {
|
|
101
|
+
if (confirm) {
|
|
25
102
|
this.buttonTarget.dataset.confirm = confirm
|
|
26
103
|
} else {
|
|
27
104
|
this.buttonTarget.removeAttribute('data-confirm')
|
|
28
105
|
}
|
|
106
|
+
this.enableButton()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
selectedOption() {
|
|
110
|
+
return this.selectTarget.options[this.selectTarget.selectedIndex]
|
|
111
|
+
}
|
|
29
112
|
|
|
30
|
-
|
|
113
|
+
enableButton() {
|
|
31
114
|
this.buttonTarget.removeAttribute('disabled')
|
|
32
115
|
}
|
|
116
|
+
|
|
117
|
+
addId(id) {
|
|
118
|
+
const template = this.idInputTemplateTarget
|
|
119
|
+
const input = template.innerHTML.replace(/ID/g, id)
|
|
120
|
+
this.formTarget.insertAdjacentHTML('afterbegin', input)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
removeIds() {
|
|
124
|
+
this.idTargets.forEach((input) => {
|
|
125
|
+
this.formTarget.removeChild(input)
|
|
126
|
+
});
|
|
127
|
+
}
|
|
33
128
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Controller} from "stimulus"
|
|
1
|
+
import {Controller} from "@hotwired/stimulus"
|
|
2
2
|
import Sortable from "sortablejs";
|
|
3
3
|
import Rails from "@rails/ujs";
|
|
4
4
|
|
|
@@ -38,25 +38,43 @@ export default class extends Controller {
|
|
|
38
38
|
const checkbox = event.target
|
|
39
39
|
this.toggleIdsCheckboxes(checkbox.checked)
|
|
40
40
|
this.toggleIdCheckboxes(checkbox.checked)
|
|
41
|
-
this.
|
|
42
|
-
this.toggleActions()
|
|
41
|
+
this.updateActions()
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
toggleId(event) {
|
|
46
45
|
this.toggleIdsCheckboxes(false)
|
|
47
|
-
this.
|
|
48
|
-
this.toggleActions()
|
|
46
|
+
this.updateActions()
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
updateActions() {
|
|
50
|
+
this.actionsTarget.dispatchEvent(
|
|
51
|
+
new CustomEvent(
|
|
52
|
+
'idSelectionChanged',
|
|
53
|
+
{
|
|
54
|
+
detail: {
|
|
55
|
+
ids: this.ids()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
ids() {
|
|
63
|
+
if (this.idsCheckboxTarget.checked) {
|
|
64
|
+
return null
|
|
55
65
|
} else {
|
|
56
|
-
this.
|
|
66
|
+
return this.selectedIdCheckboxes().map((checkbox) => {
|
|
67
|
+
return checkbox.value
|
|
68
|
+
})
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
|
|
72
|
+
selectedIdCheckboxes() {
|
|
73
|
+
return this.idCheckboxTargets.filter((checkbox) => {
|
|
74
|
+
return checkbox.checked
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
60
78
|
toggleIdsCheckboxes(checked) {
|
|
61
79
|
this.idsCheckboxTargets.forEach((checkbox) => {
|
|
62
80
|
checkbox.checked = checked
|
|
@@ -69,51 +87,4 @@ export default class extends Controller {
|
|
|
69
87
|
});
|
|
70
88
|
}
|
|
71
89
|
|
|
72
|
-
syncFields() {
|
|
73
|
-
this.removeIds()
|
|
74
|
-
if(this.idsCheckboxTarget.checked) {
|
|
75
|
-
this.addId('')
|
|
76
|
-
} else {
|
|
77
|
-
this.idCheckboxTargets.forEach((checkbox) => {
|
|
78
|
-
if(checkbox.checked) {
|
|
79
|
-
this.addId(checkbox.value)
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
addId(id) {
|
|
86
|
-
let field = this.getIdField(id)
|
|
87
|
-
if (!field) {
|
|
88
|
-
field = this.newIdField(id)
|
|
89
|
-
this.actionsTarget.querySelector('form').insertAdjacentHTML('afterbegin', field)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
removeIds() {
|
|
94
|
-
const fields = this.getIdFields()
|
|
95
|
-
fields.forEach((field) => {
|
|
96
|
-
this.actionsTarget.querySelector('form').removeChild(field)
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
removeId(id) {
|
|
101
|
-
const field = this.getIdField(id)
|
|
102
|
-
if (field) {
|
|
103
|
-
this.actionsTarget.querySelector('form').removeChild(field)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
newIdField(id) {
|
|
108
|
-
const template = this.actionsTarget.querySelector('[data-table-target="idFieldTemplate"]')
|
|
109
|
-
return template.innerHTML.replace(/ID/g, id)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
getIdFields() {
|
|
113
|
-
return this.actionsTarget.querySelectorAll(`input[name="ids[]"]`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
getIdField(id) {
|
|
117
|
-
return this.actionsTarget.querySelector(`input[name="ids[]"][value="${id}"]`);
|
|
118
|
-
}
|
|
119
90
|
}
|
data/src/js/headmin/headmin.js
CHANGED
|
@@ -4,8 +4,8 @@ import flatpickr from "flatpickr";
|
|
|
4
4
|
import bootstrap from "bootstrap/dist/js/bootstrap.bundle";
|
|
5
5
|
import Rails from "@rails/ujs";
|
|
6
6
|
|
|
7
|
-
import {Application} from "stimulus"
|
|
8
|
-
import {definitionsFromContext} from "stimulus
|
|
7
|
+
import {Application} from "@hotwired/stimulus"
|
|
8
|
+
import {definitionsFromContext} from "@hotwired/stimulus-webpack-helpers"
|
|
9
9
|
|
|
10
10
|
export class Headmin {
|
|
11
11
|
static start() {
|