feat: replace checkboxes with switches

This commit is contained in:
raizasafeel
2026-03-17 12:21:23 +05:30
parent 186cd90d42
commit b8dab3e54a
18 changed files with 183 additions and 118 deletions
+4 -3
View File
@@ -49,8 +49,9 @@
:label="__('Select an Assignment')"
:onCreate="(value, close) => redirectToForm()"
/>
<FormControl
type="checkbox"
<Switch
size="sm"
:description="__('Only show assignments from the current course')"
:label="__('Filter assignments by course')"
v-model="filterAssignmentsByCourse"
/>
@@ -61,7 +62,7 @@
</Dialog>
</template>
<script setup>
import { Dialog, FormControl } from 'frappe-ui'
import { Dialog, Switch } from 'frappe-ui'
import { nextTick, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { getLmsRoute } from '@/utils/basePath'
@@ -34,10 +34,11 @@
:required="true"
:placeholder="__('Your enrollment in {{ batch_name }} is confirmed')"
/>
<FormControl
<Switch
size="sm"
:description="__('Use HTML content for the email response')"
:label="__('Use HTML')"
v-model="template.use_html"
type="checkbox"
/>
<FormControl
v-if="template.use_html"
@@ -75,7 +76,7 @@
</Dialog>
</template>
<script setup lang="ts">
import { call, Dialog, FormControl, TextEditor, toast } from 'frappe-ui'
import { call, Dialog, FormControl, TextEditor, toast, Switch } from 'frappe-ui'
import { reactive, watch } from 'vue'
import { cleanError } from '@/utils'
+6 -2
View File
@@ -122,10 +122,13 @@
</Button>
</div>
<div v-else class="flex flex-col space-y-4 p-5">
<FormControl
type="checkbox"
<Switch
size="sm"
v-model="certificate.published"
:label="__('Published')"
:description="
__('Make this certificate visible to the participant.')
"
:disabled="!userIsEvaluator()"
/>
<Link
@@ -169,6 +172,7 @@ import {
Button,
FormControl,
createResource,
Switch,
Tabs,
Tooltip,
Textarea,
@@ -44,26 +44,26 @@
<div class="text-sm text-ink-gray-5">
{{ __('Roles') }}
</div>
<div class="flex flex-wrap gap-x-6">
<FormControl
<div class="grid md:grid-cols-2 gap-x-6 gap-y-3">
<Switch
size="sm"
:label="__('Student')"
v-model="roles.lms_student"
type="checkbox"
/>
<FormControl
<Switch
size="sm"
:label="__('Course Creator')"
v-model="roles.course_creator"
type="checkbox"
/>
<FormControl
<Switch
size="sm"
:label="__('Evaluator')"
v-model="roles.batch_evaluator"
type="checkbox"
/>
<FormControl
<Switch
size="sm"
:label="__('Moderator')"
v-model="roles.moderator"
type="checkbox"
/>
</div>
</div>
@@ -73,7 +73,7 @@
</template>
<script setup lang="ts">
import { call, Dialog, FormControl, toast } from 'frappe-ui'
import { call, Dialog, FormControl, toast, Switch } from 'frappe-ui'
import { reactive, ref, watch } from 'vue'
import { cleanError } from '@/utils'
+3 -2
View File
@@ -72,10 +72,11 @@
:label="__('Explanation')"
v-model="question[`explanation_${n}`]"
/>
<FormControl
<Switch
size="sm"
:label="__('Correct Answer')"
:description="__('Mark this option as a correct answer.')"
v-model="question[`is_correct_${n}`]"
type="checkbox"
/>
</div>
</div>
@@ -18,10 +18,13 @@
>
<template #body-content>
<div class="mb-4">
<FormControl
<Switch
size="sm"
v-model="account.enabled"
:label="__('Enabled')"
type="checkbox"
:description="
__('Activate this Zoom account for scheduling meetings.')
"
/>
</div>
<div class="grid grid-cols-2 gap-5">
@@ -61,7 +64,7 @@
</Dialog>
</template>
<script setup lang="ts">
import { call, Dialog, FormControl, toast } from 'frappe-ui'
import { call, Dialog, FormControl, Switch, toast } from 'frappe-ui'
import { inject, reactive, watch } from 'vue'
import { User } from '@/components/Settings/types'
import { openSettings, cleanError } from '@/utils'
@@ -9,11 +9,7 @@
<template #body-content>
<div class="grid grid-cols-2 gap-x-5">
<div class="space-y-4">
<FormControl
v-model="badge.enabled"
:label="__('Enabled')"
type="checkbox"
/>
<Switch size="sm" v-model="badge.enabled" :label="__('Enabled')" />
<FormControl
v-model="badge.title"
:label="__('Title')"
@@ -41,10 +37,11 @@
</div>
<div class="space-y-4">
<FormControl
<Switch
size="sm"
v-model="badge.grant_only_once"
:label="__('Grant Only Once')"
type="checkbox"
:description="__('Each user can only receive this badge one time.')"
/>
<FormControl
v-model="badge.event"
@@ -82,7 +79,7 @@
</Dialog>
</template>
<script setup lang="ts">
import { Button, call, Dialog, FormControl, toast } from 'frappe-ui'
import { Button, call, Dialog, FormControl, Switch, toast } from 'frappe-ui'
import { computed, ref, watch } from 'vue'
import { cleanError } from '@/utils'
import type { Badges, Badge } from '@/components/Settings/types'
@@ -11,10 +11,11 @@
</div>
<div class="space-y-4 overflow-y-auto">
<div>
<FormControl
<Switch
size="sm"
v-model="data.enabled"
:label="__('Enabled')"
type="checkbox"
:description="__('Allow this coupon to be used for discounts.')"
/>
</div>
<div class="grid grid-cols-2 gap-4">
@@ -81,7 +82,7 @@
</div>
</template>
<script setup lang="ts">
import { Button, FormControl, toast } from 'frappe-ui'
import { Button, FormControl, toast, Switch } from 'frappe-ui'
import { ref } from 'vue'
import { ChevronLeft } from 'lucide-vue-next'
import type { Coupon, Coupons } from './types'
@@ -20,10 +20,13 @@
>
<template #body-content>
<div class="mb-4">
<FormControl
<Switch
size="sm"
v-model="account.enabled"
:label="__('Enabled')"
type="checkbox"
:description="
__('Activate this Google Meet account for scheduling meetings.')
"
/>
</div>
<div class="grid grid-cols-2 gap-5">
@@ -51,7 +54,7 @@
</Dialog>
</template>
<script setup lang="ts">
import { call, Dialog, FormControl, toast } from 'frappe-ui'
import { call, Dialog, FormControl, Switch, toast } from 'frappe-ui'
import { inject, reactive, watch } from 'vue'
import { User } from '@/components/Settings/types'
import { openSettings, cleanError } from '@/utils'
@@ -32,14 +32,16 @@
</div>
<div v-if="transactionData" class="overflow-y-auto">
<div class="grid grid-cols-3 gap-5">
<FormControl
<Switch
size="sm"
:label="__('Payment Received')"
type="checkbox"
:description="__('Mark the payment as received.')"
v-model="transactionData.payment_received"
/>
<FormControl
<Switch
size="sm"
:label="__('Payment For Certificate')"
type="checkbox"
:description="__('This payment is for a certificate.')"
v-model="transactionData.payment_for_certificate"
/>
<FormControl
@@ -175,7 +177,7 @@
</div>
</template>
<script setup lang="ts">
import { Button, FormControl, toast } from 'frappe-ui'
import { Button, FormControl, Switch, toast } from 'frappe-ui'
import { useRouter } from 'vue-router'
import { computed, ref, watch } from 'vue'
import { ChevronLeft } from 'lucide-vue-next'
@@ -27,15 +27,17 @@
doctype="User"
:placeholder="__('Filter by Member')"
/>
<FormControl
v-model="paymentReceived"
type="checkbox"
<Switch
size="sm"
:label="__('Payment Received')"
:description="__('Mark the payment as received.')"
v-model="paymentReceived"
/>
<FormControl
<Switch
size="sm"
:label="__('Payment For Certificate')"
:description="__('This payment is for a certificate.')"
v-model="paymentForCertificate"
type="checkbox"
:label="__('Payment for Certificate')"
/>
</div>
@@ -116,6 +118,7 @@ import {
ListRow,
ListRowItem,
FormControl,
Switch,
} from 'frappe-ui'
import { computed, ref, watch } from 'vue'
import { RefreshCw } from 'lucide-vue-next'
+18 -10
View File
@@ -9,10 +9,11 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
<div class="space-y-5">
<FormControl
<Switch
size="sm"
v-model="batchDetail.doc.published"
type="checkbox"
:label="__('Published')"
:description="__('Make the batch visible to all users.')"
/>
<FormControl
v-model="batchDetail.doc.title"
@@ -43,10 +44,13 @@
/>
</div>
<div class="space-y-5">
<FormControl
<Switch
size="sm"
v-model="batchDetail.doc.allow_self_enrollment"
type="checkbox"
:label="__('Allow Self Enrollment')"
:description="
__('Allow users to enroll in this batch on their own.')
"
/>
<FormControl
v-model="batchDetail.doc.start_time"
@@ -88,10 +92,11 @@
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5 items-start">
<div class="flex flex-col space-y-5">
<FormControl
<Switch
size="sm"
v-model="batchDetail.doc.evaluation"
type="checkbox"
:label="__('Evaluation')"
:description="__('Enable evaluations for batch participants.')"
/>
<FormControl
v-if="batchDetail.doc.evaluation"
@@ -102,10 +107,11 @@
/>
</div>
<div>
<FormControl
<Switch
size="sm"
v-model="batchDetail.doc.certification"
type="checkbox"
:label="__('Certification')"
:description="__('Issue certificates to batch participants.')"
/>
</div>
</div>
@@ -218,10 +224,11 @@
<div class="text-lg text-ink-gray-9 font-semibold">
{{ __('Pricing') }}
</div>
<FormControl
<Switch
size="sm"
v-model="batchDetail.doc.paid_batch"
type="checkbox"
:label="__('Paid Batch')"
:description="__('Charge a fee for batch enrollment.')"
/>
<div
v-if="batchDetail.doc.paid_batch"
@@ -305,6 +312,7 @@ import {
} from 'vue'
import {
FormControl,
Switch,
TextEditor,
createDocumentResource,
toast,
+4 -2
View File
@@ -78,10 +78,11 @@
</div>
</div>
<FormControl
<Switch
size="sm"
v-model="certification"
:label="__('Certification')"
type="checkbox"
:description="__('Only show batches that offer a certificate.')"
@change="updateBatches()"
/>
</div>
@@ -122,6 +123,7 @@ import {
Dropdown,
FormControl,
Select,
Switch,
TabButtons,
usePageMeta,
} from 'frappe-ui'
+5 -4
View File
@@ -41,16 +41,16 @@
</div>
</div>
<div class="flex items-center space-x-4">
<FormControl
<Switch
size="sm"
v-model="openToWork"
:label="__('Open to Work')"
type="checkbox"
@change="updateParticipants()"
/>
<FormControl
<Switch
size="sm"
v-model="hiring"
:label="__('Hiring')"
type="checkbox"
@change="updateParticipants()"
/>
</div>
@@ -129,6 +129,7 @@ import {
createListResource,
FormControl,
Select,
Switch,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onMounted, ref } from 'vue'
+23 -12
View File
@@ -103,10 +103,11 @@
v-if="user.data?.is_moderator"
class="flex flex-col space-y-5"
>
<FormControl
type="checkbox"
<Switch
size="sm"
v-model="courseResource.doc.published"
:label="__('Published')"
:description="__('Make the course visible to all users.')"
@change="makeFormDirty()"
/>
<FormControl
@@ -117,16 +118,22 @@
/>
</div>
<div class="flex flex-col space-y-5">
<FormControl
type="checkbox"
<Switch
size="sm"
v-model="courseResource.doc.upcoming"
:label="__('Upcoming')"
:description="
__(
'Mark the course as upcoming but not yet open for enrollment.'
)
"
@change="makeFormDirty()"
/>
<FormControl
type="checkbox"
<Switch
size="sm"
v-model="courseResource.doc.featured"
:label="__('Featured')"
:description="__('Highlight the course on the homepage.')"
@change="makeFormDirty()"
/>
<FormControl
@@ -208,22 +215,25 @@
{{ __('Pricing and Certification') }}
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-5">
<FormControl
type="checkbox"
<Switch
size="sm"
v-model="courseResource.doc.paid_course"
:label="__('Paid Course')"
:description="__('Charge a fee for course access.')"
@change="makeFormDirty()"
/>
<FormControl
type="checkbox"
<Switch
size="sm"
v-model="courseResource.doc.enable_certification"
:label="__('Completion Certificate')"
:description="__('Issue a certificate on course completion.')"
@change="makeFormDirty()"
/>
<FormControl
type="checkbox"
<Switch
size="sm"
v-model="courseResource.doc.paid_certificate"
:label="__('Paid Certificate')"
:description="__('Charge a fee for the certificate.')"
@change="makeFormDirty()"
/>
</div>
@@ -320,6 +330,7 @@
<script setup>
import {
TextEditor,
Switch,
createResource,
createDocumentResource,
FormControl,
+4 -2
View File
@@ -77,10 +77,11 @@
</div>
</div>
<FormControl
<Switch
size="sm"
v-model="certification"
:label="__('Certification')"
type="checkbox"
:description="__('Only show courses that offer a certificate.')"
@change="updateCourses()"
/>
</div>
@@ -122,6 +123,7 @@ import {
FormControl,
Select,
TabButtons,
Switch,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onMounted, ref, watch } from 'vue'
+48 -32
View File
@@ -12,39 +12,48 @@
{{ __('You cannot change the roles in read-only mode.') }}
</span>
</div>
<div
v-else
class="flex flex-col md:flex-row gap-4 md:gap-0 justify-between w-3/4 mt-5"
>
<FormControl
:label="__('Moderator')"
v-model="moderator"
type="checkbox"
@change.stop="changeRole('moderator')"
/>
<FormControl
:label="__('Course Creator')"
v-model="course_creator"
type="checkbox"
@change.stop="changeRole('course_creator')"
/>
<FormControl
:label="__('Evaluator')"
v-model="batch_evaluator"
type="checkbox"
@change.stop="changeRole('batch_evaluator')"
/>
<FormControl
<div v-else class="grid grid-cols-1 lg:grid-cols-2 gap-5 mt-5">
<Switch
size="sm"
:label="__('Student')"
:description="
__('Can browse courses, enroll in batches, and view content.')
"
v-model="lms_student"
type="checkbox"
@change.stop="changeRole('lms_student')"
@change="changeRole('lms_student')"
/>
<Switch
size="sm"
:label="__('Course Creator')"
:description="
__('Can create, edit, and manage courses, chapters, and lessons.')
"
v-model="course_creator"
@change="changeRole('course_creator')"
/>
<Switch
size="sm"
:label="__('Evaluator')"
:description="
__('Can create batches/live classes and grade student assignments.')
"
v-model="batch_evaluator"
@change="changeRole('batch_evaluator')"
/>
<Switch
size="sm"
:label="__('Moderator')"
:description="
__('Full access to all content, users, and system-wide settings.')
"
v-model="moderator"
@change="changeRole('moderator')"
/>
</div>
</div>
</template>
<script setup>
import { FormControl, createResource, toast } from 'frappe-ui'
import { Switch, call, createResource, toast } from 'frappe-ui'
import { ref, watch } from 'vue'
import { convertToTitleCase } from '@/utils'
import { CircleAlert } from 'lucide-vue-next'
@@ -103,17 +112,24 @@ const updateRole = createResource({
},
})
// todo: use save_role for all roles to ensure consistent behavior and error handling
const changeRole = (role) => {
const roleName =
role == 'lms_student'
? 'LMS Student'
: convertToTitleCase(role.split('_').join(' '))
const value = eval(role).value
updateRole.submit(
{
role:
role == 'lms_student'
? 'LMS Student'
: convertToTitleCase(role.split('_').join(' ')),
value: eval(role).value,
role: roleName,
value: value,
},
{
onSuccess(data) {
async onSuccess() {
if (role === 'batch_evaluator') {
await syncEvaluatorRecord(value)
}
toast.success(__('Role updated successfully'))
},
}
+17 -8
View File
@@ -87,22 +87,29 @@
</div>
<div class="grid grid-cols-3 gap-5">
<div class="flex flex-col space-y-10">
<FormControl
<Switch
v-model="quizDetails.doc.show_answers"
type="checkbox"
size="sm"
:label="__('Show Answers')"
:description="
__('Display correct answers after each question is attempted.')
"
/>
<FormControl
<Switch
v-model="quizDetails.doc.show_submission_history"
type="checkbox"
size="sm"
:label="__('Show Submission History')"
:description="__('Allow users to view their past quiz attempts.')"
/>
</div>
<div class="flex flex-col space-y-5">
<FormControl
<Switch
v-model="quizDetails.doc.shuffle_questions"
type="checkbox"
size="sm"
:label="__('Shuffle Questions')"
:description="
__('Randomize the order of questions for each attempt.')
"
/>
<FormControl
v-if="quizDetails.doc.shuffle_questions"
@@ -111,10 +118,11 @@
/>
</div>
<div class="flex flex-col space-y-5">
<FormControl
<Switch
v-model="quizDetails.doc.enable_negative_marking"
type="checkbox"
size="sm"
:label="__('Enable Negative Marking')"
:description="__('Deduct marks for incorrect answers.')"
/>
<FormControl
v-if="quizDetails.doc.enable_negative_marking"
@@ -214,6 +222,7 @@ import {
toast,
createDocumentResource,
Badge,
Switch,
} from 'frappe-ui'
import {
computed,