engine2 1.0.3 → 1.0.4
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/Rakefile +3 -117
- data/{views → app}/app.coffee +0 -0
- data/{public/css → app}/app.css +203 -196
- data/{views → app}/engine2.coffee +111 -60
- data/{views → app}/engine2actions.coffee +47 -28
- data/bower.json +13 -0
- data/conf/message.yaml +2 -1
- data/conf/message_pl.yaml +2 -1
- data/config.coffee +62 -0
- data/engine2.gemspec +2 -5
- data/lib/engine2.rb +1 -1
- data/lib/engine2/action.rb +9 -24
- data/lib/engine2/core.rb +9 -8
- data/lib/engine2/handler.rb +1 -5
- data/lib/engine2/meta.rb +61 -24
- data/lib/engine2/meta/array_meta.rb +82 -0
- data/lib/engine2/meta/decode_meta.rb +1 -1
- data/lib/engine2/meta/infra_meta.rb +21 -26
- data/lib/engine2/meta/list_meta.rb +2 -3
- data/lib/engine2/model.rb +5 -5
- data/lib/engine2/pre_bootstrap.rb +9 -1
- data/lib/engine2/scheme.rb +4 -0
- data/lib/engine2/type_info.rb +8 -1
- data/lib/engine2/version.rb +1 -1
- data/package.json +38 -0
- data/public/img/ajax-loader.gif +0 -0
- data/views/fields/blob.slim +4 -5
- data/views/fields/bs_select.slim +2 -2
- data/views/fields/bsselect_picker.slim +1 -2
- data/views/fields/bsselect_picker_opt.slim +1 -2
- data/views/fields/checkbox.slim +1 -1
- data/views/fields/checkbox_buttons.slim +1 -1
- data/views/fields/checkbox_buttons_opt.slim +1 -1
- data/views/fields/currency.slim +2 -2
- data/views/fields/date.slim +0 -1
- data/views/fields/date_range.slim +0 -1
- data/views/fields/date_time.slim +0 -1
- data/views/fields/datetime.slim +0 -2
- data/views/fields/decimal.slim +0 -1
- data/views/fields/decimal_date.slim +0 -1
- data/views/fields/decimal_time.slim +0 -1
- data/views/fields/email.slim +1 -2
- data/views/fields/file_store.slim +1 -1
- data/views/fields/input_text.slim +1 -2
- data/views/fields/integer.slim +1 -1
- data/views/fields/list_bsselect.slim +1 -2
- data/views/fields/list_bsselect_opt.slim +2 -3
- data/views/fields/list_buttons.slim +1 -1
- data/views/fields/list_buttons_opt.slim +1 -1
- data/views/fields/list_select.slim +1 -2
- data/views/fields/list_select_opt.slim +2 -3
- data/views/fields/password.slim +1 -2
- data/views/fields/radio_checkbox.slim +1 -1
- data/views/fields/scaffold.slim +1 -1
- data/views/fields/scaffold_picker.slim +1 -2
- data/views/fields/select_picker.slim +1 -2
- data/views/fields/select_picker_opt.slim +1 -2
- data/views/fields/text_area.slim +0 -1
- data/views/fields/time.slim +0 -1
- data/views/fields/typeahead_picker.slim +1 -2
- data/views/index.slim +4 -8
- data/views/scaffold/fields.slim +4 -4
- data/views/scaffold/form.slim +1 -7
- data/views/scaffold/form_collapse.slim +19 -0
- data/views/scaffold/form_tabs.slim +9 -0
- data/views/scaffold/list.slim +1 -12
- data/views/scaffold/search.slim +2 -9
- data/views/scaffold/search_collapse.slim +26 -0
- data/views/scaffold/search_tabs.slim +15 -0
- data/views/scaffold/view.slim +5 -15
- data/views/scaffold/view_collapse.slim +22 -0
- data/views/scaffold/view_tabs.slim +11 -0
- data/views/search_fields/bsmselect_picker.slim +1 -2
- data/views/search_fields/bsselect_picker.slim +1 -2
- data/views/search_fields/checkbox.slim +3 -3
- data/views/search_fields/checkbox2.slim +5 -5
- data/views/search_fields/checkbox_buttons.slim +2 -2
- data/views/search_fields/date_range.slim +0 -2
- data/views/search_fields/decimal_date_range.slim +5 -5
- data/views/search_fields/input_text.slim +2 -2
- data/views/search_fields/integer.slim +1 -1
- data/views/search_fields/integer_range.slim +2 -2
- data/views/search_fields/list_bsmselect.slim +1 -1
- data/views/search_fields/list_bsselect.slim +0 -1
- data/views/search_fields/list_buttons.slim +2 -2
- data/views/search_fields/list_select.slim +1 -2
- data/views/search_fields/scaffold_picker.slim +1 -2
- data/views/search_fields/select_picker.slim +1 -2
- data/views/search_fields/typeahead_picker.slim +1 -2
- metadata +29 -103
- data/public/assets/javascripts.js +0 -13
- data/public/assets/styles.css +0 -4
- data/public/css/angular-motion.css +0 -1022
- data/public/css/angular-ui-tree.min.css +0 -1
- data/public/css/bootstrap-additions.css +0 -1560
- data/public/css/bootstrap.min.css +0 -11
- data/public/css/font-awesome.min.css +0 -4
- data/public/fonts/FontAwesome.otf +0 -0
- data/public/fonts/fontawesome-webfont.eot +0 -0
- data/public/fonts/fontawesome-webfont.svg +0 -655
- data/public/fonts/fontawesome-webfont.ttf +0 -0
- data/public/fonts/fontawesome-webfont.woff +0 -0
- data/public/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/public/fonts/glyphicons-halflings-regular.svg +0 -288
- data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/public/images/file.png +0 -0
- data/public/images/folder-closed.png +0 -0
- data/public/images/folder.png +0 -0
- data/public/images/node-closed-2.png +0 -0
- data/public/images/node-closed-light.png +0 -0
- data/public/images/node-closed.png +0 -0
- data/public/images/node-opened-2.png +0 -0
- data/public/images/node-opened-light.png +0 -0
- data/public/images/node-opened.png +0 -0
- data/public/img/ajax-loader-light.gif +0 -0
- data/public/js/angular-animate.js +0 -4147
- data/public/js/angular-cookies.js +0 -322
- data/public/js/angular-local-storage.js +0 -455
- data/public/js/angular-route.js +0 -1025
- data/public/js/angular-sanitize.js +0 -717
- data/public/js/angular-strap.js +0 -4339
- data/public/js/angular-strap.tpl.js +0 -43
- data/public/js/angular-ui-tree.js +0 -1569
- data/public/js/angular.js +0 -30868
- data/public/js/i18n/angular-locale_pl.js +0 -115
- data/public/js/lodash.custom.min.js +0 -99
- data/public/js/ng-file-upload-shim.min.js +0 -2
- data/public/js/ng-file-upload.min.js +0 -3
- data/views/engine2templates.coffee +0 -0
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
require 'angular-route'
|
|
3
|
+
require 'angular-sanitize'
|
|
4
|
+
require 'angular-animate'
|
|
5
|
+
require 'angular-cookies'
|
|
6
|
+
require 'angular-local-storage'
|
|
7
|
+
require 'angular-ui-tree'
|
|
8
|
+
require 'ng-file-upload'
|
|
9
|
+
|
|
2
10
|
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
|
3
11
|
|
|
4
12
|
angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'mgcrea.ngStrap', 'ngFileUpload', 'ui.tree', 'LocalStorageModule']) # 'draggabilly'
|
|
5
|
-
.factory 'E2Snippets', ->
|
|
6
|
-
icon = (name) -> "<span class='glyphicon glyphicon-#{name}'></span>"
|
|
7
|
-
aicon = (name) -> "<i class='fa fa-#{name}'></i>"
|
|
8
|
-
ng_class_names = ['active', 'enabled', 'disabled']
|
|
9
|
-
icon: icon
|
|
10
|
-
aicon: aicon
|
|
11
|
-
boolean_true_value: icon('check')
|
|
12
|
-
boolean_false_value: icon('unchecked')
|
|
13
|
-
make_ng_class: (o) ->
|
|
14
|
-
out = []
|
|
15
|
-
_.each ng_class_names, (e) -> out.push(if e == 'enabled' then "'disabled': !(#{o[e]})" else "'#{e}': #{o[e]}") if o[e]?
|
|
16
|
-
if out.length > 0 then "ng-class=\"{#{out.join(',')}}\"" else ""
|
|
17
|
-
|
|
18
13
|
.config ($httpProvider, $routeProvider, $compileProvider, localStorageServiceProvider, $logProvider) ->
|
|
19
14
|
loaderOn = -> angular.element(document.querySelectorAll('.loader')).eq(-1).css("visibility", 'visible')
|
|
20
15
|
$httpProvider.interceptors.push 'e2HttpInterceptor'
|
|
@@ -51,7 +46,23 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
51
46
|
$injector.get('$e2Modal').error("#{E2Snippets.icon('bell')} #{response.status}: #{message}", cause)
|
|
52
47
|
$q.reject(response)
|
|
53
48
|
|
|
54
|
-
.factory '
|
|
49
|
+
.factory 'E2Snippets', ->
|
|
50
|
+
icon = (name) -> "<span class='glyphicon glyphicon-#{name}'></span>"
|
|
51
|
+
aicon = (name) -> "<i class='fa fa-#{name}'></i>"
|
|
52
|
+
ng_class_names = ['active', 'enabled', 'disabled']
|
|
53
|
+
icon: icon
|
|
54
|
+
aicon: aicon
|
|
55
|
+
boolean_true_value: icon('check')
|
|
56
|
+
boolean_false_value: icon('unchecked')
|
|
57
|
+
make_ng_class: (o) ->
|
|
58
|
+
out = []
|
|
59
|
+
_.each ng_class_names, (e) -> out.push(if e == 'enabled' then "'disabled': !(#{o[e]})" else "'#{e}': #{o[e]}") if o[e]?
|
|
60
|
+
_.each(o.class, (v, k) -> out.push "#{k}: #{v}") if o.class?
|
|
61
|
+
if out.length > 0 then "ng-class=\"{#{out.join(',')}}\"" else ""
|
|
62
|
+
|
|
63
|
+
.factory 'E2', ($templateCache, $http, E2Snippets, $e2Modal, $q, $injector, e2HttpInterceptor, $route, $dateFormatter, $parse) ->
|
|
64
|
+
globals: {}
|
|
65
|
+
|
|
55
66
|
compact: (o) ->
|
|
56
67
|
_.each o, (v, k) =>
|
|
57
68
|
if (v == null || (_.isString(v) && !v)) || (!_.isDate(v) && _.isObject(v) && @compact(v) && _.isEmpty(v))
|
|
@@ -66,6 +77,7 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
66
77
|
else
|
|
67
78
|
# delete o[k]
|
|
68
79
|
o[k] = null
|
|
80
|
+
|
|
69
81
|
merge: (dst, src) ->
|
|
70
82
|
for k, v of src
|
|
71
83
|
if _.isObject(v) && !_.isArray(v)
|
|
@@ -80,8 +92,8 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
80
92
|
transpose: (a) ->
|
|
81
93
|
_.keys(a[0]).map((c) -> a.map (r) -> r[c])
|
|
82
94
|
|
|
83
|
-
join_keys: (keys) -> keys.join(
|
|
84
|
-
split_keys: (key) -> key.split(
|
|
95
|
+
join_keys: (keys) -> keys.join(@globals.key_separator)
|
|
96
|
+
split_keys: (key) -> key.split(@globals.key_separator)
|
|
85
97
|
id_for: (rec, meta) -> @join_keys(meta.primary_fields.map((e) -> rec[e]))
|
|
86
98
|
from_id: (id, meta) -> _.zipObject(meta.primary_fields, id) # _.zip(meta.primary_fields, id).reduce(((rec, [k, v]) -> rec[k] = v; rec), {})
|
|
87
99
|
|
|
@@ -121,13 +133,15 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
121
133
|
m.click = fun_invoke
|
|
122
134
|
|
|
123
135
|
if click
|
|
124
|
-
action[fun_name] = (
|
|
125
|
-
processor.arg_fun(action,
|
|
136
|
+
action[fun_name] = (arg) ->
|
|
137
|
+
processor.arg_fun(action, arg)
|
|
126
138
|
action.scope().$eval(click)
|
|
127
139
|
else
|
|
128
|
-
action[fun_name] ?= (
|
|
129
|
-
processor.arg_fun(action,
|
|
130
|
-
|
|
140
|
+
action[fun_name] ?= (arg) ->
|
|
141
|
+
processor.arg_fun(action, arg)
|
|
142
|
+
args = processor.arg_ret(action)
|
|
143
|
+
_.merge(args, $parse(m.arguments)(action.scope())) if m.arguments?
|
|
144
|
+
action.invoke_action(m.name, args)
|
|
131
145
|
|
|
132
146
|
if action.find_action_info(m.name, false)?
|
|
133
147
|
show = if m.show then " && " + m.show else ""
|
|
@@ -136,17 +150,16 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
136
150
|
menu_processors:
|
|
137
151
|
menu:
|
|
138
152
|
arg_name: ''
|
|
139
|
-
arg_fun: (action) ->
|
|
140
|
-
arg_ret: (action) ->
|
|
153
|
+
arg_fun: (action) ->
|
|
154
|
+
arg_ret: (action) -> {}
|
|
141
155
|
panel_menu:
|
|
142
156
|
arg_name: ''
|
|
143
|
-
arg_fun: (action) ->
|
|
144
|
-
arg_ret: (action) ->
|
|
157
|
+
arg_fun: (action) ->
|
|
158
|
+
arg_ret: (action) -> {}
|
|
145
159
|
item_menu:
|
|
146
160
|
arg_name: '$index'
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
action.current_id = $injector.get('E2').id_for(action.entries[index], action.meta)
|
|
161
|
+
arg_fun: (action, index) -> action.current_index = index
|
|
162
|
+
arg_ret: (action) -> id: action.current_id()
|
|
150
163
|
|
|
151
164
|
renderers:
|
|
152
165
|
boolean: (value, render) =>
|
|
@@ -180,7 +193,8 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
180
193
|
if f_info? && type = f_info.type
|
|
181
194
|
@renderers[type](value, f_info.render)
|
|
182
195
|
else
|
|
183
|
-
|
|
196
|
+
if f_info?.escape == false then value else
|
|
197
|
+
(value + "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")
|
|
184
198
|
else
|
|
185
199
|
value
|
|
186
200
|
|
|
@@ -200,7 +214,7 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
200
214
|
constructor: () ->
|
|
201
215
|
backdrop_z_index: (num, index) -> angular.element(document.querySelectorAll('.modal-backdrop')).eq(num).css('z-index', index)
|
|
202
216
|
modal_num: (num) -> angular.element(document.querySelectorAll('.modal')).eq(num)
|
|
203
|
-
backdrop: -> 'static'
|
|
217
|
+
backdrop: (bdr) -> bdr ? 'static'
|
|
204
218
|
show_before: ->
|
|
205
219
|
@z_index = MManager.Z_INDEX + MManager.index * 2
|
|
206
220
|
@modal.css('z-index', @z_index + 1)
|
|
@@ -218,7 +232,7 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
218
232
|
constructor: () ->
|
|
219
233
|
super()
|
|
220
234
|
@threshold = 2
|
|
221
|
-
backdrop: -> if MManager.index > @threshold then false else super()
|
|
235
|
+
backdrop: (bdr) -> if MManager.index > @threshold then false else super(bdr)
|
|
222
236
|
show_before: ->
|
|
223
237
|
super()
|
|
224
238
|
if MManager.index > @threshold
|
|
@@ -234,7 +248,7 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
234
248
|
@modal_num((MManager.index - 1) - @threshold).css('display', 'block')
|
|
235
249
|
|
|
236
250
|
class SingleBackdropMManager extends MManager
|
|
237
|
-
backdrop: -> if MManager.index > 0 then false else super()
|
|
251
|
+
backdrop: (bdr) -> if MManager.index > 0 then false else super(bdr)
|
|
238
252
|
show_before: ->
|
|
239
253
|
super()
|
|
240
254
|
@backdrop_z_index(0, @z_index)
|
|
@@ -253,33 +267,38 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
253
267
|
e.stopPropagation()
|
|
254
268
|
manager.modal = m.$element
|
|
255
269
|
manager.backdrop = m.$backdrop
|
|
256
|
-
throw "Modal has element" if
|
|
257
|
-
|
|
258
|
-
|
|
270
|
+
throw "Modal has element" if action.element?()
|
|
271
|
+
action.element = -> m.$element
|
|
272
|
+
action.panel_show?()
|
|
259
273
|
manager.show_before()
|
|
260
274
|
MManager.index++
|
|
261
275
|
|
|
262
276
|
scope.$on 'modal.show', (e, m) ->
|
|
263
277
|
e.stopPropagation()
|
|
264
278
|
manager.show()
|
|
265
|
-
|
|
279
|
+
action.panel_shown?()
|
|
266
280
|
|
|
267
281
|
scope.$on 'modal.hide.before', (e) ->
|
|
268
282
|
e.stopPropagation()
|
|
269
283
|
MManager.index--
|
|
270
284
|
manager.hide_before()
|
|
271
|
-
|
|
285
|
+
action.panel_hide?()
|
|
272
286
|
|
|
273
287
|
scope.$on 'modal.hide', (e) ->
|
|
274
288
|
e.stopPropagation()
|
|
275
289
|
manager.hide()
|
|
276
|
-
|
|
290
|
+
action.panel_hidden?()
|
|
277
291
|
scope.$destroy()
|
|
278
292
|
|
|
279
|
-
$injector.get('E2').fetch_panel(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
293
|
+
$injector.get('E2').fetch_panel(action.meta.panel, true).then (template) ->
|
|
294
|
+
modal = $modal
|
|
295
|
+
scope: scope
|
|
296
|
+
show: false
|
|
297
|
+
template: template
|
|
298
|
+
backdrop: manager.backdrop(action.meta.panel.backdrop)
|
|
299
|
+
animation: action.meta.panel.animation ? 'am-fade'
|
|
300
|
+
|
|
301
|
+
action.modal_hide = -> modal.$scope.$hide()
|
|
283
302
|
modal.$promise.then ->
|
|
284
303
|
modal.show()
|
|
285
304
|
modal
|
|
@@ -385,31 +404,54 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
385
404
|
elem.after($compile(body)(scope))
|
|
386
405
|
|
|
387
406
|
.directive 'e2TableBody', ($parse, $compile) ->
|
|
407
|
+
table_tmpl = _.template("<thead><tr>{{thead}}</tr></thead><tbody>{{tbody}}</tbody>")
|
|
388
408
|
scope: false
|
|
389
409
|
restrict: 'A'
|
|
390
410
|
link: (scope, elem, attrs) ->
|
|
391
411
|
scope.$on 'render_table', (a, ev) ->
|
|
392
412
|
# ev.stopPropagation()
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
413
|
+
action = scope.action
|
|
414
|
+
meta = action.meta
|
|
415
|
+
position = meta.menus.item_menu.properties.position ? 0
|
|
416
|
+
right_style = if position >= meta.fields.length then "style=\"text-align: right\"" else ""
|
|
417
|
+
|
|
418
|
+
thead = ""
|
|
419
|
+
fields = meta.fields.slice()
|
|
420
|
+
fields.splice(position, 0, null)
|
|
421
|
+
_.each fields, (f) ->
|
|
422
|
+
if f
|
|
423
|
+
info = meta.info[f]
|
|
424
|
+
thead += "<th>"
|
|
425
|
+
title = if info.title then "title=\"#{info.title}\"" else ""
|
|
426
|
+
if info.sort
|
|
427
|
+
thead += "<a ng-click=\"action.order('#{f}')\" #{title}><strong>#{info.loc}</strong></a>"
|
|
428
|
+
if action.ui.order == f
|
|
429
|
+
cls = if action.ui.asc then "glyphicon-chevron-up" else "glyphicon-chevron-down"
|
|
430
|
+
thead += " <span class=\"glyphicon #{cls}\"></span>"
|
|
431
|
+
else
|
|
432
|
+
thead += "<span #{title}>#{info.loc}</span>"
|
|
433
|
+
thead += "</th>"
|
|
434
|
+
else
|
|
435
|
+
thead += "<th class=\"#{meta.menus.menu.properties.class || ''}\" #{right_style}><div e2-button-set=\"action.meta.menus.menu\"></div></th>"
|
|
436
|
+
|
|
437
|
+
tbody = ""
|
|
438
|
+
_.each action.entries, (e, i) ->
|
|
439
|
+
tbody += if action.selection then "<tr ng-class=\"action.selected_class(#{i})\" class=\"tr_hover\" ng-click=\"action.select(#{i}, $event)\">" else
|
|
398
440
|
row_cls = e.$row_info?.class
|
|
399
441
|
if row_cls then "<tr class=\"#{row_cls}\">" else "<tr>"
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
442
|
+
_.each fields, (f) ->
|
|
443
|
+
if f
|
|
444
|
+
tbody += if col_cls = meta.info[f].column_class then "<td class=\"#{col_cls}\">" else "<td>"
|
|
445
|
+
tbody += action.list_cell(e, f) ? ''
|
|
446
|
+
tbody += "</td>"
|
|
447
|
+
else
|
|
448
|
+
tbody += "<td #{right_style}><div e2-button-set=\"action.meta.menus.item_menu\" index=\"#{i}\"></div></td>"
|
|
449
|
+
tbody += "</tr>"
|
|
408
450
|
|
|
409
451
|
elem.empty()
|
|
410
|
-
elem.append($compile(
|
|
452
|
+
elem.append($compile(table_tmpl thead: thead, tbody: tbody)(scope))
|
|
411
453
|
|
|
412
|
-
.directive '
|
|
454
|
+
.directive 'e2Dropdown', ($parse, $dropdown, $timeout, E2Snippets) ->
|
|
413
455
|
event_num = 0
|
|
414
456
|
dropdown_sub_tmpl = _.template("<li class='dropdown-submenu'><a href=''> {{icon}}{{aicon}} {{loc}}</a>{{sub}}</li>")
|
|
415
457
|
dropdown_tmpl = _.template("<li {{clazz}} {{show}} {{hide}}> <a href='{{href}}' {{click}}> {{icon}}{{aicon}} {{loc}}</a></li>")
|
|
@@ -446,7 +488,8 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
446
488
|
elem.off "mousedown"
|
|
447
489
|
# event.preventDefault()
|
|
448
490
|
# event.stopPropagation()
|
|
449
|
-
|
|
491
|
+
menu = $parse(attrs.e2Dropdown)(scope)
|
|
492
|
+
dropdown = $dropdown(elem, (scope: scope, template: render(menu, 0), animation: attrs.animation || 'am-flip-x', prefixEvent: "#{event_num}.tooltip")) # , delay: 1
|
|
450
493
|
dropdown.$promise.then ->
|
|
451
494
|
event_hide = scope.$on "#{event_num}.tooltip.hide", (e) ->
|
|
452
495
|
e.stopPropagation()
|
|
@@ -463,13 +506,14 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
463
506
|
|
|
464
507
|
.directive 'e2ButtonSet', ($parse, $compile, E2Snippets) ->
|
|
465
508
|
button_set_tmpl = _.template("<div class='btn btn-default' {{clazz}} {{click}} {{show}} {{hide}} {{title}}> {{icon}}{{aicon}} {{loc}}</div>")
|
|
466
|
-
button_set_arr_tmpl = _.template("<div class='btn btn-default' e2-
|
|
509
|
+
button_set_arr_tmpl = _.template("<div class='btn btn-default' e2-dropdown='{{dropdown}}' data-animation='{{animation}}'>{{icon}}{{aicon}}<span class='caret'></span></div>")
|
|
467
510
|
scope: true # because $index
|
|
468
511
|
link: (scope, elem, attrs) ->
|
|
469
512
|
menu = $parse(attrs.e2ButtonSet)(scope)
|
|
470
513
|
if menu && menu.entries.length > 0
|
|
471
514
|
group_class = menu.properties.group_class || ''
|
|
472
515
|
brk = menu.properties.break
|
|
516
|
+
animation = menu.properties.animation
|
|
473
517
|
out = ""
|
|
474
518
|
for m, i in menu.entries
|
|
475
519
|
if i >= brk
|
|
@@ -477,6 +521,7 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
477
521
|
else if m.menu
|
|
478
522
|
out += button_set_arr_tmpl
|
|
479
523
|
dropdown: "#{attrs.e2ButtonSet}.entries[#{i}].menu.entries"
|
|
524
|
+
animation: animation
|
|
480
525
|
icon: m.menu.icon && "#{E2Snippets.icon(m.menu.icon)} " || ''
|
|
481
526
|
aicon: m.menu.aicon && "#{E2Snippets.aicon(m.menu.aicon)} " || ''
|
|
482
527
|
else if m.divider
|
|
@@ -491,7 +536,13 @@ angular.module('Engine2', ['ngRoute', 'ngSanitize', 'ngAnimate', 'ngCookies', 'm
|
|
|
491
536
|
loc: !(m.button_loc == false) && m.loc || ''
|
|
492
537
|
title: (m.button_loc == false) && "title=\"#{m.loc}\"" || ''
|
|
493
538
|
|
|
494
|
-
|
|
539
|
+
if menu.entries.length > brk
|
|
540
|
+
out += button_set_arr_tmpl
|
|
541
|
+
dropdown: "#{attrs.e2ButtonSet}.entries.slice(#{brk})"
|
|
542
|
+
animation: animation
|
|
543
|
+
icon: ''
|
|
544
|
+
aicon: ''
|
|
545
|
+
|
|
495
546
|
out = "<div class='btn-group #{group_class}'>#{out}</div>"
|
|
496
547
|
out = $compile(angular.element(out))(scope)
|
|
497
548
|
if attrs.index && !scope.$index?
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict'
|
|
1
2
|
angular.module('Engine2')
|
|
2
3
|
.directive 'e2Action', (E2Actions) ->
|
|
3
4
|
scope: true
|
|
@@ -22,7 +23,7 @@ angular.module('Engine2')
|
|
|
22
23
|
$scope.action = new E2Actions.root(mresponse.data, $scope, null, $element, action_resource: 'api')
|
|
23
24
|
|
|
24
25
|
.factory 'E2Actions', (E2, $http, $timeout, $e2Modal, $injector, $compile, $templateCache, $q, localStorageService, $route, $window, $rootScope, $location) ->
|
|
25
|
-
globals =
|
|
26
|
+
globals = E2.globals
|
|
26
27
|
action: class Action
|
|
27
28
|
constructor: (response, scope, parent, element, action_info) ->
|
|
28
29
|
@find_action_info = (name, raise = true) ->
|
|
@@ -71,14 +72,17 @@ angular.module('Engine2')
|
|
|
71
72
|
|
|
72
73
|
perform_invoke: (params) ->
|
|
73
74
|
info = @action_info()
|
|
74
|
-
get_invoke = if
|
|
75
|
-
params.initial = true if
|
|
75
|
+
get_invoke = if @meta.invokable == false then $q.when(data: (response: {})) else
|
|
76
|
+
(params ?= {}).initial = true if @meta.panel && !@action_invoked && info.method == 'get'
|
|
76
77
|
$http[info.method](info.action_resource, if info.method == 'post' then params else (params: params))
|
|
77
|
-
else $q.when(data: (response: {}))
|
|
78
78
|
|
|
79
79
|
globals.action_pending = if @meta.panel then @ else @parent()
|
|
80
80
|
|
|
81
81
|
get_invoke.then (response) =>
|
|
82
|
+
if exec = response.data.$execute
|
|
83
|
+
@scope().$eval(exec)
|
|
84
|
+
delete response.data.$execute
|
|
85
|
+
|
|
82
86
|
E2.merge(@, response.data)
|
|
83
87
|
@process_meta()
|
|
84
88
|
(if @meta.reload_routes then $route.load_routes() else $q.when({})).then =>
|
|
@@ -103,7 +107,7 @@ angular.module('Engine2')
|
|
|
103
107
|
get_meta = if !info.terminal || info.meta
|
|
104
108
|
$http.get("#{info.action_resource}/meta", cache: true).then (response) =>
|
|
105
109
|
if info.recheck_access
|
|
106
|
-
$http.get("#{info.action_resource}/meta", params: (access: true, parent_id: @current_id)).then (aresponse) ->
|
|
110
|
+
$http.get("#{info.action_resource}/meta", params: (access: true, parent_id: @current_id())).then (aresponse) ->
|
|
107
111
|
response.data.actions[k].access = v for k, v of aresponse.data
|
|
108
112
|
response
|
|
109
113
|
else response # $q.when ^
|
|
@@ -113,8 +117,8 @@ angular.module('Engine2')
|
|
|
113
117
|
,
|
|
114
118
|
(err) => @handle_error(err, info, el)
|
|
115
119
|
|
|
116
|
-
invoke_action: (name,
|
|
117
|
-
@create_action(name, @scope()).then (act) -> act.invoke(
|
|
120
|
+
invoke_action: (name, args) ->
|
|
121
|
+
@create_action(name, @scope()).then (act) -> act.invoke(args)
|
|
118
122
|
|
|
119
123
|
create_action_path: (action_names, sc, elem) ->
|
|
120
124
|
last_name = action_names.pop()
|
|
@@ -126,17 +130,23 @@ angular.module('Engine2')
|
|
|
126
130
|
pre_invoke: ->
|
|
127
131
|
post_invoke: ->
|
|
128
132
|
|
|
129
|
-
invoke: ->
|
|
130
|
-
args
|
|
131
|
-
|
|
132
|
-
@perform_invoke(args
|
|
133
|
-
@post_invoke(args
|
|
133
|
+
invoke: (args) ->
|
|
134
|
+
@pre_invoke(args)
|
|
135
|
+
_.merge(args ?= {}, @meta.arguments) if @meta.arguments
|
|
136
|
+
@perform_invoke(args).then =>
|
|
137
|
+
@post_invoke(args)
|
|
138
|
+
@scope().$eval(@meta.execute) if @meta.execute
|
|
139
|
+
if @meta.repeat
|
|
140
|
+
unless @meta.destroy_repeat
|
|
141
|
+
@scope().$on("$destroy", => delete @meta.repeat)
|
|
142
|
+
@meta.destroy_repeat = true
|
|
143
|
+
$timeout (=> @invoke(args)), @meta.repeat
|
|
134
144
|
@
|
|
135
145
|
|
|
136
146
|
save_state: () ->
|
|
137
147
|
_.each @meta.state, (s) => localStorageService.set("#{globals.application}/#{@action_info().action_resource}/#{s}", @[s])
|
|
138
148
|
load_state: () ->
|
|
139
|
-
_.each @meta.state, (s) =>
|
|
149
|
+
_.each @meta.state, (s) => _.merge(@[s], localStorageService.get("#{globals.application}/#{@action_info().action_resource}/#{s}"))
|
|
140
150
|
|
|
141
151
|
destroy: (e) ->
|
|
142
152
|
console.log "DESTROY #{@action_info().action_resource}"
|
|
@@ -194,7 +204,7 @@ angular.module('Engine2')
|
|
|
194
204
|
root: class RootAction extends Action
|
|
195
205
|
initialize: ->
|
|
196
206
|
super()
|
|
197
|
-
|
|
207
|
+
_.merge(globals, @meta)
|
|
198
208
|
@meta = {}
|
|
199
209
|
|
|
200
210
|
default_action: class DefaultAction extends Action
|
|
@@ -266,10 +276,13 @@ angular.module('Engine2')
|
|
|
266
276
|
if route.menu then @register(route.menu.entries) else
|
|
267
277
|
name = '/' + route.name
|
|
268
278
|
route.href = '#' + route.name
|
|
269
|
-
|
|
279
|
+
if route.bootstrap?
|
|
280
|
+
action = if route.bootstrap == true then '' else route.bootstrap + '/'
|
|
281
|
+
$templateCache.put(route.name + '_route_template!', "<div e2-action='' action=\"'#{action}#{route.name}'\" invoke='true'></div>")
|
|
282
|
+
|
|
270
283
|
$route.routes[name] =
|
|
271
284
|
reloadOnSearch: true
|
|
272
|
-
templateUrl: route.name
|
|
285
|
+
templateUrl: if route.bootstrap? then route.name + '_route_template!' else route.name
|
|
273
286
|
originalPath: name
|
|
274
287
|
regexp: new RegExp("^#{name}$")
|
|
275
288
|
keys: []
|
|
@@ -282,14 +295,16 @@ angular.module('Engine2')
|
|
|
282
295
|
|
|
283
296
|
traverse: (routes) ->
|
|
284
297
|
menu_tmpl = _.template("<li><a href='{{href}}'>{{icon}}{{aicon}} {{loc}}</a></li>")
|
|
285
|
-
menu_sub_tmpl = _.template("<li e2-
|
|
298
|
+
menu_sub_tmpl = _.template("<li e2-dropdown='{{dropdown}}' data-animation='{{animation}}'><a href='javascript://'>{{icon}}{{aicon}} {{loc}}<span class='caret'></span></a></li>")
|
|
299
|
+
animation = @meta.menus.menu.properties.animation
|
|
286
300
|
out = routes.map (route, i) ->
|
|
287
301
|
if route.menu
|
|
288
302
|
menu_sub_tmpl
|
|
303
|
+
dropdown: "routes[#{i}].menu.entries"
|
|
304
|
+
animation: animation
|
|
289
305
|
icon: route.menu.icon && E2.icon(route.menu.icon) || ""
|
|
290
306
|
aicon: route.menu.aicon && E2.aicon(route.menu.aicon) || ""
|
|
291
307
|
loc: route.menu.loc
|
|
292
|
-
dropdown: "routes[#{i}].menu.entries"
|
|
293
308
|
else
|
|
294
309
|
menu_tmpl
|
|
295
310
|
href: route.href
|
|
@@ -298,8 +313,6 @@ angular.module('Engine2')
|
|
|
298
313
|
aicon: route.aicon && E2.aicon(route.aicon) || ''
|
|
299
314
|
out.join('')
|
|
300
315
|
|
|
301
|
-
# dummy: class DummyAction extends Action
|
|
302
|
-
|
|
303
316
|
list: class ListAction extends Action
|
|
304
317
|
initialize: ->
|
|
305
318
|
super()
|
|
@@ -340,7 +353,7 @@ angular.module('Engine2')
|
|
|
340
353
|
menu_show_meta: ->
|
|
341
354
|
$e2Modal.show
|
|
342
355
|
the_meta: @meta
|
|
343
|
-
meta: panel: (panel_template: "close_m", template_string: "<pre>{{action.the_meta | json}}</pre>", title: "Meta", class: "modal-huge")
|
|
356
|
+
meta: panel: (panel_template: "close_m", template_string: "<pre>{{action.the_meta | json}}</pre>", title: "Meta", class: "modal-huge", backdrop: true, footer: true)
|
|
344
357
|
|
|
345
358
|
# show_assoc: (index, assoc) ->
|
|
346
359
|
# # parent_id = E2.id_for(@entries[index], @meta)
|
|
@@ -350,14 +363,20 @@ angular.module('Engine2')
|
|
|
350
363
|
# @current_id = E2.id_for(@entries[index], @meta)
|
|
351
364
|
# @invoke_action(assoc)
|
|
352
365
|
|
|
366
|
+
current_entry: ->
|
|
367
|
+
@entries[@current_index]
|
|
368
|
+
|
|
369
|
+
current_id: ->
|
|
370
|
+
E2.id_for(@current_entry(), @meta)
|
|
371
|
+
|
|
353
372
|
list_cell: (e, f) ->
|
|
354
373
|
E2.render_field(e, f, @meta)
|
|
355
374
|
|
|
356
|
-
invoke: (
|
|
375
|
+
invoke: (args = {}) ->
|
|
357
376
|
@save_state()
|
|
358
377
|
query = _.cloneDeep(@query)
|
|
359
378
|
delete query.search if _.isEmpty(E2.compact(query.search))
|
|
360
|
-
_.merge(query,
|
|
379
|
+
_.merge(query, args)
|
|
361
380
|
super(query).then =>
|
|
362
381
|
@ui = _.pick @query, ['order', 'asc', 'page']
|
|
363
382
|
@ui.pagination_active = @ui.page != 0 || @entries.length >= @meta.config.per_page
|
|
@@ -599,7 +618,7 @@ angular.module('Engine2')
|
|
|
599
618
|
@multiple = @dinfo.render.multiple
|
|
600
619
|
@clear_selected()
|
|
601
620
|
@if_fk_values (fk_values) =>
|
|
602
|
-
@selected = if @multiple then E2.transpose(fk_values).map(E2.join_keys) else E2.join_keys(fk_values)
|
|
621
|
+
@selected = if @multiple then E2.transpose(fk_values).map((e) -> E2.join_keys(e)) else E2.join_keys(fk_values)
|
|
603
622
|
@invoke()
|
|
604
623
|
|
|
605
624
|
clear_selected: -> @selected = if @multiple then [] else null # no need to null complex keys
|
|
@@ -652,7 +671,7 @@ angular.module('Engine2')
|
|
|
652
671
|
|
|
653
672
|
invoke_decode: (recs, f) ->
|
|
654
673
|
if @multiple && _.size(recs) > @meta.show_max_selected
|
|
655
|
-
@decode = "#{_.size(recs)} #{@meta.decode_selected}"
|
|
674
|
+
@decode = "#{_.size(recs)} #{@meta.loc.decode_selected}"
|
|
656
675
|
else
|
|
657
676
|
decode_descriptions = (recs) => @decode = recs.map((fields) => @decode_description(fields)).join(' | ')
|
|
658
677
|
recs = recs.map (r) => if _.isArray(r) then E2.from_id(r, @meta) else r
|
|
@@ -721,7 +740,7 @@ angular.module('Engine2')
|
|
|
721
740
|
star_to_many_list: class StarToManyList extends ListAction
|
|
722
741
|
initialize: ->
|
|
723
742
|
super()
|
|
724
|
-
@query.parent_id = @parent().current_id
|
|
743
|
+
@query.parent_id = @parent().current_id()
|
|
725
744
|
|
|
726
745
|
# link_list: implicit
|
|
727
746
|
item_menu_confirm_unlink: (index) ->
|
|
@@ -786,8 +805,8 @@ angular.module('Engine2')
|
|
|
786
805
|
@panel_close()
|
|
787
806
|
|
|
788
807
|
star_to_many_field_unlink: class StarToManyFieldUnlink extends Action
|
|
789
|
-
invoke: (
|
|
790
|
-
id =
|
|
808
|
+
invoke: (args) ->
|
|
809
|
+
id = args.id
|
|
791
810
|
pparent = @parent().parent()
|
|
792
811
|
if _.includes(pparent.links.linked, id) then _.pull(pparent.links.linked, id) else pparent.links.unlinked.push id
|
|
793
812
|
pparent.sync_record()
|