fix: course form cleanup
This commit is contained in:
@@ -34,7 +34,7 @@
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="w-full !justify-start"
|
class="w-full !justify-start"
|
||||||
label="Create New"
|
:label="__('Create New')"
|
||||||
@click="attrs.onCreate(value, close)"
|
@click="attrs.onCreate(value, close)"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
|
|||||||
@@ -4,79 +4,84 @@
|
|||||||
{{ label }}
|
{{ label }}
|
||||||
<span class="text-ink-red-3" v-if="required">*</span>
|
<span class="text-ink-red-3" v-if="required">*</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="grid grid-cols-3 gap-2">
|
<div class="w-full">
|
||||||
<Button
|
<Combobox v-model="selectedValue" nullable>
|
||||||
ref="emails"
|
<Popover class="w-full" v-model:show="showOptions">
|
||||||
v-for="value in values"
|
<template #target="{ togglePopover }">
|
||||||
:key="value"
|
<ComboboxInput
|
||||||
:label="value"
|
ref="search"
|
||||||
theme="gray"
|
class="search-input form-input w-full focus-visible:!ring-0"
|
||||||
variant="subtle"
|
type="text"
|
||||||
class="rounded-md word-break-all"
|
:value="query"
|
||||||
@keydown.delete.capture.stop="removeLastValue"
|
@change="
|
||||||
>
|
(e) => {
|
||||||
<template #suffix>
|
query = e.target.value
|
||||||
<X @click="removeValue(value)" class="h-4 w-4 stroke-1.5" />
|
showOptions = true
|
||||||
</template>
|
}
|
||||||
</Button>
|
"
|
||||||
<div class="">
|
autocomplete="off"
|
||||||
<Combobox v-model="selectedValue" nullable>
|
@focus="() => togglePopover()"
|
||||||
<Popover class="w-full" v-model:show="showOptions">
|
@keydown.delete.capture.stop="removeLastValue"
|
||||||
<template #target="{ togglePopover }">
|
/>
|
||||||
<ComboboxInput
|
</template>
|
||||||
ref="search"
|
<template #body="{ isOpen, close }">
|
||||||
class="search-input form-input w-full focus-visible:!ring-0"
|
<div v-show="isOpen">
|
||||||
type="text"
|
<div
|
||||||
:value="query"
|
class="mt-1 rounded-lg bg-surface-white py-1 text-base border-2"
|
||||||
@change="
|
>
|
||||||
(e) => {
|
<ComboboxOptions
|
||||||
query = e.target.value
|
class="my-1 max-h-[12rem] overflow-y-auto px-1.5"
|
||||||
showOptions = true
|
static
|
||||||
}
|
|
||||||
"
|
|
||||||
autocomplete="off"
|
|
||||||
@focus="() => togglePopover()"
|
|
||||||
@keydown.delete.capture.stop="removeLastValue"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #body="{ isOpen }">
|
|
||||||
<div v-show="isOpen">
|
|
||||||
<div
|
|
||||||
class="mt-1 rounded-lg bg-surface-white py-1 text-base border-2"
|
|
||||||
>
|
>
|
||||||
<ComboboxOptions
|
<ComboboxOption
|
||||||
class="my-1 max-h-[12rem] overflow-y-auto px-1.5"
|
v-for="option in options"
|
||||||
static
|
:key="option.value"
|
||||||
|
:value="option"
|
||||||
|
v-slot="{ active }"
|
||||||
>
|
>
|
||||||
<ComboboxOption
|
<li
|
||||||
v-for="option in options"
|
:class="[
|
||||||
:key="option.value"
|
'flex cursor-pointer items-center rounded px-2 py-1 text-base',
|
||||||
:value="option"
|
{ 'bg-surface-gray-2': active },
|
||||||
v-slot="{ active }"
|
]"
|
||||||
>
|
>
|
||||||
<li
|
<div class="flex flex-col gap-1 p-1">
|
||||||
:class="[
|
<div class="text-base font-medium text-ink-gray-8">
|
||||||
'flex cursor-pointer items-center rounded px-2 py-1 text-base',
|
{{ option.description }}
|
||||||
{ 'bg-surface-gray-2': active },
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div class="flex flex-col gap-1 p-1">
|
|
||||||
<div class="text-base font-medium text-ink-gray-8">
|
|
||||||
{{ option.description }}
|
|
||||||
</div>
|
|
||||||
<div class="text-sm text-ink-gray-5">
|
|
||||||
{{ option.value }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
<div class="text-sm text-ink-gray-5">
|
||||||
</ComboboxOption>
|
{{ option.value }}
|
||||||
</ComboboxOptions>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</li>
|
||||||
|
</ComboboxOption>
|
||||||
|
<div v-if="attrs.onCreate" class="absolute bottom-2 left-1 w-[98%] pt-2 bg-white border-t">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
class="w-full !justify-start"
|
||||||
|
:label="__('Create New')"
|
||||||
|
@click="attrs.onCreate(close)"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<Plus class="h-4 w-4 stroke-1.5" />
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</ComboboxOptions>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
</Popover>
|
</template>
|
||||||
</Combobox>
|
</Popover>
|
||||||
|
</Combobox>
|
||||||
|
</div>
|
||||||
|
<div v-if="values.length" class="grid grid-cols-2 gap-2 mt-4">
|
||||||
|
<div v-for="value in values" class="flex items-center justify-between break-all bg-surface-gray-2 text-ink-gray-7 word-wrap p-2 rounded-md mr-2">
|
||||||
|
<span class="break-all">
|
||||||
|
{{ value }}
|
||||||
|
</span>
|
||||||
|
<X class="size-4 stroke-1.5 cursor-pointer" @click="removeValue(value)" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- <ErrorMessage class="mt-2 pl-2" v-if="error" :message="error" /> -->
|
<!-- <ErrorMessage class="mt-2 pl-2" v-if="error" :message="error" /> -->
|
||||||
</div>
|
</div>
|
||||||
@@ -90,9 +95,9 @@ import {
|
|||||||
ComboboxOption,
|
ComboboxOption,
|
||||||
} from '@headlessui/vue'
|
} from '@headlessui/vue'
|
||||||
import { createResource, Popover, Button } from 'frappe-ui'
|
import { createResource, Popover, Button } from 'frappe-ui'
|
||||||
import { ref, computed, nextTick } from 'vue'
|
import { ref, computed, nextTick, useAttrs } from 'vue'
|
||||||
import { watchDebounced } from '@vueuse/core'
|
import { watchDebounced } from '@vueuse/core'
|
||||||
import { X } from 'lucide-vue-next'
|
import { X, Plus } from 'lucide-vue-next'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
label: {
|
label: {
|
||||||
@@ -124,7 +129,7 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const values = defineModel()
|
const values = defineModel()
|
||||||
|
const attrs = useAttrs()
|
||||||
const emails = ref([])
|
const emails = ref([])
|
||||||
const search = ref(null)
|
const search = ref(null)
|
||||||
const error = ref(null)
|
const error = ref(null)
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
:debounce="300"
|
:debounce="300"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => (showForm = !showForm)">
|
<Button @click="() => (showForm = !showForm)">
|
||||||
<template #icon>
|
<template #prefix>
|
||||||
<Plus v-if="!showForm" class="h-3 w-3 stroke-1.5" />
|
<Plus v-if="!showForm" class="size-4 stroke-1.5" />
|
||||||
<X v-else class="h-3 w-3 stroke-1.5" />
|
<X v-else class="size-4 stroke-1.5" />
|
||||||
</template>
|
</template>
|
||||||
|
{{ showForm ? __('Close') : __('New') }}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
:debounce="300"
|
:debounce="300"
|
||||||
/>
|
/>
|
||||||
<Button @click="() => (showForm = !showForm)">
|
<Button @click="() => (showForm = !showForm)">
|
||||||
<template #icon>
|
<template #prefix>
|
||||||
<Plus v-if="!showForm" class="h-3 w-3 stroke-1.5" />
|
<Plus v-if="!showForm" class="size-4 stroke-1.5" />
|
||||||
<X v-else class="h-3 w-3 stroke-1.5" />
|
<X v-else class="size-4 stroke-1.5" />
|
||||||
</template>
|
</template>
|
||||||
|
{{ showForm ? __('Close') : __('New') }}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,149 +19,130 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="mt-5 mb-10">
|
<div class="mt-5 mb-5">
|
||||||
<div class="container mb-5">
|
<div class="px-10 pb-5 mb-5 space-y-5 border-b">
|
||||||
<div class="text-lg font-semibold mb-4">
|
<div class="text-lg font-semibold mb-4">
|
||||||
{{ __('Details') }}
|
{{ __('Details') }}
|
||||||
</div>
|
</div>
|
||||||
<FormControl
|
<div class="grid grid-cols-2 gap-5">
|
||||||
v-model="course.title"
|
<FormControl
|
||||||
:label="__('Title')"
|
v-model="course.title"
|
||||||
class="mb-4"
|
:label="__('Title')"
|
||||||
:required="true"
|
:required="true"
|
||||||
/>
|
|
||||||
<FormControl
|
|
||||||
v-model="course.short_introduction"
|
|
||||||
:label="__('Short Introduction')"
|
|
||||||
:placeholder="
|
|
||||||
__(
|
|
||||||
'A one line introduction to the course that appears on the course card'
|
|
||||||
)
|
|
||||||
"
|
|
||||||
class="mb-4"
|
|
||||||
:required="true"
|
|
||||||
/>
|
|
||||||
<div class="mb-4">
|
|
||||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
|
||||||
{{ __('Course Description') }}
|
|
||||||
<span class="text-ink-red-3">*</span>
|
|
||||||
</div>
|
|
||||||
<TextEditor
|
|
||||||
:content="course.description"
|
|
||||||
@change="(val) => (course.description = val)"
|
|
||||||
:editable="true"
|
|
||||||
:fixedMenu="true"
|
|
||||||
editorClass="prose-sm max-w-none border-b border-x bg-surface-gray-2 rounded-b-md py-1 px-2 min-h-[7rem]"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<div class="text-xs text-ink-gray-5 mb-2">
|
|
||||||
{{ __('Course Image') }}
|
|
||||||
<span class="text-ink-red-3">*</span>
|
|
||||||
</div>
|
|
||||||
<FileUploader
|
|
||||||
v-if="!course.course_image"
|
|
||||||
:fileTypes="['image/*']"
|
|
||||||
:validateFile="validateFile"
|
|
||||||
@success="(file) => saveImage(file)"
|
|
||||||
>
|
|
||||||
<template
|
|
||||||
v-slot="{ file, progress, uploading, openFileSelector }"
|
|
||||||
>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="border rounded-md w-fit py-5 px-20">
|
|
||||||
<Image class="size-5 stroke-1 text-ink-gray-7" />
|
|
||||||
</div>
|
|
||||||
<div class="ml-4">
|
|
||||||
<Button @click="openFileSelector">
|
|
||||||
{{ __('Upload') }}
|
|
||||||
</Button>
|
|
||||||
<div class="mt-2 text-ink-gray-5 text-sm">
|
|
||||||
{{
|
|
||||||
__('Appears on the course card in the course list')
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</FileUploader>
|
|
||||||
<div v-else class="mb-4">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<img
|
|
||||||
:src="course.course_image.file_url"
|
|
||||||
class="border rounded-md w-40"
|
|
||||||
/>
|
|
||||||
<div class="ml-4">
|
|
||||||
<Button @click="removeImage()">
|
|
||||||
{{ __('Remove') }}
|
|
||||||
</Button>
|
|
||||||
<div class="mt-2 text-ink-gray-5 text-sm">
|
|
||||||
{{ __('Appears on the course card in the course list') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<FormControl
|
|
||||||
v-model="course.video_link"
|
|
||||||
:label="__('Preview Video')"
|
|
||||||
:placeholder="
|
|
||||||
__(
|
|
||||||
'Paste the youtube link of a short video introducing the course'
|
|
||||||
)
|
|
||||||
"
|
|
||||||
class="mb-4"
|
|
||||||
/>
|
|
||||||
<div class="mb-4">
|
|
||||||
<div class="mb-1.5 text-xs text-ink-gray-5">
|
|
||||||
{{ __('Tags') }}
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div
|
|
||||||
v-if="course.tags"
|
|
||||||
v-for="tag in course.tags?.split(', ')"
|
|
||||||
class="flex items-center bg-surface-gray-2 text-ink-gray-7 p-2 rounded-md mr-2"
|
|
||||||
>
|
|
||||||
{{ tag }}
|
|
||||||
<X
|
|
||||||
class="stroke-1.5 w-3 h-3 ml-2 cursor-pointer"
|
|
||||||
@click="removeTag(tag)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<FormControl
|
|
||||||
v-model="newTag"
|
|
||||||
:placeholder="__('Add a keyword and then press enter')"
|
|
||||||
class="w-72"
|
|
||||||
@keyup.enter="updateTags()"
|
|
||||||
id="tags"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-1/2 mb-4">
|
|
||||||
<Link
|
<Link
|
||||||
doctype="LMS Category"
|
doctype="LMS Category"
|
||||||
v-model="course.category"
|
v-model="course.category"
|
||||||
:label="__('Category')"
|
:label="__('Category')"
|
||||||
:onCreate="(value, close) => openSettings(close)"
|
:onCreate="(value, close) => openSettings('Categories', close)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<MultiSelect
|
<div class="grid grid-cols-2 gap-5">
|
||||||
v-model="instructors"
|
<MultiSelect
|
||||||
doctype="User"
|
v-model="instructors"
|
||||||
:label="__('Instructors')"
|
doctype="User"
|
||||||
:filters="{ ignore_user_type: 1 }"
|
:label="__('Instructors')"
|
||||||
:required="true"
|
:filters="{ ignore_user_type: 1 }"
|
||||||
/>
|
:onCreate="(close) => openSettings('Members', close)"
|
||||||
</div>
|
:required="true"
|
||||||
<div class="container border-t">
|
/>
|
||||||
<div class="text-lg font-semibold mt-5 mb-4">
|
<div>
|
||||||
{{ __('Settings') }}
|
<div class="mb-1.5 text-xs text-ink-gray-5">
|
||||||
|
{{ __('Tags') }}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div
|
||||||
|
v-if="course.tags"
|
||||||
|
v-for="tag in course.tags?.split(', ')"
|
||||||
|
class="flex items-center bg-surface-gray-2 text-ink-gray-7 p-2 rounded-md mr-2"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
<X
|
||||||
|
class="stroke-1.5 w-3 h-3 ml-2 cursor-pointer"
|
||||||
|
@click="removeTag(tag)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<FormControl
|
||||||
|
v-model="newTag"
|
||||||
|
:placeholder="__('Add a keyword and then press enter')"
|
||||||
|
class="w-full"
|
||||||
|
@keyup.enter="updateTags()"
|
||||||
|
id="tags"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-10 mb-4">
|
<div class="grid grid-cols-2 gap-5">
|
||||||
<div
|
<FormControl
|
||||||
v-if="user.data?.is_moderator"
|
v-model="course.short_introduction"
|
||||||
class="flex flex-col space-y-4"
|
type="textarea"
|
||||||
>
|
:rows="4"
|
||||||
|
:label="__('Short Introduction')"
|
||||||
|
:placeholder="
|
||||||
|
__(
|
||||||
|
'A one line introduction to the course that appears on the course card'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:required="true"
|
||||||
|
/>
|
||||||
|
<div class="mb-4">
|
||||||
|
<div class="text-xs text-ink-gray-5 mb-2">
|
||||||
|
{{ __('Course Image') }}
|
||||||
|
<span class="text-ink-red-3">*</span>
|
||||||
|
</div>
|
||||||
|
<FileUploader
|
||||||
|
v-if="!course.course_image"
|
||||||
|
:fileTypes="['image/*']"
|
||||||
|
:validateFile="validateFile"
|
||||||
|
@success="(file) => saveImage(file)"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-slot="{ file, progress, uploading, openFileSelector }"
|
||||||
|
>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="border rounded-md w-fit py-5 px-20">
|
||||||
|
<Image class="size-5 stroke-1 text-ink-gray-7" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<Button @click="openFileSelector">
|
||||||
|
{{ __('Upload') }}
|
||||||
|
</Button>
|
||||||
|
<div class="mt-1 text-ink-gray-5 text-sm leading-5">
|
||||||
|
{{
|
||||||
|
__('Appears on the course card in the course list')
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</FileUploader>
|
||||||
|
<div v-else class="mb-4">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img
|
||||||
|
:src="course.course_image.file_url"
|
||||||
|
class="border rounded-md w-40"
|
||||||
|
/>
|
||||||
|
<div class="ml-4">
|
||||||
|
<Button @click="removeImage()">
|
||||||
|
{{ __('Remove') }}
|
||||||
|
</Button>
|
||||||
|
<div class="mt-2 text-ink-gray-5 text-sm">
|
||||||
|
{{ __('Appears on the course card in the course list') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="px-10 pb-5 mb-5 space-y-5 border-b">
|
||||||
|
<div class="text-lg font-semibold">
|
||||||
|
{{ __("Settings") }}
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-5">
|
||||||
|
<div class="flex flex-col space-y-5">
|
||||||
<FormControl
|
<FormControl
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="course.published"
|
v-model="course.published"
|
||||||
@@ -171,10 +152,9 @@
|
|||||||
v-model="course.published_on"
|
v-model="course.published_on"
|
||||||
:label="__('Published On')"
|
:label="__('Published On')"
|
||||||
type="date"
|
type="date"
|
||||||
class="mb-5"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col space-y-3">
|
<div class="flex flex-col space-y-5">
|
||||||
<FormControl
|
<FormControl
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="course.upcoming"
|
v-model="course.upcoming"
|
||||||
@@ -193,7 +173,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container border-t space-y-4">
|
|
||||||
|
|
||||||
|
<div class="px-10 pb-5 mb-5 space-y-5 border-b">
|
||||||
|
<div class="">
|
||||||
|
<div class="mb-1.5 text-sm text-ink-gray-5">
|
||||||
|
{{ __('Course Description') }}
|
||||||
|
<span class="text-ink-red-3">*</span>
|
||||||
|
</div>
|
||||||
|
<TextEditor
|
||||||
|
:content="course.description"
|
||||||
|
@change="(val) => (course.description = val)"
|
||||||
|
:editable="true"
|
||||||
|
:fixedMenu="true"
|
||||||
|
editorClass="prose-sm max-w-none border-b border-x bg-surface-gray-2 rounded-b-md py-1 px-2 min-h-[7rem]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormControl
|
||||||
|
v-model="course.video_link"
|
||||||
|
:label="__('Preview Video')"
|
||||||
|
:placeholder="
|
||||||
|
__(
|
||||||
|
'Paste the youtube link of a short video introducing the course'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="px-10 pb-5 space-y-5">
|
||||||
<div class="text-lg font-semibold mt-5">
|
<div class="text-lg font-semibold mt-5">
|
||||||
{{ __('Pricing and Certification') }}
|
{{ __('Pricing and Certification') }}
|
||||||
</div>
|
</div>
|
||||||
@@ -214,19 +223,25 @@
|
|||||||
:label="__('Paid Certificate')"
|
:label="__('Paid Certificate')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<FormControl v-model="course.course_price" :label="__('Amount')" />
|
<div class="grid grid-cols-2 gap-5">
|
||||||
<Link
|
<div class="space-y-5">
|
||||||
doctype="Currency"
|
<FormControl v-if="course.paid_course || course.paid_certificate" v-model="course.course_price" :label="__('Amount')" />
|
||||||
v-model="course.currency"
|
<Link
|
||||||
:filters="{ enabled: 1 }"
|
v-if="course.paid_certificate"
|
||||||
:label="__('Currency')"
|
doctype="Course Evaluator"
|
||||||
/>
|
v-model="course.evaluator"
|
||||||
<Link
|
:label="__('Evaluator')"
|
||||||
v-if="course.paid_certificate"
|
:onCreate="(value, close) => openSettings('Evaluators', close)"
|
||||||
doctype="Course Evaluator"
|
/>
|
||||||
v-model="course.evaluator"
|
</div>
|
||||||
:label="__('Evaluator')"
|
<Link
|
||||||
/>
|
v-if="course.paid_course || course.paid_certificate"
|
||||||
|
doctype="Currency"
|
||||||
|
v-model="course.currency"
|
||||||
|
:filters="{ enabled: 1 }"
|
||||||
|
:label="__('Currency')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -531,12 +546,6 @@ const removeImage = () => {
|
|||||||
course.course_image = null
|
course.course_image = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const openSettings = (close) => {
|
|
||||||
close()
|
|
||||||
settingsStore.activeTab = 'Categories'
|
|
||||||
settingsStore.isSettingsOpen = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const check_permission = () => {
|
const check_permission = () => {
|
||||||
let user_is_instructor = false
|
let user_is_instructor = false
|
||||||
if (user.data?.is_moderator) return
|
if (user.data?.is_moderator) return
|
||||||
@@ -552,6 +561,12 @@ const check_permission = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const openSettings = (category, close) => {
|
||||||
|
close()
|
||||||
|
settingsStore.activeTab = category
|
||||||
|
settingsStore.isSettingsOpen = true
|
||||||
|
}
|
||||||
|
|
||||||
const breadcrumbs = computed(() => {
|
const breadcrumbs = computed(() => {
|
||||||
let crumbs = [
|
let crumbs = [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user