mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-16 05:42:13 +08:00
Implement saving of table state to DB [SCI-9983]
This commit is contained in:
parent
427f7a7b2e
commit
c9490ca528
12 changed files with 105 additions and 43 deletions
29
app/controllers/users/settings/user_settings_controller.rb
Normal file
29
app/controllers/users/settings/user_settings_controller.rb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Users
|
||||
module Settings
|
||||
class UserSettingsController < ApplicationController
|
||||
def show
|
||||
render json: { data: current_user.settings[params[:key]] }
|
||||
end
|
||||
|
||||
def update
|
||||
settings_params = params.require(:settings)
|
||||
|
||||
settings_params.each do |setting|
|
||||
key = setting[:key]
|
||||
data = setting[:data]
|
||||
|
||||
current_user.settings[key] = data if Extends::WHITELISTED_USER_SETTINGS.include?(key.to_s)
|
||||
end
|
||||
|
||||
if current_user.save
|
||||
head :ok
|
||||
else
|
||||
render json: { error: 'Failed to update settings', details: current_user.errors.full_messages },
|
||||
status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<DataTable
|
||||
:columnDefs="columnDefs"
|
||||
tableId="ExperimentsList"
|
||||
tableId="ExperimentList"
|
||||
:dataUrl="dataSource"
|
||||
:reloadingTable="reloadingTable"
|
||||
:toolbarActions="toolbarActions"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="h-full">
|
||||
<DataTable :columnDefs="columnDefs"
|
||||
:tableId="'labelTemplates'"
|
||||
:tableId="'LabelTemplates'"
|
||||
:dataUrl="dataSource"
|
||||
:reloadingTable="reloadingTable"
|
||||
:toolbarActions="toolbarActions"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<DataTable
|
||||
ref="table"
|
||||
:columnDefs="columnDefs"
|
||||
tableId="MyModulesList"
|
||||
tableId="MyModuleList"
|
||||
:dataUrl="dataSource"
|
||||
:reloadingTable="reloadingTable"
|
||||
:toolbarActions="toolbarActions"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<DataTable :columnDefs="columnDefs"
|
||||
tableId="ProjectsList"
|
||||
tableId="ProjectList"
|
||||
:dataUrl="dataSource"
|
||||
:reloadingTable="reloadingTable"
|
||||
:toolbarActions="toolbarActions"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="h-full">
|
||||
<DataTable :columnDefs="columnDefs"
|
||||
:tableId="'protocolTemplates'"
|
||||
:tableId="'ProtocolTemplates'"
|
||||
:dataUrl="dataSource"
|
||||
:reloadingTable="reloadingTable"
|
||||
:currentViewMode="currentViewMode"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="h-full">
|
||||
<DataTable :columnDefs="columnDefs"
|
||||
:tableId="'reportTemplates'"
|
||||
:tableId="'ReportTemplates'"
|
||||
:dataUrl="dataSource"
|
||||
:reloadingTable="reloadingTable"
|
||||
:toolbarActions="toolbarActions"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="h-full">
|
||||
<DataTable :columnDefs="columnDefs"
|
||||
tableId="repositories"
|
||||
tableId="Repositories"
|
||||
:dataUrl="dataSource"
|
||||
:reloadingTable="reloadingTable"
|
||||
:currentViewMode="currentViewMode"
|
||||
|
|
|
|||
|
|
@ -168,7 +168,9 @@ export default {
|
|||
currentViewRender: 'table',
|
||||
cardCheckboxes: [],
|
||||
dataLoading: true,
|
||||
lastPage: false
|
||||
lastPage: false,
|
||||
tableState: null,
|
||||
userSettingsUrl: null
|
||||
};
|
||||
},
|
||||
components: {
|
||||
|
|
@ -185,11 +187,6 @@ export default {
|
|||
perPageOptions() {
|
||||
return [10, 20, 50, 100].map((value) => ([value, `${value} ${this.i18n.t('datatable.rows')}`]));
|
||||
},
|
||||
tableState() {
|
||||
if (!localStorage.getItem(`datatable:${this.tableId}_columns_state`)) return null;
|
||||
|
||||
return JSON.parse(localStorage.getItem(`datatable:${this.tableId}_columns_state`));
|
||||
},
|
||||
actionsParams() {
|
||||
return {
|
||||
items: JSON.stringify(this.selectedRows.map((row) => ({ id: row.id, type: row.type })))
|
||||
|
|
@ -247,6 +244,9 @@ export default {
|
|||
}
|
||||
|
||||
return columns;
|
||||
},
|
||||
stateKey() {
|
||||
return `${this.tableId}_${this.currentViewMode}_state`;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -264,14 +264,8 @@ export default {
|
|||
this.saveTableState();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.tableState) {
|
||||
this.currentViewRender = this.tableState.currentViewRender || 'table';
|
||||
this.perPage = this.tableState.perPage || 20;
|
||||
this.order = this.tableState.order;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.userSettingsUrl = document.querySelector('meta[name="user-settings-url"]').getAttribute('content');
|
||||
this.loadData();
|
||||
window.addEventListener('resize', this.resize);
|
||||
},
|
||||
|
|
@ -294,6 +288,39 @@ export default {
|
|||
this.loadData();
|
||||
}
|
||||
},
|
||||
fetchAndApplyTableState() {
|
||||
axios
|
||||
.get(this.userSettingsUrl, {
|
||||
params: {
|
||||
key: this.stateKey
|
||||
}
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.data) {
|
||||
const { currentViewRender, columnsState, perPage, order } = response.data.data;
|
||||
this.tableState = response.data.data;
|
||||
this.currentViewRender = currentViewRender;
|
||||
this.columnsState = columnsState;
|
||||
this.perPage = perPage;
|
||||
this.order = order;
|
||||
|
||||
if (this.order) {
|
||||
this.tableState.columnsState.forEach((column) => {
|
||||
const updatedColumn = column;
|
||||
updatedColumn.sort = this.order.column === column.colId ? this.order.dir : null;
|
||||
return updatedColumn;
|
||||
});
|
||||
}
|
||||
this.columnApi.applyColumnState({
|
||||
state: this.tableState.columnsState,
|
||||
applyOrder: true
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.initializing = false;
|
||||
}, 200);
|
||||
});
|
||||
},
|
||||
getRowClass() {
|
||||
if (this.currentViewMode === 'archived') {
|
||||
return '!bg-sn-light-grey';
|
||||
|
|
@ -370,22 +397,7 @@ export default {
|
|||
this.gridApi = params.api;
|
||||
this.columnApi = params.columnApi;
|
||||
|
||||
if (this.tableState) {
|
||||
if (this.order) {
|
||||
this.tableState.columnsState.forEach((column) => {
|
||||
const updatedColumn = column;
|
||||
updatedColumn.sort = this.order.column === column.colId ? this.order.dir : null;
|
||||
return updatedColumn;
|
||||
});
|
||||
}
|
||||
this.columnApi.applyColumnState({
|
||||
state: this.tableState.columnsState,
|
||||
applyOrder: true
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.initializing = false;
|
||||
}, 200);
|
||||
this.fetchAndApplyTableState();
|
||||
},
|
||||
onFirstDataRendered() {
|
||||
this.resize();
|
||||
|
|
@ -408,17 +420,18 @@ export default {
|
|||
this.reloadTable();
|
||||
},
|
||||
saveTableState() {
|
||||
let columnsState = this.tableState?.columnsState;
|
||||
if (this.columnApi) {
|
||||
columnsState = this.columnApi.getColumnState();
|
||||
}
|
||||
const columnsState = this.columnApi ? this.columnApi.getColumnState() : this.tableState?.columnsState || [];
|
||||
const tableState = {
|
||||
columnsState: columnsState || [],
|
||||
columnsState,
|
||||
order: this.order,
|
||||
currentViewRender: this.currentViewRender,
|
||||
perPage: this.perPage
|
||||
};
|
||||
localStorage.setItem(`datatable:${this.tableId}_columns_state`, JSON.stringify(tableState));
|
||||
const settings = {
|
||||
key: this.stateKey,
|
||||
data: tableState
|
||||
};
|
||||
axios.put(this.userSettingsUrl, { settings: [settings] });
|
||||
},
|
||||
setSelectedRows() {
|
||||
this.selectedRows = this.gridApi.getSelectedRows();
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
<% if user_signed_in? %>
|
||||
<meta name="expiration-url" content="<%= users_expire_in_path %>">
|
||||
<meta name="revive-url" content="<%= users_revive_session_path %>">
|
||||
<meta name="user-settings-url" content="<%= users_settings_user_settings_path %>">
|
||||
<% end %>
|
||||
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
|
||||
<%= stylesheet_link_tag 'bootstrap_pack', media: 'all' %>
|
||||
|
|
|
|||
|
|
@ -629,6 +629,23 @@ class Extends
|
|||
in_app: true
|
||||
}
|
||||
}
|
||||
|
||||
WHITELISTED_USER_SETTINGS = %w(
|
||||
LabelTemplates_active_state
|
||||
LabelTemplates_archived_state
|
||||
ExperimentList_active_state
|
||||
ExperimentList_archived_state
|
||||
MyModuleList_active_state
|
||||
MyModuleList_archived_state
|
||||
ProjectList_active_state
|
||||
ProjectList_archived_state
|
||||
ProtocolTemplates_active_state
|
||||
ProtocolTemplates_archived_state
|
||||
ReportTemplates_active_state
|
||||
ReportTemplates_archived_state
|
||||
Repositories_active_state
|
||||
Repositories_archived_state
|
||||
).freeze
|
||||
end
|
||||
|
||||
# rubocop:enable Style/MutableConstant
|
||||
|
|
|
|||
|
|
@ -136,11 +136,14 @@ Rails.application.routes.draw do
|
|||
|
||||
namespace :users do
|
||||
namespace :settings do
|
||||
resource :user_settings, only: %i(show update)
|
||||
|
||||
resources :teams, only: [] do
|
||||
collection do
|
||||
post :switch
|
||||
end
|
||||
end
|
||||
|
||||
resources :webhooks, only: %i(index create update destroy) do
|
||||
collection do
|
||||
post :destroy_filter
|
||||
|
|
@ -150,7 +153,6 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
# Invite users
|
||||
devise_scope :user do
|
||||
post '/invite',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue