mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-01-31 20:19:05 +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;
|
||||
|
||||
.apply-button {
|
||||
flex-grow: 1;
|
||||
margin-left: .5em !important;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
.column-filters-element {
|
||||
|
|
|
@ -7,6 +7,7 @@ class RepositoriesController < ApplicationController
|
|||
include IconsHelper
|
||||
include TeamsHelper
|
||||
include RepositoriesDatatableHelper
|
||||
include MyModulesHelper
|
||||
|
||||
before_action :switch_team_with_param, only: :show
|
||||
before_action :load_repository, except: %i(index create create_modal sidebar archive restore)
|
||||
|
@ -360,6 +361,18 @@ class RepositoriesController < ApplicationController
|
|||
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
|
||||
|
||||
def repostiory_import_actions
|
||||
|
|
|
@ -11,7 +11,8 @@ window.initRepositoryFilter = () => {
|
|||
data: () => {
|
||||
return {
|
||||
filters: [],
|
||||
columns: []
|
||||
columns: [],
|
||||
my_modules: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
@ -27,6 +28,10 @@ window.initRepositoryFilter = () => {
|
|||
}
|
||||
});
|
||||
|
||||
$.get($('#filterContainer').data('my-modules-url'), function(data) {
|
||||
repositoryFilterContainer.my_modules = data;
|
||||
});
|
||||
|
||||
// Replace with remote endpoint
|
||||
repositoryFilterContainer.columns = [
|
||||
{ id: 'assigned', name: 'Assigned to task', data_type: 'RepositoryMyModuleValue' },
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
v-for="(filter, index) in filters"
|
||||
:key="filter.id"
|
||||
:filter.sync="filters[index]"
|
||||
:my_modules.sync= "my_modules"
|
||||
@filter:update="updateFilter"
|
||||
@filter:delete="filters.splice(index, 1)"
|
||||
/>
|
||||
|
@ -55,6 +56,7 @@
|
|||
}
|
||||
},
|
||||
props: {
|
||||
my_modules: Array,
|
||||
container: Object,
|
||||
savedFilters: Array,
|
||||
columns: Array
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<component
|
||||
:is="filter.column.data_type"
|
||||
:filter="filter"
|
||||
:my_modules='my_modules'
|
||||
@filter:update="updateFilter" />
|
||||
</div>
|
||||
<div class="filter-remove">
|
||||
|
@ -23,6 +24,7 @@
|
|||
import RepositoryAssetValue from 'vue/repository_filter/filters/repositoryAssetValue.vue'
|
||||
import RepositoryTextValue from 'vue/repository_filter/filters/repositoryTextValue.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'
|
||||
|
||||
|
||||
|
@ -30,16 +32,17 @@
|
|||
name: "FilterElement",
|
||||
props: {
|
||||
filter: Object,
|
||||
my_modules: Array
|
||||
},
|
||||
components: {
|
||||
DropdownSelector,
|
||||
RepositoryAssetValue,
|
||||
RepositoryTextValue,
|
||||
RepositoryNumberValue
|
||||
RepositoryNumberValue,
|
||||
RepositoryMyModuleValue
|
||||
},
|
||||
methods: {
|
||||
updateFilter(value) {
|
||||
console.log(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 {
|
||||
props: {
|
||||
filter: Object
|
||||
filter: Object,
|
||||
my_modules: Array
|
||||
},
|
||||
created() {
|
||||
this.operator = this.operator || this.filter.data.operator;
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
<template>
|
||||
<div class="dropdown-selector">
|
||||
<select :id="this.selectorId">
|
||||
<option
|
||||
<select :id="this.selectorId"
|
||||
: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"
|
||||
:key="option.label" :value="option.value">
|
||||
{{ option.label }}
|
||||
|
@ -16,10 +27,18 @@
|
|||
props: {
|
||||
options: Array,
|
||||
selectorId: String,
|
||||
groupSelector: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
noEmptyOption: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
singleSelect: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
|
@ -36,11 +55,28 @@
|
|||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
optionClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dataCombineTags: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dataSelectMultipleAllSelected: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dataSelectMultipleName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
onChange: Function
|
||||
|
||||
},
|
||||
mounted: function() {
|
||||
dropdownSelector.init(`#${this.selectorId}`, {
|
||||
optionClass: this.optionClass,
|
||||
noEmptyOption: this.noEmptyOption,
|
||||
singleSelect: this.singleSelect,
|
||||
closeOnSelect: this.closeOnSelect,
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
<div
|
||||
class="dropdown-menu dropdown-menu-right"
|
||||
id="filterContainer"
|
||||
data-my-modules-url="<%= assigned_my_modules_repository_path(@repository) %>"
|
||||
data-datatable-id="#repository-table-<%= @repository.id %>"
|
||||
>
|
||||
<filter-container
|
||||
<filter-container
|
||||
:columns.sync="columns"
|
||||
:my_modules.sync="my_modules"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1394,7 +1394,7 @@ en:
|
|||
title: "Filters"
|
||||
clear: "Clear"
|
||||
add_filter: "Add filter"
|
||||
apply: "Apply"
|
||||
apply: "Show results"
|
||||
repository_filter:
|
||||
enter_value: "Enter text"
|
||||
filters:
|
||||
|
@ -1411,14 +1411,23 @@ en:
|
|||
not_contain: "Doesn't contain"
|
||||
empty: "Is empty"
|
||||
RepositoryNumberValue:
|
||||
input_placeholder: "Enter %{name}"
|
||||
operators:
|
||||
equal: "Equal to"
|
||||
not_equal: "Not equal to"
|
||||
greater: "Greater than"
|
||||
less: "Less than"
|
||||
less_equal: "Less than or equal to"
|
||||
between: "Between"
|
||||
input_placeholder: "Enter %{name}"
|
||||
operators:
|
||||
equal: "Equal to"
|
||||
not_equal: "Not equal to"
|
||||
greater: "Greater than"
|
||||
less: "Less than"
|
||||
less_equal: "Less than or equal to"
|
||||
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_filter: "Biomolecule filter"
|
||||
save_filters: "Save filters"
|
||||
|
|
|
@ -548,6 +548,7 @@ Rails.application.routes.draw do
|
|||
as: 'table_index',
|
||||
defaults: { format: 'json' }
|
||||
member do
|
||||
get :assigned_my_modules
|
||||
get :load_table
|
||||
end
|
||||
# Save repository table state
|
||||
|
|
Loading…
Reference in a new issue