diff --git a/cypress/e2e/course_creation.cy.js b/cypress/e2e/course_creation.cy.js index 3e28b0a5..8d6f60f0 100644 --- a/cypress/e2e/course_creation.cy.js +++ b/cypress/e2e/course_creation.cy.js @@ -31,12 +31,35 @@ describe("Course Creation", () => { .contains("Preview Video") .type("https://www.youtube.com/embed/-LPmw2Znl2c"); cy.get("[id=tags]").type("Learning{enter}Frappe{enter}ERPNext{enter}"); - cy.get(".search-input").click().type("frappe"); - cy.wait(1000); + cy.get("label") + .contains("Category") + .parent() + .within(() => { + cy.get("button").click(); + }); cy.get("[id^=headlessui-combobox-option-") .should("be.visible") .first() .click(); + + /* Instructor */ + cy.get("label") + .contains("Instructors") + .parent() + .within(() => { + cy.get("input").click().type("frappe"); + cy.get("input") + .invoke("attr", "aria-controls") + .as("instructor_list_id"); + }); + cy.get("@instructor_list_id").then((instructor_list_id) => { + cy.get(`[id^=${instructor_list_id}`) + .should("be.visible") + .within(() => { + cy.get("[id^=headlessui-combobox-option-").first().click(); + }); + }); + cy.get("label").contains("Published").click(); cy.get("label").contains("Published On").type("2021-01-01"); cy.button("Save").click(); diff --git a/frontend/src/components/Categories.vue b/frontend/src/components/Categories.vue new file mode 100644 index 00000000..20f9561e --- /dev/null +++ b/frontend/src/components/Categories.vue @@ -0,0 +1,151 @@ + + + diff --git a/frontend/src/components/Modals/Settings.vue b/frontend/src/components/Modals/Settings.vue index 97af32c8..843c945c 100644 --- a/frontend/src/components/Modals/Settings.vue +++ b/frontend/src/components/Modals/Settings.vue @@ -6,7 +6,7 @@

{{ __('Settings') }}

-
+
+ import { Dialog, createDocumentResource } from 'frappe-ui' import { ref, computed, watch } from 'vue' +import { useSettings } from '@/stores/settings' import SettingDetails from '../SettingDetails.vue' import SidebarLink from '@/components/SidebarLink.vue' import Members from '@/components/Members.vue' +import Categories from '@/components/Categories.vue' const show = defineModel() const doctype = ref('LMS Settings') const activeTab = ref(null) +const settingsStore = useSettings() const data = createDocumentResource({ doctype: doctype.value, @@ -69,8 +79,8 @@ const data = createDocumentResource({ auto: true, }) -const tabs = computed(() => { - let _tabs = [ +const tabsStructure = computed(() => { + return [ { label: 'Settings', hideLabel: true, @@ -80,6 +90,23 @@ const tabs = computed(() => { description: 'Manage the members of your learning system', icon: 'UserRoundPlus', }, + ], + }, + { + label: 'Settings', + hideLabel: true, + items: [ + { + label: 'Categories', + description: 'Manage the members of your learning system', + icon: 'Network', + }, + ], + }, + { + label: 'Settings', + hideLabel: true, + items: [ { label: 'Payment Gateway', icon: 'DollarSign', @@ -125,8 +152,8 @@ const tabs = computed(() => { ], }, { - label: 'Settings', - hideLabel: true, + label: 'Customise', + hideLabel: false, items: [ { label: 'Sidebar', @@ -168,12 +195,6 @@ const tabs = computed(() => { }, ], }, - ], - }, - { - label: 'Settings', - hideLabel: true, - items: [ { label: 'Email Templates', icon: 'MailPlus', @@ -199,12 +220,6 @@ const tabs = computed(() => { }, ], }, - ], - }, - { - label: 'Settings', - hideLabel: true, - items: [ { label: 'Signup', icon: 'LogIn', @@ -226,23 +241,28 @@ const tabs = computed(() => { ], }, ] +}) - return _tabs.map((tab) => { - tab.items = tab.items.filter((item) => { - if (item.condition) { - return item.condition() - } - return true - }) - return tab +const tabs = computed(() => { + return tabsStructure.value.map((tab) => { + return { + ...tab, + items: tab.items.filter((item) => { + return !item.condition || item.condition() + }), + } }) }) -watch(show, () => { +watch(show, async () => { if (show.value) { - activeTab.value = tabs.value[0].items[0] + const currentTab = await tabs.value + .flatMap((tab) => tab.items) + .find((item) => item.label === settingsStore.activeTab) + activeTab.value = currentTab || tabs.value[0].items[0] } else { activeTab.value = null + settingsStore.isSettingsOpen = false } }) diff --git a/frontend/src/components/UserDropdown.vue b/frontend/src/components/UserDropdown.vue index 348e7918..5071513d 100644 --- a/frontend/src/components/UserDropdown.vue +++ b/frontend/src/components/UserDropdown.vue @@ -67,25 +67,20 @@ import LMSLogo from '@/components/Icons/LMSLogo.vue' import { sessionStore } from '@/stores/session' import { Dropdown } from 'frappe-ui' import Apps from '@/components/Apps.vue' -import { - ChevronDown, - LogIn, - LogOut, - User, - ArrowRightLeft, - Settings, -} from 'lucide-vue-next' +import { ChevronDown, LogIn, LogOut, User, Settings } from 'lucide-vue-next' import { useRouter } from 'vue-router' import { convertToTitleCase } from '../utils' import { usersStore } from '@/stores/user' -import { ref, markRaw } from 'vue' +import { useSettings } from '@/stores/settings' +import { markRaw, watch, ref } from 'vue' import SettingsModal from '@/components/Modals/Settings.vue' const router = useRouter() -const showSettingsModal = ref(false) const { logout, branding } = sessionStore() let { userResource } = usersStore() +const settingsStore = useSettings() let { isLoggedIn } = sessionStore() +const showSettingsModal = ref(false) const props = defineProps({ isCollapsed: { @@ -94,6 +89,13 @@ const props = defineProps({ }, }) +watch( + () => settingsStore.isSettingsOpen, + (value) => { + showSettingsModal.value = value + } +) + const userDropdownOptions = [ { icon: User, @@ -118,7 +120,7 @@ const userDropdownOptions = [ icon: Settings, label: 'Settings', onClick: () => { - showSettingsModal.value = true + settingsStore.isSettingsOpen = true }, condition: () => { return userResource.data?.is_moderator diff --git a/frontend/src/pages/Batches.vue b/frontend/src/pages/Batches.vue index 77e73c5d..26d3892f 100644 --- a/frontend/src/pages/Batches.vue +++ b/frontend/src/pages/Batches.vue @@ -8,12 +8,12 @@ :items="[{ label: __('Batches'), route: { name: 'Batches' } }]" />
-
+