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 %>"
>