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