An opinionated ChurchTools extension that builds eGroups end-to-end: select or design a template, collect the minimal inputs, and create a fully configured group (type, roles, parent/child relations, and custom fields) in one go.
- Two-step wizard for group creation with confirmation and "create another" flow.
- Template management (create, edit, delete) backed by the ChurchTools custom module KV store.
- Approval workflow (optional) - Admin can enable a request/approval process for group creation.
- Variable naming system - Dynamic group names using member data (e.g.,
YG-{first.name.role.9}). - Multi-parent groups - Assign groups to multiple parent groups simultaneously.
- Permission-based access - Templates and requests isolated by group type permissions.
- Pulls master data (campuses, age/target groups, group types, custom DB fields) directly from the API.
- Applies the project defaults from
src/config/constants.ts. - Packs a ready-to-upload ZIP (
npm run deploy→releases/).
- Node.js 18+ and npm.
- ChurchTools account with permission to install/upload extensions and manage the target custom module.
- Install dependencies:
npm install
- Create
.envwith your ChurchTools details (used for local dev and packaging):VITE_BASE_URL=https://your.church.tools VITE_KEY=groups-builder # Must match the extension shorty in ChurchTools VITE_USERNAME=dev.user@church.tools # Optional: auto-login for dev server VITE_PASSWORD=your-password # Optional: auto-login for dev server
- In production,
base_urlis injected by ChurchTools;VITE_BASE_URLis only needed for local dev. VITE_KEYis also used to look up the custom module for template storage.
- In production,
- Adjust default IDs and settings in
src/config/constants.tsto match your ChurchTools instance (group category/type/status IDs, parent group, flow group IDs, role IDs, and signup settings).
The extension supports an optional approval workflow for group creation:
- Enable in Settings: Admins can toggle "Approval Mode" in the Settings panel (gear icon).
- Request Submission: When enabled, users without group creation permission submit requests instead of creating groups directly.
- Admin Review: Admins view pending requests in the Request List, can edit runtime fields, and approve or reject.
- Permission-Based: Request categories are isolated per group type - admins only see requests for group types they manage.
How it works:
- Requests are stored in per-group-type data categories (
requests-{groupTypeName}) - Users with write permission on a request category can submit requests
- Users with delete permission can approve/reject requests
- Bulk approve/reject operations are supported
Templates define reusable group configurations:
- Per-Group-Type Storage: Templates are stored in categories named
templates-{groupTypeName} - Permission-Based Access: Users only see templates for group types they have read permission on
- Runtime Fields: Mark fields to be filled at creation time instead of being fixed in the template
- Required Runtime Fields: Specify which runtime fields must be provided
Template Fields:
- Group type, category, status
- Naming scheme (prefix/suffix or variable template)
- Parent groups (multiple supported)
- Child groups (Flow groups)
- Visibility, campus, communities
- Fixed members with roles
- Custom group fields
Create dynamic group names using member data:
Syntax: {source.property.role.roleId}
Examples:
YG-{first.name.role.9}→ "YG-Max" (first name of person with role ID 9){first.last.role.9}'s Group→ "Schmidt's Group" (last name of leader){campus} Youth Group→ "Main Campus Youth Group"
Constraints:
- Role-based variables require exactly 1 member with that role
- Multiple members in the same role will show an error
- Variables resolve at preview time with live updates
Groups can belong to multiple parent groups:
- Template Configuration: Set
parentGroupIds: [100, 200, 300]for multiple parents - Legacy Support: Single
parentGroupIdstill works and is converted to array - Partial Failure Tolerance: If some parent assignments fail, creation continues
- All-Fail Error: If ALL parent assignments fail, error includes group ID for manual fix
Use Cases:
- Groups belonging to both regional and functional hierarchies
- Cross-departmental groups
- Matrix organizational structures
- Start the Vite dev server with hot reload:
npm run dev
- Make sure your ChurchTools instance allows requests from your dev origin (e.g.,
http://localhost:5173). If Safari blocks login, use HTTPS locally (e.g., via mkcert) and/or a Vite proxy so cookies are treated as first-party.
- Production build:
npm run build
- Preview the built app locally:
npm run preview
Run the test suite:
npm run testRun tests in watch mode:
npm run test:watch- Create an installable ZIP (build + package):
Output:
npm run deploy
releases/<name>-v<version>-<git-hash>.zip. - In ChurchTools Admin:
Extensions → Upload Extension, select the ZIP, and install. The extension key must matchVITE_KEY.
Key settings in src/config/constants.ts:
export const GROUP_CONFIG = {
GROUP_TYPE_ID: 1, // Default group type
GROUP_CATEGORY_ID: 5, // Default group category
GROUP_STATUS_ID: 1, // Default status (e.g., active)
DEFAULT_PARENT_GROUP_IDS: [100], // Default parent group(s)
FLOW_GROUP_IDS: [674, 677], // Flow groups to add as children
ROLES: {
LEADER: 9, // Leader role ID
HUB_LEADER: 10, // Hub leader role ID
REPORTING: 73, // Reporting role ID
},
RONNIE_REPORT_PERSON_ID: 999, // Person to add for reporting
VISIBILITY: 'intern', // Default visibility
// ... additional settings
};src/main.tsbootstraps the app, sets the ChurchTools base URL, performs optional dev auto-login, and exposes the extension key.GroupsBuilderApporchestrates the UI steps:- Template selection or creation (
TemplateSelection,TemplateEditor, stored viaTemplateStoreV2in the CT KV store for this extension). - Group form (
Step1Form) prefilled from a template and enriched with master data (campuses, age groups, group types, custom DB fields viaMasterDataServiceandGroupFieldsService). - Group creation and confirmation (
GroupCreationOrchestrator,Step2Confirmation).
- Template selection or creation (
SettingsServicemanages global settings like approval workflow toggle.RequestStorehandles group creation requests for the approval workflow.CategoryManagerhandles per-group-type data category creation and permission checking.- Packaging is handled by
scripts/package.js, which zipsdist/(maps excluded) intoreleases/with version and git hash.
src/
├── main.ts # Entry point
├── components/ # UI components
│ ├── GroupsBuilderApp.ts # Main orchestrator
│ ├── Step1Form.ts # Group creation form
│ ├── Step2Confirmation.ts # Confirmation step
│ ├── TemplateSelection.ts # Template picker
│ ├── TemplateEditor.ts # Template CRUD
│ ├── SettingsPanel.ts # Settings management
│ ├── RequestList.ts # Request management
│ ├── RequestDetail.ts # Request detail/edit
│ └── ...
├── services/ # Business logic
│ ├── GroupCreationOrchestrator.ts # Creates groups via API
│ ├── TemplateStoreV2.ts # Per-group-type template storage
│ ├── RequestStore.ts # Request CRUD
│ ├── SettingsService.ts # App settings
│ ├── CategoryManager.ts # Data category management
│ └── ...
├── utils/ # Utilities
│ ├── NameVariableParser.ts # Variable name resolution
│ ├── kv-store.ts # KV store client
│ └── ...
└── config/
└── constants.ts # ChurchTools instance config
When upgrading from an earlier version:
- Template Storage: Templates are now stored per-group-type. Existing templates in the old format need to be recreated.
- Parent Groups:
parentGroupId(single) is still supported butparentGroupIds(array) is preferred. - No Automatic Migration: Due to permission-based storage, automatic migration is not possible. Export your template configurations and recreate them.
The extension uses the ChurchTools custom module API (see src/utils/kv-store.ts) to persist templates and requests in per-group-type data categories.
For questions about the ChurchTools API, visit the Forum.