engine2 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/Rakefile +138 -0
- data/conf/message.yaml +93 -0
- data/conf/message_pl.yaml +93 -0
- data/engine2.gemspec +34 -0
- data/lib/engine2.rb +34 -0
- data/lib/engine2/action.rb +217 -0
- data/lib/engine2/core.rb +572 -0
- data/lib/engine2/handler.rb +134 -0
- data/lib/engine2/meta.rb +969 -0
- data/lib/engine2/meta/decode_meta.rb +110 -0
- data/lib/engine2/meta/delete_meta.rb +73 -0
- data/lib/engine2/meta/form_meta.rb +144 -0
- data/lib/engine2/meta/infra_meta.rb +292 -0
- data/lib/engine2/meta/link_meta.rb +133 -0
- data/lib/engine2/meta/list_meta.rb +284 -0
- data/lib/engine2/meta/save_meta.rb +63 -0
- data/lib/engine2/meta/view_meta.rb +22 -0
- data/lib/engine2/model.rb +390 -0
- data/lib/engine2/models/Files.rb +38 -0
- data/lib/engine2/models/UserInfo.rb +24 -0
- data/lib/engine2/post_bootstrap.rb +83 -0
- data/lib/engine2/pre_bootstrap.rb +27 -0
- data/lib/engine2/scheme.rb +202 -0
- data/lib/engine2/templates.rb +229 -0
- data/lib/engine2/type_info.rb +342 -0
- data/lib/engine2/version.rb +9 -0
- data/public/assets/javascripts.js +13 -0
- data/public/assets/styles.css +4 -0
- data/public/css/angular-motion.css +1022 -0
- data/public/css/angular-ui-tree.min.css +1 -0
- data/public/css/app.css +196 -0
- data/public/css/bootstrap-additions.css +1560 -0
- data/public/css/bootstrap.min.css +11 -0
- data/public/css/font-awesome.min.css +4 -0
- data/public/favicon.ico +0 -0
- data/public/fonts/FontAwesome.otf +0 -0
- data/public/fonts/fontawesome-webfont.eot +0 -0
- data/public/fonts/fontawesome-webfont.svg +655 -0
- 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 +288 -0
- 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-dark.gif +0 -0
- data/public/img/ajax-loader-light.gif +0 -0
- data/public/img/ajax-loader.gif +0 -0
- data/public/js/angular-animate.js +4115 -0
- data/public/js/angular-cookies.js +322 -0
- data/public/js/angular-local-storage.js +455 -0
- data/public/js/angular-route.js +1022 -0
- data/public/js/angular-sanitize.js +717 -0
- data/public/js/angular-strap.js +4339 -0
- data/public/js/angular-strap.tpl.js +43 -0
- data/public/js/angular-ui-tree.js +1569 -0
- data/public/js/angular.js +30714 -0
- data/public/js/i18n/angular-locale_pl.js +115 -0
- data/public/js/lodash.custom.min.js +97 -0
- data/public/js/ng-file-upload-shim.min.js +2 -0
- data/public/js/ng-file-upload.min.js +3 -0
- data/views/app.coffee +3 -0
- data/views/engine2.coffee +557 -0
- data/views/engine2actions.coffee +849 -0
- data/views/engine2templates.coffee +0 -0
- data/views/fields/blob.slim +22 -0
- data/views/fields/bs_select.slim +10 -0
- data/views/fields/bsselect_picker.slim +18 -0
- data/views/fields/bsselect_picker_opt.slim +22 -0
- data/views/fields/checkbox.slim +11 -0
- data/views/fields/checkbox_buttons.slim +6 -0
- data/views/fields/checkbox_buttons_opt.slim +8 -0
- data/views/fields/currency.slim +10 -0
- data/views/fields/date.slim +21 -0
- data/views/fields/date_range.slim +44 -0
- data/views/fields/date_time.slim +42 -0
- data/views/fields/datetime.slim +42 -0
- data/views/fields/decimal.slim +11 -0
- data/views/fields/decimal_date.slim +22 -0
- data/views/fields/decimal_time.slim +26 -0
- data/views/fields/email.slim +13 -0
- data/views/fields/file_store.slim +61 -0
- data/views/fields/input_text.slim +14 -0
- data/views/fields/integer.slim +11 -0
- data/views/fields/list_bsselect.slim +18 -0
- data/views/fields/list_bsselect_opt.slim +21 -0
- data/views/fields/list_buttons.slim +3 -0
- data/views/fields/list_buttons_opt.slim +5 -0
- data/views/fields/list_select.slim +11 -0
- data/views/fields/list_select_opt.slim +15 -0
- data/views/fields/password.slim +14 -0
- data/views/fields/radio_checkbox.slim +10 -0
- data/views/fields/scaffold.slim +2 -0
- data/views/fields/scaffold_picker.slim +20 -0
- data/views/fields/select_picker.slim +12 -0
- data/views/fields/select_picker_opt.slim +16 -0
- data/views/fields/text_area.slim +10 -0
- data/views/fields/time.slim +22 -0
- data/views/fields/typeahead_picker.slim +25 -0
- data/views/index.slim +44 -0
- data/views/infra/index.slim +5 -0
- data/views/infra/inspect.slim +81 -0
- data/views/modals/close_m.slim +15 -0
- data/views/modals/confirm_m.slim +19 -0
- data/views/modals/empty_m.slim +12 -0
- data/views/modals/menu_m.slim +13 -0
- data/views/modals/yes_no_m.slim +19 -0
- data/views/panels/menu_m.slim +9 -0
- data/views/scaffold/confirm.slim +3 -0
- data/views/scaffold/fields.slim +10 -0
- data/views/scaffold/form.slim +11 -0
- data/views/scaffold/list.slim +42 -0
- data/views/scaffold/message.slim +3 -0
- data/views/scaffold/search.slim +20 -0
- data/views/scaffold/view.slim +18 -0
- data/views/search_fields/bsmselect_picker.slim +25 -0
- data/views/search_fields/bsselect_picker.slim +24 -0
- data/views/search_fields/checkbox.slim +11 -0
- data/views/search_fields/checkbox2.slim +14 -0
- data/views/search_fields/checkbox_buttons.slim +10 -0
- data/views/search_fields/date_range.slim +46 -0
- data/views/search_fields/decimal_date_range.slim +47 -0
- data/views/search_fields/input_text.slim +18 -0
- data/views/search_fields/integer.slim +18 -0
- data/views/search_fields/integer_range.slim +27 -0
- data/views/search_fields/list_bsmselect.slim +24 -0
- data/views/search_fields/list_bsselect.slim +22 -0
- data/views/search_fields/list_buttons.slim +8 -0
- data/views/search_fields/list_select.slim +17 -0
- data/views/search_fields/scaffold_picker.slim +19 -0
- data/views/search_fields/select_picker.slim +17 -0
- data/views/search_fields/typeahead_picker.slim +25 -0
- metadata +327 -0
@@ -0,0 +1,849 @@
|
|
1
|
+
angular.module('Engine2')
|
2
|
+
.directive 'e2Action', (E2Actions) ->
|
3
|
+
scope: true
|
4
|
+
controller: ($scope, $attrs, $parse, $element, $http) ->
|
5
|
+
if action_attr = $attrs.action
|
6
|
+
action_names = $parse(action_attr)($scope)
|
7
|
+
throw "Invalid action path: '#{action_attr}'" unless action_names
|
8
|
+
action_names = action_names.split('/') if _.isString(action_names)
|
9
|
+
create = (action) ->
|
10
|
+
action.create_action_path(action_names, $scope, $element).then (act) -> act.invoke() if $attrs.invoke
|
11
|
+
|
12
|
+
sc = $scope
|
13
|
+
if sc.action
|
14
|
+
sc = sc.$parent until sc.action instanceof E2Actions.action
|
15
|
+
create(sc.action)
|
16
|
+
else
|
17
|
+
bootstrap_action_off = $scope.$on "bootstrap_action", (evt, action) ->
|
18
|
+
bootstrap_action_off()
|
19
|
+
create(action)
|
20
|
+
else
|
21
|
+
$http.get("api/meta").then (mresponse) -> $scope.$broadcast "bootstrap_action",
|
22
|
+
$scope.action = new E2Actions.default_action(mresponse.data, $scope, null, $element, action_resource: 'api')
|
23
|
+
|
24
|
+
.factory 'E2Actions', (E2, $http, $timeout, $e2Modal, $injector, $compile, $templateCache, $q, localStorageService, $route, $window, $rootScope, $location) ->
|
25
|
+
action: class Action
|
26
|
+
constructor: (response, scope, parent, element, action_info) ->
|
27
|
+
@find_action_info = (name, raise = true) ->
|
28
|
+
act = response.actions[name]
|
29
|
+
throw "Undefined action '#{name}' for action #{@action_info().name} (under #{@parent().action_info().action_resource})" if raise && !act
|
30
|
+
act
|
31
|
+
|
32
|
+
_.each response.actions, (act, nm) -> act.name = nm
|
33
|
+
@meta = response.meta
|
34
|
+
(@scope = -> scope) if scope
|
35
|
+
@element = -> element
|
36
|
+
@action_info = -> action_info
|
37
|
+
@parent = -> parent
|
38
|
+
|
39
|
+
if @meta.panel
|
40
|
+
@default_action_name = _(response.actions).find((o) -> o.default)?.name
|
41
|
+
|
42
|
+
scope = scope.$new(true)
|
43
|
+
scope.$on "$destroy", (e) => @destroy(e)
|
44
|
+
scope.action = @
|
45
|
+
|
46
|
+
act = parent
|
47
|
+
act = act.parent() while act && !act.meta.panel
|
48
|
+
unless act # no modal for top level panels
|
49
|
+
@meta.panel.modal_action = false
|
50
|
+
if @meta.menus.panel_menu
|
51
|
+
_.remove(@meta.menus.panel_menu.entries, (m) -> m.name == 'cancel')
|
52
|
+
|
53
|
+
@initialize()
|
54
|
+
|
55
|
+
initialize: ->
|
56
|
+
@process_static_meta()
|
57
|
+
@process_meta()
|
58
|
+
console.log "CREATE #{@action_info().action_resource}"
|
59
|
+
|
60
|
+
process_static_meta: ->
|
61
|
+
if @meta.menus
|
62
|
+
_.each @meta.menus, (menu, name) => E2.process_menu @, name
|
63
|
+
process_meta: ->
|
64
|
+
|
65
|
+
handle_error: (err, action_info, element, create) ->
|
66
|
+
if err.status == 401
|
67
|
+
if action_info.access
|
68
|
+
$rootScope.$broadcast "relogin", element?, create
|
69
|
+
else
|
70
|
+
$e2Modal.error("#{err.status}: #{err.data.message}", err.data.cause || err.data.message)
|
71
|
+
$q.reject(err)
|
72
|
+
|
73
|
+
perform_invoke: (params) ->
|
74
|
+
info = @action_info()
|
75
|
+
get_invoke = if info.invokable
|
76
|
+
params.initial = true if !@action_invoked && params && info.method == 'get'
|
77
|
+
$http[info.method](info.action_resource, if info.method == 'post' then params else (params: params))
|
78
|
+
else $q.when(data: (response: {}))
|
79
|
+
|
80
|
+
get_invoke.then (response) =>
|
81
|
+
E2.merge(@meta, response.data.meta)
|
82
|
+
@process_meta()
|
83
|
+
_.assign(@, response.data.response)
|
84
|
+
if @meta.response
|
85
|
+
E2.merge(@, @meta.response)
|
86
|
+
delete @meta.response
|
87
|
+
@arguments = _.keys(response.data.response)
|
88
|
+
unless @meta.panel # persistent action
|
89
|
+
prnt = @parent()
|
90
|
+
throw "Attempted parent merge for root action: #{info.name}" unless prnt
|
91
|
+
E2.merge(prnt.meta, @meta)
|
92
|
+
_.assign(prnt, response.data.response)
|
93
|
+
|
94
|
+
# promise = if @meta.panel && !@action_invoked
|
95
|
+
# $q.when(promise) # .then -> response.data
|
96
|
+
if @meta.panel && !@action_invoked
|
97
|
+
@action_invoked = true
|
98
|
+
@panel_render()
|
99
|
+
# else $q.when()
|
100
|
+
,
|
101
|
+
(err) =>
|
102
|
+
@parent().action_pending = false
|
103
|
+
@handle_error(err, info, @element())
|
104
|
+
|
105
|
+
create_action: (name, sc, el) ->
|
106
|
+
info = @find_action_info(name)
|
107
|
+
info.action_resource = "#{@action_info().action_resource}/#{info.name}"
|
108
|
+
get_meta = if !info.terminal || info.meta
|
109
|
+
$http.get("#{info.action_resource}/meta", cache: true).then (response) =>
|
110
|
+
if info.recheck_access
|
111
|
+
$http.get("#{info.action_resource}/meta", params: (access: true, parent_id: @current_id)).then (aresponse) ->
|
112
|
+
response.data.actions[k].access = v for k, v of aresponse.data
|
113
|
+
response
|
114
|
+
else response # $q.when ^
|
115
|
+
else $q.when(data: (meta: {}, actions: []))
|
116
|
+
E2A = $injector.get("E2Actions")
|
117
|
+
get_meta.then (mresponse) => new (E2A[info.meta_type] ? E2A.default_action)(mresponse.data, sc, @, el, info)
|
118
|
+
,
|
119
|
+
(err) => @handle_error(err, info, el)
|
120
|
+
|
121
|
+
invoke_action: (name, arg) ->
|
122
|
+
@create_action(name, @scope()).then (act) -> act.invoke(arg)
|
123
|
+
|
124
|
+
create_action_path: (action_names, sc, elem) ->
|
125
|
+
last_name = action_names.pop()
|
126
|
+
_.reduce(action_names, ((pr, nm) -> pr.then (act) -> act.create_action(nm)), $q.when(@)).then (act) ->
|
127
|
+
act.create_action(last_name, sc, elem).then (act) -> sc.action = act
|
128
|
+
|
129
|
+
pre_invoke: ->
|
130
|
+
@parent().action_pending = true
|
131
|
+
# @parent().parent().action_pending = true if @parent().parent()
|
132
|
+
post_invoke: ->
|
133
|
+
delete @parent().action_pending # = false
|
134
|
+
# @parent().parent().action_pending = false if @parent().parent()
|
135
|
+
invoke: ->
|
136
|
+
args = arguments
|
137
|
+
@pre_invoke(args...)
|
138
|
+
@perform_invoke(args...).then (response) =>
|
139
|
+
@post_invoke(args...)
|
140
|
+
@
|
141
|
+
|
142
|
+
save_state: () ->
|
143
|
+
_.each @meta.state, (s) => localStorageService.set("#{@action_info().action_resource}/#{s}", @[s])
|
144
|
+
load_state: () ->
|
145
|
+
_.each @meta.state, (s) => E2.merge(@[s], localStorageService.get("#{@action_info().action_resource}/#{s}"))
|
146
|
+
|
147
|
+
destroy: (e) ->
|
148
|
+
console.log "DESTROY #{@action_info().action_resource}"
|
149
|
+
|
150
|
+
panel_render: ->
|
151
|
+
if @meta.panel.modal_action
|
152
|
+
if @element()
|
153
|
+
E2.fetch_panel(@meta.panel, true).then (template) =>
|
154
|
+
@panel_show?()
|
155
|
+
compiled = $compile(template)(@scope())
|
156
|
+
@element().empty().append(compiled.contents())
|
157
|
+
@panel_shown?()
|
158
|
+
|
159
|
+
else
|
160
|
+
$e2Modal.show(@)
|
161
|
+
else
|
162
|
+
@panel_scope?().$destroy()
|
163
|
+
act = @
|
164
|
+
act = act.parent() until act.element()
|
165
|
+
element = act.element() # @element()
|
166
|
+
is_modal = $e2Modal.is_modal() && !@element()
|
167
|
+
E2.fetch_panel(@meta.panel, is_modal).then (template) =>
|
168
|
+
@panel_show?()
|
169
|
+
# @panel_scope().$destroy()
|
170
|
+
# @panel_scope = -> @scope().$new(false)
|
171
|
+
# @scope().$broadcast "$destroy"
|
172
|
+
@panel_scope = -> @scope().$new()
|
173
|
+
compiled = $compile(template)(@panel_scope())
|
174
|
+
if is_modal
|
175
|
+
element.empty().append(compiled.contents())
|
176
|
+
else
|
177
|
+
# element.empty().$destroy()
|
178
|
+
element.empty().append(compiled)
|
179
|
+
@panel_shown?()
|
180
|
+
|
181
|
+
# panel_refresh: ->
|
182
|
+
|
183
|
+
panel_hidden: ->
|
184
|
+
@scope().$destroy()
|
185
|
+
|
186
|
+
panel_close: ->
|
187
|
+
if @meta.panel.modal_action
|
188
|
+
@modal_hide()
|
189
|
+
else
|
190
|
+
# @parent().panel_refresh()
|
191
|
+
@panel_hide?()
|
192
|
+
@panel_hidden()
|
193
|
+
@scope().$destroy()
|
194
|
+
@parent().action_invoked = false
|
195
|
+
@parent().invoke()
|
196
|
+
|
197
|
+
panel_menu_cancel: ->
|
198
|
+
@panel_close()
|
199
|
+
|
200
|
+
default_action: class DefaultAction extends Action
|
201
|
+
initialize: ->
|
202
|
+
super()
|
203
|
+
# console.log "DEFAULT ACTION: #{@action_info().action_resource}"
|
204
|
+
|
205
|
+
inspect: class InspectAction extends Action
|
206
|
+
initialize: ->
|
207
|
+
super()
|
208
|
+
@tree = actions: [name: 'api', number: 0, access: true]
|
209
|
+
@invoke_action('models')
|
210
|
+
|
211
|
+
open: (stack, node, collapsed, expand) ->
|
212
|
+
tree = @tree
|
213
|
+
path = []
|
214
|
+
_.each stack, (index) -> # fold ?
|
215
|
+
tree = tree.actions[index]
|
216
|
+
path.push tree.name
|
217
|
+
|
218
|
+
# if !expand
|
219
|
+
@number = tree.number
|
220
|
+
if _.size(stack) > 1
|
221
|
+
$http.get("#{_.dropRight(path).join('/')}/meta").then (response) => @action_json = _.toArray(response.data.actions)[_.last(stack)]
|
222
|
+
else
|
223
|
+
@action_json = {}
|
224
|
+
|
225
|
+
# if expand && collapsed
|
226
|
+
$http.get("#{path.join('/')}/meta").then (response) =>
|
227
|
+
get_meta = if tree.recheck_access
|
228
|
+
$http.get("#{path.join('/')}/meta", params: (access: true)).then (aresponse) ->
|
229
|
+
response.data.actions[k].access = v for k, v of aresponse.data
|
230
|
+
response
|
231
|
+
else $q.when(response)
|
232
|
+
|
233
|
+
get_meta.then (response) =>
|
234
|
+
_.each response.data.actions, (act, nm) -> act.name = nm
|
235
|
+
tree.actions ?= _.toArray(response.data.actions)
|
236
|
+
@meta_json = response.data.meta
|
237
|
+
@action_state = if @meta_json.state then _.zipObject(@meta_json.state.map (k) -> [k, localStorageService.get("#{path}/#{k}")]) else {}
|
238
|
+
,
|
239
|
+
(err) =>
|
240
|
+
delete @meta_json
|
241
|
+
@handle_error(err, access: false)
|
242
|
+
|
243
|
+
has_assoc: (model) ->
|
244
|
+
_.size(model.assoc) > 0
|
245
|
+
|
246
|
+
menu: class MenuAction extends Action
|
247
|
+
process_static_meta: ->
|
248
|
+
|
249
|
+
initialize: ->
|
250
|
+
super()
|
251
|
+
$route.load_routes = =>
|
252
|
+
@invoke().then =>
|
253
|
+
_.each _.keys($route.routes), (k) -> delete $route.routes[k]
|
254
|
+
menu = @meta.menus.menu
|
255
|
+
$route.routes[null] = reloadOnSearch: true, redirectTo: '/' + (menu.properties.default ? menu.entries[0].name)
|
256
|
+
@register(menu.entries)
|
257
|
+
$route.reload() # $location.path('')
|
258
|
+
@scope().routes = menu.entries
|
259
|
+
out = if _.size(menu.entries) == 0 then angular.element("<div></div>") else $compile(@traverse(menu.entries))(@scope())
|
260
|
+
@element().replaceWith(out)
|
261
|
+
@element = -> out
|
262
|
+
$route.load_routes()
|
263
|
+
|
264
|
+
register: (routes) ->
|
265
|
+
_.each routes, (route) =>
|
266
|
+
if route.menu then @register(route.menu.entries) else
|
267
|
+
name = '/' + route.name
|
268
|
+
route.href = '#' + route.name
|
269
|
+
$templateCache.put(route.name, "<div e2-action='' action=\"'#{route.bootstrap}/#{route.name}'\" invoke='true'></div>") if route.bootstrap
|
270
|
+
$route.routes[name] =
|
271
|
+
reloadOnSearch: true
|
272
|
+
templateUrl: route.name
|
273
|
+
originalPath: name
|
274
|
+
regexp: new RegExp("^#{name}$")
|
275
|
+
keys: []
|
276
|
+
|
277
|
+
$route.routes[name + '/'] =
|
278
|
+
redirectTo: name
|
279
|
+
originalPath: name + '/'
|
280
|
+
regexp: new RegExp("^#{name}/$")
|
281
|
+
keys: []
|
282
|
+
|
283
|
+
traverse: (routes) ->
|
284
|
+
menu_tmpl = _.template("<li><a href='{{href}}'>{{icon}}{{aicon}} {{loc}}</a></li>")
|
285
|
+
menu_sub_tmpl = _.template("<li e2-drop-down='{{dropdown}}'><a href='javascript://'>{{icon}}{{aicon}}{{loc}}<span class='caret'></span></a></li>")
|
286
|
+
out = routes.map (route, i) ->
|
287
|
+
if route.menu
|
288
|
+
menu_sub_tmpl
|
289
|
+
icon: route.menu.icon && E2.icon(route.menu.icon) || ""
|
290
|
+
aicon: route.menu.aicon && E2.aicon(route.menu.aicon) || ""
|
291
|
+
loc: route.menu.loc
|
292
|
+
dropdown: "routes[#{i}].menu.entries"
|
293
|
+
else
|
294
|
+
menu_tmpl
|
295
|
+
href: route.href
|
296
|
+
loc: route.loc
|
297
|
+
icon: route.icon && E2.icon(route.icon) || ''
|
298
|
+
aicon: route.aicon && E2.aicon(route.aicon) || ''
|
299
|
+
out.join('')
|
300
|
+
|
301
|
+
# dummy: class DummyAction extends Action
|
302
|
+
|
303
|
+
list: class ListAction extends Action
|
304
|
+
initialize: ->
|
305
|
+
super()
|
306
|
+
@query = page: 0, asc: true, search: {} #, search_tab: 0
|
307
|
+
@ui_state = {}
|
308
|
+
@load_state()
|
309
|
+
|
310
|
+
delete @query.order unless _.includes(@meta.fields, @query.order)
|
311
|
+
_.each @query.search, ((sv, sn) => delete @query.search[sn] unless _.includes(@meta.search_fields, sn))
|
312
|
+
|
313
|
+
_.each @meta.info, (info, name) =>
|
314
|
+
if info.remote_onchange
|
315
|
+
@scope().$watch (=> @query.search?[name]), (n) => if n?
|
316
|
+
params = value: @query.search[name]
|
317
|
+
params.record = @query.search if info.remote_onchange_record
|
318
|
+
@invoke_action(info.remote_onchange, params)
|
319
|
+
|
320
|
+
if info.onchange
|
321
|
+
@scope().$watch (=> @query.search?[name]), (n) => if n?
|
322
|
+
@scope().$eval(info.onchange)
|
323
|
+
|
324
|
+
# $window.addEventListener 'beforeunload', (e, v) => @save_state()
|
325
|
+
|
326
|
+
destroy: ->
|
327
|
+
@save_state()
|
328
|
+
super()
|
329
|
+
|
330
|
+
process_meta: ->
|
331
|
+
super()
|
332
|
+
meta = @meta
|
333
|
+
meta.fields = meta.fields.filter((f) => !meta.info[f].hidden) if meta.fields
|
334
|
+
|
335
|
+
# confirm_create, view, confirm_modify, confirm_delete, assocs - implicit
|
336
|
+
|
337
|
+
menu_search_toggle: ->
|
338
|
+
@ui_state.search_active = !@ui_state.search_active
|
339
|
+
@save_state() unless @ui_state.search_active
|
340
|
+
|
341
|
+
menu_refresh: ->
|
342
|
+
@invoke(refresh: true)
|
343
|
+
|
344
|
+
menu_default_order: ->
|
345
|
+
delete @query.order
|
346
|
+
@invoke()
|
347
|
+
|
348
|
+
menu_select_toggle: ->
|
349
|
+
if @selection then delete @selection else @selection = {}
|
350
|
+
@scope().$broadcast 'render_table'
|
351
|
+
|
352
|
+
menu_show_meta: ->
|
353
|
+
$e2Modal.show
|
354
|
+
the_meta: @meta
|
355
|
+
meta: panel: (panel_template: "close_m", template_string: "<pre>{{action.the_meta | json}}</pre>", title: "Meta", class: "modal-huge")
|
356
|
+
|
357
|
+
# show_assoc: (index, assoc) ->
|
358
|
+
# # parent_id = E2.id_for(@entries[index], @meta)
|
359
|
+
# # @create_action(assoc, @scope(), null, parent_id).then (action) =>
|
360
|
+
# # action.query.parent_id = parent_id # E2.id_for(@entries[index], @meta)
|
361
|
+
# # action.invoke()
|
362
|
+
# @current_id = E2.id_for(@entries[index], @meta)
|
363
|
+
# @invoke_action(assoc)
|
364
|
+
|
365
|
+
list_cell: (e, f) ->
|
366
|
+
E2.render_field(e, f, @meta)
|
367
|
+
|
368
|
+
invoke: (arg = {}) ->
|
369
|
+
@save_state()
|
370
|
+
query = _.cloneDeep(@query)
|
371
|
+
delete query.search if _.isEmpty(E2.compact(query.search))
|
372
|
+
_.merge(query, arg)
|
373
|
+
super(query).then =>
|
374
|
+
@ui = _.pick @query, ['order', 'asc', 'page']
|
375
|
+
@scope().$broadcast 'render_table'
|
376
|
+
|
377
|
+
load_new: ->
|
378
|
+
@query.page = 0
|
379
|
+
@invoke()
|
380
|
+
|
381
|
+
order: (col) ->
|
382
|
+
@query.asc = if @query.order == col then !@query.asc else true
|
383
|
+
@query.order = col
|
384
|
+
@load_new()
|
385
|
+
|
386
|
+
prev_active: -> @query.page > 0
|
387
|
+
prev: ->
|
388
|
+
@query.page = Math.max(0, @query.page - @meta.config.per_page)
|
389
|
+
@invoke()
|
390
|
+
|
391
|
+
next_active: -> @entries.length == @meta.config.per_page
|
392
|
+
next: ->
|
393
|
+
@query.page += @meta.config.per_page # min & count
|
394
|
+
@invoke()
|
395
|
+
|
396
|
+
page_info: ->
|
397
|
+
page = @ui.page / @meta.config.per_page + 1
|
398
|
+
if @count then "#{page} / #{Math.ceil(@count / @meta.config.per_page)} (#{@count})" else page || ''
|
399
|
+
|
400
|
+
search_reset: ->
|
401
|
+
E2.clean(@query.search)
|
402
|
+
@scope().$broadcast "search_reset"
|
403
|
+
@load_new()
|
404
|
+
|
405
|
+
search_live: (f) ->
|
406
|
+
@load_new() if @meta.info[f].search_live
|
407
|
+
|
408
|
+
selected_class: (index) ->
|
409
|
+
(entry = @entries[index]) && @selection && @selection[E2.id_for(entry, @meta)] && 'info'
|
410
|
+
|
411
|
+
select: (index, ev) ->
|
412
|
+
if ev.target.nodeName == "TD"
|
413
|
+
if @selection
|
414
|
+
rec = @entries[index]
|
415
|
+
id = E2.id_for(rec, @meta)
|
416
|
+
if @selection[id] then delete @selection[id] else @selection[id] = rec
|
417
|
+
|
418
|
+
selected_size: ->
|
419
|
+
_.size(@selection)
|
420
|
+
|
421
|
+
bulk_delete: class BulkDeleteAction extends Action
|
422
|
+
invoke: ->
|
423
|
+
super(ids: [_.keys(@parent().parent().selection)]).then =>
|
424
|
+
@parent().parent().selection = {}
|
425
|
+
|
426
|
+
view: class ViewAction extends Action
|
427
|
+
view_cell: (e, f) ->
|
428
|
+
E2.render_field(e, f, @meta)
|
429
|
+
|
430
|
+
form_base_action: class FormBaseAction extends Action
|
431
|
+
initialize: ->
|
432
|
+
super()
|
433
|
+
_.each @meta.info, (info, name) =>
|
434
|
+
if info.remote_onchange
|
435
|
+
@scope().$watch (=> @record?[name]), (n) => if n? #if typeof(n) != "undefined"
|
436
|
+
params = value: @record[name]
|
437
|
+
params.record = @record if info.remote_onchange_record
|
438
|
+
@invoke_action(info.remote_onchange, params)
|
439
|
+
|
440
|
+
if info.onchange
|
441
|
+
@scope().$watch (=> @record?[name]), (n) => if n?
|
442
|
+
@scope().$eval(info.onchange)
|
443
|
+
|
444
|
+
if @meta.tabs
|
445
|
+
@scope().$watch "action.activeTab", (tab) => if tab? # && tab >= 0
|
446
|
+
@panel_shown()
|
447
|
+
|
448
|
+
@["panel_menu_#{@default_action_name}"] = -> @panel_menu_default_action()
|
449
|
+
@scope().$on "return_pressed", (e) => @panel_menu_default_action()
|
450
|
+
|
451
|
+
post_invoke: (args) ->
|
452
|
+
super()
|
453
|
+
_.each @meta.info, (info, name) =>
|
454
|
+
if _.isString(@record[name]) && !info.dont_strip
|
455
|
+
@record[name] = @record[name].trim()
|
456
|
+
|
457
|
+
panel_menu_default_action: ->
|
458
|
+
_.each @meta.info, (v, n) =>
|
459
|
+
@record[n] = null if @record[n] is undefined
|
460
|
+
params = record: @record
|
461
|
+
params.parent_id ?= @parent().query?.parent_id # and StarToManyList ?
|
462
|
+
@invoke_action(@default_action_name, params).then =>
|
463
|
+
dfd = $q.defer()
|
464
|
+
if @errors
|
465
|
+
if @meta.tabs
|
466
|
+
[i, first, curr] = [0, null, false]
|
467
|
+
for tab in @meta.tabs
|
468
|
+
if _(tab.fields).find((f) => @errors[f])
|
469
|
+
first = i if not first?
|
470
|
+
act = true if @activeTab == i
|
471
|
+
i++
|
472
|
+
@activeTab = first unless act
|
473
|
+
|
474
|
+
if @activeTab?
|
475
|
+
field = _(@meta.tabs[@activeTab].fields).find((f) => @errors[f])
|
476
|
+
# console.log field undefined ?
|
477
|
+
else
|
478
|
+
@activeTab = 0
|
479
|
+
@alert = @errors
|
480
|
+
else
|
481
|
+
field = _(@meta.fields).find((f) => @errors[f])
|
482
|
+
@alert = @errors if (!field || !@meta.info[field] || @meta.info[field].hidden) # ?
|
483
|
+
$timeout => @scope().$broadcast("focus_field", field)
|
484
|
+
#e.scope.$eval(meta.execute) if meta.execute # ?
|
485
|
+
dfd.reject(@errors)
|
486
|
+
else
|
487
|
+
@panel_close()
|
488
|
+
dfd.resolve(@record) # $q.when(true) ?
|
489
|
+
dfd.promise
|
490
|
+
|
491
|
+
panel_shown: ->
|
492
|
+
field = if @meta.tabs
|
493
|
+
tab = @meta.tabs[@activeTab]
|
494
|
+
if @errors
|
495
|
+
_(tab.fields).find((f) => @errors[f]) || _(tab.fields).find((f) => !@meta.info[f].hidden)
|
496
|
+
else
|
497
|
+
tab ?= @meta.tabs[0]
|
498
|
+
_(tab.fields).find((f) => !@meta.info[f].hidden && !@meta.info[f].disabled)
|
499
|
+
else
|
500
|
+
_(@meta.fields).find((f) => !@meta.info[f].hidden && !@meta.info[f].disabled)
|
501
|
+
$timeout (=> @scope().$broadcast("focus_field", field)), 300 # hack, on shown ?
|
502
|
+
|
503
|
+
infra: class InfraAction extends Action
|
504
|
+
initialize: ->
|
505
|
+
super()
|
506
|
+
@scope().$on "relogin", (evt, reload_routes, create) =>
|
507
|
+
if @user
|
508
|
+
@invoke_action('login_form').then (act) =>
|
509
|
+
act.record = name: @user.name
|
510
|
+
act.meta.info.name.disabled = true
|
511
|
+
act.dont_reload_routes = !reload_routes # true
|
512
|
+
else
|
513
|
+
@invoke().then => @set_access(true, true)
|
514
|
+
|
515
|
+
set_access: (login, load_routes) ->
|
516
|
+
@find_action_info('logout_form').access = login
|
517
|
+
@find_action_info('inspect_modal').access = login
|
518
|
+
@find_action_info('login_form').access = !login
|
519
|
+
$route.load_routes() if load_routes
|
520
|
+
|
521
|
+
login_form: class LoginFormAction extends FormBaseAction
|
522
|
+
panel_menu_default_action: ->
|
523
|
+
super().then =>
|
524
|
+
@parent().user = @user
|
525
|
+
@parent().set_access(true, !@dont_reload_routes)
|
526
|
+
|
527
|
+
logout_form: class LogoutForm extends Action
|
528
|
+
panel_menu_logout: ->
|
529
|
+
@invoke_action('logout').then =>
|
530
|
+
@parent().user = null
|
531
|
+
@parent().set_access(false, true)
|
532
|
+
@panel_close()
|
533
|
+
|
534
|
+
form: class FormAction extends FormBaseAction
|
535
|
+
panel_menu_default_action: ->
|
536
|
+
super().then => @parent().invoke()
|
537
|
+
|
538
|
+
create: class CreateAction extends FormAction
|
539
|
+
invoke: (args) ->
|
540
|
+
if parent_id = @parent().query.parent_id
|
541
|
+
args ?= {}
|
542
|
+
args.parent_id = parent_id
|
543
|
+
super(args)
|
544
|
+
|
545
|
+
modify: class ModifyAction extends FormAction
|
546
|
+
# invoke: (args) ->
|
547
|
+
# super(args).then =>
|
548
|
+
# _.each @meta.primary_fields, (f) => @meta.info[f].disabled = true
|
549
|
+
|
550
|
+
on_change: class OnChangeAction extends Action
|
551
|
+
post_invoke: ->
|
552
|
+
super()
|
553
|
+
@parent().scope().$eval(@meta.execute) if @meta.execute
|
554
|
+
|
555
|
+
confirm: class ConfirmAction extends Action
|
556
|
+
panel_menu_approve: ->
|
557
|
+
@initial_arguments ?= @arguments
|
558
|
+
@invoke_action(@default_action_name, _.pick(@, @initial_arguments)).then (act) =>
|
559
|
+
unless @errors
|
560
|
+
@parent().invoke()
|
561
|
+
@panel_close()
|
562
|
+
|
563
|
+
decode_action: class DecodeAction extends Action
|
564
|
+
initialize: ->
|
565
|
+
super()
|
566
|
+
@decode_field = @scope().f
|
567
|
+
@dinfo = @parentp().meta.info[@decode_field]
|
568
|
+
@scope().$on "search_reset", => @clean()
|
569
|
+
|
570
|
+
if_fk_values: (f) ->
|
571
|
+
fk_values = @dinfo.fields.map((f) => @record()[f])
|
572
|
+
f(fk_values) if _(fk_values).every((f) -> f?) # null_value
|
573
|
+
|
574
|
+
record: ->
|
575
|
+
@parentp().query?.search || @parentp().record
|
576
|
+
|
577
|
+
clear_record: ->
|
578
|
+
_.each @dinfo.fields, (fk) => @record()[fk] = null # null_value
|
579
|
+
|
580
|
+
reset: ->
|
581
|
+
@clean()
|
582
|
+
@parentp().search_live?(@decode_field)
|
583
|
+
|
584
|
+
decode_description: (entry) ->
|
585
|
+
fields = @meta.decode_fields ? @meta.fields
|
586
|
+
fields.map((f) => E2.render_field(entry, f, @meta)).join(@meta.separator)
|
587
|
+
|
588
|
+
parentp: ->
|
589
|
+
@parent().parent()
|
590
|
+
|
591
|
+
decode_list: class DecodeListAction extends DecodeAction
|
592
|
+
initialize: ->
|
593
|
+
super()
|
594
|
+
@multiple = @dinfo.render.multiple
|
595
|
+
@clear_selected()
|
596
|
+
@if_fk_values (fk_values) =>
|
597
|
+
@selected = if @multiple then E2.transpose(fk_values).map(E2.join_keys) else E2.join_keys(fk_values)
|
598
|
+
@invoke()
|
599
|
+
|
600
|
+
clear_selected: -> @selected = if @multiple then [] else null # no need to null complex keys
|
601
|
+
|
602
|
+
post_invoke: (args) ->
|
603
|
+
super()
|
604
|
+
@values = @entries.map (e) => id: E2.id_for(e, @meta), value: @decode_description(e)
|
605
|
+
delete @entries
|
606
|
+
|
607
|
+
change: ->
|
608
|
+
record = @record()
|
609
|
+
if @multiple
|
610
|
+
if @selected.length > 0
|
611
|
+
_.each @dinfo.fields, (fk) -> record[fk] = []
|
612
|
+
_.each @selected, (sel) =>
|
613
|
+
_(@dinfo.fields).zip(E2.split_keys(sel)).each(([fk, k]) => record[fk].push E2.parse_entry(k, @parentp().meta.info[fk])).value
|
614
|
+
else @clear_record()
|
615
|
+
else
|
616
|
+
if @selected
|
617
|
+
_(@dinfo.fields).zip(E2.split_keys(@selected)).each(([fk, k]) => record[fk] = E2.parse_entry(k, @parentp().meta.info[fk])).value
|
618
|
+
else @clear_record()
|
619
|
+
|
620
|
+
@parentp().search_live?(@decode_field)
|
621
|
+
|
622
|
+
clean: ->
|
623
|
+
@clear_selected()
|
624
|
+
@clear_record()
|
625
|
+
|
626
|
+
decode_entry: class DecodeEntryAction extends DecodeAction
|
627
|
+
initialize: ->
|
628
|
+
super()
|
629
|
+
@multiple = @dinfo.render.multiple
|
630
|
+
@if_fk_values (fk_values) =>
|
631
|
+
@invoke_decode (if @multiple then E2.transpose(fk_values) else [fk_values])
|
632
|
+
|
633
|
+
@scope().$on "picked", (ev, sel, sel_meta) =>
|
634
|
+
ev.stopPropagation()
|
635
|
+
record = @record()
|
636
|
+
if @multiple
|
637
|
+
_.each @dinfo.fields, (fk) => record[fk] = []
|
638
|
+
_.each sel, (rec, ids) =>
|
639
|
+
_(@dinfo.fields).zip(E2.split_keys(ids)).each(([k, v]) => record[k].push E2.parse_entry(v, @parentp().meta.info[k])).value
|
640
|
+
@invoke_decode _.values(sel)
|
641
|
+
delete @decode if _.isEmpty(sel)
|
642
|
+
else
|
643
|
+
[ids, rec] = _(sel).toPairs().head()
|
644
|
+
_(@dinfo.fields).zip(E2.split_keys(ids)).each(([k, v]) => record[k] = E2.parse_entry(v, @parentp().meta.info[k])).value
|
645
|
+
@invoke_decode [rec]
|
646
|
+
@parentp().search_live?(@decode_field)
|
647
|
+
|
648
|
+
invoke_decode: (recs, f) ->
|
649
|
+
if @multiple && _.size(recs) > @meta.show_max_selected
|
650
|
+
@decode = "#{_.size(recs)} #{@meta.decode_selected}"
|
651
|
+
else
|
652
|
+
decode_descriptions = (recs) => @decode = recs.map((fields) => @decode_description(fields)).join(' | ')
|
653
|
+
recs = recs.map (r) => if _.isArray(r) then E2.from_id(r, @meta) else r
|
654
|
+
if _(recs).every((r) => _(@meta.fields).every((f) -> r[f]?)) then decode_descriptions(recs) else
|
655
|
+
@invoke(ids: [recs.map((r) => @meta.primary_fields.map (k) -> r[k])]).then => decode_descriptions(@entries)
|
656
|
+
|
657
|
+
open: ->
|
658
|
+
fk_values = @dinfo.fields.map((f) => @record()[f]).filter((f) -> f?)
|
659
|
+
@create_action('list', @scope()).then (action) =>
|
660
|
+
if @multiple
|
661
|
+
action.selection = E2.transpose(fk_values).reduce(((rec, keys) => rec[E2.join_keys(keys)] = E2.from_id(keys, @meta); rec), {})
|
662
|
+
else
|
663
|
+
action.selection[E2.join_keys(fk_values)] = E2.from_id(fk_values, @meta) if fk_values.length > 0
|
664
|
+
action.invoke()
|
665
|
+
|
666
|
+
clean: ->
|
667
|
+
delete @decode
|
668
|
+
@clear_record()
|
669
|
+
|
670
|
+
typeahead: class TypeAheadAction extends DecodeAction
|
671
|
+
initialize: ->
|
672
|
+
super()
|
673
|
+
@if_fk_values (fk_values) =>
|
674
|
+
@invoke(id: E2.join_keys(fk_values)).then =>
|
675
|
+
if @entry
|
676
|
+
@decode = id: E2.id_for(@entry, @meta), value: @decode_description(@entry)
|
677
|
+
|
678
|
+
@scope().$on "$typeahead.select", (e, v, index) =>
|
679
|
+
e.stopPropagation()
|
680
|
+
_(@dinfo.fields).zip(E2.split_keys(@values[index].id)).each(([fk, k]) => @record()[fk] = E2.parse_entry(k, @parentp().meta.info[fk])).value
|
681
|
+
@parentp().search_live?(@decode_field)
|
682
|
+
|
683
|
+
@scope().$watch "action.decode", (e) => if e?
|
684
|
+
@reset() if e.length == 0
|
685
|
+
|
686
|
+
load: (value) ->
|
687
|
+
if value? && value.length > 0 && @key_pressed # check again after strap updates ?
|
688
|
+
@invoke(query: value).then =>
|
689
|
+
if @entries # ?
|
690
|
+
@values = @entries.map (e) => id: E2.id_for(e, @meta), value: @decode_description(e)
|
691
|
+
delete @entries
|
692
|
+
@values
|
693
|
+
|
694
|
+
clean: ->
|
695
|
+
delete @decode
|
696
|
+
@clear_record()
|
697
|
+
|
698
|
+
many_to_one_list: class ManyToOneListAction extends ListAction
|
699
|
+
initialize: ->
|
700
|
+
super()
|
701
|
+
@selection = {}
|
702
|
+
|
703
|
+
select: (index, ev) ->
|
704
|
+
if ev.target.nodeName == "TD"
|
705
|
+
@selection = {} unless @parent().multiple
|
706
|
+
super(index, ev)
|
707
|
+
unless @parent().multiple
|
708
|
+
@scope().$emit "picked", @selection, @meta
|
709
|
+
@panel_close()
|
710
|
+
|
711
|
+
panel_menu_choose: (e) ->
|
712
|
+
# if _.size(@selection) > 0
|
713
|
+
@scope().$emit "picked", @selection, @meta
|
714
|
+
@panel_close()
|
715
|
+
|
716
|
+
star_to_many_list: class StarToManyList extends ListAction
|
717
|
+
initialize: ->
|
718
|
+
super()
|
719
|
+
@query.parent_id = @parent().current_id
|
720
|
+
|
721
|
+
# link_list: implicit
|
722
|
+
item_menu_confirm_unlink: (index) ->
|
723
|
+
@invoke_action('confirm_unlink', id: E2.id_for(@entries[index], @meta), parent_id: @query.parent_id)
|
724
|
+
|
725
|
+
star_to_many_bulk_unlink: class StarToManyBulkUnlinkAction extends Action
|
726
|
+
invoke: ->
|
727
|
+
parent = @parent().parent()
|
728
|
+
super(ids: [_.keys(parent.selection)], parent_id: parent.query.parent_id).then =>
|
729
|
+
parent.selection = {}
|
730
|
+
|
731
|
+
star_to_many_link_list: class StarToManyLinkList extends ListAction
|
732
|
+
initialize: ->
|
733
|
+
super()
|
734
|
+
@query.negate = true
|
735
|
+
@query.parent_id = @parent().query.parent_id
|
736
|
+
@selection = {}
|
737
|
+
|
738
|
+
panel_menu_link: ->
|
739
|
+
selection = _.keys(@selection)
|
740
|
+
if selection.length > 0
|
741
|
+
@invoke_action('link', parent_id: @query.parent_id, ids: selection).then (act) =>
|
742
|
+
unless @errors
|
743
|
+
@parent().invoke()
|
744
|
+
@panel_close()
|
745
|
+
|
746
|
+
star_to_many_field: class StarToManyField extends ListAction
|
747
|
+
initialize: ->
|
748
|
+
super()
|
749
|
+
@query.parent_id = E2.id_for(@parent().record, @parent().meta)
|
750
|
+
links = @parent().record[@scope().$parent.f]
|
751
|
+
@links = links ? (linked: [], unlinked: [])
|
752
|
+
@invoke()
|
753
|
+
|
754
|
+
invoke: ->
|
755
|
+
@query.unlinked = [@links.unlinked]
|
756
|
+
@query.linked = [@links.linked]
|
757
|
+
super()
|
758
|
+
|
759
|
+
sync_record: ->
|
760
|
+
@parent().record[@scope().$parent.f] = @links
|
761
|
+
|
762
|
+
star_to_many_field_link_list: class StarToManyFieldLinkList extends ListAction
|
763
|
+
initialize: ->
|
764
|
+
super()
|
765
|
+
@query.negate = true
|
766
|
+
@query.parent_id = @parent().query.parent_id
|
767
|
+
@selection = {}
|
768
|
+
|
769
|
+
invoke: ->
|
770
|
+
@query.unlinked = [@parent().links.unlinked]
|
771
|
+
@query.linked = [@parent().links.linked]
|
772
|
+
super()
|
773
|
+
|
774
|
+
panel_menu_link: ->
|
775
|
+
if @selected_size() > 0
|
776
|
+
_.each @selection, (v, k) =>
|
777
|
+
id = k
|
778
|
+
if _.includes(@parent().links.unlinked, id) then _.pull(@parent().links.unlinked, id) else @parent().links.linked.push id
|
779
|
+
@parent().invoke()
|
780
|
+
@parent().sync_record()
|
781
|
+
@panel_close()
|
782
|
+
|
783
|
+
star_to_many_field_unlink: class StarToManyFieldUnlink extends Action
|
784
|
+
invoke: (arg) ->
|
785
|
+
id = arg.id
|
786
|
+
pparent = @parent().parent()
|
787
|
+
if _.includes(pparent.links.linked, id) then _.pull(pparent.links.linked, id) else pparent.links.unlinked.push id
|
788
|
+
pparent.sync_record()
|
789
|
+
|
790
|
+
file_store: class FileStoreAction extends Action
|
791
|
+
initialize: ->
|
792
|
+
super()
|
793
|
+
@progress = 0
|
794
|
+
id = E2.id_for(@parent().record, @parent().meta)
|
795
|
+
if id.length > 0
|
796
|
+
@invoke(owner: id).then => @sync_record()
|
797
|
+
else
|
798
|
+
@files = []
|
799
|
+
@sync_record()
|
800
|
+
|
801
|
+
sync_record: ->
|
802
|
+
@parent().record[@scope().f] = @files
|
803
|
+
|
804
|
+
select: (files) ->
|
805
|
+
_.each files, (file) =>
|
806
|
+
upload = $injector.get('Upload').upload url: "#{@action_info().action_resource}/upload", file: file
|
807
|
+
upload.progress (e) =>
|
808
|
+
@progress = parseInt(100.0 * e.loaded / e.total)
|
809
|
+
# @parent().action_pending = true
|
810
|
+
upload.success (data, status, headers, config) =>
|
811
|
+
@files.push mime: file.type, name: file.name, rackname: data.response.rackname, id: data.response.id
|
812
|
+
@message = "Wysłano, #{file.name}"
|
813
|
+
# @parent().action_pending = false
|
814
|
+
@sync_record()
|
815
|
+
|
816
|
+
delete_file: (file) ->
|
817
|
+
@scope().$broadcast 'confirm_delete',
|
818
|
+
confirm: =>
|
819
|
+
@sync_record()
|
820
|
+
file.deleted = true
|
821
|
+
@scope().$broadcast 'confirm_delete_close'
|
822
|
+
|
823
|
+
show_file: (file) ->
|
824
|
+
@file = file
|
825
|
+
@scope().$broadcast 'show_file', file: file
|
826
|
+
|
827
|
+
blob_store: class BlobStore extends Action
|
828
|
+
initialize: ->
|
829
|
+
super()
|
830
|
+
@record_id = E2.id_for(@parent().record, @parent().meta)
|
831
|
+
@progress = 0
|
832
|
+
if @record_id.length > 0
|
833
|
+
@invoke(owner: @record_id) # .then => @sync_record()
|
834
|
+
else
|
835
|
+
# @file = {}
|
836
|
+
# @sync_record()
|
837
|
+
|
838
|
+
sync_record: ->
|
839
|
+
@parent().record[@scope().f] = @file
|
840
|
+
|
841
|
+
select: (files) ->
|
842
|
+
_.each files, (file) =>
|
843
|
+
upload = $injector.get('Upload').upload url: "#{@action_info().action_resource}/upload", file: file
|
844
|
+
upload.progress (e) =>
|
845
|
+
@progress = parseInt(100.0 * e.loaded / e.total)
|
846
|
+
upload.success (data, status, headers, config) =>
|
847
|
+
@file = mime: file.type, name: file.name, rackname: data.response.rackname, id: data.response.id
|
848
|
+
@message = "Wysłano, #{file.name}"
|
849
|
+
@sync_record()
|