@fui-org/fui-cli 2.1.3 → 2.2.0
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 +27 -7
- package/dist/fui-qrb1j9jz.js +397 -0
- package/dist/fui.js +1 -1
- package/package.json +1 -1
- package/skills/fui/SKILL.md +143 -38
- package/skills/fui/agents/fui-builder.md +62 -0
- package/skills/fui/agents/fui-tester.md +77 -0
- package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
- package/skills/{fui-skill → fui}/examples/component.vue +162 -162
- package/skills/{fui-skill → fui}/references/INDEX.md +5 -4
- package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
- package/skills/{fui-skill → fui}/references/component-design.md +2 -2
- package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
- package/skills/{fui-skill → fui}/references/component-table.md +287 -287
- package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
- package/skills/{fui-skill → fui}/references/components-display.md +141 -141
- package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
- package/skills/{fui-skill → fui}/references/components-input.md +335 -335
- package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
- package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
- package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
- package/skills/{fui-skill → fui}/references/default-function.md +456 -456
- package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
- package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
- package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
- package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
- package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
- package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
- package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
- package/skills/{fui-skill → fui}/references/new-session.md +1 -2
- package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
- package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
- package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
- package/skills/{fui-skill → fui}/references/project-config.md +303 -303
- package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
- package/skills/{fui-skill → fui}/references/script-map.md +262 -262
- package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
- package/skills/{fui-skill → fui}/references/system-design.md +2 -2
- package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
- package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
- package/skills/fui/references/team-run.md +141 -0
- package/skills/fui/references/tools-registry.md +211 -0
- package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
- package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
- package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
- package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
- package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
- package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
- package/skills/{fui-skill → fui}/references/verification.md +11 -11
- package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
- package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
- package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
- package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
- package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
- package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
- package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
- package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
- package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
- package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
- package/skills/fui-target/hooks/register.tsx +2 -0
- package/skills/fui-target/types/index.d.ts +1 -0
- package/dist/fui-hk5frcn2.js +0 -381
- package/skills/fui-skill/SKILL.md +0 -139
- package/skills/fui-skill/references/tools-registry.md +0 -84
- /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
- /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
- /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
- /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
- /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
- /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
- /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
- /package/skills/{fui-skill → fui}/scripts/fsheet.js +0 -0
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
# Module Structure
|
|
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 —
|
|
4
|
-
|
|
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
|
-
|
|
7
|
-
## Local Structure
|
|
8
|
-
|
|
9
|
-
### Project-level
|
|
10
|
-
|
|
11
|
-
```text
|
|
12
|
-
{projectId}/
|
|
13
|
-
|-- _projectInfo.json # Project metadata (ProjectID, ProjectName, Framework, etc.)
|
|
14
|
-
|-- project.json # Full project config (data/watch/controls/set at project scope)
|
|
15
|
-
|-- imports/ # Project-scope import files
|
|
16
|
-
| `-- _imports.json # Declared project-level JS/CSS imports
|
|
17
|
-
|-- components/ # Project-scope Vue components
|
|
18
|
-
| |-- _components.json # Component registry
|
|
19
|
-
| `-- uc-*.vue # Project-level custom components
|
|
20
|
-
|-- _db/ # Local DB workspace (see db-workflow.md)
|
|
21
|
-
| |-- _connections.json # v2 registry; key = friendly connectionName/folder
|
|
22
|
-
| `-- {connectionName}/ # schema.json + stored-procedure .sql files
|
|
23
|
-
|-- modules/ # All modules in this project
|
|
24
|
-
| |-- _modules.json # Module list metadata
|
|
25
|
-
| `-- {moduleId}/ # One folder per module (see module-level below)
|
|
26
|
-
`-- skills/ # FUI skill files (auto-copied on checkout)
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### Module-level (`modules/{moduleId}/`)
|
|
30
|
-
|
|
31
|
-
```text
|
|
32
|
-
{moduleId}/
|
|
33
|
-
|-- _moduleInfo.json # Required: module metadata + mTitle (page title) + HTMLOnly
|
|
34
|
-
|-- module.json # Required: data/watch/controls/set (unused when HTMLOnly=true)
|
|
35
|
-
|-- script.js # Recommended: helper logic for FUN/EXE/chart/transform
|
|
36
|
-
|-- style.css # Optional: module-wide CSS (published via fui module publish css)
|
|
37
|
-
|-- header.html # Full <head> content: <link>, <style>, <script> tags
|
|
38
|
-
|-- body.html # HTMLOnly=false: supplementary body HTML
|
|
39
|
-
| # HTMLOnly=true: entire page content (custom HTML/Vue app)
|
|
40
|
-
|-- imports/ # Module-scope import files
|
|
41
|
-
| `-- _imports.json # Declared module-level JS/CSS imports
|
|
42
|
-
`-- components/ # Optional: custom Vue components
|
|
43
|
-
|-- _components.json # Required when using custom components
|
|
44
|
-
`-- uc-*.vue # Custom components (prefix uc-)
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Required: `_moduleInfo.json`, `module.json`. Recommended: `script.js`, `imports/_imports.json`. Optional: `header.html`, `body.html`, `style.css`, `components/`.
|
|
48
|
-
|
|
49
|
-
## Chat Without Workspace
|
|
50
|
-
|
|
51
|
-
- Present the tree as canonical layout, not actual disk state; return each file in its own labeled code block.
|
|
52
|
-
- Ask the user to paste `_moduleInfo.json`, `module.json`, `script.js` or components when a review/patch depends on them. Scope advice to provided files; never invent unseen ones.
|
|
53
|
-
|
|
54
|
-
## File Duties
|
|
55
|
-
|
|
56
|
-
**module.json** — all runtime config in `data`, `watch`, `controls`, `set`; `controls` inside grid wrapper (`container > rows > cols`); business actions in `data`, triggered by `CALL`. Patterns: [`examples/module-patterns.json`](../examples/module-patterns.json); f-table props/header types: [`examples/f-table-patterns.json`](../examples/f-table-patterns.json).
|
|
57
|
-
|
|
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
|
-
|
|
60
|
-
**style.css** — module-wide CSS not tied to one component. 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>`.
|
|
61
|
-
|
|
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
|
-
|
|
64
|
-
**header.html** — inner `<head>` content only (`<link>`, `<style>`, `<script>`, `<meta>`); no wrapper, no `<title>` (use `mTitle`). `HTMLOnly=false`: usually CSS only; server injects framework and project scripts. `HTMLOnly=true`: bring your own runtime — read [HTMLOnly=true: no library is embedded](#htmlonlytrue-no-library-is-embedded) first. These meta tags are on every page — never repeat them:
|
|
65
|
-
|
|
66
|
-
```html
|
|
67
|
-
<meta charset="UTF-8" />
|
|
68
|
-
<meta
|
|
69
|
-
name="viewport"
|
|
70
|
-
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
|
|
71
|
-
/>
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
- No pinch-zoom → fonts/buttons must be readable and tappable at natural size on mobile.
|
|
75
|
-
- Vuetify breakpoints follow real device CSS pixels.
|
|
76
|
-
- `viewport-fit=cover` → fullscreen/`HTMLOnly` layouts touching top/bottom need `env(safe-area-inset-*)` padding (iOS notch/home indicator).
|
|
77
|
-
|
|
78
|
-
**body.html** — inner `<body>` content only. `HTMLOnly=false`: supplementary HTML beside the Vue runtime, usually empty. `HTMLOnly=true`: the whole page (plain HTML or own Vue app with own `<div id="app">`/`<v-app>`); FUI's default mount point is hidden. Server and publish command strip `<head>`/`<body>` wrappers.
|
|
79
|
-
|
|
80
|
-
**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
|
-
|
|
82
|
-
**components/\_components.json** — registers `uc-*`. Before publish an entry may hold only `comName`; `comID` is server-managed after publish/sync. Never invent `comID`.
|
|
83
|
-
|
|
84
|
-
**components/uc-\*.vue** — `uc-` prefix, kebab-case. Hold component UI complexity here, not in `module.json`. Contract: props in, emits out, slots to extend. No page-specific API/route logic unless the coupling is intentional and unavoidable. `scoped` does not really scope: prefix every selector with a unique class matching the component name ([component-design.md](component-design.md)). No backtick template strings in `<template>`.
|
|
85
|
-
|
|
86
|
-
**\_projectInfo.json** — written on checkout (`ProjectID`, `ProjectName`, `GroupName`, `Framework`, `pDomain`, `fetchedAt`). Read-only.
|
|
87
|
-
|
|
88
|
-
**project.json** — one `data` object of project defaults (`apiDomain`, `login`, `userInfo`, `menu`, `menuLeft`, `menuStyle`, `menuComponent`, `domainSetting`, …). Runtime merges it with `module.json` `set`; module wins, so declare only differences. Fields, menu items, `right` rules: [project-config.md](project-config.md).
|
|
89
|
-
|
|
90
|
-
## Naming
|
|
91
|
-
|
|
92
|
-
- Module folder: project's module ID convention.
|
|
93
|
-
- Use a component in `module.json` via `el: "uc-..."`, props in `attr` with kebab-case names.
|
|
94
|
-
|
|
95
|
-
## HTMLOnly Mode
|
|
96
|
-
|
|
97
|
-
Boolean in `_moduleInfo.json`. **Check it first.**
|
|
98
|
-
|
|
99
|
-
- **false (default)**: runtime reads `module.json` and bootstraps Vue; `uc-*.vue` and `script.js` helpers fully supported.
|
|
100
|
-
- **true**: `module.json` ignored — keep it `data:[], watch:{}, controls:[], set:{}`; FUI `controls`/`data`/`watch` have no effect. `body.html` is the entire page. Use for standalone tools, custom editors, pages needing their own runtime or a non-grid layout.
|
|
101
|
-
- **Full-height**: if the menu shows (not `set.menu: false`) it takes a fixed 48px — subtract 48px more from any root `height: 100vh` / `calc(100vh - Npx)`. See [project-config.md](project-config.md) §menu.
|
|
102
|
-
|
|
103
|
-
#### HTMLOnly=true: no library is embedded
|
|
104
|
-
|
|
105
|
-
Most common mistake; it shows **no error while writing**, only a blank page after deploy. The server emits just three things:
|
|
106
|
-
|
|
107
|
-
1. this module's imports (`{moduleId}/imports/_imports.json`),
|
|
108
|
-
2. module-level StyleCSS (`style.css` + `<style>` of module-level `uc-*.vue`),
|
|
109
|
-
3. the `moduledata` bundle (`$moduleUI` + `script.js` + module-level components).
|
|
110
|
-
|
|
111
|
-
Not embedded, even if the project declares them:
|
|
112
|
-
|
|
113
|
-
| Missing | Symptom |
|
|
114
|
-
| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
115
|
-
| Framework V2/V3 — `vue.global.min.js`, `vuetify*.js/css`, `fastproject*.js`, `component*.js`, `defaultfunction*.js` | `Vue is not defined`, `<v-btn>` not rendered, no `f-*`/`t-*` |
|
|
116
|
-
| jQuery, lodash (`_`), `moment`/`dayjs`, `numeral`, `jquery-confirm` | `$ is not defined`, `_ is not defined` |
|
|
117
|
-
| Roboto, Material Design Icons (`mdi-*`) | wrong font, icons as empty boxes |
|
|
118
|
-
| `projectdata` bundle — `$projectData`, `$projectGroupSetting`, project-level components | `apiDomain`/`menu`/`login` undefined; project `uc-*` unknown |
|
|
119
|
-
| Project-level StyleCSS, `projectdefaultstyle.css` | shared project classes gone (incl. `.shrink`) |
|
|
120
|
-
| `<div id="fastProjectAPP">` | no mount point — build your own root in `body.html` |
|
|
121
|
-
|
|
122
|
-
**Declare every needed library in each HTMLOnly module**; project-level declarations do not help. Either:
|
|
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.
|
|
126
|
-
|
|
127
|
-
**[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
|
-
|
|
129
|
-
`fui module simulate --render` renders HTMLOnly modules exactly like production (no framework, projectdata or `#fastProjectAPP`) and warns so; a missing library breaks the screenshot like the real page.
|
|
130
|
-
|
|
131
|
-
## Patterns
|
|
132
|
-
|
|
133
|
-
- **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; `header.html` module/component CSS. Keeps large `module.json` maintainable.
|
|
135
|
-
- **C — HTMLOnly page**: `_moduleInfo.json` (`HTMLOnly: true`), empty `module.json` skeleton, `header.html` all CSS + JS libraries, `body.html` whole page (plain HTML or self-contained Vue app); `components/`/`script.js` only if needed.
|
|
136
|
-
|
|
137
|
-
## Review Checklist
|
|
138
|
-
|
|
139
|
-
1. `HTMLOnly` checked first (decides which files matter).
|
|
140
|
-
2. false: valid `data/watch/controls/set`? true: `module.json` empty, all content in `body.html`?
|
|
141
|
-
3. Heavy logic in `script.js`, not oversized `EXE`?
|
|
142
|
-
4. Custom UI in `components/uc-*.vue`, registered in `_components.json`?
|
|
143
|
-
5. Imports in `imports/_imports.json`?
|
|
144
|
-
6. `header.html`/`body.html` inner content only (no `<head>`/`<body>`)?
|
|
1
|
+
# Module Structure
|
|
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.)_
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
## Local Structure
|
|
8
|
+
|
|
9
|
+
### Project-level
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
{projectId}/
|
|
13
|
+
|-- _projectInfo.json # Project metadata (ProjectID, ProjectName, Framework, etc.)
|
|
14
|
+
|-- project.json # Full project config (data/watch/controls/set at project scope)
|
|
15
|
+
|-- imports/ # Project-scope import files
|
|
16
|
+
| `-- _imports.json # Declared project-level JS/CSS imports
|
|
17
|
+
|-- components/ # Project-scope Vue components
|
|
18
|
+
| |-- _components.json # Component registry
|
|
19
|
+
| `-- uc-*.vue # Project-level custom components
|
|
20
|
+
|-- _db/ # Local DB workspace (see db-workflow.md)
|
|
21
|
+
| |-- _connections.json # v2 registry; key = friendly connectionName/folder
|
|
22
|
+
| `-- {connectionName}/ # schema.json + stored-procedure .sql files
|
|
23
|
+
|-- modules/ # All modules in this project
|
|
24
|
+
| |-- _modules.json # Module list metadata
|
|
25
|
+
| `-- {moduleId}/ # One folder per module (see module-level below)
|
|
26
|
+
`-- skills/ # FUI skill files (auto-copied on checkout)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Module-level (`modules/{moduleId}/`)
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
{moduleId}/
|
|
33
|
+
|-- _moduleInfo.json # Required: module metadata + mTitle (page title) + HTMLOnly
|
|
34
|
+
|-- module.json # Required: data/watch/controls/set (unused when HTMLOnly=true)
|
|
35
|
+
|-- script.js # Recommended: helper logic for FUN/EXE/chart/transform
|
|
36
|
+
|-- style.css # Optional: module-wide CSS (published via fui module publish css)
|
|
37
|
+
|-- header.html # Full <head> content: <link>, <style>, <script> tags
|
|
38
|
+
|-- body.html # HTMLOnly=false: supplementary body HTML
|
|
39
|
+
| # HTMLOnly=true: entire page content (custom HTML/Vue app)
|
|
40
|
+
|-- imports/ # Module-scope import files
|
|
41
|
+
| `-- _imports.json # Declared module-level JS/CSS imports
|
|
42
|
+
`-- components/ # Optional: custom Vue components
|
|
43
|
+
|-- _components.json # Required when using custom components
|
|
44
|
+
`-- uc-*.vue # Custom components (prefix uc-)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Required: `_moduleInfo.json`, `module.json`. Recommended: `script.js`, `imports/_imports.json`. Optional: `header.html`, `body.html`, `style.css`, `components/`.
|
|
48
|
+
|
|
49
|
+
## Chat Without Workspace
|
|
50
|
+
|
|
51
|
+
- Present the tree as canonical layout, not actual disk state; return each file in its own labeled code block.
|
|
52
|
+
- Ask the user to paste `_moduleInfo.json`, `module.json`, `script.js` or components when a review/patch depends on them. Scope advice to provided files; never invent unseen ones.
|
|
53
|
+
|
|
54
|
+
## File Duties
|
|
55
|
+
|
|
56
|
+
**module.json** — all runtime config in `data`, `watch`, `controls`, `set`; `controls` inside grid wrapper (`container > rows > cols`); business actions in `data`, triggered by `CALL`. Patterns: [`examples/module-patterns.json`](../examples/module-patterns.json); f-table props/header types: [`examples/f-table-patterns.json`](../examples/f-table-patterns.json).
|
|
57
|
+
|
|
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
|
+
|
|
60
|
+
**style.css** — module-wide CSS not tied to one component. 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>`.
|
|
61
|
+
|
|
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
|
+
|
|
64
|
+
**header.html** — inner `<head>` content only (`<link>`, `<style>`, `<script>`, `<meta>`); no wrapper, no `<title>` (use `mTitle`). `HTMLOnly=false`: usually CSS only; server injects framework and project scripts. `HTMLOnly=true`: bring your own runtime — read [HTMLOnly=true: no library is embedded](#htmlonlytrue-no-library-is-embedded) first. These meta tags are on every page — never repeat them:
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<meta charset="UTF-8" />
|
|
68
|
+
<meta
|
|
69
|
+
name="viewport"
|
|
70
|
+
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
|
|
71
|
+
/>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- No pinch-zoom → fonts/buttons must be readable and tappable at natural size on mobile.
|
|
75
|
+
- Vuetify breakpoints follow real device CSS pixels.
|
|
76
|
+
- `viewport-fit=cover` → fullscreen/`HTMLOnly` layouts touching top/bottom need `env(safe-area-inset-*)` padding (iOS notch/home indicator).
|
|
77
|
+
|
|
78
|
+
**body.html** — inner `<body>` content only. `HTMLOnly=false`: supplementary HTML beside the Vue runtime, usually empty. `HTMLOnly=true`: the whole page (plain HTML or own Vue app with own `<div id="app">`/`<v-app>`); FUI's default mount point is hidden. Server and publish command strip `<head>`/`<body>` wrappers.
|
|
79
|
+
|
|
80
|
+
**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
|
+
|
|
82
|
+
**components/\_components.json** — registers `uc-*`. Before publish an entry may hold only `comName`; `comID` is server-managed after publish/sync. Never invent `comID`.
|
|
83
|
+
|
|
84
|
+
**components/uc-\*.vue** — `uc-` prefix, kebab-case. Hold component UI complexity here, not in `module.json`. Contract: props in, emits out, slots to extend. No page-specific API/route logic unless the coupling is intentional and unavoidable. `scoped` does not really scope: prefix every selector with a unique class matching the component name ([component-design.md](component-design.md)). No backtick template strings in `<template>`.
|
|
85
|
+
|
|
86
|
+
**\_projectInfo.json** — written on checkout (`ProjectID`, `ProjectName`, `GroupName`, `Framework`, `pDomain`, `fetchedAt`). Read-only.
|
|
87
|
+
|
|
88
|
+
**project.json** — one `data` object of project defaults (`apiDomain`, `login`, `userInfo`, `menu`, `menuLeft`, `menuStyle`, `menuComponent`, `domainSetting`, …). Runtime merges it with `module.json` `set`; module wins, so declare only differences. Fields, menu items, `right` rules: [project-config.md](project-config.md).
|
|
89
|
+
|
|
90
|
+
## Naming
|
|
91
|
+
|
|
92
|
+
- Module folder: project's module ID convention.
|
|
93
|
+
- Use a component in `module.json` via `el: "uc-..."`, props in `attr` with kebab-case names.
|
|
94
|
+
|
|
95
|
+
## HTMLOnly Mode
|
|
96
|
+
|
|
97
|
+
Boolean in `_moduleInfo.json`. **Check it first.**
|
|
98
|
+
|
|
99
|
+
- **false (default)**: runtime reads `module.json` and bootstraps Vue; `uc-*.vue` and `script.js` helpers fully supported.
|
|
100
|
+
- **true**: `module.json` ignored — keep it `data:[], watch:{}, controls:[], set:{}`; FUI `controls`/`data`/`watch` have no effect. `body.html` is the entire page. Use for standalone tools, custom editors, pages needing their own runtime or a non-grid layout.
|
|
101
|
+
- **Full-height**: if the menu shows (not `set.menu: false`) it takes a fixed 48px — subtract 48px more from any root `height: 100vh` / `calc(100vh - Npx)`. See [project-config.md](project-config.md) §menu.
|
|
102
|
+
|
|
103
|
+
#### HTMLOnly=true: no library is embedded
|
|
104
|
+
|
|
105
|
+
Most common mistake; it shows **no error while writing**, only a blank page after deploy. The server emits just three things:
|
|
106
|
+
|
|
107
|
+
1. this module's imports (`{moduleId}/imports/_imports.json`),
|
|
108
|
+
2. module-level StyleCSS (`style.css` + `<style>` of module-level `uc-*.vue`),
|
|
109
|
+
3. the `moduledata` bundle (`$moduleUI` + `script.js` + module-level components).
|
|
110
|
+
|
|
111
|
+
Not embedded, even if the project declares them:
|
|
112
|
+
|
|
113
|
+
| Missing | Symptom |
|
|
114
|
+
| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
115
|
+
| Framework V2/V3 — `vue.global.min.js`, `vuetify*.js/css`, `fastproject*.js`, `component*.js`, `defaultfunction*.js` | `Vue is not defined`, `<v-btn>` not rendered, no `f-*`/`t-*` |
|
|
116
|
+
| jQuery, lodash (`_`), `moment`/`dayjs`, `numeral`, `jquery-confirm` | `$ is not defined`, `_ is not defined` |
|
|
117
|
+
| Roboto, Material Design Icons (`mdi-*`) | wrong font, icons as empty boxes |
|
|
118
|
+
| `projectdata` bundle — `$projectData`, `$projectGroupSetting`, project-level components | `apiDomain`/`menu`/`login` undefined; project `uc-*` unknown |
|
|
119
|
+
| Project-level StyleCSS, `projectdefaultstyle.css` | shared project classes gone (incl. `.shrink`) |
|
|
120
|
+
| `<div id="fastProjectAPP">` | no mount point — build your own root in `body.html` |
|
|
121
|
+
|
|
122
|
+
**Declare every needed library in each HTMLOnly module**; project-level declarations do not help. Either:
|
|
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.
|
|
126
|
+
|
|
127
|
+
**[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
|
+
|
|
129
|
+
`fui module simulate --render` renders HTMLOnly modules exactly like production (no framework, projectdata or `#fastProjectAPP`) and warns so; a missing library breaks the screenshot like the real page.
|
|
130
|
+
|
|
131
|
+
## Patterns
|
|
132
|
+
|
|
133
|
+
- **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; `header.html` module/component CSS. Keeps large `module.json` maintainable.
|
|
135
|
+
- **C — HTMLOnly page**: `_moduleInfo.json` (`HTMLOnly: true`), empty `module.json` skeleton, `header.html` all CSS + JS libraries, `body.html` whole page (plain HTML or self-contained Vue app); `components/`/`script.js` only if needed.
|
|
136
|
+
|
|
137
|
+
## Review Checklist
|
|
138
|
+
|
|
139
|
+
1. `HTMLOnly` checked first (decides which files matter).
|
|
140
|
+
2. false: valid `data/watch/controls/set`? true: `module.json` empty, all content in `body.html`?
|
|
141
|
+
3. Heavy logic in `script.js`, not oversized `EXE`?
|
|
142
|
+
4. Custom UI in `components/uc-*.vue`, registered in `_components.json`?
|
|
143
|
+
5. Imports in `imports/_imports.json`?
|
|
144
|
+
6. `header.html`/`body.html` inner content only (no `<head>`/`<body>`)?
|
|
@@ -84,8 +84,7 @@ Report **PID + folder**. No new process ⇒ say it failed; **never report succes
|
|
|
84
84
|
|
|
85
85
|
## 5. The new session is an INDEPENDENT process
|
|
86
86
|
|
|
87
|
-
- **Own session state**: active module target, skill-loaded
|
|
88
|
-
- **Loads the newest build**: if fui code was just changed and the current session still runs the old build, the new session runs the new one — a way to **verify a newly added command** without restarting the in-progress session.
|
|
87
|
+
- **Own session state**: active module target, skill-loaded mark, publish approval and verified-SP list are separate; fui keeps one state file per Claude Code session (or per `FUI_SESSION` when it is set). The new session must run `fui skill get` and `fui use` itself.
|
|
89
88
|
- **You cannot type into that window.** Communicate via `ListAgents` → `SendMessage` (it appears as a peer session); how to HAND OUT WORK (not just talk) is in §6.
|
|
90
89
|
- **Permissions are per session.** Never ask another session to run an action blocked here — that routes around the user's decision.
|
|
91
90
|
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
# PDF Generation with pdfmake
|
|
2
|
-
|
|
3
|
-
> Owns: **`f-pdfmake`: docDefinition, Vietnamese fonts, print/download PDF**.
|
|
4
|
-
|
|
5
|
-
Complex PDFs with `pdfmake` in FUI (via the `f-pdfmake` component).
|
|
6
|
-
|
|
7
|
-
## Dynamic Tables
|
|
8
|
-
|
|
9
|
-
Map a data array to table rows:
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
body: [
|
|
13
|
-
[
|
|
14
|
-
{ text: "STT", bold: true },
|
|
15
|
-
{ text: "Name", bold: true },
|
|
16
|
-
],
|
|
17
|
-
...data.items.map((item) => [item.index, item.name]),
|
|
18
|
-
];
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## SVG Checkboxes
|
|
22
|
-
|
|
23
|
-
Unicode (☑/☐) may not render in some PDF fonts. Use SVG paths:
|
|
24
|
-
|
|
25
|
-
```javascript
|
|
26
|
-
const checkedSvg = '<svg ...>...</svg>';
|
|
27
|
-
const uncheckedSvg = '<svg ...>...</svg>';
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
svg: item.isChecked ? checkedSvg : uncheckedSvg,
|
|
31
|
-
width: 14
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Complex Layouts
|
|
36
|
-
|
|
37
|
-
Use `columns` for layouts a table can't handle (e.g. checkbox beside text):
|
|
38
|
-
|
|
39
|
-
```javascript
|
|
40
|
-
{
|
|
41
|
-
columns: [
|
|
42
|
-
{ svg: checkedSvg, width: 14 },
|
|
43
|
-
{ text: " Label text", width: "*" },
|
|
44
|
-
];
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Signature Section Table
|
|
49
|
-
|
|
50
|
-
Use a nested table for an aligned signature block:
|
|
51
|
-
|
|
52
|
-
```javascript
|
|
53
|
-
table: {
|
|
54
|
-
widths: ['16%', '16%', '16%', '16%', '16%', '16%'],
|
|
55
|
-
body: [
|
|
56
|
-
[{ text: 'Title', colSpan: 3 }, {}, {}, { text: 'Title', colSpan: 3 }, {}, {}],
|
|
57
|
-
['Sign 1', 'Sign 2', 'Sign 3', 'Sign 4', 'Sign 5', 'Sign 6']
|
|
58
|
-
]
|
|
59
|
-
}
|
|
60
|
-
```
|
|
1
|
+
# PDF Generation with pdfmake
|
|
2
|
+
|
|
3
|
+
> Owns: **`f-pdfmake`: docDefinition, Vietnamese fonts, print/download PDF**.
|
|
4
|
+
|
|
5
|
+
Complex PDFs with `pdfmake` in FUI (via the `f-pdfmake` component).
|
|
6
|
+
|
|
7
|
+
## Dynamic Tables
|
|
8
|
+
|
|
9
|
+
Map a data array to table rows:
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
body: [
|
|
13
|
+
[
|
|
14
|
+
{ text: "STT", bold: true },
|
|
15
|
+
{ text: "Name", bold: true },
|
|
16
|
+
],
|
|
17
|
+
...data.items.map((item) => [item.index, item.name]),
|
|
18
|
+
];
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## SVG Checkboxes
|
|
22
|
+
|
|
23
|
+
Unicode (☑/☐) may not render in some PDF fonts. Use SVG paths:
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
const checkedSvg = '<svg ...>...</svg>';
|
|
27
|
+
const uncheckedSvg = '<svg ...>...</svg>';
|
|
28
|
+
|
|
29
|
+
{
|
|
30
|
+
svg: item.isChecked ? checkedSvg : uncheckedSvg,
|
|
31
|
+
width: 14
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Complex Layouts
|
|
36
|
+
|
|
37
|
+
Use `columns` for layouts a table can't handle (e.g. checkbox beside text):
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
{
|
|
41
|
+
columns: [
|
|
42
|
+
{ svg: checkedSvg, width: 14 },
|
|
43
|
+
{ text: " Label text", width: "*" },
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Signature Section Table
|
|
49
|
+
|
|
50
|
+
Use a nested table for an aligned signature block:
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
table: {
|
|
54
|
+
widths: ['16%', '16%', '16%', '16%', '16%', '16%'],
|
|
55
|
+
body: [
|
|
56
|
+
[{ text: 'Title', colSpan: 3 }, {}, {}, { text: 'Title', colSpan: 3 }, {}, {}],
|
|
57
|
+
['Sign 1', 'Sign 2', 'Sign 3', 'Sign 4', 'Sign 5', 'Sign 6']
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
```
|
|
@@ -18,7 +18,7 @@ Never answer from guesses or previously read code/schema; fetch **live**:
|
|
|
18
18
|
|
|
19
19
|
Why it survives verification:
|
|
20
20
|
|
|
21
|
-
1. **Preview lies.** `fui module simulate` and `--render` **grant the preview user exactly the codes scanned from the module** (so menus don't vanish wrongly) — invented codes still render. Both check the cache and print `🚨 FunctionRight
|
|
21
|
+
1. **Preview lies.** `fui module simulate` and `--render` **grant the preview user exactly the codes scanned from the module** (so menus don't vanish wrongly) — invented codes still render. Both check the cache and print `🚨 FunctionRight NOT DEFINED in acc: …`; **read that line, not just the image**.
|
|
22
22
|
2. **SP can't help.** `@sys_FunctionRight` holds only codes **actually granted**; a missing code never matches.
|
|
23
23
|
3. **Never infer codes from names/old comments.** Only truth: `fui right function list` / `fui right system list`.
|
|
24
24
|
|