mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-18 14:49:31 +08:00
Add assigned tasks filters [SCI-6221] (#3726)
* Add endpoint for repository tasks [SCI-6221] * Add assigned tasks filter [SCI-6221] Co-authored-by: Anton <anton@scinote.net>
This commit is contained in:
parent
e4606abf3e
commit
00f30b8d6c
11 changed files with 146 additions and 18 deletions
|
|
@ -33,8 +33,7 @@
|
||||||
padding: .5em;
|
padding: .5em;
|
||||||
|
|
||||||
.apply-button {
|
.apply-button {
|
||||||
flex-grow: 1;
|
margin-left: auto !important;
|
||||||
margin-left: .5em !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-filters-element {
|
.column-filters-element {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ class RepositoriesController < ApplicationController
|
||||||
include IconsHelper
|
include IconsHelper
|
||||||
include TeamsHelper
|
include TeamsHelper
|
||||||
include RepositoriesDatatableHelper
|
include RepositoriesDatatableHelper
|
||||||
|
include MyModulesHelper
|
||||||
|
|
||||||
before_action :switch_team_with_param, only: :show
|
before_action :switch_team_with_param, only: :show
|
||||||
before_action :load_repository, except: %i(index create create_modal sidebar archive restore)
|
before_action :load_repository, except: %i(index create create_modal sidebar archive restore)
|
||||||
|
|
@ -360,6 +361,18 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assigned_my_modules
|
||||||
|
my_modules = MyModule.joins(:repository_rows).where(repository_rows: { repository: @repository })
|
||||||
|
.readable_by_user(current_user).distinct
|
||||||
|
render json: grouped_by_prj_exp(my_modules).map { |g|
|
||||||
|
{
|
||||||
|
label: "#{g[:project_name]} / #{g[:experiment_name]}", options: g[:tasks].map do |t|
|
||||||
|
{ label: t.name, value: t.id }
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def repostiory_import_actions
|
def repostiory_import_actions
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ window.initRepositoryFilter = () => {
|
||||||
data: () => {
|
data: () => {
|
||||||
return {
|
return {
|
||||||
filters: [],
|
filters: [],
|
||||||
columns: []
|
columns: [],
|
||||||
|
my_modules: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|
@ -27,6 +28,10 @@ window.initRepositoryFilter = () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$.get($('#filterContainer').data('my-modules-url'), function(data) {
|
||||||
|
repositoryFilterContainer.my_modules = data;
|
||||||
|
});
|
||||||
|
|
||||||
// Replace with remote endpoint
|
// Replace with remote endpoint
|
||||||
repositoryFilterContainer.columns = [
|
repositoryFilterContainer.columns = [
|
||||||
{ id: 'assigned', name: 'Assigned to task', data_type: 'RepositoryMyModuleValue' },
|
{ id: 'assigned', name: 'Assigned to task', data_type: 'RepositoryMyModuleValue' },
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
v-for="(filter, index) in filters"
|
v-for="(filter, index) in filters"
|
||||||
:key="filter.id"
|
:key="filter.id"
|
||||||
:filter.sync="filters[index]"
|
:filter.sync="filters[index]"
|
||||||
|
:my_modules.sync= "my_modules"
|
||||||
@filter:update="updateFilter"
|
@filter:update="updateFilter"
|
||||||
@filter:delete="filters.splice(index, 1)"
|
@filter:delete="filters.splice(index, 1)"
|
||||||
/>
|
/>
|
||||||
|
|
@ -55,6 +56,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
my_modules: Array,
|
||||||
container: Object,
|
container: Object,
|
||||||
savedFilters: Array,
|
savedFilters: Array,
|
||||||
columns: Array
|
columns: Array
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
<component
|
<component
|
||||||
:is="filter.column.data_type"
|
:is="filter.column.data_type"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
|
:my_modules='my_modules'
|
||||||
@filter:update="updateFilter" />
|
@filter:update="updateFilter" />
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-remove">
|
<div class="filter-remove">
|
||||||
|
|
@ -23,6 +24,7 @@
|
||||||
import RepositoryAssetValue from 'vue/repository_filter/filters/repositoryAssetValue.vue'
|
import RepositoryAssetValue from 'vue/repository_filter/filters/repositoryAssetValue.vue'
|
||||||
import RepositoryTextValue from 'vue/repository_filter/filters/repositoryTextValue.vue'
|
import RepositoryTextValue from 'vue/repository_filter/filters/repositoryTextValue.vue'
|
||||||
import RepositoryNumberValue from 'vue/repository_filter/filters/repositoryNumberValue.vue'
|
import RepositoryNumberValue from 'vue/repository_filter/filters/repositoryNumberValue.vue'
|
||||||
|
import RepositoryMyModuleValue from 'vue/repository_filter/filters/repositoryMyModuleValue.vue'
|
||||||
import DropdownSelector from 'vue/shared/dropdown_selector.vue'
|
import DropdownSelector from 'vue/shared/dropdown_selector.vue'
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,16 +32,17 @@
|
||||||
name: "FilterElement",
|
name: "FilterElement",
|
||||||
props: {
|
props: {
|
||||||
filter: Object,
|
filter: Object,
|
||||||
|
my_modules: Array
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
DropdownSelector,
|
DropdownSelector,
|
||||||
RepositoryAssetValue,
|
RepositoryAssetValue,
|
||||||
RepositoryTextValue,
|
RepositoryTextValue,
|
||||||
RepositoryNumberValue
|
RepositoryNumberValue,
|
||||||
|
RepositoryMyModuleValue
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateFilter(value) {
|
updateFilter(value) {
|
||||||
console.log(value);
|
|
||||||
this.$emit('filter:update', value)
|
this.$emit('filter:update', value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
<template>
|
||||||
|
<div class="filter-attributes">
|
||||||
|
<DropdownSelector
|
||||||
|
:disableSearch="true"
|
||||||
|
:options="this.operators"
|
||||||
|
:selectorId="`OperatorSelector${this.filter.id}`"
|
||||||
|
@dropdown:changed="updateOperator"
|
||||||
|
/>
|
||||||
|
<DropdownSelector
|
||||||
|
:optionClass="'checkbox-icon'"
|
||||||
|
:dataCombineTags="true"
|
||||||
|
:noEmptyOption="false"
|
||||||
|
:singleSelect="false"
|
||||||
|
:groupSelector="true"
|
||||||
|
:options="this.my_modules"
|
||||||
|
:dataSelectMultipleName="this.i18n.t('repositories.show.repository_filter.filters.types.RepositoryMyModuleValue.multiple_selected')"
|
||||||
|
:dataSelectMultipleAllSelected="this.i18n.t('repositories.show.repository_filter.filters.types.RepositoryMyModuleValue.all_selected')"
|
||||||
|
:selectorId="`MyModulesSelector${this.filter.id}`"
|
||||||
|
:placeholder="this.i18n.t('repositories.show.repository_filter.filters.types.RepositoryMyModuleValue.select_placeholder')"
|
||||||
|
@dropdown:changed="updateValue"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FilterMixin from 'vue/repository_filter/mixins/filter.js'
|
||||||
|
import DropdownSelector from 'vue/shared/dropdown_selector.vue'
|
||||||
|
export default {
|
||||||
|
name: 'RepositoryMyModuleValue',
|
||||||
|
mixins: [FilterMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
operators: [
|
||||||
|
{ value: 'any_of', label: this.i18n.t('repositories.show.repository_filter.filters.types.RepositoryMyModuleValue.operators.any_of') },
|
||||||
|
{ value: 'all_of', label: this.i18n.t('repositories.show.repository_filter.filters.types.RepositoryMyModuleValue.operators.all_of') },
|
||||||
|
{ value: 'none_of', label: this.i18n.t('repositories.show.repository_filter.filters.types.RepositoryMyModuleValue.operators.none_of') }
|
||||||
|
],
|
||||||
|
operator: 'any_of',
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
DropdownSelector
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateValue(value) {
|
||||||
|
this.value = value
|
||||||
|
this.updateFilter();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isBlank(){
|
||||||
|
return this.operator == 'any_of' && !this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
filter: Object
|
filter: Object,
|
||||||
|
my_modules: Array
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.operator = this.operator || this.filter.data.operator;
|
this.operator = this.operator || this.filter.data.operator;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="dropdown-selector">
|
<div class="dropdown-selector">
|
||||||
<select :id="this.selectorId">
|
<select :id="this.selectorId"
|
||||||
<option
|
:data-select-by-group="groupSelector"
|
||||||
|
:data-combine-tags="dataCombineTags"
|
||||||
|
:data-select-multiple-all-selected="dataSelectMultipleAllSelected"
|
||||||
|
:data-select-multiple-name="dataSelectMultipleName"
|
||||||
|
:data-placeholder="placeholder"
|
||||||
|
>
|
||||||
|
<optgroup v-if="groupSelector" v-for="group in this.options" :label="group.label">
|
||||||
|
<option v-for="option in group.options" :key="option.label" :value="option.value">
|
||||||
|
{{ option.label }}
|
||||||
|
</option>
|
||||||
|
</optgroup>
|
||||||
|
<option v-if="!groupSelector"
|
||||||
v-for="option in this.options"
|
v-for="option in this.options"
|
||||||
:key="option.label" :value="option.value">
|
:key="option.label" :value="option.value">
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
|
|
@ -16,10 +27,18 @@
|
||||||
props: {
|
props: {
|
||||||
options: Array,
|
options: Array,
|
||||||
selectorId: String,
|
selectorId: String,
|
||||||
|
groupSelector: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
noEmptyOption: {
|
noEmptyOption: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
singleSelect: {
|
singleSelect: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
|
@ -36,11 +55,28 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
optionClass: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
dataCombineTags: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
dataSelectMultipleAllSelected: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
dataSelectMultipleName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
onChange: Function
|
onChange: Function
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
dropdownSelector.init(`#${this.selectorId}`, {
|
dropdownSelector.init(`#${this.selectorId}`, {
|
||||||
|
optionClass: this.optionClass,
|
||||||
noEmptyOption: this.noEmptyOption,
|
noEmptyOption: this.noEmptyOption,
|
||||||
singleSelect: this.singleSelect,
|
singleSelect: this.singleSelect,
|
||||||
closeOnSelect: this.closeOnSelect,
|
closeOnSelect: this.closeOnSelect,
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,12 @@
|
||||||
<div
|
<div
|
||||||
class="dropdown-menu dropdown-menu-right"
|
class="dropdown-menu dropdown-menu-right"
|
||||||
id="filterContainer"
|
id="filterContainer"
|
||||||
|
data-my-modules-url="<%= assigned_my_modules_repository_path(@repository) %>"
|
||||||
data-datatable-id="#repository-table-<%= @repository.id %>"
|
data-datatable-id="#repository-table-<%= @repository.id %>"
|
||||||
>
|
>
|
||||||
<filter-container
|
<filter-container
|
||||||
:columns.sync="columns"
|
:columns.sync="columns"
|
||||||
|
:my_modules.sync="my_modules"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1394,7 +1394,7 @@ en:
|
||||||
title: "Filters"
|
title: "Filters"
|
||||||
clear: "Clear"
|
clear: "Clear"
|
||||||
add_filter: "Add filter"
|
add_filter: "Add filter"
|
||||||
apply: "Apply"
|
apply: "Show results"
|
||||||
repository_filter:
|
repository_filter:
|
||||||
enter_value: "Enter text"
|
enter_value: "Enter text"
|
||||||
filters:
|
filters:
|
||||||
|
|
@ -1419,6 +1419,15 @@ en:
|
||||||
less: "Less than"
|
less: "Less than"
|
||||||
less_equal: "Less than or equal to"
|
less_equal: "Less than or equal to"
|
||||||
between: "Between"
|
between: "Between"
|
||||||
|
RepositoryMyModuleValue:
|
||||||
|
select_placeholder: "Select task"
|
||||||
|
multiple_selected: "tasks selected"
|
||||||
|
all_selected: "All tasks selected"
|
||||||
|
operators:
|
||||||
|
any_of: "Any of"
|
||||||
|
all_of: "All of"
|
||||||
|
none_of: "None of"
|
||||||
|
|
||||||
bmt_search:
|
bmt_search:
|
||||||
bmt_filter: "Biomolecule filter"
|
bmt_filter: "Biomolecule filter"
|
||||||
save_filters: "Save filters"
|
save_filters: "Save filters"
|
||||||
|
|
|
||||||
|
|
@ -548,6 +548,7 @@ Rails.application.routes.draw do
|
||||||
as: 'table_index',
|
as: 'table_index',
|
||||||
defaults: { format: 'json' }
|
defaults: { format: 'json' }
|
||||||
member do
|
member do
|
||||||
|
get :assigned_my_modules
|
||||||
get :load_table
|
get :load_table
|
||||||
end
|
end
|
||||||
# Save repository table state
|
# Save repository table state
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue