-
Notifications
You must be signed in to change notification settings - Fork 727
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
Tables loading #10944
Merged
Merged
Tables loading #10944
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
eb95fb8
Align condition with the intention
MisRob 352c3ba
Remove unnecessary var
MisRob dcab66d
Show loader in the table in Coach-Plan-Lessons
MisRob 2134f34
Move handler to composable
MisRob 9261dab
Show loader in the table in Coach-Plan-Groups
MisRob 8655524
Move handler to composable
MisRob File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
kolibri/plugins/coach/assets/src/composables/__mocks__/useGroups.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/** | ||
* `useGroups` composable function mock. | ||
* | ||
* If default values are sufficient for tests, | ||
* you only need call `jest.mock('<useGroups file path>')` | ||
* at the top of a test file. | ||
* | ||
* If you need to override some default values from some tests, | ||
* you can import a helper function `useGroupsMock` that accepts | ||
* an object with values to be overriden and use it together | ||
* with `mockImplementation` as follows: | ||
* | ||
* ``` | ||
* // eslint-disable-next-line import/named | ||
* import useGroups, { useGroupsMock } from '<useGroups file path>'; | ||
* | ||
* jest.mock('<useGroups file path>') | ||
* | ||
* it('test', () => { | ||
* useGroups.mockImplementation( | ||
* () => useGroupsMock({ groupsAreLoading: true }) | ||
* ); | ||
* }) | ||
* ``` | ||
* | ||
* You can reset your mock implementation back to default values | ||
* for other tests by calling the following in `beforeEach`: | ||
* | ||
* ``` | ||
* useGroups.mockImplementation(() => useGroupsMock()) | ||
* ``` | ||
*/ | ||
|
||
const MOCK_DEFAULTS = { | ||
groupsAreLoading: false, | ||
showGroupsPage: jest.fn(), | ||
}; | ||
|
||
export function useGroupsMock(overrides = {}) { | ||
return { | ||
...MOCK_DEFAULTS, | ||
...overrides, | ||
}; | ||
} | ||
|
||
export default jest.fn(() => useGroupsMock()); |
46 changes: 46 additions & 0 deletions
46
kolibri/plugins/coach/assets/src/composables/__mocks__/useLessons.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/** | ||
* `useLessons` composable function mock. | ||
* | ||
* If default values are sufficient for tests, | ||
* you only need call `jest.mock('<useLessons file path>')` | ||
* at the top of a test file. | ||
* | ||
* If you need to override some default values from some tests, | ||
* you can import a helper function `useLessonsMock` that accepts | ||
* an object with values to be overriden and use it together | ||
* with `mockImplementation` as follows: | ||
* | ||
* ``` | ||
* // eslint-disable-next-line import/named | ||
* import useLessons, { useLessonsMock } from '<useLessons file path>'; | ||
* | ||
* jest.mock('<useLessons file path>') | ||
* | ||
* it('test', () => { | ||
* useLessons.mockImplementation( | ||
* () => useLessonsMock({ lessonsAreLoading: true }) | ||
* ); | ||
* }) | ||
* ``` | ||
* | ||
* You can reset your mock implementation back to default values | ||
* for other tests by calling the following in `beforeEach`: | ||
* | ||
* ``` | ||
* useLessons.mockImplementation(() => useLessonsMock()) | ||
* ``` | ||
*/ | ||
|
||
const MOCK_DEFAULTS = { | ||
lessonsAreLoading: false, | ||
showLessonsRootPage: jest.fn(), | ||
}; | ||
|
||
export function useLessonsMock(overrides = {}) { | ||
return { | ||
...MOCK_DEFAULTS, | ||
...overrides, | ||
}; | ||
} | ||
|
||
export default jest.fn(() => useLessonsMock()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { ref } from 'kolibri.lib.vueCompositionApi'; | ||
import samePageCheckGenerator from 'kolibri.utils.samePageCheckGenerator'; | ||
import { LearnerGroupResource, FacilityUserResource } from 'kolibri.resources'; | ||
|
||
// Place outside the function to keep the state | ||
const groupsAreLoading = ref(false); | ||
|
||
export function useGroups() { | ||
function setGroupsLoading(loading) { | ||
groupsAreLoading.value = loading; | ||
} | ||
|
||
function showGroupsPage(store, classId) { | ||
// On this page, handle loading state locally | ||
// TODO: Open follow-up so that we don't need to do this | ||
store.dispatch('notLoading'); | ||
|
||
setGroupsLoading(true); | ||
|
||
const promises = [ | ||
FacilityUserResource.fetchCollection({ | ||
getParams: { member_of: classId }, | ||
force: true, | ||
}), | ||
LearnerGroupResource.fetchCollection({ | ||
getParams: { parent: classId }, | ||
force: true, | ||
}), | ||
]; | ||
const shouldResolve = samePageCheckGenerator(store); | ||
return Promise.all(promises).then( | ||
([classUsers, groupsCollection]) => { | ||
if (shouldResolve()) { | ||
const groups = groupsCollection.map(group => ({ ...group, users: [] })); | ||
const groupUsersPromises = groups.map(group => | ||
FacilityUserResource.fetchCollection({ | ||
getParams: { member_of: group.id }, | ||
force: true, | ||
}) | ||
); | ||
|
||
Promise.all(groupUsersPromises).then( | ||
groupsUsersCollection => { | ||
if (shouldResolve()) { | ||
groupsUsersCollection.forEach((groupUsers, index) => { | ||
groups[index].users = [...groupUsers]; | ||
}); | ||
store.commit('groups/SET_STATE', { | ||
classUsers: [...classUsers], | ||
groups, | ||
groupModalShown: false, | ||
}); | ||
setGroupsLoading(false); | ||
store.dispatch('clearError'); | ||
} | ||
}, | ||
error => (shouldResolve() ? store.dispatch('handleError', error) : null) | ||
); | ||
} | ||
}, | ||
error => { | ||
shouldResolve() ? store.dispatch('handleError', error) : null; | ||
} | ||
); | ||
} | ||
|
||
return { | ||
groupsAreLoading, | ||
showGroupsPage, | ||
}; | ||
} |
46 changes: 46 additions & 0 deletions
46
kolibri/plugins/coach/assets/src/composables/useLessons.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { ref } from 'kolibri.lib.vueCompositionApi'; | ||
import { LearnerGroupResource } from 'kolibri.resources'; | ||
import { LessonsPageNames } from '../constants/lessonsConstants'; | ||
|
||
// Place outside the function to keep the state | ||
const lessonsAreLoading = ref(false); | ||
|
||
export function useLessons() { | ||
function setLessonsLoading(loading) { | ||
lessonsAreLoading.value = loading; | ||
} | ||
|
||
// Show the Lessons Root Page, where all the Lessons are listed for a given Classroom | ||
function showLessonsRootPage(store, classId) { | ||
// on this page, don't handle loading state globally so we can do it locally | ||
store.dispatch('notLoading'); | ||
|
||
setLessonsLoading(true); | ||
store.commit('lessonsRoot/SET_STATE', { | ||
lessons: [], | ||
learnerGroups: [], | ||
}); | ||
const loadRequirements = [ | ||
// Fetch learner groups for the New Lesson Modal | ||
LearnerGroupResource.fetchCollection({ getParams: { parent: classId } }), | ||
store.dispatch('lessonsRoot/refreshClassLessons', classId), | ||
]; | ||
|
||
return Promise.all(loadRequirements).then( | ||
([learnerGroups]) => { | ||
store.commit('lessonsRoot/SET_LEARNER_GROUPS', learnerGroups); | ||
store.commit('SET_PAGE_NAME', LessonsPageNames.PLAN_LESSONS_ROOT); | ||
setLessonsLoading(false); | ||
}, | ||
error => { | ||
store.dispatch('handleApiError', error); | ||
setLessonsLoading(false); | ||
} | ||
); | ||
} | ||
|
||
return { | ||
lessonsAreLoading, | ||
showLessonsRootPage, | ||
}; | ||
} |
51 changes: 0 additions & 51 deletions
51
kolibri/plugins/coach/assets/src/modules/groups/handlers.js
This file was deleted.
Oops, something went wrong.
28 changes: 0 additions & 28 deletions
28
kolibri/plugins/coach/assets/src/modules/lessonsRoot/handlers.js
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
It is a little strange that there are groups showing while the loader spins. Ideally, the table loading state would hide existing data (or at least "disable" it or otherwise indicate that it is currently part of the loading dataset)
Maybe a
v-if="!groupsAreLoading"
on thetbody
here would do it?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.
In testing I'm not actually seeing the group while the loader is shown 🤷🏻
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.
I don't understand, could you please elaborate a bit more?
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.
In any case, I think this won't harm anything so no problem to commit it
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.
Perhaps it'd make more sense to have this implemented rather in
CoreTable
, though? Not only to have a condition to show the loader whendataLoading
is truthy but also to not show the table body in this case? I think that may prevent some glitches (maybe in regards to cached data?) by ensuring that table data is never displayed as long asdataLoading
is truthy.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.
In your screencast, when you go to the Group tab, "Group 1" is visible with the loader underneath it. I think the loader being there should hide the content on the table until it is done loading.
However, I was not able to replicate it and tried as best I could so I don't think it's a blocking issue at all.
Yeah I think you're right there for sure. That might be a good follow-up issue as it'd require regression testing across a bunch of tables and this is good to go otherwise. What do you think?
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.
Ah yes, I see now. Yes, that's right. I think it might be related to the way I prepared the recording when I added a piece of code to delay loading - it's possible that I placed it in the wrong place as I couldn't reproduce it either right now. Or it could be related to some kind of cache - we can resolve that in a follow-up and do regression testing, yes. I will open the issue.
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.
#10993