You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: README.md
+5-6
Original file line number
Diff line number
Diff line change
@@ -16,15 +16,14 @@ This library is intended to be included and used within PKP's applications. If y
16
16
# install dependencies
17
17
npm install
18
18
19
-
# serve with hot reload at localhost:8080
20
-
npm run serve
19
+
# serve with hot reload at localhost:6006
20
+
npm run storybook
21
21
```
22
22
23
-
Run the following command to build the library with a base path of `/dev/ui-library/<version>`, so it can be included in [PKP's documentation hub](https://github.com/pkp/pkp-docs).
-[Latest snapshots](https://www.chromatic.com/library?appId=6555d3db80418bb1681b8b17&branch=main) captured via Chromatic service for visual testing of our components and pages
Simple composable to generate API URL. It correctly generates API URL based on currect context (Journal) selected. It does not cover adding query params, as query params are passed separately when making the request with [useFetch](?path=/docs/composables-usefetch--docs).
Most metadata has support for multiple languages. Therefore if there is need to display given metadata based on currently selected locale. `localize` function can be used.
44
+
45
+
It will search for the current locale value. If there's no value for the current locale, it will revert to the primary locale. If there's still no match, it will return the first available value or an empty string.
46
+
47
+
This method mimics the DataObject::getLocalizedData() method from the PHP backend.
OJS/OMP/OPS already have substantial [Rest API interface](https://docs.pkp.sfu.ca/dev/api/ojs/3.4) well covered with documentation.
8
+
9
+
To interact with the API there are handy composables to simplify the process.
10
+
11
+
## Compose URL
12
+
13
+
Once you know which API endpoint you want to interact with, its necessary to create correct API URL based on current context. Use [useApiUrl](?path=/docs/composables-useapiurl--docs) composable to achieve that.
14
+
15
+
## Making HTTP requests
16
+
17
+
To make HTTP request to the API, best is use dedicated [useFetch](?path=/docs/composables-usefetch--docs) or [useFetchPaginated](?path=/docs/composables-usefetchpaginated--docs) composables. Refer to their documentation for examples.
18
+
19
+
For more custom use-cases its possible to use directly underlying [ofetch](https://github.com/unjs/ofetch) package.
In version 3.5 we migrated our ui-library to new Vue3 version, which introduces new [Composition API](https://vuejs.org/guide/introduction.html#composition-api) as more flexible alternative to existing Options API.
8
+
9
+
## Composition API
10
+
11
+
Composition API builds on exactly same principles as the Options API that we are used to from Vue 2. State management still consist of **state** , **computed** properties and **methods** that are updating the **state**. Only the syntax is different.
12
+
13
+
It might take bit getting used to to new syntax, but it will reward us is with significantly better flexibility compared to mixins, which comes very handy in complex application like OJS/OPS/OMP.
14
+
15
+
Best learning source is Vue.js [documentation](https://vuejs.org/guide/introduction.html), where you can easily explore syntax differences between options API and composition API.
16
+
17
+
We follow Vue.js [recommendation](https://vuejs.org/guide/essentials/reactivity-fundamentals#limitations-of-reactive) to use exclusively `ref` to define reactive state and avoiding `reactive` API due its limits.
18
+
19
+
## Composables
20
+
21
+
Composables are replacements for mixins. More details to come about the composables that we provide instead of existing mixins. In general these will be useful to handle all common tasks, like interacting with API, translation or manupulating forms.
22
+
23
+
## How to organise the code
24
+
25
+
Even though it seems that Composition API is lacking organizational structure, it actually gives possibility of organise the code by individual features. Every feature usually consist of some state, computed properties and methods. Good example is `SubmissionsPageStore.js`.
26
+
27
+
Also it should be easy to quickly understand how the Page works when reading the business logic in store. If its too long or/and contains long functions its indication that some of the features should be moved to individual feature composables. These than can be imported to the store and connected with rest of the features in the store. This helps to get good understanding how things works together and its always possible to dive in into details in individual composables if needed.
28
+
29
+
## Refs vs reactive
30
+
31
+
If you want to dive deep and understand all details between using `ref()` vs `reactive()` when creating reactive state in Composable API, you can check out [official documentation](https://vuejs.org/guide/essentials/reactivity-fundamentals) or detailed [blog post](https://mokkapps.de/blog/ref-vs-reactive-what-to-choose-using-vue-3-composition-api).
32
+
33
+
But its not really necessary, as we follow [official recommendation](https://vuejs.org/guide/essentials/reactivity-fundamentals#limitations-of-reactive), which aligns with my personal experience as well, which is just always use `ref()` when defining state..
Copy file name to clipboardexpand all lines: src/docs/guide/PageArchitecture.mdx
+33-5
Original file line number
Diff line number
Diff line change
@@ -6,9 +6,37 @@ import {Meta} from '@storybook/blocks';
6
6
7
7
These principles applies for version 3.5 and higher when building new pages or making significant changes to existing ones.
8
8
9
-
- Using [pinia store](https://pinia.vuejs.org) for state management. Check [vue3 guide](..?path=/docs/guide-vue3--docs#pinia-store) for more details.
10
-
- Page and page related components are located in `src/pages` folder
11
-
- Not using Smarty template for page itself, template is no part of the vue.js page component. Check out [this guide](../?path=/docs/guide-smarty-vs-vue-js--docs) for more details.
12
-
- For styling use TailwindCSS, for more details check out [styling guide](../?path=/docs/guide-style-introduction--docs).
9
+
Since its recent change, we have limited number of examples in our code base. At this point best to follow [Example Page](?path=/docs/pages-example--docs) and [New Submission Page](?path=/docs/pages-submissions--docs). There is more to come soon.
13
10
14
-
Please checkout [Example Page](../?path=/docs/pages-example-examplepage--docs), which provides well documented boilerplate.
11
+
## Folder structure
12
+
13
+
All Page related files are localed in `lib/ui-library/src/pages` folder. Check out [ExamplePage](?path=/docs/pages-example--docs#folder-structure) for per file breakdown.
14
+
15
+
## Page template included in Page component.
16
+
17
+
To [simplify](?path=/docs/guide-technical-roadmap--docs#vuejs--smarty---vuejs-35) the developer experience when creating Pages, we are moving from combination of Smarty and Vue.js to use pure Vue.js components, which have templates as part of the component file.
18
+
19
+
## State management
20
+
21
+
For managing Page business logic we are leveraging Pinia store. Main reason why we want to use Pinia stores instead of just managing state directly in the Page component, is that behind the scene its very extensible and plugin friendly. You can check out more detailed break down in our [Technical Roadmap](?path=/docs/guide-technical-roadmap--docs#pinia-stores-35). General UI components still contains interaction logic directly in component.
22
+
23
+
To understand how the Components should interact with the **Component Pinia Store**, which is our simple extension of the Pinia Store, check out dedicated [page](http://localhost:6006/?path=/docs/guide-pinia-store--docs#component-pinia-store) for Pinia store.
24
+
25
+
### Where to place business logic?
26
+
27
+
-**Page**: Every Page will have its own [Component Pinia Store](?path=/docs/guide-pinia-store--docs#component-pinia-store), where most of the business logic is handled and for simpler Pages that should be good enough.
28
+
-**Complex Modals**: If Page contain Modal(s) that contain substantial functionality, which is reasonably well separable from the rest of the Page, than its good indication that the Modal should have its own Component Store. Good example is `SubmissionSummaryModal.vue`.
29
+
-**Self-Contained Component**: We don't have good example yet of Self-Contained Component, which would have its own Pinia store. But good candidates in general are Components that can be used on multiple places, and their logic can be well separated from the rest of the page. Like managing Submission files in both Submission wizard and Workflow editor.
30
+
31
+
## Server side configuration
32
+
33
+
On initial page load, there is still opportunity to pass JS object from PHP to the Vue.js. Best is to express individual items as props, so it can be easily displayed in storybook and its well documented.
34
+
35
+
This might include things like:
36
+
37
+
- Form structure configuration, as we do configure forms on PHP side
38
+
- Any configuration which needs to be passed just once on page load
39
+
40
+
## Styling
41
+
42
+
For styling use TailwindCSS, for more details check out [styling guide](../?path=/docs/guide-style-introduction--docs).
0 commit comments