@penta-b/mna-penta-smart-forms-plugins-fields-ts
v0.0.6
Published
Beeflow plugins fields
Readme
Bee Flow Plugins Fields
Plugin form fields for the Bee Flow product.
Overview
This repo packages Beeflow's plugin form fields into a single UMD bundle that the PBPM form builder loads at runtime. It currently ships one field.
Field catalog
| Type ID | Display name | Purpose |
| ----------------------- | ----------------------- | ------------------------------------------------------------------------------ |
| projectsDropdownField | Projects Dropdown Field | Multi-select dropdown of the organization's projects; stores selected project ids. |
Quick start (for contributors)
npm install # or: bun install (a bun.lock is present)
npm start # webpack-dev-server on :3005, CORS openHow to run
Start the dev server:
npm startboots webpack-dev-server onhttp://localhost:3005.Register the bundle in the PBPM admin. In the process's Process Basic Information → Add URL, paste:
http://localhost:3005/bee-flow-plugins-fields.jsThe form builder and any runtime instance of that process now load your local bundle.
Project structure
src/
├── index.ts ← bundle entry; triggers field registration on load
├── constants/ ← cross-field constants (e.g. PLUGINS_FIELDS_NAMESPACE)
├── lib/ ← in-repo wrappers (smartForms re-exports, react-query client)
├── services/ ← shared API / react-query layer
│ ├── apiEndpoints.ts ← central endpoint constants
│ └── projects/ ← projects domain (api / queries / keys / types)
├── types/ ← cross-field types + 3rd-party module augmentations
└── fields/
└── ProjectsDropdownField/
├── index.tsx ← field component (wraps DropdownField)
├── projectsDropdownSchema.ts ← designer config schema (flat field descriptors)
├── register.ts ← loader() call + config export
└── hooks/useProjectsOptions/ ← loads projects → dropdown optionsAdding a new field
- Create
src/fields/<FieldName>/with aregister.tsat the field root. - Implement the field component in
index.tsx(a custom component wrapping a smart-forms field). - Define the designer config as a flat
Record<string, unknown>of field descriptors in<fieldName>Schema.ts(seeprojectsDropdownSchema.ts). - In
register.ts, callloader('<typeId>', Component, '<Display Name>', <fieldName>Config)and export a<fieldName>Configobject shaped{ type, component, name, config }. - Re-export the config from
src/index.ts. - If the field needs new backend calls, add a domain folder under
src/services/<domain>/following the<domain>.<role>.tsconvention (see Services layer). - Run
npm run type-checkandnpm run formatbefore opening a PR.
Reference implementation. Use ProjectsDropdownField as the template.
Services layer
src/services/ is the shared data layer. One folder per backend resource. Each follows the same
file-naming convention:
| File | Contents |
| ----------------------- | -------------------------------------------------- |
| <domain>.api.ts | Raw fetcher functions (request.get/post(...)). |
| <domain>.queries.ts | useGet* react-query hooks built on the fetchers. |
| <domain>.mutations.ts | useMutation hooks (only when mutations exist). |
| <domain>.keys.ts | Query-key enum (<Domain>QueryKey { ... }). |
| <domain>.types.ts | Request/response/payload types. |
Example — src/services/projects/:
// projects.api.ts
import { request } from '@penta-b/ma-lib';
import { WORKFLOW_ADMIN_ENDPOINTS } from '../apiEndpoints';
export const fetchProjectsByOrgs = async (orgs: string[]) => {
const response = await request.get<ProjectBasicInfoType[]>(
WORKFLOW_ADMIN_ENDPOINTS.PROJECTS_BY_ORGS,
{ data: { orgs } }
);
return response.data;
};// projects.queries.ts
export const useGetProjectsByOrgs = (orgs: string[]) =>
useQuery([ProjectsQueryKey.PROJECTS_BY_ORGS, ...orgs], () => fetchProjectsByOrgs(orgs), {
enabled: orgs.length > 0,
});Central endpoints. Every URL lives in src/services/apiEndpoints.ts. Do not hard-code paths
inside .api.ts files; add them to apiEndpoints.ts first.
HTTP transport. Always use request from @penta-b/ma-lib, never raw axios. request
auto-injects auth, org, role, and locale headers. The current org is available via
getSelectedOrg() from @penta-b/ma-lib.
Coding conventions
Naming
| Element | Convention | Example |
| ---------------------------------------------- | ------------------------------------------------- | -------------------------------- |
| Component / component folder | PascalCase | ProjectsDropdownField/ |
| Hook folder + file | camelCase, use prefix | useProjectsOptions/ |
| Helper folder + file | camelCase, noun, Helper suffix | dateFormatHelper/ |
| Other folders (service domains) | camelCase | projects/ |
| Function / variable | camelCase | fetchProjectsByOrgs |
| Constant | UPPER_SNAKE_CASE | PLUGINS_FIELDS_NAMESPACE |
| CSS class | kebab-case, penta- prefix | .penta-projects-dropdown |
Types
| Purpose | Pattern (interface or type) | Example |
| ----------------------- | -------------------------------- | -------------------------------- |
| Component props | *PropsType (interface) | ProjectsDropdownFieldPropsType |
| API response | *ApiResponseType (interface) | ProjectsApiResponseType |
| Hook return | Use*ReturnType (interface) | UseProjectsOptionsReturnType |
| Domain entity | *Type (interface) | ProjectBasicInfoType |
| Union / utility / tuple | type | type Foo = 'a' \| 'b'; |
| Related constants | enum (UPPER_SNAKE members) | enum ProjectsQueryKey { ... } |
Use interface for object shapes; type only for unions, intersections, mapped/utility types.
Error logging
console.error('Error in [ComponentName]:', error);Available scripts
| Command | What it does |
| -------------------------- | -------------------------------------------------------------------- |
| npm start | Webpack dev server on :3005, CORS open. |
| npm run smartForm:dev | One-shot dev build, no server. |
| npm run smartForm:prod | Production build → dist/build/smartForm/bee-flow-plugins-fields.js. |
| npm run type-check | tsc --noEmit over src/. |
| npm run lint | ESLint over src/. |
| npm run format | Prettier write across the repo. |
Build & deployment
- Bundler: Webpack 5 (config:
webpack.smartForm.js). - Output:
dist/build/smartForm/bee-flow-plugins-fields.js(UMD, library name@penta-b/Form-Builder). - TS target: ES2020; module: ESNext; JSX:
react. - Path alias:
src/*→./src/*(mirrored in TS and webpack). - Externals (provided by host):
react,react-dom,redux,react-redux,@penta-b/ma-lib,@penta-b/mna-penta-smart-forms. - CI:
Jenkinsfileat repo root;Dockerfileprovided for containerized builds.
Publishing (npm)
This package ships the built UMD bundle, not the source. What's published is controlled by the
files field (dist/build) — verify with npm pack --dry-run before releasing.
- Entry point:
main→dist/build/smartForm/bee-flow-plugins-fields.js. - Build-before-publish:
prepublishOnlyrunstype-checkthensmartForm:prod, so the published bundle is always freshly built (webpackoutput.cleanwipes stale artifacts). - Host-provided peers:
react,react-dom,@penta-b/ma-lib,@penta-b/mna-penta-smart-formsare declared aspeerDependencies(they are webpackexternals, never bundled).@penta-b/mna-penta-smart-formsis markedoptionalinpeerDependenciesMetaso npm does not auto-install the host platform locally (it would clash with the ambient module declaration insrc/types/global.d.ts). - Registry/access: published publicly to npmjs.org under the
@penta-bscope (publishConfig.access: "public"), matching the other@penta-bpackages. Auth comes from.npmrc.
Release flow:
npm version patch # bump 0.0.1 -> 0.0.2 (use minor/major as appropriate)
npm publish # prepublishOnly builds first; `files` controls the tarball
npm view @penta-b/mna-penta-smart-forms-plugins-fields-ts # confirmContributing
- Branch from the current working branch (current default:
dev). - Follow the conventions above.
- Run
npm run type-checkandnpm run formatbefore pushing.
