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.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/adva.gemspec +0 -1
  3. data/app/assets/javascripts/adva_cms/table_tree.js +517 -0
  4. data/app/assets/javascripts/adva_cms.js +1 -1
  5. data/app/assets/stylesheets/adva_cms/admin/tooltip.scss +10 -0
  6. data/app/assets/stylesheets/adva_cms/admin.scss +1 -1
  7. data/app/controllers/admin/sections_controller.rb +1 -1
  8. data/lib/adva/version.rb +1 -1
  9. data/lib/adva.rb +0 -1
  10. metadata +4 -32
  11. data/app/assets/javascripts/adva_cms/jquery.table_tree.js +0 -704
  12. data/app/assets/stylesheets/adva_cms/jquery/alternate/jquery.tooltip.scss +0 -13
  13. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  14. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  15. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  16. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  17. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  18. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  19. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  20. data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  21. data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_222222_256x240.png +0 -0
  22. data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_2e83ff_256x240.png +0 -0
  23. data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_454545_256x240.png +0 -0
  24. data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_888888_256x240.png +0 -0
  25. data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_cd0a0a_256x240.png +0 -0
  26. 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: a0e7e2c699ec74ef78dc82a987aee784782e4ebd541a13eb5d315eed394fa88f
4
- data.tar.gz: baec20dd5bb548f0696b26935872d7b547746608f3957a98ac5e92f1530b4b25
3
+ metadata.gz: 7cf3ba6c659842798c42f6fd015bb0d54fad9dd565bb63fc323bc8c615369f4d
4
+ data.tar.gz: 0e0c7ada44b479f0dbb1ad5c66d893c499e58ec3943c799d9a83011838af9423
5
5
  SHA512:
6
- metadata.gz: 0ac4c3e3fc9bfccc631127c95ec7c5d8d393a3223ca068390b30cea6e5578403988a1d9d6bda81f2920588ba796a2210540c7a6ad2bf053cf241750f07715408
7
- data.tar.gz: 2558c1c926dfaba6acdaf51d877ae90cd89b698e0d62ff0a3e37a1c66f8cd672458d990673d4f8cecde597ec25e73f0a54285f533f0b18debdc64bbac04803d5
6
+ metadata.gz: 7a15cfe13315178e1c85398203a36a0123f4f9e722cec84945f8586ac70219f0273e191e057a28dcf14d197b1673f29595ed071ce045fee07c5774f6bb4bdd54
7
+ data.tar.gz: effc8e38738625656411470277a71032c3b5b549d34a785316d8edd7d9c4f3c342aef404bf26e7ae182fc92ed713e7b10d65bca8c11c8468999a60f727ef9070
data/adva.gemspec CHANGED
@@ -23,6 +23,5 @@ Gem::Specification.new do |gem|
23
23
  gem.add_dependency "friendly_id", "~> 5.1.0" # 5.2.0 tries to call #slug= on invalid save
24
24
  gem.add_dependency "actionpack-page_caching"
25
25
  gem.add_dependency "rails-observers"
26
- gem.add_dependency "jquery-rails"
27
26
  end
28
27
 
@@ -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
+
@@ -2,6 +2,6 @@
2
2
 
3
3
  //= require adva_cms/concat_main_menus
4
4
  //= require adva_cms/ckeditor
5
- //= require adva_cms/jquery.table_tree
5
+ //= require adva_cms/table_tree
6
6
 
7
7
 
@@ -0,0 +1,10 @@
1
+ .hint.enabled {
2
+ background: image_url('/assets/adva_cms/icons/help.png') no-repeat;
3
+ display: inline-block;
4
+ margin-left: 5px;
5
+ margin-bottom: -3px;
6
+ width: 16px;
7
+ height: 16px;
8
+ text-indent: 16px;
9
+ overflow: hidden;
10
+ }
@@ -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/jquery/jquery.tooltip.css"
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
- content.move_to_child_with_index parent, 0
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
@@ -1,3 +1,3 @@
1
1
  module Adva
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/adva.rb CHANGED
@@ -3,7 +3,6 @@ require "will_paginate"
3
3
  require "awesome_nested_set"
4
4
  require "actionpack/page_caching"
5
5
  require "rails-observers"
6
- require "jquery-rails"
7
6
 
8
7
  require "rails_ext"
9
8
 
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.2.4
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-04 00:00:00.000000000 Z
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/jquery.table_tree.js
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