-
Notifications
You must be signed in to change notification settings - Fork 344
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
Improve resources loading #692
Conversation
WalkthroughThe pull request revises the pagination logic in both the form submissions component and the forms store. In the Changes
Sequence Diagram(s)sequenceDiagram
participant UI
participant FormSubmissions
participant API
UI->>FormSubmissions: Call getSubmissionsData
FormSubmissions->>API: Fetch page 1
API-->>FormSubmissions: Return page 1 data (includes lastPage info)
alt More pages exist
FormSubmissions->>API: Concurrently fetch pages 2...lastPage using Promise.all
API-->>FormSubmissions: Return additional pages data
end
FormSubmissions->>UI: Update UI with combined submissions data
sequenceDiagram
participant User
participant FormsStore
participant API
User->>FormsStore: Invoke loadAll
FormsStore->>API: Fetch first page of forms
API-->>FormsStore: Return first page data (includes total pages)
alt Additional pages exist
FormsStore->>API: Concurrently request pages 2...lastPage using Promise.all
API-->>FormsStore: Return additional pages data
end
FormsStore->>User: Update store with all forms data and finish loading
Poem
Tip 🌐 Web search-backed reviews and chat
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 0
🧹 Nitpick comments (2)
client/stores/forms.js (1)
12-60
: Consider adding request cancellation and timeout handling.While the parallel fetching implementation is good, there are a few improvements that could enhance reliability:
- Request cancellation for cleanup during component unmount
- Timeout handling for long-running requests
- Rate limiting to prevent overwhelming the server
Here's how you could enhance the implementation:
const loadAll = (workspaceId) => { if (loadAllRequest.value) { return loadAllRequest.value } if (!workspaceId) { return } contentStore.startLoading() + const controller = new AbortController() + const signal = controller.signal + const timeout = 30000 // 30 seconds loadAllRequest.value = new Promise((resolve, reject) => { - opnFetch(formsEndpoint.replace('{workspaceId}', workspaceId), { query: { page: 1 } }) + opnFetch(formsEndpoint.replace('{workspaceId}', workspaceId), { + query: { page: 1 }, + signal, + timeout + }) .then(firstResponse => { contentStore.resetState() contentStore.save(firstResponse.data) const lastPage = firstResponse.meta.last_page if (lastPage > 1) { // Create an array of promises for remaining pages const remainingPages = Array.from({ length: lastPage - 1 }, (_, i) => { const page = i + 2 // Start from page 2 - return opnFetch(formsEndpoint.replace('{workspaceId}', workspaceId), { query: { page } }) + return opnFetch(formsEndpoint.replace('{workspaceId}', workspaceId), { + query: { page }, + signal, + timeout + }) }) // Fetch all remaining pages in parallel return Promise.all(remainingPages) } return [] }) .then(responses => { // Save all responses data responses.forEach(response => { contentStore.save(response.data) }) allLoaded.value = true contentStore.stopLoading() loadAllRequest.value = null resolve() }) .catch(err => { + if (err.name === 'AbortError') { + console.log('Request was cancelled') + } else if (err.name === 'TimeoutError') { + console.error('Request timed out') + } contentStore.stopLoading() loadAllRequest.value = null reject(err) }) }) + // Cleanup function + const cleanup = () => { + controller.abort() + loadAllRequest.value = null + contentStore.stopLoading() + } + + // Add cleanup to the promise + loadAllRequest.value.cleanup = cleanup return loadAllRequest.value }client/components/open/forms/components/FormSubmissions.vue (1)
287-321
: Consider implementing error retry and user feedback.While the parallel fetching implementation is good, there are opportunities to enhance the user experience:
- Error retry mechanism for failed requests
- Progress indicator for large datasets
- Detailed error feedback
Here's how you could enhance the implementation:
getSubmissionsData() { if (this.fullyLoaded) { return } this.recordStore.startLoading() + const maxRetries = 3 + let progress = 0 + + const fetchWithRetry = (url, retries = 0) => { + return opnFetch(url).catch(error => { + if (retries < maxRetries) { + return new Promise(resolve => setTimeout(resolve, 1000 * (retries + 1))) + .then(() => fetchWithRetry(url, retries + 1)) + } + throw error + }) + } - opnFetch('/open/forms/' + this.form.id + '/submissions?page=1') + fetchWithRetry('/open/forms/' + this.form.id + '/submissions?page=1') .then((firstResponse) => { this.recordStore.save(firstResponse.data.map((record) => record.data)) const lastPage = firstResponse.meta.last_page + progress = Math.round((1 / lastPage) * 100) + this.$emit('loading-progress', progress) if (lastPage > 1) { // Create an array of promises for remaining pages const remainingPages = Array.from({ length: lastPage - 1 }, (_, i) => { const page = i + 2 // Start from page 2 - return opnFetch('/open/forms/' + this.form.id + '/submissions?page=' + page) + return fetchWithRetry('/open/forms/' + this.form.id + '/submissions?page=' + page) + .then(response => { + progress = Math.round(((i + 2) / lastPage) * 100) + this.$emit('loading-progress', progress) + return response + }) }) // Fetch all remaining pages in parallel return Promise.all(remainingPages) } return [] }).then(responses => { // Save all responses data responses.forEach(response => { this.recordStore.save(response.data.map((record) => record.data)) }) this.fullyLoaded = true this.recordStore.stopLoading() this.dataChanged() - }).catch(() => { + }).catch((error) => { + console.error('Failed to fetch submissions:', error) + this.$emit('fetch-error', error.message || 'Failed to load submissions') this.recordStore.stopLoading() }) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
client/components/open/forms/components/FormSubmissions.vue
(1 hunks)client/stores/forms.js
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Build the Nuxt app
🔇 Additional comments (1)
client/stores/forms.js (1)
10-10
: LGTM! Good practice using ref for tracking request state.The
loadAllRequest
ref is well-suited for managing asynchronous state in Vue/Pinia stores.
Summary by CodeRabbit