|
13 | 13 | <ToolBar v-if="showTabs" :flat="!tabsElevated" class="tabs" color="white"> |
14 | 14 | <Tabs v-model="currentTab" slider-color="primary" height="64px"> |
15 | 15 | <!-- Details tab --> |
16 | | - <VTab |
17 | | - ref="detailstab" |
18 | | - :href="`#${tabs.DETAILS}`" |
19 | | - @click="trackTab('Details')" |
20 | | - > |
| 16 | + <VTab ref="detailstab" :href="`#${tabs.DETAILS}`" @click="trackTab('Details')"> |
21 | 17 | {{ $tr(tabs.DETAILS) }} |
22 | 18 | <VTooltip v-if="!areDetailsValid || !areFilesValid" top lazy> |
23 | 19 | <template #activator="{ on }"> |
|
72 | 68 | </VAlert> |
73 | 69 | <VAlert v-else-if="!areDetailsValid" :value="true" type="error" outline icon="error"> |
74 | 70 | {{ $tr('errorBannerText') }} |
| 71 | + <ul> |
| 72 | + <li |
| 73 | + v-for="(error, index) in errorsList" |
| 74 | + :key="index" |
| 75 | + @click="handleErrorClick(error)" |
| 76 | + > |
| 77 | + <a class="error-ref"> {{ $tr(error) }} </a> |
| 78 | + </li> |
| 79 | + </ul> |
75 | 80 | </VAlert> |
76 | | - <DetailsTabView |
77 | | - :key="nodeIds.join('-')" |
78 | | - ref="detailsTab" |
79 | | - :nodeIds="nodeIds" |
80 | | - /> |
| 81 | + <DetailsTabView :key="nodeIds.join('-')" ref="detailsTab" :nodeIds="nodeIds" /> |
81 | 82 | </VTabItem> |
82 | 83 | <VTabItem :key="tabs.QUESTIONS" ref="questionwindow" :value="tabs.QUESTIONS" lazy> |
83 | 84 | <AssessmentTab :nodeId="nodeIds[0]" /> |
84 | 85 | </VTabItem> |
85 | | - <VTabItem |
86 | | - :key="tabs.RELATED" |
87 | | - :value="tabs.RELATED" |
88 | | - lazy |
89 | | - > |
| 86 | + <VTabItem :key="tabs.RELATED" :value="tabs.RELATED" lazy> |
90 | 87 | <RelatedResourcesTab :nodeId="nodeIds[0]" /> |
91 | 88 | </VTabItem> |
92 | 89 | </VTabsItems> |
|
110 | 107 | import ToolBar from 'shared/views/ToolBar'; |
111 | 108 | import Tabs from 'shared/views/Tabs'; |
112 | 109 |
|
| 110 | + const EditFields = { |
| 111 | + TITLE: 'titleLabel', |
| 112 | + LICENSE: 'licenseLabel', |
| 113 | + COPYRIGHT_HOLDER: 'copyrightHolderLabel', |
| 114 | + COMPLETION: 'completionLabel', |
| 115 | + LEARNING_ACTIVITY: 'learningActivityLabel', |
| 116 | + }; |
| 117 | +
|
113 | 118 | export default { |
114 | 119 | name: 'EditView', |
115 | 120 | components: { |
|
133 | 138 | return { |
134 | 139 | currentTab: null, |
135 | 140 | tabsElevated: false, |
| 141 | + errorsList: [], |
136 | 142 | }; |
137 | 143 | }, |
138 | 144 | computed: { |
|
141 | 147 | 'getContentNodeDetailsAreValid', |
142 | 148 | 'getContentNodeFilesAreValid', |
143 | 149 | 'getImmediateRelatedResourcesCount', |
| 150 | + 'getNodeDetailsErrorsList', |
144 | 151 | ]), |
145 | 152 | ...mapGetters('assessmentItem', ['getAssessmentItemsAreValid', 'getAssessmentItemsCount']), |
146 | 153 | firstNode() { |
|
182 | 189 | return this.$tr('editingMultipleCount', totals); |
183 | 190 | }, |
184 | 191 | areDetailsValid() { |
| 192 | + this.setErrors(this.nodeIds[0]); |
185 | 193 | return !this.oneSelected || this.getContentNodeDetailsAreValid(this.nodeIds[0]); |
186 | 194 | }, |
187 | 195 | areAssessmentItemsValid() { |
|
243 | 251 | trackTab(name) { |
244 | 252 | this.$analytics.trackClick('channel_editor_modal', name); |
245 | 253 | }, |
| 254 | + handleErrorClick(error) { |
| 255 | + const errorRefs = { |
| 256 | + [EditFields.TITLE]: 'title', |
| 257 | + [EditFields.LICENSE]: 'license', |
| 258 | + [EditFields.COPYRIGHT_HOLDER]: 'copyright_holder', |
| 259 | + [EditFields.COMPLETION]: 'randomize', |
| 260 | + [EditFields.LEARNING_ACTIVITY]: 'learning_activities', |
| 261 | + }; |
| 262 | +
|
| 263 | + const errorRef = errorRefs[error]; |
| 264 | + const targetElement = this.$refs.detailsTab.$refs[errorRef]; |
| 265 | +
|
| 266 | + if (!targetElement) { |
| 267 | + console.error(`Target element ref not found for error: ${error}`); |
| 268 | + return; |
| 269 | + } |
| 270 | +
|
| 271 | + const nativeElement = targetElement.$el; |
| 272 | + const containerElement = this.$refs.editview; |
| 273 | + const position = nativeElement.getBoundingClientRect(); |
| 274 | + const offsetY = position.top - nativeElement.clientHeight - 50; // additional padding of 50 to adjust position. |
| 275 | + containerElement.scrollTo({ top: offsetY, behavior: 'smooth' }); |
| 276 | + }, |
| 277 | + setErrors(nodeId) { |
| 278 | + const errorsTagList = this.getNodeDetailsErrorsList(nodeId); |
| 279 | + // fetch unique errors |
| 280 | + // set that to errorsList |
| 281 | + const errorRefs = { |
| 282 | + TITLE_REQUIRED: EditFields.TITLE, |
| 283 | + LICENSE_REQUIRED: EditFields.LICENSE, |
| 284 | + COPYRIGHT_HOLDER_REQUIRED: EditFields.COPYRIGHT_HOLDER, |
| 285 | + MASTERY_MODEL_REQUIRED: EditFields.COMPLETION, |
| 286 | + MASTERY_MODEL_M_REQUIRED: EditFields.COMPLETION, |
| 287 | + MASTERY_MODEL_M_WHOLE_NUMBER: EditFields.COMPLETION, |
| 288 | + MASTERY_MODEL_M_GT_ZERO: EditFields.COMPLETION, |
| 289 | + MASTERY_MODEL_M_LTE_N: EditFields.COMPLETION, |
| 290 | + MASTERY_MODEL_N_REQUIRED: EditFields.COMPLETION, |
| 291 | + MASTERY_MODEL_N_WHOLE_NUMBER: EditFields.COMPLETION, |
| 292 | + MASTERY_MODEL_N_GT_ZERO: EditFields.COMPLETION, |
| 293 | + LEARNING_ACTIVITY_REQUIRED: EditFields.LEARNING_ACTIVITY, |
| 294 | + }; |
| 295 | +
|
| 296 | + const uniqueErrorsSet = new Set(); |
| 297 | + for (const error of errorsTagList) { |
| 298 | + if (errorRefs[error]) { |
| 299 | + uniqueErrorsSet.add(errorRefs[error]); |
| 300 | + } |
| 301 | + } |
| 302 | + const arr = [...uniqueErrorsSet]; |
| 303 | + this.errorsList = arr; |
| 304 | + }, |
246 | 305 | /* |
247 | 306 | * @public |
248 | 307 | */ |
|
266 | 325 | errorBannerText: 'Please provide the required information', |
267 | 326 | editingMultipleCount: |
268 | 327 | 'Editing details for {topicCount, plural,\n =1 {# folder}\n other {# folders}}, {resourceCount, plural,\n =1 {# resource}\n other {# resources}}', |
| 328 | + titleLabel: 'Title', |
| 329 | + licenseLabel: 'License', |
| 330 | + copyrightHolderLabel: 'Copyright holder', |
| 331 | + completionLabel: 'Completion', |
| 332 | + learningActivityLabel: 'Learning activity', |
269 | 333 | }, |
270 | 334 | }; |
271 | 335 |
|
|
315 | 379 | overflow: auto; |
316 | 380 | } |
317 | 381 |
|
| 382 | + .error-ref { |
| 383 | + color: inherit; |
| 384 | + text-decoration: underline; |
| 385 | + } |
| 386 | +
|
318 | 387 | </style> |
0 commit comments