From 592ca187cec8fd11290b694bae47133f55a523f5 Mon Sep 17 00:00:00 2001 From: Matt Szczerba Date: Fri, 7 Jun 2024 11:40:09 -0400 Subject: [PATCH] Added a warning to inform the user of potentially long save times and disabled the button until complete. Added the title and a scrollbar to UUID dropdown --- src/components/metadata-editor.vue | 86 +++++++++++++++++++++++------- src/stores/userStore.ts | 1 + tailwind.config.js | 3 ++ 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/src/components/metadata-editor.vue b/src/components/metadata-editor.vue index f2c3d471d..b38b12b39 100644 --- a/src/components/metadata-editor.vue +++ b/src/components/metadata-editor.vue @@ -55,23 +55,29 @@ v-model="uuid" @focus="showDropdown = true" @blur="showDropdown = false" + @keydown.down.prevent="highlightNext" + @keydown.up.prevent="highlightPrevious" + @keydown.enter.prevent="selectHighlighted" :class="{ 'input-error': error || !reqFields.uuid }" />
@@ -379,6 +385,7 @@ export default class MetadataEditorV extends Vue { warning: 'none' | 'uuid' | 'rename' = 'none'; // used for duplicate uuid warning configLang = 'en'; showDropdown = false; + highlightedIndex = -1; storylineHistory: History[] = []; selectedHistory: History | null = null; @@ -944,6 +951,7 @@ export default class MetadataEditorV extends Vue { const formData = new FormData(); formData.append('data', content, `${this.uuid}.zip`); const headers = { 'Content-Type': 'multipart/form-data' }; + Message.warning('Please wait. This may take several minutes.'); axios .post(this.apiUrl + '/upload', formData, { headers }) @@ -953,13 +961,13 @@ export default class MetadataEditorV extends Vue { responseData.status; // HTTP status this.unsavedChanges = false; this.loadExisting = true; // if editExisting was false, we can now set it to true - Message.success('Successfully saved changes!'); if (process.env.VUE_APP_CURR_ENV !== '#{CURR_ENV}#') { if (responseData.new) { axios .post(process.env.VUE_APP_NET_API_URL + '/api/user/register', { - uuid: this.uuid + uuid: this.uuid, + title: this.metadata.title ?? '' }) .then((response: any) => { const userStore = useUserStore(); @@ -970,9 +978,15 @@ export default class MetadataEditorV extends Vue { axios .post(process.env.VUE_APP_NET_API_URL + '/api/version/commit', formData) .then((response: any) => { - console.log('Version saved successfully.'); + Message.success('Successfully saved changes!'); }) - .catch((error: any) => console.log(error.response || error)); + .catch((error: any) => console.log(error.response || error)) + .finally(() => { + // padding to prevent save button from being clicked rapidly + setTimeout(() => { + this.saving = false; + }, 500); + }); }) .catch((error: any) => console.log(error.response || error)); } else { @@ -980,9 +994,15 @@ export default class MetadataEditorV extends Vue { axios .post(process.env.VUE_APP_NET_API_URL + '/api/version/commit', formData) .then((response: any) => { - console.log('Version saved successfully.'); + Message.success('Successfully saved changes!'); }) - .catch((error: any) => console.log(error.response || error)); + .catch((error: any) => console.log(error.response || error)) + .finally(() => { + // padding to prevent save button from being clicked rapidly + setTimeout(() => { + this.saving = false; + }, 500); + }); } fetch(this.apiUrl + `/retrieveMessages`) @@ -1001,12 +1021,6 @@ export default class MetadataEditorV extends Vue { }) .catch(() => { Message.error('Failed to save changes.'); - }) - .finally(() => { - // padding to prevent save button from being clicked rapidly - setTimeout(() => { - this.saving = false; - }, 500); }); }); @@ -1140,6 +1154,7 @@ export default class MetadataEditorV extends Vue { }); } this.warning = 'none'; + this.highlightedIndex = -1; }); /** @@ -1268,16 +1283,49 @@ export default class MetadataEditorV extends Vue { } } + highlightNext() { + if (this.highlightedIndex < this.getStorylines.length - 1) { + this.highlightedIndex++; + this.scrollIntoView(); + } + } + + highlightPrevious() { + if (this.highlightedIndex > 0) { + this.highlightedIndex--; + this.scrollIntoView(); + } + } + + selectHighlighted() { + if (this.highlightedIndex !== -1) { + const selectedStoryline = this.getStorylines[this.highlightedIndex]; + this.selectUuid(selectedStoryline.uuid); + } + } + + scrollIntoView() { + this.$nextTick(() => { + const container = this.$el.querySelector('.overflow-y-auto'); + const activeItem = container.querySelector('li.bg-gray-300'); + if (activeItem) container.scrollTop = activeItem.offsetTop - container.offsetTop; + }); + } + get getStorylines() { const userStore = useUserStore(); const userStorylines = userStore.userProfile.storylines?.map((s) => ({ ...s, isUserStoryline: true })) || []; const allStorylines = userStore.userProfile.allStorylines?.filter((s) => !userStorylines.some((u) => u.uuid === s.uuid)) || []; - let combined = [...userStorylines, ...allStorylines]; - if (this.uuid) - combined = combined.filter((storyline) => storyline.uuid.toLowerCase().includes(this.uuid.toLowerCase())); + if (this.uuid) { + combined = combined.filter( + (storyline) => + storyline.uuid.toLowerCase().includes(this.uuid.toLowerCase()) || + (storyline.title && storyline.title.toLowerCase().includes(this.uuid.toLowerCase())) + ); + } return combined; } diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts index 57b28b553..2a40264e9 100644 --- a/src/stores/userStore.ts +++ b/src/stores/userStore.ts @@ -2,6 +2,7 @@ import { defineStore } from 'pinia'; interface Storyline { uuid: string; + title: string; isUserStoryline?: boolean; } diff --git a/tailwind.config.js b/tailwind.config.js index 39a7cabef..2a4631df2 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -22,6 +22,9 @@ module.exports = { flex: { 2: '2 2 0%' }, + maxHeight:{ + '60vh': '60vh' + }, maxWidth: { '8xl': '90rem', '9xl': '110rem'