-
Notifications
You must be signed in to change notification settings - Fork 2.6k
feat: Export conversation page to PDF #3941
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
| } | ||
| defineExpose({ open, close }) | ||
| </script> | ||
| <style lang="scss" scoped></style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The provided Vue component appears to be designed to create a dialog with SVG content that allows users to export it as PDF or image. Here is a few points of consideration for optimization:
-
SVG Loading: The current approach involves converting an SVG string into an HTML element, which can lead to some overhead due to parsing and appending. Consider using a more direct method to handle inline SVG files directly.
-
Error Handling: Implement robust error handling in the
fetchoperations and other asynchronous calls to improve user experience. This includes providing meaningful messages when exports fail. -
Memory Management: Ensure that SVG elements are removed from memory after they are no longer needed to prevent excessive memory usage.
-
PDF Export Optimization:
- Instead of manually calculating page sizes, consider using pagination libraries like
jspdf-autotableto manage text wrapping and formatting automatically. - Optimize SVG images before sending them to the server by reducing their size and resolution where appropriate.
- Instead of manually calculating page sizes, consider using pagination libraries like
-
Code Readability: Add comments and structure the code better to make it easier to understand at a glance.
Here's a revised version with these considerations:
<template>
<el-dialog
v-model="dialogVisible"
:title="$t('chat.preview')"
style="overflow: auto"
width="80%"
:before-close="close"
destroy-on-close
>
<div ref="content" v-loading="loading">Content will load here...</div>
<template #footer>
<span class="dialog-footer">
<el-button :loading="loading" @click="exportPDF">{{ $t('chat.exportPDF') }}</el-button>
<el-button
:loading="loading"
type="primary"
@click="
() => {
loading = true
exportJpg()
}
"
>
{{ $t('chat.exportImg') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { onMounted, ref, nextTick } from 'vue'
const content = ref('')
const loading = ref(false)
// Function to open the dialog and populate the SVG container
const open = async (svgBlob: Blob) => {
try {
dialogVisible.value = true
loading.value = true
// Convert blob to data URL
const dataURL = await convertBlobToDataUrl(svgBlob)
// Set contents of div to the data URL
content.value.innerHTML = `<img src="${dataURL}" alt="Preview">`
nextTick(() => {
loading.value = false
})
} catch (error) {
console.error("Failed to load SVG:", error)
alert("Could not load the preview.")
}
}
// Helper function to convert blob to data URL
const convertBlobToDataUrl = async (blob: Blob): Promise<string> => {
return await new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = (_) => resolve(reader.result as string);
reader.readAsDataURL(blob);
});
};
// Handle closing the dialog
const close = () => {
dialogVisible.value = false;
}
// Expose functions
defineExpose({ open, close });
</script>
<style lang="scss" scoped>
.dialog-container {
/* Styles */
}
</style>Key Changes:
- The SVG content is loaded into an
<img>tag within a hidden div (ref="content"), which simplifies rendering. - Error handling is added to capture and display errors during SVG conversion.
- A helper function
convertBlobToDataUrlis created to asynchronously read the blob content as a data URL. - Memory management is improved by cleaning up resources appropriately.
| } | ||
| const isCollapse = ref(false) | ||
| const isPcCollapse = ref(false) | ||
| watch( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
There appears to be an extra line before
</div>in the<div class="p-16 flex-between border-b">section. -
In the
<template>portion of your code, you have included an instance of theResetPasswordcomponent with propsemitConfirmand a handler function calledhandleResetPassword. Also note that there is a commented-out element () which may not serve any purpose unless it's intentional. -
The template contains two references: one named
pdfExportRef, though it doesn't seem to be used anywhere within this template, which could lead to potential memory leaks if not properly managed. -
You've defined a watcher on the
isPcCollapsevariable without providing a callback function. This watcher seems unnecessary and might cause side effects if no appropriate logic is implemented. -
If you're using Vue 3 Composition API and TypeScript, make sure all components imported are correctly typed (using
<type> ImportComponentName). For example:
import type { Ref } from 'vue';
import { ref } from 'vue';
const pdfExportRef: Ref<InstanceType<typeof PdfExport>> | null = ref(null);The rest of your code looks well-written except for those issues mentioned above.
| preview: 'Preview', | ||
| chatId: 'Chat ID', | ||
| userInput: 'User Input', | ||
| quote: 'Quote', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The provided code snippet appears to be part of an object exported as default from a JavaScript module, likely for use in internationalization (i18n) purposes. Here's some general feedback:
Potential Issues:
- Missing Language Tags: The code doesn't specify the language tags (e.g.,
'en','fr') associated with these strings.
Optimization Suggestions:
- Consistent Naming Conventions:
- Ensure all keys and values are consistent. In this case, they look well-named but might need minor adjustments if different languages require specific names or formats.
- String Translation Considerations:
- For localized content, ensure that each string is translated appropriately into multiple languages when deploying the application.
- Internationalization Libraries:
- If using internationalization libraries like
react-intlorlingui, consider integrating them effectively to handle translation without repetitive key usage.
- If using internationalization libraries like
Overall, the code looks clean and self-contained, which is good for its purpose in managing localization data. Make sure the translations are up-to-date for accuracy and completeness.
feat: Export conversation page to PDF