@fui-org/fui-cli 2.2.3 → 2.2.4
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 +19 -0
- package/dist/fui-gt54fgs7.js +402 -0
- package/dist/fui.js +1 -1
- package/package.json +1 -1
- package/skills/fui/SKILL.md +18 -3
- package/skills/fui/references/INDEX.md +7 -5
- package/skills/fui/references/cdn-files.md +30 -0
- package/skills/fui/references/coding-standards.md +2 -2
- package/skills/fui/references/component-design.md +2 -2
- package/skills/fui/references/controls-styling-vocabulary.md +3 -3
- package/skills/fui/references/db-workflow.md +3 -3
- package/skills/fui/references/design-modes.md +1 -1
- package/skills/fui/references/module-structure.md +44 -16
- package/skills/fui/references/permission-system.md +15 -9
- package/skills/fui/references/project-config.md +1 -1
- package/skills/fui/references/project-provisioning.md +129 -218
- package/skills/fui/references/tools-registry.md +13 -7
- package/skills/fui/references/ui-screenshot-review.md +1 -1
- package/skills/fui/references/verification.md +2 -1
- package/dist/fui-8tyckpke.js +0 -397
package/dist/fui.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{enableCompileCache as a}from"node:module";a?.();var{run:e}=await import("./fui-
|
|
2
|
+
import{enableCompileCache as a}from"node:module";a?.();var{run:e}=await import("./fui-gt54fgs7.js");await e();
|
package/package.json
CHANGED
package/skills/fui/SKILL.md
CHANGED
|
@@ -63,10 +63,16 @@ A request to create, design, fix or update a module authorizes the agent to publ
|
|
|
63
63
|
|
|
64
64
|
- **No `style`/`class` beautifying unless asked**; grid + Vuetify + project theme suffice. → [controls-styling-vocabulary.md](references/controls-styling-vocabulary.md)
|
|
65
65
|
|
|
66
|
+
**CSS and JS placement (both `HTMLOnly` values)**
|
|
67
|
+
|
|
68
|
+
- **NEVER** CSS in `header.html`/`body.html`: no `<style>` block, no static `style="…"`. Module CSS → `style.css` (`fui module publish css`); component CSS → its `.vue` `<style scoped>`.
|
|
69
|
+
- **NEVER** `<link rel="stylesheet">`/`<script src>` in header/body: every JS/CSS library or CDN URL → `fui import new` (own file: then `fui import upload`). Inline page code → `script.js`.
|
|
70
|
+
- Editing header/body/CSS of a module that already breaks this → move it out in the same change. Raw tag only when an import cannot do it (`type="module"`, `integrity`, `defer`, a config global needed before the library loads...); say which and why. `module validate`/`check`/`preview` list leftovers as **header/body warnings**. → [module-structure.md](references/module-structure.md) §CSS and JS placement
|
|
71
|
+
|
|
66
72
|
**`uc-*.vue` components**
|
|
67
73
|
|
|
68
74
|
- One `uc-<name>.vue` file (Vue 2 options API). FUI names it by filename and registers every `uc-*.vue` globally: **NEVER** `name:` or `components: {}`.
|
|
69
|
-
- Component CSS → `<style scoped>` (saved as `ComCSS`), but it does NOT scope (text concat, no SFC compile): prefix EVERY selector with the component's class. Module-wide CSS → `style.css` (`fui module publish css`)
|
|
75
|
+
- Component CSS → `<style scoped>` (saved as `ComCSS`), but it does NOT scope (text concat, no SFC compile): prefix EVERY selector with the component's class. Module-wide CSS → `style.css` (`fui module publish css`), never `header.html`. → [coding-standards.md](references/coding-standards.md)
|
|
70
76
|
- **NEVER** backtick template strings in `<template>`. → [component-design.md](references/component-design.md) · [coding-standards.md](references/coding-standards.md)
|
|
71
77
|
- Use Vuetify components where they fit and validate props. Check one alone with `fui component preview <uc-name> --cases [...]` before wiring it into a module, then `fui component new|update <name>`.
|
|
72
78
|
|
|
@@ -74,7 +80,7 @@ A request to create, design, fix or update a module authorizes the agent to publ
|
|
|
74
80
|
|
|
75
81
|
- Before using an existing control, check `defaultControlAttr[control].import` in `scripts/component.js` (V2) or `scripts/component-3.0.js` (V3). Treat that array and its order as the source of truth for required JS/CSS; then check imports on every add or remove. → [component-quickref.md](references/component-quickref.md)
|
|
76
82
|
- **NEVER** add CDN for bundled libs (jQuery, lodash, moment, numeral, Vuetify, toast, jquery-confirm...); list: [script-map.md](references/script-map.md) §0.
|
|
77
|
-
- That ban is `HTMLOnly=false` only. `HTMLOnly: true` bundles **nothing** (no Vue, Vuetify, jQuery, lodash, MDI, `projectdefaultstyle.css`, `#fastProjectAPP`): CDNs are **required**, **per HTMLOnly module** (project level has no effect). → [module-structure.md](references/module-structure.md) §HTMLOnly=true
|
|
83
|
+
- That ban is `HTMLOnly=false` only. `HTMLOnly: true` bundles **nothing** (no Vue, Vuetify, jQuery, lodash, MDI, `projectdefaultstyle.css`, `#fastProjectAPP`): CDNs are **required**, as module imports (`fui import new`), **per HTMLOnly module** (project level has no effect). → [module-structure.md](references/module-structure.md) §HTMLOnly=true
|
|
78
84
|
|
|
79
85
|
**Database** (enforced in code; details under "Writes need the user")
|
|
80
86
|
|
|
@@ -220,6 +226,10 @@ fui sp list --search Student # columns: db name kind count local
|
|
|
220
226
|
|
|
221
227
|
Before writing `apiMocks` for an SP that exists, run `fui sp verify <name>`. It reads the real body (never calls the endpoint) and prints the params, the response shape, the error contract, read/write and a mock snippet. `sp delete` and `sp rename` change the server: ask the user first.
|
|
222
228
|
|
|
229
|
+
## New database or project
|
|
230
|
+
|
|
231
|
+
"Create a database" (database + SQL accounts + SEC alias + its manager), "create a project" (FUI project + IDE rights) and "create both" are three separate scopes. Before any write, show the user a **result frame** of the end state, let them adjust it and wait for their approval; a database frame needs a proved login to the exact server first. Steps and commands: [project-provisioning.md](references/project-provisioning.md).
|
|
232
|
+
|
|
223
233
|
## Writes need the user
|
|
224
234
|
|
|
225
235
|
- Writes to real data exit `3` until you add `--confirm-write`. That covers `INSERT`, `UPDATE`, `DELETE`, `MERGE` and `TRUNCATE` in `query` or `exec` (also inside `EXEC('...')` or `sp_executesql`), `SELECT ... INTO` a real table, `DROP PROCEDURE`/`FUNCTION`/`VIEW`, and `ALTER TABLE ... ALTER COLUMN`.
|
|
@@ -240,6 +250,10 @@ fui file restore <path> [--at YYYYMMDD_HHMMSS] # the current file is archived
|
|
|
240
250
|
fui file ledger <path...> [--mark|--forget]
|
|
241
251
|
```
|
|
242
252
|
|
|
253
|
+
## Project CDN files
|
|
254
|
+
|
|
255
|
+
Use `fui cdn` to inspect and manage CKFinder project files with the saved `userToken`. Read [references/cdn-files.md](references/cdn-files.md) before uploading, moving, renaming or deleting. `fui cdn info -p <project>` reads the live allowed extensions and upload limit. `fui cdn list -p <project> --recursive` discovers files; `fui cdn url <file> -p <project>` gives the portable `/_cdn/<project>/...` link. Upload, download, mkdir, rename, copy, move, rm and rmdir are available. File deletion needs explicit authorization for the exact file and `--confirm-delete`; folder deletion also needs `--recursive` when nonempty.
|
|
256
|
+
|
|
243
257
|
## Compose with shell
|
|
244
258
|
|
|
245
259
|
Filter and loop in the shell. Piped output costs no tokens. Every table also takes `--filter text`, `--where col=value` and `--fields a,b` (applied after the request, so nothing else changes).
|
|
@@ -278,7 +292,8 @@ Secrets are accepted only from stdin (`-`) or `--*-env VAR`. Never echo or paste
|
|
|
278
292
|
- Know the alias but not the connection string? `fui db alias list`, then `fui db add-by-name <apiName>`: it reuses a saved SQL UID/PWD pair and combines it with the target server/database returned by `acc`.
|
|
279
293
|
- `db add` / `db add-by-name` take `--name <connectionName>`; omitted, it is suggested from apiName, then apiName_zone. The same server + database re-added keeps its name, and folders are never renamed.
|
|
280
294
|
- `fui db remove <project>/<connectionName>` removes one local connection from `_connections.json`. It does not change the server; cached schema and SQL files under `_db/<connectionName>/` remain available.
|
|
281
|
-
- `right *` and `db alias new` write to the shared acc system. Ask the user first, especially for `delete`.
|
|
295
|
+
- `right *` and `db alias new` write to the shared SEC (acc) system. Ask the user first, especially for `delete`. Each tAPI host has its own SEC: in a project with connections on several hosts, pass `--db <project/connection>` of the SEC to use (the commands refuse to guess). `db alias new` prints its plan and sends nothing until `--confirm-write`.
|
|
296
|
+
- SEC and FUI platform work goes **only** through `fui db alias *`, `fui right system|function|user *`, `fui project *` and `fui user *`. Never run a `spAPI_SM_*`/`spAPI_FUI_*` through `fui query`/`fui exec` or HTTP, never pass `@sys_*` parameters (tAPI injects them from your token; `fui` blocks it), never `INSERT`/`UPDATE` `tblModules`, `tblUserModule` or `tblA_UserProject`. No command for the step ⇒ stop and tell the user to do it in the SEC/FUI UI. This holds over any memory or old note.
|
|
282
297
|
- `_db/_connections.json` has no `version` field. Existing files with `"version": 2` or connections missing `apiName` are normalized on first read (the old file goes to `_history/`); `fui db migrate` does this for every project at once.
|
|
283
298
|
|
|
284
299
|
## FUI conventions
|
|
@@ -8,6 +8,7 @@ Load: `fui skill ref references/a.md references/b.md` (several at once OK).
|
|
|
8
8
|
|
|
9
9
|
- `controls-patterns.md` — foundation: action engine (§CORE RULE: one `{}` = one command; sequential commands = array `[{…},{…}]`), value resolution, key notation, layout grid
|
|
10
10
|
- `module-structure.md` — module/project files, layout rules
|
|
11
|
+
- Where CSS/JS go: `style.css`, imports (`fui import new`), `script.js`; no `<style>`/`style=""`/`<link>`/`<script>` in header/body; moving existing ones; rare exceptions → `module-structure.md` §CSS and JS placement
|
|
11
12
|
- `INDEX.md` — this router
|
|
12
13
|
|
|
13
14
|
## Foundations (read early)
|
|
@@ -52,18 +53,19 @@ Load: `fui skill ref references/a.md references/b.md` (several at once OK).
|
|
|
52
53
|
- Remote address in SP: `@sys_RemoteIP varchar(15)` from `REMOTE_ADDR`; HTTP headers (`User-Agent`, `Cookie`, `X-Forwarded-For`, device/browser): `@sys_header_*`, each `-` → `_`, except `Authorization` → `tapi-reference.md` §2
|
|
53
54
|
- SP permission checks (5 patterns, `@sys_SystemRight`, `getSystemRight`) → `tapi-permission-patterns.md`
|
|
54
55
|
- File upload/download/view (`spAPIFILE_`, `fileContent`, `tblFileData`) → `tapi-file-api.md`
|
|
56
|
+
- Project CDN assets (CKFinder list, upload, folder, rename, move, copy, delete, portable URL) → `cdn-files.md`
|
|
55
57
|
- SQL CLR: httpCall, sendMail, ImageResize, FileReader, RegexMatch… → `sql-clr-functions.md`
|
|
56
58
|
|
|
57
59
|
## User permissions
|
|
58
60
|
|
|
59
|
-
- `SystemRight` (level) vs `FunctionRight` (per function), `v-if`/menu `right`, `fui right system|function list/new/update/delete` (8 commands) → `permission-system.md`
|
|
61
|
+
- `SystemRight` (level) vs `FunctionRight` (per function), `v-if`/menu `right`, `fui right system|function list/new/update/delete` (8 commands), who holds a level / SEC module manager (`fui right user list/search/add/set/remove`) → `permission-system.md`
|
|
60
62
|
- Guarding control/menu/SP with a right code — it must exist; how to create → `permission-system.md` (§"A right code must EXIST before guarding with it")
|
|
61
63
|
- SQL permission checks in SP body → `tapi-permission-patterns.md`
|
|
62
64
|
|
|
63
65
|
## Database
|
|
64
66
|
|
|
65
67
|
- DB doesn't exist: new SQL Server DB, two SQL account types, tAPI alias in `acc` → `project-provisioning.md`
|
|
66
|
-
- Before `CREATE DATABASE` / `CREATE LOGIN`: check server rights (`sysadmin`, or `CREATE ANY DATABASE` + `ALTER ANY LOGIN`); if missing, refuse, no trial run → `project-provisioning.md` §
|
|
68
|
+
- Before `CREATE DATABASE` / `CREATE LOGIN`: check server rights (`sysadmin`, or `CREATE ANY DATABASE` + `ALTER ANY LOGIN`); if missing, refuse, no trial run → `project-provisioning.md` §Phase B
|
|
67
69
|
- Connection, dbToken, schema, SP workflow → `db-workflow.md`
|
|
68
70
|
- Multiple DBs / an alias repeated across zones: `connectionName` names a readable folder, `apiName` is stored separately, `--db` picks the connection → `db-workflow.md` (§1, §4)
|
|
69
71
|
- Cross-domain SSO: userToken of same parent domain works as-is; don't re-ask/verify → `db-workflow.md` §6a
|
|
@@ -72,8 +74,8 @@ Load: `fui skill ref references/a.md references/b.md` (several at once OK).
|
|
|
72
74
|
|
|
73
75
|
## Process / system design
|
|
74
76
|
|
|
75
|
-
-
|
|
76
|
-
- Grant/revoke IDE project-edit rights for a developer (`UserRight`, `fui user search/list/add/set/remove`); not end-user rights (`permission-system.md`) → `project-provisioning.md` (§
|
|
77
|
+
- "Create a database", "create a project" or both (three separate scopes): result frame approved by the user first, CREATE DATABASE, app vs dev accounts, SEC alias + its manager, `fui project new`, IDE rights; do BEFORE `system-design.md` → `project-provisioning.md`
|
|
78
|
+
- Grant/revoke IDE project-edit rights for a developer (`UserRight`, `fui user search/list/add/set/remove`); not end-user rights (`permission-system.md`) → `project-provisioning.md` (§Phase C, project block)
|
|
77
79
|
- Multi-module app from a description (decomposition, schema-first, menu, rights) → `system-design.md`
|
|
78
80
|
- One fullstack module, 6-step UI-first → `fullstack-workflow.md`
|
|
79
81
|
- project.json: menu, navigation, permissions, domain → `project-config.md`
|
|
@@ -104,7 +106,7 @@ Load: `fui skill ref references/a.md references/b.md` (several at once OK).
|
|
|
104
106
|
Pick the mode BEFORE writing controls. Owner: `design-modes.md`.
|
|
105
107
|
|
|
106
108
|
- App-mode (default): CRUD, forms, lists, internal dashboards. Source: ONLY `fui design read fui` + `controls-styling-vocabulary.md`; NO brand DESIGN.md, NO custom styles.
|
|
107
|
-
- Web-mode: landing/intro/public pages (usually `HTMLOnly: true`). Source: `fui design list` → `fui design read <brand>` by tone/industry; free CSS in
|
|
109
|
+
- Web-mode: landing/intro/public pages (usually `HTMLOnly: true`). Source: `fui design list` → `fui design read <brand>` by tone/industry; free CSS in `style.css`, libraries as imports.
|
|
108
110
|
- Mode choice, `border-radius` limits, `{projectId}/DESIGN.md` loop → `design-modes.md`
|
|
109
111
|
- App-mode dialog/form/palette anatomy → `fui design read fui` (not `fui skill ref`)
|
|
110
112
|
- `{projectId}/DESIGN.md`, if present, overrides same-topic rules of the active mode; check before designing.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Project CDN files
|
|
2
|
+
|
|
3
|
+
`fui cdn` works with the project's CKFinder 2.6 connector at `cdn.fui.vn`. It uses a saved `userToken` as a Bearer credential, sends `Referer: https://cdn.fui.vn/?folder=<projectId>`, obtains the project's resource type and hash with `Init`, and handles the connector's CSRF cookie on writes. Never print or paste the token, session cookie or resource hash. A resource type is named after the project ID; do not assume it is `Images` or `Files`.
|
|
4
|
+
|
|
5
|
+
The tool reads allowed extensions and the 20 MB default upload limit from each project's live `Init` response. The supplied server configuration permits `js,json,css,csv,doc,docx,gif,jpeg,jpg,png,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,ppt,pptx,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,zip,woff,woff2,ttf,otf`; the live response is authoritative. CKFinder may resize large images to 2000 × 2000, rename an upload on collision, and reject unsafe names or invalid images.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
fui cdn info -p fp
|
|
11
|
+
fui cdn list / -p fp --recursive
|
|
12
|
+
fui cdn list /images/ -p fp
|
|
13
|
+
fui cdn mkdir /images/ -p fp
|
|
14
|
+
fui cdn upload ./logo.png -p fp --to /images/
|
|
15
|
+
fui cdn url /images/logo.png -p fp --origin https://fui.vn
|
|
16
|
+
fui cdn download /images/logo.png -o ./logo.png -p fp
|
|
17
|
+
fui cdn rename /images/logo.png logo-new.png -p fp
|
|
18
|
+
fui cdn rename /images/ assets -p fp
|
|
19
|
+
fui cdn copy /assets/logo-new.png --to /archive/ -p fp
|
|
20
|
+
fui cdn move /assets/logo-new.png --to /images/ -p fp
|
|
21
|
+
fui cdn rm /images/logo-new.png -p fp --confirm-delete
|
|
22
|
+
fui cdn rmdir /images/ -p fp --confirm-delete
|
|
23
|
+
fui cdn rmdir /archive/ -p fp --confirm-delete --recursive
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`cdn list` shows both folders and files. Add `--recursive` to walk the tree, and `--depth N` to limit recursion. Copy and move operate on files, into an existing folder, without overwriting a same-named item. `cdn rename` handles files and folders. `cdn download` refuses to replace a local file unless `--overwrite` is supplied. Use `--user-token-from <project/connection>` or `--user-token-env VAR` if the FUI domain has multiple saved tokens.
|
|
27
|
+
|
|
28
|
+
Upload and URL commands return both a portable relative link and a full link for `https://fui.vn`; `--origin` changes the full link to another project-serving domain. Prefer the relative `/_cdn/<projectId>/folder/file.ext` link in web pages. `cdn url` verifies the file exists before returning it.
|
|
29
|
+
|
|
30
|
+
Deletion is permanent. A request to build or edit a page does not by itself authorize removing existing project files. Obtain explicit authorization for the exact file or folder, then pass `--confirm-delete`; a nonempty folder also needs `--recursive`. Temporary assets created during an authorized test may be removed after the test if the user identified them as disposable.
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
### CSS Classes
|
|
18
18
|
|
|
19
19
|
- **`<style scoped>` in `.vue` is allowed** (saved server-side as `ComCSS`) but `scoped` has **no real effect** — FUI just concatenates every component's `ComCSS` in the module into one global stylesheet (`ComponentCSSBuild()`): no AST transform, no `data-v-xxxx`. **Scope every selector manually**: give the root template element a unique class matching the component name (kebab-case, e.g. `uc-invoice-list`) and write every rule under it (`.uc-invoice-list__title`, never bare `.title`). Full example: [component-design.md](component-design.md).
|
|
20
|
-
- **Placement**: component CSS → `<style scoped>` in the `.vue` (manually scoped). Module-wide CSS → `style.css` (publish with `fui module publish css`). `header.html`
|
|
20
|
+
- **Placement**: component CSS → `<style scoped>` in the `.vue` (manually scoped). Module-wide CSS → `style.css` (publish with `fui module publish css`). Never CSS in `header.html`/`body.html` (no `<style>`, no static `style="…"`): [module-structure.md](module-structure.md) §CSS and JS placement.
|
|
21
21
|
- **Vuetify utilities first** (`ma-2`, `pa-0`, `d-flex`, `primary--text`).
|
|
22
22
|
- **Custom classes**: meaningful prefixed names (`ep-hero`, `ep-field-grid`); avoid generic `.box`, `.red`.
|
|
23
23
|
- **State classes**: descriptive (`.is-active`, `.has-error`).
|
|
@@ -65,7 +65,7 @@ Define the app menu in `module.json`'s `set` object.
|
|
|
65
65
|
- **Required**: `_info.json` and `module.json` at module root.
|
|
66
66
|
- **`components/`**: only `.vue` files; no subfolders unless strictly necessary (FUI scans this root).
|
|
67
67
|
- **`components/_components.json`**: keep the registry when using `uc-*` components.
|
|
68
|
-
- **`header.html`**:
|
|
68
|
+
- **`header.html` / `body.html`**: markup only. CSS → `style.css` (component CSS → its `.vue`), JS/CSS libraries → `fui import new`, inline code → `script.js`. Existing CSS or library tags there → move them when you edit those files. Rules and the rare exceptions: [module-structure.md](module-structure.md) §CSS and JS placement.
|
|
69
69
|
- **`module.json`**: keep clean; move large static lists to the DB or separate JSON files if supported.
|
|
70
70
|
|
|
71
71
|
## 4. Best Practices
|
|
@@ -227,7 +227,7 @@ methods: {
|
|
|
227
227
|
</style>
|
|
228
228
|
```
|
|
229
229
|
|
|
230
|
-
Module-wide CSS → `style.css` (`fui module publish css`)
|
|
230
|
+
Module-wide CSS → `style.css` (`fui module publish css`), never `header.html`/`body.html` ([module-structure.md](module-structure.md) §CSS and JS placement).
|
|
231
231
|
|
|
232
232
|
### Before adding a class → check the approved vocabulary
|
|
233
233
|
|
|
@@ -244,7 +244,7 @@ Allowed Vuetify classes/props (spacing, flex, text, color, radius, elevation, br
|
|
|
244
244
|
|
|
245
245
|
§8 is **V3** (`v-row`/`v-col`); V2 projects use `v-layout`/`v-flex`. Silent breakage both ways: `v-flex` in V3 **shows content with wrong layout**, nothing reports it. Fixing an old component → `fui component preview` on **the project's framework** before pushing.
|
|
246
246
|
|
|
247
|
-
Component-specific CSS → its own `<style scoped>`, manually scoped
|
|
247
|
+
Component-specific CSS → its own `<style scoped>`, manually scoped. CSS shared by several module components or the whole module → `style.css`, never `header.html`.
|
|
248
248
|
|
|
249
249
|
---
|
|
250
250
|
|
|
@@ -110,7 +110,7 @@ The override does **not** touch `transition`. In particular, never add `scrollba
|
|
|
110
110
|
Do not use `fpScrollbar` for:
|
|
111
111
|
|
|
112
112
|
- **`f-table`/`f-sheet`**: the table scrolls internally by `:height` (see [ui-table-cell-patterns.md](ui-table-cell-patterns.md)); putting it on an outer wrapper only adds a nested scrollbar.
|
|
113
|
-
- **`HTMLOnly: true` modules**: they do not load `projectdefaultstyle.css`, so the class does not exist (see [module-structure.md](module-structure.md) §HTMLOnly=true). There, writing scrollbar CSS in the module is fine.
|
|
113
|
+
- **`HTMLOnly: true` modules**: they do not load `projectdefaultstyle.css`, so the class does not exist (see [module-structure.md](module-structure.md) §HTMLOnly=true). There, writing scrollbar CSS in the module's `style.css` is fine.
|
|
114
114
|
|
|
115
115
|
### Icon size
|
|
116
116
|
|
|
@@ -118,7 +118,7 @@ Do not use `fpScrollbar` for:
|
|
|
118
118
|
- **Don't set `small` or `:small`** on `v-icon`, icon buttons, or buttons with icons just to look "compact".
|
|
119
119
|
- Shrink only when the user explicitly asks or a specialised component/pattern prescribes it; then set the prop on exactly that component — don't shrink the whole button unintentionally.
|
|
120
120
|
|
|
121
|
-
**Before adding a class → check the table above.** Define a custom class only for what Vuetify lacks: complex grid-template, animation, pseudo-element (`::before`), specific child selectors. Put it in `
|
|
121
|
+
**Before adding a class → check the table above.** Define a custom class only for what Vuetify lacks: complex grid-template, animation, pseudo-element (`::before`), specific child selectors. Put it in the module's `style.css` (a component's own class: its `<style scoped>`), clearly prefixed, **minimal count**; never in `header.html`/`body.html` — don't recreate card/badge/spacing Vuetify already has.
|
|
122
122
|
|
|
123
123
|
> `flex-md-grow-0` + `col: { class: "shrink" }` + `style: "width:200px"` = **fixed-width filter field** — standard toolbar pattern ([ui-patterns.md](ui-patterns.md) §4). The only valid place for `style` (width only).
|
|
124
124
|
|
|
@@ -168,6 +168,6 @@ Only when the user **explicitly requests** specific presentation (e.g. "grey bac
|
|
|
168
168
|
|
|
169
169
|
- Prop → Vuetify utility class → `mw-*` for width → `style` last.
|
|
170
170
|
- `border-radius` on request: obey limits in [design-modes.md](design-modes.md) (large frame ≤12px, medium ≤8px, small ≤6px).
|
|
171
|
-
-
|
|
171
|
+
- CSS goes in `style.css` (component-only CSS: the component's manually prefixed `<style scoped>`), never in `header.html`/`body.html`. [module-structure.md](module-structure.md) §CSS and JS placement.
|
|
172
172
|
|
|
173
173
|
> **About to type `style` or name a new class → stop and ask "did the user request this?". If not → drop it.**
|
|
@@ -277,9 +277,9 @@ EXEC XDATA23.Calendar2015.dbo.spIO_IN_DeleteMonHocInfo @MonHocID, @ErrorDKMH OUT
|
|
|
277
277
|
|
|
278
278
|
| Situation | Command |
|
|
279
279
|
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
280
|
-
| DB doesn't exist (from scratch) | [project-provisioning.md](project-provisioning.md):
|
|
281
|
-
| Check `CREATE DATABASE`/`CREATE LOGIN` rights | [project-provisioning.md](project-provisioning.md) §
|
|
282
|
-
| DB exists, no alias in `acc` | `fui db alias new` ([project-provisioning.md](project-provisioning.md) §
|
|
280
|
+
| DB doesn't exist (from scratch) | [project-provisioning.md](project-provisioning.md): result frame → read-only checks → CREATE DATABASE → 2 accounts → `fui db alias new` → SEC manager |
|
|
281
|
+
| Check `CREATE DATABASE`/`CREATE LOGIN` rights | [project-provisioning.md](project-provisioning.md) §Phase B — `IS_SRVROLEMEMBER` + `HAS_PERMS_BY_NAME`, read-only |
|
|
282
|
+
| DB exists, no alias in `acc` | `fui db alias new` ([project-provisioning.md](project-provisioning.md) §Phase C, database block) |
|
|
283
283
|
| First connect, have dbToken | `fui db add` |
|
|
284
284
|
| Alias only, no dbToken | `fui db alias list` → `fui db add-by-name` |
|
|
285
285
|
| Which DBs am I granted | `fui db alias list` |
|
|
@@ -13,7 +13,7 @@ Before writing any `controls`, decide the module's mode. This is the first, **ha
|
|
|
13
13
|
| Applies to | Management software: CRUD, lists, forms, internal dashboards, permissions | Landing pages, product intros, public pages (usually `HTMLOnly: true`) |
|
|
14
14
|
| Aesthetic source | **ONLY** `fui design read fui` + `controls-styling-vocabulary.md` | Brand DESIGN.md (`fui design list` → `fui design read <brand>`) |
|
|
15
15
|
| Brand DESIGN.md (nike, linear, bmw...) | **FORBIDDEN** — even "just the colors" | Allowed, pick by tone/industry |
|
|
16
|
-
| Custom style/class | **FORBIDDEN** (per `controls-styling-vocabulary.md`) | Allowed in `header.html`
|
|
16
|
+
| Custom style/class | **FORBIDDEN** (per `controls-styling-vocabulary.md`) | Allowed, in `style.css` only (never `header.html`/`body.html`) |
|
|
17
17
|
| Component preference | `f-*` / `v-*` per FUI standard | Free HTML/CSS |
|
|
18
18
|
|
|
19
19
|
**Web-mode signals**: `HTMLOnly: true` in `_moduleInfo.json`, or user says "landing page / intro page / public home page". Everything else → App-mode. Unsure → **ask the user**.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Module Structure
|
|
2
2
|
|
|
3
|
-
> Owns: project/module tree, per-file duties, `_moduleInfo.json`/`mTitle`, `HTMLOnly`, default meta tags. `uc-*.vue` rules: [component-design.md](component-design.md); `module.json` content: [controls-patterns.md](controls-patterns.md). _(Tier A — load with `fui skill ref references/controls-patterns.md references/module-structure.md` before any module/UI work; `fui skill get` does not print it.)_
|
|
3
|
+
> Owns: project/module tree, per-file duties, where CSS/JS go (`style.css`, imports, `script.js`; never in header/body), `_moduleInfo.json`/`mTitle`, `HTMLOnly`, default meta tags. `uc-*.vue` rules: [component-design.md](component-design.md); `module.json` content: [controls-patterns.md](controls-patterns.md). _(Tier A — load with `fui skill ref references/controls-patterns.md references/module-structure.md` before any module/UI work; `fui skill get` does not print it.)_
|
|
4
4
|
|
|
5
5
|
Use when creating, refactoring or reviewing a module. With workspace access it is the real folder layout; in chat, use it to organize the response without assuming files exist.
|
|
6
6
|
|
|
@@ -33,10 +33,10 @@ Use when creating, refactoring or reviewing a module. With workspace access it i
|
|
|
33
33
|
|-- _moduleInfo.json # Required: module metadata + mTitle (page title) + HTMLOnly
|
|
34
34
|
|-- module.json # Required: data/watch/controls/set (unused when HTMLOnly=true)
|
|
35
35
|
|-- script.js # Recommended: helper logic for FUN/EXE/chart/transform
|
|
36
|
-
|-- style.css #
|
|
37
|
-
|-- header.html #
|
|
38
|
-
|-- body.html # HTMLOnly=false: supplementary body
|
|
39
|
-
| # HTMLOnly=true: entire page
|
|
36
|
+
|-- style.css # Module-wide CSS: the ONLY place for page CSS (fui module publish css)
|
|
37
|
+
|-- header.html # Inner <head>: <meta>/icon tags; normally empty (no CSS, no library tags)
|
|
38
|
+
|-- body.html # HTMLOnly=false: supplementary body markup, usually empty
|
|
39
|
+
| # HTMLOnly=true: entire page markup (no <style>, style="", <link>, <script>)
|
|
40
40
|
|-- imports/ # Module-scope import files
|
|
41
41
|
| `-- _imports.json # Declared module-level JS/CSS imports
|
|
42
42
|
`-- components/ # Optional: custom Vue components
|
|
@@ -57,11 +57,11 @@ Required: `_moduleInfo.json`, `module.json`. Recommended: `script.js`, `imports/
|
|
|
57
57
|
|
|
58
58
|
**script.js** — complex transforms, chart builders, debounce, parsing; expose functions for `FUN`/`EXE` and template helpers. Prefer a reusable function over large inline `EXE`.
|
|
59
59
|
|
|
60
|
-
**style.css** — module
|
|
60
|
+
**style.css** — all module CSS not tied to one component (both `HTMLOnly` values). Publish with `fui module publish css`; an empty file is not auto-cleared by `fui module publish html`. Component-local CSS goes in the component's `<style scoped>`. Placement rules: [§CSS and JS placement](#css-and-js-placement).
|
|
61
61
|
|
|
62
62
|
**\_moduleInfo.json** — keep `ProjectID`, `ModuleID`, `ModuleName`, `Framework` accurate. `mTitle` is the page title (edit it here; sent as `title` by `fui module publish html`). Read `HTMLOnly` before structuring anything.
|
|
63
63
|
|
|
64
|
-
**header.html** — inner `<head>` content only
|
|
64
|
+
**header.html** — inner `<head>` content only; no wrapper, no `<title>` (use `mTitle`). Normally **empty**: CSS goes to `style.css`, JS/CSS libraries to imports, page JS to `script.js` ([§CSS and JS placement](#css-and-js-placement)). What may stay: extra `<meta>` and non-CSS/JS `<link>` (`icon`, `manifest`, `preconnect`), plus the rare exception tag listed in that section. `HTMLOnly=true`: bring your own runtime through imports — read [HTMLOnly=true: no library is embedded](#htmlonlytrue-no-library-is-embedded) first. These meta tags are on every page — never repeat them:
|
|
65
65
|
|
|
66
66
|
```html
|
|
67
67
|
<meta charset="UTF-8" />
|
|
@@ -75,7 +75,38 @@ Required: `_moduleInfo.json`, `module.json`. Recommended: `script.js`, `imports/
|
|
|
75
75
|
- Vuetify breakpoints follow real device CSS pixels.
|
|
76
76
|
- `viewport-fit=cover` → fullscreen/`HTMLOnly` layouts touching top/bottom need `env(safe-area-inset-*)` padding (iOS notch/home indicator).
|
|
77
77
|
|
|
78
|
-
**body.html** — inner `<body>`
|
|
78
|
+
**body.html** — inner `<body>` markup only. `HTMLOnly=false`: supplementary HTML beside the Vue runtime, usually empty. `HTMLOnly=true`: the whole page markup (plain HTML or own Vue app with own `<div id="app">`/`<v-app>`), with its app code in `script.js`; FUI's default mount point is hidden. No `<style>`, static `style="…"`, `<link>` or `<script>` here ([§CSS and JS placement](#css-and-js-placement)). Server and publish command strip `<head>`/`<body>` wrappers.
|
|
79
|
+
|
|
80
|
+
## CSS and JS placement
|
|
81
|
+
|
|
82
|
+
`header.html` and `body.html` hold markup, never design or libraries. `style.css` and imports load as separate cacheable files (`style.css` as the module StyleCSS `<link>`), are visible to `fui import list`, `fui file status` and the render report, and keep CSS in one place instead of scattered through the page.
|
|
83
|
+
|
|
84
|
+
| Content | Goes to | Push |
|
|
85
|
+
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
86
|
+
| Module CSS: classes, layout, `@font-face`, `@media`, keyframes | `style.css` | `fui module publish css` |
|
|
87
|
+
| Component CSS | the component's `<style scoped>`, every selector prefixed ([component-design.md](component-design.md)) | `fui component update <name>` |
|
|
88
|
+
| JS/CSS library or CDN URL | `fui import new --type js\|css --content-type link --name <url> --sort N` | immediate |
|
|
89
|
+
| Own JS/CSS file to host | `fui import new --content-type text/javascript\|text/css`, then `fui import upload <fileId> -f <file>` | immediate |
|
|
90
|
+
| Page logic (also an `HTMLOnly` Vue app) | `script.js`: it runs after the body markup and after every import | `fui module publish script` |
|
|
91
|
+
| Images, fonts, documents | `fui cdn upload`, referenced as `/_cdn/<project>/…` from `style.css` or markup ([cdn-files.md](cdn-files.md)) | immediate |
|
|
92
|
+
|
|
93
|
+
Never in `header.html`/`body.html`:
|
|
94
|
+
|
|
95
|
+
- a `<style>` block or a static `style="…"` attribute → a named, prefixed class in `style.css`. A Vue `:style` binding whose value comes from data is fine; a constant value is not.
|
|
96
|
+
- `<link rel="stylesheet">` or `<script src>` → an import, in load order through `--sort`.
|
|
97
|
+
- inline `<script>` code → `script.js`.
|
|
98
|
+
|
|
99
|
+
**A module that already has them:** when the task edits `header.html`, `body.html` or the module's CSS/JS, move them in the same change: `<style>` content → `style.css` (keep rule order), each static `style="…"` → a class in `style.css`, each `<link>`/`<script src>` → `fui import new` keeping the old order, inline code → `script.js`; then delete them from header/body. Order shifts (`style.css` loads after project CSS; import scripts load after the body), so compare with `fui module simulate --render` and push everything: imports, `fui module publish css|script`, then `fui module preview` → `fui module publish html`. For any other edit to such a module, name the leftovers in the report and offer the move.
|
|
100
|
+
|
|
101
|
+
**Exceptions** (only when no import or file above can do it): imports emit a plain `<link rel="stylesheet">` or `<script src>`, so a tag that needs more stays in `header.html`:
|
|
102
|
+
|
|
103
|
+
- attributes an import cannot carry: `type="module"`, `nomodule`, `integrity`/`crossorigin`, `async`/`defer`, `data-*` config the library reads from its own tag;
|
|
104
|
+
- a config global that must exist **before** a library loads (e.g. `window.MathJax = {…}`), since `script.js` runs after the imports;
|
|
105
|
+
- a third-party embed snippet the vendor requires at a fixed spot in the markup.
|
|
106
|
+
|
|
107
|
+
Keep such a tag minimal, never put design CSS beside it, and tell the user which tag stayed and why.
|
|
108
|
+
|
|
109
|
+
`fui module validate`, `module check`, `module preview` and `module publish html` print a **header/body warning** block for each `<style>`, static `style="…"`, stylesheet `<link>`, `<script src>` and inline JS `<script>` they find, plus the placeholders an old FUI MCP wrote (`<style>/* Module styles */</style>`, `<!-- Module body -->`: delete them). Tags with an exception attribute above, `<script type="module">`, templates (`type="text/x-template"`) and JSON data scripts are not reported. The warnings never block a publish; clear the ones in files this task edits.
|
|
79
110
|
|
|
80
111
|
**imports/\_imports.json** — module-scope JS/CSS imports; entry `{ name, type, contentType, fileID, scope, sort }`. `sort` = load order: new imports use **>= 40** (40, 50, 60…); 1–39 is reserved for system/framework. Project-scope imports live in `{projectId}/imports/_imports.json`.
|
|
81
112
|
|
|
@@ -119,10 +150,7 @@ Not embedded, even if the project declares them:
|
|
|
119
150
|
| Project-level StyleCSS, `projectdefaultstyle.css` | shared project classes gone (incl. `.shrink`) |
|
|
120
151
|
| `<div id="fastProjectAPP">` | no mount point — build your own root in `body.html` |
|
|
121
152
|
|
|
122
|
-
**Declare every needed library in each HTMLOnly module**; project-level declarations do not help.
|
|
123
|
-
|
|
124
|
-
- `fui import new` into the module's `imports/_imports.json` with `--sort` >= 40 (see `fui import new --help`) — preferred: visible in `fui import list` and the `fui module simulate --render` report; or
|
|
125
|
-
- raw `<link>`/`<script>` in `header.html` — flexible, but no command lists them.
|
|
153
|
+
**Declare every needed library in each HTMLOnly module**; project-level declarations do not help. Use `fui import new` into the module's `imports/_imports.json`, one import per file in load order via `--sort` (see `fui import new --help`): imports are visible in `fui import list` and the `fui module simulate --render` report. A raw `<link>`/`<script>` in `header.html` only for the exceptions in [§CSS and JS placement](#css-and-js-placement). Page CSS still goes to `style.css` and the app code to `script.js` (both are emitted for HTMLOnly too).
|
|
126
154
|
|
|
127
155
|
**[script-map.md](script-map.md) does not apply here**: its "already bundled, no duplicate CDN" list is for `HTMLOnly=false` only. In HTMLOnly the CDN is required, not a duplicate.
|
|
128
156
|
|
|
@@ -131,8 +159,8 @@ Not embedded, even if the project declares them:
|
|
|
131
159
|
## Patterns
|
|
132
160
|
|
|
133
161
|
- **A — simple**: `_moduleInfo.json`, `module.json`, `script.js`, `imports/_imports.json`; no `components/` unless needed.
|
|
134
|
-
- **B — dashboard/report (recommended)**: `module.json` filters + action orchestration; `script.js` conversion/chart utils; `components/uc-*.vue` chart/table presentation; `
|
|
135
|
-
- **C — HTMLOnly page**: `_moduleInfo.json` (`HTMLOnly: true`), empty `module.json` skeleton, `
|
|
162
|
+
- **B — dashboard/report (recommended)**: `module.json` filters + action orchestration; `script.js` conversion/chart utils; `components/uc-*.vue` chart/table presentation; `style.css` module CSS, component CSS in each `.vue`. Keeps large `module.json` maintainable.
|
|
163
|
+
- **C — HTMLOnly page**: `_moduleInfo.json` (`HTMLOnly: true`), empty `module.json` skeleton, every JS/CSS library as a module import, `style.css` all page CSS, `body.html` page markup only, `script.js` the page/Vue app code; `components/` only if needed.
|
|
136
164
|
|
|
137
165
|
## Review Checklist
|
|
138
166
|
|
|
@@ -140,5 +168,5 @@ Not embedded, even if the project declares them:
|
|
|
140
168
|
2. false: valid `data/watch/controls/set`? true: `module.json` empty, all content in `body.html`?
|
|
141
169
|
3. Heavy logic in `script.js`, not oversized `EXE`?
|
|
142
170
|
4. Custom UI in `components/uc-*.vue`, registered in `_components.json`?
|
|
143
|
-
5.
|
|
144
|
-
6. `header.html`/`body.html` inner content only (no `<head>`/`<body>`)
|
|
171
|
+
5. Every JS/CSS library in `imports/_imports.json`, none as `<link>`/`<script src>` in header/body (exceptions: [§CSS and JS placement](#css-and-js-placement))?
|
|
172
|
+
6. `header.html`/`body.html` inner content only (no `<head>`/`<body>`), with no `<style>`, static `style="…"` or inline `<script>`; CSS in `style.css`, code in `script.js`?
|
|
@@ -56,7 +56,8 @@ Shared by all FUI projects:
|
|
|
56
56
|
- **`tblSysRight`** — `SystemRight` levels (0–9) of **one project** + `Note`; `9` always **Project Admin**
|
|
57
57
|
- **`tblFunction`** — `FunctionRight` definitions (`FunctionCode` + `FunctionName`) of **one project** — catalog of assignable functions, not per-user assignment
|
|
58
58
|
|
|
59
|
-
> **
|
|
59
|
+
> **Definitions** (which levels/codes exist) are the 8 `fui right system|function` commands; **assignments** (which user holds which level on the system) are the 5 `fui right user` commands. Both go through the SEC with your userToken; never call their `spAPI_SM_*` yourself.
|
|
60
|
+
- **`tblUserModule`** — who holds which `SystemRight` on which system; level `9` on a module makes that user its **SEC manager**
|
|
60
61
|
|
|
61
62
|
### ⚠️ Not `UserRight` — right to EDIT a project in the FUI IDE
|
|
62
63
|
|
|
@@ -67,7 +68,7 @@ Shared by all FUI projects:
|
|
|
67
68
|
| Scope | **Whole app** — one level per user | **Per project** |
|
|
68
69
|
| Stored in | `acc.tblSysRight` / `acc.tblFunction` | `tblA_UserProject` (FUI platform DB, not `acc`) |
|
|
69
70
|
| Runtime read | `vueData.user.SystemRight` / `.FunctionRight` | none — FUI IDE only |
|
|
70
|
-
| Commands | 8 `fui right …` below
|
|
71
|
+
| Commands | 8 + 5 `fui right …` below | 5 `fui user …` → [project-provisioning.md](project-provisioning.md) §Phase C |
|
|
71
72
|
|
|
72
73
|
The FUI IDE _is itself a FUI app_ (project `fp`), so `SystemRight` **on `fp`** is the developer's IDE right. Both axes **AND** (from real SP bodies):
|
|
73
74
|
|
|
@@ -140,11 +141,16 @@ Create / edit / delete are **three separate commands**: delete is 🔴 irreversi
|
|
|
140
141
|
3. `apiName`/`projectId` default to the session's active project — pass `apiName` for **another** project, or when the project has **several connections** and the right belongs to a non-default alias.
|
|
141
142
|
4. Server checks the caller: Select needs `SystemRight >= 2` on `acc`; Update needs higher, or admin (`9`) of the target project.
|
|
142
143
|
|
|
143
|
-
|
|
144
|
+
5. **Which SEC**: each tAPI host (LHU, LHBS, FUI, FAP …) runs its own SEC. A project with connections on several hosts makes every `right`/`db alias` command refuse until `--db <project/connection>` names the connection whose apiDomain + userToken to use; the output always says `SEC <apiDomain>`.
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
## 5 commands — who holds a level (`tblUserModule`)
|
|
147
|
+
|
|
148
|
+
| Command | Role | Safety |
|
|
149
|
+
| --------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
150
|
+
| `fui right user list [--api-name a] [--db c]` | Users of the system with their level and FunctionRights | Read-only |
|
|
151
|
+
| `fui right user search <UserID or username prefix> [--db c]` | Find a SEC account (top 50) | Read-only — the only source of the exact SEC `UserID` (≤ 9 chars, not the FUI `DEV…` id) |
|
|
152
|
+
| `fui right user add <UserID> --sys-right N [--api-name a] [--db c]` | Give a user with no right on the system level `N` | Level must be defined (`fui right system new N` first); existing user = hard error → `set` |
|
|
153
|
+
| `fui right user set <UserID> --sys-right N …` | Change the level of a user who has one | No row = hard error → `add` |
|
|
154
|
+
| `fui right user remove <UserID> --confirm-write …` | Remove the user from the system | 🔴 Also deletes every FunctionRight they hold there; ask first, then `--confirm-write` |
|
|
155
|
+
|
|
156
|
+
Show the `search` table and let the user pick before `add`: names repeat. A new system's manager = `fui right system new 9` then `fui right user add <UserID> --sys-right 9` ([project-provisioning.md](project-provisioning.md) Phase C).
|
|
@@ -120,7 +120,7 @@ height: calc(100vh - 48px);
|
|
|
120
120
|
height: 100vh;
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
Applies to `module.json` (`:height` of `f-table`, `f-echart`...) and to CSS in `
|
|
123
|
+
Applies to `module.json` (`:height` of `f-table`, `f-echart`...) and to CSS in `style.css`/components for `HTMLOnly=true` pages.
|
|
124
124
|
|
|
125
125
|
## menuLeft (sidebar)
|
|
126
126
|
|