Conversation
thorsteneckel
left a comment
There was a problem hiding this comment.
Hi @egorovdunice,
I just reviewed your changes and added some inline comments. There are two other broader topics I want to cover here because they are related to multiple files:
Changes in generic files
There are quite a lot of changes to frontend files which meant to be generic. They now contain special organization logic which is not the way we should solve this requirement. Here is a list of related files:
app/assets/javascripts/app/controllers/_application_controller_form.coffeeapp/assets/javascripts/app/controllers/_ui_element/autocompletion_ajax.coffeeapp/assets/javascripts/app/controllers/_ui_element/select.coffeeapp/assets/javascripts/app/lib/app_post/searchable_select.coffeeapp/assets/javascripts/app/lib/bootstrap/transition.jsapp/assets/javascripts/app/views/agent_ticket_create.jst.ecoapp/assets/javascripts/app/views/customer_ticket_create.jst.ecoapp/assets/javascripts/app/views/generic/searchable_select.jst.ecoapp/assets/stylesheets/zammad.scss
I think the issue here is that you changed the existing generic files instead of inheriting from them and create a new custom element for the organization requirements (like e.g. app/assets/javascripts/app/lib/app_post/z_searchable_ajax_select.coffee does). This should resolve all of those file conflicts.
Debugging code
There are some changes and added files that I think are related to debugging. To be honest I don't know which are and which are not. So I added comments to the ones where I'm not sure. Would be a great help if you could mark them with TODO: DEBUGGING or something so I can get an idea what your thoughts where while adding/changing things.
There are some other things we need to get straight before merging (e.g. only one migration) but it's ok for now.
To be honest I don't have tested it yet because I think the required changes I described above might solve/introduce some bugs. After you changed things I'm happy to start testing.
Feel free to ask any questions!
| sender_id: sender.id | ||
| form_id: @form_id | ||
| content_type: 'text/html' | ||
| organization_id: +params.organization_id |
There was a problem hiding this comment.
The + in front of params looks wrong to me.
| js_shadow_ids.each( -> ids.push $(this).val() ) | ||
| if !ids.includes(data_value) && $(".js-shadow[name='organization_id']").val() != data_value | ||
| newInput = @input.closest('.searchableSelect').find('div.items') | ||
| input = "<input class='searchableSelect-shadow form-control js-shadow-ids' name='organization_ids'>" |
There was a problem hiding this comment.
Please use templates for HTML structures and don't build them in JS.
| { name: 'title', display: 'Title', tag: 'input', type: 'text', limit: 100, null: false }, | ||
| { name: 'customer_id', display: 'Customer', tag: 'input', type: 'text', limit: 100, null: false, autocapitalize: false, relation: 'User' }, | ||
| { name: 'organization_id', display: 'Organization', tag: 'select', relation: 'Organization', readonly: 1 }, | ||
| # { name: 'organization_id', display: 'Organization', tag: 'select', relation: 'Organization', readonly: 1 }, |
There was a problem hiding this comment.
A ticket should still be assigned to one Organization.
| return | ||
| end | ||
| 8.times do | ||
| 28.times do |
There was a problem hiding this comment.
What's the purpose of this increased value?
|
|
||
| # overwrite params | ||
| if !current_user.permissions?('ticket.agent') | ||
| %i[owner owner_id customer customer_id organization organization_id preferences].each do |key| |
There was a problem hiding this comment.
Why did you remove the organization_id key?
| filter: Ticket::State.by_category(:viewable_agent_new).pluck(:id), | ||
| }, | ||
| 'ticket.customer' => { | ||
| item_class: 'column', |
There was a problem hiding this comment.
it's needed to fit 2 select (Ticket.state and Ticket.organization_id) in 1 row
| class App.ControllerForm extends App.Controller | ||
| constructor: (params) -> | ||
| super | ||
| if params['screen'] == 'create_middle_org' |
There was a problem hiding this comment.
Please don't introduce hard coded attribute logic into generic files.
| @@ -0,0 +1,5 @@ | |||
| class App.UiElement.select_organization extends App.UiElement.select | |||
| @render: (attribute, params) -> | |||
| if attribute['name'] == 'organization_id' && attribute['default'] == 0 | |||
There was a problem hiding this comment.
Why is there a check for the attribute name if the name of the class is already limited to the attribute?
| el: @$('.ticket-form-organization') | ||
| form_id: @formId | ||
| model: App.Ticket | ||
| screen: 'create_middle_org' |
| el: @el.find('.ticket-form-organization') | ||
| form_id: @form_id | ||
| model: App.Ticket | ||
| screen: 'create_middle_org' |
| @shadowInput.val event.currentTarget.getAttribute('data-value') | ||
| @shadowInput.trigger('change') | ||
|
|
||
|
|
app/models/organization.rb
Outdated
| include Organization::SearchIndex | ||
|
|
||
| has_many :members, class_name: 'User' | ||
| has_and_belongs_to_many :members, after_add: :cache_update, after_remove: :cache_update, class_name: 'User' |
There was a problem hiding this comment.
There are two associations with the same name members which looks wrong to me.
config/database.yml.pkgr
Outdated
| encoding: utf8 | ||
| username: zammad | ||
| password: | ||
| password: No newline at end of file |
| active: true, | ||
|
|
||
| screens: { | ||
| create_middle_org: { |
There was a problem hiding this comment.
Uniq screen for new field as 'create_middle', 'create_top' and etc.
There was a problem hiding this comment.
If I would use generic hooks then on ticket create form there appear wrong additional fields with the same hooks.
There was a problem hiding this comment.
Then we need to change the priority of those so that the order matches the expectations.
| } | ||
|
|
||
| .dropdown-menu { | ||
| margin-top: -3px; |
There was a problem hiding this comment.
Why were these changes required? Looks like they might break other parts of the application.
| active: true, | ||
|
|
||
| screens: { | ||
| create_middle_org: { |
There was a problem hiding this comment.
Uniq screen for new field as 'create_middle', 'create_top' and etc.
There was a problem hiding this comment.
See comments above regarding generic hooks.
There was a problem hiding this comment.
If I would use generic hooks then on ticket create form there appear wrong additional fields with the same hooks.
There was a problem hiding this comment.
Then we need to change the priority of those so that the order matches the expectations.
| ids = [] | ||
| if js_shadow_ids.length > 0 | ||
| js_shadow_ids.each( -> ids.push $(this).val() ) | ||
| unless ids.includes(data_value) || $(".js-shadow[name='organization_id']").val() == data_value |
There was a problem hiding this comment.
Please don't introduce hard coded attribute logic into generic files (organization_id ).
|
|
||
| <div class="formset-inset"> | ||
| <div class="ticket-form-middle horizontal two-columns"></div> | ||
| <div class="ticket-form-organization horizontal two-columns"></div> |
There was a problem hiding this comment.
The field should use the existing generic hooks (ticket-form-middle in this case) as the other attributes do.
| <div class="ticket-form-middle horizontal two-columns"></div> | ||
| <div class="two-columns horizontal"> | ||
| <div class="ticket-form-middle column"></div> | ||
| <div class="ticket-form-organization column"></div> |
| <% if @attribute.value: %> | ||
| <% for value in @attribute.value: %> | ||
| <div> | ||
| <span class='selected_organization' onclick="$(this).closest('div').remove()"> |
There was a problem hiding this comment.
Please don't introduce hard coded attribute logic into generic files (organization).
| @@ -0,0 +1,4 @@ | |||
| <div> | |||
| <span class='selected_organization' onclick="$(this).closest('div').remove()"><%= @title %></span> | |||
| <input class='searchableSelect-shadow form-control js-shadow-ids' name='organization_ids' value=<%= @data_value %>> | |||
There was a problem hiding this comment.
Please don't introduce hard coded attribute logic into generic files (organization_ids).
app/assets/stylesheets/zammad.scss
Outdated
| .searchableSelect { | ||
| position: relative; | ||
|
|
||
| .selected_organization { |
There was a problem hiding this comment.
What is required for? There should be no hard coded attribute logic in generic files (selected_organization).
| active: true, | ||
|
|
||
| screens: { | ||
| create_middle_org: { |
There was a problem hiding this comment.
See comments above regarding generic hooks.
spec/models/ticket_spec.rb
Outdated
| end | ||
| end | ||
|
|
||
| describe '#check_defaults' do |
There was a problem hiding this comment.
Please don't test private/internal methods because they should be easy to change. Instead test functionality. You might want to use run_callbacks instead.
Indentation corrected
| active: true, | ||
|
|
||
| screens: { | ||
| create_middle_org: { |
There was a problem hiding this comment.
Then we need to change the priority of those so that the order matches the expectations.
| active: true, | ||
|
|
||
| screens: { | ||
| create_middle_org: { |
There was a problem hiding this comment.
Then we need to change the priority of those so that the order matches the expectations.
| @input.trigger('change') | ||
| @shadowInput.val event.currentTarget.getAttribute('data-value') | ||
| @shadowInput.trigger('change') | ||
| $(".js-shadow-ids[value=#{event.currentTarget.getAttribute('data-value')}]").closest('div').remove() |
There was a problem hiding this comment.
What is this line for?
If we keep it:
It's not really expressive. We should add a comment for it and extend the tests to cover the functionality.
| '.js-input': 'input' | ||
| '.js-shadow': 'shadowInput' | ||
| '.js-optionsList': 'optionsList' | ||
| '.items': 'itemList' |
There was a problem hiding this comment.
This is only used in a descendant of the class so there is no need to have it in the base class.
| ids = [] | ||
| if js_shadow_ids.length > 0 | ||
| js_shadow_ids.each( -> ids.push $(this).val() ) | ||
| unless ids.includes(data_value) || $(".js-shadow[name='"+@attribute.name+"']").val() == data_value |
There was a problem hiding this comment.
Please don't use unless statements.
| <% if @attribute.value: %> | ||
| <% for value in @attribute.value: %> | ||
| <div> | ||
| <span class='selected_item' onclick="$(this).closest('div').remove()"> |
There was a problem hiding this comment.
Please don't use inline JS. Move it to the controller that handles the template.
| @@ -0,0 +1,4 @@ | |||
| <div> | |||
| <span class='selected_item' onclick="$(this).closest('div').remove()"><%= @title %></span> | |||
There was a problem hiding this comment.
Please don't use inline JS. Move it to the controller that handles the template.
app/models/ticket.rb
Outdated
| return true if !customer | ||
| return true if organization_id == customer.organization_id | ||
| self.organization_id = customer.organization_id | ||
| return true if (customer.organization_ids.include?(organization_id) || customer.organization_id? && customer.organization_id == organization_id) |
There was a problem hiding this comment.
Please split this line/if statment if possible. It carries way to much complexity.
app/models/ticket.rb
Outdated
| if !owner_id | ||
| self.owner_id = 1 | ||
| end | ||
| self.owner_id = 1 unless owner_id |
app/models/user/assets.rb
Outdated
| end | ||
|
|
||
| if local_attributes['organization_id'] | ||
| unless data[:Organization] || data[:Organization]&[local_attributes['organization_id']] |
| <% for value in @attribute.value: %> | ||
| <div> | ||
| <span class='selected_item'> | ||
| <%- App.Organization.findNative(value).name %> |
There was a problem hiding this comment.
Please don't use specific code in generic components.
…tate new is set to open on second update by customer.
… if access is via roles
…e they are migrated to rspec now).
…stamp e. g. "2018-09-19 15:25".
…k for invalid attribute names (fixes zammad#2236)
…ing bulk action form (fixes zammad#2026)
Fixed typo in 404: Ressource -> resource
…Error: undefined method `match' for nil:NilClass>"`.
…eferences[:delivery_status_message] has no utf8 charset.
…eptions::UnprocessableEntity: Invalid email>"`.
…rough HTML nodes.
… Also added hiding of empty string attribute fields.
…nt race conditions (if callback comes later).
…if file is corrupt in filesystem and remove it in case).
…_to_organization_ids_for_user
No description provided.