devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
720 lines (719 loc) • 60.1 kB
JavaScript
/**
* DevExtreme (cjs/__internal/scheduler/appointments_new/appointments.test.js)
* Version: 25.2.7
* Build date: Tue May 05 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
"use strict";
var _globals = require("@jest/globals");
var _renderer = _interopRequireDefault(require("../../../core/renderer"));
var _fx = _interopRequireDefault(require("../../../common/core/animation/fx"));
var _appointment_data_accessor = require("../__mock__/appointment_data_accessor.mock");
var _resource_manager = require("../__mock__/resource_manager.mock");
var _appointment_view_model = require("./__mock__/appointment_view_model");
var _appointments = require("./appointments");
var _const = require("./const");
function _interopRequireDefault(e) {
return e && e.__esModule ? e : {
default: e
}
}
const mockAppointmentDataSource = () => ({
getUpdatedAppointment: () => null,
getUpdatedAppointmentKeys: () => []
});
const getProperties = function() {
let options = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
return {
currentView: "week",
tabIndex: 0,
viewModel: [],
items: [],
$allDayContainer: (0, _renderer.default)("<div>"),
appointmentTemplate: "appointment",
appointmentCollectorTemplate: "appointmentCollector",
onAppointmentRendered: () => {},
getStartViewDate: () => new Date(2024, 0, 1),
getSortedAppointments: () => [],
isVirtualScrolling: () => false,
scrollTo: () => {},
getAppointmentDataSource: mockAppointmentDataSource,
getResourceManager: () => (0, _resource_manager.getResourceManagerMock)(options.resources ?? []),
getDataAccessor: () => _appointment_data_accessor.mockAppointmentDataAccessor
}
};
const createAppointments = properties => {
const $element = (0, _renderer.default)(".root");
return new _appointments.Appointments($element, properties)
};
const defaultAppointmentData = {
text: "Test appointment",
startDate: new Date(2024, 0, 1, 9, 0),
endDate: new Date(2024, 0, 1, 10, 0)
};
(0, _globals.describe)("Appointments", () => {
(0, _globals.beforeEach)(() => {
_fx.default.off = true;
const $container = (0, _renderer.default)("<div>").addClass("container").appendTo(document.body);
(0, _renderer.default)("<div>").addClass("root").appendTo($container);
(0, _renderer.default)("<div>").addClass("allday-container").appendTo($container)
});
(0, _globals.afterEach)(() => {
(0, _renderer.default)(".container").remove();
_fx.default.off = false;
_globals.jest.useRealTimers()
});
(0, _globals.describe)("Classes", () => {
(0, _globals.it)("should have correct container class", () => {
const instance = createAppointments(getProperties());
(0, _globals.expect)(instance.$element().hasClass(_const.APPOINTMENTS_CONTAINER_CLASS)).toBe(true)
})
});
(0, _globals.describe)("Rendering", () => {
(0, _globals.it)("should render view model with grid appointments", () => {
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(defaultAppointmentData, {
sortedIndex: 0
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(1)
});
(0, _globals.it)("should render view model with agenda appointments", () => {
const instance = createAppointments(Object.assign({}, getProperties(), {
currentView: "agenda"
}));
instance.option("viewModel", [(0, _appointment_view_model.mockAgendaViewModel)(defaultAppointmentData, {
sortedIndex: 0
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(1)
});
(0, _globals.it)("should render view model with appointment collectors", () => {
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockAppointmentCollectorViewModel)(defaultAppointmentData, {
sortedIndex: 0
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_COLLECTOR_CLASSES.CONTAINER}`).length).toBe(1)
});
(0, _globals.it)("should rerender all appointments when view model is completely changed", () => {
const data1 = Object.assign({}, defaultAppointmentData);
const data2 = Object.assign({}, defaultAppointmentData, {
text: "Appointment 2"
});
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(data1, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(data2, {
sortedIndex: 1
})]);
const elementsBefore = instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).toArray();
(0, _globals.expect)(elementsBefore.length).toBe(2);
const data3 = Object.assign({}, defaultAppointmentData, {
text: "Appointment 3"
});
const data4 = Object.assign({}, defaultAppointmentData, {
text: "Appointment 4"
});
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(data3, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(data4, {
sortedIndex: 1
})]);
const elementsAfter = instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).toArray();
(0, _globals.expect)(elementsAfter.length).toBe(2);
(0, _globals.expect)(elementsAfter[0]).not.toBe(elementsBefore[0]);
(0, _globals.expect)(elementsAfter[1]).not.toBe(elementsBefore[1])
});
(0, _globals.it)("should render allDay appointment to the allDay container", () => {
var _instance$option$$all;
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData, {
allDay: true
}), {
sortedIndex: 0
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(0);
(0, _globals.expect)(null === (_instance$option$$all = instance.option().$allDayContainer) || void 0 === _instance$option$$all ? void 0 : _instance$option$$all.find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(1)
});
(0, _globals.it)("should not render allDay agenda appointment to the allDay container", () => {
var _instance$option$$all2;
const instance = createAppointments(Object.assign({}, getProperties(), {
currentView: "agenda"
}));
instance.option("viewModel", [(0, _appointment_view_model.mockAgendaViewModel)(Object.assign({}, defaultAppointmentData, {
allDay: true
}), {
sortedIndex: 0
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(1);
(0, _globals.expect)(null === (_instance$option$$all2 = instance.option().$allDayContainer) || void 0 === _instance$option$$all2 ? void 0 : _instance$option$$all2.find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(0)
});
(0, _globals.it)("should clean all day container when switching from grid view to agenda view", () => {
var _instance$option$$all3, _instance$option$$all4;
const instance = createAppointments(Object.assign({}, getProperties(), {
currentView: "week"
}));
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData, {
allDay: true
}), {
sortedIndex: 0
})]);
(0, _globals.expect)(null === (_instance$option$$all3 = instance.option().$allDayContainer) || void 0 === _instance$option$$all3 ? void 0 : _instance$option$$all3.find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(1);
instance.option("currentView", "agenda");
instance.option("viewModel", [(0, _appointment_view_model.mockAgendaViewModel)(Object.assign({}, defaultAppointmentData, {
allDay: true
}), {
sortedIndex: 0
})]);
(0, _globals.expect)(null === (_instance$option$$all4 = instance.option().$allDayContainer) || void 0 === _instance$option$$all4 ? void 0 : _instance$option$$all4.find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(0);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(1)
});
_globals.it.each(["appointmentTemplate", "appointmentCollectorTemplate"])("should rerender appointments if %s is changed", optionName => {
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(defaultAppointmentData, {
sortedIndex: 0
})]);
const elementsBefore = instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).toArray();
(0, _globals.expect)(elementsBefore.length).toBe(1);
instance.option(optionName, () => {});
const elementsAfter = instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).toArray();
(0, _globals.expect)(elementsAfter.length).toBe(1);
(0, _globals.expect)(elementsAfter[0]).not.toBe(elementsBefore[0])
})
});
(0, _globals.describe)("Partial rendering", () => {
(0, _globals.it)("should render only changed view items on add", () => {
var _instance$getViewItem, _instance$getViewItem2;
const dataA = Object.assign({}, defaultAppointmentData);
const dataB = Object.assign({}, defaultAppointmentData, {
text: "Appointment B"
});
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1
})]);
const viewItemA = instance.getViewItemBySortedIndex(0);
const viewItemB = instance.getViewItemBySortedIndex(1);
const elementA = null === viewItemA || void 0 === viewItemA ? void 0 : viewItemA.$element().get(0);
const elementB = null === viewItemB || void 0 === viewItemB ? void 0 : viewItemB.$element().get(0);
const dataNEW = Object.assign({}, defaultAppointmentData, {
text: "Appointment NEW"
});
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataNEW, {
sortedIndex: 1
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 2
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(3);
(0, _globals.expect)(instance.getViewItemBySortedIndex(0)).toBe(viewItemA);
(0, _globals.expect)(instance.getViewItemBySortedIndex(2)).toBe(viewItemB);
(0, _globals.expect)(null === (_instance$getViewItem = instance.getViewItemBySortedIndex(0)) || void 0 === _instance$getViewItem ? void 0 : _instance$getViewItem.$element().get(0)).toBe(elementA);
(0, _globals.expect)(null === (_instance$getViewItem2 = instance.getViewItemBySortedIndex(2)) || void 0 === _instance$getViewItem2 ? void 0 : _instance$getViewItem2.$element().get(0)).toBe(elementB)
});
(0, _globals.it)("should render only changed view items on remove", () => {
var _instance$getViewItem3, _instance$getViewItem4;
const dataA = Object.assign({}, defaultAppointmentData);
const dataB = Object.assign({}, defaultAppointmentData, {
text: "Appointment B"
});
const dataC = Object.assign({}, defaultAppointmentData, {
text: "Appointment C"
});
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 2
})]);
const viewItemA = instance.getViewItemBySortedIndex(0);
const viewItemC = instance.getViewItemBySortedIndex(2);
const elementA = null === viewItemA || void 0 === viewItemA ? void 0 : viewItemA.$element().get(0);
const elementC = null === viewItemC || void 0 === viewItemC ? void 0 : viewItemC.$element().get(0);
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 1
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(2);
(0, _globals.expect)(instance.getViewItemBySortedIndex(0)).toBe(viewItemA);
(0, _globals.expect)(instance.getViewItemBySortedIndex(1)).toBe(viewItemC);
(0, _globals.expect)(null === (_instance$getViewItem3 = instance.getViewItemBySortedIndex(0)) || void 0 === _instance$getViewItem3 ? void 0 : _instance$getViewItem3.$element().get(0)).toBe(elementA);
(0, _globals.expect)(null === (_instance$getViewItem4 = instance.getViewItemBySortedIndex(1)) || void 0 === _instance$getViewItem4 ? void 0 : _instance$getViewItem4.$element().get(0)).toBe(elementC)
});
(0, _globals.it)("should render only changed view items on update", () => {
var _instance$getViewItem5, _instance$getViewItem6, _instance$getViewItem7;
const dataA = Object.assign({}, defaultAppointmentData);
const dataB = Object.assign({}, defaultAppointmentData, {
text: "Appointment B"
});
const dataC = Object.assign({}, defaultAppointmentData, {
text: "Appointment C"
});
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 2
})]);
const viewItemA = instance.getViewItemBySortedIndex(0);
const viewItemB = instance.getViewItemBySortedIndex(1);
const viewItemC = instance.getViewItemBySortedIndex(2);
const elementA = null === viewItemA || void 0 === viewItemA ? void 0 : viewItemA.$element().get(0);
const elementB = null === viewItemB || void 0 === viewItemB ? void 0 : viewItemB.$element().get(0);
const elementC = null === viewItemC || void 0 === viewItemC ? void 0 : viewItemC.$element().get(0);
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1,
groupIndex: 1
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 2
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(3);
(0, _globals.expect)(instance.getViewItemBySortedIndex(0)).toBe(viewItemA);
(0, _globals.expect)(instance.getViewItemBySortedIndex(1)).not.toBe(viewItemB);
(0, _globals.expect)(instance.getViewItemBySortedIndex(2)).toBe(viewItemC);
(0, _globals.expect)(null === (_instance$getViewItem5 = instance.getViewItemBySortedIndex(0)) || void 0 === _instance$getViewItem5 ? void 0 : _instance$getViewItem5.$element().get(0)).toBe(elementA);
(0, _globals.expect)(null === (_instance$getViewItem6 = instance.getViewItemBySortedIndex(1)) || void 0 === _instance$getViewItem6 ? void 0 : _instance$getViewItem6.$element().get(0)).not.toBe(elementB);
(0, _globals.expect)(null === (_instance$getViewItem7 = instance.getViewItemBySortedIndex(2)) || void 0 === _instance$getViewItem7 ? void 0 : _instance$getViewItem7.$element().get(0)).toBe(elementC)
});
(0, _globals.it)("should rerender several view items on several items update", () => {
var _instance$getViewItem8, _instance$getViewItem9, _instance$getViewItem0;
const dataA = Object.assign({}, defaultAppointmentData);
const dataB = Object.assign({}, defaultAppointmentData, {
text: "Appointment 1"
});
const dataC = Object.assign({}, defaultAppointmentData, {
text: "Appointment 2"
});
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 2
})]);
const viewItem0 = instance.getViewItemBySortedIndex(0);
const viewItem1 = instance.getViewItemBySortedIndex(1);
const viewItem2 = instance.getViewItemBySortedIndex(2);
const element0 = null === viewItem0 || void 0 === viewItem0 ? void 0 : viewItem0.$element().get(0);
const element1 = null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().get(0);
const element2 = null === viewItem2 || void 0 === viewItem2 ? void 0 : viewItem2.$element().get(0);
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1,
groupIndex: 1
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 2,
groupIndex: 1
})]);
const appointmentsAfter = instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).toArray();
(0, _globals.expect)(appointmentsAfter.length).toBe(3);
(0, _globals.expect)(instance.getViewItemBySortedIndex(0)).toBe(viewItem0);
(0, _globals.expect)(instance.getViewItemBySortedIndex(1)).not.toBe(viewItem1);
(0, _globals.expect)(instance.getViewItemBySortedIndex(2)).not.toBe(viewItem2);
(0, _globals.expect)(null === (_instance$getViewItem8 = instance.getViewItemBySortedIndex(0)) || void 0 === _instance$getViewItem8 ? void 0 : _instance$getViewItem8.$element().get(0)).toBe(element0);
(0, _globals.expect)(null === (_instance$getViewItem9 = instance.getViewItemBySortedIndex(1)) || void 0 === _instance$getViewItem9 ? void 0 : _instance$getViewItem9.$element().get(0)).not.toBe(element1);
(0, _globals.expect)(null === (_instance$getViewItem0 = instance.getViewItemBySortedIndex(2)) || void 0 === _instance$getViewItem0 ? void 0 : _instance$getViewItem0.$element().get(0)).not.toBe(element2)
});
(0, _globals.it)("should only resize view item if its size changed", () => {
var _instance$getViewItem1, _instance$getViewItem10, _instance$getViewItem11;
const dataA = Object.assign({}, defaultAppointmentData);
const dataB = Object.assign({}, defaultAppointmentData, {
text: "Appointment B"
});
const dataC = Object.assign({}, defaultAppointmentData, {
text: "Appointment C"
});
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1,
top: 10,
left: 10,
height: 50,
width: 100
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 2
})]);
const viewItemA = instance.getViewItemBySortedIndex(0);
const viewItemB = instance.getViewItemBySortedIndex(1);
const viewItemC = instance.getViewItemBySortedIndex(2);
const elementA = null === viewItemA || void 0 === viewItemA ? void 0 : viewItemA.$element().get(0);
const elementB = null === viewItemB || void 0 === viewItemB ? void 0 : viewItemB.$element().get(0);
const elementC = null === viewItemC || void 0 === viewItemC ? void 0 : viewItemC.$element().get(0);
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(dataB, {
sortedIndex: 1,
top: 20,
left: 20,
height: 60,
width: 110
}), (0, _appointment_view_model.mockGridViewModel)(dataC, {
sortedIndex: 2
})]);
(0, _globals.expect)(instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).length).toBe(3);
(0, _globals.expect)(instance.getViewItemBySortedIndex(0)).toBe(viewItemA);
(0, _globals.expect)(instance.getViewItemBySortedIndex(1)).toBe(viewItemB);
(0, _globals.expect)(instance.getViewItemBySortedIndex(2)).toBe(viewItemC);
(0, _globals.expect)(null === (_instance$getViewItem1 = instance.getViewItemBySortedIndex(0)) || void 0 === _instance$getViewItem1 ? void 0 : _instance$getViewItem1.$element().get(0)).toBe(elementA);
(0, _globals.expect)(null === (_instance$getViewItem10 = instance.getViewItemBySortedIndex(1)) || void 0 === _instance$getViewItem10 ? void 0 : _instance$getViewItem10.$element().get(0)).toBe(elementB);
(0, _globals.expect)(null === (_instance$getViewItem11 = instance.getViewItemBySortedIndex(2)) || void 0 === _instance$getViewItem11 ? void 0 : _instance$getViewItem11.$element().get(0)).toBe(elementC);
(0, _globals.expect)((0, _renderer.default)(elementB).css("top")).toBe("20px");
(0, _globals.expect)((0, _renderer.default)(elementB).css("left")).toBe("20px");
(0, _globals.expect)((0, _renderer.default)(elementB).css("height")).toBe("60px");
(0, _globals.expect)((0, _renderer.default)(elementB).css("width")).toBe("110px")
})
});
(0, _globals.describe)("Resources", () => {
(0, _globals.it)("should apply resource color", async () => {
const instance = createAppointments(Object.assign({}, getProperties({
resources: [{
fieldExpr: "roomId",
dataSource: [{
text: "Room 1",
id: 1,
color: "red"
}]
}]
})));
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData, {
roomId: 1
}), {
sortedIndex: 0
})]);
await new Promise(process.nextTick);
const $appointment = instance.$element().find(`.${_const.APPOINTMENT_CLASSES.CONTAINER}`).first();
(0, _globals.expect)($appointment.css("backgroundColor")).toBe("red")
})
});
(0, _globals.describe)("Options", () => {
(0, _globals.describe)("tabIndex", () => {
(0, _globals.it)("should pass tabIndex change to view items", () => {
var _instance$getViewItem12, _instance$getViewItem13, _instance$getViewItem14;
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
}), (0, _appointment_view_model.mockAppointmentCollectorViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
})]);
instance.option("tabIndex", 2);
(0, _globals.expect)(null === (_instance$getViewItem12 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem12 ? void 0 : _instance$getViewItem12.$element().attr("tabindex")).toBe("2");
(0, _globals.expect)(null === (_instance$getViewItem13 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem13 ? void 0 : _instance$getViewItem13.$element().attr("tabindex")).toBe("-1");
(0, _globals.expect)(null === (_instance$getViewItem14 = instance.getViewItemByIndex(2)) || void 0 === _instance$getViewItem14 ? void 0 : _instance$getViewItem14.$element().attr("tabindex")).toBe("-1")
});
(0, _globals.it)("should keep only focused appointment tabbable on tabIndex change", () => {
var _instance$getViewItem15, _instance$getViewItem16, _instance$getViewItem17, _instance$getViewItem18;
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
}), (0, _appointment_view_model.mockAppointmentCollectorViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
})]);
(null === (_instance$getViewItem15 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem15 ? void 0 : _instance$getViewItem15.$element().get(0)).click();
instance.option("tabIndex", 2);
(0, _globals.expect)(null === (_instance$getViewItem16 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem16 ? void 0 : _instance$getViewItem16.$element().attr("tabindex")).toBe("-1");
(0, _globals.expect)(null === (_instance$getViewItem17 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem17 ? void 0 : _instance$getViewItem17.$element().attr("tabindex")).toBe("2");
(0, _globals.expect)(null === (_instance$getViewItem18 = instance.getViewItemByIndex(2)) || void 0 === _instance$getViewItem18 ? void 0 : _instance$getViewItem18.$element().attr("tabindex")).toBe("-1")
});
(0, _globals.it)("should not rerender view items on tabIndex change", () => {
var _instance$getViewItem19, _instance$getViewItem20, _instance$getViewItem21, _instance$getViewItem22;
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockAppointmentCollectorViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
})]);
const element0 = null === (_instance$getViewItem19 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem19 ? void 0 : _instance$getViewItem19.$element().get(0);
const element1 = null === (_instance$getViewItem20 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem20 ? void 0 : _instance$getViewItem20.$element().get(0);
instance.option("tabIndex", 2);
(0, _globals.expect)(null === (_instance$getViewItem21 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem21 ? void 0 : _instance$getViewItem21.$element().get(0)).toBe(element0);
(0, _globals.expect)(null === (_instance$getViewItem22 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem22 ? void 0 : _instance$getViewItem22.$element().get(0)).toBe(element1)
});
(0, _globals.it)("should have first appointment have correct index after tabIndex changed from -1 to 0", () => {
var _instance$getViewItem23, _instance$getViewItem24;
const instance = createAppointments(Object.assign({}, getProperties(), {
tabIndex: -1
}));
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
})]);
instance.option("tabIndex", 0);
(0, _globals.expect)(null === (_instance$getViewItem23 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem23 ? void 0 : _instance$getViewItem23.$element().attr("tabindex")).toBe("0");
(0, _globals.expect)(null === (_instance$getViewItem24 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem24 ? void 0 : _instance$getViewItem24.$element().attr("tabindex")).toBe("-1")
})
})
});
(0, _globals.describe)("Focus and keyboard navigation", () => {
(0, _globals.describe)("Basic navigation", () => {
(0, _globals.it)("should set tabindex=0 on first appointment and tabindex=-1 on others after render", () => {
var _instance$getViewItem25, _instance$getViewItem26, _instance$getViewItem27;
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
}), (0, _appointment_view_model.mockAppointmentCollectorViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
})]);
(0, _globals.expect)(null === (_instance$getViewItem25 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem25 ? void 0 : _instance$getViewItem25.$element().attr("tabindex")).toBe("0");
(0, _globals.expect)(null === (_instance$getViewItem26 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem26 ? void 0 : _instance$getViewItem26.$element().attr("tabindex")).toBe("-1");
(0, _globals.expect)(null === (_instance$getViewItem27 = instance.getViewItemByIndex(2)) || void 0 === _instance$getViewItem27 ? void 0 : _instance$getViewItem27.$element().attr("tabindex")).toBe("-1")
});
(0, _globals.it)("should restore tabindex=0 on first appointment and tabindex=-1 on others after rerender", () => {
var _instance$getViewItem28, _instance$getViewItem29, _instance$getViewItem30;
const instance = createAppointments(getProperties());
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
}), (0, _appointment_view_model.mockAppointmentCollectorViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
})]);
instance.option("appointmentTemplate", () => {});
(0, _globals.expect)(null === (_instance$getViewItem28 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem28 ? void 0 : _instance$getViewItem28.$element().attr("tabindex")).toBe("0");
(0, _globals.expect)(null === (_instance$getViewItem29 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem29 ? void 0 : _instance$getViewItem29.$element().attr("tabindex")).toBe("-1");
(0, _globals.expect)(null === (_instance$getViewItem30 = instance.getViewItemByIndex(2)) || void 0 === _instance$getViewItem30 ? void 0 : _instance$getViewItem30.$element().attr("tabindex")).toBe("-1")
})
});
_globals.describe.each(["appointment", "appointmentCollector"])("Basic navigation for %s", type => {
const createItem = (data, overrides) => "appointmentCollector" === type ? (0, _appointment_view_model.mockAppointmentCollectorViewModel)(data, overrides) : (0, _appointment_view_model.mockGridViewModel)(data, overrides);
(0, _globals.it)("should move focus to next view item on Tab", () => {
const viewModel = [createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
}), createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
})];
const instance = createAppointments(Object.assign({}, getProperties(), {
getSortedAppointments: () => viewModel
}));
instance.option("viewModel", viewModel);
const viewItem0 = instance.getViewItemBySortedIndex(0);
const viewItem1 = instance.getViewItemBySortedIndex(1);
(null === viewItem0 || void 0 === viewItem0 ? void 0 : viewItem0.$element().get(0)).click();
null === viewItem0 || void 0 === viewItem0 || viewItem0.$element().get(0).dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
bubbles: true
}));
(0, _globals.expect)(null === viewItem0 || void 0 === viewItem0 ? void 0 : viewItem0.$element().attr("tabindex")).toBe("-1");
(0, _globals.expect)(null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().attr("tabindex")).toBe("0");
(0, _globals.expect)(document.activeElement).toBe(null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().get(0))
});
(0, _globals.it)("should move focus to previous view item on Shift+Tab", () => {
const viewModel = [createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
}), createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
})];
const instance = createAppointments(Object.assign({}, getProperties(), {
getSortedAppointments: () => viewModel
}));
instance.option("viewModel", viewModel);
const viewItem0 = instance.getViewItemBySortedIndex(0);
const viewItem1 = instance.getViewItemBySortedIndex(1);
(null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().get(0)).click();
null === viewItem1 || void 0 === viewItem1 || viewItem1.$element().get(0).dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
shiftKey: true,
bubbles: true
}));
(0, _globals.expect)(null === viewItem0 || void 0 === viewItem0 ? void 0 : viewItem0.$element().attr("tabindex")).toBe("0");
(0, _globals.expect)(null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().attr("tabindex")).toBe("-1");
(0, _globals.expect)(document.activeElement).toBe(null === viewItem0 || void 0 === viewItem0 ? void 0 : viewItem0.$element().get(0))
});
(0, _globals.it)("should focus view item on click", () => {
const instance = createAppointments(getProperties());
instance.option("viewModel", [createItem(defaultAppointmentData, {
sortedIndex: 0
})]);
const viewItem = instance.getViewItemBySortedIndex(0);
const element = null === viewItem || void 0 === viewItem ? void 0 : viewItem.$element().get(0);
element.click();
(0, _globals.expect)(element.getAttribute("tabindex")).toBe("0");
(0, _globals.expect)(element.classList.contains("dx-state-focused")).toBe(true);
(0, _globals.expect)(document.activeElement).toBe(element)
});
(0, _globals.it)("should reset focused state when focus moves outside the container", () => {
var _instance$getViewItem31, _instance$getViewItem32, _instance$getViewItem33;
const externalButton = (0, _renderer.default)("<button>").prependTo((0, _renderer.default)(".container")).get(0);
const instance = createAppointments(getProperties());
instance.option("viewModel", [createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), createItem(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
})]);
(null === (_instance$getViewItem31 = instance.getViewItemBySortedIndex(1)) || void 0 === _instance$getViewItem31 ? void 0 : _instance$getViewItem31.$element().get(0)).click();
externalButton.focus();
(0, _globals.expect)(null === (_instance$getViewItem32 = instance.getViewItemByIndex(0)) || void 0 === _instance$getViewItem32 ? void 0 : _instance$getViewItem32.$element().attr("tabindex")).toBe("0");
(0, _globals.expect)(null === (_instance$getViewItem33 = instance.getViewItemByIndex(1)) || void 0 === _instance$getViewItem33 ? void 0 : _instance$getViewItem33.$element().attr("tabindex")).toBe("-1")
})
});
(0, _globals.describe)("Virtual scrolling navigation", () => {
const makeSortedEntity = function(sortedIndex) {
let startDate = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : new Date(2024, 0, 1, 9, 0);
return {
sortedIndex: sortedIndex,
allDay: false,
itemData: {},
source: {
startDate: startDate.getTime(),
endDate: startDate.getTime() + 36e5
}
}
};
(0, _globals.it)("should call scrollTo on Tab when virtual scrolling is enabled", () => {
const scrollTo = _globals.jest.fn();
const instance = createAppointments(Object.assign({}, getProperties(), {
isVirtualScrolling: () => true,
scrollTo: scrollTo,
getSortedAppointments: () => [makeSortedEntity(0), makeSortedEntity(1), makeSortedEntity(1)]
}));
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
})]);
const viewItem1 = instance.getViewItemBySortedIndex(0);
(null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().get(0)).click();
null === viewItem1 || void 0 === viewItem1 || viewItem1.$element().get(0).dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
bubbles: true
}));
(0, _globals.expect)(scrollTo).toHaveBeenCalled()
});
(0, _globals.it)("should focus next appointment directly if it is already rendered", () => {
const instance = createAppointments(Object.assign({}, getProperties(), {
isVirtualScrolling: () => true,
getSortedAppointments: () => [makeSortedEntity(0), makeSortedEntity(1), makeSortedEntity(2)]
}));
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
}), (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
})]);
const viewItem1 = instance.getViewItemBySortedIndex(1);
const viewItem2 = instance.getViewItemBySortedIndex(2);
(null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().get(0)).click();
null === viewItem1 || void 0 === viewItem1 || viewItem1.$element().get(0).dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
bubbles: true
}));
(0, _globals.expect)(document.activeElement).toBe(null === viewItem2 || void 0 === viewItem2 ? void 0 : viewItem2.$element().get(0))
});
(0, _globals.it)("should restore focus to target appointment after it scrolls into view", () => {
var _instance$getViewItem34;
const item0 = (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
});
const item1 = (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 1
});
const item2 = (0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 2
});
const instance = createAppointments(Object.assign({}, getProperties(), {
isVirtualScrolling: () => true,
getSortedAppointments: () => [makeSortedEntity(0), makeSortedEntity(1), makeSortedEntity(2)]
}));
instance.option("viewModel", [item0, item1]);
const viewItem1 = instance.getViewItemBySortedIndex(1);
(null === viewItem1 || void 0 === viewItem1 ? void 0 : viewItem1.$element().get(0)).click();
null === viewItem1 || void 0 === viewItem1 || viewItem1.$element().get(0).dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
bubbles: true
}));
(0, _globals.expect)(instance.getViewItemBySortedIndex(2)).toBeUndefined();
instance.option("viewModel", [item0, item1, item2]);
const $viewItem2 = null === (_instance$getViewItem34 = instance.getViewItemBySortedIndex(2)) || void 0 === _instance$getViewItem34 ? void 0 : _instance$getViewItem34.$element();
(0, _globals.expect)(document.activeElement).toBe(null === $viewItem2 || void 0 === $viewItem2 ? void 0 : $viewItem2.get(0));
(0, _globals.expect)(null === $viewItem2 || void 0 === $viewItem2 ? void 0 : $viewItem2.attr("tabindex")).toBe("0")
});
(0, _globals.it)("should pass appointment start date to scrollTo when it is after the start view date", () => {
const scrollTo = _globals.jest.fn();
const startViewDate = new Date(2024, 0, 1);
const appointmentStartDate = new Date(2024, 0, 5, 9, 0);
const instance = createAppointments(Object.assign({}, getProperties(), {
isVirtualScrolling: () => true,
scrollTo: scrollTo,
getStartViewDate: () => startViewDate,
getSortedAppointments: () => [makeSortedEntity(0), makeSortedEntity(1, appointmentStartDate)]
}));
instance.option("viewModel", [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
})]);
const viewItem0 = instance.getViewItemBySortedIndex(0);
(null === viewItem0 || void 0 === viewItem0 ? void 0 : viewItem0.$element().get(0)).click();
null === viewItem0 || void 0 === viewItem0 || viewItem0.$element().get(0).dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
bubbles: true
}));
(0, _globals.expect)(scrollTo).toHaveBeenCalledWith(appointmentStartDate, _globals.expect.anything())
});
(0, _globals.it)("should clamp scrollTo date to start view date when appointment starts before it", () => {
const scrollTo = _globals.jest.fn();
const startViewDate = new Date(2024, 0, 1);
const appointmentStartDate = new Date(2023, 11, 31, 9, 0);
const viewModel = [(0, _appointment_view_model.mockGridViewModel)(Object.assign({}, defaultAppointmentData), {
sortedIndex: 0
})];
const sortedEntities = [makeSortedEntity(0), makeSortedEntity(1, appointmentStartDate)];
const instance = createAppointments(Object.assign({}, getProperties(), {
isVirtualScrolling: () => true,
scrollTo: scrollTo,
getStartViewDate: () => startViewDate,
getSortedAppointments: () => sortedEntities
}));
instance.option("viewModel", viewModel);
const viewItem0 = instance.getViewItemBySortedIndex(0);
(null === viewItem0 || void 0 === viewItem0 ? void 0 : viewItem0.$element().get(0)).click();
null === viewItem0 || void 0 === viewItem0 || viewItem0.$element().get(0).dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
bubbles: true
}));
(0, _globals.expect)(scrollTo).toHaveBeenCalledWith(startViewDate, _globals.expect.anything())
})
});
(0, _globals.describe)("Navigation after partial render", () => {
const pressTab = () => {
const activeElement = document.activeElement;
activeElement.dispatchEvent(new KeyboardEvent("keydown", {
key: "Tab",
bubbles: true
}))
};
(0, _globals.it)("should navigate to the last appointment correctly after an appointment is added", () => {
var _instance$getViewItem35;
const dataA = Object.assign({}, defaultAppointmentData);
const dataB = Object.assign({}, defaultAppointmentData, {
text: "Appointment B"
});
const dataC = Object.assign({}, defaultAppointmentData, {
text: "Appointment C"
});
let viewModel = [(0, _appointment_view_model.mockGridViewModel)(dataA, {
sortedIndex: 0
}), (0, _appointment_view_model.moc