How Can Switch To Desk From Student-Portal

How can go to LMS or home page ?

is there is way to get portal from desk ? or i should write /student-portal at the end of link every time ?!

For that case, you can add the URL shortcut and set it in the workspace.

Example:

1 Like

If there is not other easy way, then explore files:

Sidebar.vue and SidebarLink.vue from folder education/frontend/src/components and add URL / Links as appropraite.

Then rebuild frontend, clear cache and restart bench.

Code of Sidebar.vue:

<template>
  <div
    class="flex h-full flex-col justify-between transition-all duration-300 ease-in-out"
    :class="isSidebarCollapsed ? 'w-12' : 'w-56'"
  >
    <div class="flex flex-col overflow-hidden">
      <UserDropdown 
        class="p-2"  
        :isCollapsed="isSidebarCollapsed" 
        :educationSettings="!educationSettings.loading && educationSettings.data"
      />
      <div class="flex flex-col overflow-y-auto">
        <SidebarLink
          :label="link.label"
          :to="link.to"
          v-for="link in links"
          :isCollapsed="isSidebarCollapsed"
          :icon="link.icon"
          class="mx-2 my-0.5"
        />
      </div>
    </div>
    <SidebarLink
      :label="isSidebarCollapsed ? 'Expand' : 'Collapse'"
      :isCollapsed="isSidebarCollapsed"
      @click="isSidebarCollapsed = !isSidebarCollapsed"
      class="m-2"
    >
      <template #icon>
        <span class="grid h-5 w-6 flex-shrink-0 place-items-center">
          <ArrowLeftToLine
            class="h-4.5 w-4.5 text-gray-700 duration-300 ease-in-out"
            :class="{ '[transform:rotateY(180deg)]': isSidebarCollapsed }"
          />
        </span>
      </template>
    </SidebarLink>
  </div>
</template>

<script setup>
import { useStorage } from '@vueuse/core'
import SidebarLink from '@/components/SidebarLink.vue'
import { LayoutDashboard, CalendarCheck, GraduationCap, Banknote, UserCheck, ArrowLeftToLine, BookOpen } from 'lucide-vue-next'
import UserDropdown from './UserDropdown.vue'
import { createResource } from 'frappe-ui'

const links = [
  {
    label: 'Desk',
    to: '../../app',  // Corrected relative path for the internal route
    icon: LayoutDashboard,
  },
  {
    label: 'Schedule',
    to: '/schedule',
    icon: CalendarCheck,
  },
  {
    label: 'Grades',
    to: '/grades',
    icon: GraduationCap,
  },
  {
    label: 'Fees',
    to: '/fees',
    icon: Banknote,
  },
  {
    label: 'Attendance',
    to: '/attendance',
    icon: UserCheck,
  },
  {
    label: 'Google Search',
    to: 'https://google.com',  // External link
    icon: BookOpen,
  },
]

const isSidebarCollapsed = useStorage('sidebar_is_collapsed', false)

// create a resource which call the function get_school_abbr_logo in api file using createResource
const educationSettings = createResource({
  url: 'education.education.api.get_school_abbr_logo',
  auto: true,
})

</script>

Code of SidebarLink.vue

<template>
  <button
    class="flex h-7 cursor-pointer items-center rounded text-gray-800 duration-300 ease-in-out focus:outline-none focus:transition-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-gray-400"
    :class="isActive ? 'bg-white shadow-sm' : 'hover:bg-gray-100'"
    @click="handleClick"
  >
    <div
      class="flex items-center duration-300 ease-in-out"
      :class="isCollapsed ? 'p-1' : 'px-2 py-1'"
    >
      <Tooltip :text="label" placement="right">
        <slot name="icon">
          <span class="grid h-5 w-6 flex-shrink-0 place-items-center">
            <component :is="icon" class="h-4.5 w-4.5 text-gray-700" />
          </span>
        </slot>
      </Tooltip>
      <span
        class="flex-shrink-0 text-base duration-300 ease-in-out"
        :class="
          isCollapsed
            ? 'ml-0 w-0 overflow-hidden opacity-0'
            : 'ml-2 w-auto opacity-100'
        "
      >
        {{ label }}
      </span>
    </div>
  </button>
</template>

<script setup>
import { Tooltip } from 'frappe-ui'
import { computed } from 'vue'
import { useRouter } from 'vue-router'

const router = useRouter()
const props = defineProps({
  icon: {
    type: Function,
  },
  label: {
    type: String,
    default: '',
  },
  to: {
    type: String,
    default: '',
  },
  isCollapsed: {
    type: Boolean,
    default: false,
  },
})

function handleClick() {
  if (props.to.startsWith('http')) {
    // External link
    window.open(props.to, '_blank')
  } else if (props.to.startsWith('/')) {
    // Internal link handled by Vue Router
    router.push(props.to).catch(err => {
      console.error('Failed to navigate:', err)
    })
  } else {
    // Internal link not handled by Vue Router (relative)
    window.location.href = props.to
  }
}

let isActive = computed(() => {
  return router.currentRoute.value.path === props.to
})

</script>