diff --git a/app/assets/javascripts/app/controllers/_ui_element/object_manager_attribute.coffee b/app/assets/javascripts/app/controllers/_ui_element/object_manager_attribute.coffee index ebd2a3222..1d9648b2d 100644 --- a/app/assets/javascripts/app/controllers/_ui_element/object_manager_attribute.coffee +++ b/app/assets/javascripts/app/controllers/_ui_element/object_manager_attribute.coffee @@ -6,11 +6,10 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi updateDataMap = (localParams, localAttribute, localAttributes, localClassname, localForm, localA) => localItem = localForm.closest('.js-data') - values = [] - values = {a: 123, b: 'aaa'} + console.log('updateDataMap', attribute, params) element = $(App.view("object_manager/attribute/#{localParams.data_type}")( attribute: attribute - values: values + params: params )) @[localParams.data_type](element, localParams, params) localItem.find('.js-dataMap').html(element) @@ -20,10 +19,10 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi datetime: 'Datetime' date: 'Date' input: 'Text' - # select: 'Select' - # boolean: 'Boolean' - # integer: 'Integer' - # autocompletion: 'Autocompletion (AJAX remote URL)' + select: 'Select' + boolean: 'Boolean' + integer: 'Integer' + autocompletion: 'Autocompletion (AJAX remote URL)' configureAttributes = [ { name: attribute.name, display: '', tag: 'select', null: false, options: options, translate: true, default: 'input', disabled: attribute.disabled }, @@ -149,7 +148,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi params: params ) configureAttributes = [ - { name: 'data_option::type', display: 'Type', tag: 'select', null: false, default: 'text', options: {text: 'Text', phone: 'Phone', fax: 'Fax', email: 'Email', url: 'Url'}, translate: true }, + { name: 'data_option::type', display: 'Type', tag: 'select', null: false, default: 'text', options: {text: 'Text', tel: 'Phone', email: 'Email', url: 'Url'}, translate: true }, ] inputType = new App.ControllerForm( model: @@ -267,6 +266,27 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi item.find('.js-integerMax').html(integerMax.form) @select: (item, localParams, params) -> + item.find('.js-add').on('click', (e) -> + addRow = $(e.target).closest('tr') + key = addRow.find('.js-key').val() + value = addRow.find('.js-value').val() + addRow.find('.js-selected[value]').attr('value', key) + selected = addRow.find('.js-selected').prop('checked') + newRow = item.find('.js-template').clone().removeClass('js-template') + newRow.find('.js-key').val(key) + newRow.find('.js-value').val(value) + newRow.find('.js-value[value]').attr('name', "data_option::options::#{key}") + newRow.find('.js-selected').prop('checked', selected) + newRow.find('.js-selected').val(key) + newRow.find('.js-selected').attr('name', 'data_option::default') + item.find('.js-Table tr').last().before(newRow) + addRow.find('.js-key').val('') + addRow.find('.js-value').val('') + addRow.find('.js-selected').prop('checked', false) + ) + item.on('click', '.js-remove', (e) -> + $(e.target).closest('tr').remove() + ) @boolean: (item, localParams, params) -> diff --git a/app/assets/javascripts/app/views/object_manager/attribute/select.jst.eco b/app/assets/javascripts/app/views/object_manager/attribute/select.jst.eco index 600b2908f..e385f6ca5 100644 --- a/app/assets/javascripts/app/views/object_manager/attribute/select.jst.eco +++ b/app/assets/javascripts/app/views/object_manager/attribute/select.jst.eco @@ -2,7 +2,7 @@
- +
- <% for key, display of @values: %> - - +
<%- @T('Key') %> @@ -11,31 +11,46 @@ <%- @T('Action') %>
- - - - - - -
- <%- @Icon('trash') %> <%- @T('Remove') %> -
+ <% if @params.data_option && @params.data_option.options: %> + <% for key, display of @params.data_option.options: %> +
+ + + + + checked<% end %>/> + +
+ <%- @Icon('trash') %> <%- @T('Remove') %> +
+ <% end %> <% end %> -
- + - + - +
<%- @Icon('plus-small') %> <%- @T('Add') %>
+ + + + \ No newline at end of file diff --git a/app/controllers/object_manager_attributes_controller.rb b/app/controllers/object_manager_attributes_controller.rb index bddae29e4..3a6aeecd6 100644 --- a/app/controllers/object_manager_attributes_controller.rb +++ b/app/controllers/object_manager_attributes_controller.rb @@ -110,6 +110,9 @@ class ObjectManagerAttributesController < ApplicationController private def check_params + if params[:data_option] && !params[:data_option].key?(:default) + params[:data_option][:default] = '' + end return if !params[:data_option][:null].nil? params[:data_option][:null] = true end diff --git a/app/models/object_manager/attribute.rb b/app/models/object_manager/attribute.rb index 1f95be405..891559913 100644 --- a/app/models/object_manager/attribute.rb +++ b/app/models/object_manager/attribute.rb @@ -103,6 +103,7 @@ possible types 'aa' => 'aa (comment)', 'bb' => 'bb (comment)', }, + nulloption: true, null: false, multiple: false, # currently only "false" supported translate: true, # optional @@ -485,7 +486,7 @@ returns if attribute.to_delete if model.column_names.include?(attribute.name) ActiveRecord::Migration.remove_column model.table_name, attribute.name - model.reset_column_information + reset_database_info(model) end execute_count += 1 attribute.destroy @@ -538,7 +539,7 @@ returns # restart processes attribute.to_migrate = false attribute.save! - model.reset_column_information + reset_database_info(model) execute_count += 1 next end @@ -586,22 +587,22 @@ returns attribute.to_delete = false attribute.save! - model.reset_column_information + reset_database_info(model) execute_count += 1 } # sent reload to clients if execute_count != 0 - pid = fork do - $stdout.reopen('out.txt', 'w') - $stderr.reopen('err.txt', 'w') - AppControl.restart - end - + AppVersion.set(true) end true end + def self.reset_database_info(model) + model.connection.schema_cache.clear! + model.reset_column_information + end + def check_name return if !name if name =~ /_(id|ids)$/i || name =~ /^id$/i @@ -652,6 +653,9 @@ returns if data_type == 'select' || data_type == 'checkbox' raise 'Need data_option[:default] param' if data_option[:default].nil? raise 'Invalid data_option[:options] or data_option[:relation] param' if data_option[:options].nil? && data_option[:relation].nil? + if !data_option.key?(:nulloption) + data_option[:nulloption] = true + end end if data_type == 'boolean' diff --git a/lib/sessions.rb b/lib/sessions.rb index 5956903de..ed53c0838 100644 --- a/lib/sessions.rb +++ b/lib/sessions.rb @@ -351,7 +351,7 @@ send message to all authenticated client returns - true|false + [array_with_client_ids_of_recipients] broadcase also to not authenticated client @@ -366,6 +366,7 @@ broadcase also not to sender def self.broadcast(data, recipient = 'autenticated', sender_user_id = nil) # list all current clients + recipients = [] client_list = sessions client_list.each {|client_id| session = Sessions.get(client_id) @@ -380,8 +381,9 @@ broadcase also not to sender next if session[:user] && session[:user]['id'] && session[:user]['id'].to_i == sender_user_id.to_i end Sessions.send(client_id, data) + recipients.push client_id } - true + recipients end =begin diff --git a/test/browser/admin_object_manager_test.rb b/test/browser/admin_object_manager_test.rb index 914761f69..4739eba71 100644 --- a/test/browser/admin_object_manager_test.rb +++ b/test/browser/admin_object_manager_test.rb @@ -12,95 +12,55 @@ class AdminObjectManagerTest < TestCase ) tasks_close_all() - click(css: 'a[href="#manage"]') - click(css: 'a[href="#system/object_manager"]') - - click(css: '#content .js-new') - - modal_ready() - # already existing - set( - css: '.modal input[name="name"]', - value: 'customer_id', - ) - set( - css: '.modal input[name="display"]', - value: 'Customer Should Not Creatable', - ) - click(css: '.modal button.js-submit') - sleep 4 - watch_for( - css: '.modal', - value: '(already exists)', + object_manager_attribute_create( + data: { + name: 'customer_id', + display: 'Customer Should Not Creatable', + data_type: 'Text', + }, + error: 'already exists' ) # invalid name - set( - css: '.modal input[name="name"]', - value: 'some_other_id', - ) - set( - css: '.modal input[name="display"]', - value: 'Should Not Creatable', - ) - click(css: '.modal button.js-submit') - sleep 4 - watch_for( - css: '.modal', - value: '(are not allowed)', + object_manager_attribute_create( + data: { + name: 'some_other_id', + display: 'Should Not Creatable', + data_type: 'Text', + }, + error: 'are not allowed' ) # invalid name - set( - css: '.modal input[name="name"]', - value: 'some_other_ids', - ) - set( - css: '.modal input[name="display"]', - value: 'Should Not Creatable', - ) - click(css: '.modal button.js-submit') - sleep 4 - watch_for( - css: '.modal', - value: '(are not allowed)', + object_manager_attribute_create( + data: { + name: 'some_other_ids', + display: 'Should Not Creatable', + data_type: 'Text', + }, + error: 'are not allowed' ) # invalid name - set( - css: '.modal input[name="name"]', - value: 'some spaces', + object_manager_attribute_create( + data: { + name: 'some spaces', + display: 'Should Not Creatable', + data_type: 'Text', + }, + error: 'are not allowed' ) - set( - css: '.modal input[name="display"]', - value: 'Should Not Creatable', - ) - click(css: '.modal button.js-submit') - sleep 4 - watch_for( - css: '.modal', - value: '(are not allowed)', - ) - click(css: '.modal .js-close') - modal_ready() # valid name - click(css: '#content .js-new') - modal_ready() - set( - css: '.modal input[name="name"]', - value: 'browser_test1', - ) - set( - css: '.modal input[name="display"]', - value: 'Browser Test 1', - ) - click(css: '.modal button.js-submit') - watch_for( - css: '#content table', - value: 'browser_test1', + object_manager_attribute_create( + data: { + name: 'browser_test1', + display: 'Browser Test 1', + data_type: 'Text', + }, ) + watch_for( css: '#content', value: 'Database Update required', @@ -180,4 +140,38 @@ class AdminObjectManagerTest < TestCase ) end + def test_basic_b + @browser = browser_instance + login( + username: 'master@example.com', + password: 'test', + url: browser_url, + ) + tasks_close_all() + + object_manager_attribute_create( + data: { + name: 'browser_test2', + display: 'Browser Test 2', + data_type: 'Select', + data_option: { + options: { + 'aa' => 'AA', + 'bb' => 'BB', + }, + }, + }, + ) + + sleep 10 + + object_manager_attribute_discard_changes + + #object_manager_attribute_delete( + # data: { + # name: 'browser_test2', + # }, + #) + end + end diff --git a/test/browser_test_helper.rb b/test/browser_test_helper.rb index be6e0c86c..a24ad808a 100644 --- a/test/browser_test_helper.rb +++ b/test/browser_test_helper.rb @@ -2717,6 +2717,13 @@ wait untill text in selector disabppears data: { name: 'field_name' + random, display: 'Display Name of Field', + data_type: 'Text', # Text|Select|... + data_option: { + options: { + 'aa' => 'AA', + 'bb' => 'BB', + }, + }, }, error: 'already exists' ) @@ -2753,6 +2760,26 @@ wait untill text in selector disabppears element = instance.find_elements(css: '.modal input[name=display]')[0] element.clear element.send_keys(data[:display]) + select( + browser: instance, + css: '.modal select[name="data_type"]', + value: data[:data_type], + mute_log: true, + ) + if data[:data_option] + if data[:data_option][:options] + data[:data_option][:options].each {|key, value| + element = instance.find_elements(css: '.modal .js-Table .js-key').last + element.clear + element.send_keys(key) + element = instance.find_elements(css: '.modal .js-Table .js-value').last + element.clear + element.send_keys(value) + element = instance.find_elements(css: '.modal .js-Table .js-add')[0] + element.click + } + end + end instance.find_elements(css: '.modal button.js-submit')[0].click if params[:error] sleep 4 @@ -2782,6 +2809,75 @@ wait untill text in selector disabppears raise 'object manager attribute creation failed' end +=begin + + object_manager_attribute_delete( + browser: browser2, + data: { + name: 'field_name' + random, + }, + ) + +=end + + def object_manager_attribute_delete(params = {}) + switch_window_focus(params) + log('object_manager_attribute_delete', params) + + click( + browser: instance, + css: 'a[href="#manage"]', + mute_log: true, + ) + click( + browser: instance, + css: 'a[href="#system/object_manager"]', + mute_log: true, + ) + sleep 4 + + instance = params[:browser] || @browser + data = params[:data] + r = instance.execute_script("$(\"#content td:contains('#{data[:name]}')\").first().closest('tr').find('.js-delete').click()") + p "rrr #{r.inspect}" + end + +=begin + + object_manager_attribute_discard_changes( + browser: browser2, + ) + +=end + + def object_manager_attribute_discard_changes(params = {}) + switch_window_focus(params) + log('object_manager_attribute_discard_changes', params) + + instance = params[:browser] || @browser + + click( + browser: instance, + css: 'a[href="#manage"]', + mute_log: true, + ) + click( + browser: instance, + css: 'a[href="#system/object_manager"]', + mute_log: true, + ) + sleep 4 + + element = instance.find_elements(css: '#content .js-discard').first + element.click + + watch_for_disappear( + browser: instance, + css: '#content .js-discard', + ) + + end + def quote(string) string_quoted = string string_quoted.gsub!(/&/, '&') diff --git a/test/unit/object_manager_test.rb b/test/unit/object_manager_test.rb index 8409a694d..2d8040bdd 100644 --- a/test/unit/object_manager_test.rb +++ b/test/unit/object_manager_test.rb @@ -368,6 +368,45 @@ class ObjectManagerTest < ActiveSupport::TestCase } assert_equal(false, ObjectManager::Attribute.pending_migration?) + assert_raises(RuntimeError) { + attribute16 = ObjectManager::Attribute.add( + object: 'Ticket', + name: 'test16', + display: 'Test 16', + data_type: 'integer', + data_option: { + default: 2, + min: 1, + max: 999, + }, + active: true, + screens: {}, + position: 20, + created_by_id: 1, + updated_by_id: 1, + ) + } + assert_equal(false, ObjectManager::Attribute.pending_migration?) + + assert_raises(RuntimeError) { + attribute17 = ObjectManager::Attribute.add( + object: 'Ticket', + name: 'test17', + display: 'Test 17', + data_type: 'integer', + data_option: { + default: 2, + min: 1, + }, + active: true, + screens: {}, + position: 20, + created_by_id: 1, + updated_by_id: 1, + ) + } + assert_equal(false, ObjectManager::Attribute.pending_migration?) + end test 'b object manager attribute' do