adva 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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