@akanjs/cli 0.0.143 → 0.0.145
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/cjs/index.js +2310 -3101
- package/cjs/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/cjs/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/cjs/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/cjs/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/cjs/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/cjs/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/cjs/src/guidelines/framework/framework.instruction.md +1112 -0
- package/cjs/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/cjs/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/cjs/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/cjs/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/cjs/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/cjs/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/cjs/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/cjs/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/cjs/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/cjs/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/cjs/src/templates/module/__model__.dictionary.js +4 -5
- package/esm/index.js +2398 -3184
- package/esm/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/esm/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/esm/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/esm/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/esm/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/esm/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/esm/src/guidelines/framework/framework.instruction.md +1112 -0
- package/esm/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/esm/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/esm/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/esm/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/esm/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/esm/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/esm/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/esm/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/esm/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/esm/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/esm/src/templates/module/__model__.dictionary.js +4 -5
- package/package.json +3 -1
- package/src/guideline/guideline.command.d.ts +7 -0
- package/src/guideline/guideline.prompt.d.ts +15 -0
- package/src/guideline/guideline.runner.d.ts +5 -0
- package/src/guideline/guideline.script.d.ts +6 -0
- package/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
- package/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/src/guidelines/componentRule/componentRule.instruction.md +732 -0
- package/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
- package/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
- package/src/guidelines/framework/framework.instruction.md +1112 -0
- package/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
- package/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
- package/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
- package/src/guidelines/modelService/modelService.instruction.md +935 -0
- package/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
- package/src/guidelines/modelStore/modelStore.instruction.md +591 -0
- package/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
- package/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
- package/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/src/guidelines/modelView/modelView.instruction.md +1005 -0
- package/src/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
- package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
- package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
- package/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/src/module/module.command.d.ts +0 -1
- package/src/module/module.prompt.d.ts +2 -15
- package/src/module/module.request.d.ts +22 -18
- package/src/module/module.runner.d.ts +1 -17
- package/src/module/module.script.d.ts +0 -1
- package/src/scalar/scalar.command.d.ts +7 -0
- package/src/scalar/scalar.prompt.d.ts +23 -0
- package/src/scalar/scalar.runner.d.ts +13 -0
- package/src/scalar/scalar.script.d.ts +6 -0
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -47
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -128
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -42
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -50
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -41
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -51
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -43
- package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -60
- package/cjs/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -54
- package/cjs/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
- package/cjs/src/templates/app/app/[lang]/admin/layout.js +0 -54
- package/cjs/src/templates/app/app/[lang]/admin/page.js +0 -63
- package/cjs/src/templates/app/app/csr.js +0 -34
- package/cjs/src/templates/app/app/index.html.template +0 -13
- package/cjs/src/templates/app/app/layout.js +0 -38
- package/cjs/src/templates/app/capacitor.config.ts.template +0 -8
- package/cjs/src/templates/app/env/env.client.debug.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.develop.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.local.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.main.ts.template +0 -7
- package/cjs/src/templates/app/env/env.client.testing.ts.template +0 -7
- package/cjs/src/templates/app/env/env.server.debug.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.develop.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.local.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.main.ts.template +0 -15
- package/cjs/src/templates/app/env/env.server.testing.ts.template +0 -7
- package/cjs/src/templates/app/lib/setting/Setting.Template.js +0 -57
- package/cjs/src/templates/app/lib/setting/Setting.Unit.js +0 -38
- package/cjs/src/templates/app/lib/setting/Setting.Util.js +0 -34
- package/cjs/src/templates/app/lib/setting/Setting.View.js +0 -51
- package/cjs/src/templates/app/lib/setting/Setting.Zone.js +0 -80
- package/cjs/src/templates/app/lib/setting/index.js +0 -61
- package/cjs/src/templates/app/lib/summary/Summary.Template.js +0 -43
- package/cjs/src/templates/app/lib/summary/Summary.Unit.js +0 -38
- package/cjs/src/templates/app/lib/summary/Summary.Util.js +0 -33
- package/cjs/src/templates/app/lib/summary/Summary.View.js +0 -51
- package/cjs/src/templates/app/lib/summary/Summary.Zone.js +0 -62
- package/cjs/src/templates/app/lib/summary/index.js +0 -67
- package/cjs/src/templates/app/lib/user/User.Template.js +0 -65
- package/cjs/src/templates/app/lib/user/User.Unit.js +0 -38
- package/cjs/src/templates/app/lib/user/User.Util.js +0 -94
- package/cjs/src/templates/app/lib/user/User.View.js +0 -66
- package/cjs/src/templates/app/lib/user/User.Zone.js +0 -74
- package/cjs/src/templates/app/lib/user/index.js +0 -61
- package/cjs/src/templates/app/page.test.ts.template +0 -10
- package/cjs/src/templates/app/playwright.config.ts.template +0 -6
- package/cjs/src/templates/app/postcss.config.js.template +0 -10
- package/cjs/src/templates/app/public/manifest.json.template +0 -67
- package/cjs/src/templates/app/tsconfig.json.template +0 -22
- package/cjs/src/templates/app/tsconfig.spec.json.template +0 -7
- package/cjs/src/templates/app/ui/Footer.js +0 -67
- package/cjs/src/templates/app/ui/MainHeader.js +0 -131
- package/cjs/src/templates/crudPages/[__model__Id]/edit/page.js +0 -73
- package/cjs/src/templates/crudPages/[__model__Id]/page.js +0 -83
- package/cjs/src/templates/crudPages/new/page.js +0 -70
- package/cjs/src/templates/crudPages/page.js +0 -71
- package/cjs/src/templates/libRoot/.gitignore.template +0 -15
- package/cjs/src/templates/libRoot/env/env.server.example.ts.template +0 -7
- package/cjs/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
- package/cjs/src/templates/libRoot/lib/setting/Setting.Template.js +0 -57
- package/cjs/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/setting/Setting.Util.js +0 -34
- package/cjs/src/templates/libRoot/lib/setting/Setting.View.js +0 -51
- package/cjs/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -80
- package/cjs/src/templates/libRoot/lib/setting/index.js +0 -61
- package/cjs/src/templates/libRoot/lib/summary/Summary.Template.js +0 -43
- package/cjs/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/summary/Summary.Util.js +0 -33
- package/cjs/src/templates/libRoot/lib/summary/Summary.View.js +0 -51
- package/cjs/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -62
- package/cjs/src/templates/libRoot/lib/summary/index.js +0 -67
- package/cjs/src/templates/libRoot/lib/user/User.Template.js +0 -65
- package/cjs/src/templates/libRoot/lib/user/User.Unit.js +0 -38
- package/cjs/src/templates/libRoot/lib/user/User.Util.js +0 -94
- package/cjs/src/templates/libRoot/lib/user/User.View.js +0 -66
- package/cjs/src/templates/libRoot/lib/user/User.Zone.js +0 -74
- package/cjs/src/templates/libRoot/lib/user/index.js +0 -61
- package/cjs/src/templates/libRoot/package.json.template +0 -4
- package/cjs/src/templates/libRoot/tsconfig.json.template +0 -13
- package/cjs/src/templates/libRoot/tsconfig.spec.json.template +0 -7
- package/cjs/src/templates/localDev/docker-compose.yaml.template +0 -36
- package/cjs/src/templates/module/__Model__.Template.js +0 -54
- package/cjs/src/templates/module/__Model__.Unit.js +0 -42
- package/cjs/src/templates/module/__Model__.Util.js +0 -70
- package/cjs/src/templates/module/__Model__.View.js +0 -48
- package/cjs/src/templates/module/__Model__.Zone.js +0 -83
- package/cjs/src/templates/module/index.js +0 -61
- package/cjs/src/templates/pkgRoot/tsconfig.json.template +0 -15
- package/cjs/src/templates/workspaceRoot/.env.template +0 -20
- package/cjs/src/templates/workspaceRoot/.gitignore.template +0 -118
- package/cjs/src/templates/workspaceRoot/.prettierignore.template +0 -10
- package/cjs/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
- package/cjs/src/templates/workspaceRoot/.swcrc.template +0 -9
- package/cjs/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
- package/cjs/src/templates/workspaceRoot/README.md.template +0 -37
- package/cjs/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
- package/cjs/src/templates/workspaceRoot/package.json.template +0 -43
- package/cjs/src/templates/workspaceRoot/tsconfig.json.template +0 -29
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -27
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -108
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -22
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -30
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -21
- package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -31
- package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -23
- package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -40
- package/esm/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -34
- package/esm/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
- package/esm/src/templates/app/app/[lang]/admin/layout.js +0 -34
- package/esm/src/templates/app/app/[lang]/admin/page.js +0 -43
- package/esm/src/templates/app/app/csr.js +0 -14
- package/esm/src/templates/app/app/index.html.template +0 -13
- package/esm/src/templates/app/app/layout.js +0 -18
- package/esm/src/templates/app/capacitor.config.ts.template +0 -8
- package/esm/src/templates/app/env/env.client.debug.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.develop.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.local.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.main.ts.template +0 -7
- package/esm/src/templates/app/env/env.client.testing.ts.template +0 -7
- package/esm/src/templates/app/env/env.server.debug.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.develop.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.local.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.main.ts.template +0 -15
- package/esm/src/templates/app/env/env.server.testing.ts.template +0 -7
- package/esm/src/templates/app/lib/setting/Setting.Template.js +0 -37
- package/esm/src/templates/app/lib/setting/Setting.Unit.js +0 -18
- package/esm/src/templates/app/lib/setting/Setting.Util.js +0 -14
- package/esm/src/templates/app/lib/setting/Setting.View.js +0 -31
- package/esm/src/templates/app/lib/setting/Setting.Zone.js +0 -60
- package/esm/src/templates/app/lib/setting/index.js +0 -41
- package/esm/src/templates/app/lib/summary/Summary.Template.js +0 -23
- package/esm/src/templates/app/lib/summary/Summary.Unit.js +0 -18
- package/esm/src/templates/app/lib/summary/Summary.Util.js +0 -13
- package/esm/src/templates/app/lib/summary/Summary.View.js +0 -31
- package/esm/src/templates/app/lib/summary/Summary.Zone.js +0 -42
- package/esm/src/templates/app/lib/summary/index.js +0 -47
- package/esm/src/templates/app/lib/user/User.Template.js +0 -45
- package/esm/src/templates/app/lib/user/User.Unit.js +0 -18
- package/esm/src/templates/app/lib/user/User.Util.js +0 -74
- package/esm/src/templates/app/lib/user/User.View.js +0 -46
- package/esm/src/templates/app/lib/user/User.Zone.js +0 -54
- package/esm/src/templates/app/lib/user/index.js +0 -41
- package/esm/src/templates/app/page.test.ts.template +0 -10
- package/esm/src/templates/app/playwright.config.ts.template +0 -6
- package/esm/src/templates/app/postcss.config.js.template +0 -10
- package/esm/src/templates/app/public/manifest.json.template +0 -67
- package/esm/src/templates/app/tsconfig.json.template +0 -22
- package/esm/src/templates/app/tsconfig.spec.json.template +0 -7
- package/esm/src/templates/app/ui/Footer.js +0 -47
- package/esm/src/templates/app/ui/MainHeader.js +0 -111
- package/esm/src/templates/crudPages/[__model__Id]/edit/page.js +0 -53
- package/esm/src/templates/crudPages/[__model__Id]/page.js +0 -63
- package/esm/src/templates/crudPages/new/page.js +0 -50
- package/esm/src/templates/crudPages/page.js +0 -51
- package/esm/src/templates/libRoot/.gitignore.template +0 -15
- package/esm/src/templates/libRoot/env/env.server.example.ts.template +0 -7
- package/esm/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
- package/esm/src/templates/libRoot/lib/setting/Setting.Template.js +0 -37
- package/esm/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/setting/Setting.Util.js +0 -14
- package/esm/src/templates/libRoot/lib/setting/Setting.View.js +0 -31
- package/esm/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -60
- package/esm/src/templates/libRoot/lib/setting/index.js +0 -41
- package/esm/src/templates/libRoot/lib/summary/Summary.Template.js +0 -23
- package/esm/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/summary/Summary.Util.js +0 -13
- package/esm/src/templates/libRoot/lib/summary/Summary.View.js +0 -31
- package/esm/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -42
- package/esm/src/templates/libRoot/lib/summary/index.js +0 -47
- package/esm/src/templates/libRoot/lib/user/User.Template.js +0 -45
- package/esm/src/templates/libRoot/lib/user/User.Unit.js +0 -18
- package/esm/src/templates/libRoot/lib/user/User.Util.js +0 -74
- package/esm/src/templates/libRoot/lib/user/User.View.js +0 -46
- package/esm/src/templates/libRoot/lib/user/User.Zone.js +0 -54
- package/esm/src/templates/libRoot/lib/user/index.js +0 -41
- package/esm/src/templates/libRoot/package.json.template +0 -4
- package/esm/src/templates/libRoot/tsconfig.json.template +0 -13
- package/esm/src/templates/libRoot/tsconfig.spec.json.template +0 -7
- package/esm/src/templates/localDev/docker-compose.yaml.template +0 -36
- package/esm/src/templates/module/__Model__.Template.js +0 -34
- package/esm/src/templates/module/__Model__.Unit.js +0 -22
- package/esm/src/templates/module/__Model__.Util.js +0 -50
- package/esm/src/templates/module/__Model__.View.js +0 -28
- package/esm/src/templates/module/__Model__.Zone.js +0 -63
- package/esm/src/templates/module/index.js +0 -41
- package/esm/src/templates/pkgRoot/tsconfig.json.template +0 -15
- package/esm/src/templates/workspaceRoot/.env.template +0 -20
- package/esm/src/templates/workspaceRoot/.gitignore.template +0 -118
- package/esm/src/templates/workspaceRoot/.prettierignore.template +0 -10
- package/esm/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
- package/esm/src/templates/workspaceRoot/.swcrc.template +0 -9
- package/esm/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
- package/esm/src/templates/workspaceRoot/README.md.template +0 -37
- package/esm/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
- package/esm/src/templates/workspaceRoot/package.json.template +0 -43
- package/esm/src/templates/workspaceRoot/tsconfig.json.template +0 -29
- package/src/application/application.prompt.d.ts +0 -2
- package/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.d.ts +0 -10
- package/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(user)/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.d.ts +0 -9
- package/src/templates/app/app/[lang]/(__appName__)/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/admin/layout.d.ts +0 -9
- package/src/templates/app/app/[lang]/admin/page.d.ts +0 -9
- package/src/templates/app/app/csr.d.ts +0 -9
- package/src/templates/app/app/layout.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Template.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Unit.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Util.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.View.d.ts +0 -9
- package/src/templates/app/lib/setting/Setting.Zone.d.ts +0 -9
- package/src/templates/app/lib/setting/index.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Template.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Unit.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Util.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.View.d.ts +0 -9
- package/src/templates/app/lib/summary/Summary.Zone.d.ts +0 -9
- package/src/templates/app/lib/summary/index.d.ts +0 -9
- package/src/templates/app/lib/user/User.Template.d.ts +0 -9
- package/src/templates/app/lib/user/User.Unit.d.ts +0 -9
- package/src/templates/app/lib/user/User.Util.d.ts +0 -9
- package/src/templates/app/lib/user/User.View.d.ts +0 -9
- package/src/templates/app/lib/user/User.Zone.d.ts +0 -9
- package/src/templates/app/lib/user/index.d.ts +0 -9
- package/src/templates/app/ui/Footer.d.ts +0 -9
- package/src/templates/app/ui/MainHeader.d.ts +0 -10
- package/src/templates/crudPages/[__model__Id]/edit/page.d.ts +0 -11
- package/src/templates/crudPages/[__model__Id]/page.d.ts +0 -11
- package/src/templates/crudPages/new/page.d.ts +0 -11
- package/src/templates/crudPages/page.d.ts +0 -11
- package/src/templates/libRoot/lib/setting/Setting.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.View.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/Setting.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/setting/index.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.View.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/Summary.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/summary/index.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Template.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Unit.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Util.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.View.d.ts +0 -9
- package/src/templates/libRoot/lib/user/User.Zone.d.ts +0 -9
- package/src/templates/libRoot/lib/user/index.d.ts +0 -9
- package/src/templates/module/__Model__.Template.d.ts +0 -11
- package/src/templates/module/__Model__.Unit.d.ts +0 -11
- package/src/templates/module/__Model__.Util.d.ts +0 -11
- package/src/templates/module/__Model__.View.d.ts +0 -11
- package/src/templates/module/__Model__.Zone.d.ts +0 -11
- package/src/templates/module/index.d.ts +0 -11
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+
# Model.Util Implementation Guide for Akan.js
|
|
2
|
+
|
|
3
|
+
## Purpose and Role of Model.Util.ts Files
|
|
4
|
+
|
|
5
|
+
`Model.Util.tsx` files are specialized client-side components in the Akan.js framework that provide reusable utility components encapsulating model-specific functionality. They serve several critical roles:
|
|
6
|
+
|
|
7
|
+
1. **Action Handlers**: Implement UI-triggered operations (create, read, update, delete)
|
|
8
|
+
2. **Interactive UI Elements**: Provide specialized buttons, forms, menus, and controls
|
|
9
|
+
3. **Data Visualization**: Create model-specific charts, stats, and insights displays
|
|
10
|
+
4. **Store Integration**: Connect UI components to Zustand store state and actions
|
|
11
|
+
5. **Signal Integration**: Encapsulate API calls through signal methods
|
|
12
|
+
6. **Client-side Logic**: Implement complex client-side business logic and validations
|
|
13
|
+
7. **Composite Components**: Combine multiple UI elements into cohesive functional units
|
|
14
|
+
|
|
15
|
+
Key characteristics of Model.Util components:
|
|
16
|
+
|
|
17
|
+
- **Client Components**: Always marked with `"use client"` directive
|
|
18
|
+
- **Model-Specific**: Tailored to a particular domain model
|
|
19
|
+
- **Reusable**: Designed to be used across different parts of the application
|
|
20
|
+
- **Self-Contained**: Handle their own loading, error, and success states
|
|
21
|
+
- **Typed**: Use TypeScript for prop definitions and return values
|
|
22
|
+
- **Functional**: Implement React's functional component pattern
|
|
23
|
+
|
|
24
|
+
## How to Create Model.Util.ts Files
|
|
25
|
+
|
|
26
|
+
### Basic Structure
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
// File: lib/modelName/ModelName.Util.tsx
|
|
30
|
+
"use client";
|
|
31
|
+
|
|
32
|
+
import { useState } from "react";
|
|
33
|
+
import { Button, Modal } from "@util/ui";
|
|
34
|
+
import { st } from "../st";
|
|
35
|
+
import { sig } from "../sig";
|
|
36
|
+
import { dict } from "../dict";
|
|
37
|
+
|
|
38
|
+
// Simple action button
|
|
39
|
+
export const CreateButton = () => {
|
|
40
|
+
const { setModelForm, showCreateModal } = st.do.model();
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Button
|
|
44
|
+
variant="primary"
|
|
45
|
+
onClick={() => {
|
|
46
|
+
setModelForm({});
|
|
47
|
+
showCreateModal();
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
{dict.model.create_new}
|
|
51
|
+
</Button>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Complex utility with state management
|
|
56
|
+
export const FilterPanel = ({ onFilter }: { onFilter: (filters: any) => void }) => {
|
|
57
|
+
const [filters, setFilters] = useState({});
|
|
58
|
+
|
|
59
|
+
const handleFilter = () => {
|
|
60
|
+
onFilter(filters);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className="filter-panel">
|
|
65
|
+
{/* Filter inputs */}
|
|
66
|
+
<Button onClick={handleFilter}>{dict.common.apply_filters}</Button>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Additional utility components...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Common Patterns and Implementations
|
|
75
|
+
|
|
76
|
+
#### 1. Action Buttons
|
|
77
|
+
|
|
78
|
+
Action buttons trigger specific operations on models, often connecting to store actions:
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
export const DeleteButton = ({ id, name }: { id: string; name: string }) => {
|
|
82
|
+
const [isConfirming, setIsConfirming] = useState(false);
|
|
83
|
+
const { deleteModel } = st.do.model();
|
|
84
|
+
|
|
85
|
+
const handleDelete = async () => {
|
|
86
|
+
await deleteModel(id);
|
|
87
|
+
setIsConfirming(false);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<>
|
|
92
|
+
<Button variant="danger" size="sm" onClick={() => setIsConfirming(true)}>
|
|
93
|
+
{dict.common.delete}
|
|
94
|
+
</Button>
|
|
95
|
+
|
|
96
|
+
<Modal isOpen={isConfirming} onClose={() => setIsConfirming(false)} title={dict.model.confirm_delete}>
|
|
97
|
+
<p>{dict.model.delete_confirmation.replace("{name}", name)}</p>
|
|
98
|
+
<div className="flex justify-end gap-2">
|
|
99
|
+
<Button variant="outline" onClick={() => setIsConfirming(false)}>
|
|
100
|
+
{dict.common.cancel}
|
|
101
|
+
</Button>
|
|
102
|
+
<Button variant="danger" onClick={handleDelete}>
|
|
103
|
+
{dict.common.delete}
|
|
104
|
+
</Button>
|
|
105
|
+
</div>
|
|
106
|
+
</Modal>
|
|
107
|
+
</>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### 2. Data Display Components
|
|
113
|
+
|
|
114
|
+
Components that visualize model data in specialized ways:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
export const StatsPanel = ({ modelId }: { modelId: string }) => {
|
|
118
|
+
const { model } = st.use.model((state) => ({
|
|
119
|
+
model: state.models[modelId],
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
if (!model) return null;
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div className="stats-grid">
|
|
126
|
+
<StatCard title={dict.model.total_views} value={model.stats.views} icon={<EyeIcon />} />
|
|
127
|
+
<StatCard title={dict.model.completion_rate} value={`${model.stats.completionRate}%`} icon={<ChartIcon />} />
|
|
128
|
+
{/* Additional stats */}
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
};
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### 3. Form Wrappers
|
|
135
|
+
|
|
136
|
+
Components that encapsulate form handling logic:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
export const QuickEditForm = ({ id }: { id: string }) => {
|
|
140
|
+
const { model } = st.use.model((state) => ({
|
|
141
|
+
model: state.models[id],
|
|
142
|
+
}));
|
|
143
|
+
const { updateModel } = st.do.model();
|
|
144
|
+
const [form, setForm] = useState(model || {});
|
|
145
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
146
|
+
|
|
147
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
148
|
+
e.preventDefault();
|
|
149
|
+
setIsSubmitting(true);
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
await updateModel(id, form);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error(error);
|
|
155
|
+
} finally {
|
|
156
|
+
setIsSubmitting(false);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (!model) return null;
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<form onSubmit={handleSubmit}>
|
|
164
|
+
<Field.Text
|
|
165
|
+
label={dict.model.name}
|
|
166
|
+
value={form.name || ""}
|
|
167
|
+
onChange={(value) => setForm({ ...form, name: value })}
|
|
168
|
+
/>
|
|
169
|
+
{/* Additional fields */}
|
|
170
|
+
|
|
171
|
+
<Button type="submit" disabled={isSubmitting}>
|
|
172
|
+
{isSubmitting ? dict.common.saving : dict.common.save}
|
|
173
|
+
</Button>
|
|
174
|
+
</form>
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Using with Store Actions and State
|
|
180
|
+
|
|
181
|
+
Util components often connect to the model's store to access state and actions:
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
export const StatusToggle = ({ id }: { id: string }) => {
|
|
185
|
+
// Using store selectors to get only what we need
|
|
186
|
+
const { status, isUpdating } = st.use.model((state) => ({
|
|
187
|
+
status: state.models[id]?.status,
|
|
188
|
+
isUpdating: state.updating[id] || false,
|
|
189
|
+
}));
|
|
190
|
+
|
|
191
|
+
// Using store actions
|
|
192
|
+
const { updateModelStatus } = st.do.model();
|
|
193
|
+
|
|
194
|
+
const toggleStatus = () => {
|
|
195
|
+
const newStatus = status === "active" ? "inactive" : "active";
|
|
196
|
+
updateModelStatus(id, newStatus);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<Toggle
|
|
201
|
+
checked={status === "active"}
|
|
202
|
+
onChange={toggleStatus}
|
|
203
|
+
disabled={isUpdating}
|
|
204
|
+
label={dict.model.status_labels[status || "unknown"]}
|
|
205
|
+
/>
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Best Practices for Store Integration
|
|
211
|
+
|
|
212
|
+
1. **Selective State Access**: Use selectors to extract only the specific state pieces needed
|
|
213
|
+
2. **Action Abstraction**: Use store actions rather than directly mutating state
|
|
214
|
+
3. **Loading State**: Track and handle loading states from the store
|
|
215
|
+
4. **Error Handling**: Handle and display error states from the store
|
|
216
|
+
|
|
217
|
+
## Using with Signal API Calls
|
|
218
|
+
|
|
219
|
+
Util components can make direct API calls using signal methods:
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
export const RefreshButton = ({ id, onRefresh }: { id: string; onRefresh?: () => void }) => {
|
|
223
|
+
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
224
|
+
const { setModel } = st.do.model();
|
|
225
|
+
|
|
226
|
+
const handleRefresh = async () => {
|
|
227
|
+
setIsRefreshing(true);
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
const refreshedModel = await sig.model.getModel({ id });
|
|
231
|
+
setModel(refreshedModel);
|
|
232
|
+
onRefresh?.();
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error("Failed to refresh model:", error);
|
|
235
|
+
} finally {
|
|
236
|
+
setIsRefreshing(false);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
return (
|
|
241
|
+
<Button variant="outline" size="sm" onClick={handleRefresh} disabled={isRefreshing}>
|
|
242
|
+
{isRefreshing ? <Spinner size="sm" /> : <RefreshIcon />}
|
|
243
|
+
{dict.common.refresh}
|
|
244
|
+
</Button>
|
|
245
|
+
);
|
|
246
|
+
};
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Best Practices for Signal Integration
|
|
250
|
+
|
|
251
|
+
1. **Loading States**: Always show loading indicators during API calls
|
|
252
|
+
2. **Error Handling**: Implement proper error catching and user feedback
|
|
253
|
+
3. **Optimistic Updates**: Consider updating UI optimistically before API response
|
|
254
|
+
4. **Store Integration**: Update the store with API response data
|
|
255
|
+
5. **Debouncing**: Implement debouncing for frequent operations (e.g., search)
|
|
256
|
+
|
|
257
|
+
## Performance Optimization Techniques
|
|
258
|
+
|
|
259
|
+
### 1. Memoization
|
|
260
|
+
|
|
261
|
+
Use React's `memo` and `useMemo` to prevent unnecessary re-renders:
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
import { memo, useMemo } from "react";
|
|
265
|
+
|
|
266
|
+
export const ExpensiveComponent = memo(({ data }: { data: any[] }) => {
|
|
267
|
+
const processedData = useMemo(() => {
|
|
268
|
+
return data.map(item => /* expensive computation */);
|
|
269
|
+
}, [data]);
|
|
270
|
+
|
|
271
|
+
return <div>{/* render using processedData */}</div>;
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 2. Lazy Loading
|
|
276
|
+
|
|
277
|
+
Use dynamic imports for heavy components:
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import dynamic from "next/dynamic";
|
|
281
|
+
|
|
282
|
+
const LazyChartComponent = dynamic(() => import("./ChartComponent"), {
|
|
283
|
+
loading: () => <div>Loading chart...</div>,
|
|
284
|
+
ssr: false, // Disable server-side rendering if component uses browser APIs
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
export const ModelInsights = ({ id }: { id: string }) => {
|
|
288
|
+
const { shouldShowChart } = st.use.model();
|
|
289
|
+
|
|
290
|
+
return <div>{shouldShowChart && <LazyChartComponent id={id} />}</div>;
|
|
291
|
+
};
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 3. Virtualization
|
|
295
|
+
|
|
296
|
+
For large lists, use virtualization libraries:
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
300
|
+
|
|
301
|
+
export const VirtualizedList = ({ items }: { items: any[] }) => {
|
|
302
|
+
const parentRef = useRef<HTMLDivElement>(null);
|
|
303
|
+
|
|
304
|
+
const virtualizer = useVirtualizer({
|
|
305
|
+
count: items.length,
|
|
306
|
+
getScrollElement: () => parentRef.current,
|
|
307
|
+
estimateSize: () => 50, // estimated row height
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
return (
|
|
311
|
+
<div ref={parentRef} style={{ height: "400px", overflow: "auto" }}>
|
|
312
|
+
<div
|
|
313
|
+
style={{
|
|
314
|
+
height: `${virtualizer.getTotalSize()}px`,
|
|
315
|
+
width: "100%",
|
|
316
|
+
position: "relative",
|
|
317
|
+
}}
|
|
318
|
+
>
|
|
319
|
+
{virtualizer.getVirtualItems().map((virtualItem) => (
|
|
320
|
+
<div
|
|
321
|
+
key={virtualItem.key}
|
|
322
|
+
style={{
|
|
323
|
+
position: "absolute",
|
|
324
|
+
top: 0,
|
|
325
|
+
left: 0,
|
|
326
|
+
width: "100%",
|
|
327
|
+
height: `${virtualItem.size}px`,
|
|
328
|
+
transform: `translateY(${virtualItem.start}px)`,
|
|
329
|
+
}}
|
|
330
|
+
>
|
|
331
|
+
{/* Render item content */}
|
|
332
|
+
{items[virtualItem.index].name}
|
|
333
|
+
</div>
|
|
334
|
+
))}
|
|
335
|
+
</div>
|
|
336
|
+
</div>
|
|
337
|
+
);
|
|
338
|
+
};
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## How to Use Model.Util.ts Files in Pages
|
|
342
|
+
|
|
343
|
+
In Next.js pages, Util components can be used directly since pages are client components:
|
|
344
|
+
|
|
345
|
+
```tsx
|
|
346
|
+
// app/models/page.tsx
|
|
347
|
+
"use client";
|
|
348
|
+
|
|
349
|
+
import { Model } from "@client";
|
|
350
|
+
import { Container } from "@util/ui";
|
|
351
|
+
|
|
352
|
+
export default function ModelsPage() {
|
|
353
|
+
return (
|
|
354
|
+
<Container>
|
|
355
|
+
<div className="mb-4 flex items-center justify-between">
|
|
356
|
+
<h1 className="text-2xl font-bold">{dict.model.title}</h1>
|
|
357
|
+
<Model.Util.CreateButton />
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<Model.Util.FilterPanel />
|
|
361
|
+
|
|
362
|
+
<Model.View.List />
|
|
363
|
+
</Container>
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
In server component pages, use client boundaries:
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
// app/models/[id]/page.tsx
|
|
372
|
+
import { Model } from "@client";
|
|
373
|
+
import { ClientOnly } from "@util/ui";
|
|
374
|
+
|
|
375
|
+
// This is a server component
|
|
376
|
+
export default function ModelDetailPage({ params }: { params: { id: string } }) {
|
|
377
|
+
return (
|
|
378
|
+
<div>
|
|
379
|
+
<h1>Model Details</h1>
|
|
380
|
+
|
|
381
|
+
{/* Client boundary for Util components */}
|
|
382
|
+
<ClientOnly>
|
|
383
|
+
<div className="actions">
|
|
384
|
+
<Model.Util.EditButton id={params.id} />
|
|
385
|
+
<Model.Util.DeleteButton id={params.id} />
|
|
386
|
+
</div>
|
|
387
|
+
</ClientOnly>
|
|
388
|
+
|
|
389
|
+
{/* Server-rendered content */}
|
|
390
|
+
<ModelDetails id={params.id} />
|
|
391
|
+
</div>
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## How to Use Model.Util.ts Files in Units
|
|
397
|
+
|
|
398
|
+
Units represent list items or cards, and often use Util components for actions:
|
|
399
|
+
|
|
400
|
+
```tsx
|
|
401
|
+
// Model.Unit.tsx
|
|
402
|
+
"use client";
|
|
403
|
+
|
|
404
|
+
import { Card, ModelProps } from "@util/ui";
|
|
405
|
+
import * as Util from "./Model.Util";
|
|
406
|
+
|
|
407
|
+
export const ListItem = ({ model }: ModelProps<"model">) => (
|
|
408
|
+
<div className="flex items-center justify-between border-b p-4">
|
|
409
|
+
<div>
|
|
410
|
+
<h3 className="font-medium">{model.name}</h3>
|
|
411
|
+
<p className="text-sm text-gray-500">{model.description}</p>
|
|
412
|
+
</div>
|
|
413
|
+
|
|
414
|
+
<div className="flex gap-2">
|
|
415
|
+
<Util.ViewButton id={model.id} />
|
|
416
|
+
<Util.EditButton id={model.id} />
|
|
417
|
+
<Util.DeleteButton id={model.id} name={model.name} />
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
export const Card = ({ model }: ModelProps<"model">) => (
|
|
423
|
+
<Card>
|
|
424
|
+
<Card.Image src={model.image} />
|
|
425
|
+
<Card.Title>{model.name}</Card.Title>
|
|
426
|
+
<Card.Content>{model.summary}</Card.Content>
|
|
427
|
+
<Card.Footer>
|
|
428
|
+
<Util.StatusBadge status={model.status} />
|
|
429
|
+
<div className="ml-auto flex gap-2">
|
|
430
|
+
<Util.ViewButton id={model.id} size="sm" />
|
|
431
|
+
<Util.EditButton id={model.id} size="sm" />
|
|
432
|
+
</div>
|
|
433
|
+
</Card.Footer>
|
|
434
|
+
</Card>
|
|
435
|
+
);
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## How to Use Model.Util.ts Files in Templates
|
|
439
|
+
|
|
440
|
+
Templates use Util components for form actions and specialized inputs:
|
|
441
|
+
|
|
442
|
+
```tsx
|
|
443
|
+
// Model.Template.tsx
|
|
444
|
+
"use client";
|
|
445
|
+
|
|
446
|
+
import { Field, Form } from "@util/ui";
|
|
447
|
+
import * as Util from "./Model.Util";
|
|
448
|
+
import { st } from "../st";
|
|
449
|
+
|
|
450
|
+
export const CreateTemplate = () => {
|
|
451
|
+
const { modelForm } = st.use.model();
|
|
452
|
+
const { setModelForm, createModel } = st.do.model();
|
|
453
|
+
|
|
454
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
455
|
+
e.preventDefault();
|
|
456
|
+
await createModel();
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
return (
|
|
460
|
+
<Form onSubmit={handleSubmit}>
|
|
461
|
+
<Field.Text
|
|
462
|
+
label={dict.model.name}
|
|
463
|
+
value={modelForm.name || ""}
|
|
464
|
+
onChange={(value) => setModelForm({ name: value })}
|
|
465
|
+
required
|
|
466
|
+
/>
|
|
467
|
+
|
|
468
|
+
{/* Category selector utility */}
|
|
469
|
+
<Util.CategorySelector selected={modelForm.category} onChange={(category) => setModelForm({ category })} />
|
|
470
|
+
|
|
471
|
+
{/* Tags input utility */}
|
|
472
|
+
<Util.TagsInput tags={modelForm.tags || []} onChange={(tags) => setModelForm({ tags })} />
|
|
473
|
+
|
|
474
|
+
<div className="mt-4 flex justify-end gap-2">
|
|
475
|
+
<Util.CancelButton />
|
|
476
|
+
<Util.SubmitButton />
|
|
477
|
+
</div>
|
|
478
|
+
</Form>
|
|
479
|
+
);
|
|
480
|
+
};
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## How to Use Model.Util.ts Files in Views
|
|
484
|
+
|
|
485
|
+
Views represent detailed model displays and often use Util components for actions and data visualization:
|
|
486
|
+
|
|
487
|
+
```tsx
|
|
488
|
+
// Model.View.tsx
|
|
489
|
+
"use client";
|
|
490
|
+
|
|
491
|
+
import { Container, Tabs } from "@util/ui";
|
|
492
|
+
import * as Util from "./Model.Util";
|
|
493
|
+
import { st } from "../st";
|
|
494
|
+
import { useEffect } from "react";
|
|
495
|
+
import { sig } from "../sig";
|
|
496
|
+
|
|
497
|
+
export const DetailView = ({ id }: { id: string }) => {
|
|
498
|
+
const { model, loading } = st.use.model((state) => ({
|
|
499
|
+
model: state.models[id],
|
|
500
|
+
loading: state.loading,
|
|
501
|
+
}));
|
|
502
|
+
|
|
503
|
+
useEffect(() => {
|
|
504
|
+
if (!model) {
|
|
505
|
+
void sig.model.getModel({ id }).then((data) => {
|
|
506
|
+
st.do.model().setModel(data.model);
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}, [id, model]);
|
|
510
|
+
|
|
511
|
+
if (loading) return <Util.LoadingSkeleton />;
|
|
512
|
+
if (!model) return <Util.NotFound />;
|
|
513
|
+
|
|
514
|
+
return (
|
|
515
|
+
<Container>
|
|
516
|
+
<div className="mb-6 flex items-center justify-between">
|
|
517
|
+
<h1 className="text-3xl font-bold">{model.name}</h1>
|
|
518
|
+
|
|
519
|
+
<div className="flex gap-2">
|
|
520
|
+
<Util.EditButton id={id} />
|
|
521
|
+
<Util.ShareButton id={id} />
|
|
522
|
+
<Util.DeleteButton id={id} name={model.name} />
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
|
|
526
|
+
<Tabs>
|
|
527
|
+
<Tabs.Tab label={dict.model.overview}>
|
|
528
|
+
<Util.DetailPanel model={model} />
|
|
529
|
+
</Tabs.Tab>
|
|
530
|
+
|
|
531
|
+
<Tabs.Tab label={dict.model.analytics}>
|
|
532
|
+
<Util.AnalyticsPanel id={id} />
|
|
533
|
+
</Tabs.Tab>
|
|
534
|
+
|
|
535
|
+
<Tabs.Tab label={dict.model.history}>
|
|
536
|
+
<Util.HistoryTimeline id={id} />
|
|
537
|
+
</Tabs.Tab>
|
|
538
|
+
</Tabs>
|
|
539
|
+
</Container>
|
|
540
|
+
);
|
|
541
|
+
};
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## How to Use Model.Util.ts Files in Zones
|
|
545
|
+
|
|
546
|
+
Zones are layout containers that define page sections and often use Util components for dashboards and controls:
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
// Model.Zone.tsx
|
|
550
|
+
"use client";
|
|
551
|
+
|
|
552
|
+
import { Zone } from "@util/ui";
|
|
553
|
+
import * as View from "./Model.View";
|
|
554
|
+
import * as Template from "./Model.Template";
|
|
555
|
+
import * as Util from "./Model.Util";
|
|
556
|
+
import { dict } from "../dict";
|
|
557
|
+
|
|
558
|
+
export const ModelZone = () => (
|
|
559
|
+
<Zone title={dict.model.zone_title}>
|
|
560
|
+
<Zone.Header>
|
|
561
|
+
<Zone.Title>{dict.model.models}</Zone.Title>
|
|
562
|
+
<Util.CreateButton />
|
|
563
|
+
</Zone.Header>
|
|
564
|
+
|
|
565
|
+
<Zone.Dashboard>
|
|
566
|
+
<Util.StatsPanel />
|
|
567
|
+
<Util.TrendChart />
|
|
568
|
+
</Zone.Dashboard>
|
|
569
|
+
|
|
570
|
+
<Zone.Filters>
|
|
571
|
+
<Util.FilterPanel />
|
|
572
|
+
</Zone.Filters>
|
|
573
|
+
|
|
574
|
+
<Zone.Content>
|
|
575
|
+
<View.ListView />
|
|
576
|
+
</Zone.Content>
|
|
577
|
+
|
|
578
|
+
<Zone.Modal id="createModel" title={dict.model.create_new}>
|
|
579
|
+
<Template.CreateTemplate />
|
|
580
|
+
</Zone.Modal>
|
|
581
|
+
|
|
582
|
+
<Zone.Modal id="editModel" title={dict.model.edit}>
|
|
583
|
+
<Template.EditTemplate />
|
|
584
|
+
</Zone.Modal>
|
|
585
|
+
</Zone>
|
|
586
|
+
);
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
## Best Practices and Error Handling
|
|
590
|
+
|
|
591
|
+
### 1. Consistent Error Handling
|
|
592
|
+
|
|
593
|
+
Implement a consistent approach to error handling:
|
|
594
|
+
|
|
595
|
+
```tsx
|
|
596
|
+
export const DataAction = ({ id }: { id: string }) => {
|
|
597
|
+
const [error, setError] = useState<Error | null>(null);
|
|
598
|
+
const [loading, setLoading] = useState(false);
|
|
599
|
+
|
|
600
|
+
const handleAction = async () => {
|
|
601
|
+
setLoading(true);
|
|
602
|
+
setError(null);
|
|
603
|
+
|
|
604
|
+
try {
|
|
605
|
+
await sig.model.performAction({ id });
|
|
606
|
+
// Success handling
|
|
607
|
+
} catch (err) {
|
|
608
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
609
|
+
} finally {
|
|
610
|
+
setLoading(false);
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
return (
|
|
615
|
+
<div>
|
|
616
|
+
{error && <div className="error-message mb-2">{error.message}</div>}
|
|
617
|
+
|
|
618
|
+
<Button onClick={handleAction} disabled={loading} variant="primary">
|
|
619
|
+
{loading ? <Spinner size="sm" /> : null}
|
|
620
|
+
{dict.model.perform_action}
|
|
621
|
+
</Button>
|
|
622
|
+
</div>
|
|
623
|
+
);
|
|
624
|
+
};
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### 2. TypeScript Type Safety
|
|
628
|
+
|
|
629
|
+
Use TypeScript interfaces for props and state:
|
|
630
|
+
|
|
631
|
+
```tsx
|
|
632
|
+
interface FilterPanelProps {
|
|
633
|
+
/** Initial filter values */
|
|
634
|
+
initialFilters?: ModelFilters;
|
|
635
|
+
/** Called when filters are applied */
|
|
636
|
+
onFilter: (filters: ModelFilters) => void;
|
|
637
|
+
/** Additional filter options */
|
|
638
|
+
options?: FilterOptions;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
interface ModelFilters {
|
|
642
|
+
status?: string[];
|
|
643
|
+
category?: string;
|
|
644
|
+
dateRange?: [Date, Date];
|
|
645
|
+
searchTerm?: string;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
interface FilterOptions {
|
|
649
|
+
showCategories?: boolean;
|
|
650
|
+
showDateRange?: boolean;
|
|
651
|
+
showStatus?: boolean;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
export const FilterPanel = ({ initialFilters = {}, onFilter, options = {} }: FilterPanelProps) => {
|
|
655
|
+
// Implementation
|
|
656
|
+
};
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
### 3. Component Documentation
|
|
660
|
+
|
|
661
|
+
Add JSDoc comments for clear documentation:
|
|
662
|
+
|
|
663
|
+
```tsx
|
|
664
|
+
/**
|
|
665
|
+
* Renders a status badge with appropriate color based on status value
|
|
666
|
+
*
|
|
667
|
+
* @param status - The current status value
|
|
668
|
+
* @param size - Badge size (default: 'md')
|
|
669
|
+
* @returns A styled status indicator
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* <StatusBadge status="active" />
|
|
673
|
+
*/
|
|
674
|
+
export const StatusBadge = ({ status, size = "md" }: { status: string; size?: "sm" | "md" | "lg" }) => {
|
|
675
|
+
// Get color based on status
|
|
676
|
+
const getColor = () => {
|
|
677
|
+
switch (status) {
|
|
678
|
+
case "active":
|
|
679
|
+
return "green";
|
|
680
|
+
case "pending":
|
|
681
|
+
return "yellow";
|
|
682
|
+
case "inactive":
|
|
683
|
+
return "gray";
|
|
684
|
+
default:
|
|
685
|
+
return "blue";
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
return (
|
|
690
|
+
<span className={`badge badge-${getColor()} badge-${size}`}>{dict.model.status_labels[status] || status}</span>
|
|
691
|
+
);
|
|
692
|
+
};
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### 4. Loading States
|
|
696
|
+
|
|
697
|
+
Always handle loading states explicitly:
|
|
698
|
+
|
|
699
|
+
```tsx
|
|
700
|
+
export const ModelSelector = ({ onChange, value }: { onChange: (id: string) => void; value?: string }) => {
|
|
701
|
+
const [loading, setLoading] = useState(false);
|
|
702
|
+
const [options, setOptions] = useState<{ label: string; value: string }[]>([]);
|
|
703
|
+
|
|
704
|
+
useEffect(() => {
|
|
705
|
+
const fetchOptions = async () => {
|
|
706
|
+
setLoading(true);
|
|
707
|
+
try {
|
|
708
|
+
const { models } = await sig.model.listModels({ limit: 100 });
|
|
709
|
+
setOptions(
|
|
710
|
+
models.map((m) => ({
|
|
711
|
+
label: m.name,
|
|
712
|
+
value: m.id,
|
|
713
|
+
}))
|
|
714
|
+
);
|
|
715
|
+
} catch (error) {
|
|
716
|
+
console.error("Failed to load options:", error);
|
|
717
|
+
setOptions([]);
|
|
718
|
+
} finally {
|
|
719
|
+
setLoading(false);
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
void fetchOptions();
|
|
724
|
+
}, []);
|
|
725
|
+
|
|
726
|
+
return (
|
|
727
|
+
<Select
|
|
728
|
+
options={options}
|
|
729
|
+
value={value}
|
|
730
|
+
onChange={onChange}
|
|
731
|
+
isLoading={loading}
|
|
732
|
+
placeholder={loading ? dict.common.loading : dict.model.select_model}
|
|
733
|
+
/>
|
|
734
|
+
);
|
|
735
|
+
};
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
## Summary
|
|
739
|
+
|
|
740
|
+
Model.Util components in Akan.js are essential for creating reusable, model-specific functionality. By following these patterns and best practices, you can create a consistent, maintainable set of utility components that enhance your application's user experience while maintaining clean separation between business logic and presentation layers.
|
|
741
|
+
|
|
742
|
+
Remember these key principles:
|
|
743
|
+
|
|
744
|
+
1. Create focused, single-responsibility components
|
|
745
|
+
2. Handle loading and error states consistently
|
|
746
|
+
3. Use TypeScript for type safety
|
|
747
|
+
4. Connect to stores for state management
|
|
748
|
+
5. Use signals for API calls
|
|
749
|
+
6. Implement proper performance optimizations
|
|
750
|
+
7. Document your components thoroughly
|
|
751
|
+
|
|
752
|
+
By applying these guidelines, your Model.Util components will serve as reliable building blocks throughout your Akan.js application.
|