app/actions.coffee in engine2-1.0.5 vs app/actions.coffee in engine2-1.0.6

- old
+ new

@@ -132,11 +132,11 @@ prnt = @parent() throw "Attempted parent merge for root action: #{info.name}" unless prnt E2.merge(prnt, response.data) @post_invoke(params) - @scope().$eval(@meta.execute) if @meta.execute + @execute_commands() if @meta.execute if @meta.repeat @scope().$on "$destroy", => @destroyed = true $timeout (=> @invoke(params)), @meta.repeat unless @destroyed delete @meta.repeat @@ -201,28 +201,31 @@ 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 _.each @globals().ws_methods, (method) => ws_method_impl = @["ws_#{method}"] - ws_method_exec = ws_meta.execute?[method] - if ws_method_impl || ws_method_exec - ws_method = (evt) => - is_message = method == 'message' - if is_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) - @process_meta() - else msg = evt - ws_method_impl.bind(@)(msg, ws, evt) if ws_method_impl - @scope().$eval(ws_method_exec) if ws_method_exec + 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) + @process_meta() + else msg = evt + ws_method_impl.bind(@)(msg, ws, evt) if ws_method_impl + @execute_commands() if @meta.execute + delete @meta.execute - ws["on#{_.capitalize(method)}"](ws_method) - @web_socket = -> ws @scope().$on "$destroy", -> ws.close() + execute_commands: -> + scope = @scope() + _.reduce(@meta.execute, ((pr, cmd) -> pr.then -> scope.$eval(cmd)), $q.when()) + + console_log: (o) -> + console.log o + root: class RootAction extends Action initialize: -> super() _.merge(globals, @meta) @meta = {} @@ -266,11 +269,14 @@ get_meta.then (response) => _.each response.data.actions, (act, nm) -> act.name = nm tree.actions ?= _.toArray(response.data.actions) @meta_json = response.data.meta - @action_state = if @meta_json.state then _.zipObject(@meta_json.state.map (k) -> [k, localStorageService.get("#{path}/#{k}")]) else {} + if @meta_json.state + @action_state = {} + _.each @meta_json.state, (s) => @action_state[s] = localStorageService.get("#{@globals().application}/#{path.join('/')}/#{s}") + @action_state , (err) => delete @meta_json @handle_error(err, access: false) @@ -316,11 +322,11 @@ url: '/' + route.name # reloadOnSearch: true 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}}' href-attr='ui-sref' data-animation='{{animation}}'><a href='javascript://'>{{icon}} {{loc}}<span class='caret'></span></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 menu_sub_tmpl dropdown: "routes[#{i}].menu.entries" @@ -343,24 +349,27 @@ super() @query = page: 0, asc: true, search: {} #, search_tab: 0 @ui_state = {} @load_state() - delete @query.order unless @meta.info[@query.order]?.sort # _.includes(@meta.fields, @query.order) - _.each @query.search, ((sv, sn) => delete @query.search[sn] unless _.includes(@meta.search_fields, sn)) + delete @query.order unless @meta.fields[@query.order]?.sort # _.includes(@meta.field_list, @query.order) + _.each @query.search, ((sv, sn) => delete @query.search[sn] unless _.includes(@meta.search_field_list, sn)) destroy: -> @save_state() super() process_meta: -> super() meta = @meta - meta.fields = meta.fields.filter((f) => !meta.info[f].hidden) if meta.fields + meta.field_list = meta.field_list.filter((f) => !meta.fields[f].hidden) if meta.field_list # confirm_create, view, confirm_modify, confirm_delete, assocs - implicit + render_table: -> + @scope().$broadcast 'render_table' + menu_search_toggle: -> @ui_state.search_active = !@ui_state.search_active @save_state() unless @ui_state.search_active menu_refresh: -> @@ -370,12 +379,13 @@ delete @query.order @invoke() menu_select_toggle: -> if @selection then delete @selection else @selection = {} - @scope().$broadcast 'render_table' + @render_table() + 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) @@ -392,21 +402,21 @@ current_id: -> E2.id_for(@current_entry(), @meta) list_cell: (e, f) -> - E2.render_field(e, f, @meta) + E2.render_field(e, f, @meta, "<br>") invoke: (args = {}) -> @save_state() query = _.cloneDeep(@query) delete query.search if _.isEmpty(E2.compact(query.search)) _.merge(query, args) super(query).then => @ui = _.pick @query, ['order', 'asc', 'page'] @ui.pagination_active = @ui.page != 0 || @entries.length >= @meta.config.per_page - @scope().$broadcast 'render_table' + @render_table() load_new: -> @query.page = 0 @invoke() @@ -435,11 +445,11 @@ E2.clean(@query.search) @scope().$broadcast "search_reset" @load_new() search_field_change: (f) -> - info = @meta.info[f] + info = @meta.fields[f] @scope().$eval(info.onchange) if info.onchange if remote_onchange = info.remote_onchange params = value: @query.search[f] @@ -463,98 +473,110 @@ _.size(@selection) selected_info: -> @meta.loc.selected + ": " + @selected_size() + entry_dropped: (moved_to, render = true) -> + from = @entries[@moved_from] + @entries.splice(@moved_from, 1) + @entries.splice((if moved_to > @moved_from then moved_to - 1 else moved_to), 0, from) + delete @moved_from + @render_table() if render + true + + entry_moved: (index) -> + @moved_from = index + bulk_delete: class BulkDeleteAction extends Action invoke: -> super(ids: [_.keys(@parent().parent().selection)]).then => @parent().parent().selection = {} view: class ViewAction extends Action view_cell: (e, f) -> - E2.render_field(e, f, @meta) + E2.render_field(e, f, @meta, "<br>") form_base_action: class FormBaseAction extends Action initialize: -> super() - _.each @meta.info, (info, name) => + _.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.tabs + 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.info, (info, name) => + _.each @meta.fields, (info, name) => if _.isString(@record[name]) && !info.dont_strip @record[name] = @record[name].trim() panel_menu_default_action: -> - _.each @meta.info, (v, n) => + _.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 - if @meta.tabs + if @meta.tab_list [i, first, curr] = [0, null, false] - for tab in @meta.tabs - if _(tab.fields).find((f) => @errors[f]) + for tab_name in @meta.tab_list + tab = @meta.tabs[tab_name] + if _(tab.field_list).find((f) => @errors[f]) first = i if not first? act = true if @activeTab == i i++ @activeTab = first unless act if @activeTab? - field = _(@meta.tabs[@activeTab].fields).find((f) => @errors[f]) + field = _(@meta.tabs[@meta.tab_list[@activeTab]].field_list).find((f) => @errors[f]) # console.log field undefined ? else @activeTab = 0 @alert = @errors else - field = _(@meta.fields).find((f) => @errors[f]) - @alert = @errors if (!field || !@meta.info[field] || @meta.info[field].hidden) # ? + field = _(@meta.field_list).find((f) => @errors[f]) + @alert = @errors if (!field || !@meta.fields[field] || @meta.fields[field].hidden) # ? $timeout => @scope().$broadcast("focus_field", field) #e.scope.$eval(meta.execute) if meta.execute # ? dfd.resolve() else dfd.resolve(@record) # $q.when(true) ? dfd.promise panel_shown: -> - field = if @meta.tabs - tab = @meta.tabs[@activeTab] + field = if @meta.tab_list + tab = @meta.tabs[@meta.tab_list[@activeTab]] if @errors - _(tab.fields).find((f) => @errors[f]) || _(tab.fields).find((f) => !@meta.info[f].hidden) + _(tab.field_list).find((f) => @errors[f]) || _(tab.field_list).find((f) => !@meta.fields[f].hidden) else - tab ?= @meta.tabs[0] - _(tab.fields).find((f) => !@meta.info[f].hidden && !@meta.info[f].disabled) + tab ?= @meta.tabs[@meta.tab_list[0]] + _(tab.field_list).find((f) => !@meta.fields[f].hidden && !@meta.fields[f].disabled) else - _(@meta.fields).find((f) => !@meta.info[f].hidden && !@meta.info[f].disabled) + _(@meta.field_list).find((f) => !@meta.fields[f].hidden && !@meta.fields[f].disabled) $timeout (=> @scope().$broadcast("focus_field", field)), 300 # hack, on shown ? infra: class InfraAction extends Action initialize: -> super() @scope().$on "relogin", (evt, reload_routes, create) => if @user @invoke_action('login_form').then (act) => act.record = name: @user.name - act.meta.info.name.disabled = true + act.meta.fields.name.disabled = true act.dont_reload_routes = !reload_routes # true else @invoke().then => @set_access(true, true, @user) @scope().$on "set_access", (evt, login, load_routes, user) => @set_access(login, load_routes, user) @@ -589,27 +611,22 @@ super(args) modify: class ModifyAction extends FormAction # invoke: (args) -> # super(args).then => - # _.each @meta.primary_fields, (f) => @meta.info[f].disabled = true + # _.each @meta.primary_fields, (f) => @meta.fields[f].disabled = true - on_change: class OnChangeAction extends Action - post_invoke: -> - super() - @parent().scope().$eval(@meta.execute) if @meta.execute - confirm: class ConfirmAction extends Action panel_menu_approve: -> @initial_arguments ?= @arguments @invoke_action(@default_action_name, _.pick(@, @initial_arguments)) decode_action: class DecodeAction extends Action initialize: -> super() @decode_field = @scope().f - @dinfo = @parentp().meta.info[@decode_field] + @dinfo = @parentp().meta.fields[@decode_field] throw "Primary and foreign key list lengths dont match: [#{@meta.primary_fields}] and [#{@dinfo.fields}]" unless @meta.primary_fields.length == @dinfo.fields.length @scope().$on "search_reset", => @clean() if_fk_values: (f) -> fk_values = @dinfo.fields.map((f) => @record()[f]) @@ -624,11 +641,11 @@ reset: -> @clean() @parentp().search_field_change?(@decode_field) decode_description: (entry) -> - @meta.decode_fields.map((f) => E2.render_field(entry, f, @meta)).join(@meta.separator) + @meta.decode_fields.map((f) => E2.render_field(entry, f, @meta, ', ')).join(@meta.separator) parentp: -> @parent().parent() decode_list: class DecodeListAction extends DecodeAction @@ -651,15 +668,15 @@ record = @record() if @multiple if @selected.length > 0 _.each @dinfo.fields, (fk) -> record[fk] = [] _.each @selected, (sel) => - _(@dinfo.fields).zip(E2.split_keys(sel)).each(([fk, k]) => record[fk].push E2.parse_entry(k, @parentp().meta.info[fk])).value + _(@dinfo.fields).zip(E2.split_keys(sel)).each(([fk, k]) => record[fk].push E2.parse_entry(k, @parentp().meta.fields[fk])).value else @clear_record() else if @selected - _(@dinfo.fields).zip(E2.split_keys(@selected)).each(([fk, k]) => record[fk] = E2.parse_entry(k, @parentp().meta.info[fk])).value + _(@dinfo.fields).zip(E2.split_keys(@selected)).each(([fk, k]) => record[fk] = E2.parse_entry(k, @parentp().meta.fields[fk])).value else @clear_record() @parentp().search_field_change?(@decode_field) clean: -> @@ -677,26 +694,26 @@ ev.stopPropagation() record = @record() if @multiple _.each @dinfo.fields, (fk) => record[fk] = [] _.each sel, (rec, ids) => - _(@dinfo.fields).zip(E2.split_keys(ids)).each(([k, v]) => record[k].push E2.parse_entry(v, @parentp().meta.info[k])).value + _(@dinfo.fields).zip(E2.split_keys(ids)).each(([k, v]) => record[k].push E2.parse_entry(v, @parentp().meta.fields[k])).value @invoke_decode _.values(sel) delete @decode if _.isEmpty(sel) else [ids, rec] = _(sel).toPairs().head() - _(@dinfo.fields).zip(E2.split_keys(ids)).each(([k, v]) => record[k] = E2.parse_entry(v, @parentp().meta.info[k])).value + _(@dinfo.fields).zip(E2.split_keys(ids)).each(([k, v]) => record[k] = E2.parse_entry(v, @parentp().meta.fields[k])).value @invoke_decode [rec] @parentp().search_field_change?(@decode_field) invoke_decode: (recs, f) -> if @multiple && _.size(recs) > @meta.show_max_selected @decode = "#{_.size(recs)} #{@meta.loc.decode_selected}" else decode_descriptions = (recs) => @decode = recs.map((fields) => @decode_description(fields)).join(' | ') recs = recs.map (r) => if _.isArray(r) then E2.from_id(r, @meta) else r - if _(recs).every((r) => _(@meta.fields).every((f) -> r[f]?)) && !@meta.dynamic_meta then decode_descriptions(recs) else + if _(recs).every((r) => _(@meta.field_list).every((f) -> r[f]?)) && !@meta.dynamic_meta then decode_descriptions(recs) else @invoke(ids: [recs.map((r) => @meta.primary_fields.map (k) -> r[k])]).then => decode_descriptions(@entries) open: -> fk_values = @dinfo.fields.map((f) => @record()[f]).filter((f) -> f?) @create_action('list', @scope()).then (action) => @@ -718,11 +735,11 @@ 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.info[fk])).value + _(@dinfo.fields).zip(E2.split_keys(@values[index].id)).each(([fk, k]) => @record()[fk] = E2.parse_entry(k, @parentp().meta.fields[fk])).value @parentp().search_field_change?(@decode_field) @scope().$watch "action.decode", (e) => if e? @reset() if e.length == 0 @@ -793,12 +810,27 @@ invoke: -> @query.changes = @changes super() - current_entry_is: (mode) -> - key = E2.id_for(@current_entry(), @meta) + entry_dropped: (moved_to) -> + pos_field = @meta.draggable.position_field + positions = @entries.map (e) -> e[pos_field] + super(moved_to, false) + _.each positions, (p, i) => + if @entries[i][pos_field] != p + if entry = @current_entry_is('create', @entries[i]) ? @current_entry_is('modify', @entries[i]) + entry[pos_field] = p + else + @changes.modify.push(@entries[i]) + @entries[i][pos_field] = p + + @render_table() # @invoke() + true + + current_entry_is: (mode, entry = @current_entry()) -> + key = E2.id_for(entry, @meta) _.find(@changes[mode], (e) => E2.id_for(e, @meta) == key) star_to_many_field_view: class StarToManyFieldView extends ViewAction invoke: (args) -> if entry = @parent().current_entry_is('create') ? @parent().current_entry_is('modify') @@ -823,9 +855,12 @@ _.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) + 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 star_to_many_field_delete: class StarToManyFieldDelete extends Action invoke: (args) -> pparent = @parent().parent()