adva 0.2.4 → 0.3.0
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/adva.gemspec +0 -1
- data/app/assets/javascripts/adva_cms/table_tree.js +517 -0
- data/app/assets/javascripts/adva_cms.js +1 -1
- data/app/assets/stylesheets/adva_cms/admin/tooltip.scss +10 -0
- data/app/assets/stylesheets/adva_cms/admin.scss +1 -1
- data/app/controllers/admin/sections_controller.rb +1 -1
- data/lib/adva/version.rb +1 -1
- data/lib/adva.rb +0 -1
- metadata +4 -32
- data/app/assets/javascripts/adva_cms/jquery.table_tree.js +0 -704
- data/app/assets/stylesheets/adva_cms/jquery/alternate/jquery.tooltip.scss +0 -13
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_222222_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_2e83ff_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_454545_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_888888_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/jquery.tooltip.scss +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cf3ba6c659842798c42f6fd015bb0d54fad9dd565bb63fc323bc8c615369f4d
|
4
|
+
data.tar.gz: 0e0c7ada44b479f0dbb1ad5c66d893c499e58ec3943c799d9a83011838af9423
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a15cfe13315178e1c85398203a36a0123f4f9e722cec84945f8586ac70219f0273e191e057a28dcf14d197b1673f29595ed071ce045fee07c5774f6bb4bdd54
|
7
|
+
data.tar.gz: effc8e38738625656411470277a71032c3b5b549d34a785316d8edd7d9c4f3c342aef404bf26e7ae182fc92ed713e7b10d65bca8c11c8468999a60f727ef9070
|
data/adva.gemspec
CHANGED
@@ -0,0 +1,517 @@
|
|
1
|
+
document.addEventListener("DOMContentLoaded", () => {
|
2
|
+
const table = document.querySelector("table.list")
|
3
|
+
const link = document.querySelector("a.reorder")
|
4
|
+
if(table && link) new TableTree(table, link)
|
5
|
+
})
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Configuration options:
|
9
|
+
*
|
10
|
+
* onDragClass
|
11
|
+
* This class is added for the duration of the drag and then removed when the row is dropped. It is more
|
12
|
+
* flexible than using onDragStyle since it can be inherited by the row cells and other content. The default
|
13
|
+
* is class is tDnD_whileDrag. So to use the default, simply customise this CSS class in your
|
14
|
+
* stylesheet.
|
15
|
+
* onDrop
|
16
|
+
* Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table
|
17
|
+
* and the row that was dropped. You can work out the new order of the rows by using
|
18
|
+
* table.rows.
|
19
|
+
* onDragStart
|
20
|
+
* Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the
|
21
|
+
* table and the row which the user has started to drag.
|
22
|
+
* onAllowDrop
|
23
|
+
* Pass a function that will be called as a row is over another row. If the function returns true, allow
|
24
|
+
* dropping on that row, otherwise not. The function takes 2 parameters: the dragged row and the row under
|
25
|
+
* the cursor. It returns a boolean: true allows the drop, false doesn't allow it.
|
26
|
+
* scrollAmount
|
27
|
+
* This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the
|
28
|
+
* window. The page should automatically scroll up or down as appropriate.
|
29
|
+
*/
|
30
|
+
|
31
|
+
class TableDnD {
|
32
|
+
constructor() {
|
33
|
+
this.currentTable = null
|
34
|
+
this.dragObject = null
|
35
|
+
this.mouseOffset = null
|
36
|
+
this.oldY = 0
|
37
|
+
}
|
38
|
+
|
39
|
+
add(table, options) {
|
40
|
+
table.tableDnDConfig = {
|
41
|
+
// Add in the default class for whileDragging
|
42
|
+
onDragClass: "tDnD_whileDrag",
|
43
|
+
onDrop: null,
|
44
|
+
onDrag: null, // ADDED
|
45
|
+
onDragStart: null,
|
46
|
+
scrollAmount: 5,
|
47
|
+
...(options || {}),
|
48
|
+
}
|
49
|
+
this.makeDraggable(table)
|
50
|
+
}
|
51
|
+
|
52
|
+
makeDraggable(table) {
|
53
|
+
table.querySelectorAll("tr").forEach(row => {
|
54
|
+
row.addEventListener("mousedown", event => this.mousedown(table, row, event))
|
55
|
+
row.style.cursor = "move"
|
56
|
+
})
|
57
|
+
// Now we need to capture the mouse up and mouse move event
|
58
|
+
// We can use bind so that we don't interfere with other event handlers
|
59
|
+
document.addEventListener('mousemove', event => this.mousemove(event))
|
60
|
+
document.addEventListener('mouseup', event => this.mouseup(event))
|
61
|
+
}
|
62
|
+
|
63
|
+
mousedown(table, row, event) {
|
64
|
+
if(event.target.tagName == "TD") {
|
65
|
+
event.preventDefault()
|
66
|
+
this.dragObject = row
|
67
|
+
this.currentTable = table
|
68
|
+
this.mouseOffset = this.getMouseOffset(row, event)
|
69
|
+
let config = table.tableDnDConfig
|
70
|
+
if(config.onDragStart) config.onDragStart(table, row)
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
/** Given a target element and a mouse event, get the mouse offset from that element.
|
75
|
+
To do this we need the element's position and the mouse position */
|
76
|
+
getMouseOffset(target, event) {
|
77
|
+
var docPos = this.getPosition(target)
|
78
|
+
return {
|
79
|
+
x: event.pageX - docPos.x,
|
80
|
+
y: event.pageY - docPos.y,
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
getPosition(element) {
|
85
|
+
const rect = element.getBoundingClientRect()
|
86
|
+
return {
|
87
|
+
x: rect.left + window.pageXOffset,
|
88
|
+
y: rect.top + window.pageYOffset,
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
mousemove(event) {
|
93
|
+
if (this.dragObject == null) {
|
94
|
+
return
|
95
|
+
}
|
96
|
+
|
97
|
+
var config = this.currentTable.tableDnDConfig
|
98
|
+
var y = event.pageY - this.mouseOffset.y
|
99
|
+
var yOffset = window.pageYOffset
|
100
|
+
if (event.pageY - yOffset < config.scrollAmount) {
|
101
|
+
window.scrollBy(0, -config.scrollAmount)
|
102
|
+
} else if(window.innerHeight - (event.pageY-yOffset) < config.scrollAmount) {
|
103
|
+
window.scrollBy(0, config.scrollAmount)
|
104
|
+
}
|
105
|
+
|
106
|
+
if (y != this.oldY) {
|
107
|
+
// work out if we're going up or down...
|
108
|
+
var movingDown = y > this.oldY
|
109
|
+
this.oldY = y
|
110
|
+
this.dragObject.classList.add(config.onDragClass)
|
111
|
+
// If we're over a row then move the dragged row to there so that the user sees the
|
112
|
+
// effect dynamically
|
113
|
+
var currentRow = this.findDropTargetRow(this.dragObject, y, movingDown)
|
114
|
+
if(currentRow) {
|
115
|
+
if (movingDown && this.dragObject != currentRow) {
|
116
|
+
this.dragObject.parentNode.insertBefore(this.dragObject, currentRow.nextSibling)
|
117
|
+
} else if(!movingDown && this.dragObject != currentRow) {
|
118
|
+
this.dragObject.parentNode.insertBefore(this.dragObject, currentRow)
|
119
|
+
}
|
120
|
+
if(config.onDrag) {
|
121
|
+
config.onDrag(this.currentTable, this.dragObject)
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
return false
|
126
|
+
}
|
127
|
+
|
128
|
+
/** We're only worried about the y position really, because we can only move rows up and down */
|
129
|
+
findDropTargetRow(draggedRow, y, movingDown) {
|
130
|
+
const rows = Array.from(this.currentTable.querySelectorAll("tr"))
|
131
|
+
for (var i=0; i<rows.length; i++) {
|
132
|
+
var row = rows[i]
|
133
|
+
var rowY = this.getPosition(row).y
|
134
|
+
var rowHeight = parseInt(row.offsetHeight)/2
|
135
|
+
if (row.offsetHeight == 0) {
|
136
|
+
rowY = this.getPosition(row.firstChild).y
|
137
|
+
rowHeight = parseInt(row.firstChild.offsetHeight)/2
|
138
|
+
}
|
139
|
+
// Because we always have to insert before, we need to offset the height a bit
|
140
|
+
if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) {
|
141
|
+
// that's the row we're over
|
142
|
+
// If it's the same as the current row, ignore it
|
143
|
+
if(row == draggedRow) return
|
144
|
+
var config = this.currentTable.tableDnDConfig
|
145
|
+
if (config.onAllowDrop) {
|
146
|
+
if(!config.onAllowDrop(draggedRow, row, movingDown)) return
|
147
|
+
}
|
148
|
+
return row
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
mouseup(e) {
|
154
|
+
if(this.currentTable && this.dragObject) {
|
155
|
+
var droppedRow = this.dragObject
|
156
|
+
var config = this.currentTable.tableDnDConfig
|
157
|
+
// If we have a dragObject, then we need to release it,
|
158
|
+
// The row will already have been moved to the right place so we just reset stuff
|
159
|
+
droppedRow.classList.remove(config.onDragClass)
|
160
|
+
this.dragObject = null
|
161
|
+
if(config.onDrop) config.onDrop(this.currentTable, droppedRow)
|
162
|
+
this.currentTable = null; // let go of the table too
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
teardown(table) {
|
167
|
+
table.querySelectorAll("tr").forEach(row => {
|
168
|
+
row.removeEventListener("mousedown", event => this.mousedown(table, row, event))
|
169
|
+
row.style.cursor = "auto"
|
170
|
+
})
|
171
|
+
this.dragObject = null
|
172
|
+
this.currentTable = null
|
173
|
+
this.mouseOffset = null
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
class Base {
|
178
|
+
find_node(element) {
|
179
|
+
for (var i = 0; i < this.children.length; i++) {
|
180
|
+
var child = this.children[i]
|
181
|
+
if (this.children[i].element == element) {
|
182
|
+
return this.children[i]
|
183
|
+
} else {
|
184
|
+
var result = this.children[i].find_node(element)
|
185
|
+
if (result) return result
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
ttnode(node) {
|
191
|
+
var subject = node.push ? node[0] : node
|
192
|
+
return (this.current_table || this.table_tree.current_table).find_node(subject)
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
class TableTree extends Base {
|
197
|
+
constructor(table, link) {
|
198
|
+
super()
|
199
|
+
this.table = table
|
200
|
+
this.type = link.id.replace('reorder_', '')
|
201
|
+
this.collection_url = link.href
|
202
|
+
this.tableDnD = new TableDnD()
|
203
|
+
|
204
|
+
link.addEventListener("click", event => {
|
205
|
+
event.preventDefault()
|
206
|
+
link.parentElement.classList.toggle('active')
|
207
|
+
this.toggle()
|
208
|
+
})
|
209
|
+
|
210
|
+
this.tableDnDOptions = {
|
211
|
+
onDragClass: 'drag',
|
212
|
+
onDragStart: (table, row) => {
|
213
|
+
this.startOffset = this.tableDnD.mouseOffset.x
|
214
|
+
row.addEventListener("mousemove", event => this.mousemove(event))
|
215
|
+
this.ttnode(row)?.dragStart()
|
216
|
+
},
|
217
|
+
onDrag: (table, row) => {
|
218
|
+
this.current_table.dirty = true
|
219
|
+
this.ttnode(row)?.update_children()
|
220
|
+
},
|
221
|
+
onDrop: (table, row) => {
|
222
|
+
row.removeEventListener("mousemove", event => this.mousemove(event))
|
223
|
+
this.ttnode(row)?.drop()
|
224
|
+
this.current_table.rebuild()
|
225
|
+
this.current_table.update_remote(row)
|
226
|
+
},
|
227
|
+
onAllowDrop: (draggedRow, row, movingDown) => {
|
228
|
+
const node = this.ttnode(row)
|
229
|
+
const next = movingDown ? node.next_row_sibling() : node
|
230
|
+
if(next && next.parent && this.ttnode(draggedRow)) {
|
231
|
+
if(next.parent.level >= this.ttnode(draggedRow).level) return false
|
232
|
+
}
|
233
|
+
return node ? true : false
|
234
|
+
}
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
toggle() {
|
239
|
+
this.current_table ? this.teardown() : this.setup()
|
240
|
+
}
|
241
|
+
|
242
|
+
setup() {
|
243
|
+
const tbody = this.table.querySelector('tbody')
|
244
|
+
this.tableDnD.add(tbody, this.tableDnDOptions)
|
245
|
+
this.current_table = new Table(this, this.table, this.type, this.collection_url)
|
246
|
+
this.current_table.setSortable()
|
247
|
+
}
|
248
|
+
|
249
|
+
teardown() {
|
250
|
+
// this.current_table.update_remote()
|
251
|
+
this.tableDnD.teardown(this.table)
|
252
|
+
this.current_table.setUnsortable()
|
253
|
+
this.current_table = null
|
254
|
+
}
|
255
|
+
|
256
|
+
level(element) {
|
257
|
+
var match = element.className.match(/level_([\d]+)/)
|
258
|
+
return match ? parseInt(match[1]) : 0
|
259
|
+
}
|
260
|
+
|
261
|
+
mousemove(event) {
|
262
|
+
if (!this.current_table.is_tree) return
|
263
|
+
|
264
|
+
const element = event.target.closest("tr")
|
265
|
+
const offset = this.tableDnD.getMouseOffset(element, event).x - this.startOffset
|
266
|
+
if(offset > 25) {
|
267
|
+
this.current_table.dirty = true
|
268
|
+
this.ttnode(element).increment_level(event)
|
269
|
+
} else if(offset < -25) {
|
270
|
+
this.current_table.dirty = true
|
271
|
+
this.ttnode(element).decrement_level(event)
|
272
|
+
}
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
276
|
+
class Table extends Base {
|
277
|
+
constructor(table_tree, table, type, collection_url) {
|
278
|
+
super()
|
279
|
+
this.table_tree = table_tree
|
280
|
+
this.is_tree = table.classList.contains('tree')
|
281
|
+
this.table = table
|
282
|
+
this.type = type
|
283
|
+
this.level = -1
|
284
|
+
this.collection_url = collection_url
|
285
|
+
this.rebuild()
|
286
|
+
}
|
287
|
+
|
288
|
+
rebuild() {
|
289
|
+
this.trs = Array.from(this.table.querySelectorAll('tr'))
|
290
|
+
this.children = this.trs.map(tr => {
|
291
|
+
if(this.table_tree.level(tr) === 0) {
|
292
|
+
return new Node(this.table_tree, this, tr, this.table_tree.level(tr))
|
293
|
+
}
|
294
|
+
}).filter(e => e)
|
295
|
+
}
|
296
|
+
|
297
|
+
setSortable() {
|
298
|
+
this.trs.forEach(tr => {
|
299
|
+
// tr is in thead
|
300
|
+
let cells = tr.querySelectorAll('th')
|
301
|
+
cells.forEach((th, index) => {
|
302
|
+
if(index === 0) {
|
303
|
+
th.setAttribute('colspan', cells.length)
|
304
|
+
} else {
|
305
|
+
th.hidden = true
|
306
|
+
}
|
307
|
+
})
|
308
|
+
|
309
|
+
// tbody
|
310
|
+
cells = tr.querySelectorAll('td')
|
311
|
+
cells.forEach((td, index) => {
|
312
|
+
if (index === 0) {
|
313
|
+
td.setAttribute('colspan', cells.length)
|
314
|
+
td.querySelectorAll('a').forEach((a, index) => {
|
315
|
+
a.hidden = true
|
316
|
+
if (index === 0) {
|
317
|
+
td.appendChild(document.createTextNode(a.innerText))
|
318
|
+
}
|
319
|
+
})
|
320
|
+
} else {
|
321
|
+
td.hidden = true
|
322
|
+
}
|
323
|
+
})
|
324
|
+
})
|
325
|
+
}
|
326
|
+
|
327
|
+
setUnsortable() {
|
328
|
+
this.trs.forEach(tr => {
|
329
|
+
// tr is in thead
|
330
|
+
let cells = tr.querySelectorAll('th')
|
331
|
+
cells.forEach((th, index) => {
|
332
|
+
if(index === 0) {
|
333
|
+
this.setAttribute('colspan', 1)
|
334
|
+
} else {
|
335
|
+
th.hidden = false
|
336
|
+
}
|
337
|
+
})
|
338
|
+
|
339
|
+
// tbody
|
340
|
+
cells = tr.querySelectorAll('td')
|
341
|
+
cells.forEach((td, index) => {
|
342
|
+
if (index === 0) {
|
343
|
+
td.querySelectorAll('a').forEach((a, index) => {
|
344
|
+
a.hidden = false
|
345
|
+
if (index === 0) {
|
346
|
+
td.removeChild(td.lastChild)
|
347
|
+
}
|
348
|
+
})
|
349
|
+
td.querySelector('img.spinner')?.remove()
|
350
|
+
td.setAttribute('colspan', 1)
|
351
|
+
} else {
|
352
|
+
td.hidden = false
|
353
|
+
}
|
354
|
+
})
|
355
|
+
})
|
356
|
+
}
|
357
|
+
|
358
|
+
update_remote(row) {
|
359
|
+
if(!this.dirty) return
|
360
|
+
this.dirty = false
|
361
|
+
this.show_spinner(row)
|
362
|
+
|
363
|
+
fetch(this.collection_url, {
|
364
|
+
method: "PUT",
|
365
|
+
body: new URLSearchParams({
|
366
|
+
...this.serialize(row),
|
367
|
+
authenticity_token: window._auth_token,
|
368
|
+
}),
|
369
|
+
})
|
370
|
+
.then(() => this.hide_spinner(row))
|
371
|
+
.catch(() => this.hide_spinner(row))
|
372
|
+
}
|
373
|
+
|
374
|
+
serialize(row) {
|
375
|
+
row = this.ttnode(row)
|
376
|
+
let data = {}
|
377
|
+
data[`${this.type}[${row.id()}][parent_id]`] = row.parent_id()
|
378
|
+
data[`${this.type}[${row.id()}][left_id]`] = row.left_id()
|
379
|
+
return data
|
380
|
+
}
|
381
|
+
|
382
|
+
show_spinner(row) {
|
383
|
+
let img = document.createElement('img')
|
384
|
+
img.src = 'data:image/gif;base64,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'
|
385
|
+
img.className = 'spinner'
|
386
|
+
row.querySelector("td").appendChild(img)
|
387
|
+
}
|
388
|
+
|
389
|
+
hide_spinner(row) {
|
390
|
+
let cell = row.querySelector('td')
|
391
|
+
cell.removeChild(cell.lastChild)
|
392
|
+
}
|
393
|
+
}
|
394
|
+
|
395
|
+
class Node extends Base {
|
396
|
+
constructor(table_tree, parent, element, level) {
|
397
|
+
super()
|
398
|
+
this.table_tree = table_tree
|
399
|
+
this.parent = parent
|
400
|
+
this.element = element
|
401
|
+
this.level = level
|
402
|
+
|
403
|
+
this.children = this.find_children().map(child => {
|
404
|
+
var level = this.table_tree.level(child)
|
405
|
+
if(level == this.level + 1) {
|
406
|
+
return new Node(this.table_tree, this, child, level)
|
407
|
+
}
|
408
|
+
}).filter(e => e)
|
409
|
+
}
|
410
|
+
|
411
|
+
find_children() {
|
412
|
+
var stop = false
|
413
|
+
return this.row_siblings().slice(this.row_index() + 1).filter(child => {
|
414
|
+
var level = this.table_tree.level(child)
|
415
|
+
if(this.level == level) stop = true // how to break from an iterator?
|
416
|
+
return !stop && this.level + 1 == level
|
417
|
+
})
|
418
|
+
}
|
419
|
+
|
420
|
+
depth() {
|
421
|
+
if (this.children.length > 0) {
|
422
|
+
return Math.max.apply(Math, this.children.map(child => child.depth()))
|
423
|
+
} else {
|
424
|
+
return this.level
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
siblings() {
|
429
|
+
return this.parent.children
|
430
|
+
}
|
431
|
+
|
432
|
+
id() {
|
433
|
+
return this.element ? this.to_int(this.element.id) : 'null'
|
434
|
+
}
|
435
|
+
|
436
|
+
parent_id() {
|
437
|
+
return this.parent.element ? this.to_int(this.parent.element.id) : 'null'
|
438
|
+
}
|
439
|
+
|
440
|
+
left_id() {
|
441
|
+
let left = this.left()
|
442
|
+
return left ? this.to_int(left.element.id) : 'null'
|
443
|
+
}
|
444
|
+
|
445
|
+
left() {
|
446
|
+
let siblings = this.siblings()
|
447
|
+
let ix = siblings.indexOf(this) - 1
|
448
|
+
if(ix >= 0) return siblings[ix]
|
449
|
+
}
|
450
|
+
|
451
|
+
to_int(str) {
|
452
|
+
if(str) return str.replace(/[\D]+/, '')
|
453
|
+
}
|
454
|
+
|
455
|
+
next_row_sibling() {
|
456
|
+
return this.row_siblings()[this.row_index() + 1]
|
457
|
+
}
|
458
|
+
|
459
|
+
row_siblings() {
|
460
|
+
this._row_siblings ||= Array.from(this.element.parentElement.children)
|
461
|
+
return this._row_siblings
|
462
|
+
}
|
463
|
+
|
464
|
+
row_index() {
|
465
|
+
return this.row_siblings().indexOf(this.element)
|
466
|
+
}
|
467
|
+
|
468
|
+
dragStart() {
|
469
|
+
this.element.classList.add('drag')
|
470
|
+
this.children.forEach(child => child.dragStart())
|
471
|
+
}
|
472
|
+
|
473
|
+
drop() {
|
474
|
+
this.element.classList.remove('drag')
|
475
|
+
this.children.forEach(child => child.drop())
|
476
|
+
this.adjust_level()
|
477
|
+
}
|
478
|
+
|
479
|
+
increment_level(event) {
|
480
|
+
let prev = this.element.previousElementSibling
|
481
|
+
if(prev) prev = this.ttnode(prev)
|
482
|
+
if(!prev || prev.level < this.level || this.depth() >= 5) return
|
483
|
+
this.update_level(event, this.level + 1)
|
484
|
+
}
|
485
|
+
|
486
|
+
decrement_level(event) {
|
487
|
+
if(this.level == 0) return
|
488
|
+
this.update_level(event, this.level - 1)
|
489
|
+
}
|
490
|
+
|
491
|
+
update_level(event, level) {
|
492
|
+
if (event) this.table_tree.startOffset = this.table_tree.tableDnD.getMouseOffset(this.element, event).x
|
493
|
+
|
494
|
+
this.element.classList.remove('level_' + this.level)
|
495
|
+
this.element.classList.add('level_' + level)
|
496
|
+
|
497
|
+
this.level = level
|
498
|
+
this.children.forEach(child => child.update_level(event, level + 1))
|
499
|
+
}
|
500
|
+
|
501
|
+
adjust_level() {
|
502
|
+
var prev = this.element.previousElementSibling
|
503
|
+
if(!prev) {
|
504
|
+
this.update_level(null, 0)
|
505
|
+
} else if(this.ttnode(prev).level + 1 < this.level) {
|
506
|
+
this.update_level(null, this.ttnode(prev).level + 1)
|
507
|
+
}
|
508
|
+
}
|
509
|
+
|
510
|
+
update_children() {
|
511
|
+
this.children.forEach(child => child.element.parentNode.removeChild(child.element))
|
512
|
+
var next = this.element.nextSibling
|
513
|
+
this.children.forEach(child => this.element.parentNode.insertBefore(child.element, next))
|
514
|
+
this.children.forEach(child => child.update_children())
|
515
|
+
}
|
516
|
+
}
|
517
|
+
|
@@ -11,5 +11,5 @@
|
|
11
11
|
//= require "adva_cms/admin/helptip.css"
|
12
12
|
//= require "adva_cms/admin/users.css"
|
13
13
|
//= require "adva_cms/admin/activities.css"
|
14
|
-
//= require "adva_cms/
|
14
|
+
//= require "adva_cms/admin/tooltip.css"
|
15
15
|
//= require "adva_cms/admin/projection.css"
|
@@ -52,7 +52,7 @@ class Admin::SectionsController < Admin::BaseController
|
|
52
52
|
parent = Section.find_by(id: attrs[:parent_id])
|
53
53
|
left = Section.find_by_id attrs[:left_id]
|
54
54
|
if parent
|
55
|
-
|
55
|
+
section.move_to_child_with_index parent, 0
|
56
56
|
else
|
57
57
|
section.move_to_root
|
58
58
|
section.move_to_left_of section.siblings.first
|
data/lib/adva/version.rb
CHANGED
data/lib/adva.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adva
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Geisel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: will_paginate
|
@@ -122,20 +122,6 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: jquery-rails
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :runtime
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
125
|
description: Adva CMS
|
140
126
|
email:
|
141
127
|
- micah@botandrose.com
|
@@ -255,7 +241,7 @@ files:
|
|
255
241
|
- app/assets/javascripts/adva_cms.js
|
256
242
|
- app/assets/javascripts/adva_cms/ckeditor.js.erb
|
257
243
|
- app/assets/javascripts/adva_cms/concat_main_menus.js
|
258
|
-
- app/assets/javascripts/adva_cms/
|
244
|
+
- app/assets/javascripts/adva_cms/table_tree.js
|
259
245
|
- app/assets/javascripts/ckeditor/config.js.erb
|
260
246
|
- app/assets/stylesheets/admin.scss
|
261
247
|
- app/assets/stylesheets/adva_cms/admin.scss
|
@@ -279,26 +265,12 @@ files:
|
|
279
265
|
- app/assets/stylesheets/adva_cms/admin/screen/top.scss
|
280
266
|
- app/assets/stylesheets/adva_cms/admin/sidebar.scss
|
281
267
|
- app/assets/stylesheets/adva_cms/admin/themes.scss
|
268
|
+
- app/assets/stylesheets/adva_cms/admin/tooltip.scss
|
282
269
|
- app/assets/stylesheets/adva_cms/admin/top.scss
|
283
270
|
- app/assets/stylesheets/adva_cms/admin/users.scss
|
284
271
|
- app/assets/stylesheets/adva_cms/common.scss
|
285
272
|
- app/assets/stylesheets/adva_cms/default.scss
|
286
273
|
- app/assets/stylesheets/adva_cms/forms.scss
|
287
|
-
- app/assets/stylesheets/adva_cms/jquery/alternate/jquery.tooltip.scss
|
288
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png
|
289
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_75_ffffff_40x100.png
|
290
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png
|
291
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_65_ffffff_1x400.png
|
292
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_dadada_1x400.png
|
293
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png
|
294
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_95_fef1ec_1x400.png
|
295
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png
|
296
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-icons_222222_256x240.png
|
297
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-icons_2e83ff_256x240.png
|
298
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-icons_454545_256x240.png
|
299
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-icons_888888_256x240.png
|
300
|
-
- app/assets/stylesheets/adva_cms/jquery/images/ui-icons_cd0a0a_256x240.png
|
301
|
-
- app/assets/stylesheets/adva_cms/jquery/jquery.tooltip.scss
|
302
274
|
- app/assets/stylesheets/adva_cms/layout/login.scss
|
303
275
|
- app/assets/stylesheets/adva_cms/layout/simple.scss
|
304
276
|
- app/assets/stylesheets/adva_cms/menu.scss
|