Планирование встреч и назначение встреч иногда может быть огромной проблемой. Довольно легко назначать встречи один на один с помощью инструментов, синхронизированных с нашим личным и рабочим календарями. Но как насчет планирования встреч с несколькими участниками или большими группами? Что еще хуже, что, если это международная команда, разбросанная по разным часовым поясам.

В этом посте я представлю и объясню одно из решений, которое мы разработали в Spurwing для облегчения групповых календарей доступности и расписания команд.

Требования

Это решение построено с использованием JavaScript и NodeJS v12+. Мы использовали следующие библиотеки: jQuery, Luxon и Express.

Демо

Ссылка на демо-версию: https://cloud.spurwing.io/Availability/S01/

Домашняя страница:

Календарь используется для выбора нескольких дат-кандидатов (без ограничений). После отправки вы увидите две ссылки: одну для страницы результатов и одну для отправки другим пользователям.

Страница представления пользователя:

На странице отправки каждый пользователь может щелкнуть ячейки, чтобы указать свою доступность на определенную дату и время. Для отправки ответа необходимо указать имя и адрес электронной почты. Обновление уже отправленного ответа возможно путем повторной отправки с использованием того же адреса электронной почты.

Страница результатов:

Страница результатов показывает строгое совпадение всех представлений каждого пользователя. Учитывая эти перекрывающиеся области, организатор/организатор может приступить к настройке встречи на дату и время, которые подходят всем календарям.

Обратите внимание, что все данные относятся к часовому поясу. Это означает, что мы можем легко планировать и назначать встречи с участниками из разных часовых поясов на лету. Часовой пояс каждого пользователя учитывается и преобразуется в универсальную временную метку UTC. На странице с окончательными результатами отображаются все отправленные материалы в соответствии с часовым поясом зрителя.

Скоро: возможность запланировать встречу с помощью Spurwing API и отправить всем участникам приглашения по электронной почте.

Выполнение

Полная реализация этого решения для группового планирования доступна в нашем подрепозитории Github. Корневой каталог нашего репозитория будет включать в себя еще несколько связанных решений.

Серверная часть

Сценарий server.js представляет сервер NodeJS API/REST, работающий по умолчанию на порту 8000. Он имеет несколько конечных точек для получения, отправки и обновления данных. Файловая база данных JSON используется в демонстрационных целях. Рекомендуется заменить ее готовой к работе базой данных, такой как MongoDB.

Внешний интерфейс

Каталог public содержит файлы HTML, JavaScript и CSS. Весь пользовательский код JavaScript находится внутри файлов HTML для демонстрационных целей. scheduler Файлы JS и CSS являются внешними ресурсами с открытым исходным кодом для планировщика пользовательского интерфейса.

Наш пользовательский код JavaScript довольно короткий и простой. Единственная неизбежная сложность связана с библиотекой планирования пользовательского интерфейса. Он использует строки и столбцы в качестве индикаторов для ячеек. Между ячейками и фактическими данными даты/времени нет внутренней связи. Эта информация является неявной и вычисляется на основе строк и столбцов с учетом точности (то есть точности) 24-часового периода.

Код

Может быть интересно объяснить, как достигается это преобразование между row:col и datetime.

Внутри meeting.html у нас есть некоторый пользовательский код JavaScript, который отвечает за: захват выбора пользователя, перевод данных выбора в формат даты и времени ISO, затем в эквивалент UTC и, наконец, отправку данных на сервер:

let selection = [];
const accuracy = 2; // 30 minute intervals
let dates = [...]; // date strings associated with the meeting
$('#test1').scheduler({
  accuracy: accuracy,
  onSelect: (x) => convert(x, dates),
            // x contains all selected cells in the format:
            // { row1: [...cols], row2: [...cols] }
            // the row keys are just numbers starting from 1.
            // the value is an array of columns starting from 0.
});
// convert row-column format into ISO/UTC date format
function convert(sel, dates) {
  selection = []; // empty previous selection (if any)
  for (const row_ in sel) {
    for (const col of sel[row_]) {
      let row = row_ - 1; // make row zero-based
      let hour = Math.floor(col/accuracy) // compute hour
      let minute = ((col / accuracy) - hour)*60; // compute minutes
      let dt = luxon.DateTime.fromISO(dates[row]); // get date and parse it
      dt.set({hour, minute}); // set hour and minutes
      selection.push(dt.toUTC().toString()) // relative to UTC datetime
    }
  }
}
// on click submit -> send { selection } as data

Аналогичная обратная операция выполняется в results.html, где даты и время в формате UTC получаются с сервера, строго перекрываются, преобразуются в обнаруженный пользователем часовой пояс и, наконец, отображаются в пользовательском интерфейсе только для чтения.

Вывод

Вы можете разместить это программное обеспечение на своем сервере или у облачного провайдера и использовать его. Но вы также можете захотеть добавить дополнительный уровень безопасности (например, пароль), чтобы помочь пользователям не использовать брутфорс для просмотра/сбора имен и адресов электронной почты всех пользователей.

В конце концов, это решение экономит нам массу времени при планировании встреч, особенно в международных командах, работающих в разных часовых поясах. Для получения дополнительных инструментов и ресурсов посетите нашу страницу Github.