Skip to main content

Setup Packages

Status: Closed Testing

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.

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.

npx @dimescheduler/setup <command>

Quick start

  1. 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" }]
}
]
}
}
]
}
  1. Validate your configuration:
dimescheduler-setup validate my-profile.json5
  1. 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:

TypePurpose
profileDefine the workspace configuration, including planning settings and the workspace tree.
layoutsGrid and component layouts
usersUser accounts and permissions
configurationSystem-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

FieldTypeDescription
namestringDisplay name (e.g., "Service Planning")
codestringUnique identifier in UPPERCASE_WITH_UNDERSCORES

Theme

Customize the visual appearance:

theme: {
color: "blue", // Accent color
scheme: "sltl" // Color scheme
}

Colors

  • default (black)
  • primary (teal)
  • red
  • green
  • orange
  • purple
  • blue

Schemes

CodeDescription
sltlLight sidebar, Light toolbar
sltdLight sidebar, Dark toolbar
sdtlDark sidebar, Light toolbar
sdtdDark 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:

  • 5min
  • 10min
  • 15min
  • 30min
  • 1hour
  • 2hours
  • 4hours
  • 12hours
  • 1day

Range modes

ModeDescription
daySingle day view
weekWeek view
monthMonth view

Start modes

ModeDescription
todayStart from today
startOfWeekStart from beginning of current week
startOfMonthStart 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

  • openTasks
  • planningBoard
  • plannedTasks
  • map
  • indicators
  • resourceFilters
  • details
  • datePicker
  • gantt
  • capacity
  • routeSequence
  • notifications

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:

  • planningBoard
  • openTasks
  • plannedTasks
  • details
  • capacity
  • gantt
  • routeSequence
  • notifications

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:

  • day
  • week
  • workWeek
  • month

Row heights:

  • 1row
  • 2rows
  • 3rows
  • 4rows

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

CategoryKeyDescription
CompanyCompanyNameCompany name displayed in the application
CompanyAddressCompany address for route calculations
CompanyAddressCountryCountry of the company address
DisplayDurationFormatDuration format: Decimal, HoursMinutes, DaysDecimal, DaysHours
EnableAppointmentContainersEnable appointment containers feature
EnablePlanningBoardTooltipShow tooltips on planning board appointments
RenderCategoryInBackgroundRender category color in appointment background
AlternateRowsAlternate row colors in planning board
EnableResourceCalendarsVisualisationShow resource calendar zones on planning board
ResourceZonesColorColor for resource availability zones (hex format)
PlanningApplyRequestedDatesApply requested date constraints when planning
ApplyRequestedTimesApply requested time constraints when planning
RespectAllowedDateConstraintsRespect allowed date constraints from source system
MultiDayCapacityDistributionModeMulti-day capacity distribution: None, Constant, Even
ResourceCalendarRecalculationModeCalendar recalculation: None, ExtendDuration, UpdatePlanningQuantity, SubtractNonWorkingTime
DoNotCountAssignmentDo not count appointment resource in capacity calculations
DisableTaskDurationCalculationDisable automatic recalculation of planning quantity
RoutingRouteReschedulingModeRoute rescheduling: DoNothing, UpdateTravelTime, Optimize
CalculateRouteAndTravelTimeCalculate route and travel time automatically
DistanceUnitUnit of distance: km, mi
RouteProfileRoute profile: car, van, truck, motorcycle, bicycle, pedestrian
ShowWaypointsShow waypoints on map routes
MobileMobileVisibilityModeForLockedAppointmentsLocked appointment visibility: Locked, Hidden
AI & OptimizationSolverApiKeyAPI key for route optimization solver
EnableRouteModelEnable route optimization features
EnableFieldServiceModelEnable field service solver (VRP)
ChatShow AI chat feature in sidebar
OpenAiApiKeyOpenAI API key for AI chat features
Exchange SyncExchangeClientIdMicrosoft Entra ID App Registration client ID
ExchangeClientSecretMicrosoft Entra ID App Registration client secret
ExchangeClientTenantMicrosoft Entra ID App Registration tenant ID
ExchangeEnableTwoWaySyncEnable two-way sync between Exchange and Dime.Scheduler
ExchangeDeltaStartDelta start time for Exchange sync (e.g., -30 days)
ExchangeDeltaEndDelta end time for Exchange sync (e.g., 30 days)
ExchangeResourcePreferencesEnabledAllow users to manage their Exchange sync preferences
ExchangeDefaultShowAsBusy status filter (array): Free, Tentative, Office, OutOfOffice, WorkingElsewhere, Unknown
ExchangeDefaultSensitivitySensitivity filter (array): Normal, Personal, Private, Confidential
ExchangeCategoryPresetCategory preset for Exchange appointments
ExchangeUseCategoryUse 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:

StrategyBehavior
appendAdd new items, keep existing (default for layouts/users)
replaceReplace all existing items
errorFail if duplicates exist
last-winsLast definition wins (default for profiles)
first-winsFirst 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"
}
]
}
]
}
}

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.