fix: roles, permission and access on profile page
This commit is contained in:
@@ -66,7 +66,11 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ __('View Certificate') }}
|
{{ __('View Certificate') }}
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-else @click="openCallLink(event.venue)" class="w-full">
|
<Button
|
||||||
|
v-else-if="userIsEvaluator()"
|
||||||
|
@click="openCallLink(event.venue)"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<Video class="h-4 w-4 stroke-1.5" />
|
<Video class="h-4 w-4 stroke-1.5" />
|
||||||
</template>
|
</template>
|
||||||
@@ -83,21 +87,31 @@
|
|||||||
class="flex flex-col space-y-4 p-5"
|
class="flex flex-col space-y-4 p-5"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<Rating v-model="evaluation.rating" :label="__('Rating')" />
|
<Rating
|
||||||
|
v-model="evaluation.rating"
|
||||||
|
:label="__('Rating')"
|
||||||
|
:disabled="!userIsEvaluator()"
|
||||||
|
/>
|
||||||
<FormControl
|
<FormControl
|
||||||
type="select"
|
type="select"
|
||||||
:options="statusOptions"
|
:options="statusOptions"
|
||||||
v-model="evaluation.status"
|
v-model="evaluation.status"
|
||||||
:label="__('Status')"
|
:label="__('Status')"
|
||||||
class="w-1/2"
|
class="w-1/2"
|
||||||
|
:disabled="!userIsEvaluator()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Textarea
|
<Textarea
|
||||||
v-model="evaluation.summary"
|
v-model="evaluation.summary"
|
||||||
:label="__('Summary')"
|
:label="__('Summary')"
|
||||||
:rows="7"
|
:rows="7"
|
||||||
|
:disabled="!userIsEvaluator()"
|
||||||
/>
|
/>
|
||||||
<Button variant="solid" @click="saveEvaluation()">
|
<Button
|
||||||
|
v-if="userIsEvaluator()"
|
||||||
|
variant="solid"
|
||||||
|
@click="saveEvaluation()"
|
||||||
|
>
|
||||||
{{ __('Save') }}
|
{{ __('Save') }}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -106,11 +120,13 @@
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="certificate.published"
|
v-model="certificate.published"
|
||||||
:label="__('Published')"
|
:label="__('Published')"
|
||||||
|
:disabled="!userIsEvaluator()"
|
||||||
/>
|
/>
|
||||||
<Link
|
<Link
|
||||||
v-model="certificate.template"
|
v-model="certificate.template"
|
||||||
:label="__('Template')"
|
:label="__('Template')"
|
||||||
doctype="Print Format"
|
doctype="Print Format"
|
||||||
|
:disabled="!userIsEvaluator()"
|
||||||
:filters="{
|
:filters="{
|
||||||
doc_type: 'LMS Certificate',
|
doc_type: 'LMS Certificate',
|
||||||
}"
|
}"
|
||||||
@@ -118,14 +134,20 @@
|
|||||||
<FormControl
|
<FormControl
|
||||||
type="date"
|
type="date"
|
||||||
v-model="certificate.issue_date"
|
v-model="certificate.issue_date"
|
||||||
|
:disabled="!userIsEvaluator()"
|
||||||
:label="__('Issue Date')"
|
:label="__('Issue Date')"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<FormControl
|
||||||
type="date"
|
type="date"
|
||||||
v-model="certificate.expiry_date"
|
v-model="certificate.expiry_date"
|
||||||
|
:disabled="!userIsEvaluator()"
|
||||||
:label="__('Expiry Date')"
|
:label="__('Expiry Date')"
|
||||||
/>
|
/>
|
||||||
<Button variant="solid" @click="saveCertificate()">
|
<Button
|
||||||
|
v-if="userIsEvaluator()"
|
||||||
|
variant="solid"
|
||||||
|
@click="saveCertificate()"
|
||||||
|
>
|
||||||
{{ __('Save') }}
|
{{ __('Save') }}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -163,6 +185,7 @@ import Rating from '@/components/Controls/Rating.vue'
|
|||||||
import Link from '@/components/Controls/Link.vue'
|
import Link from '@/components/Controls/Link.vue'
|
||||||
|
|
||||||
const show = defineModel()
|
const show = defineModel()
|
||||||
|
const user = inject('$user')
|
||||||
const dayjs = inject('$dayjs')
|
const dayjs = inject('$dayjs')
|
||||||
const tabIndex = ref(0)
|
const tabIndex = ref(0)
|
||||||
const showCertification = ref(false)
|
const showCertification = ref(false)
|
||||||
@@ -175,9 +198,18 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const evaluation = reactive({})
|
const evaluation = reactive({})
|
||||||
|
|
||||||
const certificate = reactive({})
|
const certificate = reactive({})
|
||||||
|
|
||||||
|
watch(user, () => {
|
||||||
|
if (userIsEvaluator()) {
|
||||||
|
defaultTemplate.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const userIsEvaluator = () => {
|
||||||
|
return user.data && user.data.name == props.event.evaluator
|
||||||
|
}
|
||||||
|
|
||||||
const defaultTemplate = createResource({
|
const defaultTemplate = createResource({
|
||||||
url: 'frappe.client.get_value',
|
url: 'frappe.client.get_value',
|
||||||
makeParams(values) {
|
makeParams(values) {
|
||||||
@@ -190,7 +222,6 @@ const defaultTemplate = createResource({
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
auto: true,
|
|
||||||
onSuccess(data) {
|
onSuccess(data) {
|
||||||
certificate.template = data.value
|
certificate.template = data.value
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -124,19 +124,13 @@ const props = defineProps({
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if ($user.data) profile.reload()
|
if ($user.data) profile.reload()
|
||||||
|
|
||||||
setActiveTab()
|
setActiveTab()
|
||||||
})
|
})
|
||||||
|
|
||||||
const profile = createResource({
|
const profile = createResource({
|
||||||
url: 'frappe.client.get',
|
url: 'lms.lms.api.get_profile_details',
|
||||||
makeParams(values) {
|
params: {
|
||||||
return {
|
username: props.username,
|
||||||
doctype: 'User',
|
|
||||||
filters: {
|
|
||||||
username: props.username,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -183,6 +177,7 @@ watch(
|
|||||||
() => props.username,
|
() => props.username,
|
||||||
() => {
|
() => {
|
||||||
profile.reload()
|
profile.reload()
|
||||||
|
getProfileRoles()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -199,6 +194,7 @@ const hasHigherAccess = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isEvaluatorOrModerator = () => {
|
const isEvaluatorOrModerator = () => {
|
||||||
|
console.log(profile.data)
|
||||||
return (
|
return (
|
||||||
profile.data?.roles.filter(
|
profile.data?.roles.filter(
|
||||||
(row) => row.role === 'Moderator' || row.role === 'Evaluator'
|
(row) => row.role === 'Moderator' || row.role === 'Evaluator'
|
||||||
@@ -210,7 +206,7 @@ const getTabButtons = () => {
|
|||||||
let buttons = [{ label: 'About' }, { label: 'Certificates' }]
|
let buttons = [{ label: 'About' }, { label: 'Certificates' }]
|
||||||
if ($user.data?.is_moderator) buttons.push({ label: 'Roles' })
|
if ($user.data?.is_moderator) buttons.push({ label: 'Roles' })
|
||||||
|
|
||||||
if (hasHigherAccess() && isEvaluatorOrModerator()) {
|
if (hasHigherAccess()) {
|
||||||
buttons.push({ label: 'Slots' })
|
buttons.push({ label: 'Slots' })
|
||||||
buttons.push({ label: 'Schedule' })
|
buttons.push({ label: 'Schedule' })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
</Calendar>
|
</Calendar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Event v-model="showEvent" :event="currentEvent" />
|
<Event v-if="showEvent" v-model="showEvent" :event="currentEvent" />
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Calendar, createListResource, Button } from 'frappe-ui'
|
import { Calendar, createListResource, Button } from 'frappe-ui'
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ import { Play, X, Check, Settings } from 'lucide-vue-next'
|
|||||||
import { sessionStore } from '@/stores/session'
|
import { sessionStore } from '@/stores/session'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { openSettings } from '@/utils'
|
import { openSettings } from '@/utils'
|
||||||
|
import { useSettings } from '@/stores/settings'
|
||||||
|
|
||||||
const user = inject<any>('$user')
|
const user = inject<any>('$user')
|
||||||
const code = ref<string | null>('')
|
const code = ref<string | null>('')
|
||||||
@@ -162,7 +163,8 @@ const errorMessage = ref<string | null>(null)
|
|||||||
const testCaseSection = ref<HTMLElement | null>(null)
|
const testCaseSection = ref<HTMLElement | null>(null)
|
||||||
const testCases = ref<TestCase[]>([])
|
const testCases = ref<TestCase[]>([])
|
||||||
const boilerplate = ref<string>('')
|
const boilerplate = ref<string>('')
|
||||||
const { brand, livecodeURL } = sessionStore()
|
const { brand } = sessionStore()
|
||||||
|
const { livecodeURL } = useSettings()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const fromLesson = ref(false)
|
const fromLesson = ref(false)
|
||||||
const falconURL = ref<string>('https://falcon.frappe.io/')
|
const falconURL = ref<string>('https://falcon.frappe.io/')
|
||||||
|
|||||||
@@ -54,16 +54,6 @@ export const sessionStore = defineStore('lms-session', () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const livecodeURL = createResource({
|
|
||||||
url: 'frappe.client.get_single_value',
|
|
||||||
params: {
|
|
||||||
doctype: 'LMS Settings',
|
|
||||||
field: 'livecode_url',
|
|
||||||
},
|
|
||||||
cache: 'livecodeURL',
|
|
||||||
auto: user.value ? true : false,
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
user,
|
user,
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
@@ -71,6 +61,5 @@ export const sessionStore = defineStore('lms-session', () => {
|
|||||||
logout,
|
logout,
|
||||||
brand,
|
brand,
|
||||||
branding,
|
branding,
|
||||||
livecodeURL,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ export const useSettings = defineStore('settings', () => {
|
|||||||
auto: false,
|
auto: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const livecodeURL = createResource({
|
||||||
|
url: 'lms.lms.api.get_lms_setting',
|
||||||
|
params: { field: 'livecode_url' },
|
||||||
|
auto: true,
|
||||||
|
cache: ['livecodeURL'],
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isSettingsOpen,
|
isSettingsOpen,
|
||||||
activeTab,
|
activeTab,
|
||||||
|
|||||||
@@ -1672,3 +1672,14 @@ def get_pwa_manifest():
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Response(json.dumps(manifest), status=200, content_type="application/manifest+json")
|
return Response(json.dumps(manifest), status=200, content_type="application/manifest+json")
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_profile_details(username):
|
||||||
|
print(username)
|
||||||
|
return frappe.db.get_value(
|
||||||
|
"User",
|
||||||
|
{"username": username},
|
||||||
|
["full_name", "name", "username", "user_image", "bio", "headline", "cover_image"],
|
||||||
|
as_dict=True,
|
||||||
|
)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-07-07 20:37:22.449149",
|
"modified": "2025-11-06 11:38:35.903520",
|
||||||
"modified_by": "sayali@frappe.io",
|
"modified_by": "sayali@frappe.io",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Badge Assignment",
|
"name": "LMS Badge Assignment",
|
||||||
@@ -135,6 +135,30 @@
|
|||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "LMS Student",
|
"role": "LMS Student",
|
||||||
"share": 1
|
"share": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Batch Evaluator",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Course Creator",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"row_format": "Dynamic",
|
"row_format": "Dynamic",
|
||||||
|
|||||||
Reference in New Issue
Block a user