import 'bootstrap.css';
import '@mescius/wijmo.styles/wijmo.css';
import './styles.css';
import * as wjcCore from '@mescius/wijmo';
import * as wjcInput from '@mescius/wijmo.input';
import * as wjcScheduler from '@mescius/wijmo.scheduler';
import { getDemoDisplayDate, getSchedulerItems, getSchedulerResources } from './data';
const bindings = {
none: null,
'time:hour': {
type: wjcScheduler.SchedulerAxisBindingType.Time,
unit: wjcScheduler.SchedulerTimeUnit.Hour,
visible: (args) => args.hour !== undefined && args.hour >= 6 && args.hour < 20,
},
'time:day': { type: wjcScheduler.SchedulerAxisBindingType.Time, unit: wjcScheduler.SchedulerTimeUnit.Day },
'time:dayOfWeek': {
type: wjcScheduler.SchedulerAxisBindingType.Time,
unit: wjcScheduler.SchedulerTimeUnit.DayOfWeek,
},
'time:dayOfMonth': {
type: wjcScheduler.SchedulerAxisBindingType.Time,
unit: wjcScheduler.SchedulerTimeUnit.DayOfMonth,
},
'time:weekOfMonth': {
type: wjcScheduler.SchedulerAxisBindingType.Time,
unit: wjcScheduler.SchedulerTimeUnit.WeekOfMonth,
},
'resource:team': { type: wjcScheduler.SchedulerAxisBindingType.Resource, fieldExpr: 'teamId' },
'resource:region': { type: wjcScheduler.SchedulerAxisBindingType.Resource, fieldExpr: 'regionId' },
};
const bindingLabels = {
none: 'None',
'time:hour': 'Hour',
'time:day': 'Day',
'time:dayOfWeek': 'Day of Week',
'time:dayOfMonth': 'Day of Month',
'time:weekOfMonth': 'Week of Month',
'resource:team': 'Resource: Team',
'resource:region': 'Resource: Region',
};
const toolbarViewOptions = [
[wjcScheduler.SchedulerBuiltInViewItem.Day, 'Day'],
[wjcScheduler.SchedulerBuiltInViewItem.Week, 'Week'],
[wjcScheduler.SchedulerBuiltInViewItem.WorkWeek, 'Work Week'],
[wjcScheduler.SchedulerBuiltInViewItem.Month, 'Month'],
[wjcScheduler.SchedulerBuiltInViewItem.TimelineDay, 'Timeline Day'],
[wjcScheduler.SchedulerBuiltInViewItem.TimelineWeek, 'Timeline Week'],
[wjcScheduler.SchedulerBuiltInViewItem.TimelineMonth, 'Timeline Month'],
];
function clone(config) {
return {
viewport: config.viewport,
semantic: config.semantic,
row: config.row.slice(),
column: config.column.slice(),
};
}
function preset(viewport) {
const timed = wjcScheduler.SchedulerCellSemantic.Timed;
const summary = wjcScheduler.SchedulerCellSemantic.Summary;
switch (viewport) {
case 'day':
return { viewport, semantic: timed, row: ['time:hour'], column: ['time:day'] };
case 'month':
return { viewport, semantic: summary, row: ['time:weekOfMonth'], column: ['time:dayOfWeek'] };
case 'timelineDay':
return { viewport, semantic: timed, row: [], column: ['time:day', 'time:hour'] };
case 'timelineWeek':
return { viewport, semantic: timed, row: [], column: ['time:dayOfWeek', 'time:hour'] };
case 'timelineMonth':
return { viewport, semantic: summary, row: [], column: ['time:dayOfMonth'] };
case 'workWeek':
return { viewport, semantic: timed, row: ['time:hour'], column: ['time:dayOfWeek'] };
default:
return { viewport: 'week', semantic: timed, row: ['time:hour'], column: ['time:dayOfWeek'] };
}
}
function definition(config) {
const make = (keys) => keys.map((key) => bindings[key]).filter((value) => !!value);
const columns = make(config.column).map((binding) => binding.type === wjcScheduler.SchedulerAxisBindingType.Time &&
binding.unit === wjcScheduler.SchedulerTimeUnit.DayOfWeek &&
config.viewport === 'workWeek'
? Object.assign(Object.assign({}, binding), { visible: (args) => args.dayOfWeek >= 1 && args.dayOfWeek <= 5 }) : binding);
return {
key: config.viewport === 'custom' ? 'customOverview' : config.viewport,
rows: { bindings: make(config.row) },
columns: { bindings: columns },
cellSemantic: config.semantic,
};
}
function init() {
const resourceData = getSchedulerResources();
const itemsSource = new wjcCore.CollectionView(getSchedulerItems());
const resources = [
{ fieldExpr: 'teamId', label: 'Team', dataSource: resourceData.teams, valueExpr: 'id', displayExpr: 'text' },
{
fieldExpr: 'regionId',
label: 'Region',
dataSource: resourceData.regions,
valueExpr: 'id',
displayExpr: 'text',
},
];
const toolbarViews = new Set(toolbarViewOptions.map(([key]) => key));
const createToolbarViewItems = () => toolbarViewOptions.filter(([key]) => toolbarViews.has(key)).map(([key, name]) => ({ key, name }));
const toolbarViewItems = createToolbarViewItems();
const scheduler = new wjcScheduler.FlexScheduler('#theScheduler', {
itemsSource,
resources,
definition: definition(preset('workWeek')),
displayDate: getDemoDisplayDate(),
timeZone: 'Asia/Shanghai',
workHours: [{ start: '06:00', end: '19:00' }],
showToolbar: true,
showColumnHeaders: true,
showRowHeaders: true,
allowDragEvent: true,
allowResizeEvent: true,
toolbarViewItems,
});
const state = { config: preset('workWeek'), workingTime: true, customTemplate: false };
const dateInput = new wjcInput.InputDate('#displayDateInput', { value: scheduler.displayDate });
dateInput.valueChanged.addHandler(() => {
if (dateInput.value)
scheduler.displayDate = dateInput.value;
});
scheduler.displayDateChanged.addHandler(() => {
if (!dateInput.value || dateInput.value.getTime() !== scheduler.displayDate.getTime())
dateInput.value = scheduler.displayDate;
});
document.querySelectorAll('[data-config-tab]').forEach((button) => button.addEventListener('click', () => {
document.querySelectorAll('.config-section').forEach((section) => {
section.hidden = section.dataset.section !== button.dataset.configTab;
});
document.querySelectorAll('[data-config-tab]').forEach((tab) => {
const selected = tab === button;
tab.classList.toggle('active', selected);
tab.setAttribute('aria-selected', String(selected));
});
}));
document.querySelectorAll('.config-section').forEach((section) => {
section.hidden = section.dataset.section !== 'view';
});
const definitionFeedback = document.querySelector('#definitionFeedback');
const apply = () => {
const next = definition(state.config);
const integrity = wjcScheduler.planSchedulerProjection(next).integrity;
if (integrity.level === 'unsupported') {
showDefinitionFeedback('error', `Layout not applied: ${integrity.reasons.join(' ')}`);
return;
}
scheduler.definition = Object.assign(Object.assign({}, next), { itemTemplate: state.customTemplate ? renderItem : null });
if (integrity.level === 'lossy') {
showDefinitionFeedback('warning', `Layout adjusted: ${integrity.reasons.join(' ')}`);
}
else {
definitionFeedback.hidden = true;
definitionFeedback.textContent = '';
}
};
const showDefinitionFeedback = (level, message) => {
definitionFeedback.className = `definition-feedback ${level}`;
definitionFeedback.textContent = message;
definitionFeedback.hidden = false;
};
const select = document.querySelector('#viewportSelect');
select.addEventListener('change', () => {
if (select.value !== 'custom') {
state.config = preset(select.value);
render();
apply();
}
});
document.querySelector('#semanticSelect').addEventListener('change', (event) => {
state.config.semantic =
event.target.value === 'summary'
? wjcScheduler.SchedulerCellSemantic.Summary
: wjcScheduler.SchedulerCellSemantic.Timed;
state.config.viewport = 'custom';
render();
});
document.querySelector('#applyAxisConfig').addEventListener('click', apply);
document.querySelector('#resetAxisConfig').addEventListener('click', () => {
state.config = preset('workWeek');
render();
apply();
});
document
.querySelector('#timeZoneSelect')
.addEventListener('change', (event) => (scheduler.timeZone = event.target.value || null));
document.querySelector('#workingTime').addEventListener('change', (event) => {
state.workingTime = event.target.checked;
scheduler.workHours = state.workingTime ? [{ start: '06:00', end: '19:00' }] : null;
});
document.querySelector('#customItemTemplate').addEventListener('change', (event) => {
state.customTemplate = event.target.checked;
apply();
});
document
.querySelector('#showToolbar')
.addEventListener('change', (event) => (scheduler.showToolbar = event.target.checked));
document
.querySelector('#showColumnHeaders')
.addEventListener('change', (event) => (scheduler.showColumnHeaders = event.target.checked));
document
.querySelector('#showRowHeaders')
.addEventListener('change', (event) => (scheduler.showRowHeaders = event.target.checked));
document
.querySelector('#allowDrag')
.addEventListener('change', (event) => (scheduler.allowDragEvent = event.target.checked));
document
.querySelector('#allowResize')
.addEventListener('change', (event) => (scheduler.allowResizeEvent = event.target.checked));
document.querySelectorAll('#builtInViewItems input').forEach((checkbox, index) => checkbox.addEventListener('change', () => {
const key = toolbarViewOptions[index][0];
if (checkbox.checked)
toolbarViews.add(key);
else
toolbarViews.delete(key);
scheduler.toolbarViewItems = createToolbarViewItems();
}));
document.querySelectorAll('[data-add-binding]').forEach((button) => button.addEventListener('click', () => {
const group = button.dataset.addBinding;
(group === 'row' ? state.config.row : state.config.column).push('none');
state.config.viewport = 'custom';
render();
}));
render();
function render() {
select.value = state.config.viewport;
document.querySelector('#semanticSelect').value =
state.config.semantic === wjcScheduler.SchedulerCellSemantic.Summary ? 'summary' : 'timed';
for (const group of ['row', 'column']) {
const list = document.querySelector(`#${group}BindingsList`);
list.textContent = '';
state.config[group].forEach((value, index) => {
const row = document.createElement('div');
const bindingSelect = document.createElement('select');
const removeButton = document.createElement('button');
row.className = 'binding-row';
Object.keys(bindings).forEach((key) => bindingSelect.add(new Option(bindingLabels[key], key)));
bindingSelect.value = value;
bindingSelect.addEventListener('change', () => {
state.config[group][index] = bindingSelect.value;
state.config.viewport = 'custom';
render();
});
removeButton.className = 'icon-button';
removeButton.type = 'button';
removeButton.title = 'Remove binding';
removeButton.textContent = 'x';
removeButton.addEventListener('click', () => {
state.config[group].splice(index, 1);
state.config.viewport = 'custom';
render();
});
row.append(bindingSelect, removeButton);
list.appendChild(row);
});
}
document.querySelector('#configRowsPreview').textContent =
`Rows: ${state.config.row.map((key) => bindingLabels[key]).join(' + ') || 'none'}`;
document.querySelector('#configColumnsPreview').textContent =
`Columns: ${state.config.column.map((key) => bindingLabels[key]).join(' + ') || 'none'}`;
}
}
function renderItem(ctx, element) {
element.textContent = '';
const subject = document.createElement('strong');
subject.textContent = ctx.item.subject;
element.appendChild(subject);
return null;
}
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', init) : init();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>MESCIUS Wijmo Scheduler Overview</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/systemjs@0.21.5/dist/system.src.js" integrity="sha512-skZbMyvYdNoZfLmiGn5ii6KmklM82rYX2uWctBhzaXPxJgiv4XBwJnFGr5k8s+6tE1pcR1nuTKghozJHyzMcoA==" crossorigin="anonymous"></script>
<script src="systemjs.config.js"></script>
<script>System.import('./src/app');</script>
</head>
<body>
<main class="scheduler-demo-page">
<section class="workspace-layout">
<div class="scheduler-shell"><div id="theScheduler"></div></div>
<aside class="config-panel">
<div class="config-panel-header">
<h2>Scheduler Configuration</h2>
<div class="config-tabs" role="tablist" aria-label="Scheduler configuration">
<button class="active" type="button" role="tab" data-config-tab="view" aria-selected="true">View</button>
<button type="button" role="tab" data-config-tab="time" aria-selected="false">Time</button>
<button type="button" role="tab" data-config-tab="display" aria-selected="false">Display</button>
<button type="button" role="tab" data-config-tab="interaction" aria-selected="false">Interaction</button>
</div>
</div>
<div class="config-panel-body">
<section class="config-section" data-section="view">
<label class="field-control"><span>View preset</span><select id="viewportSelect"><option value="custom">Custom</option><option value="day">Day</option><option value="week">Week</option><option value="workWeek">Work Week</option><option value="month">Month</option><option value="timelineDay">Timeline Day</option><option value="timelineWeek">Timeline Week</option><option value="timelineMonth">Timeline Month</option></select></label>
<label class="field-control"><span>Cell semantic</span><select id="semanticSelect"><option value="timed">Timed</option><option value="summary">Summary</option></select></label>
<section class="binding-section"><div class="section-heading"><h3>Row bindings</h3><button class="small-button" type="button" data-add-binding="row">Add</button></div><div id="rowBindingsList" class="binding-list"></div></section>
<section class="binding-section"><div class="section-heading"><h3>Column bindings</h3><button class="small-button" type="button" data-add-binding="column">Add</button></div><div id="columnBindingsList" class="binding-list"></div></section>
<div class="draft-preview"><span id="configRowsPreview"></span><span id="configColumnsPreview"></span></div>
<div id="definitionFeedback" class="definition-feedback" role="alert" aria-live="polite" hidden></div>
<div class="button-row"><button id="applyAxisConfig" class="demo-button primary-button" type="button">Apply Layout</button><button id="resetAxisConfig" class="demo-button" type="button">Reset Layout</button></div>
</section>
<section class="config-section" data-section="time">
<div class="field-control"><label for="displayDateInput">Display date</label><div id="displayDateInput"></div></div>
<label class="field-control"><span>Time zone</span><select id="timeZoneSelect"><option value="">Browser local</option><option value="UTC">UTC</option><option value="America/Los_Angeles">America/Los_Angeles</option><option value="America/New_York">America/New_York</option><option value="Europe/London">Europe/London</option><option value="Asia/Tokyo">Asia/Tokyo</option><option value="Asia/Shanghai" selected>Asia/Shanghai</option></select></label>
<label class="toggle-control"><input id="workingTime" type="checkbox" checked><span>Working time (06:00-19:00)</span></label>
</section>
<section class="config-section" data-section="display">
<div class="toggle-list"><label class="toggle-control"><input id="showToolbar" type="checkbox" checked><span>Toolbar</span></label><label class="toggle-control"><input id="showColumnHeaders" type="checkbox" checked><span>Column headers</span></label><label class="toggle-control"><input id="showRowHeaders" type="checkbox" checked><span>Row headers</span></label><label class="toggle-control"><input id="customItemTemplate" type="checkbox"><span>Custom item template</span></label></div>
<div class="field-control"><span>Built-in view buttons</span><div id="builtInViewItems" class="view-item-grid"><label><input type="checkbox" checked>Day</label><label><input type="checkbox" checked>Week</label><label><input type="checkbox" checked>Work Week</label><label><input type="checkbox" checked>Month</label><label><input type="checkbox" checked>Timeline Day</label><label><input type="checkbox" checked>Timeline Week</label><label><input type="checkbox" checked>Timeline Month</label></div></div>
</section>
<section class="config-section" data-section="interaction"><div class="toggle-list"><label class="toggle-control"><input id="allowDrag" type="checkbox" checked><span>Allow drag</span></label><label class="toggle-control"><input id="allowResize" type="checkbox" checked><span>Allow resize</span></label></div></section>
</div>
</aside>
</section>
</main>
</body>
</html>
function createUtcDate(year, month, day, hour, minute = 0) {
// Demo data uses fixed instants so changing the browser time zone changes the rendered slot.
return new Date(Date.UTC(year, month, day, hour, minute, 0, 0));
}
export function getDemoDisplayDate() {
return createUtcDate(2026, 4, 6, 1, 0);
}
export function getSchedulerResources() {
return {
regions: [
{ id: 'region-east', text: 'East Region', backgroundColor: '#dbeafe', foreColor: '#0f172a' },
{ id: 'region-west', text: 'West Region', backgroundColor: '#dcfce7', foreColor: '#0f172a' },
{ id: 'region-central', text: 'Central Region', backgroundColor: '#fef3c7', foreColor: '#0f172a' },
],
teams: [
{ id: 'team-alpha', text: 'Alpha Team', backgroundColor: '#4f8ef7', foreColor: '#ffffff' },
{ id: 'team-beta', text: 'Beta Team', backgroundColor: '#36b37e', foreColor: '#ffffff' },
{ id: 'team-gamma', text: 'Gamma Team', backgroundColor: '#8a6fd1', foreColor: '#ffffff' },
{ id: 'team-delta', text: 'Delta Team', backgroundColor: '#e7785b', foreColor: '#ffffff' },
{ id: 'team-epsilon', text: 'Epsilon Team', backgroundColor: '#d19a3b', foreColor: '#ffffff' },
{ id: 'team-zeta', text: 'Zeta Team', backgroundColor: '#3ba7c9', foreColor: '#ffffff' },
{ id: 'team-eta', text: 'Eta Team', backgroundColor: '#6574cd', foreColor: '#ffffff' },
],
};
}
export function getSchedulerItems() {
return [
{
id: 1,
subject: 'Daily Operations',
start: createUtcDate(2026, 4, 4, 0, 30),
end: createUtcDate(2026, 4, 4, 1, 15),
regionId: 'region-east',
teamId: 'team-alpha',
description: 'Review priorities, staffing, and service health for the day.',
},
{
id: 2,
subject: 'Roadmap Planning',
start: createUtcDate(2026, 4, 4, 2, 0),
end: createUtcDate(2026, 4, 4, 3, 30),
regionId: 'region-central',
teamId: 'team-beta',
description: 'Prioritize the next release milestones with product and engineering.',
},
{
id: 3,
subject: 'Customer Onboarding',
start: createUtcDate(2026, 4, 4, 5, 30),
end: createUtcDate(2026, 4, 4, 6, 30),
regionId: 'region-west',
teamId: 'team-gamma',
description: 'Guide the customer team through launch tasks and ownership.',
},
{
id: 4,
subject: 'Design Review',
start: createUtcDate(2026, 4, 5, 1, 0),
end: createUtcDate(2026, 4, 5, 2, 0),
regionId: 'region-west',
teamId: 'team-delta',
description: 'Validate the new workflow and resolve outstanding design decisions.',
},
{
id: 5,
subject: 'Partner Demo',
start: createUtcDate(2026, 4, 5, 3, 0),
end: createUtcDate(2026, 4, 5, 4, 0),
regionId: 'region-east',
teamId: 'team-epsilon',
description: 'Demonstrate the reporting workflow to the implementation partner.',
},
{
id: 6,
subject: 'Release Preparation',
start: createUtcDate(2026, 4, 5, 6, 0),
end: createUtcDate(2026, 4, 5, 8, 0),
regionId: 'region-central',
teamId: 'team-zeta',
description: 'Complete the release checklist and confirm deployment ownership.',
},
{
id: 7,
subject: 'Support Triage',
start: createUtcDate(2026, 4, 6, 0, 0),
end: createUtcDate(2026, 4, 6, 0, 45),
regionId: 'region-east',
teamId: 'team-eta',
description: 'Review overnight incidents and assign customer follow-ups.',
},
{
id: 8,
subject: 'Sprint Planning',
start: createUtcDate(2026, 4, 6, 2, 30),
end: createUtcDate(2026, 4, 6, 4, 0),
regionId: 'region-central',
teamId: 'team-alpha',
description: 'Set the sprint goal and confirm delivery capacity across the team.',
},
{
id: 9,
subject: 'Campaign Briefing',
start: createUtcDate(2026, 4, 6, 5, 0),
end: createUtcDate(2026, 4, 6, 6, 0),
regionId: 'region-west',
teamId: 'team-beta',
description: 'Align sales and marketing teams on campaign timing and messaging.',
},
{
id: 10,
subject: 'Architecture Review',
start: createUtcDate(2026, 4, 6, 7, 0),
end: createUtcDate(2026, 4, 6, 8, 30),
regionId: 'region-east',
teamId: 'team-gamma',
description: 'Review integration boundaries and approve the implementation approach.',
},
{
id: 11,
subject: 'Sales Pipeline Review',
start: createUtcDate(2026, 4, 7, 1, 0),
end: createUtcDate(2026, 4, 7, 2, 0),
regionId: 'region-west',
teamId: 'team-delta',
description: 'Review priority opportunities and agree on next actions.',
},
{
id: 12,
subject: 'Security Workshop',
start: createUtcDate(2026, 4, 7, 3, 30),
end: createUtcDate(2026, 4, 7, 5, 0),
regionId: 'region-central',
teamId: 'team-epsilon',
description: 'Review access controls and close the remaining audit actions.',
},
{
id: 13,
subject: 'Client Check-in',
start: createUtcDate(2026, 4, 7, 6, 30),
end: createUtcDate(2026, 4, 7, 7, 15),
regionId: 'region-east',
teamId: 'team-zeta',
description: 'Share delivery progress and confirm next-week priorities.',
},
{
id: 14,
subject: 'Weekly Metrics',
start: createUtcDate(2026, 4, 8, 0, 30),
end: createUtcDate(2026, 4, 8, 1, 30),
regionId: 'region-central',
teamId: 'team-eta',
description: 'Review product adoption, service levels, and delivery trends.',
},
{
id: 15,
subject: 'Product Showcase',
start: createUtcDate(2026, 4, 8, 2, 30),
end: createUtcDate(2026, 4, 8, 4, 0),
regionId: 'region-east',
teamId: 'team-alpha',
description: 'Present completed features and collect stakeholder feedback.',
},
{
id: 16,
subject: 'Team Retrospective',
start: createUtcDate(2026, 4, 8, 6, 0),
end: createUtcDate(2026, 4, 8, 7, 0),
regionId: 'region-west',
teamId: 'team-beta',
description: 'Capture lessons learned and select improvements for the next sprint.',
},
{
id: 17,
subject: 'Release Readiness',
start: createUtcDate(2026, 4, 12, 1, 0),
end: createUtcDate(2026, 4, 12, 2, 0),
regionId: 'region-west',
teamId: 'team-gamma',
description: 'Confirm launch criteria, communications, and support coverage.',
},
{
id: 18,
subject: 'Quarterly Planning',
start: createUtcDate(2026, 4, 13, 5, 0),
end: createUtcDate(2026, 4, 13, 7, 0),
regionId: 'region-central',
teamId: 'team-delta',
description: 'Align quarterly outcomes, dependencies, and accountable owners.',
},
];
}
html, body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
background: #f3f4f6;
color: #1f2937;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Light", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
user-select: none;
}
.scheduler-demo-page {
box-sizing: border-box;
height: 100vh;
min-height: 100vh;
padding: 5px;
}
.workspace-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 340px;
grid-template-rows: minmax(0, 1fr);
gap: 12px;
box-sizing: border-box;
height: 100%;
min-height: 0;
}
.scheduler-shell, .config-panel {
box-sizing: border-box;
height: 100%;
min-height: 0;
border: 1px solid #e5e7eb;
background: #fff;
}
.scheduler-shell {
min-width: 0;
overflow: hidden;
}
#theScheduler {
width: 100%;
height: 100%;
min-height: 0;
}
.config-panel {
min-width: 0;
overflow: auto;
}
.config-panel,
.config-panel button,
.config-panel input,
.config-panel select,
.config-panel .wj-control,
.config-panel .wj-input,
.config-panel .wj-listbox,
.config-panel .wj-listbox-item,
.config-panel .wj-calendar {
font-family: inherit;
}
.config-panel {
font-size: 14px;
line-height: 1.4;
}
.config-panel .wj-control {
font-size: 14px;
}
.config-panel .wj-listbox-item {
font-size: 14px;
line-height: 1.4;
}
.config-panel-header {
padding: 14px 16px 0;
border-bottom: 1px solid #e5e7eb;
}
.config-panel-header h2 {
margin: 0 0 12px;
color: #111827;
font-size: 16px;
font-weight: 600;
}
.config-tabs {
display: flex;
gap: 2px;
overflow-x: auto;
}
.config-tabs button {
min-height: 34px;
padding: 0 10px;
border: 0;
border-bottom: 2px solid transparent;
background: transparent;
color: #6b7280;
font: inherit;
font-size: 14px;
font-weight: 600;
white-space: nowrap;
}
.config-tabs button.active {
border-bottom-color: #4f46e5;
color: #3730a3;
}
.config-tabs button:focus-visible, .demo-button:focus-visible, .small-button:focus-visible, .icon-button:focus-visible {
outline: 2px solid #4f46e5;
outline-offset: 2px;
}
.config-panel-body {
display: flex;
flex-direction: column;
gap: 12px;
padding: 14px 16px 16px;
}
.config-section {
display: flex;
flex-direction: column;
gap: 12px;
}
.field-control {
display: flex;
flex-direction: column;
gap: 5px;
}
.field-control > span, .field-control > label, .toggle-control, .section-heading h3 {
color: #4b5563;
font-size: 14px;
font-weight: 600;
}
.field-control select, .binding-row select {
width: 100%;
min-height: 32px;
padding: 0 8px;
border: 1px solid #d1d5db;
background: #fff;
color: #111827;
font: inherit;
}
.binding-section {
display: flex;
flex-direction: column;
gap: 8px;
}
.section-heading {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.section-heading h3 {
margin: 0;
color: #111827;
font-size: 14px;
}
.binding-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.binding-row {
display: grid;
grid-template-columns: minmax(0, 1fr) 28px;
gap: 6px;
align-items: center;
}
.small-button, .demo-button, .icon-button {
min-height: 32px;
padding: 0 9px;
border: 1px solid #d1d5db;
background: #fff;
color: #111827;
font: inherit;
font-size: 14px;
font-weight: 600;
}
.icon-button {
width: 28px;
padding: 0;
color: #b91c1c;
}
.primary-button {
border-color: #4f46e5;
background: #4f46e5;
color: #fff;
}
.draft-preview {
display: flex;
flex-direction: column;
gap: 5px;
padding: 9px;
border: 1px solid #e5e7eb;
background: #f9fafb;
color: #4b5563;
font-size: 11px;
}
.definition-feedback {
padding: 8px 10px;
border: 1px solid;
border-radius: 4px;
font-size: 12px;
line-height: 1.4;
}
.definition-feedback.warning {
border-color: #d97706;
background: #fffbeb;
color: #92400e;
}
.definition-feedback.error {
border-color: #dc2626;
background: #fef2f2;
color: #991b1b;
}
.button-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.toggle-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.toggle-control {
display: flex;
align-items: center;
gap: 8px;
color: #374151;
}
.toggle-control input {
accent-color: #4f46e5;
}
.view-item-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 7px;
}
.view-item-grid label {
display: flex;
align-items: center;
gap: 6px;
min-height: 32px;
padding: 0 7px;
border: 1px solid #e5e7eb;
color: #374151;
font-size: 14px;
}
.wj-control:focus-within {
outline: 2px solid rgb(79 70 229 / 24%);
outline-offset: 1px;
}
@media (max-width: 760px) {html, body {
overflow: auto;
}.workspace-layout {
grid-template-columns: 1fr;
height: auto;
min-height: 100vh;
}.scheduler-shell, .config-panel {
height: auto;
}#theScheduler {
height: 680px;
min-height: 680px;
}.config-panel {
max-height: none;
} }
input,
textarea,
[contenteditable="true"] {
user-select: text;
}
(function (global) {
System.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true,
},
meta: {
'*.css': { loader: 'css' },
},
paths: {
// paths serve as alias
'npm:': 'node_modules/',
'cdn:': 'https://cdn.mescius.io/demoapps/packages/wijmojs/5.20262.60-rc/',
'pcdn:': 'https://cdn.jsdelivr.net/npm/',
},
// map tells the System loader where to look for things
map: {
'@mescius/wijmo': 'cdn:@mescius/wijmo/index.js',
'@mescius/wijmo.input': 'cdn:@mescius/wijmo.input/index.js',
'@mescius/wijmo.scheduler': 'cdn:@mescius/wijmo.scheduler/index.js',
'@mescius/wijmo.styles': 'cdn:@mescius/wijmo.styles',
'@mescius/wijmo.cultures': 'cdn:@mescius/wijmo.cultures',
jszip: 'pcdn:jszip@3.8.0/dist/jszip.js',
'bootstrap.css': 'pcdn:bootstrap@5.3.8/dist/css/bootstrap.min.css',
css: 'pcdn:systemjs-plugin-css@0.1.37/css.js',
'plugin-babel': 'pcdn:systemjs-plugin-babel@0.0.25/plugin-babel.js',
'systemjs-babel-build': 'pcdn:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js',
},
packages: {
src: {
defaultExtension: 'js',
},
node_modules: {
defaultExtension: 'js',
},
},
});
})(this);