From 871e1975a4829dd9ec992e25afe83a7da2a793aa Mon Sep 17 00:00:00 2001 From: Gordon Lin <75815453+gordlin@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:25:49 -0400 Subject: [PATCH] Redesign metadata details form --- src/components/helpers/metadata-content.vue | 448 +++++++++++++------- src/components/metadata-editor.vue | 211 ++++++--- src/lang/lang.csv | 18 +- 3 files changed, 451 insertions(+), 226 deletions(-) diff --git a/src/components/helpers/metadata-content.vue b/src/components/helpers/metadata-content.vue index 3fd9c751..aea99ecf 100644 --- a/src/components/helpers/metadata-content.vue +++ b/src/components/helpers/metadata-content.vue @@ -1,161 +1,238 @@ + + diff --git a/src/components/metadata-editor.vue b/src/components/metadata-editor.vue index 30dac41c..2af46efe 100644 --- a/src/components/metadata-editor.vue +++ b/src/components/metadata-editor.vue @@ -6,11 +6,11 @@
-
+
{{ editExisting ? $t('editor.editProduct') : $t('editor.createProduct') }}
-

+

{{ $t('editor.editMetadata.editExistingHeader') }}

@@ -82,7 +82,8 @@ v-tippy="{ content: $t('editor.editMetadata.input.tooltip'), trigger: 'focusin', - placement: 'top-end' + placement: 'top-end', + touch: false }" /> +
+
+ + +
+ + +
- -
@@ -424,24 +470,27 @@ @@ -574,6 +623,21 @@ export default class MetadataEditorV extends Vue { returnTop: true, dateModified: '' }; + editingMetadata = false; + temporaryMetadataCopy: MetadataContent = { + // A copy to save changes before edit, so they can be reverted + title: '', + introTitle: '', + introSubtitle: '', + logoPreview: '', + logoName: '', + logoAltText: '', + contextLink: '', + contextLabel: '', + tocOrientation: '', + returnTop: true, + dateModified: '' + }; // add more required metadata fields to here as needed reqFields: { uuid: boolean } = { uuid: true @@ -583,6 +647,7 @@ export default class MetadataEditorV extends Vue { mounted(): void { this.currLang = (this.$route.params.lang as string) || 'en'; + this.editingMetadata = !this.editExisting; } created(): void { @@ -666,6 +731,28 @@ export default class MetadataEditorV extends Vue { } } + /** + * Open current editor config as a new Storylines product in new tab. + * Note: Preview button on metadata editor will only show when editing an existing product, not cwhen creating a new one + * This is a design decision, can change if we decide that people would want to preview new products for some reason + */ + preview(): void { + // save current metadata final changes before previewing product + this.saveMetadata(false); + + setTimeout(() => { + const routeData = this.$router.resolve({ + name: 'preview', + params: { lang: this.configLang, uid: this.uuid } + }); + const previewTab = window.open(routeData.href, '_blank'); + (previewTab as Window).props = { + configs: this.configs, + configFileStructure: this.configFileStructure + }; + }, 5); + } + /** * Generates a new product file for brand new products. */ @@ -1127,6 +1214,9 @@ export default class MetadataEditorV extends Vue { // If there's no logo, mark the product as loaded. this.loadStatus = 'loaded'; } + + // Load the temp copy of the metadata + this.temporaryMetadataCopy = JSON.parse(JSON.stringify(this.metadata)); } /** @@ -1238,6 +1328,12 @@ export default class MetadataEditorV extends Vue { this.unsavedChanges = true; } + discardMetadataUpdates(): void { + this.metadata = JSON.parse(JSON.stringify(this.temporaryMetadataCopy)); + this.editingMetadata = false; + this.unsavedChanges = false; // TODO: Does this cause false negatives? (maybe not if we don't have discarding for vfm) + } + /** * Called when `Save Changes` is pressed on metadata page. Save metadata content fields * to config file. If `publish` is set to true, publish to server as well. @@ -1277,6 +1373,8 @@ export default class MetadataEditorV extends Vue { if (publish) { this.generateConfig(); + this.temporaryMetadataCopy = JSON.parse(JSON.stringify(this.metadata)); + this.editingMetadata = false; } const userStore = useUserStore(); @@ -1303,6 +1401,7 @@ export default class MetadataEditorV extends Vue { tocOrientation: '', returnTop: true }; + this.temporaryMetadataCopy = JSON.parse(JSON.stringify(this.metadata)); this.configs = { en: undefined, fr: undefined }; this.slides = []; } @@ -1561,49 +1660,21 @@ $font-list: 'Segoe UI', system-ui, ui-sans-serif, Tahoma, Geneva, Verdana, sans- max-width: 80%; min-width: 70%; max-height: 90%; - padding: 12px; + padding: 20px; } .vfm__content label { - width: 10vw; - text-align: right; - margin-right: 15px; - display: inline-block; + display: block; } .editor-container h3 { - font-size: larger; - } - - .vfm__content input { - padding: 5px 10px; - margin-top: 5px; - border: 1px solid black; - display: inline; + font-size: x-large; } .editor-container .input-error { border: 1px solid red; } - .vfm__content button { - padding: 5px 12px; - margin: 0px 10px; - font-weight: 600; - transition-duration: 0.2s; - } - - .vfm__content button:hover:enabled { - background-color: #dbdbdb; - color: black; - } - - .vfm__content button:disabled { - border: 1px solid gray; - color: gray; - cursor: not-allowed; - } - .image-preview { max-width: 150px; max-height: 150px; diff --git a/src/lang/lang.csv b/src/lang/lang.csv index 40a05bcf..4f52ec92 100644 --- a/src/lang/lang.csv +++ b/src/lang/lang.csv @@ -57,10 +57,23 @@ editor.editMetadata.versionHistory.noResults,There are no previous versions of t editor.editMetadata.versionHistory.load,Load this version,1,Charger cette version,0 editor.editMetadata.versionHistory.actions,Actions,1,Actes,0 editor.editMetadata.versionHistory.saveDate,Save Date,1,Enregistrer la date,0 +editor.editMetadata.previewProject,Preview project,1,Projet d'aperçu,0 editor.editMetadata.retrievalAborted,Product retrieval manually aborted.,1,Récupération du produit interrompue manuellement.,0 +editor.metadataForm.caption.title,The title field appears in the top bar of the storyline product. The top bar is visible to users at all times.,1,Le champ de titre apparaît dans la barre supérieure du produit de scénario. La barre supérieure est visible à tout moment pour les utilisateurs.,0 +editor.metadataForm.caption.tocOrientation,"Determines the direction of the storyline's table of contents: horizontal (above the storyline) or vertical (beside the storyline, on the left).",1,"Détermine la direction de la table des matières du scénario : horizontale (au-dessus du scénario) ou verticale (à côté du scénario, à gauche).",0 +editor.metadataForm.caption.introTitle,"The intro title is the title displayed in large text on the first slide, right underneath the logo (if given).",1,"Le titre d'introduction est le titre affiché en gros texte sur la première diapositive, juste en dessous du logo (s'il est fourni).",0 +editor.metadataForm.caption.introSubtitle,"The intro subtitle displays underneath the intro title, in small text.",1,"Le sous-titre d'introduction s'affiche sous le titre d'introduction, en petit texte.",0 +editor.metadataForm.caption.logoAltText,"For accessibility purposes, provide description text for the logo.",1,"À des fins d’accessibilité, veuillez fournir un texte de description pour le logo.",0 +editor.metadataForm.caption.contextLink,"Context link shows up at the bottom of the page to provide additional resources for interested users.",1,"Le lien contextuel apparaît au bas de la page pour fournir des ressources supplémentaires aux utilisateurs intéressés.",0 +editor.metadataForm.caption.contextLabel,"Context label shows up as text. When users click the context link, the linked site appears in a new tab for the user.",1,"L'étiquette de contexte s'affiche sous forme de texte. Lorsque les utilisateurs cliquent sur le lien contextuel, le site lié apparaît dans un nouvel onglet pour l'utilisateur.",0 +editor.metadataForm.introPage.heading,Introduction page details,1,Détails de la page d'introduction,0 +editor.metadataForm.introPage.explanation,"The introduction page of the storylines product is displayed to users at the beginning of the storyline product, before any content slides.",1,"La page d'introduction du produit Storylines est affichée aux utilisateurs au début du produit Storylines, avant toute diapositive de contenu.",0 +editor.metadataForm.endOfPage.heading,End of page information,1,Informations de fin de page,0 +editor.metadataForm.endOfPage.explanation,"This information is displayed at the end of the storyline product, after all content slides.",1,"Ces informations sont affichées à la fin du scénario du produit, après toutes les diapositives de contenu.",0 editor.done,Done,1,Fini,0 editor.productDetails,Storylines product details,1,Détails du produit de scénarios,1 -editor.metadata.instructions,Fill in metadata details about your new Storylines product. Use the "Preview" button to see what your slides will look like.,1,Inscrivez les métadonnées de votre nouveau produit de scénario. Utilisez la fonction « Afficher l’aperçu » pour voir à quoi ressemblent vos diapositives.,1 +editor.metadata.instructions.new,Fill in metadata details about your new Storylines product.,1,Inscrivez les métadonnées de votre nouveau produit de scénario.,1 +editor.metadata.instructions.existing,View or edit metadata details about your Storylines product. Use the "Preview" button to see what your slides will look like.,1,Affichez ou modifiez les détails des métadonnées de votre produit Storylines. Utilisez le bouton « Aperçu » pour voir à quoi ressembleront vos diapositives.,0 editor.uuid,UUID,1,UUID,0 editor.uuid.required,(required),1,(obligatoire),0 editor.uuid.new,New UUID,1,New UUID,0 @@ -96,7 +109,8 @@ editor.preview,Preview,1,Afficher l’aperçu,1 editor.confirm,Confirm,1,Confirmer,1 editor.cancel,Cancel,1,Annuler,1 editor.unsavedChanges,Unsaved changes,1,Modifications non enregistrées,1 -editor.saveChanges,Save Changes,1,Enregistrer les modifications,1 +editor.saveChanges,Save changes,1,Enregistrer les modifications,1 +editor.discardChanges,Discard changes,1,Annuler les modifications,0 editor.label.or,or,1,ou,1 editor.label.browse,browse,1,parcourir,1 editor.label.upload,to upload,1,téléverser,1