create-saasicat-admin 1.0.0-rc.2 → 1.0.0-rc.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -13
- package/bin/create.js +3 -3
- package/package.json +1 -1
- package/templates/README.md.tpl +2 -1
- package/templates/package.json.tpl +1 -5
- package/templates/src/main.ts.tpl +22 -6
- package/templates/src/services/http.ts.tpl +1 -1
- package/templates/src/services/platform-loaders.ts.tpl +2 -6
- package/templates/src/stores/manifest.ts.tpl +2 -1
- package/templates/vite.config.ts.tpl +8 -13
- package/templates/src/styles/theme.scss.tpl +0 -30
package/README.md
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
# create-saasicat-admin
|
|
2
2
|
|
|
3
|
+
## What this is
|
|
4
|
+
|
|
3
5
|
Scaffolding CLI for SuperAdmin frontend projects. Generates a runnable
|
|
4
6
|
Vue 3 + Quasar + Vite project that builds on `@saasicat/ui-vue` and ships
|
|
5
7
|
all standard pages.
|
|
6
8
|
|
|
9
|
+
## What this is not
|
|
10
|
+
|
|
11
|
+
Not a dependency. It runs once, writes a Vite + Vue 3 + Quasar project you
|
|
12
|
+
own, and is never installed into it. Nothing it writes is generated again
|
|
13
|
+
later — edit the files freely.
|
|
14
|
+
|
|
15
|
+
Not the backend. The scaffolded admin talks to a NestJS application that
|
|
16
|
+
already has `@saasicat/nest` wired; without one it starts and shows a login
|
|
17
|
+
screen it cannot get past.
|
|
18
|
+
|
|
7
19
|
## Usage
|
|
8
20
|
|
|
9
21
|
```bash
|
|
10
22
|
pnpm create saasicat-admin <dir> \
|
|
11
|
-
--
|
|
23
|
+
--app-key notesapp \
|
|
12
24
|
--brand-name NotesApp \
|
|
13
25
|
--logo-text NA \
|
|
14
26
|
--api-base /api/v1/admin
|
|
@@ -16,7 +28,7 @@ pnpm create saasicat-admin <dir> \
|
|
|
16
28
|
|
|
17
29
|
Generates this directory structure:
|
|
18
30
|
|
|
19
|
-
```
|
|
31
|
+
```text
|
|
20
32
|
<dir>/
|
|
21
33
|
├── package.json
|
|
22
34
|
├── vite.config.ts
|
|
@@ -26,8 +38,7 @@ Generates this directory structure:
|
|
|
26
38
|
│ ├── main.ts (calls createSuperAdminApp)
|
|
27
39
|
│ ├── App.vue (<router-view />)
|
|
28
40
|
│ ├── services/http.ts (HTTP client + adminLogin stub)
|
|
29
|
-
│
|
|
30
|
-
│ └── styles/theme.scss
|
|
41
|
+
│ └── router/routes.ts (all standard pages)
|
|
31
42
|
└── README.md
|
|
32
43
|
```
|
|
33
44
|
|
|
@@ -41,15 +52,15 @@ pnpm dev # http://localhost:9100/admin/login
|
|
|
41
52
|
|
|
42
53
|
## Options
|
|
43
54
|
|
|
44
|
-
| Flag | Default | Purpose
|
|
45
|
-
| ---------------- | --------------- |
|
|
46
|
-
| `--
|
|
47
|
-
| `--brand-name` | `App` | shown in the AdminLayout header
|
|
48
|
-
| `--logo-text` | `AP` | two-letter badge in the logo
|
|
49
|
-
| `--api-base` | `/api/v1/admin` | backend endpoint prefix
|
|
50
|
-
| `--dev-port` | `9100` | Vite dev server port
|
|
51
|
-
| `--backend-port` | `3000` | backend port for the Vite proxy
|
|
52
|
-
| `--no-install` | false | only generate files, skip the final `pnpm install`
|
|
55
|
+
| Flag | Default | Purpose |
|
|
56
|
+
| ---------------- | --------------- | ------------------------------------------------------------ |
|
|
57
|
+
| `--app-key` | `app` | slug of the application; npm package name and storage prefix |
|
|
58
|
+
| `--brand-name` | `App` | shown in the AdminLayout header |
|
|
59
|
+
| `--logo-text` | `AP` | two-letter badge in the logo |
|
|
60
|
+
| `--api-base` | `/api/v1/admin` | backend endpoint prefix |
|
|
61
|
+
| `--dev-port` | `9100` | Vite dev server port |
|
|
62
|
+
| `--backend-port` | `3000` | backend port for the Vite proxy |
|
|
63
|
+
| `--no-install` | false | only generate files, skip the final `pnpm install` |
|
|
53
64
|
|
|
54
65
|
## What is left to do afterwards
|
|
55
66
|
|
|
@@ -59,3 +70,9 @@ pnpm dev # http://localhost:9100/admin/login
|
|
|
59
70
|
3. Adapt the Vite proxy in `vite.config.ts` to your backend port.
|
|
60
71
|
|
|
61
72
|
Everything else comes from `@saasicat/ui-vue`.
|
|
73
|
+
|
|
74
|
+
## Next
|
|
75
|
+
|
|
76
|
+
- [Build the admin frontend](../../docs/guides/build-the-admin-frontend.md) — what the scaffolder
|
|
77
|
+
wrote, explained
|
|
78
|
+
- [Design guide](../../docs/explanation/design-guide.md) — before you write a page of your own
|
package/bin/create.js
CHANGED
|
@@ -20,7 +20,7 @@ const OWN_VERSION = JSON.parse(
|
|
|
20
20
|
).version;
|
|
21
21
|
|
|
22
22
|
export const DEFAULT_TOKENS = {
|
|
23
|
-
|
|
23
|
+
APP_KEY: 'app',
|
|
24
24
|
BRAND_NAME: 'App',
|
|
25
25
|
LOGO_TEXT: 'AP',
|
|
26
26
|
API_BASE: '/api/v1/admin',
|
|
@@ -30,7 +30,7 @@ export const DEFAULT_TOKENS = {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
const TOKEN_FLAGS = {
|
|
33
|
-
'
|
|
33
|
+
'app-key': 'APP_KEY',
|
|
34
34
|
'brand-name': 'BRAND_NAME',
|
|
35
35
|
'logo-text': 'LOGO_TEXT',
|
|
36
36
|
'api-base': 'API_BASE',
|
|
@@ -119,7 +119,7 @@ async function main() {
|
|
|
119
119
|
console.log('Usage: pnpm create saasicat-admin <dir> [flags]');
|
|
120
120
|
console.log('');
|
|
121
121
|
console.log('Flags:');
|
|
122
|
-
console.log(' --
|
|
122
|
+
console.log(' --app-key=app the slug of this application');
|
|
123
123
|
console.log(' (also the storage-key prefix)');
|
|
124
124
|
console.log(' --brand-name=App brand name in the header');
|
|
125
125
|
console.log(' --logo-text=AP two-letter badge');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-saasicat-admin",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.20",
|
|
4
4
|
"description": "Scaffolding CLI for SuperAdmin frontend projects (Vue 3 + Quasar + Vite). Generates a minimal working admin app built on @saasicat/ui-vue. Usage: `pnpm create saasicat-admin <dir>`.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/templates/README.md.tpl
CHANGED
|
@@ -21,4 +21,5 @@ serve `__API_BASE__/manifest`.
|
|
|
21
21
|
- Add your own project pages in `src/router/routes.ts` (with
|
|
22
22
|
`createProjectPageHostRoute()` as a catch-all).
|
|
23
23
|
- Register KPI cards, tenant actions and project pages in your backend
|
|
24
|
-
manifest (see `docs/
|
|
24
|
+
manifest (see `docs/guides/wire-the-backend.md`, "Manifest Contributions",
|
|
25
|
+
in the saasicat repo).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
2
|
+
"name": "__APP_KEY__-admin",
|
|
3
3
|
"version": "0.0.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
@@ -9,19 +9,15 @@
|
|
|
9
9
|
"preview": "vite preview"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@quasar/extras": "^1.16.0",
|
|
13
12
|
"@saasicat/core": "__PLATFORM_VERSION__",
|
|
14
13
|
"@saasicat/ui-vue": "__PLATFORM_VERSION__",
|
|
15
14
|
"axios": "^1.15.0",
|
|
16
15
|
"pinia": "^3.0.0",
|
|
17
|
-
"quasar": "^2.22.0",
|
|
18
16
|
"vue": "^3.5.0",
|
|
19
17
|
"vue-router": "^4.5.0"
|
|
20
18
|
},
|
|
21
19
|
"devDependencies": {
|
|
22
|
-
"@quasar/vite-plugin": "^1.10.0",
|
|
23
20
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
24
|
-
"sass": "^1.83.0",
|
|
25
21
|
"typescript": "^5.7.0",
|
|
26
22
|
"vite": "^7.0.0",
|
|
27
23
|
"vue-tsc": "^2.2.0"
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
// Bootstrap. createSuperAdminApp wires up Quasar + Pinia + Router + guards.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// Every stylesheet the admin needs, all from the one package you installed.
|
|
4
|
+
// The components are built (ADR 0011), so their styles arrive as `style.css`
|
|
5
|
+
// rather than being compiled by your build — without it the standard pages
|
|
6
|
+
// render unstyled.
|
|
7
|
+
import '@saasicat/ui-vue/quasar.css';
|
|
8
|
+
import '@saasicat/ui-vue/icons.css';
|
|
7
9
|
import '@saasicat/ui-vue/theme.css';
|
|
10
|
+
import '@saasicat/ui-vue/style.css';
|
|
8
11
|
|
|
9
12
|
import { createSuperAdminApp } from '@saasicat/ui-vue/quasar';
|
|
10
13
|
import App from './App.vue';
|
|
@@ -15,7 +18,20 @@ import { useManifestStore } from './stores/manifest';
|
|
|
15
18
|
|
|
16
19
|
const handle = createSuperAdminApp({
|
|
17
20
|
rootComponent: App,
|
|
18
|
-
|
|
21
|
+
// `color` is the ONE place your admin's brand colour is decided:
|
|
22
|
+
// `--sa-color-accent` reads Quasar's `--q-primary`, which this writes, so
|
|
23
|
+
// the hero, the buttons, the focus ring, the tinted surfaces, Quasar's own
|
|
24
|
+
// components and the tenant-facing pages all follow. There is no second
|
|
25
|
+
// switch — with one trap beside it: Quasar's own `config.brand` writes to
|
|
26
|
+
// `<body>`, where the accent role cannot see it. Leave that one alone.
|
|
27
|
+
//
|
|
28
|
+
// The default is SaaSiCat's own, so a fresh admin looks like the
|
|
29
|
+
// documentation until you decide otherwise.
|
|
30
|
+
//
|
|
31
|
+
// One caveat if you pick a LIGHT brand: text on accent-filled controls is
|
|
32
|
+
// white, and CSS cannot work out that white on a light amber is 2.15:1.
|
|
33
|
+
// Override `--sa-color-fg-on-accent` in your own CSS if so — in both themes.
|
|
34
|
+
brand: { logoText: '__LOGO_TEXT__', name: '__BRAND_NAME__', color: '#3f6bff' },
|
|
19
35
|
endpoints: ADMIN_ENDPOINTS,
|
|
20
36
|
appRoutes,
|
|
21
37
|
loginAdapter: { login: adminLogin },
|
|
@@ -37,7 +53,7 @@ const handle = createSuperAdminApp({
|
|
|
37
53
|
extensions: {},
|
|
38
54
|
// Starting UI language — the shell's header switcher lets the user change
|
|
39
55
|
// it from there and remembers the pick. `overrides` replaces individual
|
|
40
|
-
// strings (
|
|
56
|
+
// strings (docs/guides/build-the-admin-frontend.md, "UI Language").
|
|
41
57
|
i18n: { locale: 'en' },
|
|
42
58
|
});
|
|
43
59
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import axios from 'axios';
|
|
7
7
|
import { createAxiosHttpClient } from '@saasicat/ui-vue';
|
|
8
8
|
|
|
9
|
-
const TOKEN_KEY = '
|
|
9
|
+
const TOKEN_KEY = '__APP_KEY__-admin-token';
|
|
10
10
|
|
|
11
11
|
export const api = axios.create({ baseURL: '/api/v1' });
|
|
12
12
|
api.interceptors.request.use((cfg) => {
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
// BootLoader + ManifestLoader built from the same endpoint constant that
|
|
2
2
|
// `main.ts` passes to `createSuperAdminApp()` — endpoints live in exactly
|
|
3
|
-
// one place (
|
|
3
|
+
// one place (docs/guides/build-the-admin-frontend.md, "Platform Loaders").
|
|
4
4
|
|
|
5
5
|
import { createPlatformLoaders, type SuperAdminEndpoints } from '@saasicat/ui-vue';
|
|
6
6
|
import { platformHttp } from './http';
|
|
7
7
|
|
|
8
|
-
// `projectKey` names the catalogue this admin administers — the same key your
|
|
9
|
-
// backend configuration uses. The shell hands it to every platform resource,
|
|
10
|
-
// so a catalogue page does not have to carry it as a prop.
|
|
11
8
|
export const ADMIN_ENDPOINTS: SuperAdminEndpoints = {
|
|
12
9
|
apiBase: '__API_BASE__',
|
|
13
|
-
projectKey: '__PROJECT_KEY__',
|
|
14
10
|
};
|
|
15
11
|
|
|
16
12
|
export const loaders = createPlatformLoaders({
|
|
17
13
|
endpoints: ADMIN_ENDPOINTS,
|
|
18
14
|
http: platformHttp,
|
|
19
|
-
storageKeyPrefix: '
|
|
15
|
+
storageKeyPrefix: '__APP_KEY__:',
|
|
20
16
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Manifest Pinia store — the router guard in `main.ts` awaits
|
|
2
|
-
// `ensureLoaded()` before rendering admin routes
|
|
2
|
+
// `ensureLoaded()` before rendering admin routes
|
|
3
|
+
// (docs/guides/build-the-admin-frontend.md, "Manifest Store").
|
|
3
4
|
|
|
4
5
|
import { createManifestStore } from '@saasicat/ui-vue';
|
|
5
6
|
import { loaders } from '../services/platform-loaders';
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { fileURLToPath } from 'node:url';
|
|
2
2
|
import { defineConfig } from 'vite';
|
|
3
3
|
import vue from '@vitejs/plugin-vue';
|
|
4
|
-
import { quasar } from '@quasar/vite-plugin';
|
|
5
4
|
|
|
6
5
|
export default defineConfig({
|
|
7
6
|
base: '/admin/',
|
|
8
7
|
plugins: [
|
|
9
8
|
vue(),
|
|
10
|
-
quasar({
|
|
11
|
-
// Absolute path — sass resolves plain relative paths against the
|
|
12
|
-
// importing file inside node_modules/quasar, not the project root.
|
|
13
|
-
sassVariables: fileURLToPath(new URL('./src/styles/theme.scss', import.meta.url)),
|
|
14
|
-
}),
|
|
15
9
|
],
|
|
16
10
|
// Exactly one copy of each of these, always.
|
|
17
11
|
//
|
|
@@ -22,17 +16,18 @@ export default defineConfig({
|
|
|
22
16
|
// so two copies of the library do not share one, and the lookup silently
|
|
23
17
|
// returns `undefined`.
|
|
24
18
|
//
|
|
25
|
-
// The platform
|
|
26
|
-
// `import … from 'vue-router'`
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
19
|
+
// The platform's pages are built (ADR 0011), and its chunks resolve
|
|
20
|
+
// `import … from 'vue-router'` relative to the platform package while this
|
|
21
|
+
// app's own files resolve relative to here. Without dedupe the bundle ends
|
|
22
|
+
// up with both, and every consumer page that reads a route param throws
|
|
23
|
+
// `Cannot read properties of undefined (reading 'params')` — the shell
|
|
24
|
+
// renders, the content area is blank. The reason survived the move from
|
|
25
|
+
// source to a build; only the first clause of it changed.
|
|
31
26
|
//
|
|
32
27
|
// The list is `@saasicat/ui-vue`'s peerDependencies: a peer is precisely a
|
|
33
28
|
// dependency the host is expected to own exactly one of.
|
|
34
29
|
resolve: {
|
|
35
|
-
dedupe: ['vue', 'vue-router', 'pinia'
|
|
30
|
+
dedupe: ['vue', 'vue-router', 'pinia'],
|
|
36
31
|
},
|
|
37
32
|
server: {
|
|
38
33
|
port: __DEV_PORT__,
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Quasar theme variables — override your branding here.
|
|
2
|
-
//
|
|
3
|
-
// `$primary` is the ONE place your admin's brand colour is decided. SaaSiCat has
|
|
4
|
-
// no palette of its own for it: `--sa-color-accent` reads Quasar's `--q-primary`,
|
|
5
|
-
// which Quasar publishes from this variable. Change it and the hero, the buttons,
|
|
6
|
-
// the focus ring, the tinted surfaces, Quasar's own components and the
|
|
7
|
-
// tenant-facing pages all follow — there is no second switch.
|
|
8
|
-
//
|
|
9
|
-
// The four status colours are NOT read from here, and that is deliberate: each
|
|
10
|
-
// SaaSiCat status tone is a family of six contrast-tuned values (solid, strong,
|
|
11
|
-
// text, two tints, border), and a single Quasar variable cannot say which rung it
|
|
12
|
-
// is — `$warning` is a bright graphic amber, while warning TEXT has to be dark
|
|
13
|
-
// enough to read on it. They are set below to the values the platform's own roles
|
|
14
|
-
// use, so Quasar's components and the admin pages agree out of the box. To change
|
|
15
|
-
// them, override the `--sa-color-<tone>*` roles as a set.
|
|
16
|
-
//
|
|
17
|
-
// The defaults are SaaSiCat's own, so a freshly scaffolded admin looks like the
|
|
18
|
-
// documentation until you decide otherwise.
|
|
19
|
-
// One caveat if you pick a LIGHT brand: text on accent-filled controls is white
|
|
20
|
-
// by default, and CSS cannot work out that white on a light amber is 2.15:1. Set
|
|
21
|
-
// `--sa-color-fg-on-accent` to a dark colour in your own CSS if so — in both
|
|
22
|
-
// themes, like any role.
|
|
23
|
-
$primary: #3f6bff;
|
|
24
|
-
$secondary: #475569;
|
|
25
|
-
$accent: #0ea5e9;
|
|
26
|
-
|
|
27
|
-
$positive: #047857;
|
|
28
|
-
$negative: #dc2626;
|
|
29
|
-
$warning: #f59e0b;
|
|
30
|
-
$info: #2563eb;
|