nitro_rails 0.1.0 → 0.1.1
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/README.md +18 -0
- data/app/assets/audio/mousetap.mp3 +0 -0
- data/app/assets/config/nitro_rails_manifest.js +2 -0
- data/app/assets/javascript/nitro_rails/application.js +4 -0
- data/app/assets/javascript/nitro_rails/controllers/application.js +9 -0
- data/app/assets/javascript/nitro_rails/controllers/audio_controller.js +16 -0
- data/app/assets/javascript/nitro_rails/controllers/clock_controller.js +21 -0
- data/app/assets/javascript/nitro_rails/controllers/editable_text_controller.js +61 -0
- data/app/assets/javascript/nitro_rails/controllers/index.js +21 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_collection_controller.js +127 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_controller.js +35 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_form_controller.js +81 -0
- data/app/assets/javascript/nitro_rails/controllers/panel_controller.js +70 -0
- data/app/assets/javascript/nitro_rails/controllers/panel_manager_controller.js +89 -0
- data/app/assets/javascript/nitro_rails/controllers/tabs_controller.js +81 -0
- data/app/assets/javascript/nitro_rails/controllers/time_zone_controller.js +47 -0
- data/app/assets/javascript/nitro_rails/controllers/togglable_checkbox_controller.js +9 -0
- data/app/assets/javascript/nitro_rails/helpers/device_info_helper.js +99 -0
- data/app/assets/javascript/nitro_rails/helpers/screen_info_helper.js +20 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/clear_errors.js +22 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/focus.js +8 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/index.js +8 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/insert.js +10 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/redirect.js +10 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/refresh_frame.js +9 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/render_errors.js +26 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/toggle_checkbox.js +9 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/toggle_class.js +14 -0
- data/app/assets/stylesheets/nitro_rails/__reset.css +25 -0
- data/app/assets/stylesheets/nitro_rails/_base/_color.css +24 -0
- data/app/assets/stylesheets/nitro_rails/_base/_font.css +35 -0
- data/app/assets/stylesheets/nitro_rails/_base/_format.css +38 -0
- data/app/assets/stylesheets/nitro_rails/_base/_grayscale.css +79 -0
- data/app/assets/stylesheets/nitro_rails/_base/_utility.css +34 -0
- data/app/assets/stylesheets/nitro_rails/application.css +23 -0
- data/app/assets/stylesheets/nitro_rails/modules/action-navigation.css +24 -0
- data/app/assets/stylesheets/nitro_rails/modules/alert.css +31 -0
- data/app/assets/stylesheets/nitro_rails/modules/btn.css +57 -0
- data/app/assets/stylesheets/nitro_rails/modules/checkbox.css +42 -0
- data/app/assets/stylesheets/nitro_rails/modules/clickable.css +9 -0
- data/app/assets/stylesheets/nitro_rails/modules/clock.css +0 -0
- data/app/assets/stylesheets/nitro_rails/modules/editable-text.css +45 -0
- data/app/assets/stylesheets/nitro_rails/modules/forms.css +108 -0
- data/app/assets/stylesheets/nitro_rails/modules/hover-reveal.css +11 -0
- data/app/assets/stylesheets/nitro_rails/modules/inline-svg.css +14 -0
- data/app/assets/stylesheets/nitro_rails/modules/list.css +29 -0
- data/app/assets/stylesheets/nitro_rails/modules/main-navigation.css +20 -0
- data/app/assets/stylesheets/nitro_rails/modules/nitro-checkbox.css +42 -0
- data/app/assets/stylesheets/nitro_rails/modules/resource-collection.css +12 -0
- data/app/assets/stylesheets/nitro_rails/modules/search-bar.css +36 -0
- data/app/assets/stylesheets/nitro_rails/modules/settings.css +33 -0
- data/app/assets/stylesheets/nitro_rails/modules/tabs.css +38 -0
- data/app/assets/stylesheets/nitro_rails/modules/toggle-switch.css +60 -0
- data/app/assets/stylesheets/nitro_rails/panels/bound-card-dropdown-panel.css +0 -0
- data/app/assets/stylesheets/nitro_rails/panels/card-panel.css +0 -0
- data/app/assets/stylesheets/nitro_rails/panels/embedded-panel.css +31 -0
- data/app/assets/stylesheets/nitro_rails/panels/panel-display.css +111 -0
- data/app/assets/stylesheets/nitro_rails/panels/popup-panel.css +123 -0
- data/app/assets/stylesheets/nitro_rails/panels/side-panel.css +0 -0
- data/app/controllers/nitro_rails/sequence_controller.rb +64 -0
- data/app/helpers/nitro_rails/application_helper.rb +42 -1
- data/app/helpers/nitro_rails/color_helper.rb +23 -0
- data/app/helpers/nitro_rails/components_helper.rb +49 -0
- data/app/helpers/nitro_rails/inline_edit_helper.rb +48 -0
- data/app/helpers/nitro_rails/nitro_action_helper.rb +178 -0
- data/app/helpers/nitro_rails/nitro_collection_helper.rb +87 -0
- data/app/helpers/nitro_rails/nitro_edit_helper.rb +15 -0
- data/app/helpers/nitro_rails/nitro_form_helper.rb +104 -0
- data/app/helpers/nitro_rails/nitro_options_helper.rb +78 -0
- data/app/helpers/nitro_rails/nitro_tag_helper.rb +183 -0
- data/app/helpers/nitro_rails/panel_helper.rb +65 -0
- data/app/helpers/nitro_rails/resource_collection_helper.rb +66 -0
- data/app/helpers/nitro_rails/tabs_helper.rb +51 -0
- data/app/helpers/nitro_rails/turbo_stream_helper.rb +46 -0
- data/app/lib/nitro_rails/local_time.rb +51 -0
- data/app/lib/nitro_rails/performable_routes.rb +24 -0
- data/app/lib/nitro_rails/resource_collection.rb +183 -0
- data/app/lib/nitro_rails/sequential_routes.rb +36 -0
- data/app/lib/nitro_rails/time_interval.rb +88 -0
- data/app/lib/nitro_rails/time_string.rb +22 -0
- data/app/models/nitro_rails/broadcast.rb +76 -0
- data/app/models/nitro_rails/broadcastable_model.rb +91 -0
- data/app/models/nitro_rails/broadcastable_record.rb +118 -0
- data/app/models/nitro_rails/default_broadcasts.rb +149 -0
- data/app/models/nitro_rails/record.rb +50 -0
- data/app/pseudocode/nitro.html.erb +18 -0
- data/app/view_components/nitro_rails/nitro_collection/batch_selectable.rb +24 -0
- data/app/view_components/nitro_rails/nitro_collection.rb +66 -0
- data/app/view_components/nitro_rails/view_component.rb +9 -0
- data/app/views/layouts/nitro_rails/application.html.erb +3 -5
- data/app/views/nitro_rails/_editable_text.html.erb +32 -0
- data/app/views/nitro_rails/_nitro_checkbox.html.erb +5 -0
- data/app/views/nitro_rails/_nitro_form.html.erb +10 -0
- data/app/views/nitro_rails/_panel_frame_tag.html.erb +8 -0
- data/app/views/nitro_rails/_panel_template.html.erb +40 -0
- data/app/views/nitro_rails/_togglable_checkbox.html.erb +16 -0
- data/config/importmap.rb +1 -0
- data/config/initializers/date_formatters.rb +9 -0
- data/lib/nitro_rails/engine.rb +25 -0
- data/lib/nitro_rails/version.rb +1 -1
- metadata +165 -3
- data/app/models/nitro_rails/application_record.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f71c75899ffa891a15764b40d7b2689c0bb60ed23ebd40e6122837958e0a613
|
4
|
+
data.tar.gz: ebd57bac0083b2d6c1b19b0212e5c61c152fe7d8a92194a44113912f59996879
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a287da566c8533cf9793ce71405e48a62610862cdd1277361fa7c714af73c3ba03c7555505a19bd7098a34bf3eda713a685ee2628d003e7e2c3cdc2d49c86ba1
|
7
|
+
data.tar.gz: 979d4d22beccf10641a959762e6c91c8bb084746bea0e79dcc880a8fe65efa68c305763e90c6bdf7352138ff66d857376c4d621d3e3955f577fdf973375928a6
|
data/README.md
CHANGED
@@ -21,6 +21,24 @@ Or install it yourself as:
|
|
21
21
|
$ gem install nitro_rails
|
22
22
|
```
|
23
23
|
|
24
|
+
## Features
|
25
|
+
|
26
|
+
### NitroTags
|
27
|
+
Similar to content_tag with additional functions.
|
28
|
+
```erb
|
29
|
+
<%= nitro_tag(:h1, "Hello World") %>
|
30
|
+
```
|
31
|
+
|
32
|
+
Allows for hashed styles:
|
33
|
+
```erb
|
34
|
+
<%= nitro_tag(:div, "Hello World", style: { color: "red", margin_bottom: 20 })
|
35
|
+
```
|
36
|
+
|
37
|
+
Allows for easy "nitro_id" via resource and attribut
|
38
|
+
```erb
|
39
|
+
<%= nitro_tag(:p, resource: @task, attribute: :description) %> <%# data-nitro-id = "task_3:description" %>
|
40
|
+
```
|
41
|
+
|
24
42
|
## Contributing
|
25
43
|
Contribution directions go here.
|
26
44
|
|
Binary file
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
// Preload audio files
|
5
|
+
connect() {
|
6
|
+
this.audio = new Audio(`/assets/${this.element.dataset.audio}.mp3`)
|
7
|
+
this.audio.load();
|
8
|
+
this.audio.preload = "auto";
|
9
|
+
// this.audio.time
|
10
|
+
}
|
11
|
+
|
12
|
+
play() {
|
13
|
+
this.audio.currentTime = 20000;
|
14
|
+
this.audio.play();
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["time"]
|
5
|
+
static values = { format: String }
|
6
|
+
|
7
|
+
connect() {
|
8
|
+
this.updateTime();
|
9
|
+
this.interval = setInterval(this.updateTime.bind(this), 1000);
|
10
|
+
}
|
11
|
+
|
12
|
+
disconnect() {
|
13
|
+
clearInterval(this.interval);
|
14
|
+
}
|
15
|
+
|
16
|
+
updateTime() {
|
17
|
+
const now = new Date();
|
18
|
+
const options = { hour: 'numeric', minute: 'numeric' };
|
19
|
+
this.timeTarget.textContent = now.toLocaleTimeString(undefined, options);
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["input", "editor", "form"]
|
5
|
+
static values = { attribute: String }
|
6
|
+
|
7
|
+
connect() {
|
8
|
+
this.inputTarget.value = this.editorTarget.innerText;
|
9
|
+
this.typingTimer;
|
10
|
+
}
|
11
|
+
|
12
|
+
focus() {
|
13
|
+
this.editorTarget.setAttribute('data-reject-broadcasts', '');
|
14
|
+
}
|
15
|
+
|
16
|
+
blur() {
|
17
|
+
this.editorTarget.removeAttribute('data-reject-broadcasts');
|
18
|
+
this.submit();
|
19
|
+
}
|
20
|
+
|
21
|
+
submit() {
|
22
|
+
if(this.inputTarget.value != this.editorTarget.innerText || this.editorTarget.innerText == '') {
|
23
|
+
this.inputTarget.value = this.editorTarget.innerText.trim();
|
24
|
+
this.formTarget.requestSubmit();
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
handleKeyDown(event) {
|
29
|
+
if(event.key == 'Enter') {
|
30
|
+
this.handleEnterKey(event);
|
31
|
+
} else {
|
32
|
+
clearTimeout(this.typingTimer);
|
33
|
+
this.typingTimer = setTimeout(this.submit.bind(this), 750)
|
34
|
+
if(event.key == 'Backspace') {
|
35
|
+
this.handleBackspaceKey(event);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
handleEnterKey(event) {
|
41
|
+
event.preventDefault();
|
42
|
+
this.editorTarget.dataset.temporaryPlacement = window.getSelection().getRangeAt(0).startOffset;
|
43
|
+
this.editorTarget.blur();
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
|
47
|
+
handleBackspaceKey(event) {
|
48
|
+
const selectionRange = window.getSelection().getRangeAt(0);
|
49
|
+
|
50
|
+
if(selectionRange.startOffset == 0 && selectionRange.endOffset == 0) {
|
51
|
+
event.preventDefault();
|
52
|
+
}
|
53
|
+
|
54
|
+
if(this.editorTarget.innerText.length == 1 || (selectionRange.startOffset == 0 && selectionRange.endOffset == this.editorTarget.innerText.length)) {
|
55
|
+
this.editorTarget.innerText = '';
|
56
|
+
}
|
57
|
+
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
|
61
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// Import and register all your controllers from the importmap under controllers/*
|
2
|
+
|
3
|
+
import { application } from "./application"
|
4
|
+
|
5
|
+
// Load all controllers one by one
|
6
|
+
// import EngineController from "./engine_controller"
|
7
|
+
// application.register("engine", EngineController)
|
8
|
+
|
9
|
+
// const controllers = ["editable_text", "search", "panel", "panel_manager", "resource_collection", "switch"];
|
10
|
+
|
11
|
+
const controllers = ["panel", "panel_manager", "editable_text", "time_zone", "togglable_checkbox", "nitro", "clock", "nitro_form", "audio", "nitro_collection", "tabs"];
|
12
|
+
|
13
|
+
controllers.forEach((controller) => {
|
14
|
+
import(`./${controller}_controller.js`).then(( { default: module }) => {
|
15
|
+
application.register(controller.replace("_", "-"), module)
|
16
|
+
})
|
17
|
+
})
|
18
|
+
|
19
|
+
// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
|
20
|
+
// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
|
21
|
+
// lazyLoadControllersFrom("controllers", application)
|
@@ -0,0 +1,127 @@
|
|
1
|
+
// HACK: Needs major refactoring
|
2
|
+
|
3
|
+
import { Controller } from '@hotwired/stimulus';
|
4
|
+
|
5
|
+
export default class extends Controller {
|
6
|
+
static targets = ["template", "collection", "container", "item", "selections", "selectionForm"];
|
7
|
+
|
8
|
+
connect() {
|
9
|
+
this.selectedItems = [];
|
10
|
+
this.dragEvent = {
|
11
|
+
dragging: false,
|
12
|
+
originItem: null,
|
13
|
+
currentItem: null,
|
14
|
+
draggingItem: null
|
15
|
+
};
|
16
|
+
}
|
17
|
+
|
18
|
+
addTemporaryItem() {
|
19
|
+
var content = this.templateTarget.innerHTML;
|
20
|
+
var newElement = document.createElement("div");
|
21
|
+
newElement.innerHTML = content;
|
22
|
+
this.collectionTarget.appendChild(newElement);
|
23
|
+
}
|
24
|
+
|
25
|
+
selectItem(event) {
|
26
|
+
var item = event.currentTarget.closest("[data-nitro-collection-target='item']");
|
27
|
+
|
28
|
+
if(item.dataset.selected === "true") {
|
29
|
+
item.dataset.selected = "false";
|
30
|
+
item.classList.remove("selected");
|
31
|
+
this.selectedItems = this.selectedItems.filter(i => i !== item);
|
32
|
+
} else {
|
33
|
+
item.dataset.selected = "true";
|
34
|
+
item.classList.add("selected");
|
35
|
+
this.selectedItems.push(item);
|
36
|
+
}
|
37
|
+
|
38
|
+
if(this.selectedItems.length > 0) {
|
39
|
+
this.collectionTarget.classList.add("has-selection");
|
40
|
+
this.selectionsTarget.classList.remove("hidden");
|
41
|
+
} else {
|
42
|
+
this.collectionTarget.classList.remove("has-selection");
|
43
|
+
this.selectionsTarget.classList.add("hidden");
|
44
|
+
}
|
45
|
+
|
46
|
+
this.selectionsTarget.querySelector("#selection-count").innerText = `${this.selectedItems.length}`;
|
47
|
+
|
48
|
+
this.selectionFormTargets.forEach((form) => {
|
49
|
+
if(!form.querySelector(`#hidden-selections`)) {
|
50
|
+
var hiddenDiv = document.createElement("div");
|
51
|
+
hiddenDiv.id = "hidden-selections";
|
52
|
+
form.appendChild(hiddenDiv);
|
53
|
+
}
|
54
|
+
|
55
|
+
const selectionsDiv = form.querySelector(`#hidden-selections`);
|
56
|
+
selectionsDiv.innerHTML = "";
|
57
|
+
|
58
|
+
this.selectedItems.forEach((item, index) => {
|
59
|
+
selectionsDiv.innerHTML += `<input type="hidden" name="selected_ids[]" value="${item.dataset.id}">`;
|
60
|
+
});
|
61
|
+
});
|
62
|
+
}
|
63
|
+
|
64
|
+
startReposition(event) {
|
65
|
+
if(event.target.closest("a, input, button, textarea, .nitro-form-submit")) {
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
|
69
|
+
event.preventDefault();
|
70
|
+
const item = event.currentTarget.closest("[data-nitro-collection-target='item']");
|
71
|
+
const itemClone = item.cloneNode(true);
|
72
|
+
|
73
|
+
this.dragEvent.originItem = item;
|
74
|
+
this.dragEvent.draggingItem = itemClone;
|
75
|
+
this.dragEvent.dragging = true;
|
76
|
+
|
77
|
+
item.classList.add("placeholder");
|
78
|
+
|
79
|
+
|
80
|
+
itemClone.style.position = "absolute";
|
81
|
+
itemClone.style.zIndex = "1000";
|
82
|
+
itemClone.id = "dragging-item";
|
83
|
+
itemClone.classList.add("dragging");
|
84
|
+
itemClone.dataset.action = "mouseup->nitro-collection#endReposition";
|
85
|
+
|
86
|
+
document.addEventListener("mousemove", (e) => {
|
87
|
+
itemClone.style.left = `${e.pageX - itemClone.offsetWidth / 2}px`;
|
88
|
+
itemClone.style.top = `${e.pageY - itemClone.offsetHeight / 2}px`;
|
89
|
+
});
|
90
|
+
|
91
|
+
document.addEventListener("mouseup", (e) => {
|
92
|
+
this.endReposition(e);
|
93
|
+
document.removeEventListener("mousemove", null);
|
94
|
+
});
|
95
|
+
|
96
|
+
this.collectionTarget.appendChild(itemClone);
|
97
|
+
|
98
|
+
itemClone.style.width = `${item.getBoundingClientRect().width}px`;
|
99
|
+
itemClone.style.left = `${event.pageX - itemClone.offsetWidth / 2}px`;
|
100
|
+
itemClone.style.top = `${event.pageY - itemClone.offsetHeight / 2}px`;
|
101
|
+
}
|
102
|
+
|
103
|
+
changePosition(event) {
|
104
|
+
this.dragEvent.currentItem = event.currentTarget.closest("[data-nitro-collection-target='item']");
|
105
|
+
|
106
|
+
if(this.dragEvent.dragging && this.dragEvent.currentItem !== this.dragEvent.originItem) {
|
107
|
+
if(this.dragEvent.currentItem !== this.dragEvent.originItem.nextElementSibling) {
|
108
|
+
this.collectionTarget.insertBefore(this.dragEvent.originItem, this.dragEvent.currentItem);
|
109
|
+
} else {
|
110
|
+
this.collectionTarget.insertBefore(this.dragEvent.originItem, this.dragEvent.currentItem.nextElementSibling);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
endReposition() {
|
116
|
+
if(this.dragEvent.dragging) {
|
117
|
+
this.dragEvent.originItem.classList.remove("placeholder");
|
118
|
+
this.dragEvent.draggingItem.remove();
|
119
|
+
this.dragEvent = {
|
120
|
+
dragging: false,
|
121
|
+
originItem: null,
|
122
|
+
currentItem: null,
|
123
|
+
draggingItem: null
|
124
|
+
};
|
125
|
+
}
|
126
|
+
}
|
127
|
+
};
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
changeClasses(event) {
|
5
|
+
console.log("Changing classes");
|
6
|
+
var data = new FormData(event.target)
|
7
|
+
console.log(data.keys());
|
8
|
+
console.log(data.get("daypoint[num_stars]"));
|
9
|
+
var newNum = data.get("daypoint[num_stars]");
|
10
|
+
document.querySelector('[data-broadcast-tag="daypoint-69"]').classList.remove("stars-1", "stars-2", "stars-3", "stars-4", "stars-5");
|
11
|
+
document.querySelector('[data-broadcast-tag="daypoint-69"]').classList.add("stars-" + newNum);
|
12
|
+
// document.querySelector("[data-broadcast-tag='daypoint-69'").toggleClass("stars-" + newNum, true);
|
13
|
+
|
14
|
+
// data.getAll.for
|
15
|
+
|
16
|
+
for (const [name, value] of data.entries()) {
|
17
|
+
console.log(name + ": " + value);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
simulateResponse() {
|
22
|
+
console.log("Simulating response");
|
23
|
+
// var data = new FormData();
|
24
|
+
// data.append("daypoint[num_stars]", "3");
|
25
|
+
// var event = {
|
26
|
+
// target: document.querySelector('[data-broadcast-tag="daypoint-69"]')
|
27
|
+
// };
|
28
|
+
// this.changeClasses(event);
|
29
|
+
}
|
30
|
+
|
31
|
+
link(event) {
|
32
|
+
var url = event.currentTarget.getAttribute("data-nitro-link");
|
33
|
+
window.location.href = url;
|
34
|
+
}
|
35
|
+
};
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["form", "field", "collection"]
|
5
|
+
static values = {
|
6
|
+
resourceTarget: String
|
7
|
+
}
|
8
|
+
|
9
|
+
submit(event) {
|
10
|
+
event.preventDefault();
|
11
|
+
event.stopPropagation();
|
12
|
+
this.formTarget.requestSubmit();
|
13
|
+
|
14
|
+
if(this.formTarget.dataset.nitroEffects) {
|
15
|
+
console.log(this.formTarget.dataset.nitroEffects);
|
16
|
+
this.formTarget.dataset.nitroEffects.split(" ").forEach((effect) => {
|
17
|
+
if(this[effect]) {
|
18
|
+
this[effect]();
|
19
|
+
}
|
20
|
+
});
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
insertItems(){
|
25
|
+
|
26
|
+
}
|
27
|
+
|
28
|
+
addToAffiliatedLists(affiliation, value, field) {
|
29
|
+
document.querySelectorAll(`[data-nitro-collection-id="${affiliation}"]`).forEach((element) => {
|
30
|
+
var collectionController = window.Stimulus.getControllerForElementAndIdentifier(element, "nitro-collection");
|
31
|
+
collectionController.addTemporaryItem();
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
attributeEffects(){
|
36
|
+
this.fieldTargets.forEach((field) => {
|
37
|
+
field.dataset.nitroEffects.split(" ").forEach((effect) => {
|
38
|
+
if(this[effect]) {
|
39
|
+
this[effect](field.dataset.nitroAttribute, field.value, field);
|
40
|
+
}
|
41
|
+
});
|
42
|
+
console.log(field.dataset.nitroEffects)
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
updateStatusClass(attribute, value) {
|
47
|
+
console.log(`Updating status class for ${attribute} with value ${value}`);
|
48
|
+
document.querySelectorAll(`[data-nitro-id="${this.resourceTargetValue}"], [data-nitro-id="${this.resourceTargetValue}:${attribute}"]`).forEach((element) => {
|
49
|
+
// Remove classes starting with attribute
|
50
|
+
element.classList.forEach((className) => {
|
51
|
+
if(className.startsWith(attribute)) {
|
52
|
+
element.classList.remove(className);
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
element.classList.add(`${attribute}-${value}`);
|
57
|
+
});
|
58
|
+
|
59
|
+
this.resourceTargetValue
|
60
|
+
}
|
61
|
+
|
62
|
+
toggleBooleanStatusClass(attribute, value, field) {
|
63
|
+
document.querySelectorAll(`[data-nitro-id="${this.resourceTargetValue}"]`).forEach((element) => {
|
64
|
+
if(field.checked) {
|
65
|
+
element.classList.add(`${attribute}`);
|
66
|
+
} else {
|
67
|
+
element.classList.remove(`${attribute}`);
|
68
|
+
}
|
69
|
+
});
|
70
|
+
}
|
71
|
+
|
72
|
+
removeItem() {
|
73
|
+
document.querySelectorAll(`[data-nitro-id="${this.resourceTargetValue}"]`).forEach((element) => {
|
74
|
+
element.remove();
|
75
|
+
});
|
76
|
+
}
|
77
|
+
|
78
|
+
connect() {
|
79
|
+
console.log("Nitro Form Connected!");
|
80
|
+
}
|
81
|
+
};
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["turboFrame"]
|
5
|
+
|
6
|
+
connect() {
|
7
|
+
this.initialPanelTop = null;
|
8
|
+
this.isCardFullyExpanded = false;
|
9
|
+
console.log("Panel Connected!");
|
10
|
+
// this.element.addEventListener('wheel', this.handleScroll.bind(this));
|
11
|
+
}
|
12
|
+
|
13
|
+
open() {
|
14
|
+
let path = this.turboFrameTarget.src
|
15
|
+
path = new URL(path, window.location.href);
|
16
|
+
path.searchParams.delete("panel_request");
|
17
|
+
Turbo.visit(path, { action: "advance" });
|
18
|
+
}
|
19
|
+
|
20
|
+
beforeVisit(event) {
|
21
|
+
console.log(event);
|
22
|
+
console.log(event.srcElement.src);
|
23
|
+
// event.srcElement.src = event.srcElement.src + "?panel_request=true";
|
24
|
+
|
25
|
+
const { fetchOptions } = event.detail;
|
26
|
+
|
27
|
+
// Add your custom header
|
28
|
+
fetchOptions.headers["Turbo-Panel-Request"] = "true";
|
29
|
+
console.log(fetchOptions.headers);
|
30
|
+
|
31
|
+
}
|
32
|
+
|
33
|
+
close() {
|
34
|
+
this.element.remove();
|
35
|
+
}
|
36
|
+
|
37
|
+
scroll(event) {
|
38
|
+
event.preventDefault();
|
39
|
+
event.stopPropagation();
|
40
|
+
console.log("SCROLLING PANEL");
|
41
|
+
console.log(event);
|
42
|
+
}
|
43
|
+
|
44
|
+
handleScroll(event) {
|
45
|
+
if (!this.isCardFullyExpanded) {
|
46
|
+
event.preventDefault();
|
47
|
+
const scrollDirection = event.deltaY * -1; // Positive when scrolling down, negative when scrolling up
|
48
|
+
|
49
|
+
// Initialize initialPanelTop if it's not set
|
50
|
+
if (this.initialPanelTop === null) {
|
51
|
+
const panelPosition = this.element.getBoundingClientRect();
|
52
|
+
this.initialPanelTop = panelPosition.top;
|
53
|
+
}
|
54
|
+
|
55
|
+
// Calculate new position based on scroll direction
|
56
|
+
let newTopPosition = this.initialPanelTop + scrollDirection;
|
57
|
+
newTopPosition = Math.max(newTopPosition, 0); // Ensure the panel does not move above the top of the screen
|
58
|
+
|
59
|
+
// Move the panel by updating its CSS transform property
|
60
|
+
this.element.style.transform = `translateY(${newTopPosition}px)`;
|
61
|
+
|
62
|
+
if (newTopPosition === 0) {
|
63
|
+
this.isCardFullyExpanded = true; // The card is now fully expanded
|
64
|
+
} else {
|
65
|
+
// Update initialPanelTop for the next scroll event
|
66
|
+
this.initialPanelTop = newTopPosition;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
@@ -0,0 +1,89 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
2
|
+
import { deviceInfoHelper } from '../helpers/device_info_helper';
|
3
|
+
import { screenInfoHelper } from '../helpers/screen_info_helper';
|
4
|
+
|
5
|
+
// Needs a complete overhaul, probably so that links and panels are connected without panel containers
|
6
|
+
export default class extends Controller {
|
7
|
+
static targets = ["panelTemplate", "container", "panel"]
|
8
|
+
connect() {
|
9
|
+
}
|
10
|
+
|
11
|
+
morph(event) {
|
12
|
+
this.containerTargets.forEach((panel) => {
|
13
|
+
console.log(panel);
|
14
|
+
});
|
15
|
+
}
|
16
|
+
|
17
|
+
closeOtherPanels(event) {
|
18
|
+
let activePanels = this.panelTargets.filter((panel) => {
|
19
|
+
return panel.closest('.panel-container').classList.contains("active");
|
20
|
+
});
|
21
|
+
|
22
|
+
let currentPanelContainer = event.target.closest('.panel-container');
|
23
|
+
activePanels.forEach((panel) => {
|
24
|
+
|
25
|
+
if(panel.closest('.panel-container') !== currentPanelContainer) {
|
26
|
+
panel.closest('.panel-container').classList.remove("active");
|
27
|
+
panel.classList.add("hidden");
|
28
|
+
}
|
29
|
+
});
|
30
|
+
}
|
31
|
+
|
32
|
+
closeAllPanels(event) {
|
33
|
+
if(event.target === event.currentTarget) {
|
34
|
+
this.panelTargets.forEach((panel) => {
|
35
|
+
panel.closest('.panel-container').classList.remove("active");
|
36
|
+
panel.classList.add("hidden");
|
37
|
+
});
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
initializePanel(anchor, panelContainer, panelID) {
|
42
|
+
const panel = this.panelTemplateTarget.cloneNode(true);
|
43
|
+
|
44
|
+
panel.id = panelID;
|
45
|
+
|
46
|
+
// Add panel request parameter to path
|
47
|
+
let path = new URL(anchor.getAttribute("href"), window.location.href);
|
48
|
+
path.searchParams.append("panel_request", "true");
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
if(anchor.dataset.panelPresentation) {
|
53
|
+
console.log(anchor.dataset);
|
54
|
+
panel.classList.add(anchor.dataset.panelPresentation);
|
55
|
+
}
|
56
|
+
|
57
|
+
panel.dataset.panelManagerTarget = "panel";
|
58
|
+
panelContainer.appendChild(panel);
|
59
|
+
panel.querySelector("turbo-frame").src = anchor.getAttribute("href");
|
60
|
+
return panel;
|
61
|
+
}
|
62
|
+
|
63
|
+
toggle(event) {
|
64
|
+
if(deviceInfoHelper.isIOSApp() || this.isInPanel(event)) {
|
65
|
+
console.log("HERE");
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
|
69
|
+
event.preventDefault();
|
70
|
+
|
71
|
+
let anchor = event.currentTarget;
|
72
|
+
let panelContainer = (anchor.closest('.panel-container') || document.body);
|
73
|
+
|
74
|
+
let panelID = `panel-${anchor.dataset.panelId}`;
|
75
|
+
let panel = (panelContainer.querySelector(`#${panelID}`) || this.initializePanel(anchor, panelContainer, panelID));
|
76
|
+
|
77
|
+
if(panel.classList.contains("hidden")) {
|
78
|
+
panel.classList.remove("hidden");
|
79
|
+
panelContainer.classList.add("active");
|
80
|
+
} else {
|
81
|
+
panel.classList.add("hidden");
|
82
|
+
panelContainer.classList.remove("active");
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
isInPanel(event) {
|
87
|
+
return event.currentTarget.closest('[data-controller~="panel"]') !== null;
|
88
|
+
}
|
89
|
+
}
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["tab", "screen", "screens"]
|
5
|
+
|
6
|
+
connect(event) {
|
7
|
+
if(this.element.dataset.tabsLoaded === "true") {
|
8
|
+
return
|
9
|
+
}
|
10
|
+
|
11
|
+
this.tabId = this.element.id || "tab";
|
12
|
+
const source = this.element.closest("turbo-frame");
|
13
|
+
let urlParams;
|
14
|
+
|
15
|
+
if (source && source.src) {
|
16
|
+
urlParams = new URLSearchParams(source.src.split("?")[1]);
|
17
|
+
} else {
|
18
|
+
urlParams = new URLSearchParams(window.location.search);
|
19
|
+
}
|
20
|
+
|
21
|
+
const tab = urlParams.get(this.tabId);
|
22
|
+
|
23
|
+
if (tab) {
|
24
|
+
const selectedTab = this.tabTargets.find((searchTab) => searchTab.dataset.tabsScreen === tab);
|
25
|
+
|
26
|
+
if (selectedTab) {
|
27
|
+
this.#showScreen(selectedTab);
|
28
|
+
}
|
29
|
+
} else {
|
30
|
+
this.#showScreen(this.tabTargets[0]);
|
31
|
+
}
|
32
|
+
|
33
|
+
this.element.dataset.tabsLoaded = "true";
|
34
|
+
}
|
35
|
+
|
36
|
+
changeScreens(event) {
|
37
|
+
event.preventDefault();
|
38
|
+
event.stopPropagation();
|
39
|
+
|
40
|
+
let selectedScreen = this.#showScreen(event.currentTarget);
|
41
|
+
console.log(selectedScreen);
|
42
|
+
let masonry = selectedScreen.querySelectorAll(".masonry");
|
43
|
+
|
44
|
+
if (masonry.length > 0) {
|
45
|
+
masonry.forEach((m) => {
|
46
|
+
let stimulusController = this.application.getControllerForElementAndIdentifier(m, "masonry")
|
47
|
+
stimulusController.layout()
|
48
|
+
})
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
#showScreen(tab) {
|
53
|
+
const screenName = tab.dataset.tabsScreen
|
54
|
+
this.#addQueryParamToCurrentUrl(this.tabId, screenName)
|
55
|
+
this.#clearState();
|
56
|
+
|
57
|
+
tab.classList.add("active")
|
58
|
+
|
59
|
+
let screenTarget = this.screensTarget.querySelector(`[data-tabs-screen="${screenName}"]`);
|
60
|
+
if (screenTarget) {
|
61
|
+
screenTarget.classList.remove("hidden")
|
62
|
+
}
|
63
|
+
return screenTarget;
|
64
|
+
}
|
65
|
+
|
66
|
+
#addQueryParamToCurrentUrl(key, value) {
|
67
|
+
const url = new URL(window.location.href);
|
68
|
+
url.searchParams.set(key, value);
|
69
|
+
window.history.replaceState({}, '', url);
|
70
|
+
}
|
71
|
+
|
72
|
+
#clearState() {
|
73
|
+
this.tabTargets.forEach((tab) => {
|
74
|
+
tab.classList.remove("active");
|
75
|
+
})
|
76
|
+
|
77
|
+
this.screenTargets.forEach((screen) => {
|
78
|
+
screen.classList.add("hidden");
|
79
|
+
})
|
80
|
+
}
|
81
|
+
}
|