0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-03 21:48:55 -05:00

refactor(console): support explicit tutorial order (#4404)

This commit is contained in:
Gao Sun 2023-08-29 16:01:35 +08:00 committed by GitHub
parent 2a8a5ede70
commit c5bf1d7171
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 189 additions and 86 deletions

View file

@ -55,3 +55,20 @@ Images and other assets (if any) should be placed in the `assets` directory of t
Since Parcel doesn't support dynamic import (see [#112](https://github.com/parcel-bundler/parcel/issues/112) [#125](https://github.com/parcel-bundler/parcel/issues/125)), we need to run `node generate-metadata.js` to update the metadata in `index.ts`, thus we can use it in the guide components with React lazy loading.
This may be fixed by replacing Parcel with something else.
### Order guides
The guides are ordered by the following rules in ascending order:
1. The first segment of the directory name, which should be the target of the guide;
2. The `order` property of the guide.
You can configure the property by creating a `config.json` file in the guide directory. The file should be an object with the following structure:
```json
{
"order": 1
}
```
If no `config.json` file is found, the guide will be placed at the end of the list.

View file

@ -8,8 +8,8 @@ import fs from 'node:fs/promises';
const entries = await fs.readdir('.');
const directories = entries.filter((entry) => !entry.includes('.'));
const metadata = directories
.map((directory) => {
const data = await Promise.all(
directories.map(async (directory) => {
if (!existsSync(`${directory}/README.mdx`)) {
console.warn(`No README.mdx file found in ${directory} directory, skipping.`);
return;
@ -23,12 +23,24 @@ const metadata = directories
// Add `.png` later
const logo = ['logo.svg'].find((logo) => existsSync(`${directory}/${logo}`));
const config = existsSync(`${directory}/config.json`)
? await import(`./${directory}/config.json`, { assert: { type: 'json' } }).then((module) => module.default)
: undefined;
return {
name: directory,
logo,
order: config?.order ?? Number.POSITIVE_INFINITY,
};
})
.filter(Boolean);
);
const metadata = data.filter(Boolean).slice().sort((a, b) => {
if (a.name.split('-')[0] !== b.name.split('-')[0]) {
return a.name.localeCompare(b.name);
}
return a.order - b.order;
});
const camelCase = (value) => value.replaceAll(/-./g, (x) => x[1].toUpperCase());
const filename = 'index.ts';
@ -46,12 +58,13 @@ for (const { name } of metadata) {
await fs.appendFile(filename, '\n');
await fs.appendFile(filename, 'const guides: Readonly<Guide[]> = Object.freeze([');
for (const { name, logo } of metadata) {
for (const { name, logo, order } of metadata) {
// eslint-disable-next-line no-await-in-loop
await fs.appendFile(
filename,
`
{
order: ${order},
id: '${name}',
Logo: ${logo ? `lazy(async () => import('./${name}/${logo}'))` : 'undefined'},
Component: lazy(async () => import('./${name}/README.mdx')),

View file

@ -25,118 +25,137 @@ import webRemix from './web-remix/index';
const guides: Readonly<Guide[]> = Object.freeze([
{
id: 'web-next',
Logo: lazy(async () => import('./web-next/logo.svg')),
Component: lazy(async () => import('./web-next/README.mdx')),
metadata: webNext,
},
{
id: 'web-next-app-router',
Logo: lazy(async () => import('./web-next-app-router/logo.svg')),
Component: lazy(async () => import('./web-next-app-router/README.mdx')),
metadata: webNextAppRouter,
},
{
id: 'web-express',
Logo: lazy(async () => import('./web-express/logo.svg')),
Component: lazy(async () => import('./web-express/README.mdx')),
metadata: webExpress,
},
{
id: 'web-go',
Logo: lazy(async () => import('./web-go/logo.svg')),
Component: lazy(async () => import('./web-go/README.mdx')),
metadata: webGo,
},
{
id: 'web-php',
Logo: lazy(async () => import('./web-php/logo.svg')),
Component: lazy(async () => import('./web-php/README.mdx')),
metadata: webPhp,
},
{
id: 'web-python',
Logo: lazy(async () => import('./web-python/logo.svg')),
Component: lazy(async () => import('./web-python/README.mdx')),
metadata: webPython,
},
{
id: 'web-remix',
Logo: lazy(async () => import('./web-remix/logo.svg')),
Component: lazy(async () => import('./web-remix/README.mdx')),
metadata: webRemix,
},
{
id: 'web-asp-net-core',
Logo: lazy(async () => import('./web-asp-net-core/logo.svg')),
Component: lazy(async () => import('./web-asp-net-core/README.mdx')),
metadata: webAspNetCore,
},
{
id: 'web-outline',
Logo: lazy(async () => import('./web-outline/logo.svg')),
Component: lazy(async () => import('./web-outline/README.mdx')),
metadata: webOutline,
},
{
id: 'spa-react',
Logo: lazy(async () => import('./spa-react/logo.svg')),
Component: lazy(async () => import('./spa-react/README.mdx')),
metadata: spaReact,
},
{
order: Number.POSITIVE_INFINITY,
id: 'm2m-general',
Logo: lazy(async () => import('./m2m-general/logo.svg')),
Component: lazy(async () => import('./m2m-general/README.mdx')),
metadata: m2mGeneral,
},
{
id: 'web-gpt-plugin',
Logo: lazy(async () => import('./web-gpt-plugin/logo.svg')),
Component: lazy(async () => import('./web-gpt-plugin/README.mdx')),
metadata: webGptPlugin,
},
{
id: 'spa-vue',
Logo: lazy(async () => import('./spa-vue/logo.svg')),
Component: lazy(async () => import('./spa-vue/README.mdx')),
metadata: spaVue,
},
{
id: 'spa-vanilla',
Logo: lazy(async () => import('./spa-vanilla/logo.svg')),
Component: lazy(async () => import('./spa-vanilla/README.mdx')),
metadata: spaVanilla,
},
{
order: 1,
id: 'native-ios-swift',
Logo: lazy(async () => import('./native-ios-swift/logo.svg')),
Component: lazy(async () => import('./native-ios-swift/README.mdx')),
metadata: nativeIosSwift,
},
{
order: 2,
id: 'native-android-java',
Logo: lazy(async () => import('./native-android-java/logo.svg')),
Component: lazy(async () => import('./native-android-java/README.mdx')),
metadata: nativeAndroidJava,
},
{
order: 2.1,
id: 'native-android-kt',
Logo: lazy(async () => import('./native-android-kt/logo.svg')),
Component: lazy(async () => import('./native-android-kt/README.mdx')),
metadata: nativeAndroidKt,
},
{
order: 3,
id: 'native-flutter',
Logo: lazy(async () => import('./native-flutter/logo.svg')),
Component: lazy(async () => import('./native-flutter/README.mdx')),
metadata: nativeFlutter,
},
{
order: 4,
id: 'native-capacitor',
Logo: lazy(async () => import('./native-capacitor/logo.svg')),
Component: lazy(async () => import('./native-capacitor/README.mdx')),
metadata: nativeCapacitor,
},
{
id: 'native-flutter',
Logo: lazy(async () => import('./native-flutter/logo.svg')),
Component: lazy(async () => import('./native-flutter/README.mdx')),
metadata: nativeFlutter,
order: 1,
id: 'spa-react',
Logo: lazy(async () => import('./spa-react/logo.svg')),
Component: lazy(async () => import('./spa-react/README.mdx')),
metadata: spaReact,
},
{
order: 2,
id: 'spa-vue',
Logo: lazy(async () => import('./spa-vue/logo.svg')),
Component: lazy(async () => import('./spa-vue/README.mdx')),
metadata: spaVue,
},
{
order: 3,
id: 'spa-vanilla',
Logo: lazy(async () => import('./spa-vanilla/logo.svg')),
Component: lazy(async () => import('./spa-vanilla/README.mdx')),
metadata: spaVanilla,
},
{
order: 1,
id: 'web-next',
Logo: lazy(async () => import('./web-next/logo.svg')),
Component: lazy(async () => import('./web-next/README.mdx')),
metadata: webNext,
},
{
order: 1.1,
id: 'web-next-app-router',
Logo: lazy(async () => import('./web-next-app-router/logo.svg')),
Component: lazy(async () => import('./web-next-app-router/README.mdx')),
metadata: webNextAppRouter,
},
{
order: 2,
id: 'web-express',
Logo: lazy(async () => import('./web-express/logo.svg')),
Component: lazy(async () => import('./web-express/README.mdx')),
metadata: webExpress,
},
{
order: 3,
id: 'web-go',
Logo: lazy(async () => import('./web-go/logo.svg')),
Component: lazy(async () => import('./web-go/README.mdx')),
metadata: webGo,
},
{
order: 4,
id: 'web-python',
Logo: lazy(async () => import('./web-python/logo.svg')),
Component: lazy(async () => import('./web-python/README.mdx')),
metadata: webPython,
},
{
order: 5,
id: 'web-php',
Logo: lazy(async () => import('./web-php/logo.svg')),
Component: lazy(async () => import('./web-php/README.mdx')),
metadata: webPhp,
},
{
order: 6,
id: 'web-remix',
Logo: lazy(async () => import('./web-remix/logo.svg')),
Component: lazy(async () => import('./web-remix/README.mdx')),
metadata: webRemix,
},
{
order: 7,
id: 'web-asp-net-core',
Logo: lazy(async () => import('./web-asp-net-core/logo.svg')),
Component: lazy(async () => import('./web-asp-net-core/README.mdx')),
metadata: webAspNetCore,
},
{
order: 8,
id: 'web-outline',
Logo: lazy(async () => import('./web-outline/logo.svg')),
Component: lazy(async () => import('./web-outline/README.mdx')),
metadata: webOutline,
},
{
order: 9,
id: 'web-gpt-plugin',
Logo: lazy(async () => import('./web-gpt-plugin/logo.svg')),
Component: lazy(async () => import('./web-gpt-plugin/README.mdx')),
metadata: webGptPlugin,
},
]);

View file

@ -0,0 +1,3 @@
{
"order": 2
}

View file

@ -0,0 +1,3 @@
{
"order": 2.1
}

View file

@ -0,0 +1,3 @@
{
"order": 4
}

View file

@ -0,0 +1,3 @@
{
"order": 3
}

View file

@ -0,0 +1,3 @@
{
"order": 1
}

View file

@ -0,0 +1,3 @@
{
"order": 1
}

View file

@ -0,0 +1,3 @@
{
"order": 3
}

View file

@ -0,0 +1,3 @@
{
"order": 2
}

View file

@ -0,0 +1,3 @@
{
"order": 7
}

View file

@ -0,0 +1,3 @@
{
"order": 2
}

View file

@ -0,0 +1,3 @@
{
"order": 3
}

View file

@ -0,0 +1,3 @@
{
"order": 9
}

View file

@ -0,0 +1,3 @@
{
"order": 1.1
}

View file

@ -0,0 +1,3 @@
{
"order": 1
}

View file

@ -0,0 +1,3 @@
{
"order": 8
}

View file

@ -0,0 +1,3 @@
{
"order": 5
}

View file

@ -0,0 +1,3 @@
{
"order": 4
}

View file

@ -0,0 +1,3 @@
{
"order": 6
}