bring documentation from old repo and fix Makefile to copy all content of dist folder
This commit is contained in:
parent
88dbd80f85
commit
59ce6e3d99
195
packages/merchant-backoffice-ui/DESIGN.md
Normal file
195
packages/merchant-backoffice-ui/DESIGN.md
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
# Page internal routing
|
||||||
|
|
||||||
|
* The SPA is loaded from the BACKOFFICE_URL
|
||||||
|
|
||||||
|
* The view to be rendered is decided by the URL fragment
|
||||||
|
|
||||||
|
* Query parameters that may affect routing
|
||||||
|
|
||||||
|
- instance: use from the default instance to mimic another instance management
|
||||||
|
|
||||||
|
* The user must provide BACKEND_URL or BACKOFFICE_URL will use as default
|
||||||
|
|
||||||
|
* Token for querying the backend will be saved in localStorage under
|
||||||
|
backend-token-${name}
|
||||||
|
|
||||||
|
# HTTP queries to the backend
|
||||||
|
|
||||||
|
HTTP queries will have 4 states:
|
||||||
|
|
||||||
|
* loading: request did not end yet. data and error are undefined
|
||||||
|
|
||||||
|
* ok: data has information, http response status == 200
|
||||||
|
|
||||||
|
* clientError: http response status is between 400 and 499
|
||||||
|
|
||||||
|
- notfound: http status 404
|
||||||
|
|
||||||
|
- unauthorized: http status 401
|
||||||
|
|
||||||
|
* serverError: http response status is grater than 500
|
||||||
|
|
||||||
|
There are categories of queries:
|
||||||
|
|
||||||
|
* sync: getting information for the page rendering
|
||||||
|
|
||||||
|
* async: performing an CRUD operation
|
||||||
|
|
||||||
|
## Loading the page information (sync)
|
||||||
|
|
||||||
|
In this scenario, a failed request will make the app flow to break.
|
||||||
|
|
||||||
|
When receiving an not found error a generic not found page will be shown. If the
|
||||||
|
BACKEND_URL points to a default instance it should send the user to create the
|
||||||
|
instance.
|
||||||
|
|
||||||
|
When receiving an unauthorized error, the user should be prompted with a login form.
|
||||||
|
|
||||||
|
When receiving an another error (400 < http status < 600), the login form should
|
||||||
|
be shown with an error message using the hint from the backend.
|
||||||
|
|
||||||
|
On other unexpected error (like network error), the login form should be shown
|
||||||
|
with an error message.
|
||||||
|
|
||||||
|
## CRUD operation (async)
|
||||||
|
|
||||||
|
In this scenario, a failed request does not break the flow but a message will be
|
||||||
|
prompted.
|
||||||
|
|
||||||
|
# Forms
|
||||||
|
|
||||||
|
All the input components should be placed in the folder `src/components/from`.
|
||||||
|
|
||||||
|
The core concepts are:
|
||||||
|
|
||||||
|
* <FormProvider<T> /> places instead of <form /> it should be mapped to an
|
||||||
|
object of type T
|
||||||
|
|
||||||
|
* <Input /> an others: defines UI, create <input /> DOM controls and access the
|
||||||
|
form with useField()
|
||||||
|
|
||||||
|
To use it you will need a state somewhere with the object holding all the form
|
||||||
|
information.
|
||||||
|
|
||||||
|
```
|
||||||
|
const [state, setState] = useState({ name: '', age: 11 })
|
||||||
|
```
|
||||||
|
|
||||||
|
Optionally an error object an be built with the error messages
|
||||||
|
|
||||||
|
```
|
||||||
|
const errors = {
|
||||||
|
field1: undefined,
|
||||||
|
field2: 'should be greater than 18',
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
These 3 elements are used to setup the FormProvider
|
||||||
|
|
||||||
|
```
|
||||||
|
<FormProvider errors={errors} object={state} valueHandler={setState}>
|
||||||
|
...inputs
|
||||||
|
</FormProvider>
|
||||||
|
```
|
||||||
|
|
||||||
|
Inputs should handle UI rendering and use `useField(name)` to get:
|
||||||
|
|
||||||
|
* error: the field has been modified and the value is not correct
|
||||||
|
* required: the field need to be corrected
|
||||||
|
* value: the current value of the object
|
||||||
|
* initial: original value before change
|
||||||
|
* onChange: function to update the current field
|
||||||
|
|
||||||
|
Also, every input must be ready to receive these properties
|
||||||
|
|
||||||
|
* name: property of the form object being manipulated
|
||||||
|
* label: how the name of the property will be shown in the UI
|
||||||
|
* placeholder: optional, inplace text when there is no value yet
|
||||||
|
* readonly: default to false, will prevent change the value
|
||||||
|
* help: optional, example text below the input text to help the user
|
||||||
|
* tooltip: optional, will add a (i) with a popup to describe the field
|
||||||
|
|
||||||
|
|
||||||
|
# Custom Hooks
|
||||||
|
|
||||||
|
All the general purpose hooks should be placed in folder `src/hooks` and tests
|
||||||
|
under `tests/hooks`. Starts with the `use` word.
|
||||||
|
|
||||||
|
# Contexts
|
||||||
|
|
||||||
|
All the contexts should be placed in the folder `src/context` as a function.
|
||||||
|
Should expose provider as a component `<XxxContextProvider />` and consumer as a
|
||||||
|
hook function `useXxxContext()` (where XXX is the name)
|
||||||
|
|
||||||
|
# Components
|
||||||
|
|
||||||
|
Type of components:
|
||||||
|
|
||||||
|
* main entry point: src/index.tsx, mostly initialization
|
||||||
|
|
||||||
|
* routing: in the `src` folder, deciding who is going to take the work. That's
|
||||||
|
when the page is loading but also create navigation handlers
|
||||||
|
|
||||||
|
* pages: in the `paths` folder, setup page information (like querying the
|
||||||
|
backend for the list of things), handlers for CRUD events, delegated routing
|
||||||
|
to parent and UI to children.
|
||||||
|
|
||||||
|
Some other guidelines:
|
||||||
|
|
||||||
|
* Hooks over classes are preferred
|
||||||
|
|
||||||
|
* Components that are ready to be reused on any place should be in
|
||||||
|
`src/components` folder
|
||||||
|
|
||||||
|
* Since one of the build targets is a single bundle with all the pages, we are
|
||||||
|
avoiding route based code splitting
|
||||||
|
https://github.com/preactjs/preact-cli#route-based-code-splitting
|
||||||
|
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
|
||||||
|
Every components should have examples using storybook (xxx.stories.tsx). There
|
||||||
|
is an automated test that check that every example can be rendered so we make
|
||||||
|
sure that we do not add a regression.
|
||||||
|
|
||||||
|
Every hook should have examples under `tests/hooks` with common usage trying to
|
||||||
|
follow this structure:
|
||||||
|
|
||||||
|
* (Given) set some context of the initial condition
|
||||||
|
|
||||||
|
* (When) some action to be tested. May be the initialization of a hook or an
|
||||||
|
action associated with it
|
||||||
|
|
||||||
|
* (Then) a particular set of observable consequences should be expected
|
||||||
|
|
||||||
|
# Accessibility
|
||||||
|
|
||||||
|
Pages and components should be built with accessibility in mind.
|
||||||
|
|
||||||
|
https://github.com/nickcolley/jest-axe
|
||||||
|
https://orkhanhuseyn.medium.com/accessibility-testing-in-react-with-jest-axe-e08c2a3f3289
|
||||||
|
http://accesibilidadweb.dlsi.ua.es/?menu=jaws
|
||||||
|
https://webaim.org/projects/screenreadersurvey8/#intro
|
||||||
|
https://www.gov.uk/service-manual/technology/testing-with-assistive-technologies#how-to-test
|
||||||
|
https://es.reactjs.org/docs/accessibility.html
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
|
||||||
|
Every non translated message should be written in English and wrapped into:
|
||||||
|
|
||||||
|
* i18n function from useTranslator() hook
|
||||||
|
* <Translate /> component
|
||||||
|
|
||||||
|
Makefile has a i18n that will parse source files and update the po template.
|
||||||
|
When *.po are updated, running the i18n target will create the strings.ts that
|
||||||
|
the application will use in runtime.
|
||||||
|
|
||||||
|
# Documentation Conventions
|
||||||
|
|
||||||
|
* labels
|
||||||
|
* begin w/ a capital letter
|
||||||
|
* acronyms (e.g., "URL") are upper case
|
||||||
|
* tooltips
|
||||||
|
* begin w/ a lower case letter
|
||||||
|
* do not end w/ punctuation (period)
|
||||||
|
* avoid leading article ("a", "an", "the")
|
@ -11,6 +11,5 @@ spa_dir=$(prefix)/share/taler/merchant-backoffice
|
|||||||
install:
|
install:
|
||||||
pnpm install --frozen-lockfile --filter @gnu-taler/merchant-backoffice...
|
pnpm install --frozen-lockfile --filter @gnu-taler/merchant-backoffice...
|
||||||
pnpm run build
|
pnpm run build
|
||||||
install -d $(spa_dir)
|
(cd dist && find . -type f -exec install -D "{}" "$(spa_dir)/{}" \;)
|
||||||
install ./dist/* $(spa_dir)
|
|
||||||
|
|
||||||
|
64
packages/merchant-backoffice-ui/README.md
Normal file
64
packages/merchant-backoffice-ui/README.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
## Merchant Admin Frontend
|
||||||
|
|
||||||
|
Merchant Admin Frontend is a Single Page Application (SPA) that connects with a running Merchant Backend and lets you manage instances, orders, products and tipping.
|
||||||
|
|
||||||
|
## System requirements
|
||||||
|
|
||||||
|
- Node: v16.15.0
|
||||||
|
- pnpm: 7.14.2
|
||||||
|
- make
|
||||||
|
|
||||||
|
## Compiling from source
|
||||||
|
|
||||||
|
Run `pnpm install --frozen-lockfile --filter @gnu-taler/merchant-backoffice...` to install all the nodejs dependencies.
|
||||||
|
|
||||||
|
Then the command `pnpm build` create the distribution in the `dist` folder.
|
||||||
|
|
||||||
|
By default the installation prefix will be `/usr/local/share/taler/merchant-backoffice/` but it can be overridden by `--prefix` in the configuration process:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./configure --prefix=/another/directory
|
||||||
|
```
|
||||||
|
|
||||||
|
To install run `make install`
|
||||||
|
|
||||||
|
## Running develop
|
||||||
|
|
||||||
|
To run a development server run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./dev.mjs
|
||||||
|
```
|
||||||
|
|
||||||
|
This should start a watch process that will reload the server every time that a file is saved.
|
||||||
|
|
||||||
|
The application need to connect to a merchant-backend properly configured to run.
|
||||||
|
|
||||||
|
## Building for deploy
|
||||||
|
|
||||||
|
To build and deploy the SPA in your local server run the install script:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Runtime dependencies
|
||||||
|
|
||||||
|
* preact: Fast 3kB alternative to React with the same modern API
|
||||||
|
|
||||||
|
* preact-router: URL component router for Preact
|
||||||
|
|
||||||
|
* SWR: React Hooks library for data fetching (stale-while-revalidate)
|
||||||
|
|
||||||
|
* Yup: schema builder for value parsing and validation (to be deprecated)
|
||||||
|
|
||||||
|
* Date-fns: library for manipulating javascript date
|
||||||
|
|
||||||
|
* qrcode-generator: simplest qr implementation based on JIS X 0510:1999
|
||||||
|
|
||||||
|
* @gnu-taler/taler-util: types and tooling
|
||||||
|
|
||||||
|
* history: manage the history stack, navigate, and persist state between sessions
|
||||||
|
|
||||||
|
* jed: gettext like library for internationalization
|
||||||
|
|
Loading…
Reference in New Issue
Block a user