|
|
|
|
@ -215,24 +215,31 @@ |
|
|
|
|
<div v-if="viewSection === 'lessons'" class="kit__body"> |
|
|
|
|
<div class="lessons__title title">Содержание курса</div> |
|
|
|
|
<div v-if="!lessonsLoading" class="lessons__list"> |
|
|
|
|
<div class="lessons__item" v-for="(lesson, index) in lessons"> |
|
|
|
|
<div class="lessons__actions"> |
|
|
|
|
<button type="button" class="lessons__action" @click="removeLesson(index)"> |
|
|
|
|
<svg class="icon icon-delete"> |
|
|
|
|
<use xlink:href="/static/img/sprite.svg#icon-delete"></use> |
|
|
|
|
</svg> |
|
|
|
|
</button> |
|
|
|
|
<button type="button" class="lessons__action" @click="editLesson(index)"> |
|
|
|
|
<svg class="icon icon-edit"> |
|
|
|
|
<use xlink:href="/static/img/sprite.svg#icon-edit"></use> |
|
|
|
|
</svg> |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
<div class="lessons__subtitle subtitle">{{ lesson.title }}</div> |
|
|
|
|
<div class="lessons__row"> |
|
|
|
|
<div class="lessons__content">{{ lesson.short_description }}</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<vue-draggable v-model="lessons" @start="drag=true" @end="onLessonsChanged" :options="{ handle: '.sortable__handle' }"> |
|
|
|
|
<div class="lessons__item" v-for="(lesson, index) in lessons" :key="lesson.id"> |
|
|
|
|
<div class="lessons__actions"> |
|
|
|
|
<button class="sortable__handle" type="button"> |
|
|
|
|
<svg class="icon icon-hamburger"> |
|
|
|
|
<use xlink:href="/static/img/sprite.svg#icon-hamburger"></use> |
|
|
|
|
</svg> |
|
|
|
|
</button> |
|
|
|
|
<button type="button" class="lessons__action" @click="removeLesson(index)"> |
|
|
|
|
<svg class="icon icon-delete"> |
|
|
|
|
<use xlink:href="/static/img/sprite.svg#icon-delete"></use> |
|
|
|
|
</svg> |
|
|
|
|
</button> |
|
|
|
|
<button type="button" class="lessons__action" @click="editLesson(index)"> |
|
|
|
|
<svg class="icon icon-edit"> |
|
|
|
|
<use xlink:href="/static/img/sprite.svg#icon-edit"></use> |
|
|
|
|
</svg> |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
<div class="lessons__subtitle subtitle">{{ lesson.title }}</div> |
|
|
|
|
<div class="lessons__row"> |
|
|
|
|
<div class="lessons__content">{{ lesson.short_description }}</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</vue-draggable> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="lessonsLoading">Загрузка...</div> |
|
|
|
|
<div class="lessons__foot"> |
|
|
|
|
@ -307,7 +314,7 @@ |
|
|
|
|
price: null, |
|
|
|
|
url: '', |
|
|
|
|
coverImage: '', |
|
|
|
|
coverImageId: null, |
|
|
|
|
kit__body: null, |
|
|
|
|
is_paid: false, |
|
|
|
|
is_featured: true, |
|
|
|
|
is_deferred: false, |
|
|
|
|
@ -507,6 +514,7 @@ |
|
|
|
|
api.removeCourseLesson(lesson.id, this.accessToken); |
|
|
|
|
} |
|
|
|
|
this.lessons.splice(lessonIndex, 1); |
|
|
|
|
this.onLessonsChanged(); |
|
|
|
|
}, |
|
|
|
|
editLesson(lessonIndex) { |
|
|
|
|
this.currentLesson = this.lessons[lessonIndex]; |
|
|
|
|
@ -581,11 +589,7 @@ |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = 'СОХРАНЕНО'; |
|
|
|
|
this.savingTimeout = setTimeout(() => { |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = ''; |
|
|
|
|
}, 2000); |
|
|
|
|
|
|
|
|
|
this.changeSavingStatus(true); |
|
|
|
|
showNotification("success", 'Урок сохранён'); |
|
|
|
|
// this.goToLessons(); |
|
|
|
|
|
|
|
|
|
@ -594,10 +598,7 @@ |
|
|
|
|
.catch((err) => { |
|
|
|
|
this.lessonSaving = false; |
|
|
|
|
//console.error(err); |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = 'ОШИБКА'; |
|
|
|
|
this.savingTimeout = setTimeout(() => { |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = ''; |
|
|
|
|
}, 2000); |
|
|
|
|
this.changeSavingStatus(true, true); |
|
|
|
|
// alert('Произошло что-то страшное: '+err.toString()); |
|
|
|
|
console.log(err); |
|
|
|
|
if(err.response) { |
|
|
|
|
@ -661,6 +662,15 @@ |
|
|
|
|
this.$nextTick(() => { |
|
|
|
|
this.courseLoading = false; |
|
|
|
|
}); |
|
|
|
|
this.lessons.sort((a, b) => { |
|
|
|
|
if (a.position > b.position) { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
if (a.position < b.position) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
}); |
|
|
|
|
}) |
|
|
|
|
.catch((err) => { |
|
|
|
|
this.courseLoading = false; |
|
|
|
|
@ -787,17 +797,13 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.courseSaving = true; |
|
|
|
|
clearTimeout(this.savingTimeout); |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = 'СОХРАНЕНИЕ...'; |
|
|
|
|
this.changeSavingStatus(); |
|
|
|
|
const courseObject = this.course; |
|
|
|
|
courseObject.url = (courseObject.url) ? slugify(courseObject.url):courseObject.url; |
|
|
|
|
api.saveCourse(courseObject, this.accessToken) |
|
|
|
|
.then((response) => { |
|
|
|
|
this.courseSaving = false; |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = 'СОХРАНЕНО'; |
|
|
|
|
this.savingTimeout = setTimeout(() => { |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = ''; |
|
|
|
|
}, 2000); |
|
|
|
|
this.changeSavingStatus(true); |
|
|
|
|
this.courseSyncHook = true; |
|
|
|
|
const courseData = api.convertCourseJson(response.data); |
|
|
|
|
if (this.course.coverImage) { |
|
|
|
|
@ -847,10 +853,7 @@ |
|
|
|
|
this.courseSyncHook = false; |
|
|
|
|
this.courseSaving = false; |
|
|
|
|
//console.error(err); |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = 'ОШИБКА'; |
|
|
|
|
this.savingTimeout = setTimeout(() => { |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = ''; |
|
|
|
|
}, 2000); |
|
|
|
|
this.changeSavingStatus(true, true); |
|
|
|
|
// alert('Произошло что-то страшное: '+err.toString()); |
|
|
|
|
//console.log(err.response.data); |
|
|
|
|
if(err.response) { |
|
|
|
|
@ -879,10 +882,42 @@ |
|
|
|
|
this.viewSection = 'lessons-edit'; |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
onLessonsChanged() { |
|
|
|
|
let promises = []; |
|
|
|
|
this.courseSaving = true; |
|
|
|
|
this.lessons.map((lesson, index) => { |
|
|
|
|
lesson.position = index + 1; |
|
|
|
|
lesson.course_id = this.course.id; |
|
|
|
|
let res = api.saveLesson(lesson, this.accessToken); |
|
|
|
|
promises.push(res); |
|
|
|
|
}); |
|
|
|
|
Promise.all(promises).then(() => { |
|
|
|
|
this.courseSaving = false; |
|
|
|
|
this.changeSavingStatus(true); |
|
|
|
|
}, () => { |
|
|
|
|
this.courseSaving = false; |
|
|
|
|
this.changeSavingStatus(true, true); |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
pluralize(count, words) { |
|
|
|
|
var cases = [2, 0, 1, 1, 1, 2]; |
|
|
|
|
return words[ (count % 100 > 4 && count % 100 < 20) ? 2 : cases[ Math.min(count % 10, 5)] ]; |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
changeSavingStatus(saved, error) { |
|
|
|
|
let text = ''; |
|
|
|
|
if(error) { |
|
|
|
|
text = 'ОШИБКА'; |
|
|
|
|
} else { |
|
|
|
|
text = saved ? 'СОХРАНЕНО' : 'СОХРАНЕНИЕ...'; |
|
|
|
|
} |
|
|
|
|
clearTimeout(this.savingTimeout); |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = text; |
|
|
|
|
if(saved || error){ |
|
|
|
|
this.savingTimeout = setTimeout(() => { |
|
|
|
|
document.getElementById('course-redactor__saving-status').innerText = ''; |
|
|
|
|
}, 2000); |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
mounted() { |
|
|
|
|
this.mounting = true; |
|
|
|
|
|