mini_tree 0.0.4 → 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 +6 -8
- data/app/javascript/controllers/tree_controller.js +38 -46
- data/app/views/mini_trees/_index.html.erb +12 -2
- data/app/views/mini_trees/_index.html.erb.bak +45 -0
- data/app/views/mini_trees/_item.html.erb +4 -4
- data/lib/mini_tree/utils.rb +14 -7
- data/lib/mini_tree/version.rb +3 -1
- data/lib/mini_tree/version.rb.bak +3 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 26a99772164b7332c0f3f41e6c546bb54169d22ebe6cbc1b0948b859b72afd13
|
|
4
|
+
data.tar.gz: ba98b4540ee1473d84801c3384b20ed08c7b1ea6054699f7765dce0999f644e6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ed1aa746b44b269c9b70341363127fc1670a80672eed0c73e3e2ce48a05c4f75a6ba6378ca9b6df5c6634b3bcfe5349e574ed48d0efe0a23e57058e0097e799
|
|
7
|
+
data.tar.gz: e8bbf9cf71eb303c2388d52e436632568e2907c5334cf3696edcfb9bb96229b8256efaf80b66394de15143d0aea6eb2e74534afeddd618f9ef3e5a9d1a34b835
|
data/README.md
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# UNDER CONSTRUCTION
|
|
2
|
-
|
|
3
1
|
# MiniTree
|
|
4
2
|
|
|
5
3
|
[](https://rubygems.org/gems/mini_tree)
|
|
@@ -65,9 +63,9 @@ end
|
|
|
65
63
|
|
|
66
64
|
You may specify your view of an item in the treeview:
|
|
67
65
|
~~~Ruby
|
|
68
|
-
# ./app/views/
|
|
66
|
+
# ./app/views/application/_mini_tree_title.html.erb
|
|
69
67
|
# id and legend are defined
|
|
70
|
-
<%= link_to "action", edit_<model>(id:)
|
|
68
|
+
<%= link_to "action", edit_<model>(id:) %>
|
|
71
69
|
<%= legend %>
|
|
72
70
|
~~~
|
|
73
71
|
|
|
@@ -75,9 +73,9 @@ You may specify your view of an item in the treeview:
|
|
|
75
73
|
|
|
76
74
|
~~~Ruby
|
|
77
75
|
<Model>Tree.refresh
|
|
78
|
-
<Model>Tree.refresh_item(<id>, <legend>)
|
|
79
76
|
<Model>Tree.create_item(<id>, <legend>)
|
|
80
|
-
<Model>Tree.
|
|
77
|
+
<Model>Tree.destroy_item(<id>)
|
|
78
|
+
<Model>Tree.update_item(<id>, <legend>)
|
|
81
79
|
~~~
|
|
82
80
|
|
|
83
81
|
## Usage
|
|
@@ -103,7 +101,7 @@ gem "mini_tree"
|
|
|
103
101
|
and run "bundle install".
|
|
104
102
|
|
|
105
103
|
Furthermore, copy manually *app/javascript/controllers/tree_controller.js*
|
|
106
|
-
from the _gem
|
|
104
|
+
from the _gem mini_tree_
|
|
107
105
|
into your own _app/javascript/controllers/_ directory.
|
|
108
106
|
|
|
109
107
|
|
|
@@ -112,7 +110,7 @@ into your own _app/javascript/controllers/_ directory.
|
|
|
112
110
|
This software has been developed and tested with:
|
|
113
111
|
- Ubuntu 24.04
|
|
114
112
|
- Ruby 3.4.7
|
|
115
|
-
- Rails 8.1.
|
|
113
|
+
- Rails 8.1.1
|
|
116
114
|
|
|
117
115
|
See also:
|
|
118
116
|
- ./.github/workflows/rake.yml
|
|
@@ -5,8 +5,8 @@ export default class extends Controller {
|
|
|
5
5
|
static values = {owner: String}
|
|
6
6
|
|
|
7
7
|
connect() {
|
|
8
|
-
this.expanded = "\
|
|
9
|
-
this.collapsed = "\
|
|
8
|
+
this.expanded = "\u25BC" // down triangle
|
|
9
|
+
this.collapsed = "\u25bA" // right triangle
|
|
10
10
|
this.itemTargets.forEach(item => this.attach(item))
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -20,7 +20,6 @@ export default class extends Controller {
|
|
|
20
20
|
dragStart(e, el) {
|
|
21
21
|
e.stopPropagation()
|
|
22
22
|
|
|
23
|
-
// ev.dataTransfer.setData("text/plain", "")
|
|
24
23
|
this.dragged = el
|
|
25
24
|
e.dataTransfer.effectAllowed = "move"
|
|
26
25
|
el.classList.add("dragging")
|
|
@@ -30,10 +29,35 @@ export default class extends Controller {
|
|
|
30
29
|
e.stopPropagation()
|
|
31
30
|
this.dragged.classList.remove("dragging")
|
|
32
31
|
this.dragged = null
|
|
32
|
+
this.removeTraversed()
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
dragOver(e, el) {
|
|
36
36
|
e.preventDefault()
|
|
37
|
+
e.stopPropagation()
|
|
38
|
+
this.removeTraversed()
|
|
39
|
+
|
|
40
|
+
const title = el.querySelector("span.title")
|
|
41
|
+
if (this.topPart(e, el)) {
|
|
42
|
+
title.classList.add("topline")
|
|
43
|
+
} else {
|
|
44
|
+
title.classList.add("bottomline")
|
|
45
|
+
}
|
|
46
|
+
this.traversed = title
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
removeTraversed() {
|
|
50
|
+
if (!this.traversed) { return }
|
|
51
|
+
|
|
52
|
+
this.traversed.classList.remove("topline")
|
|
53
|
+
this.traversed.classList.remove("bottomline")
|
|
54
|
+
this.traversed = null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
topPart(event, elem) {
|
|
58
|
+
const rect = elem.getBoundingClientRect()
|
|
59
|
+
const offset = event.clientY - rect.top
|
|
60
|
+
return offset < (rect.height / 3) * 2
|
|
37
61
|
}
|
|
38
62
|
|
|
39
63
|
drop(e) {
|
|
@@ -60,11 +84,7 @@ export default class extends Controller {
|
|
|
60
84
|
}
|
|
61
85
|
}
|
|
62
86
|
|
|
63
|
-
const
|
|
64
|
-
const offset = e.clientY - rect.top
|
|
65
|
-
const threshold = (rect.height / 3) * 2
|
|
66
|
-
|
|
67
|
-
const target2 = (offset > threshold) ? target.nextSibling : target
|
|
87
|
+
const target2 = this.topPart(e, target) ? target : target.nextSibling
|
|
68
88
|
target.parentNode.insertBefore(dragged, target2)
|
|
69
89
|
}
|
|
70
90
|
|
|
@@ -94,8 +114,10 @@ export default class extends Controller {
|
|
|
94
114
|
|
|
95
115
|
toNode(elem) {
|
|
96
116
|
var row = elem.firstElementChild
|
|
97
|
-
const newRow = this.create("
|
|
98
|
-
|
|
117
|
+
const newRow = this.create("a", {className: "toggle-btn",
|
|
118
|
+
textContent: this.expanded})
|
|
119
|
+
// type: "button", textContent: this.expanded})
|
|
120
|
+
newRow.dataset.action = "click->tree#toggle"
|
|
99
121
|
|
|
100
122
|
this.removeUl(elem)
|
|
101
123
|
const ulRow2 = this.create("ul", {className: "nested"})
|
|
@@ -212,41 +234,11 @@ export default class extends Controller {
|
|
|
212
234
|
}
|
|
213
235
|
}
|
|
214
236
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
//console.log("over")
|
|
219
|
-
// e.preventDefault()
|
|
220
|
-
// if (this.dragged === el) return
|
|
221
|
-
// const rect = el.getBoundingClientRect()
|
|
222
|
-
// const offset = e.clientY - rect.top
|
|
223
|
-
// const third = rect.height / 3
|
|
224
|
-
//
|
|
225
|
-
// if (offset < third) {
|
|
226
|
-
// el.parentNode.insertBefore(this.placeholder, el)
|
|
227
|
-
// } else if (offset > 2 * third) {
|
|
228
|
-
// el.parentNode.insertBefore(this.placeholder, el.nextSibling)
|
|
229
|
-
// } else {
|
|
230
|
-
// let ul = el.querySelector(".nested")
|
|
231
|
-
// if (!ul) {
|
|
232
|
-
// ul = document.createElement("ul")
|
|
233
|
-
// ul.className = "nested"
|
|
234
|
-
// el.appendChild(ul)
|
|
235
|
-
// }
|
|
236
|
-
// ul.classList.remove("hidden")
|
|
237
|
-
// ul.appendChild(this.placeholder)
|
|
238
|
-
// }
|
|
239
|
-
// }
|
|
240
|
-
//
|
|
241
|
-
// removePlaceholder() {
|
|
242
|
-
// this.placeholder?.remove()
|
|
243
|
-
// }
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
// // rails javascript no jquery no sortablejs use stimulus sortable treeview
|
|
247
|
-
// // expand collapse support
|
|
248
|
-
// // nested reordering
|
|
237
|
+
// rails javascript no jquery no sortablejs use stimulus sortable treeview
|
|
238
|
+
// expand collapse support
|
|
239
|
+
// nested reordering
|
|
249
240
|
//
|
|
250
241
|
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
242
|
+
// https://wiki.selfhtml.org/wiki/JavaScript/Drag_%26_Drop
|
|
243
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API
|
|
244
|
+
// simple rails 8 program with two javascript classes
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
<style>
|
|
2
2
|
.mini-tree {
|
|
3
|
-
xbackground: yellow;
|
|
4
3
|
.mini-tree-view, .nested {
|
|
5
4
|
list-style: none;
|
|
5
|
+
}
|
|
6
|
+
span.title.topline {
|
|
7
|
+
border-top: solid 2px red;
|
|
8
|
+
border-top: solid 1px red;
|
|
9
|
+
}
|
|
10
|
+
span.title.bottomline {
|
|
11
|
+
border-bottom: solid 2px red;
|
|
12
|
+
border-bottom: solid 1px red;
|
|
13
|
+
}
|
|
14
|
+
.nested {
|
|
6
15
|
padding-left: 1rem;
|
|
7
16
|
}
|
|
8
17
|
.tree-row {
|
|
@@ -11,7 +20,7 @@
|
|
|
11
20
|
}
|
|
12
21
|
.toggle-btn {
|
|
13
22
|
background: transparent;
|
|
14
|
-
|
|
23
|
+
cursor: pointer;
|
|
15
24
|
}
|
|
16
25
|
.dragging { opacity: 0.5; }
|
|
17
26
|
.hidden { display: none; }
|
|
@@ -25,6 +34,7 @@
|
|
|
25
34
|
owner = list.first.class.name[0..-5]
|
|
26
35
|
%>
|
|
27
36
|
<div class="mini-tree" data-item-id="0"
|
|
37
|
+
data-turbo-prefetch="false"
|
|
28
38
|
data-controller="tree" data-tree-owner-value="<%= owner %>">
|
|
29
39
|
<ul class="mini-tree-view" data-tree-target="top">
|
|
30
40
|
<%= render partial: "mini_trees/item",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.mini-tree {
|
|
3
|
+
.mini-tree-view, .nested {
|
|
4
|
+
list-style: none;
|
|
5
|
+
xpadding-left: 1rem;
|
|
6
|
+
}
|
|
7
|
+
span.title.topline {
|
|
8
|
+
border-top: solid 2px red;
|
|
9
|
+
border-top: solid 1px red;
|
|
10
|
+
}
|
|
11
|
+
span.title.bottomline {
|
|
12
|
+
border-bottom: solid 2px red;
|
|
13
|
+
border-bottom: solid 1px red;
|
|
14
|
+
}
|
|
15
|
+
.nested {
|
|
16
|
+
padding-left: 1rem;
|
|
17
|
+
}
|
|
18
|
+
.tree-row {
|
|
19
|
+
display: flex;
|
|
20
|
+
gap: 0.5rem;
|
|
21
|
+
}
|
|
22
|
+
.toggle-btn {
|
|
23
|
+
background: transparent;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
}
|
|
26
|
+
.dragging { opacity: 0.5; }
|
|
27
|
+
.hidden { display: none; }
|
|
28
|
+
.toggle-btn, .toggle-space { width: 1rem; }
|
|
29
|
+
.tree-row:hover { background: rgba(0,0,0,0.05); }
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
32
|
+
|
|
33
|
+
<%
|
|
34
|
+
list = locals[:list]
|
|
35
|
+
owner = list.first.class.name[0..-5]
|
|
36
|
+
%>
|
|
37
|
+
<div class="mini-tree" data-item-id="0"
|
|
38
|
+
data-turbo-prefetch="false"
|
|
39
|
+
data-controller="tree" data-tree-owner-value="<%= owner %>">
|
|
40
|
+
<ul class="mini-tree-view" data-tree-target="top">
|
|
41
|
+
<%= render partial: "mini_trees/item",
|
|
42
|
+
collection: list.where(parent_id: 0).order(:position)
|
|
43
|
+
%>
|
|
44
|
+
</ul>
|
|
45
|
+
</div>
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<%
|
|
2
|
-
icon = (item.collapsed ? "\
|
|
2
|
+
icon = (item.collapsed ? "\u25ba" : "\u25bc").html_safe
|
|
3
3
|
klass = item.collapsed ? "nested hidden" : "nested"
|
|
4
4
|
%>
|
|
5
5
|
|
|
6
6
|
<li class="tree-item" data-tree-target="item"
|
|
7
7
|
data-item-id="<%= item.id %>" draggable="true">
|
|
8
|
-
<div class="tree-row"
|
|
8
|
+
<div class="tree-row">
|
|
9
9
|
<% if item.kind == "node" %>
|
|
10
|
-
<
|
|
10
|
+
<a class="toggle-btn" type="button"
|
|
11
|
+
data-action="click->tree#toggle"> <%= icon %> </a>
|
|
11
12
|
<% else %>
|
|
12
13
|
<span class="toggle-space"></span>
|
|
13
14
|
<% end %>
|
|
@@ -23,5 +24,4 @@
|
|
|
23
24
|
<%= render partial: "mini_trees/item", collection: item.children %>
|
|
24
25
|
</ul>
|
|
25
26
|
<% end %>
|
|
26
|
-
|
|
27
27
|
</li>
|
data/lib/mini_tree/utils.rb
CHANGED
|
@@ -24,28 +24,35 @@ module MiniTree::Utils
|
|
|
24
24
|
missing_cnt += 1
|
|
25
25
|
}
|
|
26
26
|
(ids - owner_ids).each { |id|
|
|
27
|
-
|
|
27
|
+
destroy_item(id)
|
|
28
28
|
delete_cnt += 1
|
|
29
29
|
}
|
|
30
30
|
(owner_ids & ids).each { |id|
|
|
31
|
-
|
|
31
|
+
update_item(id, owner_class.find_by(id:).legend)
|
|
32
32
|
refresh_cnt += 1
|
|
33
33
|
}
|
|
34
34
|
[missing_cnt, delete_cnt, refresh_cnt]
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def refresh_item(id, legend)
|
|
38
|
-
find_by(id:).update!(legend:)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
37
|
def create_item(id, legend)
|
|
42
38
|
create! id:, legend:, parent_id: 0, position: id, kind: "leaf"
|
|
43
39
|
end
|
|
44
40
|
|
|
45
|
-
def
|
|
41
|
+
def destroy_item(id)
|
|
46
42
|
where(id:).delete_all
|
|
47
43
|
end
|
|
48
44
|
|
|
45
|
+
def update_item(id, legend)
|
|
46
|
+
find_by(id:).update!(legend:)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ancestors(id)
|
|
50
|
+
parent_id = find(id).parent_id
|
|
51
|
+
return [id] if parent_id == 0
|
|
52
|
+
|
|
53
|
+
ancestors(parent_id) << id
|
|
54
|
+
end
|
|
55
|
+
|
|
49
56
|
# used by tests
|
|
50
57
|
def flat
|
|
51
58
|
res = []
|
data/lib/mini_tree/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mini_tree
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dittmar Krall
|
|
@@ -99,6 +99,7 @@ files:
|
|
|
99
99
|
- app/javascript/controllers/tree_controller.js
|
|
100
100
|
- app/views/application/_mini_tree_title.html.erb
|
|
101
101
|
- app/views/mini_trees/_index.html.erb
|
|
102
|
+
- app/views/mini_trees/_index.html.erb.bak
|
|
102
103
|
- app/views/mini_trees/_item.html.erb
|
|
103
104
|
- config/routes.rb
|
|
104
105
|
- lib/mini_tree.rb
|
|
@@ -115,7 +116,7 @@ require_paths:
|
|
|
115
116
|
- lib
|
|
116
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
118
|
requirements:
|
|
118
|
-
- - "
|
|
119
|
+
- - ">"
|
|
119
120
|
- !ruby/object:Gem::Version
|
|
120
121
|
version: '3'
|
|
121
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|