Setup Packages
This feature is currently in closed testing phase. Contact us if you're interested in participating.
Dime.Scheduler Setup Packages are deployment templates that capture your scheduling configuration as portable, non-transactional data. Import and export these packages to quickly replicate setups across environments, share configurations between instances, or version-control your reusable templates. Define everything in human-readable JSON5 format with no code required.
What comes out of the box
The following entities can be packaged into setup bundles:
- Profiles: Define the UI structure using columns, rows, stacks, and components
- Layouts: Define the component's columns, sorting, filtering, and other contextual settings.
- Users: User accounts, roles, and profile assignments, categories, time markers, filter values.
- Configuration: System-wide application settings as key/value pairs.
There are two ways to use the capabilities of the setup package builder:
- Desktop Application: Visual workspace building, guided wizards, first-time setup
- CLI: Automation, CI/CD pipelines, version control workflows
There is a two-way document flow: packages can be imported from Dime.Scheduler, and packages can be created from scratch and deployed to Dime.Scheduler. Human-friendly package files can also be easily stored in version control and deployments can be automated through the CLI.
Getting started
Installation
Desktop application
The desktop application provides a visual interface for creating and managing configurations. It can be downloaded via one of the two available package managers. This installs the Dime.Scheduler Setup Package Builder to your desktop.
- Chocolatey
- Scoop
Deployments to chocolatey are currently suspended. For the time being, use scoop.
choco install dimescheduler-setup
scoop bucket add dimescheduler https://github.com/dime-scheduler/setup-packages-distro
scoop install dimescheduler-setup
If you're on macOS, you can install via Homebrew:
brew tap dime-scheduler/setup-packages-distro https://github.com/dime-scheduler/setup-packages-distro
brew install --cask dimescheduler-setup
CLI
The CLI is ideal for automation, CI/CD pipelines, and version control workflows.
- npm
- npx
npm install -g @dimescheduler/setup
npx @dimescheduler/setup <command>
Quick start
- Create a configuration file
my-profile.json5:
{
type: "bundle",
name: "Complete Setup Package",
version: "1.0.0",
owner: "[email protected]",
notificationEmail: "[email protected]",
documents: [
{
type: "profile",
payload: {
name: "Service Planning",
code: "SERVICE_PLANNING",
theme: { color: "blue" },
workspace: [
{
type: "column",
width: 30,
content: [{ type: "component", component: "openTasks", title: "Open Tasks" }]
},
{
type: "column",
width: 70,
content: [{ type: "component", component: "planningBoard", title: "Planning Board", id: "scheduler1" }]
}
]
}
}
]
}
- Validate your configuration:
dimescheduler-setup validate my-profile.json5
- Deploy to your Dime.Scheduler instance:
dimescheduler-setup deploy my-profile.json5 --api-key YOUR_API_KEY --env production
Document types
The DSL supports the following document types, each serving a specific purpose:
| Type | Purpose |
|---|---|
profile | Define the workspace configuration, including planning settings and the workspace tree. |
layouts | Grid and component layouts |
users | User accounts and permissions |
configuration | System-wide application settings |
Every document follows this structure:
{
type: "profile" | "layouts" | "users" | "configuration",
payload: { ... }
}
Each document belongs to the documents element in the documents root node. More about this later in the bundles section.
{
type: "bundle",
name: "Complete Setup Package",
version: "1.0.0",
owner: "[email protected]",
notificationEmail: "[email protected]",
documents: [
{
type: "profile",
payload: {
name: "Service Planning",
code: "SERVICE_PLANNING",
// ... profile configuration
}
},
{
type: "layouts",
payload: [
// ... layout definitions
]
},
{
type: "users",
payload: [
// ... user definitions
]
},
{
type: "configuration",
payload: [
// ... user definitions
]
}
],
}
Profile
A profile defines a complete workspace configuration including theme, planning settings, and UI layout.
Required fields
| Field | Type | Description |
|---|---|---|
name | string | Display name (e.g., "Service Planning") |
code | string | Unique identifier in UPPERCASE_WITH_UNDERSCORES |
Theme
Customize the visual appearance:
theme: {
color: "blue", // Accent color
scheme: "sltl" // Color scheme
}
Colors
default(black)primary(teal)redgreenorangepurpleblue
Schemes
| Code | Description |
|---|---|
sltl | Light sidebar, Light toolbar |
sltd | Light sidebar, Dark toolbar |
sdtl | Dark sidebar, Light toolbar |
sdtd | Dark sidebar, Dark toolbar (default) |
Sharing
Control who can access the profile:
shared: {
global: false, // Available to all users
userGroup: "Planners" // Restrict to specific group
}
Route configuration
Configure route calculation behavior:
route: {
calculateRoutes: true, // Enable automatic route calculation
showSequenceIndicators: true, // Show sequence numbers on routes
unitOfDistance: "km" // "km" or "mi"
}
Planning settings
Configure the planning board behavior:
planning: {
snapInterval: "1hour", // Task snapping interval
range: {
mode: "week", // Display range
value: 2 // Number of units
},
start: {
mode: "startOfWeek", // Start date mode
value: 0 // Offset in days
},
hours: {
start: 8, // Working day start (0-23)
end: 18 // Working day end (0-24)
}
}
Snap interval options
Available options are:
5min10min15min30min1hour2hours4hours12hours1day
Range modes
| Mode | Description |
|---|---|
day | Single day view |
week | Week view |
month | Month view |
Start modes
| Mode | Description |
|---|---|
today | Start from today |
startOfWeek | Start from beginning of current week |
startOfMonth | Start from beginning of current month |
Workspace builder
The workspace defines the UI layout using a tree structure of containers and components.
Container types
Column (vertical split)
Children are stacked top-to-bottom:
{
type: "column",
width: 30, // Percentage width (0-100)
content: [ ... ] // Child elements
}
Row (horizontal split)
Children are placed side-by-side:
{
type: "row",
height: 50, // Percentage height (0-100)
content: [ ... ] // Child elements
}
Stack (tabbed container)
Only one child visible at a time, with tabs to switch:
{
type: "stack",
width: 100, // Optional
height: 50, // Optional
content: [ ... ] // Components or nested containers
}
Components
Leaf nodes that render actual UI components:
{
type: "component",
component: "planningBoard", // Component identifier
title: "Planning Board", // Tab/header title
id: "scheduler1", // Unique instance ID
layoutRef: "SCHEDULER_LAYOUT" // Optional: reference to layout code to set this layout as the default configuration for this component instance
}
Available components
openTasksplanningBoardplannedTasksmapindicatorsresourceFiltersdetailsdatePickerganttcapacityrouteSequencenotifications
Layout example
A typical two-column layout with sidebar and main content:
workspace: [
{
type: "column",
width: 25,
content: [
{
type: "stack",
content: [
{ type: "component", component: "openTasks", title: "Open Tasks" },
{ type: "component", component: "plannedTasks", title: "Planned Tasks" }
]
},
{ type: "component", component: "resourceFilters", title: "Filters" }
]
},
{
type: "column",
width: 75,
content: [
{
type: "component",
component: "planningBoard",
title: "Planning Board",
id: "scheduler1",
layoutRef: "SCHEDULER_DEFAULT"
}
]
}
]
Layouts
Layouts define how data grids and components display information. They can be defined inline within components or as standalone documents for reuse.
Layout contexts
Each layout targets a specific component type:
planningBoardopenTasksplannedTasksdetailscapacityganttrouteSequencenotifications
Grid-based component layout properties
{
context: "planningBoard", // Target component type
code: "SCHEDULER_COMPACT", // Unique identifier
name: "Compact View", // Display name
// Grid configuration
columns: [
{ property: "DisplayName", width: 200 },
{ property: "Category", width: 100 }
],
sorters: [
{ property: "DisplayName", direction: "ASC" }
],
filters: [ ... ],
grouper: {
property: "Category",
direction: "ASC"
},
pageSize: 50,
// Sharing
shared: {
public: true,
userGroup: "Planners"
}
}
Planning board layout properties
Additional properties specific to the planning board (context: "planningBoard"):
{
context: "planningBoard",
code: "SCHEDULER_WEEK",
viewPreset: "week", // day, week, workWeek, month
rowHeight: "2rows", // 1row, 2rows, 3rows, 4rows
resourcesGridWidth: "25%", // Width of resource column
fitToScreen: false, // Fit grid to screen
ignoreCalendars: false // Ignore calendar configurations
}
View presets:
dayweekworkWeekmonth
Row heights:
1row2rows3rows4rows
Standalone layouts document
Create reusable layouts in a separate document:
{
type: "layouts",
payload: [
{
context: "planningBoard",
code: "SCHEDULER_COMPACT",
name: "Compact Scheduler",
default: true,
viewPreset: "week",
rowHeight: "1row",
columns: [
{ property: "DisplayName" }
]
},
{
context: "openTasks",
code: "OPEN_TASKS_DEFAULT",
name: "Default Open Tasks",
columns: [
{ property: "TaskNo" },
{ property: "ShortDescription" },
{ property: "Category" }
],
sorters: [
{ property: "TaskNo", direction: "DESC" }
]
}
]
}
Referencing layouts
Reference standalone layouts from components using layoutRef:
{
type: "component",
component: "planningBoard",
title: "Planning Board",
id: "scheduler1",
layoutRef: "SCHEDULER_COMPACT" // Reference by code
}
Users
Define user accounts, their roles, and profile assignments.
User properties
{
name: "John Smith", // Display name
email: "[email protected]", // Email
isMSEntraID: true, // MS Entra ID authentication
language: "en", // Language code
timeZone: "Europe/Brussels", // IANA timezone
profiles: [
{ name: "SERVICE_PLANNING", default: true },
{ name: "FIELD_SERVICE" }
],
roles: ["Planner", "Dispatcher"],
timeMarkers: ["Lunch", "Break"],
categories: ["Urgent", "Normal"],
filterValues: ["Region A", "Region B"]
}
Users document
{
type: "users",
payload: [
{
name: "John Smith",
email: "[email protected]",
language: "en",
timeZone: "Europe/Brussels",
profiles: [
{ name: "SERVICE_PLANNING", default: true }
],
roles: ["Planner"]
},
{
name: "Jane Doe",
email: "[email protected]",
language: "nl",
timeZone: "Europe/Amsterdam",
profiles: [
{ name: "SERVICE_PLANNING" },
{ name: "FIELD_SERVICE", default: true }
],
roles: ["Dispatcher", "Administrator"]
}
]
}
Configuration
Configuration documents define system-wide application settings as key/value pairs. These settings control application behavior, integrations, and display preferences.
Configuration document
{
type: "configuration",
payload: [
{ key: "CompanyName", value: "Acme Corporation" },
{ key: "DurationFormat", value: "HoursMinutes" },
{ key: "DistanceUnit", value: "km" },
{ key: "EnablePlanningBoardTooltip", value: true },
{ key: "ExchangeDefaultShowAs", value: ["Office", "OutOfOffice"] }
]
}
Available configuration keys
| Category | Key | Description |
|---|---|---|
| Company | CompanyName | Company name displayed in the application |
CompanyAddress | Company address for route calculations | |
CompanyAddressCountry | Country of the company address | |
| Display | DurationFormat | Duration format: Decimal, HoursMinutes, DaysDecimal, DaysHours |
EnableAppointmentContainers | Enable appointment containers feature | |
EnablePlanningBoardTooltip | Show tooltips on planning board appointments | |
RenderCategoryInBackground | Render category color in appointment background | |
AlternateRows | Alternate row colors in planning board | |
EnableResourceCalendarsVisualisation | Show resource calendar zones on planning board | |
ResourceZonesColor | Color for resource availability zones (hex format) | |
| Planning | ApplyRequestedDates | Apply requested date constraints when planning |
ApplyRequestedTimes | Apply requested time constraints when planning | |
RespectAllowedDateConstraints | Respect allowed date constraints from source system | |
MultiDayCapacityDistributionMode | Multi-day capacity distribution: None, Constant, Even | |
ResourceCalendarRecalculationMode | Calendar recalculation: None, ExtendDuration, UpdatePlanningQuantity, SubtractNonWorkingTime | |
DoNotCountAssignment | Do not count appointment resource in capacity calculations | |
DisableTaskDurationCalculation | Disable automatic recalculation of planning quantity | |
| Routing | RouteReschedulingMode | Route rescheduling: DoNothing, UpdateTravelTime, Optimize |
CalculateRouteAndTravelTime | Calculate route and travel time automatically | |
DistanceUnit | Unit of distance: km, mi | |
RouteProfile | Route profile: car, van, truck, motorcycle, bicycle, pedestrian | |
ShowWaypoints | Show waypoints on map routes | |
| Mobile | MobileVisibilityModeForLockedAppointments | Locked appointment visibility: Locked, Hidden |
| AI & Optimization | SolverApiKey | API key for route optimization solver |
EnableRouteModel | Enable route optimization features | |
EnableFieldServiceModel | Enable field service solver (VRP) | |
Chat | Show AI chat feature in sidebar | |
OpenAiApiKey | OpenAI API key for AI chat features | |
| Exchange Sync | ExchangeClientId | Microsoft Entra ID App Registration client ID |
ExchangeClientSecret | Microsoft Entra ID App Registration client secret | |
ExchangeClientTenant | Microsoft Entra ID App Registration tenant ID | |
ExchangeEnableTwoWaySync | Enable two-way sync between Exchange and Dime.Scheduler | |
ExchangeDeltaStart | Delta start time for Exchange sync (e.g., -30 days) | |
ExchangeDeltaEnd | Delta end time for Exchange sync (e.g., 30 days) | |
ExchangeResourcePreferencesEnabled | Allow users to manage their Exchange sync preferences | |
ExchangeDefaultShowAs | Busy status filter (array): Free, Tentative, Office, OutOfOffice, WorkingElsewhere, Unknown | |
ExchangeDefaultSensitivity | Sensitivity filter (array): Normal, Personal, Private, Confidential | |
ExchangeCategoryPreset | Category preset for Exchange appointments | |
ExchangeUseCategory | Use category for Exchange appointments |
Bundles
Bundles combine multiple documents for atomic deployment. To deploy profiles, layouts, and/or users (together), you must include them in the documents array in the package schema.
Bundle structure
{
type: "bundle",
name: "Complete Setup Package",
version: "1.0.0",
owner: "[email protected]",
notificationEmail: "[email protected]",
documents: [
{
type: "profile",
payload: {
name: "Service Planning",
code: "SERVICE_PLANNING",
// ... profile configuration
}
},
{
type: "layouts",
payload: [
// ... layout definitions
]
},
{
type: "users",
payload: [
// ... user definitions
]
},
{
type: "configuration",
payload: [
// ... user definitions
]
}
],
mergeStrategy: {
layouts: "append", // append, replace, error
users: "append", // append, replace, error
profiles: "last-wins" // last-wins, first-wins, error
}
}
Merge strategies
Control how duplicate items are handled:
| Strategy | Behavior |
|---|---|
append | Add new items, keep existing (default for layouts/users) |
replace | Replace all existing items |
error | Fail if duplicates exist |
last-wins | Last definition wins (default for profiles) |
first-wins | First definition wins |
Examples
Basic profile
A minimal profile with planning board and open tasks:
{
type: "profile",
owner: "[email protected]",
payload: {
name: "Basic Planning",
code: "BASIC_PLANNING",
theme: {
color: "blue",
scheme: "sltl"
},
planning: {
snapInterval: "1hour",
range: { mode: "week" },
hours: { start: 8, end: 17 }
},
workspace: [
{
type: "column",
width: 25,
content: [
{
type: "component",
component: "openTasks",
title: "Open Tasks"
}
]
},
{
type: "column",
width: 75,
content: [
{
type: "component",
component: "planningBoard",
title: "Planning Board",
id: "scheduler1"
}
]
}
]
}
}
Full-featured profile
A complete profile with all components and custom layouts:
{
type: "profile",
owner: "[email protected]",
notificationEmail: "[email protected]",
payload: {
name: "Service Planning",
code: "SERVICE_PLANNING",
theme: {
color: "primary",
scheme: "sdtd"
},
shared: {
global: false,
userGroup: "Planners"
},
route: {
calculateRoutes: true,
showSequenceIndicators: true,
unitOfDistance: "km"
},
planning: {
snapInterval: "30min",
range: { mode: "week", value: 2 },
start: { mode: "startOfWeek" },
hours: { start: 7, end: 19 }
},
workspace: [
{
type: "column",
width: 20,
content: [
{
type: "stack",
content: [
{ type: "component", component: "openTasks", title: "Open Tasks" },
{ type: "component", component: "plannedTasks", title: "Planned" }
]
},
{ type: "component", component: "resourceFilters", title: "Filters" },
{ type: "component", component: "datePicker", title: "Calendar" }
]
},
{
type: "column",
width: 60,
content: [
{
type: "component",
component: "planningBoard",
title: "Planning Board",
id: "scheduler1",
layoutRef: "SCHEDULER_DETAILED"
}
]
},
{
type: "column",
width: 20,
content: [
{ type: "component", component: "map", title: "Map" },
{ type: "component", component: "details", title: "Details" },
{ type: "component", component: "indicators", title: "Indicators" }
]
}
]
}
}
Complete bundle
A bundle with profile, layouts, and users:
{
type: "bundle",
name: "Service Department Setup",
version: "1.0.0",
owner: "[email protected]",
documents: [
// Profile
{
type: "profile",
payload: {
name: "Service Planning",
code: "SERVICE_PLANNING",
theme: { color: "blue" },
workspace: [
{
type: "column",
width: 30,
content: [
{ type: "component", component: "openTasks", title: "Tasks" }
]
},
{
type: "column",
width: 70,
content: [
{
type: "component",
component: "planningBoard",
title: "Board",
id: "scheduler1",
layoutRef: "SCHEDULER_DEFAULT"
}
]
}
]
}
},
// Layouts
{
type: "layouts",
payload: [
{
context: "planningBoard",
code: "SCHEDULER_DEFAULT",
name: "Default Scheduler",
default: true,
viewPreset: "week",
rowHeight: "2rows",
columns: [
{ property: "DisplayName" },
{ property: "Category" }
]
}
]
},
// Users
{
type: "users",
payload: [
{
name: "Service Manager",
email: "[email protected]",
profiles: [{ name: "SERVICE_PLANNING", default: true }],
roles: ["Administrator", "Planner"]
},
{
name: "Dispatcher",
email: "[email protected]",
profiles: [{ name: "SERVICE_PLANNING", default: true }],
roles: ["Planner"]
}
]
}
],
mergeStrategy: {
layouts: "append",
users: "append",
profiles: "last-wins"
}
}
CI/CD integration
CI pipeline example (GitHub Actions):
name: Deploy Configuration
on:
push:
branches: [main]
paths:
- 'config/**'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install CLI
run: npm install -g @dimescheduler/setup
- name: Validate
run: dimescheduler-setup validate config/bundle.json5
- name: Deploy to Sandbox
if: github.ref == 'refs/heads/develop'
run: dimescheduler-setup deploy config/bundle.json5 --env sandbox -y
env:
DS_API_KEY: ${{ secrets.DS_API_KEY_SANDBOX }}
- name: Deploy to Production
if: github.ref == 'refs/heads/main'
run: dimescheduler-setup deploy config/bundle.json5 --env production -y
env:
DS_API_KEY: ${{ secrets.DS_API_KEY_PRODUCTION }}
Import from Dime.Scheduler
User-generated content
In Dime.Scheduler's user-generated content page, you can export a bundle that contains the profiles and the default layouts to the components in those layouts.
The exported, raw, JSON file can be then imported into the setup package builder.
System
In the System page, there is a button to export all supported non-transactional setup:
- Profiles
- Layouts
- Users
The exported, raw, JSON file can be then also imported into the setup package builder.