mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-10 23:25:31 +08:00
Add favorite to project table [SCI-11800]
This commit is contained in:
parent
72f549f00b
commit
fe676f8996
7 changed files with 144 additions and 2 deletions
|
@ -27,6 +27,7 @@
|
||||||
@access="access"
|
@access="access"
|
||||||
@updateDueDate="updateDueDate"
|
@updateDueDate="updateDueDate"
|
||||||
@updateStartDate="updateStartDate"
|
@updateStartDate="updateStartDate"
|
||||||
|
@updateFavorite="updateFavorite"
|
||||||
>
|
>
|
||||||
<template #card="data">
|
<template #card="data">
|
||||||
<ProjectCard :params="data.params" :dtComponent="data.dtComponent" ></ProjectCard>
|
<ProjectCard :params="data.params" :dtComponent="data.dtComponent" ></ProjectCard>
|
||||||
|
@ -93,6 +94,7 @@ import NewFolderModal from './modals/new_folder.vue';
|
||||||
import MoveModal from './modals/move.vue';
|
import MoveModal from './modals/move.vue';
|
||||||
import AccessModal from '../shared/access_modal/modal.vue';
|
import AccessModal from '../shared/access_modal/modal.vue';
|
||||||
import ExportLimitExceededModal from './modals/export_limit_exceeded_modal.vue';
|
import ExportLimitExceededModal from './modals/export_limit_exceeded_modal.vue';
|
||||||
|
import FavoriteRenderer from '../shared/datatable/renderers/favorite.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ProjectsList',
|
name: 'ProjectsList',
|
||||||
|
@ -112,7 +114,8 @@ export default {
|
||||||
DescriptionRenderer,
|
DescriptionRenderer,
|
||||||
DescriptionModal,
|
DescriptionModal,
|
||||||
StatusRenderer,
|
StatusRenderer,
|
||||||
SuperviserRenderer
|
SuperviserRenderer,
|
||||||
|
FavoriteRenderer
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
dataSource: { type: String, required: true },
|
dataSource: { type: String, required: true },
|
||||||
|
@ -158,6 +161,17 @@ export default {
|
||||||
sortable: true,
|
sortable: true,
|
||||||
cellRenderer: 'NameRenderer'
|
cellRenderer: 'NameRenderer'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'favorite',
|
||||||
|
headerComponentParams: {
|
||||||
|
html: '<div class="sn-icon sn-icon-star-filled"></div>'
|
||||||
|
},
|
||||||
|
headerName: this.i18n.t('projects.index.favorite'),
|
||||||
|
sortable: true,
|
||||||
|
cellRenderer: FavoriteRenderer,
|
||||||
|
minWidth: 80,
|
||||||
|
notSelectable: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'code',
|
field: 'code',
|
||||||
headerName: this.i18n.t('projects.index.card.id'),
|
headerName: this.i18n.t('projects.index.card.id'),
|
||||||
|
@ -365,6 +379,12 @@ export default {
|
||||||
this.updateTable();
|
this.updateTable();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updateFavorite(value, params) {
|
||||||
|
const url = value ? params.data.urls.favorite : params.data.urls.unfavorite;
|
||||||
|
axios.post(url).then(() => {
|
||||||
|
this.updateTable();
|
||||||
|
});
|
||||||
|
},
|
||||||
showDescription(_e, project) {
|
showDescription(_e, project) {
|
||||||
[this.descriptionModalObject] = project;
|
[this.descriptionModalObject] = project;
|
||||||
},
|
},
|
||||||
|
|
43
app/javascript/vue/shared/datatable/renderers/favorite.vue
Normal file
43
app/javascript/vue/shared/datatable/renderers/favorite.vue
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<template>
|
||||||
|
<div v-if="hasFavorite">
|
||||||
|
<button @click="updateFavorite(!favorite)"
|
||||||
|
class="flex justify-center items-center w-full h-9 bg-transparent border-none cursor-pointer">
|
||||||
|
<div v-if="favorite" class="sn-icon sn-icon-star-filled text-sn-alert-brittlebush"></div>
|
||||||
|
<div v-else @mouseover="hovered = true"
|
||||||
|
@mouseleave="hovered = false">
|
||||||
|
<div class="text-sn-grey-500 sn-icon" :class="{ 'sn-icon-star-filled': hovered, 'sn-icon-star': !hovered }"></div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'favoriteRenderer',
|
||||||
|
props: {
|
||||||
|
params: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
favorite: false,
|
||||||
|
hovered: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.favorite = this.params.data.favorite;
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasFavorite() {
|
||||||
|
return this.params.data.favorite !== null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateFavorite(value) {
|
||||||
|
this.params.dtComponent.$emit('updateFavorite', value, this.params);
|
||||||
|
this.favorite = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -77,6 +77,7 @@ module UserAssignments
|
||||||
assigned_by: @assigned_by
|
assigned_by: @assigned_by
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
object.favorites.where(user: @user).destroy_all if object.respond_to?(:favorites)
|
||||||
user_assignment.destroy!
|
user_assignment.destroy!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ module Lists
|
||||||
|
|
||||||
attributes :name, :code, :created_at, :archived_on, :users, :urls, :folder, :hidden,
|
attributes :name, :code, :created_at, :archived_on, :users, :urls, :folder, :hidden,
|
||||||
:folder_info, :default_public_user_role_id, :team, :top_level_assignable, :supervised_by,
|
:folder_info, :default_public_user_role_id, :team, :top_level_assignable, :supervised_by,
|
||||||
:comments, :updated_at, :permissions, :due_date_cell, :start_on_cell, :description, :status,
|
:comments, :updated_at, :permissions, :due_date_cell, :start_on_cell, :description, :status, :favorite,
|
||||||
def team
|
def team
|
||||||
object.team.name
|
object.team.name
|
||||||
end
|
end
|
||||||
|
@ -17,6 +17,10 @@ module Lists
|
||||||
!project?
|
!project?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def favorite
|
||||||
|
object.favorite if project?
|
||||||
|
end
|
||||||
|
|
||||||
def top_level_assignable
|
def top_level_assignable
|
||||||
project?
|
project?
|
||||||
end
|
end
|
||||||
|
|
|
@ -148,6 +148,10 @@ module Lists
|
||||||
@records = @records.sort_by { |object| project_comments_count(object) }
|
@records = @records.sort_by { |object| project_comments_count(object) }
|
||||||
when 'comments_DESC'
|
when 'comments_DESC'
|
||||||
@records = @records.sort_by { |object| project_comments_count(object) }.reverse!
|
@records = @records.sort_by { |object| project_comments_count(object) }.reverse!
|
||||||
|
when 'favorite_ASC'
|
||||||
|
@records = @records.sort_by { |object| project_favorites(object) }
|
||||||
|
when 'favorite_DESC'
|
||||||
|
@records = @records.sort_by { |object| project_favorites(object) }.reverse!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -163,6 +167,14 @@ module Lists
|
||||||
project?(object) ? object.users.count : -1
|
project?(object) ? object.users.count : -1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project_favorites(object)
|
||||||
|
if project?(object)
|
||||||
|
object.favorite ? 1 : 0
|
||||||
|
else
|
||||||
|
-1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def project?(object)
|
def project?(object)
|
||||||
object.instance_of?(Project)
|
object.instance_of?(Project)
|
||||||
end
|
end
|
||||||
|
|
|
@ -655,6 +655,7 @@ en:
|
||||||
add_start_date: "Add start date"
|
add_start_date: "Add start date"
|
||||||
no_start_date: "No start date"
|
no_start_date: "No start date"
|
||||||
add_description: 'Add description'
|
add_description: 'Add description'
|
||||||
|
favorite: 'Favorites'
|
||||||
status:
|
status:
|
||||||
not_started: "Not started"
|
not_started: "Not started"
|
||||||
started: "In progress"
|
started: "In progress"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CreateFavorites < ActiveRecord::Migration[7.0]
|
class CreateFavorites < ActiveRecord::Migration[7.0]
|
||||||
|
STATE_NAMES = %w(ProjectList_active_state ProjectList_archived_state ExperimentList_active_state
|
||||||
|
ExperimentList_archived_state MyModuleList_active_state MyModuleList_archived_state).freeze
|
||||||
def change
|
def change
|
||||||
create_table :favorites do |t|
|
create_table :favorites do |t|
|
||||||
t.references :user, null: false, foreign_key: true
|
t.references :user, null: false, foreign_key: true
|
||||||
|
@ -16,5 +18,64 @@ class CreateFavorites < ActiveRecord::Migration[7.0]
|
||||||
unique: true,
|
unique: true,
|
||||||
name: :index_favorites_on_user_and_item_and_team
|
name: :index_favorites_on_user_and_item_and_team
|
||||||
)
|
)
|
||||||
|
|
||||||
|
reversible do |dir|
|
||||||
|
dir.up do
|
||||||
|
User.find_each do |user|
|
||||||
|
update = false
|
||||||
|
STATE_NAMES.each do |state_name|
|
||||||
|
state = user.settings.dig(state_name, 'columnsState')
|
||||||
|
next if state.blank?
|
||||||
|
|
||||||
|
update = true
|
||||||
|
|
||||||
|
# get number of pinned columns
|
||||||
|
pinned_items_count = state.count { |el| el['pinned'].present? }
|
||||||
|
|
||||||
|
# update position of columns if they are not pinned
|
||||||
|
state.each do |el|
|
||||||
|
el['position'] += 1 if el['pinned'].blank? && el['position'].present?
|
||||||
|
end
|
||||||
|
|
||||||
|
# create new state of favorite column
|
||||||
|
new_element = {
|
||||||
|
colId: 'favorite',
|
||||||
|
hide: false,
|
||||||
|
pinned: nil
|
||||||
|
}
|
||||||
|
|
||||||
|
# add only position if other columns have positions. Position only get columns for which user at least once change settings
|
||||||
|
new_element[:position] = pinned_items_count if state.dig(0, 'position').present?
|
||||||
|
state.insert(pinned_items_count, new_element)
|
||||||
|
end
|
||||||
|
user.save! if update
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
dir.down do
|
||||||
|
User.find_each do |user|
|
||||||
|
update = false
|
||||||
|
STATE_NAMES.each do |state_name|
|
||||||
|
state = user.settings.dig(state_name, 'columnsState')
|
||||||
|
next if state.blank?
|
||||||
|
|
||||||
|
update = true
|
||||||
|
|
||||||
|
favorite = state.find { |el| el['colId'] == 'favorite' }
|
||||||
|
|
||||||
|
next unless favorite
|
||||||
|
|
||||||
|
state.reject! { |el| el['colId'] == 'favorite' }
|
||||||
|
|
||||||
|
next if favorite['position'].blank?
|
||||||
|
|
||||||
|
state.each do |el|
|
||||||
|
el['position'] -= 1 if el['position'].present? && el['position'] > favorite['position']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
user.save! if update
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue