aerogel-admin 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +13 -0
- data/Rakefile +1 -0
- data/aerogel-admin.gemspec +31 -0
- data/app/helpers/admin.rb +54 -0
- data/app/helpers/decorators.rb +29 -0
- data/app/helpers/icons.rb +11 -0
- data/app/helpers/table_builder.rb +8 -0
- data/app/helpers/tabs_builder.rb +7 -0
- data/app/routes/admin.rb +37 -0
- data/app/routes/users.rb +71 -0
- data/app/routes/users_access.rb +54 -0
- data/app/routes/users_roles.rb +53 -0
- data/assets/fonts/aerogel-icons.css +28 -0
- data/assets/fonts/aerogel-icons.eot +0 -0
- data/assets/fonts/aerogel-icons.svg +11 -0
- data/assets/fonts/aerogel-icons.ttf +0 -0
- data/assets/fonts/aerogel-icons.woff +0 -0
- data/assets/javascripts/.gitkeep +0 -0
- data/assets/javascripts/controllers/admin-modal.js.coffee +7 -0
- data/assets/javascripts/controllers/admin-modal/admin-modal-form-buttons.js.coffee +56 -0
- data/assets/javascripts/controllers/admin.js.coffee +13 -0
- data/assets/javascripts/controllers/admin/selectize-inputs.js.coffee +7 -0
- data/assets/javascripts/controllers/admin/top-menu-shadow.js.coffee +9 -0
- data/assets/javascripts/utils/ajax-spinner.js.coffee +26 -0
- data/assets/javascripts/utils/ajax-watcher.js.coffee +18 -0
- data/assets/javascripts/utils/bootstrap-modal-reload.js.coffee +8 -0
- data/assets/javascripts/utils/form-data-async.js.coffee +27 -0
- data/assets/javascripts/utils/i18n.js.coffee +27 -0
- data/assets/javascripts/utils/on-future-elements.js.coffee +15 -0
- data/assets/stylesheets/admin/bootstrap-settings.css.scss +33 -0
- data/assets/stylesheets/admin/global.css.scss +61 -0
- data/assets/stylesheets/admin/styles/ajax-indicator.css.scss +26 -0
- data/assets/stylesheets/admin/styles/bootstrap-modal.css.scss +24 -0
- data/assets/stylesheets/admin/styles/language-selector.css.scss +5 -0
- data/assets/stylesheets/admin/styles/page-header.css.scss +7 -0
- data/assets/stylesheets/admin/styles/sticky-footer-navbar.css.scss +34 -0
- data/assets/stylesheets/admin/styles/table.css.scss +3 -0
- data/assets/stylesheets/admin/styles/top-menu.css.scss +3 -0
- data/assets/stylesheets/admin/utils/center-absolutely.css.scss +5 -0
- data/assets/stylesheets/controllers/admin.css.scss +14 -0
- data/assets/vendor/bootstrap-datetimepicker.css.scss +1 -0
- data/assets/vendor/bootstrap-datetimepicker.js.coffee +1 -0
- data/assets/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css +5 -0
- data/assets/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js +1 -0
- data/assets/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.ru.js +163 -0
- data/assets/vendor/moment.js.coffee +1 -0
- data/assets/vendor/momentjs/moment-with-langs.min.js +9 -0
- data/assets/vendor/selectize.css.scss +2 -0
- data/assets/vendor/selectize.js.coffee +1 -0
- data/assets/vendor/selectize/selectize.bootstrap3.css +385 -0
- data/assets/vendor/selectize/selectize.css +311 -0
- data/assets/vendor/selectize/selectize.default.css +381 -0
- data/assets/vendor/selectize/selectize.js +3345 -0
- data/assets/vendor/smart-list-table.css.scss +42 -0
- data/assets/vendor/smart-list-table.js.coffee +1 -0
- data/assets/vendor/smart-list-table/smart-list-table-row.js.coffee +63 -0
- data/assets/vendor/smart-list-table/smart-list-table.css.scss +54 -0
- data/assets/vendor/smart-list-table/smart-list-table.js.coffee +133 -0
- data/assets/vendor/smart-tree-table.css.scss +42 -0
- data/assets/vendor/smart-tree-table.js.coffee +1 -0
- data/assets/vendor/smart-tree-table/smart-tree-table-drag-n-drop.js.coffee +190 -0
- data/assets/vendor/smart-tree-table/smart-tree-table-row.js.coffee +78 -0
- data/assets/vendor/smart-tree-table/smart-tree-table.css.scss +54 -0
- data/assets/vendor/smart-tree-table/smart-tree-table.js.coffee +267 -0
- data/assets/vendor/spin.js +353 -0
- data/config/README.md +3 -0
- data/config/development/.keep +0 -0
- data/config/production/.keep +0 -0
- data/db/model/README.md +1 -0
- data/db/model/admin/user_new_form.rb +40 -0
- data/db/model/user.rb +26 -0
- data/db/seed/01_admin_roles.seed +8 -0
- data/db/seed/02_admin_access.seed +24 -0
- data/db/seed/development/.keep +0 -0
- data/db/seed/development/20_users.seed +45 -0
- data/db/seed/development/admin_users.seed +38 -0
- data/db/seed/production/.keep +0 -0
- data/lib/aerogel/admin.rb +25 -0
- data/lib/aerogel/admin/core.rb +14 -0
- data/lib/aerogel/admin/menu.rb +38 -0
- data/lib/aerogel/admin/table_builder.rb +100 -0
- data/lib/aerogel/admin/tabs_builder.rb +69 -0
- data/lib/aerogel/admin/version.rb +5 -0
- data/locales/actions.en.yml +27 -0
- data/locales/actions.ru.yml +28 -0
- data/locales/admin.en.yml +14 -0
- data/locales/admin.ru.yml +14 -0
- data/locales/models.en.yml +8 -0
- data/locales/models.ru.yml +8 -0
- data/locales/views.en.yml +46 -0
- data/locales/views.ru.yml +46 -0
- data/public/README.md +1 -0
- data/rake/README.md +3 -0
- data/views/admin/index.html.erb +3 -0
- data/views/admin/table_builder/standard/_table_column.html.erb +3 -0
- data/views/admin/table_builder/standard/_table_row.html.erb +7 -0
- data/views/admin/table_builder/standard/table.html.erb +10 -0
- data/views/admin/tabs_builder/standard/_tab.html.erb +3 -0
- data/views/admin/tabs_builder/standard/tabs.html.erb +3 -0
- data/views/admin/users/_tabs.html.erb +8 -0
- data/views/admin/users/access/delete.html.erb +12 -0
- data/views/admin/users/access/edit.html.erb +9 -0
- data/views/admin/users/access/index.html.erb +23 -0
- data/views/admin/users/access/new.html.erb +9 -0
- data/views/admin/users/delete.html.erb +12 -0
- data/views/admin/users/edit.html.erb +46 -0
- data/views/admin/users/index.html.erb +31 -0
- data/views/admin/users/new.html.erb +11 -0
- data/views/admin/users/roles/delete.html.erb +12 -0
- data/views/admin/users/roles/edit.html.erb +9 -0
- data/views/admin/users/roles/index.html.erb +21 -0
- data/views/admin/users/roles/new.html.erb +7 -0
- data/views/form_builder/standard/field_multiselect.erb +14 -0
- data/views/form_builder/standard/field_select.erb +17 -0
- data/views/layouts/admin.html.erb +63 -0
- data/views/layouts/admin/_ajax_indicator.html.erb +4 -0
- data/views/layouts/admin/_alerts.html.erb +22 -0
- data/views/layouts/admin/_menu.html.erb +50 -0
- data/views/layouts/admin/_menu_item.html.erb +5 -0
- data/views/layouts/admin/_modals.html.erb +8 -0
- data/views/layouts/admin/modal.html.erb +38 -0
- metadata +280 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
// set parameters here
|
2
|
+
// ...
|
3
|
+
// $stt-selected-bg = ...
|
4
|
+
// $stt-selected-fg = ...
|
5
|
+
|
6
|
+
$stt-hover-fg: #000 !default;
|
7
|
+
$stt-hover-bg: #eee !default;
|
8
|
+
$stt-hover-cursor: pointer !default;
|
9
|
+
|
10
|
+
$stt-selected-fg: inherit !default;
|
11
|
+
$stt-selected-bg: #5e96de !default;
|
12
|
+
|
13
|
+
$stt-drag-helper-bg: #fff !default;
|
14
|
+
$stt-drag-helper-fg: #000 !default;
|
15
|
+
$stt-drag-helper-shadow: 5px 5px 5px #777 !default;
|
16
|
+
$stt-drag-helper-border: 1px solid #ccc !default;
|
17
|
+
$stt-drag-helper-zindex: 100 !default;
|
18
|
+
|
19
|
+
$stt-drag-over-bg: #eee !default;
|
20
|
+
$stt-drag-over-fg: inherit !default;
|
21
|
+
|
22
|
+
$stt-drag-source-bg: #e9e9e9 !default;
|
23
|
+
$stt-drag-source-fg: inherit !default;
|
24
|
+
|
25
|
+
$stt-drop-target-overlay-border-width: 3px !default;
|
26
|
+
$stt-drop-target-overlay-border-color: black !default;
|
27
|
+
$stt-drop-target-overlay-border-style: solid !default;
|
28
|
+
|
29
|
+
$stt-drop-target-overlay-before-border-style: $stt-drop-target-overlay-border-style none none none !default;
|
30
|
+
$stt-drop-target-overlay-before-border-width: $stt-drop-target-overlay-border-width !default;
|
31
|
+
$stt-drop-target-overlay-before-border-color: $stt-drop-target-overlay-border-color !default;
|
32
|
+
|
33
|
+
$stt-drop-target-overlay-into-border-style: $stt-drop-target-overlay-border-style !default;
|
34
|
+
$stt-drop-target-overlay-into-border-width: $stt-drop-target-overlay-border-width !default;
|
35
|
+
$stt-drop-target-overlay-into-border-color: $stt-drop-target-overlay-border-color !default;
|
36
|
+
|
37
|
+
$stt-drop-target-overlay-after-border-style: none none $stt-drop-target-overlay-border-style none !default;
|
38
|
+
$stt-drop-target-overlay-after-border-width: $stt-drop-target-overlay-border-width !default;
|
39
|
+
$stt-drop-target-overlay-after-border-color: $stt-drop-target-overlay-border-color !default;
|
40
|
+
|
41
|
+
|
42
|
+
@import "smart-list-table/smart-list-table";
|
@@ -0,0 +1 @@
|
|
1
|
+
#= require ./smart-list-table/smart-list-table
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
Function::property = (name) ->
|
3
|
+
Object.defineProperty @prototype, name,
|
4
|
+
get: -> @get_property name
|
5
|
+
set: (v) -> @set_property name, v
|
6
|
+
|
7
|
+
# An object representing tree table row.
|
8
|
+
#
|
9
|
+
#
|
10
|
+
class @SmartListTableRow
|
11
|
+
|
12
|
+
constructor: (@table, @el) ->
|
13
|
+
@id = @el.attr 'data-id'
|
14
|
+
@contents = @active_column().html()
|
15
|
+
@attributes = {}
|
16
|
+
for attr in @el.get(0).attributes
|
17
|
+
@attributes[attr.name] = attr.value
|
18
|
+
@_properties = {}
|
19
|
+
|
20
|
+
|
21
|
+
active_column: ->
|
22
|
+
@el.find(@table.settings.active_column_selector).first()
|
23
|
+
|
24
|
+
render: ->
|
25
|
+
@el.removeClass "#{@table.settings.selectedClass}"
|
26
|
+
@el.addClass @table.settings.selectedClass if @get_property 'selected'
|
27
|
+
# @active_column().html( "#{@_prefix()}#{@contents}")
|
28
|
+
|
29
|
+
show: ->
|
30
|
+
@el.show()
|
31
|
+
|
32
|
+
hide: ->
|
33
|
+
@el.hide()
|
34
|
+
|
35
|
+
get_property: (name) ->
|
36
|
+
@_properties[name]
|
37
|
+
set_property: (name, v) ->
|
38
|
+
@_properties[name] = v
|
39
|
+
@render()
|
40
|
+
v
|
41
|
+
|
42
|
+
@property 'selected'
|
43
|
+
# @property 'other_prop1'
|
44
|
+
|
45
|
+
|
46
|
+
_indenter: (level) ->
|
47
|
+
px = level * @table.settings.indent
|
48
|
+
"<span class='indenter' style='padding-left:#{px}px'></span>"
|
49
|
+
|
50
|
+
_prefix: ->
|
51
|
+
p_indent = @_indenter @get_property 'level'
|
52
|
+
p_prefix = ''
|
53
|
+
s = {}
|
54
|
+
if @get_property 'branch'
|
55
|
+
s = @table.settings.prefix.branch
|
56
|
+
else
|
57
|
+
s = @table.settings.prefix.leaf
|
58
|
+
if @get_property 'expanded'
|
59
|
+
p_prefix = s.expanded
|
60
|
+
else
|
61
|
+
p_prefix = s.collapsed
|
62
|
+
"#{p_indent}#{p_prefix}"
|
63
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
.smart-list-table tbody {
|
3
|
+
|
4
|
+
tr:hover {
|
5
|
+
background: $stt-hover-bg;
|
6
|
+
color: $stt-hover-fg;
|
7
|
+
cursor: $stt-hover-cursor;
|
8
|
+
}
|
9
|
+
tr.selected {
|
10
|
+
background: $stt-selected-bg;
|
11
|
+
color: $stt-selected-fg;
|
12
|
+
}
|
13
|
+
|
14
|
+
tr td span.indenter {
|
15
|
+
display: inline-block;
|
16
|
+
// margin: 0;
|
17
|
+
}
|
18
|
+
|
19
|
+
tr.drag-helper {
|
20
|
+
background: $stt-drag-helper-bg;
|
21
|
+
box-shadow: $stt-drag-helper-shadow;
|
22
|
+
border: $stt-drag-helper-border;
|
23
|
+
z-index: $stt-drag-helper-zindex;
|
24
|
+
}
|
25
|
+
|
26
|
+
tr.drag-over {
|
27
|
+
background: $stt-drag-over-bg;
|
28
|
+
color: $stt-drag-over-fg;
|
29
|
+
}
|
30
|
+
|
31
|
+
tr.drag-source {
|
32
|
+
background: $stt-drag-source-bg;
|
33
|
+
color: $stt-drag-source-fg;
|
34
|
+
}
|
35
|
+
|
36
|
+
.drop-target-overlay {
|
37
|
+
// border: 1px solid green;
|
38
|
+
}
|
39
|
+
.drop-target-overlay.before {
|
40
|
+
border-style: $stt-drop-target-overlay-before-border-style;
|
41
|
+
border-width: $stt-drop-target-overlay-before-border-width;
|
42
|
+
border-color: $stt-drop-target-overlay-before-border-color;
|
43
|
+
}
|
44
|
+
.drop-target-overlay.into {
|
45
|
+
border-style: $stt-drop-target-overlay-into-border-style;
|
46
|
+
border-width: $stt-drop-target-overlay-into-border-width;
|
47
|
+
border-color: $stt-drop-target-overlay-into-border-color;
|
48
|
+
}
|
49
|
+
.drop-target-overlay.after {
|
50
|
+
border-style: $stt-drop-target-overlay-after-border-style;
|
51
|
+
border-width: $stt-drop-target-overlay-after-border-width;
|
52
|
+
border-color: $stt-drop-target-overlay-after-border-color;
|
53
|
+
}
|
54
|
+
}
|
@@ -0,0 +1,133 @@
|
|
1
|
+
#= require ./smart-list-table-row
|
2
|
+
#
|
3
|
+
debug = false
|
4
|
+
log = (msg) ->
|
5
|
+
console?.log "** smart-list-table: #{msg}" if debug
|
6
|
+
error = (msg) ->
|
7
|
+
console?.error "** smart-list-table: #{msg}" if debug
|
8
|
+
throw new Error msg
|
9
|
+
|
10
|
+
class @SmartListTable
|
11
|
+
|
12
|
+
# Default settings
|
13
|
+
@_default_settings:
|
14
|
+
column: 1
|
15
|
+
addClass: 'smart-list-table'
|
16
|
+
selectedClass: "selected"
|
17
|
+
hoverClass: null # or class to add on mouseenter/mouseleave
|
18
|
+
dragAndDrop:
|
19
|
+
enabled: false
|
20
|
+
handle: null # or selector to drag-n-drop handle
|
21
|
+
helper: null # or function returning helper element
|
22
|
+
helperClass: 'drag-helper'
|
23
|
+
helperOpacity: 0.85
|
24
|
+
dragOverClass: 'drag-over'
|
25
|
+
dragSourceClass: 'drag-source'
|
26
|
+
dropTarget:
|
27
|
+
beforePx: 7
|
28
|
+
afterPx: 10
|
29
|
+
overlay:
|
30
|
+
class: "drop-target-overlay"
|
31
|
+
before: '' # contents for 'before' insert mode
|
32
|
+
into: '' # contents for 'into' insert mode
|
33
|
+
after: '' # contents for 'after' insert mode
|
34
|
+
debug: false
|
35
|
+
on_select: null
|
36
|
+
|
37
|
+
# Creates a SmartTreeTable object using an HTML table specified by +el+ selector.
|
38
|
+
#
|
39
|
+
constructor: (el, options = {}) ->
|
40
|
+
unless $(el).length > 0
|
41
|
+
error "No matching elements specified by selector '#{el}'"
|
42
|
+
@settings = $.extend true, SmartListTable._default_settings, options
|
43
|
+
@settings.active_column_selector = "td:nth-child(#{@settings.column})"
|
44
|
+
@table = $(el).first()
|
45
|
+
@table.addClass @settings.addClass if @settings.addClass?
|
46
|
+
@init_table_rows()
|
47
|
+
@bind_event_listeners()
|
48
|
+
@selected_row = null
|
49
|
+
@drag_and_drop = null
|
50
|
+
$(el).disableSelection()
|
51
|
+
# SmartListTable object ready
|
52
|
+
#
|
53
|
+
# @enable_drag_and_drop() if @settings.dragAndDrop.enabled
|
54
|
+
log "created SmartListTable: #{el}"
|
55
|
+
|
56
|
+
|
57
|
+
#
|
58
|
+
# private methods
|
59
|
+
#
|
60
|
+
|
61
|
+
# Returns SmartListTable rows as list.
|
62
|
+
#
|
63
|
+
table_html_rows: ->
|
64
|
+
@table.find('tbody tr')
|
65
|
+
|
66
|
+
# Returns table row ids as list.
|
67
|
+
#
|
68
|
+
table_html_row_ids: ->
|
69
|
+
@id_of(row) for row in @table_html_rows()
|
70
|
+
|
71
|
+
# Returns Rows as list, ordered as the table.
|
72
|
+
#
|
73
|
+
rows_list: ->
|
74
|
+
@rows[id] for id in @table_html_row_ids()
|
75
|
+
|
76
|
+
# Returns +id+ of a given row HTML element.
|
77
|
+
#
|
78
|
+
id_of: (el) ->
|
79
|
+
$(el).attr 'data-id'
|
80
|
+
|
81
|
+
# initializes table rows
|
82
|
+
#
|
83
|
+
init_table_rows: ->
|
84
|
+
@rows = {}
|
85
|
+
for row in @table_html_rows()
|
86
|
+
row_obj = new SmartListTableRow @, $(row)
|
87
|
+
row_obj.expanded = true
|
88
|
+
@rows[row_obj.id] = row_obj
|
89
|
+
|
90
|
+
@update_table_rows()
|
91
|
+
#for row in @rows_list()
|
92
|
+
# @collapse row.id
|
93
|
+
# log "row: #{row.id} -> #{row.parent_id} (level:#{row.level}): #{row.contents}"
|
94
|
+
|
95
|
+
|
96
|
+
# Updates table rows.
|
97
|
+
# Sets level, branch/leaf properties.
|
98
|
+
#
|
99
|
+
update_table_rows: ->
|
100
|
+
# nothing
|
101
|
+
|
102
|
+
|
103
|
+
# Selects row with +id+.
|
104
|
+
#
|
105
|
+
select: (id, process_callbacks = true ) ->
|
106
|
+
@selected_row.selected = false if @selected_row?
|
107
|
+
@selected_row = null
|
108
|
+
@selected_row = @rows[id] if id?
|
109
|
+
@selected_row.selected = true if @selected_row?
|
110
|
+
# if parent is collapsed, expand all until first expanded ancestor
|
111
|
+
|
112
|
+
if @settings.on_select? && process_callbacks
|
113
|
+
selected_id = if @selected_row? then @selected_row.id else null
|
114
|
+
selected_el = if @selected_row? then @selected_row.el else null
|
115
|
+
@settings.on_select selected_id, @selected_row, selected_el
|
116
|
+
|
117
|
+
|
118
|
+
# Binds event listeners on rows.
|
119
|
+
#
|
120
|
+
bind_event_listeners: ->
|
121
|
+
@table.find('tbody').on 'click', 'tr', (e) =>
|
122
|
+
id = @id_of $(e.currentTarget)
|
123
|
+
@select id
|
124
|
+
|
125
|
+
if @settings.hoverClass?
|
126
|
+
@table.find('tbody').on 'mouseenter', 'tr', (e) =>
|
127
|
+
$(e.currentTarget).addClass @settings.hoverClass
|
128
|
+
@table.find('tbody').on 'mouseleave', 'tr', (e) =>
|
129
|
+
$(e.currentTarget).removeClass @settings.hoverClass
|
130
|
+
|
131
|
+
|
132
|
+
$ ->
|
133
|
+
log "initialized"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
// set parameters here
|
2
|
+
// ...
|
3
|
+
// $stt-selected-bg = ...
|
4
|
+
// $stt-selected-fg = ...
|
5
|
+
|
6
|
+
$stt-hover-fg: #000 !default;
|
7
|
+
$stt-hover-bg: #eee !default;
|
8
|
+
$stt-hover-cursor: pointer !default;
|
9
|
+
|
10
|
+
$stt-selected-fg: inherit !default;
|
11
|
+
$stt-selected-bg: #5e96de !default;
|
12
|
+
|
13
|
+
$stt-drag-helper-bg: #fff !default;
|
14
|
+
$stt-drag-helper-fg: #000 !default;
|
15
|
+
$stt-drag-helper-shadow: 5px 5px 5px #777 !default;
|
16
|
+
$stt-drag-helper-border: 1px solid #ccc !default;
|
17
|
+
$stt-drag-helper-zindex: 100 !default;
|
18
|
+
|
19
|
+
$stt-drag-over-bg: #eee !default;
|
20
|
+
$stt-drag-over-fg: inherit !default;
|
21
|
+
|
22
|
+
$stt-drag-source-bg: #e9e9e9 !default;
|
23
|
+
$stt-drag-source-fg: inherit !default;
|
24
|
+
|
25
|
+
$stt-drop-target-overlay-border-width: 3px !default;
|
26
|
+
$stt-drop-target-overlay-border-color: black !default;
|
27
|
+
$stt-drop-target-overlay-border-style: solid !default;
|
28
|
+
|
29
|
+
$stt-drop-target-overlay-before-border-style: $stt-drop-target-overlay-border-style none none none !default;
|
30
|
+
$stt-drop-target-overlay-before-border-width: $stt-drop-target-overlay-border-width !default;
|
31
|
+
$stt-drop-target-overlay-before-border-color: $stt-drop-target-overlay-border-color !default;
|
32
|
+
|
33
|
+
$stt-drop-target-overlay-into-border-style: $stt-drop-target-overlay-border-style !default;
|
34
|
+
$stt-drop-target-overlay-into-border-width: $stt-drop-target-overlay-border-width !default;
|
35
|
+
$stt-drop-target-overlay-into-border-color: $stt-drop-target-overlay-border-color !default;
|
36
|
+
|
37
|
+
$stt-drop-target-overlay-after-border-style: none none $stt-drop-target-overlay-border-style none !default;
|
38
|
+
$stt-drop-target-overlay-after-border-width: $stt-drop-target-overlay-border-width !default;
|
39
|
+
$stt-drop-target-overlay-after-border-color: $stt-drop-target-overlay-border-color !default;
|
40
|
+
|
41
|
+
|
42
|
+
@import "smart-tree-table/smart-tree-table";
|
@@ -0,0 +1 @@
|
|
1
|
+
#= require ./smart-tree-table/smart-tree-table
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# Enables drag-and-drop functionality on passed SmartTreeTable
|
2
|
+
#
|
3
|
+
debug = false
|
4
|
+
log = (msg) ->
|
5
|
+
console?.log "** smart-tree-table-drag-n-drop: #{msg}" if debug
|
6
|
+
error = (msg) ->
|
7
|
+
console?.error "** smart-tree-table-drag-n-drop: #{msg}" if debug
|
8
|
+
throw new Error msg
|
9
|
+
|
10
|
+
|
11
|
+
class @SmartTreeTableDragAndDrop
|
12
|
+
|
13
|
+
constructor: (@table) ->
|
14
|
+
@settings = @table.settings.dragAndDrop
|
15
|
+
@reset()
|
16
|
+
@bind_draggables()
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
# Resets inner structures.
|
21
|
+
#
|
22
|
+
reset: ->
|
23
|
+
@helper = null
|
24
|
+
@drag_over_row = null
|
25
|
+
@drop_target = {}
|
26
|
+
@drop_target_overlay = null
|
27
|
+
@drag_start_row = null
|
28
|
+
|
29
|
+
|
30
|
+
bind_draggables: ->
|
31
|
+
draggable_options =
|
32
|
+
addClasses: false
|
33
|
+
appendTo: @table.table
|
34
|
+
helper: ( @settings.helper || @create_drag_and_drop_helper )
|
35
|
+
opacity: @settings.helperOpacity
|
36
|
+
|
37
|
+
start: (e, ui) =>
|
38
|
+
if @settings.handle
|
39
|
+
id = @table.id_of $(e.currentTarget).closest 'tr'
|
40
|
+
else
|
41
|
+
id = @table.id_of $(e.currentTarget)
|
42
|
+
@on_drag_start id
|
43
|
+
|
44
|
+
stop: =>
|
45
|
+
@on_drag_stop()
|
46
|
+
|
47
|
+
drag: (e, ui) =>
|
48
|
+
center_y = ui.helper.position().top + ui.helper.height()/2;
|
49
|
+
@on_drag_evaluate center_y
|
50
|
+
|
51
|
+
if @settings.handle?
|
52
|
+
@table.table_html_rows().find(@settings.handle).draggable draggable_options
|
53
|
+
else
|
54
|
+
@table.table_html_rows().draggable draggable_options
|
55
|
+
log "enabled, handle: #{if @settings.handle? then @settings.handle else 'all rows'}"
|
56
|
+
|
57
|
+
# Callback to be invoked on drag start.
|
58
|
+
#
|
59
|
+
on_drag_start: (id) ->
|
60
|
+
@drag_start_row = @table.rows[id]
|
61
|
+
@table.select null
|
62
|
+
@table.collapse id
|
63
|
+
@drag_start_row.el.addClass @settings.dragSourceClass if @settings.dragSourceClass
|
64
|
+
# validate drop targets
|
65
|
+
@create_drop_target_overlay()
|
66
|
+
log "started row #{id}"
|
67
|
+
|
68
|
+
# Callback to be invoked on drag finish.
|
69
|
+
#
|
70
|
+
on_drag_stop: ->
|
71
|
+
@destroy_drop_target_overlay()
|
72
|
+
@drag_over_row.el.removeClass @settings.dragOverClass if @drag_over_row?
|
73
|
+
@drag_start_row.el.removeClass @settings.dragSourceClass if @settings.dragSourceClass
|
74
|
+
if @drop_target.id? && @drop_target.insert_mode != 'outside'
|
75
|
+
@table.move_tree_node @drag_start_row.id, @drop_target.id, @drop_target.insert_mode
|
76
|
+
log "finished: #{@drop_target.insert_mode}:#{@drop_target.id}"
|
77
|
+
else
|
78
|
+
log "finished outside of valid targets"
|
79
|
+
@reset()
|
80
|
+
|
81
|
+
|
82
|
+
# Callback to be invoked on each drag movement.
|
83
|
+
# +y+ is the center position of the draggable helper.
|
84
|
+
#
|
85
|
+
on_drag_evaluate: (y) ->
|
86
|
+
drag_over_table = false
|
87
|
+
for id, row of @table.rows
|
88
|
+
row_top = row.el.position().top
|
89
|
+
row_bottom = row_top + row.el.height()
|
90
|
+
if row_top < y && row_bottom > y
|
91
|
+
drag_over_table = true
|
92
|
+
@on_drag_over row, y-row_top, row_bottom-y
|
93
|
+
@on_drag_over null, 0, 0 unless drag_over_table
|
94
|
+
|
95
|
+
|
96
|
+
# Callback to be invoked on drag over table row,
|
97
|
+
# +row+ is Row object or null if helper is dragged outside of the table
|
98
|
+
# +before_px+ is the distance from row top to helper's +y+
|
99
|
+
# +after_px+ is the distance from row bottom to helper's +y+
|
100
|
+
#
|
101
|
+
on_drag_over: (row, before_px, after_px) ->
|
102
|
+
@drag_over_row.el.removeClass @settings.dragOverClass if @drag_over_row?
|
103
|
+
@drag_over_row = row
|
104
|
+
@drop_target = {}
|
105
|
+
unless row?
|
106
|
+
@hide_drop_target_overlay()
|
107
|
+
return
|
108
|
+
@drag_over_row.el.addClass @settings.dragOverClass
|
109
|
+
unless @drag_start_row.id == row.id
|
110
|
+
@drop_target.id = row.id
|
111
|
+
@drop_target.row = row
|
112
|
+
if before_px < @settings.dropTarget.beforePx
|
113
|
+
@drop_target.insert_mode = 'before'
|
114
|
+
else if after_px < @settings.dropTarget.afterPx
|
115
|
+
@drop_target.insert_mode = 'after'
|
116
|
+
else
|
117
|
+
@drop_target.insert_mode = 'into'
|
118
|
+
@update_drop_target_overlay row, @drop_target.insert_mode
|
119
|
+
|
120
|
+
#
|
121
|
+
#
|
122
|
+
create_drag_and_drop_helper: (e) =>
|
123
|
+
src = null
|
124
|
+
if @settings.handle?
|
125
|
+
src = $(e.currentTarget).closest 'tr'
|
126
|
+
else
|
127
|
+
src = $(e.currentTarget)
|
128
|
+
helper = src.clone()
|
129
|
+
helper.children().each (i) ->
|
130
|
+
$(@).width src.children().eq(i).width()
|
131
|
+
helper.width src.width()
|
132
|
+
helper.height src.height()
|
133
|
+
helper.addClass @settings.helperClass
|
134
|
+
helper.removeClass "selected"
|
135
|
+
log "helper created"
|
136
|
+
helper
|
137
|
+
|
138
|
+
# Create drop target overlay
|
139
|
+
#
|
140
|
+
create_drop_target_overlay: ->
|
141
|
+
@drop_target_overlay = $( '<div>', { class: @settings.dropTarget.overlay.class } )
|
142
|
+
@drop_target_overlay.css 'position', 'absolute'
|
143
|
+
# @drop_target_overlay.css 'z-index', 100
|
144
|
+
@table.table.find('tbody').append @drop_target_overlay
|
145
|
+
@drop_target_overlay.text( "overlay created" )
|
146
|
+
|
147
|
+
|
148
|
+
# Destroy drag target overlay
|
149
|
+
#
|
150
|
+
destroy_drop_target_overlay: ->
|
151
|
+
@drop_target_overlay.remove() if @drop_target_overlay?
|
152
|
+
|
153
|
+
# Hides drag_target_overlay
|
154
|
+
#
|
155
|
+
hide_drop_target_overlay: ->
|
156
|
+
@drop_target_overlay.hide() if @drop_target_overlay?
|
157
|
+
|
158
|
+
# Shows drop_target_overlay
|
159
|
+
#
|
160
|
+
show_drop_target_overlay: ->
|
161
|
+
@drop_target_overlay.show() if @drop_target_overlay?
|
162
|
+
|
163
|
+
# Updates drag target overlay.
|
164
|
+
#
|
165
|
+
update_drop_target_overlay: (row, insert_mode = 'outside' ) ->
|
166
|
+
@show_drop_target_overlay()
|
167
|
+
@drop_target_overlay.html ''
|
168
|
+
if insert_mode == 'before'
|
169
|
+
@drop_target_overlay.html @settings.dropTarget.overlay.before
|
170
|
+
if insert_mode == 'into'
|
171
|
+
@drop_target_overlay.html @settings.dropTarget.overlay.into
|
172
|
+
if insert_mode == 'after'
|
173
|
+
@drop_target_overlay.html @settings.dropTarget.overlay.after
|
174
|
+
el_top = row.el.position().top
|
175
|
+
el_left = row.el.position().left
|
176
|
+
el_height = row.el.height()
|
177
|
+
el_width = row.el.width()
|
178
|
+
@drop_target_overlay.removeClass "before into after outside"
|
179
|
+
@drop_target_overlay.addClass insert_mode
|
180
|
+
@drop_target_overlay.css(
|
181
|
+
top: el_top
|
182
|
+
left: el_left
|
183
|
+
height: el_height
|
184
|
+
width: el_width
|
185
|
+
)
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
|
190
|
+
|