feat: member list
This commit is contained in:
70
frontend/src/components/Members.vue
Normal file
70
frontend/src/components/Members.vue
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<div class="text-base p-4">
|
||||||
|
<div class="font-semibold mb-1">
|
||||||
|
{{ __(label) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-600">
|
||||||
|
{{ __(description) }}
|
||||||
|
</div>
|
||||||
|
<div class="my-4">
|
||||||
|
<div v-for="member in members.data" class="grid grid-cols-5 grid-flow-row py-2">
|
||||||
|
<div class="flex items-center space-x-2 col-span-2">
|
||||||
|
<Avatar :image="member.user_image" :label="member.full_name" size="sm" />
|
||||||
|
<div>
|
||||||
|
{{ member.full_name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-gray-700 col-span-2">
|
||||||
|
{{ member.name }}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-gray-700 justify-self-end">
|
||||||
|
{{ getRole(member.role) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="members.hasNextPage" class="flex justify-center">
|
||||||
|
<Button variant="solid" @click="members.next">
|
||||||
|
<template #prefix>
|
||||||
|
<component
|
||||||
|
:is="icons['RefreshCw']"
|
||||||
|
class="h-3 w-3 stroke-1.5"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
{{ __('Load More') }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { createListResource, Avatar, Button, FormControl } from 'frappe-ui'
|
||||||
|
import * as icons from 'lucide-vue-next'
|
||||||
|
import { computed } from "vue"
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const members = createListResource({
|
||||||
|
url: "lms.lms.api.get_members",
|
||||||
|
doctype: "User",
|
||||||
|
auto: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const getRole = (role) => {
|
||||||
|
const map = {
|
||||||
|
'LMS Student': 'Student',
|
||||||
|
'Course Creator': 'Course Instructor',
|
||||||
|
'Moderator': 'Moderator',
|
||||||
|
'Batch Evaluator': 'Evaluator'
|
||||||
|
}
|
||||||
|
return map[role]
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -28,11 +28,13 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-1 flex-col overflow-y-auto">
|
<div v-if="activeTab && data.doc" class="flex flex-1 flex-col overflow-y-auto">
|
||||||
|
<Members v-if="activeTab.label === 'Members'" :label="activeTab.label" :description="activeTab.description"/>
|
||||||
<SettingDetails
|
<SettingDetails
|
||||||
v-if="activeTab && data.doc"
|
v-else
|
||||||
:fields="activeTab.fields"
|
:fields="activeTab.fields"
|
||||||
:data="data"
|
:data="data"
|
||||||
|
:label="activeTab.label"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,6 +46,7 @@ import { Dialog, createDocumentResource } from 'frappe-ui'
|
|||||||
import { ref, computed, watch } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
import SettingDetails from '../SettingDetails.vue'
|
import SettingDetails from '../SettingDetails.vue'
|
||||||
import SidebarLink from '@/components/SidebarLink.vue'
|
import SidebarLink from '@/components/SidebarLink.vue'
|
||||||
|
import Members from '@/components/Members.vue'
|
||||||
|
|
||||||
const show = defineModel()
|
const show = defineModel()
|
||||||
const doctype = ref('LMS Settings')
|
const doctype = ref('LMS Settings')
|
||||||
@@ -236,17 +239,17 @@ const tabs = computed(() => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
/* {
|
|
||||||
label: 'Settings',
|
|
||||||
hideLabel: true,
|
|
||||||
items: [
|
|
||||||
{
|
{
|
||||||
label: 'Members',
|
label: 'Settings',
|
||||||
icon: "UserRoundPlus",
|
hideLabel: true,
|
||||||
component: markRaw(MemberSettings),
|
items: [
|
||||||
|
{
|
||||||
|
label: 'Members',
|
||||||
|
description: 'Manage the members of your learning system',
|
||||||
|
icon: "UserRoundPlus",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
|
||||||
}, */
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return _tabs.map((tab) => {
|
return _tabs.map((tab) => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col justify-between h-full p-8">
|
<div class="flex flex-col justify-between h-full p-10">
|
||||||
<div class="flex space-x-10">
|
<div class="flex space-x-10">
|
||||||
<div v-for="(column, index) in columns" :key="index">
|
<div v-for="(column, index) in columns" :key="index">
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
|
|||||||
@@ -562,3 +562,27 @@ def get_categories(doctype, filters):
|
|||||||
categoryOptions.append({"label": category, "value": category})
|
categoryOptions.append({"label": category, "value": category})
|
||||||
|
|
||||||
return categoryOptions
|
return categoryOptions
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_members(start=0):
|
||||||
|
members = frappe.get_all("User", filters={
|
||||||
|
"enabled": 1,
|
||||||
|
"name": ["not in", ["Administrator", "Guest"]]
|
||||||
|
}, fields=["name", "full_name", "user_image"],
|
||||||
|
page_length=20, start=start)
|
||||||
|
|
||||||
|
for member in members:
|
||||||
|
roles = frappe.get_roles(member.name)
|
||||||
|
if "Moderator" in roles:
|
||||||
|
member.role = "Moderator"
|
||||||
|
elif "Course Creator" in roles:
|
||||||
|
member.role = "Course Creator"
|
||||||
|
elif "Batch Evaluator" in roles:
|
||||||
|
member.role = "Batch Evaluator"
|
||||||
|
elif "LMS Student" in roles:
|
||||||
|
member.role = "LMS Student"
|
||||||
|
|
||||||
|
return members
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user