diff --git a/app/assets/javascripts/my_modules/protocols.js b/app/assets/javascripts/my_modules/protocols.js index 52c43602b..48ad28728 100644 --- a/app/assets/javascripts/my_modules/protocols.js +++ b/app/assets/javascripts/my_modules/protocols.js @@ -342,7 +342,7 @@ function init() { init(); const viewMode = new URLSearchParams(window.location.search).get('view_mode'); -if (viewMode === 'archived') { +if (['archived', 'locked', 'active'].includes(viewMode)) { setTimeout(() => { const notesContainerEl = document.getElementById('notes-container'); window.wrapTables(notesContainerEl); diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index f98b73f9b..1c12be781 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -96,7 +96,7 @@ class RepositoriesController < ApplicationController end def shareable_teams - teams = current_user.teams - [@repository.team] + teams = current_user.teams.order(:name) - [@repository.team] render json: teams, each_serializer: ShareableTeamSerializer, repository: @repository end diff --git a/app/javascript/packs/vue/repository_filter.js b/app/javascript/packs/vue/repository_filter.js index 3c51cba8d..f130d82fd 100644 --- a/app/javascript/packs/vue/repository_filter.js +++ b/app/javascript/packs/vue/repository_filter.js @@ -37,6 +37,16 @@ const DEFAULT_FILTERS = [ }, { id: 4, + column: { + data_type: 'RepositoryRelationshipValue', + id: 'relationships', + name: I18n.t('repositories.table.relationships') + }, + data: { operator: 'contains' }, + isBlank: true + }, + { + id: 5, column: { data_type: 'RepositoryDateTimeValue', id: 'added_on', @@ -46,7 +56,7 @@ const DEFAULT_FILTERS = [ isBlank: true }, { - id: 5, + id: 6, column: { data_type: 'RepositoryUserValue', id: 'added_by', @@ -63,6 +73,7 @@ window.initRepositoryFilter = () => { { id: 'assigned', name: I18n.t('repositories.table.assigned_tasks'), data_type: 'RepositoryMyModuleValue' }, { id: 'row_id', name: I18n.t('repositories.table.id'), data_type: 'RepositoryTextValue' }, { id: 'row_name', name: I18n.t('repositories.table.row_name'), data_type: 'RepositoryTextValue' }, + { id: 'relationships', name: I18n.t('repositories.table.relationships'), data_type: 'RepositoryRelationshipValue' }, { id: 'added_on', name: I18n.t('repositories.table.added_on'), data_type: 'RepositoryDateTimeValue' }, { id: 'added_by', name: I18n.t('repositories.table.added_by'), data_type: 'RepositoryUserValue' }, { id: 'archived_by', name: I18n.t('repositories.table.archived_by'), data_type: 'RepositoryUserValue' }, @@ -70,6 +81,7 @@ window.initRepositoryFilter = () => { ]; const app = createApp({ data: () => ({ + open: false, filters: [], defaultFilters: DEFAULT_FILTERS, columns: [], @@ -79,19 +91,29 @@ window.initRepositoryFilter = () => { filterName: null }), created() { - this.dataTableElement = $($('#filterContainer').data('datatable-id')); + $('#filtersDropdownButton').on('show.bs.dropdown', () => { + this.open = true; + this.dataTableElement = $($('#filterContainer').data('datatable-id')); - $.get($('#filterContainer').data('my-modules-url'), (data) => { - this.my_modules = data.data; + $.get($('#filterContainer').data('my-modules-url'), (data) => { + this.my_modules = data.data; + }); + + $.get($('#filterContainer').data('columns-url'), (data) => { + const combinedColumns = data.response.concat(defaultColumns); + this.columns = combinedColumns.sort((a, b) => (a.name > b.name ? 1 : -1)); + }); + + $.get($('#filterContainer').data('saved-filters-url'), (data) => { + this.savedFilters = data.data; + }); + + $('#filtersColumnsDropdown, #savedFiltersContainer').removeClass('open'); }); - $.get($('#filterContainer').data('columns-url'), (data) => { - const combinedColumns = data.response.concat(defaultColumns); - this.columns = combinedColumns.sort((a, b) => a.name > b.name ? 1 : -1); - }); - - $.get($('#filterContainer').data('saved-filters-url'), (data) => { - this.savedFilters = data.data; + $('#filterContainer').on('click', (e) => { + $('#filterContainer .dropdown-selector-container').removeClass('open'); + e.stopPropagation(); }); }, computed: { @@ -151,13 +173,4 @@ window.initRepositoryFilter = () => { app.config.globalProperties.i18n = window.I18n; app.config.globalProperties.dateFormat = $('#filterContainer').data('date-format'); window.repositoryFilterObject = mountWithTurbolinks(app, '#filterContainer'); - - $('#filterContainer').on('click', (e) => { - $('#filterContainer .dropdown-selector-container').removeClass('open') - e.stopPropagation(); - }); - - $('#filtersDropdownButton').on('show.bs.dropdown', () => { - $('#filtersColumnsDropdown, #savedFiltersContainer').removeClass('open'); - }); }; diff --git a/app/javascript/vue/repository_filter/filter.vue b/app/javascript/vue/repository_filter/filter.vue index 6b172901a..4791b0a45 100644 --- a/app/javascript/vue/repository_filter/filter.vue +++ b/app/javascript/vue/repository_filter/filter.vue @@ -21,6 +21,7 @@ diff --git a/app/javascript/vue/shared/content/modal/move.vue b/app/javascript/vue/shared/content/modal/move.vue index 327e557ef..01913cc11 100644 --- a/app/javascript/vue/shared/content/modal/move.vue +++ b/app/javascript/vue/shared/content/modal/move.vue @@ -23,7 +23,7 @@ " :no-options-placeholder=" i18n.t( - 'my_modules.results.move_modal.no_options_placeholder' + `my_modules.results.move_modal.${parent_type}.no_options_placeholder` ) " /> diff --git a/app/serializers/asset_serializer.rb b/app/serializers/asset_serializer.rb index 84933cc46..989e851af 100644 --- a/app/serializers/asset_serializer.rb +++ b/app/serializers/asset_serializer.rb @@ -157,7 +157,7 @@ class AssetSerializer < ActiveModel::Serializer urls[:asset_checksum] = asset_checksum_path(object) end - urls[:wopi_action] = object.get_action_url(user, 'embedview') if wopi && can_manage_asset?(user, object) + urls[:wopi_action] = object.get_action_url(user, 'embedview') if wopi && can_read_asset?(user, object) urls[:blob] = rails_blob_path(object.file, disposition: 'attachment') if object.file.attached? urls diff --git a/app/services/repository_datatable_service.rb b/app/services/repository_datatable_service.rb index 56dd700bd..86d545bc8 100644 --- a/app/services/repository_datatable_service.rb +++ b/app/services/repository_datatable_service.rb @@ -10,7 +10,7 @@ class RepositoryDatatableService include MyModulesHelper attr_reader :repository_rows, :all_count, :mappings - PREDEFINED_COLUMNS = %w(row_id row_name added_on added_by archived_on archived_by assigned).freeze + PREDEFINED_COLUMNS = %w(row_id row_name added_on added_by archived_on archived_by assigned relationships).freeze def initialize(repository, params, user, my_module = nil) @repository = repository @@ -154,6 +154,8 @@ class RepositoryDatatableService build_row_id_filter_condition(repository_rows, filter_element_params) when 'row_name' build_name_filter_condition(repository_rows, filter_element_params) + when 'relationships' + build_relationship_filter_condition(repository_rows, filter_element_params) when 'added_on' build_added_on_filter_condition(repository_rows, filter_element_params) when 'added_by' @@ -202,6 +204,32 @@ class RepositoryDatatableService end end + def build_relationship_filter_condition(repository_rows, filter_element_params) + case filter_element_params[:operator] + when 'contains' + text = "%#{ActiveRecord::Base.sanitize_sql_like(filter_element_params.dig(:parameters, :text))}%" + + repository_rows.where( + id: repository_rows.left_outer_joins(:parent_repository_rows, :child_repository_rows) + .where("trim_html_tags(child_repository_rows_repository_rows.name)::text ILIKE ? OR + trim_html_tags(parent_repository_rows_repository_rows.name)::text ILIKE ? OR + ('#{RepositoryRow::ID_PREFIX}' || + child_repository_rows_repository_rows.id)::text ILIKE ? OR + ('#{RepositoryRow::ID_PREFIX}' || + parent_repository_rows_repository_rows.id)::text ILIKE ?", + text, text, text, text).select(:id) + ) + when 'contains_relationship' + repository_rows = repository_rows.left_outer_joins(:parent_connections, :child_connections) + repository_rows.where.not(parent_connections: { id: nil }) + .or(repository_rows.where.not(child_connections: { id: nil })) + when 'doesnt_contain_relationship' + repository_rows.where.missing(:parent_connections, :child_connections) + else + raise ArgumentError, 'Wrong operator for RepositoryRow Relationship!' + end + end + def build_added_on_filter_condition(repository_rows, filter_element_params) case filter_element_params[:operator] when 'today' diff --git a/app/views/repositories/_repository_filters.html.erb b/app/views/repositories/_repository_filters.html.erb index 57dac1c36..11083e980 100644 --- a/app/views/repositories/_repository_filters.html.erb +++ b/app/views/repositories/_repository_filters.html.erb @@ -23,6 +23,7 @@ data-user-utc-offset="<%= ActiveSupport::TimeZone.find_tzinfo(current_user.time_zone).utc_offset %>" >