Remember the state of Step (Collapsed or Extended) per User [SCI-10258]

This commit is contained in:
Ivan Kljun 2024-04-03 13:23:10 +02:00
parent 5d93713341
commit c49ddd972b
5 changed files with 70 additions and 4 deletions

View file

@ -14,7 +14,14 @@ module Users
key = setting[:key] key = setting[:key]
data = setting[:data] data = setting[:data]
current_user.settings[key] = data if Extends::WHITELISTED_USER_SETTINGS.include?(key.to_s) next unless Extends::WHITELISTED_USER_SETTINGS.include?(key.to_s)
case key.to_s
when 'task_step_states'
update_task_step_states(data)
else
current_user.settings[key] = data
end
end end
if current_user.save if current_user.save
@ -24,6 +31,22 @@ module Users
status: :unprocessable_entity status: :unprocessable_entity
end end
end end
private
def update_task_step_states(task_step_states_data)
current_states = current_user.settings.fetch('task_step_states', {})
task_step_states_data.each do |step_id, collapsed|
if collapsed
current_states[step_id] = true
else
current_states.delete(step_id)
end
end
current_user.settings['task_step_states'] = current_states
end
end end
end end
end end

View file

@ -183,6 +183,7 @@
@step:move_attachment="reloadStep" @step:move_attachment="reloadStep"
@step:drag_enter="dragEnter" @step:drag_enter="dragEnter"
:reorderStepUrl="steps.length > 1 ? urls.reorder_steps_url : null" :reorderStepUrl="steps.length > 1 ? urls.reorder_steps_url : null"
:userSettingsUrl="userSettingsUrl"
:assignableMyModuleId="protocol.attributes.assignable_my_module_id" :assignableMyModuleId="protocol.attributes.assignable_my_module_id"
/> />
<div v-if="(index === steps.length - 1) && urls.add_step_url" class="insert-step" @click="addStep(index + 1)"> <div v-if="(index === steps.length - 1) && urls.add_step_url" class="insert-step" @click="addStep(index + 1)">
@ -237,7 +238,7 @@ import ReorderableItemsModal from '../shared/reorderable_items_modal.vue';
import PublishProtocol from './modals/publish_protocol.vue'; import PublishProtocol from './modals/publish_protocol.vue';
import clipboardPasteModal from '../shared/content/attachments/clipboard_paste_modal.vue'; import clipboardPasteModal from '../shared/content/attachments/clipboard_paste_modal.vue';
import AssetPasteMixin from '../shared/content/attachments/mixins/paste.js'; import AssetPasteMixin from '../shared/content/attachments/mixins/paste.js';
import axios from '../../packs/custom_axios';
import UtilsMixin from '../mixins/utils.js'; import UtilsMixin from '../mixins/utils.js';
import stackableHeadersMixin from '../mixins/stackableHeadersMixin'; import stackableHeadersMixin from '../mixins/stackableHeadersMixin';
import moduleNameObserver from '../mixins/moduleNameObserver'; import moduleNameObserver from '../mixins/moduleNameObserver';
@ -277,10 +278,12 @@ export default {
reordering: false, reordering: false,
publishing: false, publishing: false,
stepToReload: null, stepToReload: null,
activeDragStep: null activeDragStep: null,
userSettingsUrl: null
}; };
}, },
mounted() { mounted() {
this.userSettingsUrl = document.querySelector('meta[name="user-settings-url"]').getAttribute('content');
$.get(this.protocolUrl, (result) => { $.get(this.protocolUrl, (result) => {
this.protocol = result.data; this.protocol = result.data;
this.$nextTick(() => { this.$nextTick(() => {
@ -309,9 +312,24 @@ export default {
}, },
collapseSteps() { collapseSteps() {
$('.step-container .collapse').collapse('hide'); $('.step-container .collapse').collapse('hide');
this.updateStepStateSettings(true);
}, },
expandSteps() { expandSteps() {
$('.step-container .collapse').collapse('show'); $('.step-container .collapse').collapse('show');
this.updateStepStateSettings(false);
},
updateStepStateSettings(newState) {
const updatedData = this.steps.reduce((acc, currentStep) => {
acc[currentStep.id] = newState;
return acc;
}, {});
const settings = {
key: 'task_step_states',
data: updatedData
};
axios.put(this.userSettingsUrl, { settings: [settings] });
}, },
deleteSteps() { deleteSteps() {
$.post(this.urls.delete_steps_url, () => { $.post(this.urls.delete_steps_url, () => {

View file

@ -183,6 +183,9 @@
reorderStepUrl: { reorderStepUrl: {
required: false required: false
}, },
userSettingsUrl: {
required: false
},
assignableMyModuleId: { assignableMyModuleId: {
type: Number, type: Number,
required: false required: false
@ -249,6 +252,15 @@
} }
}, },
mounted() { mounted() {
this.$nextTick(() => {
const stepId = `#stepBody${this.step.id}`;
this.isCollapsed = this.step.attributes.collapsed;
if (this.isCollapsed) {
$(stepId).collapse('hide');
} else {
$(stepId).collapse('show');
}
});
$(this.$refs.comments).data('closeCallback', this.closeCommentsSidebar); $(this.$refs.comments).data('closeCallback', this.closeCommentsSidebar);
$(this.$refs.comments).data('openCallback', this.closeCommentsSidebar); $(this.$refs.comments).data('openCallback', this.closeCommentsSidebar);
$(this.$refs.actionsDropdownButton).on('shown.bs.dropdown hidden.bs.dropdown', () => { $(this.$refs.actionsDropdownButton).on('shown.bs.dropdown hidden.bs.dropdown', () => {
@ -402,6 +414,13 @@
}, },
toggleCollapsed() { toggleCollapsed() {
this.isCollapsed = !this.isCollapsed; this.isCollapsed = !this.isCollapsed;
const settings = {
key: 'task_step_states',
data: { [this.step.id]: this.isCollapsed }
};
axios.put(this.userSettingsUrl, { settings: [settings] });
}, },
showDeleteModal() { showDeleteModal() {
this.confirmingDelete = true; this.confirmingDelete = true;

View file

@ -10,7 +10,12 @@ class StepSerializer < ActiveModel::Serializer
attributes :name, :position, :completed, :attachments_manageble, :urls, :assets_view_mode, attributes :name, :position, :completed, :attachments_manageble, :urls, :assets_view_mode,
:marvinjs_enabled, :marvinjs_context, :created_by, :created_at, :assets_order, :marvinjs_enabled, :marvinjs_context, :created_by, :created_at, :assets_order,
:wopi_enabled, :wopi_context, :comments_count, :unseen_comments, :storage_limit, :wopi_enabled, :wopi_context, :comments_count, :unseen_comments, :storage_limit,
:type, :open_vector_editor_context :type, :open_vector_editor_context, :collapsed
def collapsed
step_states = @instance_options[:user].settings.fetch('task_step_states', {})
step_states[object.id.to_s] == true
end
def marvinjs_enabled def marvinjs_enabled
MarvinJsService.enabled? MarvinJsService.enabled?

View file

@ -650,6 +650,7 @@ class Extends
ReportTemplates_archived_state ReportTemplates_archived_state
Repositories_active_state Repositories_active_state
Repositories_archived_state Repositories_archived_state
task_step_states
).freeze ).freeze
end end