Skip to content

Commit

Permalink
Merge pull request #493 from RyanCoulsonCA/fix-310
Browse files Browse the repository at this point in the history
add export product button
  • Loading branch information
yileifeng authored Jan 10, 2025
2 parents 3ef2cd0 + 03d87b4 commit 09dea86
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 87 deletions.
57 changes: 55 additions & 2 deletions src/components/editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,50 @@
>
<span class="bottom-0 question-mark-button"> ? </span>
</button>

<!-- Export button -->
<button
@click="exportProduct"
class="bg-white border border-black rounded-full w-9 h-9 flex items-center justify-center hover:bg-gray-100"
v-tippy="{
delay: '200',
placement: 'top',
content: $t('editor.export'),
animateFill: true
}"
:aria-label="$t('editor.export')"
>
<span class="bottom-0 question-mark-button">
<svg
width="20px"
height="20px"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
stroke="#000000"
stroke-width="0.336"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
stroke="#CCCCCC"
stroke-width="0.288"
></g>
<g id="SVGRepo_iconCarrier">
<path
d="M12.5535 16.5061C12.4114 16.6615 12.2106 16.75 12 16.75C11.7894 16.75 11.5886 16.6615 11.4465 16.5061L7.44648 12.1311C7.16698 11.8254 7.18822 11.351 7.49392 11.0715C7.79963 10.792 8.27402 10.8132 8.55352 11.1189L11.25 14.0682V3C11.25 2.58579 11.5858 2.25 12 2.25C12.4142 2.25 12.75 2.58579 12.75 3V14.0682L15.4465 11.1189C15.726 10.8132 16.2004 10.792 16.5061 11.0715C16.8118 11.351 16.833 11.8254 16.5535 12.1311L12.5535 16.5061Z"
fill="#000"
></path>
<path
d="M3.75 15C3.75 14.5858 3.41422 14.25 3 14.25C2.58579 14.25 2.25 14.5858 2.25 15V15.0549C2.24998 16.4225 2.24996 17.5248 2.36652 18.3918C2.48754 19.2919 2.74643 20.0497 3.34835 20.6516C3.95027 21.2536 4.70814 21.5125 5.60825 21.6335C6.47522 21.75 7.57754 21.75 8.94513 21.75H15.0549C16.4225 21.75 17.5248 21.75 18.3918 21.6335C19.2919 21.5125 20.0497 21.2536 20.6517 20.6516C21.2536 20.0497 21.5125 19.2919 21.6335 18.3918C21.75 17.5248 21.75 16.4225 21.75 15.0549V15C21.75 14.5858 21.4142 14.25 21 14.25C20.5858 14.25 20.25 14.5858 20.25 15C20.25 16.4354 20.2484 17.4365 20.1469 18.1919C20.0482 18.9257 19.8678 19.3142 19.591 19.591C19.3142 19.8678 18.9257 20.0482 18.1919 20.1469C17.4365 20.2484 16.4354 20.25 15 20.25H9C7.56459 20.25 6.56347 20.2484 5.80812 20.1469C5.07435 20.0482 4.68577 19.8678 4.40901 19.591C4.13225 19.3142 3.9518 18.9257 3.85315 18.1919C3.75159 17.4365 3.75 16.4354 3.75 15Z"
fill="#000"
></path>
</g>
</svg>
</span>
</button>
</div>
</div>
</div>
Expand Down Expand Up @@ -543,6 +587,14 @@ export default class EditorV extends Vue {
});
}
exportProduct(): void {
if (this.$refs.slide != null && this.currentSlide !== '') {
(this.$refs.slide as SlideEditorV).saveChanges();
}
this.$emit('export-product');
}
/**
* Open current editor config as a new Storylines product in new tab.
* @param language The config language to preview (either 'en' or 'fr')
Expand Down Expand Up @@ -692,8 +744,9 @@ select:focus {
}
.question-mark-button {
font-size: 24px;
line-height: 1.8rem;
font-size: 20px;
line-height: 1.4rem;
font-weight: 500;
}
.toc-popup-button {
Expand Down
196 changes: 111 additions & 85 deletions src/components/metadata-editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@
@save-changes="onSave"
@save-status="updateSaveStatus"
@refresh-config="refreshConfig"
@export-product="exportProduct"
ref="mainEditor"
>
<!-- Metadata editing modal inside the editor -->
Expand Down Expand Up @@ -591,6 +592,7 @@ import { useUserStore } from '../stores/userStore';
import JSZip from 'jszip';
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import { saveAs } from 'file-saver';
import Message from 'vue-m-message';
import SlideEditorV from './slide-editor.vue';
Expand Down Expand Up @@ -1357,6 +1359,20 @@ export default class MetadataEditorV extends Vue {
this.temporaryMetadataCopy = JSON.parse(JSON.stringify(this.metadata));
}
exportProduct(): void {
this.generateConfig(false);
this.configFileStructure?.zip.generateAsync({ type: 'blob' }).then(
(blob) => {
saveAs(blob, `${this.configFileStructure?.uuid}.zip`);
Message.success(this.$t('editor.export.success'));
},
(err) => {
Message.error(this.$t('editor.export.error'));
}
);
}
/**
* Conducts various checks before saving.
*/
Expand All @@ -1368,9 +1384,9 @@ export default class MetadataEditorV extends Vue {
/**
* Called when `Save Changes` is pressed. Re-generates the Storylines configuration file
* with the new changes, then generates and submits the product file to the server.
* with the new changes, and if `publish` is set to true, generates and submits the product file to the server.
*/
generateConfig(): ConfigFileStructure {
generateConfig(publish = true): ConfigFileStructure {
this.saving = true;
// Update the configuration files, for both languages.
Expand All @@ -1393,97 +1409,107 @@ export default class MetadataEditorV extends Vue {
this.configFileStructure?.zip.file(frFileName, frFormattedConfigFile);
// Upload the ZIP file.
this.configFileStructure?.zip.generateAsync({ type: 'blob' }).then((content: Blob) => {
const formData = new FormData();
formData.append('data', content, `${this.uuid}.zip`);
const userStore = useUserStore();
const headers = { 'Content-Type': 'multipart/form-data', user: userStore.userProfile.userName || 'Guest' };
Message.warning(this.$t('editor.editMetadata.message.wait'));
if (publish) {
this.configFileStructure?.zip.generateAsync({ type: 'blob' }).then((content: Blob) => {
const formData = new FormData();
formData.append('data', content, `${this.uuid}.zip`);
const userStore = useUserStore();
const headers = {
'Content-Type': 'multipart/form-data',
user: userStore.userProfile.userName || 'Guest'
};
Message.warning(this.$t('editor.editMetadata.message.wait'));
axios
.post(this.apiUrl + '/upload', formData, { headers })
.then((res: AxiosResponse) => {
const responseData = res.data;
responseData.files; // binary representation of the file
responseData.status; // HTTP status
const commitHash = responseData.commitHash; // commit hash of the git commit
this.unsavedChanges = false;
this.loadExisting = true; // if editExisting was false, we can now set it to true
if (import.meta.env.VITE_APP_CURR_ENV) {
if (responseData.new) {
axios
.post(import.meta.env.VITE_APP_NET_API_URL + '/api/user/register', {
uuid: this.uuid,
titleEn: this.configs['en']?.title ?? '',
titleFr: this.configs['fr']?.title ?? ''
})
.then((response: any) => {
const userStore = useUserStore();
userStore.fetchUserProfile();
formData.append('uuid', this.uuid);
formData.append('titleEn', this.configs['en']?.title ?? '');
formData.append('titleFr', this.configs['fr']?.title ?? '');
formData.append('commitHash', commitHash);
formData.delete('data'); // Remove the data from the form so that we don't pass it into the .NET API
axios
.post(
import.meta.env.VITE_APP_NET_API_URL + '/api/version/commit',
formData
)
.then((response: any) => {
Message.success(this.$t('editor.editMetadata.message.successfulSave'));
})
.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 {
formData.append('uuid', this.uuid);
formData.append('titleEn', this.configs['en']?.title ?? '');
formData.append('titleFr', this.configs['fr']?.title ?? '');
formData.append('commitHash', commitHash);
formData.delete('data'); // Remove the data from the form so that we don't pass it into the .NET API
axios
.post(import.meta.env.VITE_APP_NET_API_URL + '/api/version/commit', formData)
.then((response: any) => {
Message.success(this.$t('editor.editMetadata.message.successfulSave'));
})
.catch((error: any) => console.log(error.response || error))
.finally(() => {
// padding to prevent save button from being clicked rapidly
setTimeout(() => {
this.saving = false;
}, 500);
});
}
axios
.post(this.apiUrl + '/upload', formData, { headers })
.then((res: AxiosResponse) => {
const responseData = res.data;
responseData.files; // binary representation of the file
responseData.status; // HTTP status
const commitHash = responseData.commitHash; // commit hash of the git commit
this.unsavedChanges = false;
this.loadExisting = true; // if editExisting was false, we can now set it to true
if (import.meta.env.VITE_APP_CURR_ENV) {
if (responseData.new) {
axios
.post(import.meta.env.VITE_APP_NET_API_URL + '/api/user/register', {
uuid: this.uuid,
titleEn: this.configs['en']?.title ?? '',
titleFr: this.configs['fr']?.title ?? ''
fetch(this.apiUrl + `/retrieveMessages`)
.then((res: any) => {
if (res.ok) return res.json();
})
.then((response: any) => {
const userStore = useUserStore();
userStore.fetchUserProfile();
formData.append('uuid', this.uuid);
formData.append('titleEn', this.configs['en']?.title ?? '');
formData.append('titleFr', this.configs['fr']?.title ?? '');
formData.append('commitHash', commitHash);
formData.delete('data'); // Remove the data from the form so that we don't pass it into the .NET API
.then((data) => {
axios
.post(import.meta.env.VITE_APP_NET_API_URL + '/api/version/commit', formData)
.then((response: any) => {
Message.success(this.$t('editor.editMetadata.message.successfulSave'));
.post(import.meta.env.VITE_APP_NET_API_URL + '/api/log/create', {
messages: data.messages
})
.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));
})
.catch((error: any) => console.log(error.response || error));
} else {
formData.append('uuid', this.uuid);
formData.append('titleEn', this.configs['en']?.title ?? '');
formData.append('titleFr', this.configs['fr']?.title ?? '');
formData.append('commitHash', commitHash);
formData.delete('data'); // Remove the data from the form so that we don't pass it into the .NET API
axios
.post(import.meta.env.VITE_APP_NET_API_URL + '/api/version/commit', formData)
.then((response: any) => {
Message.success(this.$t('editor.editMetadata.message.successfulSave'));
})
.catch((error: any) => console.log(error.response || error))
.finally(() => {
// padding to prevent save button from being clicked rapidly
setTimeout(() => {
this.saving = false;
}, 500);
});
Message.success(this.$t('editor.editMetadata.message.successfulSave'));
// padding to prevent save button from being clicked rapidly
setTimeout(() => {
this.saving = false;
}, 500);
}
fetch(this.apiUrl + `/retrieveMessages`)
.then((res: any) => {
if (res.ok) return res.json();
})
.then((data) => {
axios
.post(import.meta.env.VITE_APP_NET_API_URL + '/api/log/create', {
messages: data.messages
})
.catch((error: any) => console.log(error.response || error));
})
.catch((error: any) => console.log(error.response || error));
} else {
Message.success(this.$t('editor.editMetadata.message.successfulSave'));
// padding to prevent save button from being clicked rapidly
setTimeout(() => {
this.saving = false;
}, 500);
}
})
.catch(() => {
Message.error(this.$t('editor.editMetadata.message.error.failedSave'));
});
});
})
.catch(() => {
Message.error(this.$t('editor.editMetadata.message.error.failedSave'));
});
});
} else {
this.saving = false;
}
return this.configFileStructure as ConfigFileStructure;
}
Expand Down
3 changes: 3 additions & 0 deletions src/lang/lang.csv
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ editor.contextLabel,Context label,1,Étiquette de contexte,1
editor.contextLabel.info,Context label shows up before the context link to explain what the link is for,1,L’étiquette de contexte apparaît avant le lien contextuel et explique à quoi sert le lien.,1
editor.dateModified,Date modified,1,Date de modification,1
editor.load,Load,1,Charger,1
editor.export,Export,1,Exporter,0
editor.export.success,Export successful,1,Exportation réussie,0
editor.export.error,Export failed,1,Échec de l’exportation,0
editor.rename,Rename,1,Rename,0
editor.loadPrevious,Load Previous,1,Charger le précédent,0
editor.viewHistory,View Previous,1,Voir précédent,0
Expand Down

0 comments on commit 09dea86

Please sign in to comment.