|
5 | 5 | :step="step" |
6 | 6 | :steps="steps" |
7 | 7 | :showBackArrow="true" |
| 8 | + :backArrowDisabled="learnersBeingImported.length > 0" |
8 | 9 | :eventOnGoBack="backArrowEvent" |
9 | 10 | :title="selectAUser$()" |
10 | 11 | :description="facilityDescription" |
|
52 | 53 | <template #buttons> |
53 | 54 | <div></div> |
54 | 55 | </template> |
| 56 | + <GlobalSnackbar /> |
55 | 57 | </OnboardingStepBase> |
56 | 58 |
|
57 | 59 | </template> |
|
65 | 67 | import PaginatedListContainer from 'kolibri-common/components/PaginatedListContainer'; |
66 | 68 | import { lodUsersManagementStrings } from 'kolibri-common/strings/lodUsersManagementStrings'; |
67 | 69 | import { DemographicConstants } from 'kolibri/constants'; |
68 | | - import { TaskStatuses } from 'kolibri-common/utils/syncTaskUtils'; |
| 70 | + import { TaskStatuses, TaskTypes } from 'kolibri-common/utils/syncTaskUtils'; |
69 | 71 | import UserTable from 'kolibri-common/components/UserTable'; |
| 72 | + import useSnackbar from 'kolibri/composables/useSnackbar'; |
| 73 | + import GlobalSnackbar from 'kolibri/components/GlobalSnackbar'; |
70 | 74 | import { FooterMessageTypes, SoudQueue } from '../constants'; |
71 | 75 | import OnboardingStepBase from './OnboardingStepBase'; |
72 | 76 |
|
|
85 | 89 | OnboardingStepBase, |
86 | 90 | PaginatedListContainer, |
87 | 91 | UserTable, |
| 92 | + GlobalSnackbar, |
88 | 93 | }, |
89 | 94 | mixins: [commonCoreStrings, commonSyncElements], |
90 | 95 | setup() { |
91 | | - const { selectAUser$, importedLabel$ } = lodUsersManagementStrings; |
| 96 | + const { selectAUser$, importedLabel$, importUserError$ } = lodUsersManagementStrings; |
| 97 | + const { createSnackbar } = useSnackbar(); |
92 | 98 |
|
93 | 99 | return { |
| 100 | + createSnackbar, |
| 101 | +
|
94 | 102 | selectAUser$, |
95 | 103 | importedLabel$, |
| 104 | + importUserError$, |
96 | 105 | }; |
97 | 106 | }, |
98 | 107 | data() { |
|
151 | 160 | beforeMount() { |
152 | 161 | this.isPolling = true; |
153 | 162 | this.pollImportTask(); |
| 163 | + this.learnersBeingImported = this.wizardService.state.context.usersBeingImported.map( |
| 164 | + u => u.id, |
| 165 | + ); |
154 | 166 | }, |
155 | 167 | methods: { |
156 | 168 | importedLearners() { |
|
159 | 171 | pollImportTask() { |
160 | 172 | TaskResource.list({ queue: SoudQueue }).then(tasks => { |
161 | 173 | if (tasks.length) { |
| 174 | + let isFailingTasks = false; |
162 | 175 | tasks.forEach(task => { |
163 | | - if (task.status === TaskStatuses.COMPLETED) { |
164 | | - // Remove completed user id from 'being imported' |
| 176 | + if ([TaskStatuses.COMPLETED, TaskStatuses.FAILED].includes(task.status)) { |
| 177 | + // Remove completed/failed user id from 'being imported' |
165 | 178 | const taskUserId = task.extra_metadata.user_id; |
166 | 179 | this.learnersBeingImported = this.learnersBeingImported.filter( |
167 | 180 | id => id != taskUserId, |
168 | 181 | ); |
169 | | -
|
| 182 | + this.wizardService.send({ |
| 183 | + type: 'REMOVE_USER_BEING_IMPORTED', |
| 184 | + value: taskUserId, |
| 185 | + }); |
| 186 | + } |
| 187 | + if (task.status === TaskStatuses.COMPLETED) { |
170 | 188 | // Update the wizard context to know this user has been imported - only if they |
171 | 189 | // haven't already been added to the list (ie, imported by other means) |
172 | 190 | const taskUsername = task.extra_metadata.username; |
|
186 | 204 | value: taskUsername, |
187 | 205 | }); |
188 | 206 | } |
| 207 | + } else if (task.status === TaskStatuses.FAILED) { |
| 208 | + isFailingTasks = true; |
189 | 209 | } |
190 | 210 | }); |
| 211 | + if (isFailingTasks) { |
| 212 | + this.createSnackbar(this.importUserError$()); |
| 213 | + TaskResource.clearAll(SoudQueue); |
| 214 | + } |
191 | 215 | } |
192 | 216 | }); |
193 | 217 | if (this.isPolling) { |
|
196 | 220 | }, 2000); |
197 | 221 | } |
198 | 222 | }, |
199 | | - startImport(learner) { |
| 223 | + async startImport(learner) { |
200 | 224 | // Push the learner into being imported, we'll remove it if we get an error later on |
201 | 225 | this.learnersBeingImported.push(learner.id); |
202 | 226 |
|
203 | | - const task_name = 'kolibri.core.auth.tasks.peeruserimport'; |
| 227 | + const task_name = TaskTypes.IMPORTLODUSER; |
204 | 228 | const params = { |
205 | 229 | type: task_name, |
206 | 230 | ...this.wizardService.state.context.remoteAdmin, |
|
216 | 240 | value: { username: learner.username, password: DemographicConstants.NOT_SPECIFIED }, |
217 | 241 | }); |
218 | 242 | } |
219 | | - TaskResource.startTask(params).catch(() => { |
| 243 | + try { |
| 244 | + const newTask = await TaskResource.startTask(params); |
| 245 | + this.wizardService.send({ |
| 246 | + type: 'ADD_USER_BEING_IMPORTED', |
| 247 | + value: { |
| 248 | + id: learner.id, |
| 249 | + full_name: learner.full_name, |
| 250 | + username: learner.username, |
| 251 | + taskId: newTask.id, |
| 252 | + }, |
| 253 | + }); |
| 254 | + } catch (error) { |
| 255 | + this.createSnackbar(this.importUserError$()); |
220 | 256 | this.learnersBeingImported = this.learnersBeingImported.filter(id => id != learner.id); |
221 | | - }); |
| 257 | + } |
222 | 258 | }, |
223 | 259 | isImported(learner) { |
224 | 260 | return this.importedLearners().find(u => u === learner.username); |
|
0 commit comments