app/actions.coffee in engine2-1.0.8 vs app/actions.coffee in engine2-1.0.9
- old
+ new
@@ -49,13 +49,20 @@
act = act.parent() while act && !act.meta.panel
unless act # no modal for top level panels
@meta.panel.modal_action = false
@meta.panel.footer = true unless @meta.panel.footer == false
+
+ if scope && @meta.invokable != false
+ scope.$on action_info.action_resource, (e, args) => @invoke(args)
+
@websocket_connect() if @meta.websocket
@initialize()
+ broadcast: (sub_action, args) ->
+ @scope().$broadcast(@action_info().action_resource + '/' + sub_action, args)
+
initialize: ->
@process_static_meta()
console.info "CREATE #{@action_info().action_resource}"
process_static_meta: ->
@@ -66,11 +73,17 @@
handle_error: (err, action_info, element, create) ->
if err.status == 401
if action_info.access
$rootScope.$broadcast "relogin", element?, create
else
- @globals().modal().error("#{err.status}: #{err.data.message}", err.data.cause || err.data.message)
+ tle = "#{err.status}: #{err.data.message}"
+ msg = err.data.cause || err.data.message
+ if msg.length > 500
+ @globals().modal().error(tle, msg)
+ else
+ @globals().toastr().error(tle, msg, extendedTimeOut: 5000, closeButton: true)
+
$q.reject(err)
save_state: () ->
_.each @meta.state, (s) => localStorageService.set("#{@globals().application}/#{@action_info().action_resource}/#{s}", @[s])
load_state: () ->
@@ -98,55 +111,64 @@
invoke_action: (name, args) ->
@create_action(name, @scope()).then (act) -> act.invoke(args)
create_action_path: (action_names, sc, elem) ->
last_name = action_names.pop()
- _.reduce(action_names, ((pr, nm) -> pr.then (act) -> act.create_action(nm)), $q.when(@)).then (act) ->
+ _.reduce(action_names, ((pr, nm) -> pr.then (act) -> act.create_action(nm)), $q.when(@)).then (act) -> # self = @
act.create_action(last_name, sc, elem).then (act) -> sc.action = act
globals: -> globals
+ _ : -> _
+ current: -> @globals().current_action
action_pending: -> globals.action_pending == @
pre_invoke: ->
post_invoke: ->
invoke: (params) ->
+ @globals().current_action = @
params ?= {}
@globals().action_pending = if @meta.panel then @ else @parent()
@pre_invoke(params)
- _.merge(params, @meta.arguments) if @meta.arguments
+ if @meta.arguments # _.merge(params, @meta.arguments)
+ _.each @meta.arguments, (v, k) =>
+ if _.endsWith(k, '!') then params[k.slice(0, -1)] = @scope().$eval(v) else params[k] = v
+
info = @action_info()
get_invoke = if @meta.invokable == false then $q.when(data: (response: {})) else
params.initial = true if @meta.panel && !@action_invoked && info.method == 'get'
$http[info.method](info.action_resource, if info.method == 'post' then params else (params: params))
+ @execute_commands('pre_execute')
get_invoke.then (response) =>
@arguments = _.keys(response.data)
- E2.merge(@, response.data)
+ E2.merge_meta(@, response.data)
@process_meta()
promise = if @meta.panel # persistent action
if !@action_invoked
@action_invoked = true
@panel_render()
else
prnt = @parent()
throw "Attempted parent merge for root action: #{info.name}" unless prnt
- E2.merge(prnt, response.data)
+ E2.merge_meta(prnt, response.data)
@post_invoke(params)
- @execute_commands() if @meta.execute
+ @execute_commands('execute')
if @meta.repeat
@scope().$on "$destroy", => @destroyed = true
$timeout (=> @invoke(params)), @meta.repeat unless @destroyed
delete @meta.repeat
@globals().action_pending = false
+ @globals().current_action = null
promise
,
(err) =>
@globals().action_pending = false
+ @globals().current_action = null
@handle_error(err, info, @element())
panel_render: ->
if @meta.panel.modal_action
if @element()
@@ -201,30 +223,32 @@
@panel_close()
websocket_connect: ->
l = $location
ws_meta = @meta.websocket
- ws = $websocket "ws#{l.protocol().slice(4, 5)}://#{l.host()}:#{l.port()}/#{@action_info().action_resource}", undefined, ws_meta.options
+ ws = $websocket "ws#{l.protocol().slice(4, 5)}://#{l.host()}:#{l.port()}#{'/'}#{@action_info().action_resource}", undefined, ws_meta.options
_.each @globals().ws_methods, (method) =>
ws_method_impl = @["ws_#{method}"]
ws["on#{_.capitalize(method)}"] (evt) =>
if method == 'message'
msg = JSON.parse(evt.data)
if msg.error then @globals().modal().error("WebSocket [#{evt.origin}] - #{msg.error.method}", msg.error.exception) else
- E2.merge(@, msg)
+ E2.merge_meta(@, msg)
@process_meta()
else msg = evt
ws_method_impl.bind(@)(msg, ws, evt) if ws_method_impl
- @execute_commands() if @meta.execute
- delete @meta.execute
+ @execute_commands('execute')
@web_socket = -> ws
@scope().$on "$destroy", -> ws.close()
- execute_commands: ->
- scope = @scope()
- _.reduce(@meta.execute, ((pr, cmd) -> pr.then -> scope.$eval(cmd)), $q.when())
+ execute_commands: (execute) ->
+ if @meta[execute]
+ scope = @scope()
+ _.reduce(@meta[execute], ((pr, cmd) -> pr.then -> scope.$eval(cmd)), $q.when())
+ @meta[execute].splice(0, @meta[execute].length)
+ delete @meta[execute]
console_log: (o) ->
console.log o
root: class RootAction extends Action
@@ -301,11 +325,11 @@
_.each $stateRegistry.get(), (s) -> $stateRegistry.deregister(s.name) unless _.isEmpty(s.name)
otherwise = menu.properties.default ? menu.entries[0].name
$urlRouter.otherwise(otherwise)
@register(menu.entries)
@scope().routes = menu.entries
- out = if _.size(menu.entries) == 0 then angular.element("<div></div>") else $compile(@traverse(menu.entries))(@scope())
+ out = $compile(@traverse(menu.entries))(@scope())
@element().replaceWith(out)
@element = -> out
loc = $location.path().slice(1)
@globals().state().go(if init && !_.isEmpty($location.path()) && $stateRegistry.get(loc)? then loc else otherwise)
@@ -329,11 +353,13 @@
traverse: (routes) ->
menu_tmpl = _.template("<li {{show}} {{hide}} ui-sref-active='active'><a {{href}}>{{icon}} {{loc}}</a></li>")
menu_sub_tmpl = _.template("<li {{show}} {{hide}} e2-dropdown='{{dropdown}}' nav='true' data-animation='{{animation}}'><a href='javascript://'>{{icon}} {{loc}}<span class='caret'></span></a></li>")
animation = @meta.menus.menu.properties.animation
out = routes.map (route, i) ->
- if route.menu
+ if route.render == false
+ ''
+ else if route.menu
menu_sub_tmpl
dropdown: "routes[#{i}].menu.entries"
animation: animation
loc: route.menu.loc
show: route.show && "ng-show=\"#{route.show}\"" || ''
@@ -344,11 +370,12 @@
href: "ui-sref='#{route.name}'"
loc: route.loc
show: route.show && "ng-show=\"#{route.show}\"" || ''
hide: route.hide && "ng-hide=\"#{route.hide}\"" || ''
icon: route.icon && E2.icon(route.icon) || ''
- out.join('')
+ out = out.join('')
+ if _.size(out) == 0 then "<div></div>" else out
list: class ListAction extends Action
initialize: ->
super()
@query = page: 0, asc: true, search: {} #, search_tab: 0
@@ -389,11 +416,11 @@
menu_show_meta: ->
@globals().modal().show
the_meta: @meta
- meta: panel: (panel_template: "close_m", template_string: "<pre>{{action.the_meta | json}}</pre>", title: "Meta", class: "modal-huge", backdrop: true, footer: true)
+ meta: panel: (panel_template: "close_m", template_string: "<pre>{{action.the_meta | yaml}}</pre>", title: "Meta", class: "modal-huge", backdrop: true, footer: true)
# show_assoc: (index, assoc) ->
# # parent_id = E2.id_for(@entries[index], @meta)
# # @create_action(assoc, @scope(), null, parent_id).then (action) =>
# # action.query.parent_id = parent_id # E2.id_for(@entries[index], @meta)
@@ -451,16 +478,16 @@
@load_new()
search_field_change: (f) ->
info = @meta.fields[f]
- @scope().$eval(info.onchange) if info.onchange
+ @scope().$eval(info.onchange.action) if info.onchange
if remote_onchange = info.remote_onchange
params = value: @query.search[f]
- params.record = @query.search if info.remote_onchange_record
- @invoke_action(remote_onchange, params).then =>
+ params.record = @query.search if remote_onchange.record
+ @invoke_action(remote_onchange.action, params).then =>
@load_new() if info.search_live
else
@load_new() if info.search_live
selected_class: (index) ->
@@ -488,10 +515,15 @@
true
entry_moved: (index) ->
@moved_from = index
+ list_parent_action: ->
+ parent = @parent()
+ parent = parent.parent() until parent instanceof ListAction
+ parent
+
bulk_delete: class BulkDeleteAction extends Action
invoke: ->
super(ids: [_.keys(@parent().parent().selection)]).then =>
@parent().parent().selection = {}
@@ -500,36 +532,39 @@
E2.render_field(e, f, @meta, "<br>")
form_base_action: class FormBaseAction extends Action
initialize: ->
super()
- _.each @meta.fields, (info, name) =>
- if info.remote_onchange
- @scope().$watch (=> @record?[name]), (n) => if n? #if typeof(n) != "undefined"
- params = value: @record[name]
- params.record = @record if info.remote_onchange_record
- @invoke_action(info.remote_onchange, params)
-
- if info.onchange
- @scope().$watch (=> @record?[name]), (n) => if n?
- @scope().$eval(info.onchange)
-
if @meta.tab_list
@scope().$watch "action.activeTab", (tab) => if tab? # && tab >= 0
@panel_shown()
@["panel_menu_#{@default_action_name}"] = -> @panel_menu_default_action()
post_invoke: (args) ->
super()
_.each @meta.fields, (info, name) =>
- if _.isString(@record[name]) && !info.dont_strip
+ if @record[name] is undefined
+ @record[name] = null
+ else if _.isString(@record[name]) && !info.dont_strip
@record[name] = @record[name].trim()
+ if info.onchange || info.remote_onchange
+ onchange = => @scope().$eval(info.onchange.action)
+ remote_onchange = =>
+ params = value: @record[name]
+ params.record = @record if info.remote_onchange.record
+ @invoke_action(info.remote_onchange.action, params)
+
+ @scope().$watch (=> @record[name]), (n, o) => if n != o
+ onchange() if info.onchange
+ remote_onchange() if info.remote_onchange
+
+ onchange() if info.onchange?.trigger_on_start
+ remote_onchange() if info.remote_onchange?.trigger_on_start
+
panel_menu_default_action: ->
- _.each @meta.fields, (v, n) =>
- @record[n] = null if @record[n] is undefined
params = record: @record
params.parent_id ?= @parent().query?.parent_id # and StarToManyList ?
@invoke_action(@default_action_name, params).then =>
dfd = $q.defer()
if @errors
@@ -732,33 +767,35 @@
@clear_record()
typeahead: class TypeAheadAction extends DecodeAction
initialize: ->
super()
- @if_fk_values (fk_values) =>
- @invoke(id: E2.join_keys(fk_values)).then =>
- if @entry
- @decode = id: E2.id_for(@entry, @meta), value: @decode_description(@entry)
-
@scope().$on "$typeahead.select", (e, v, index) =>
e.stopPropagation()
_(@dinfo.fields).zip(E2.split_keys(@values[index].id)).each(([fk, k]) => @record()[fk] = E2.parse_entry(k, @parentp().meta.fields[fk])).value
+ @parentp().scope().$digest()
@parentp().search_field_change?(@decode_field)
- @scope().$watch "action.decode", (e) => if e?
- @reset() if e.length == 0
+ @scope().$watch "action.decode", (e) => @reset() if e == null
+ @if_fk_values (fk_values) =>
+ @invoke(id: E2.join_keys(fk_values)).then =>
+ if @entry
+ @decode = id: E2.id_for(@entry, @meta), value: @decode_description(@entry)
+
+ @decode = '' unless @decode?
+ # @dinfo.render.min_length == 0
+
load: (value) ->
- if value? && value.length > 0 && @key_pressed # check again after strap updates ?
- @invoke(query: value).then =>
- if @entries # ?
- @values = @entries.map (e) => id: E2.id_for(e, @meta), value: @decode_description(e)
- delete @entries
- @values
+ if _.isString(value)
+ @invoke(query: value).then => if @entries # ?
+ @values = @entries.map (e) => id: E2.id_for(e, @meta), value: @decode_description(e)
+ delete @entries
+ @values
clean: ->
- delete @decode
+ @decode = ''
@clear_record()
many_to_one_list: class ManyToOneListAction extends ListAction
initialize: ->
super()
@@ -778,11 +815,11 @@
@panel_close()
star_to_many_list: class StarToManyList extends ListAction
initialize: ->
super()
- @query.parent_id = @parent().current_id()
+ @query.parent_id = @list_parent_action().current_id()
# link_list: implicit
item_menu_confirm_unlink: (args) ->
args.parent_id = @query.parent_id
@item_menu_confirm_unlink_super(args)
@@ -858,10 +895,10 @@
if entry = pparent.current_entry_is('create') ? pparent.current_entry_is('modify')
_.assign(entry, @parent().record)
else
pparent.changes.modify.push @parent().record
else # CreateAction
- _(@parent().meta.primary_fields).each (k) => @parent().record[k] = E2.uuid(5)
+ _(@parent().meta.primary_fields).each (k) => @parent().record[k] = E2.uuid()
if draggable = pparent.meta.draggable
max = _.maxBy(pparent.entries, (e) -> e.position)
@parent().record[draggable.position_field] = if max then max[draggable.position_field] + 1 else 1
pparent.changes.create.push @parent().record