diff options
Diffstat (limited to 'front-end/src/bootstrap')
-rw-r--r-- | front-end/src/bootstrap/Environment.vue | 44 | ||||
-rw-r--r-- | front-end/src/bootstrap/components/ConfirmPrompt.vue | 6 | ||||
-rw-r--r-- | front-end/src/bootstrap/components/Footer.vue | 2 | ||||
-rw-r--r-- | front-end/src/bootstrap/components/Header.vue | 26 | ||||
-rw-r--r-- | front-end/src/bootstrap/index.ts | 71 | ||||
-rw-r--r-- | front-end/src/bootstrap/style/modals.scss | 4 |
6 files changed, 50 insertions, 103 deletions
diff --git a/front-end/src/bootstrap/Environment.vue b/front-end/src/bootstrap/Environment.vue index f575529..618ee62 100644 --- a/front-end/src/bootstrap/Environment.vue +++ b/front-end/src/bootstrap/Environment.vue @@ -1,7 +1,4 @@ <template> - <head> - <title>{{ metaTile }}</title> - </head> <div id="env-entry" ref="content" class="absolute top-0 left-0 w-full min-h-screen env-bg"> <div class="absolute flex w-full"> <notifications @@ -20,7 +17,7 @@ /> </div> - <site-header ref="header" :site-title="siteTitle" :routes="routes" > + <site-header ref="header" :routes="routes" @logout="emit('logout')" > <template #site_logo> <!-- Use the global site-logo if enabled --> <site-logo /> @@ -53,54 +50,37 @@ import { computed } from 'vue' import { RouteLocation, useRouter } from 'vue-router' import { filter, map, without, find, includes } from 'lodash-es' -import { useEnvSize, useScrollOnRouteChange, useSession, useTitle } from '@vnuge/vnlib.browser' +import { storeToRefs } from 'pinia' +import { useEnvSize } from '@vnuge/vnlib.browser' +import { useStore } from '../store' import CookieWarning from './components/CookieWarning.vue' import PasswordPrompt from './components/PasswordPrompt.vue' import siteHeader from './components/Header.vue' import siteFooter from './components/Footer.vue' import ConfirmPrompt from './components/ConfirmPrompt.vue' -import { headerRoutes, authRoutes, siteTitle, showCookieWarning } from './index' -const { loggedIn } = useSession(); +const emit = defineEmits(['logout']) +const store = useStore() +const { showCookieWarning, currentRoutes } = storeToRefs(store) const { getRoutes } = useRouter(); -const { title } = useTitle(siteTitle.value); //Use the env size to calculate the header and footer heights for us const { header, footer, content, headerHeight, footerHeight } = useEnvSize(true) -//setup autoscroll -useScrollOnRouteChange(); - -//Compute meta title from the default site title and the page title -const metaTile = computed(() => title.value ? `${title.value} | ${siteTitle.value}` : siteTitle.value) - const routes = computed<RouteLocation[]>(() => { // Get routes that are defined above but only if they are defined in the router // This is a computed property because loggedin is a reactive property - const routeNames = loggedIn.value ? authRoutes.value : headerRoutes.value - const routes = filter(getRoutes(), (pageName) => includes(routeNames, pageName.name)) + const routes = filter(getRoutes(), (pageName) => includes(currentRoutes.value, pageName.name)) - const activeRoutes = map(routeNames, route => find(routes, { name: route })) + const activeRoutes = map(currentRoutes.value, route => find(routes, { name: route })) return without<RouteLocation>(activeRoutes, undefined) }) - //Forces the page content to be exactly the height of the viewport - header and footer sizes -const bodyStyle = computed(() => { - return { 'min-height': `calc(100vh - ${headerHeight.value + footerHeight.value}px)` } -}) +const bodyStyle = computed(() => ({ 'min-height': `calc(100vh - ${headerHeight.value + footerHeight.value}px)` })) +const generalToastStyle = computed(() => ({ top: `${headerHeight.value + 5}px` })) +const formToastStyle = computed(() => ({ top: `${headerHeight.value}px` })) -const generalToastStyle = computed(() => { - return { top: `${headerHeight.value + 5}px` } -}) - -const formToastStyle = computed(() => { - return { top: `${headerHeight.value}px` } -}) </script> - -<style> - -</style> diff --git a/front-end/src/bootstrap/components/ConfirmPrompt.vue b/front-end/src/bootstrap/components/ConfirmPrompt.vue index 78317e0..c67bcfc 100644 --- a/front-end/src/bootstrap/components/ConfirmPrompt.vue +++ b/front-end/src/bootstrap/components/ConfirmPrompt.vue @@ -5,7 +5,7 @@ <div class="modal-content-container"> <DialogPanel> <DialogTitle class="modal-title"> - {{ title }} + {{ message.title ?? 'Confirm' }} </DialogTitle> <DialogDescription class="modal-description"> @@ -55,9 +55,7 @@ const message = ref({}) onClickOutside(dialog, () => isRevealed.value ? cancel() : null) //Set message on reveal -onReveal(m => message.value = m); - -const title = computed(() => defaultTo(message.value.title, 'Confirm')) +onReveal(m => message.value = defaultTo(m, {})); const style = computed(() => { return { diff --git a/front-end/src/bootstrap/components/Footer.vue b/front-end/src/bootstrap/components/Footer.vue index 6af6936..7c306c9 100644 --- a/front-end/src/bootstrap/components/Footer.vue +++ b/front-end/src/bootstrap/components/Footer.vue @@ -17,7 +17,7 @@ <p class="nav-title"> Built with </p> - <a class="footer-link" href="https://www.vaughnnugent.com/resources/software/modules">VNLib HTTP v1.0.1</a> + <a class="footer-link" href="https://www.vaughnnugent.com/resources/software/modules">VNLib HTTP v0.1.0</a> <a class="footer-link" href="https://tailwindcss.com/">Tailwindcss</a> <a class="footer-link" href="https://vuejs.org/">Vuejs v3</a> <a class="footer-link" href="https://fontawesome.com/">Font Awesome</a> diff --git a/front-end/src/bootstrap/components/Header.vue b/front-end/src/bootstrap/components/Header.vue index 8ea2240..43a805b 100644 --- a/front-end/src/bootstrap/components/Header.vue +++ b/front-end/src/bootstrap/components/Header.vue @@ -78,18 +78,21 @@ import { debounce, find } from 'lodash-es' import { useElementSize, onClickOutside, useElementHover } from '@vueuse/core' import { computed, ref, toRefs } from 'vue' -import { useSession, useUser, useEnvSize, apiCall } from '@vnuge/vnlib.browser' +import { useEnvSize } from '@vnuge/vnlib.browser' import { RouteLocation, useRouter } from 'vue-router'; +import { storeToRefs } from 'pinia'; +import { useStore } from '../../store'; +const emit = defineEmits(['logout']) const props = defineProps<{ - siteTitle: string, routes: RouteLocation[] }>() -const { siteTitle, routes } = toRefs(props) +const { routes } = toRefs(props) + +const store = useStore(); +const { loggedIn, siteTitle } = storeToRefs(store); -const { loggedIn } = useSession() -const { userName, logout } = useUser() const { headerHeight } = useEnvSize() //Get the router for navigation @@ -105,7 +108,7 @@ const dropMenuSize = useElementSize(userDrop) const sideMenuSize = useElementSize(sideMenu) const userMenuHovered = useElementHover(userMenu) -const uname = computed(() => userName.value || 'Visitor') +const uname = computed(() => (store as any).userName || 'Visitor') const sideMenuStyle = computed(() => { // Side menu should be the exact height of the page and under the header, // So menu height is the height of the page minus the height of the header @@ -148,15 +151,8 @@ const gotoRoute = (route : string) =>{ } const OnLogout = () =>{ - apiCall(async ({ toaster }) => { - await logout() - toaster.general.success({ - id: 'logout-success', - title: 'Success', - text: 'You have been logged out', - duration: 5000 - }) - }) + //Emit logout event + emit('logout') } </script>
\ No newline at end of file diff --git a/front-end/src/bootstrap/index.ts b/front-end/src/bootstrap/index.ts index ead41e1..343def6 100644 --- a/front-end/src/bootstrap/index.ts +++ b/front-end/src/bootstrap/index.ts @@ -1,47 +1,25 @@ import App from '../App.vue' import Notifications, { notify } from '@kyvg/vue3-notification' import { configureNotifier } from '@vnuge/vnlib.browser' -import { createApp as vueCreateApp, ref } from "vue"; +import { CreateAppFunction, createApp as vueCreateApp } from "vue"; import { useDark } from "@vueuse/core"; +import { createPinia, type Pinia } from "pinia"; //Font awesome support import { Library } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { faBars, faLightbulb, faTimes } from '@fortawesome/free-solid-svg-icons' - -//Required global state elements for app components -export const headerRoutes = ref<string[]>([]); -export const authRoutes = ref<string[]>([]); -export const siteTitle = ref<string>(""); -export const showCookieWarning = ref<boolean>(false); - - export interface AppConfig { /** - * Routes to be displayed in the header when the user is not logged in - */ - headerRoutes: string[]; - - /** - * Routes to be displayed in the header when the user is logged in - */ - authRoutes: string[]; - - /** - * The title of the site, used in the title bar - */ - siteTitle: string; - - /** * Enables dark mode support */ - useDarkMode: boolean; + useDarkMode?: boolean; /** * The element to mount the app to */ - mountElement: string; + mountElement: string | Element; /** * library instance for adding required icons @@ -49,16 +27,19 @@ export interface AppConfig { faLibrary: Library; /** - * If true, the cookie warning will not be displayed + * Called when the app is created for you to add custom elements + * and configure the app + * @param app The app instance + * @param store The pinia store instance */ - hideCookieWarning?: boolean; + onCreate(app: any, piniaStore: Pinia): void; /** - * Called when the app is created for you to add custom elements - * and configure the app + * Allows the user to override the createApp function * @param app The app instance + * @returns The app instance */ - onCreate: (app: any) => void; + createApp?: CreateAppFunction<Element> } /** @@ -66,13 +47,12 @@ export interface AppConfig { * @param config The configuration for the app * @returns The app instance */ -export const createVnApp = (config: AppConfig, createApp?: (app: any) => any) => { - headerRoutes.value = config.headerRoutes; - authRoutes.value = config.authRoutes; - siteTitle.value = config.siteTitle; +export const createVnApp = (config: AppConfig) => { + + const store = createPinia(); //Allow the user to override the createApp function - createApp = createApp || vueCreateApp; + config.createApp ??= vueCreateApp; //Enable dark mode support if (config.useDarkMode) { @@ -83,25 +63,18 @@ export const createVnApp = (config: AppConfig, createApp?: (app: any) => any) => }); } - if (!config.hideCookieWarning) { - //Configure the cookie warning to be displayed cookies are not enabled - showCookieWarning.value = navigator?.cookieEnabled === false; - } - //Add required icons to library config.faLibrary.add(faBars, faLightbulb, faTimes); //create the vue app - const app = createApp(App) - - //Add the library to the app - app.component('fa-icon', FontAwesomeIcon) - - //Add the notification and router to the app - app.use(Notifications); + const app = config.createApp(App) + + app.use(Notifications) //Add the notification component to the app + .use(store) //Add pinia to the app + .component('fa-icon', FontAwesomeIcon) //Add the font awesome icon component to the app //Call the onCreate callback - config.onCreate(app); + config.onCreate(app, store); //Mount the app app.mount(config.mountElement); diff --git a/front-end/src/bootstrap/style/modals.scss b/front-end/src/bootstrap/style/modals.scss index 254b8e1..b868406 100644 --- a/front-end/src/bootstrap/style/modals.scss +++ b/front-end/src/bootstrap/style/modals.scss @@ -3,8 +3,8 @@ @apply fixed z-50 flex w-full px-6; .modal-content-container { - @apply w-full max-w-md p-5 m-auto rounded-md shadow-2xl mt-44; - @apply bg-white border border-transparent dark:bg-dark-600 dark:border-primary-500 dark:text-white; + @apply w-full max-w-md p-5 m-auto rounded shadow-2xl mt-44; + @apply bg-white border border-transparent dark:bg-dark-700 dark:border-dark-300 dark:text-white; .modal-title { @apply text-xl font-bold; |