Skip to content

Commit

Permalink
docs: added some pages
Browse files Browse the repository at this point in the history
  • Loading branch information
mle-moni committed Jun 2, 2024
1 parent f9f1e44 commit e6440f9
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/**/*.mdx
5 changes: 5 additions & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export default defineConfig({
path: '/reference/views',
autogenerate: { directory: 'reference/views', collapsed: true },
},
{
label: 'Frontend',
path: '/reference/frontend',
autogenerate: { directory: 'reference/frontend', collapsed: true },
},
],
},
],
Expand Down
132 changes: 132 additions & 0 deletions docs/src/content/docs/guides/frontend-deployment.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
title: 'Frontend Deployment'
description: How to deploy Adomin frontend
sidebar:
order: 4
---

To deploy the Adomin frontend, you will need to:

- run `yarn build` with correct VITE_API_URL env variable set
- copy dist folder to your static files service
- serve those files with a rule for SPAs (e.g. serving the index.html on 404)

## S3 / Cloudfront

```fish
# copy dist files into your s3 bucket
aws s3 sync ./dist s3://your-s3-bucket-name/
# invalidate cloudfront distribution to serve the new files
aws cloudfront create-invalidation --distribution-id YOUR_DISTRIB_ID --paths "/*"
```

### Github action for S3 / Cloudfront

```yml
name: Deploy staging ⚙️
on:
push:
branches:
- does-not-exist # replace by e.g: staging

jobs:
back-office:
runs-on: ubuntu-latest
env:
VITE_API_URL: https://api.staging.your-own-domain.fr/ # replace by your API url
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: yarn
- name: Build
run: yarn build
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
# you will have to create AWS_ACCESS_KEY and AWS_SECRET_KEY secrets in your repository settings
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: eu-west-3
- name: Deploy
run: aws s3 sync ./dist s3://your-s3-bucket-name/ # replace by your s3 bucket name
- name: Invalidate dashboard cloudfront
run: aws cloudfront create-invalidation --distribution-id YOUR_DISTRIB_ID --paths "/*" # replace by your cloudfront distribution id
```
## Caddy
Example of Caddy config to serve a SPA
```
example.com {
root * /usr/share/caddy/frontend
file_server
try_files {path} {path}/ /index.html
}
```

### Github action for Caddy

:::note
This github action is taken from a project that uses [Galacrypt](https://github.com/galadrimteam/galacrypt) to encrypt/decrypt the env file
:::

```yml
name: Deploy staging ⚙️
on:
push:
branches:
- does-not-exist # replace by e.g: staging

jobs:
frontend:
runs-on: ubuntu-latest
env:
VITE_API_URL: https://api.staging.your-own-domain.fr/ # replace by your API url
SERVER_IP: 1.2.3.4 # replace by your server IP
KEY_PATH: ./ssh_keys/staging/id_ed25519 # do not commit/push this file directly
SSH_USER: YOUR_SSH_USER # replace by your ssh user
SSH_PARAMS: -i ./ssh_keys/staging/id_ed25519 [email protected] # replace dummy user / ip

steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'yarn'

- name: Dependencies installation
run: yarn

- name: Galacrypt decrypt # used to decrypt ssh key, you will have to create GALACRYPT_KEY in your repository secrets
run: yarn galacrypt use ${{ secrets.GALACRYPT_KEY }} && yarn galacrypt decrypt

- name: Generate build
run: yarn build

- name: Generate frontend zip
run: cd dist && zip -r ../frontend.zip .

- name: Setup SSH
run: |
mkdir -p ~/.ssh
ssh-keyscan $SERVER_IP 2>/dev/null > ~/.ssh/known_hosts
chmod 600 $KEY_PATH
- name: Copy files
run: scp -i $KEY_PATH ./frontend.zip $SSH_USER@$SERVER_IP:/home/$SSH_USER/frontend.zip

- name: Unzip
run: ssh $SSH_PARAMS "cd /home/$SSH_USER/ && rm -rf front-build && mkdir front-build && mv frontend.zip front-build/ && cd front-build && unzip frontend.zip && rm frontend.zip"

- name: Move website files
run: ssh $SSH_PARAMS "cd /home/$SSH_USER/ && (sudo mv /usr/share/caddy/frontend old_frontend || echo 'skipping mv old_frontend') && sudo mv front-build /usr/share/caddy/frontend && sudo rm -rf old_frontend"
```
## Nginx
I don't want to deal with nginx anymore, but if you want to, you can find inspiration [here](https://sdickinson.com/nginx-config-for-single-page-applications/)
2 changes: 1 addition & 1 deletion docs/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { Card, CardGrid, LinkCard } from "@astrojs/starlight/components";
</Card>

<Card title="Sidebar" icon="seti:image">
- icons from tabler icons
- icons from [tabler icons](https://tabler.io/icons)
- folders and subfolders (with no limit)
</Card>

Expand Down
134 changes: 134 additions & 0 deletions docs/src/content/docs/reference/frontend/routing.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: Frontend Routing
description: Adomin frontend routing reference
sidebar:
order: 0
---

You might have some questions:

- how does the frontend routing work ?
- how to add custom routes ?

## Router file

It all begins with the **react-router-dom** router

import { FileTree } from '@astrojs/starlight/components'

<FileTree>
- src
- [router.tsx](https://github.com/galadrimteam/adomin-frontend/blob/main/src/router.tsx) Frontend react-router-dom router
</FileTree>

Inside this file is all the routing

If this documentation is up to date 😳, it will look like this:

```tsx
export const adominRoutes = createBrowserRouter([
{
path: '/',
element: <Navigate to={ADOMIN_HOME_PATH} />,
},
{
path: ADOMIN_HOME_PATH,
element: <Navigate to={ADOMIN_FOLDERS_PATH} />,
},
{
path: ADOMIN_FOLDERS_PATH,
children: [
{
path: ':view',
element: <FoldersPage />,
},
],
element: <HomePage />,
},
{
path: ADOMIN_STATS_PATH,
children: [
{
path: ':view',
element: <StatsPage />,
},
],
element: <HomePage />,
},
{
path: ADOMIN_MODELS_PATH,
children: [
{
path: ':view',
children: [
{ index: true, element: <ModelListPage /> },
{ path: 'create', element: <CreateModelPage /> },
{ path: ':primaryKeyValue', element: <EditModelPage /> },
],
element: <ModelsPageLayout />,
},
],
element: <HomePage />,
},
{
path: ADOMIN_LOGIN_PATH,
element: <LoginPage />,
},
])
```

You can see that it is creating dynamic paths, those paths will be determined with your backend adomin config.

To be clear, if you do not change the `ADOMIN_*_PATH` variables, the following paths are created:

```bash
/ # this path just redirects to /adomin, you can customize/remove this behaviour if you don't like it
/login

/backoffice/folders/:view # this dynamic path renders a folder view, which will redirect you to the nearest non-folder view
/backoffice/stats/:view # this dynamic path renders a stat view

/backoffice # this path adds a layout around the children of this route
/backoffice/:model # this is the list page
/backoffice/:model/create # this is the create page
/backoffice/:model/:primaryKeyValue # this is the update page
```

and here is an example if you configured adomin with the User model

```bash
/backoffice/User
/backoffice/User/create
/backoffice/User/1 # page to update user with id = 1
```

## Custom routes and overrides

If you want to override some page, let's say the create and the update page for your resource User, you will be able to do so by using the `makeOverridePage` helper, then put it somewhere in the router config, here is an example:

```tsx
export const adominRoutes = createBrowserRouter([
// default adomin config
// ...

// your config
makeOverridePage({ model: 'User', type: 'create' }, <MyOverridePage />),
makeOverridePage({ model: 'User', type: 'update' }, <MyOverridePage2 />),
makeOverridePage({ model: 'User', type: 'list' }, <MyOverridePage3 />),
])
```

:::note
💡 the `makeOverridePage` helper just creates a `RouteObject` wrapping the override component with a `CustomPage`, you can do it manually if you want more control:

```tsx
{
path: "/backoffice/User/create",
element:
<CustomPage currentView="User">
<MyOverridePage />
</CustomPage>,
}
```

:::

0 comments on commit e6440f9

Please sign in to comment.