From 2348ed8d65a86a27801792cdfddfa91024473715 Mon Sep 17 00:00:00 2001 From: Alex Harding Date: Tue, 23 Jan 2024 09:23:05 -0500 Subject: [PATCH 1/5] adding the options provided to harness to the metadata store --- src/harness.js | 2 +- src/store/harnessStore.js | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/harness.js b/src/harness.js index c47d75c..c7adca9 100644 --- a/src/harness.js +++ b/src/harness.js @@ -8,7 +8,7 @@ const harnessPlugin = { install: (app, options) => { // create harness metadata store in pinia const harness = useHarnessStore(options.pinia); - + harness.optionsProvided = options; // validate page files const validatedPages = pages(options.pages); diff --git a/src/store/harnessStore.js b/src/store/harnessStore.js index 9ee6331..b784fe8 100644 --- a/src/store/harnessStore.js +++ b/src/store/harnessStore.js @@ -1,7 +1,12 @@ import { defineStore } from "pinia"; export default defineStore("harnessVue", { - state: () => ({ pages: [], pageDefinitions: {}, pageStores: {} }), + state: () => ({ + pages: [], + pageDefinitions: {}, + pageStores: {}, + optionsProvided: {}, + }), getters: { getPages() { return this.pages; @@ -12,6 +17,9 @@ export default defineStore("harnessVue", { getPageStores() { return this.pageStores; }, + getOptionsProvided() { + return this.optionsProvided; + }, }, actions: { addStore(key, definition, store) { From d2dbc6afc69ebccfea1ac288a8c2f5fc269cf77b Mon Sep 17 00:00:00 2001 From: Alex Harding Date: Tue, 23 Jan 2024 09:23:18 -0500 Subject: [PATCH 2/5] revising composable to no longer depend on getCurrentInstance --- src/composable/composable.js | 50 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/composable/composable.js b/src/composable/composable.js index 5d9b142..21d88c5 100644 --- a/src/composable/composable.js +++ b/src/composable/composable.js @@ -1,38 +1,38 @@ // https://stackoverflow.com/questions/72209080/vue-3-is-getcurrentinstance-deprecated -import { getCurrentInstance } from "vue"; import { useHarnessStore } from "../harness.js"; -export default function useHarnessComposable() { +/** + * Returns the current harness page store + * If a waypoint is provided, that store is returned + * If the route is provided and the route name matches a harness store key, that store is returned + * If there is no router and only a single harness page exists, that store is returned + * @param {any} waypoint=false a string matching a harness page store key + * @returns {Object} a pinia store representing a harness page + */ +export default function useHarnessComposable(waypoint = false) { const harnessMetadata = useHarnessStore(); - const vueInstance = getCurrentInstance(); + if (waypoint === false) { + let currentRoute = + harnessMetadata.optionsProvided?.router?.currentRoute?.name; - let waypoint = false; + // check for a vue-router route + if (currentRoute && harnessMetadata.getPages.includes(currentRoute)) { + waypoint = currentRoute; + } - // check for a vue-router route - if ( - vueInstance.appContext.config.globalProperties.$route?.name && - harnessMetadata.getPages.includes( - vueInstance.appContext.config.globalProperties.$route.name, - ) - ) { - waypoint = vueInstance.appContext.config.globalProperties.$route.name; + // if router is not installed and only a single harness page exists, use it as waypoint + if (harnessMetadata.getPages.length === 1 && !currentRoute) { + waypoint = harnessMetadata.pages[0]; + } } - // if router is not installed and only a single harness page exists, use it as waypoint if ( - (harnessMetadata.getPages.length === 1) & - !vueInstance.appContext.config.globalProperties.$route + waypoint && + Object.keys(harnessMetadata.getPageStores).includes(waypoint) ) { - waypoint = harnessMetadata.pages[0]; - } - - // // if a waypoint override was specified, use that - if (vueInstance.attrs["harness-waypoint"]) { - waypoint = vueInstance.attrs["harness-waypoint"]; - } - - if (waypoint) { return harnessMetadata.getPageStores[waypoint](); } - return waypoint; + console.error( + `The detected waypoint ${waypoint} is not a valid harness page.`, + ); } From 1b898a5b4ed4dc018a9c6c260ef674ac5e964984 Mon Sep 17 00:00:00 2001 From: Alex Harding Date: Tue, 23 Jan 2024 09:23:32 -0500 Subject: [PATCH 3/5] altering route to allow for developer control over route behaviors --- src/router/route.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/router/route.js b/src/router/route.js index 63f3382..2d18c0f 100644 --- a/src/router/route.js +++ b/src/router/route.js @@ -1,19 +1,21 @@ export default function createHarnessRoute(store, pageDefinition) { return { - path: "/" + pageDefinition.key, - name: pageDefinition.key, + path: `/${pageDefinition?.routePath || pageDefinition.key}`, + name: pageDefinition?.routeName || pageDefinition.key, component: pageDefinition.pageComponent, - props: pageDefinition.pageProps ? pageDefinition.pageProps : false, - beforeEnter: pageDefinition.loadData - ? (to, from, next) => { - if (from.name) { - store.clearData(); - } - if (to.name) { - store.loadData(); - } - next(); + props: pageDefinition?.pageProps, + beforeEnter: (to, from, next) => { + if (pageDefinition?.routeBeforeEnter) { + pageDefinition.routeBeforeEnter(to, from, next, store); + } else { + if (from.name) { + store.clearData(); } - : null, + if (to.name) { + store.loadData(); + } + next(); + } + }, }; } From 7500c94004f3a5dddf9d48c4f35fee3351cc9cf1 Mon Sep 17 00:00:00 2001 From: Alex Harding Date: Tue, 23 Jan 2024 09:41:38 -0500 Subject: [PATCH 4/5] adding routing info to docs --- docs/introduction/getting-started.md | 3 ++- docs/introduction/page-definitions.md | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/introduction/getting-started.md b/docs/introduction/getting-started.md index d6fcefd..16656dc 100644 --- a/docs/introduction/getting-started.md +++ b/docs/introduction/getting-started.md @@ -47,12 +47,13 @@ app.use(harnessPlugin, { pinia, pages, router }) app.use(router); app.mount("#app"); ``` + ## Automagic Page Stores One of the goals of Harness-Vue is the ability to write components that are widely reusable across pages, charts and filters - having an API of helper functions that provide contextualized actions on each page is a convenience feature that allows for more robust and reusable components. In order to assist in that process, Harness-Vue exports a global mixin for the options API and a composable for the composition API that detect what page your component is currently referring to using the following logic: * first by checking if the route name (if vue-router is used) matches the name of an installed page definition * second by checking if there is only one page and no vue-router installed and using that by default - * third by checking for a `harness-waypoint` prop that matches a page definition key + * third by checking for a provided `waypoint` rop that matches a page definition key ### Options API mixin diff --git a/docs/introduction/page-definitions.md b/docs/introduction/page-definitions.md index 76253ee..c99c34e 100644 --- a/docs/introduction/page-definitions.md +++ b/docs/introduction/page-definitions.md @@ -1,4 +1,4 @@ -# Page definitions +# Page Definitions The core unit of the Harness-Vue plugin is the page definition. The page definition is an expected format for developers to provide to the plugin to be translated into Harness Vue pinia stores. @@ -146,10 +146,28 @@ export default class ExamplePage { } } ``` +### Before and After loadData +Similar to the `beforeSet` and `afterSet` functionality in the charts and filters, page definitions can include `beforeLoadData` and `afterLoadData` functions to be run before and after `loadData`, respectively. +## Routing +If a router was provided, a [named route](https://router.vuejs.org/guide/essentials/named-routes.html) will be created for your page definition. This route will be defined using defaults, all of which can be overridden by providing your page definition with select attributes. -## Other -Similar to the `beforeSet` and `afterSet` functionality in the charts and filters, page definitions can include `beforeLoadData` and `afterLoadData` functions to be run before and after `loadData`, respectively. +* The `path` of the route will default to the page key, but can be overridden by providing a `routePath` attribute. Note that this will have a prepended slash automatically. +* The `name` of the route will default to the page key, but can be overridden by providing a `routeName` attribute. +* The route will be provided with a [navigation guard](https://router.vuejs.org/guide/advanced/navigation-guards.html#Per-Route-Guard) using the `beforeEnter` syntax. By default, this will run `clearData()` on route exit and `loadData()` on route enter. This can be overridden by providing your own `routeBeforeEnter(to, from, next, store)` function, which takes the `to`/`from`/`next` arguments from `beforeEnter` and additionally provides the page store. + +```javascript +export default class ExamplePage { + // ... // + routePath = 'dashboards/examplePage' + routeName = 'Example Page' + routeBeforeEnter(to, from, next, store){ + console.log(`Came from ${from.name}`) + store.initializeDefaults() + store.loadData() + } +} +``` ## Full Example From 29bb71b9076d35456fdbb26cb28e530e10fc56f0 Mon Sep 17 00:00:00 2001 From: Alex Harding Date: Tue, 23 Jan 2024 09:42:31 -0500 Subject: [PATCH 5/5] 1.7.0-0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6557be8..a72448f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@rtidatascience/harness-vue", - "version": "1.6.0", + "version": "1.7.0-0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@rtidatascience/harness-vue", - "version": "1.6.0", + "version": "1.7.0-0", "license": "MIT", "dependencies": { "file-saver": "^2.0.5", diff --git a/package.json b/package.json index 3e10dbc..3c4d106 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@rtidatascience/harness-vue", "author": "RTI CDS ", "private": false, - "version": "1.6.0", + "version": "1.7.0-0", "type": "module", "repository": { "type": "git",