Socket
Socket
Sign inDemoInstall

cronofy-elements

Package Overview
Dependencies
12
Maintainers
1
Versions
171
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.4.1 to 1.7.0

build/CronofyElements.v1.5.0.js

33

build/server.js

@@ -379,4 +379,37 @@ "use strict";

app.get("/calendar-sync", function () {
var _ref8 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(req, res) {
var cal_sync_token;
return regeneratorRuntime.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
_context8.next = 2;
return getData(baseUrl, calendarSyncTokenOptions);
case 2:
cal_sync_token = _context8.sent;
return _context8.abrupt("return", res.render("calendar-sync", {
cal_sync_token: cal_sync_token.element_token.token,
api_domain: apiDomain,
app_domain: appDomain,
sub: env.LIVE_SUB,
client_id: env.CLIENT_ID
}));
case 4:
case "end":
return _context8.stop();
}
}
}, _callee8, undefined);
}));
return function (_x14, _x15) {
return _ref8.apply(this, arguments);
};
}());
app.listen(8080);
console.log("serving on port 8080 - http://localhost:8080/");

@@ -210,4 +210,15 @@ require("@babel/polyfill");

app.get("/calendar-sync", async (req, res) => {
const cal_sync_token = await getData(baseUrl, calendarSyncTokenOptions);
return res.render("calendar-sync", {
cal_sync_token: cal_sync_token.element_token.token,
api_domain: apiDomain,
app_domain: appDomain,
sub: env.LIVE_SUB,
client_id: env.CLIENT_ID
});
});
app.listen(8080);
console.log("serving on port 8080 - http://localhost:8080/");

2

package.json
{
"name": "cronofy-elements",
"version": "1.4.1",
"version": "1.7.0",
"description": "Fast track scheduling with Cronofy's embeddable UI Elements",

@@ -5,0 +5,0 @@ "main": "build/npm/CronofyElements.js",

@@ -11,2 +11,3 @@ import React, { useState, useContext } from "react";

import Calendar from "./Calendar";
import UnknownCalendar from "./UnknownCalendar";
import CalendarSelector from "./CalendarSelector";

@@ -74,2 +75,10 @@ import LoadingSpinner from "../generic/LoadingSpinner";

);
} else {
return (
<UnknownCalendar
key={`${calendarId}-calendar`}
id={calendarId}
remove={removeCalendars}
/>
);
}

@@ -76,0 +85,0 @@ })

@@ -42,5 +42,3 @@ import React, { useContext } from "react";

`}
className={`${
theme.prefix
}__calendars__modal-item-title`}
className={`${theme.prefix}__calendars__modal-item-title`}
>

@@ -57,5 +55,3 @@ {cal.name}

`}
className={`${
theme.prefix
}__calendars__modal-item-subtitle`}
className={`${theme.prefix}__calendars__modal-item-subtitle`}
>{`${cal.profile_name} [${cal.provider_name}]`}</span>

@@ -62,0 +58,0 @@ </div>

@@ -73,2 +73,3 @@ import React, { useState, useEffect } from "react";

),
slotSelection: options.config.slot_selection,
tzid: options.tzid,

@@ -109,3 +110,5 @@ weeksLoaded: []

moment.locale(options.locale);
}, []);
useEffect(() => {
triggerSlotsForWeek();

@@ -126,60 +129,68 @@

});
if (croppedQuery.available_periods.length > 0) {
connections
.getAvailability(
options.token,
options.domains.apiDomain,
croppedQuery,
`AvailabilityViewer`,
options.demo
)
.then(res => {
if (
typeof res.available_slots === "undefined" &&
typeof res.available_periods === "undefined"
) {
console.error(
"AvailabilityViewer error",
res,
"\nCheck your `token`, `target`, and `query` params are correct. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/"
);
setStatus({
...status,
error: true,
loading: false
});
return;
}
connections
.getAvailability(
options.token,
options.domains.apiDomain,
croppedQuery,
`AvailabilityViewer`,
options.demo
)
.then(res => {
if (
typeof res.available_slots === "undefined" &&
typeof res.available_periods === "undefined"
) {
console.error(
"AvailabilityViewer error",
res,
"\nCheck your `token`, `target`, and `query` params are correct. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/"
);
setStatus({
...status,
error: true,
loading: false
});
return;
}
const response =
query.response_format === "overlapping_slots"
? res.available_slots
: res.available_periods;
const response =
query.response_format === "overlapping_slots"
? res.available_slots
: res.available_periods;
const slotsWithKeys = addKeysToSlots(response);
const slotsWithKeys = addKeysToSlots(response);
setRawData({ ...rawData, ...slotsWithKeys });
setRawData({ ...rawData, ...slotsWithKeys });
const weeksLoaded = uniqueItems([
...status.weeksLoaded,
weeks.current
]);
const weeksLoaded = uniqueItems([
...status.weeksLoaded,
weeks.current
]);
setStatus({
...status,
error: false,
loading: false,
preloading: false,
weeksLoaded
setStatus({
...status,
error: false,
loading: false,
preloading: false,
weeksLoaded
});
})
.catch(error => {
// TODO: expose these errors in console when "dev mode" is active
console.log("AvailabilityViewer error", error);
return error;
});
})
.catch(error => {
// TODO: expose these errors in console when "dev mode" is active
console.log("AvailabilityViewer error", error);
return error;
} else {
// If we get here, the available_periods are not within the visible window
console.warn(
"CronofyElements.AvailabilityViewer: the provided available_periods are not within the visible window"
);
setStatus({
...status,
error: false,
loading: false,
preloading: false
});
window.addEventListener(
"resize",
setStatus({ ...status, selected: [] })
);
}
} else {

@@ -213,3 +224,4 @@ setStatus({ ...status, error: true, loading: false });

weeks,
tzid: status.tzid
tzid: status.tzid,
unrestricted: status.slotSelection === "unrestricted"
});

@@ -216,0 +228,0 @@ setSlotData(slots.slots);

@@ -21,7 +21,5 @@ import React, { useContext } from "react";

`}
className={`${theme.prefix}__column-body ${
theme.prefix
}__column-body--empty`}
className={`${theme.prefix}__column-body ${theme.prefix}__column-body--empty`}
>
<span className={`${theme.prefix}__column-message`}>
<span className={`${theme.prefix}__column-message visuallyhidden`}>
{status.loading

@@ -28,0 +26,0 @@ ? null

import React, { useContext } from "react";
import { css } from "react-emotion";
import { ThemeContext } from "./AvailabilityViewer";
import { StatusContext, ThemeContext } from "./AvailabilityViewer";
const HoverSlot = ({ available }) => {
const [status, setStatus] = useContext(StatusContext);
const [theme, setTheme] = useContext(ThemeContext);
const classModifier =
!available && status.slotSelection === "unrestricted"
? `${theme.prefix}__hover-slot--unavailable`
: "";
return (
<div
className={`${theme.prefix}__hover-slot`}
className={`${theme.prefix}__hover-slot ${classModifier}`}
css={css`

@@ -21,3 +27,4 @@ width: 100%;

align-items: center;
background: ${available
background: ${available ||
status.slotSelection === "unrestricted"
? theme.colors.availableHover

@@ -24,0 +31,0 @@ : theme.colors.unavailableHover};

@@ -12,3 +12,3 @@ import React, { useContext } from "react";

<div
className={`${theme.prefix}__hover-slot`}
className={`${theme.prefix}__tooltip-positioner`}
css={css`

@@ -15,0 +15,0 @@ width: 100%;

@@ -43,3 +43,3 @@ import React, { useState, useContext, useEffect } from "react";

const hoverTopPosition = hoverButton.current.offsetTop;
if (slot.visiblyAvailable && slot.target) {
if (slot.target) {
// If the slot is "overlapped" by an available slot

@@ -58,2 +58,3 @@ // we want to select the overlapping slot instead,

slot: {
available: targetSlot.available,
start: targetSlot.start,

@@ -69,2 +70,3 @@ end: targetSlot.end,

slot: {
available: slot.available,
start: slot.start,

@@ -128,3 +130,7 @@ end: slot.end,

if (slot.available || (slot.visiblyAvailable && slot.target)) {
if (
slot.available ||
(slot.visiblyAvailable && slot.target) ||
status.slotSelection === "unrestricted"
) {
const slotForSelection = {

@@ -131,0 +137,0 @@ ...slotData,

@@ -15,3 +15,3 @@ import React, { useContext } from "react";

${slot.available || slot.visiblyAvailable
${slot.visiblyAvailable
? `background: ${theme.colors.available};`

@@ -18,0 +18,0 @@ : ""}

@@ -103,5 +103,6 @@ import React, { useContext, useState, useEffect } from "react";

const tooltipText = hover.available
? hover.times
: i18n(status.context, "unavailable", status.locale);
const tooltipText =
hover.available || status.slotSelection === "unrestricted"
? hover.times
: i18n(status.context, "unavailable", status.locale);

@@ -134,5 +135,6 @@ const calculateColumnWidth = () => {

const hoverHeight = hover.available
? theme.slotHeightCalc.height * theme.slotHeightCalc.multiple
: theme.slotHeightCalc.height;
const hoverHeight =
hover.available || status.slotSelection === "unrestricted"
? theme.slotHeightCalc.height * theme.slotHeightCalc.multiple
: theme.slotHeightCalc.height;

@@ -172,3 +174,3 @@ return (

`}
className={`${theme.prefix}__hover-positioner`}
className={`${theme.prefix}__hover-positioner ${theme.prefix}__hover-positioner--main`}
>

@@ -209,3 +211,3 @@ <HoverSlot

`}
className={`${theme.prefix}__hover-positioner`}
className={`${theme.prefix}__hover-positioner ${theme.prefix}__hover-positioner--tooltip`}
>

@@ -212,0 +214,0 @@ {!hover.hideTooltip ? (

@@ -29,11 +29,12 @@ import React, { useState, useEffect } from "react";

const [status, setStatus] = useState({
adding: false,
demo: options.demo || false,
context: "calendar_sync", // for i18n
editing: false,
error: false,
loading: true,
error: false,
editing: false,
adding: false,
reload: true, // trigger "reload" on first load
locale: options.locale,
pendingNotification: null,
context: "calendar_sync" // for i18n
reload: true, // trigger "reload" on first load
singleProfile: options.single_profile
});

@@ -43,3 +44,8 @@ const [authUrl, setAuthUrl] = useState(options.authorization_url || false);

const [providers, setProviders] = useState(
setupProviderData(auth, options.domains.appDomain, authUrl)
setupProviderData(
auth,
options.domains.appDomain,
authUrl,
status.singleProfile
)
);

@@ -54,3 +60,3 @@ const [profiles, setProfiles] = useState([]);

const sendCallback = (res) => {
const sendCallback = res => {
if (status.pendingNotification !== null) {

@@ -69,2 +75,6 @@ if (typeof options.callback === "function") {

useEffect(() => {
moment.locale(options.locale);
}, []);
useEffect(() => {
if (status.reload === false) {

@@ -74,4 +84,2 @@ return;

moment.locale(options.locale);
if (options.token) {

@@ -78,0 +86,0 @@ connections

@@ -25,3 +25,7 @@ import React, { useContext } from "react";

>
{!status.editing ? <AddToggle /> : <span />}
{!status.editing && !status.singleProfile ? (
<AddToggle />
) : (
<span />
)}
{!status.adding ? <EditToggle /> : null}

@@ -28,0 +32,0 @@ </div>

@@ -40,8 +40,10 @@ import * as mocks from "./mocks";

const calendars = response["cronofy.data"].profiles.map(profile => {
return profile.profile_calendars.map(cal => ({
name: cal.calendar_name,
id: cal.calendar_id,
profile_name: profile.profile_name,
provider_name: profile.provider_name
}));
return profile.profile_calendars
.filter(cal => !cal.calendar_deleted)
.map(cal => ({
name: cal.calendar_name,
id: cal.calendar_id,
profile_name: profile.profile_name,
provider_name: profile.provider_name
}));
});

@@ -48,0 +50,0 @@ return calendars.reduce((acc, curr) => [...acc, ...curr], []);

@@ -78,280 +78,1 @@ export const parseConnectionDomains = (

};
export const parseAgendaOptions = (options = {}) => {
const demoMode = typeof options.demo === "undefined" ? false : options.demo;
if (demoMode) {
console.warn(
"CronofyElements.Agenda: you are running in demo mode. No API requests will be made"
);
}
const token = parseToken(options, "Agenda", "agenda-view");
if (!token && !demoMode) {
console.error(
"CronofyElements.Agenda: you need to include an `element_token`. If you're just testing (and don't want to use real API data) you can set the `demo` option to `true` to bypass the API connection and view dummy content."
);
return false;
}
const target = parseTarget(options, "Agenda", "agenda");
const domains = parseConnectionDomains(
options.data_center,
options.api_domain,
options.app_domain
);
delete options.target_id;
delete options.element_token;
return { ...options, target, token, domains };
};
export const parseSlotPickerOptions = (options = {}) => {
const demoMode = typeof options.demo === "undefined" ? false : options.demo;
if (demoMode) {
console.warn(
"CronofyElements.SlotPicker: you are running in demo mode. No API requests will be made"
);
}
const token = parseToken(options, "SlotPicker", "slot-picker");
if (!token && !demoMode) {
console.error(
"CronofyElements.SlotPicker: you need to include an `element_token`. If you're just testing (and don't want to use real API data) you can set the `demo` option to `true` to bypass the API connection and view dummy content."
);
return false;
}
const target = parseTarget(options, "SlotPicker", "slot-picker");
const query = parseQuery(options, "SlotPicker", "slot-picker");
const config = typeof options.config === "undefined" ? {} : options.config;
const mode = typeof config.mode === "undefined" ? "confirm" : config.mode;
const domains = parseConnectionDomains(
options.data_center,
options.api_domain,
options.app_domain
);
delete options.availability_query;
delete options.element_token;
delete options.target_id;
return {
...options,
target,
token,
domains,
query,
config: { ...config, mode }
};
};
export const parseAvailabilityViewerOptions = (options = {}) => {
options.error = false;
const demoMode = typeof options.demo === "undefined" ? false : options.demo;
if (demoMode) {
console.warn(
"CronofyElements.AvailabilityViewer: you are running in demo mode. No API requests will be made"
);
}
const token = parseToken(
options,
"AvailabilityViewer",
"availability-viewer"
);
if (!token && !demoMode) {
console.error(
"CronofyElements.AvailabilityViewer: you need to include an `element_token`. If you're just testing (and don't want to use real API data) you can set the `demo` option to `true` to bypass the API connection and view dummy content."
);
return false;
}
const target = parseTarget(
options,
"AvailabilityViewer",
"availability-viewer"
);
const query = parseQuery(
options,
"AvailabilityViewer",
"availability-viewer"
);
const error = !query;
let config = {};
if (typeof options.extras !== "undefined") {
console.warn(
"CronofyElements.AvailabilityViewer: the `extras` option has been deprecated in v1.0.0. Please use `config` option instead. https://docs.cronofy.com/developers/ui-elements/availability-viewer/#config"
);
config = options.extras;
}
if (typeof options.config !== "undefined") {
config = { ...config, ...options.config };
}
if (typeof options.tzid === "undefined") {
const sniffedTimezone = Intl.DateTimeFormat().resolvedOptions()
.timeZone;
options.tzid = sniffedTimezone;
options.customtzid = false;
} else {
options.customtzid = true;
}
const mode =
typeof config.mode === "undefined" || config.mode === "default"
? "confirm"
: config.mode;
const boundsControl =
typeof config.bounds_control === "undefined" ||
config.bounds_control === "default"
? false
: true;
config = { ...config, mode, boundsControl };
const domains = parseConnectionDomains(
options.data_center,
options.api_domain,
options.app_domain
);
delete options.availability_query;
delete options.element_token;
delete options.target_id;
delete config.bounds_control;
return { ...options, error, target, token, domains, config, query };
};
export const parseAvailabilityRulesOptions = (options = {}) => {
options.error = false;
const demoMode = typeof options.demo === "undefined" ? false : options.demo;
if (demoMode) {
console.warn(
"CronofyElements.AvailabilityRules: you are running in demo mode. No API requests will be made"
);
}
const token = parseToken(
options,
"AvailabilityRules",
"availability-rules"
);
if (!token && !demoMode) {
console.error(
"CronofyElements.AvailabilityRules: you need to include an `element_token`. If you're just testing (and don't want to use real API data) you can set the `demo` option to `true` to bypass the API connection and view dummy content."
);
return false;
}
const target = parseTarget(
options,
"AvailabilityRules",
"availability-rules"
);
if (typeof options.availability_rule_id === "undefined") {
// options.error = true;
console.warn(
'CronofyElements.AvailabilityRules: you have not defined an availability_rule_id, so "default" will be used instead. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/'
);
}
if (typeof options.tzid === "undefined") {
options.error = true;
console.error(
"CronofyElements.AvailabilityRules: you need to include a `tzid`. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/availability-rules/#tzid"
);
return false;
}
let config = typeof options.config === "undefined" ? {} : options.config;
const domains = parseConnectionDomains(
options.data_center,
options.api_domain,
options.app_domain
);
delete options.target_id;
delete options.element_token;
return { ...options, target, token, domains, config };
};
export const parseCalendarSyncOptions = (options = {}) => {
options.error = false;
const demoMode = typeof options.demo === "undefined" ? false : options.demo;
if (demoMode) {
console.warn(
"CronofyElements.CalendarSync: you are running in demo mode. No API requests will be made"
);
}
const token = parseToken(options, "CalendarSync", "calendar-sync");
const target = parseTarget(options, "CalendarSync", "calendar-sync");
if (!options.authorization_url) {
if (typeof options.authorization === "undefined" && !demoMode) {
console.error(
"CronofyElements.CalendarSync: you need to specify authorization options. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/"
);
return false;
} else if (typeof options.authorization === "undefined" && demoMode) {
options.authorization = {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
};
} else {
if (
typeof options.authorization.redirect_uri === "undefined" &&
!demoMode
) {
console.error(
"CronofyElements.CalendarSync: you need to specify authorization option: `redirect_uri`. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/"
);
return false;
}
if (
typeof options.authorization.client_id === "undefined" &&
!demoMode
) {
console.error(
"CronofyElements.CalendarSync: you need to specify authorization option: `client_id`. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/"
);
return false;
}
if (
typeof options.authorization.scope === "undefined" &&
!demoMode
) {
console.error(
"CronofyElements.CalendarSync: you need to specify authorization option: `scope`. Full details can be found on the Cronofy Elements documention page: https://docs.cronofy.com/developers/ui-elements/"
);
return false;
}
}
}
delete options.target_id;
delete options.element_token;
const domains = parseConnectionDomains(
options.data_center,
options.api_domain,
options.app_domain
);
return { ...options, target, token, domains };
};

@@ -27,8 +27,4 @@ const getTranslationsFromJson = (locales, contexts) =>

];
const locales = [
"de", //
"en", //
"fr"
];
const locales = ["de", "en", "es", "fr", "it", "nl"];
export const translations = getTranslationsFromJson(locales, contexts);

@@ -142,3 +142,4 @@ import moment from "moment-timezone";

duration,
interval
interval,
unrestricted
) => {

@@ -154,35 +155,35 @@ const intervalsPerSlot = duration / interval;

const slots = day.slots.map(slot => {
const availableSlot = availablePeriods[slot.start] || false;
// If a slot is `available` then it can be selected by a user.
//
// If a slot is `visiblyAvailable`, it cannot be directly selected, but
// should be displayed as "available" (because it falls in the duration
// overflow)
//
// If a slot is `blocked` it would normally be available, but is currently
// unselectable becasue of an existing user selection (this is a dynamic
// effect, and not set here).
const slotStart = moment.utc(slot.start, "YYYY-MM-DDTHH:mm:00Z");
const actualSlotEnd = slotStart.clone().add(duration, "minutes");
// This is the slot object that we'll eventually return.
let parsedSlot = {
start: slot.start,
end: actualSlotEnd.format("YYYY-MM-DDTHH:mm[:00Z]"),
available: false,
blocked: false,
target: false,
targetOffset: 0,
visiblyAvailable: false,
participants: []
};
// Does the slot overrun the end of the visible window?
const endDiff = actualSlotEnd.diff(elementEndTime, "minutes");
const overruns = endDiff > 0;
// If a slot is `available` then it can be selected by a user.
if ((overruns && unrestricted) || (overruns && slot.available)) {
// If the slot overruns, we need to caluclate the `target` and `targetOffset`
// If a slot is `visiblyAvailable`, it cannot be directly selected, but
// should be displayed as "available" (because it falls in the duration
// overflow)
// If a slot is `blocked` it would normally be available, but is currently
// unselectable becasue of an existing user selection (this is a dynamic
// effect, and not set here).
if (availableSlot && !overruns) {
// If there is a matching available slot, we just need to return the
// slot marked as available (and visibly available).
return {
start: slot.start,
end: actualSlotEnd.format("YYYY-MM-DDTHH:mm[:00Z]"),
available: true,
blocked: false,
target: false,
targetOffset: 0,
visiblyAvailable: true,
participants: availableSlot.participants
};
} else if (availableSlot && overruns) {
// We know the end-time of the window already...
const targetEndTime = moment(

@@ -192,2 +193,4 @@ elementEndTime,

);
// ...so we can use that to calculate the start time of the "last selectable
// slot" (which is what we mean by "target" slot).
const targetStartTime = targetEndTime

@@ -197,76 +200,57 @@ .subtract(duration, "minutes")

const target = availablePeriods[targetStartTime];
const hasOverruningSlot = typeof target !== "undefined";
const offsetInt = (duration - endDiff) / interval;
if (hasOverruningSlot) {
const offsetMinutes = actualSlotEnd.diff(
moment(target.end, "YYYY-MM-DDTHH:mm:00Z"),
"minutes"
);
const offsetInt = (duration - offsetMinutes) / interval;
parsedSlot.target = targetStartTime;
parsedSlot.targetOffset = offsetInt;
}
return {
start: slot.start,
end: actualSlotEnd.format("YYYY-MM-DDTHH:mm[:00Z]"),
available: false,
blocked: false,
target: targetStartTime,
targetOffset: offsetInt,
visiblyAvailable: true,
participants: false
};
} else {
return {
start: slot.start,
end: actualSlotEnd.format("YYYY-MM-DDTHH:mm[:00Z]"),
available: false,
blocked: false,
target: false,
targetOffset: 0,
visiblyAvailable: false,
participants: false
};
}
} else {
// If there is no matching available slot, we will *probably* want to
// return the slot marked as unavailable and not visibly available.
// BUT we should check to see if the slot is overlapped by a preceeding
// available slot (overlapping occurs in instances where the slot
// duration is longer than the interval between the slots).
const checkAvailabilityFor = parsedSlot.target
? parsedSlot.target
: slot.start;
const availableSlot =
availablePeriods[checkAvailabilityFor] || false;
if (availableSlot) {
parsedSlot.available = true;
parsedSlot.visiblyAvailable = true;
parsedSlot.participants = availableSlot.participants;
}
// Check if there are any overlapping slots
// Default to *not* visibly available.
let isOverlapped = false;
let overlappingSlotTimes = [];
let overlappingSlotsCount = 0;
if (intervalsPerSlot > 1) {
for (let i = 1; i < intervalsPerSlot; i++) {
const potentialOverlappingStartTime = slotStart
.clone()
.subtract(i * interval, "minutes")
.format("YYYY-MM-DDTHH:mm[:00Z]");
// Default to *not* visibly available.
let isOverlapped = false;
let overlappingSlotTimes = [];
const overlappingSlot =
availablePeriods[potentialOverlappingStartTime];
// Check if there are any overlapping slots
if (intervalsPerSlot > 1) {
for (let i = 1; i < intervalsPerSlot; i++) {
const potentialOverlappingStartTime = slotStart
.clone()
.subtract(i * interval, "minutes")
.format("YYYY-MM-DDTHH:mm[:00Z]");
const overlappingSlot =
availablePeriods[potentialOverlappingStartTime];
if (typeof overlappingSlot !== "undefined") {
isOverlapped = true;
overlappingSlotTimes.push(
potentialOverlappingStartTime
);
if (typeof overlappingSlot !== "undefined") {
overlappingSlotsCount++;
isOverlapped = true;
overlappingSlotTimes.push(
potentialOverlappingStartTime
);
} else {
if (overlappingSlotTimes.length > 0) {
overlappingSlotsCount++;
}
}
}
}
if (isOverlapped && !parsedSlot.available) {
// Only apply these values if the slot IS overlapped, but is
// also NOT available in it's own right.
parsedSlot.visiblyAvailable = true;
if (!unrestricted) {
parsedSlot.target = overlappingSlotTimes[0];
parsedSlot.targetOffset = overlappingSlotsCount;
}
}
return {
start: slot.start,
end: actualSlotEnd.format("YYYY-MM-DDTHH:mm[:00Z]"),
available: false,
blocked: false,
target: overlappingSlotTimes[0],
targetOffset: overlappingSlotTimes.length,
visiblyAvailable: isOverlapped,
participants: false
};
}
return parsedSlot;
});

@@ -282,3 +266,3 @@

export const generateWeeklySlots = (
{ availablePeriods, limits, weeks, tzid },
{ availablePeriods, limits, weeks, tzid, unrestricted },
getEmpties = createEmptySlotsForPeriod,

@@ -300,3 +284,4 @@ buildPeriod = buildDayPeriod

limits.duration,
limits.interval
limits.interval,
unrestricted
);

@@ -393,3 +378,3 @@

// console.log(`${testPeriod.end.format("(DD) HH:mm")} is ${endsBefore} hours after ${wrapper.start.format("(DD) HH:mm")}`);
if (endsBefore < 0) return false;
if (endsBefore <= 0) return false;

@@ -399,3 +384,3 @@ // If `wrapper` starts after `testPeriod` ends, then there's no overlap

// console.log(`${testPeriod.start.format("(DD) HH:mm")} is ${startsAfter} hours after ${wrapper.end.format("(DD) HH:mm")}`);
if (startsAfter > 0) return false;
if (startsAfter >= 0) return false;

@@ -402,0 +387,0 @@ const startDiff = wrapper.start.diff(testPeriod.start, "minutes");

@@ -7,3 +7,9 @@ import React from "react";

export const buildAuthUrl = ({ authUrl, authOptions, provider, appDomain }) => {
export const buildAuthUrl = ({
authUrl,
authOptions,
provider,
appDomain,
singleProfile
}) => {
let url;

@@ -23,2 +29,7 @@

// If we're in singleProfile mode, set avoid_linking
if (singleProfile) {
url.searchParams.append("avoid_linking", true);
}
// Then add each of the authOptions as url params

@@ -44,2 +55,3 @@ for (let param in authOptions) {

appDomain,
singleProfile,
useBuildAuthUrl = buildAuthUrl

@@ -53,3 +65,4 @@ ) => ({

provider: slug,
appDomain
appDomain,
singleProfile
})

@@ -62,9 +75,38 @@ });

authUrl = false,
singleProfile = false,
useBuildProviderData = buildProviderData
) => [
useBuildProviderData("google", "Google", auth, authUrl, appDomain),
useBuildProviderData("apple", "iCloud", auth, authUrl, appDomain),
useBuildProviderData("office365", "Office 365", auth, authUrl, appDomain),
useBuildProviderData("exchange", "Exchange", auth, authUrl, appDomain),
useBuildProviderData(
"google",
"Google",
auth,
authUrl,
appDomain,
singleProfile
),
useBuildProviderData(
"apple",
"iCloud",
auth,
authUrl,
appDomain,
singleProfile
),
useBuildProviderData(
"office365",
"Office 365",
auth,
authUrl,
appDomain,
singleProfile
),
useBuildProviderData(
"exchange",
"Exchange",
auth,
authUrl,
appDomain,
singleProfile
),
useBuildProviderData(
"live_connect",

@@ -74,3 +116,4 @@ "Outlook.com",

authUrl,
appDomain
appDomain,
singleProfile
)

@@ -77,0 +120,0 @@ ];

@@ -10,9 +10,8 @@ import React from "react";

import {
parseAgendaOptions,
parseSlotPickerOptions,
parseAvailabilityViewerOptions,
parseAvailabilityRulesOptions,
parseCalendarSyncOptions
} from "./helpers/init";
import { parseAgendaOptions } from "./helpers/init.Agenda";
import { parseSlotPickerOptions } from "./helpers/init.SlotPicker";
import { parseAvailabilityViewerOptions } from "./helpers/init.AvailabilityViewer";
import { parseAvailabilityRulesOptions } from "./helpers/init.AvailabilityRules";
import { parseCalendarSyncOptions } from "./helpers/init.CalendarSync";
import { generateElementAPI } from "./helpers/generator";

@@ -19,0 +18,0 @@ import { getNavigatorLanguage } from "./helpers/i18n";

{
"agenda": {
"all_day": "Den ganzen Tag",
"go_to_today": "Gehe zu heute",
"needs_action": "Braucht Aktion",
"no_all_day_events": "Keine ganztägigen Ereignisse zu zeigen",
"no_events": "Keine Ereignisse, für die angezeigt werden soll",
"all_day": "Ganztägig",
"go_to_today": "Heutigen Tag anzeigen",
"needs_action": "Unbestätigt",
"no_all_day_events": "Keine ganztägigen Ereignisse",
"no_events": "Keine Ereignisse",
"opaque": "Beschäftigt",

@@ -9,0 +9,0 @@ "today": "Heute",

{
"availability_rules": {}
"availability_rules": {
"add_calendar": "Kalender hinzufügen",
"available": "Verfügbar",
"checked": "Markiert",
"end": "Abschließen",
"included_calendars": "Enthaltene Kalender",
"rules_saved": "Regeln gespeichert",
"remove": "Entfernen",
"save_new_rules": "Neue Regeln speichern",
"saving": "Speichern",
"start": "Starten",
"toggle_slot": "Zeitfenster aktivieren/deaktivieren",
"unavailable": "Nicht verfügbar",
"unchecked": "Nicht markiert",
"unknown": "Unbekannt"
}
}
{
"availability_viewer": {}
"availability_viewer": {
"available": "Verfügbar",
"confirm": "Bestätigen",
"end": "Abschließen",
"no_slots_found": "Keine Zeitfenster gefunden",
"start": "Starten",
"unavailable": "Nicht verfügbar"
}
}
{
"calendar_sync": {}
"calendar_sync": {
"active": "Aktiv",
"add_calendar_account": "Kalender-Konto hinzufügen",
"calendar_accounts": "Kalender-Konten",
"cancel": "Abbrechen",
"edit_accounts": "Konten bearbeiten",
"pending": "Ausstehend",
"relink": "Erneut verlinken",
"remove": "Entfernen",
"select_provider": "Anbieter auswählen",
"select_provider_to_add_first_account": "Wählen Sie einen Anbieter, um Ihr erstes Konto hinzuzufügen."
}
}
{
"core": {
"loading": "Wird geladen...",
"next": "Nächster",
"previous": "Bisherige",
"back": "Zurück",
"close": "Schließen",
"error": "Fehler",
"global_error": "Das Element konnte nicht geladen werden.",
"loading": "Wird geladen",
"next": "Weiter",
"previous": "Zurück",
"refreshing": "Wird aktualisiert",
"time_zone": "Zeitzone"
}
}
{
"slot_picker": {}
"slot_picker": {
"cancel": "Abbrechen",
"confirm": "Bestätigen",
"no_slots_found": "Keine Zeitfenster gefunden",
"not_applicable": "N/A",
"select_day": "Tag auswählen"
}
}
{
"time_zones": {
"Africa/Addis_Ababa": "Addis Abeba",
"Africa/Algiers": "Algier",
"Africa/Asmera": "Asmara",
"Africa/Cairo": "Kairo",
"Africa/Dar_es_Salaam": "Daressalam",
"Africa/Djibouti": "Dschibuti",
"Africa/El_Aaiun": "El Aaiún",
"Africa/Khartoum": "Khartum",
"Africa/Lome": "Lomé",
"Africa/Mogadishu": "Mogadischu",
"Africa/Ndjamena": "N’Djamena",
"Africa/Porto-Novo": "Porto Novo",
"Africa/Sao_Tome": "São Tomé",
"Africa/Tripoli": "Tripolis",
"America/Asuncion": "Asunción",
"America/Bogota": "Bogotá",
"America/Cancun": "Cancún",
"America/Cayman": "Kaimaninseln",
"America/Coral_Harbour": "Atikokan",
"America/Cordoba": "Córdoba",
"America/Curacao": "Curaçao",
"America/Godthab": "Nuuk",
"America/Havana": "Havanna",
"America/Indiana/Knox": "Knox, Indiana",
"America/Indiana/Marengo": "Marengo, Indiana",
"America/Indiana/Petersburg": "Petersburg, Indiana",
"America/Indiana/Tell_City": "Tell City, Indiana",
"America/Indiana/Vevay": "Vevay, Indiana",
"America/Indiana/Vincennes": "Vincennes, Indiana",
"America/Indiana/Winamac": "Winamac, Indiana",
"America/Jamaica": "Jamaika",
"America/Kentucky/Monticello": "Monticello, Kentucky",
"America/Lower_Princes": "Lower Prince’s Quarter",
"America/Mexico_City": "Mexiko-Stadt",
"America/North_Dakota/Beulah": "Beulah, North Dakota",
"America/North_Dakota/Center": "Center, North Dakota",
"America/North_Dakota/New_Salem": "New Salem, North Dakota",
"America/Sao_Paulo": "São Paulo",
"America/Scoresbysund": "Ittoqqortoormiit",
"America/St_Barthelemy": "Saint-Barthélemy",
"America/St_Johns": "St. John’s",
"America/St_Kitts": "St. Kitts",
"America/St_Lucia": "St. Lucia",
"America/St_Thomas": "St. Thomas",
"America/St_Vincent": "St. Vincent",
"Antarctica/DumontDUrville": "Dumont d’Urville",
"Antarctica/Vostok": "Wostok",
"Asia/Aqtobe": "Aktobe",
"Asia/Ashgabat": "Aşgabat",
"Asia/Baghdad": "Bagdad",
"Asia/Bishkek": "Bischkek",
"Asia/Brunei": "Brunei Darussalam",
"Asia/Calcutta": "Kalkutta",
"Asia/Chita": "Tschita",
"Asia/Choibalsan": "Tschoibalsan",
"Asia/Damascus": "Damaskus",
"Asia/Dushanbe": "Duschanbe",
"Asia/Hong_Kong": "Hongkong",
"Asia/Hovd": "Chowd",
"Asia/Kamchatka": "Kamtschatka",
"Asia/Karachi": "Karatschi",
"Asia/Katmandu": "Kathmandu",
"Asia/Khandyga": "Chandyga",
"Asia/Krasnoyarsk": "Krasnojarsk",
"Asia/Muscat": "Maskat",
"Asia/Nicosia": "Nikosia",
"Asia/Novokuznetsk": "Nowokuznetsk",
"Asia/Novosibirsk": "Nowosibirsk",
"Asia/Pyongyang": "Pjöngjang",
"Asia/Qatar": "Katar",
"Asia/Qyzylorda": "Qysylorda",
"Asia/Rangoon": "Rangun",
"Asia/Riyadh": "Riad",
"Asia/Saigon": "Ho-Chi-Minh-Stadt",
"Asia/Sakhalin": "Sachalin",
"Asia/Singapore": "Singapur",
"Asia/Taipei": "Taipeh",
"Asia/Tashkent": "Taschkent",
"Asia/Tbilisi": "Tiflis",
"Asia/Tehran": "Teheran",
"Asia/Tokyo": "Tokio",
"Asia/Urumqi": "Ürümqi",
"Asia/Vladivostok": "Wladiwostok",
"Asia/Yakutsk": "Jakutsk",
"Asia/Yekaterinburg": "Jekaterinburg",
"Asia/Yerevan": "Eriwan",
"Atlantic/Azores": "Azoren",
"Atlantic/Canary": "Kanaren",
"Atlantic/Cape_Verde": "Cabo Verde",
"Atlantic/Faeroe": "Färöer",
"Atlantic/Reykjavik": "Reyk­ja­vík",
"Atlantic/South_Georgia": "Südgeorgien",
"Atlantic/St_Helena": "St. Helena",
"Etc/Unknown": "Unbekannt",
"Europe/Astrakhan": "Astrachan",
"Europe/Athens": "Athen",
"Europe/Belgrade": "Belgrad",
"Europe/Brussels": "Brüssel",
"Europe/Bucharest": "Bukarest",
"Europe/Busingen": "Büsingen",
"Europe/Chisinau": "Kischinau",
"Europe/Copenhagen": "Kopenhagen",
"Europe/Kiev": "Kiew",
"Europe/Kirov": "Kirow",
"Europe/Lisbon": "Lissabon",
"Europe/Luxembourg": "Luxemburg",
"Europe/Moscow": "Moskau",
"Europe/Prague": "Prag",
"Europe/Rome": "Rom",
"Europe/Saratov": "Saratow",
"Europe/Tirane": "Tirana",
"Europe/Ulyanovsk": "Uljanowsk",
"Europe/Uzhgorod": "Uschgorod",
"Europe/Vatican": "Vatikan",
"Europe/Vienna": "Wien",
"Europe/Volgograd": "Wolgograd",
"Europe/Warsaw": "Warschau",
"Europe/Zaporozhye": "Saporischja",
"Europe/Zurich": "Zürich",
"Indian/Christmas": "Weihnachtsinsel",
"Indian/Comoro": "Komoren",
"Indian/Maldives": "Malediven",
"Indian/Reunion": "Réunion",
"Pacific/Easter": "Osterinsel",
"Pacific/Fiji": "Fidschi",
"Pacific/Ponape": "Pohnpei",
"Pacific/Truk": "Chuuk"
}
}
"time_zone": {
"label": "Zeitzone"
},
"time_zones": {
"Africa/Addis_Ababa": "Addis Abeba",
"Africa/Algiers": "Algier",
"Africa/Asmera": "Asmara",
"Africa/Cairo": "Kairo",
"Africa/Dar_es_Salaam": "Daressalam",
"Africa/Djibouti": "Dschibuti",
"Africa/El_Aaiun": "El Aaiún",
"Africa/Khartoum": "Khartum",
"Africa/Lome": "Lomé",
"Africa/Mogadishu": "Mogadischu",
"Africa/Ndjamena": "N’Djamena",
"Africa/Porto-Novo": "Porto Novo",
"Africa/Sao_Tome": "São Tomé",
"Africa/Tripoli": "Tripolis",
"America/Asuncion": "Asunción",
"America/Bogota": "Bogotá",
"America/Cancun": "Cancún",
"America/Cayman": "Kaimaninseln",
"America/Coral_Harbour": "Atikokan",
"America/Cordoba": "Córdoba",
"America/Curacao": "Curaçao",
"America/Godthab": "Nuuk",
"America/Havana": "Havanna",
"America/Indiana/Knox": "Knox, Indiana",
"America/Indiana/Marengo": "Marengo, Indiana",
"America/Indiana/Petersburg": "Petersburg, Indiana",
"America/Indiana/Tell_City": "Tell City, Indiana",
"America/Indiana/Vevay": "Vevay, Indiana",
"America/Indiana/Vincennes": "Vincennes, Indiana",
"America/Indiana/Winamac": "Winamac, Indiana",
"America/Jamaica": "Jamaika",
"America/Kentucky/Monticello": "Monticello, Kentucky",
"America/Lower_Princes": "Lower Prince’s Quarter",
"America/Mexico_City": "Mexiko-Stadt",
"America/North_Dakota/Beulah": "Beulah, North Dakota",
"America/North_Dakota/Center": "Center, North Dakota",
"America/North_Dakota/New_Salem": "New Salem, North Dakota",
"America/Sao_Paulo": "São Paulo",
"America/Scoresbysund": "Ittoqqortoormiit",
"America/St_Barthelemy": "Saint-Barthélemy",
"America/St_Johns": "St. John’s",
"America/St_Kitts": "St. Kitts",
"America/St_Lucia": "St. Lucia",
"America/St_Thomas": "St. Thomas",
"America/St_Vincent": "St. Vincent",
"Antarctica/DumontDUrville": "Dumont d’Urville",
"Antarctica/Vostok": "Wostok",
"Asia/Aqtobe": "Aktobe",
"Asia/Ashgabat": "Aşgabat",
"Asia/Baghdad": "Bagdad",
"Asia/Bishkek": "Bischkek",
"Asia/Brunei": "Brunei Darussalam",
"Asia/Calcutta": "Kalkutta",
"Asia/Chita": "Tschita",
"Asia/Choibalsan": "Tschoibalsan",
"Asia/Damascus": "Damaskus",
"Asia/Dushanbe": "Duschanbe",
"Asia/Hong_Kong": "Hongkong",
"Asia/Hovd": "Chowd",
"Asia/Kamchatka": "Kamtschatka",
"Asia/Karachi": "Karatschi",
"Asia/Katmandu": "Kathmandu",
"Asia/Khandyga": "Chandyga",
"Asia/Krasnoyarsk": "Krasnojarsk",
"Asia/Muscat": "Maskat",
"Asia/Nicosia": "Nikosia",
"Asia/Novokuznetsk": "Nowokuznetsk",
"Asia/Novosibirsk": "Nowosibirsk",
"Asia/Pyongyang": "Pjöngjang",
"Asia/Qatar": "Katar",
"Asia/Qyzylorda": "Qysylorda",
"Asia/Rangoon": "Rangun",
"Asia/Riyadh": "Riad",
"Asia/Saigon": "Ho-Chi-Minh-Stadt",
"Asia/Sakhalin": "Sachalin",
"Asia/Singapore": "Singapur",
"Asia/Taipei": "Taipeh",
"Asia/Tashkent": "Taschkent",
"Asia/Tbilisi": "Tiflis",
"Asia/Tehran": "Teheran",
"Asia/Tokyo": "Tokio",
"Asia/Urumqi": "Ürümqi",
"Asia/Vladivostok": "Wladiwostok",
"Asia/Yakutsk": "Jakutsk",
"Asia/Yekaterinburg": "Jekaterinburg",
"Asia/Yerevan": "Eriwan",
"Atlantic/Azores": "Azoren",
"Atlantic/Canary": "Kanaren",
"Atlantic/Cape_Verde": "Cabo Verde",
"Atlantic/Faeroe": "Färöer",
"Atlantic/Reykjavik": "Reyk­ja­vík",
"Atlantic/South_Georgia": "Südgeorgien",
"Atlantic/St_Helena": "St. Helena",
"Etc/Unknown": "Unbekannt",
"Europe/Astrakhan": "Astrachan",
"Europe/Athens": "Athen",
"Europe/Belgrade": "Belgrad",
"Europe/Brussels": "Brüssel",
"Europe/Bucharest": "Bukarest",
"Europe/Busingen": "Büsingen",
"Europe/Chisinau": "Kischinau",
"Europe/Copenhagen": "Kopenhagen",
"Europe/Kiev": "Kiew",
"Europe/Kirov": "Kirow",
"Europe/Lisbon": "Lissabon",
"Europe/Luxembourg": "Luxemburg",
"Europe/Moscow": "Moskau",
"Europe/Prague": "Prag",
"Europe/Rome": "Rom",
"Europe/Saratov": "Saratow",
"Europe/Tirane": "Tirana",
"Europe/Ulyanovsk": "Uljanowsk",
"Europe/Uzhgorod": "Uschgorod",
"Europe/Vatican": "Vatikan",
"Europe/Vienna": "Wien",
"Europe/Volgograd": "Wolgograd",
"Europe/Warsaw": "Warschau",
"Europe/Zaporozhye": "Saporischja",
"Europe/Zurich": "Zürich",
"Indian/Christmas": "Weihnachtsinsel",
"Indian/Comoro": "Komoren",
"Indian/Maldives": "Malediven",
"Indian/Reunion": "Réunion",
"Pacific/Easter": "Osterinsel",
"Pacific/Fiji": "Fidschi",
"Pacific/Ponape": "Pohnpei",
"Pacific/Truk": "Chuuk"
}
}

@@ -9,3 +9,2 @@ {

"rules_saved": "Rules saved",
"no_events": "No events to show",
"remove": "Remove",

@@ -17,4 +16,5 @@ "save_new_rules": "Save new rules",

"unavailable": "Unavailable",
"unchecked": "Unchecked"
"unchecked": "Unchecked",
"unknown": "Unknown"
}
}
{
"time_zones": {
"Africa/Sao_Tome": "São Tomé",
"America/Asuncion": "Asunción",
"America/Curacao": "Curaçao",
"America/St_Barthelemy": "St. Barthélemy",
"Antarctica/DumontDUrville": "Dumont d’Urville",
"Asia/Qostanay": "Kostanay",
"Asia/Saigon": "Ho Chi Minh City",
"Etc/Unknown": "Unknown City",
"Europe/Uzhgorod": "Uzhhorod",
"Indian/Reunion": "Réunion"
}
}
"time_zone": {
"label": "Time Zone"
},
"time_zones": {
"Africa/Sao_Tome": "São Tomé",
"America/Asuncion": "Asunción",
"America/Curacao": "Curaçao",
"America/St_Barthelemy": "St. Barthélemy",
"Antarctica/DumontDUrville": "Dumont d’Urville",
"Asia/Qostanay": "Kostanay",
"Asia/Saigon": "Ho Chi Minh City",
"Etc/Unknown": "Unknown City",
"Europe/Uzhgorod": "Uzhhorod",
"Indian/Reunion": "Réunion"
}
}
{
"agenda": {}
"agenda": {
"all_day": "Journée entière",
"go_to_today": "Voir aujourd’hui",
"needs_action": "Non confirmé",
"no_all_day_events": "Aucun événement d’une journée à afficher",
"no_events": "Aucun événement à afficher",
"opaque": "Occupé(e)",
"today": "Aujourd’hui",
"transparent": "Libre"
}
}
{
"availability_rules": {}
"availability_rules": {
"add_calendar": "Ajouter un calendrier",
"available": "Disponible",
"checked": "Coché",
"end": "Fin",
"included_calendars": "Calendriers inclus",
"rules_saved": "Règles enregistrées",
"remove": "Supprimer",
"save_new_rules": "Enregistrer de nouvelles règles",
"saving": "Enregistrement",
"start": "Début",
"toggle_slot": "Activer/Désactiver le créneau",
"unavailable": "Indisponible",
"unchecked": "Non coché",
"unknown": "Inconnu"
}
}
{
"availability_viewer": {
"available": "Disponible",
"confirm": "Confirmer",
"no_slots_found": "Aucun emplacement trouvé"
"end": "Fin",
"no_slots_found": "Aucun créneau trouvé",
"start": "Début",
"unavailable": "Indisponible"
}
}
{
"calendar_sync": {}
"calendar_sync": {
"active": "Actif",
"add_calendar_account": "Ajouter un compte de calendrier",
"calendar_accounts": "Comptes de calendrier",
"cancel": "Annuler",
"edit_accounts": "Modifier les comptes",
"pending": "En attente",
"relink": "Reconnecter",
"remove": "Supprimer",
"select_provider": "Sélectionner un fournisseur",
"select_provider_to_add_first_account": "Sélectionnez un fournisseur pour ajouter votre premier compte"
}
}
{
"core": {
"back": "Retour",
"close": "Fermer",
"error": "Erreur",
"error_global": "Une erreur s'est produite lors du chargement du composant",
"global_error": "Une erreur est survenue lors du chargement de l’élément",
"loading": "Chargement",
"next": "Suivant",
"previous": "Précédent",
"refreshing": "Actualisation",
"time_zone": "Fuseau horaire"
}
}
{
"slot_picker": {
"cancel": "Annuler",
"confirm": "Confirmer",
"no_slots_found": "Aucun emplacement trouvé"
"no_slots_found": "Aucun créneau trouvé",
"not_applicable": "S.O.",
"select_day": "Sélectionner un jour"
}
}
{
"time_zones": {
"Africa/Addis_Ababa": "Addis-Abeba",
"Africa/Algiers": "Alger",
"Africa/Asmera": "Asmara",
"Africa/Cairo": "Le Caire",
"Africa/El_Aaiun": "Laâyoune",
"Africa/Lome": "Lomé",
"Africa/Mogadishu": "Mogadiscio",
"Africa/Ndjamena": "N'Djamena",
"Africa/Sao_Tome": "São Tomé",
"Africa/Tripoli": "Tripoli (Libye)",
"America/Araguaina": "Araguaína",
"America/Argentina/Rio_Gallegos": "Río Gallegos",
"America/Argentina/Tucuman": "Tucumán",
"America/Argentina/Ushuaia": "Ushuaïa",
"America/Asuncion": "Asunción",
"America/Bahia_Banderas": "Bahia de Banderas",
"America/Barbados": "La Barbade",
"America/Belem": "Belém",
"America/Cancun": "Cancún",
"America/Cayman": "Caïmans",
"America/Coral_Harbour": "Atikokan",
"America/Cordoba": "Córdoba",
"America/Cuiaba": "Cuiabá",
"America/Curacao": "Curaçao",
"America/Detroit": "Détroit",
"America/Dominica": "Dominique",
"America/Eirunepe": "Eirunepé",
"America/Godthab": "Nuuk",
"America/Grenada": "Grenade",
"America/Havana": "La Havane",
"America/Indiana/Knox": "Knox [Indiana]",
"America/Indiana/Marengo": "Marengo [Indiana]",
"America/Indiana/Petersburg": "Petersburg [Indiana]",
"America/Indiana/Tell_City": "Tell City [Indiana]",
"America/Indiana/Vevay": "Vevay [Indiana]",
"America/Indiana/Vincennes": "Vincennes [Indiana]",
"America/Indiana/Winamac": "Winamac [Indiana]",
"America/Jamaica": "Jamaïque",
"America/Kentucky/Monticello": "Monticello [Kentucky]",
"America/Lower_Princes": "Lower Prince's Quarter",
"America/Maceio": "Maceió",
"America/Manaus": "Manaos",
"America/Mazatlan": "Mazatlán",
"America/Merida": "Mérida",
"America/Mexico_City": "Mexico",
"America/North_Dakota/Beulah": "Beulah (Dakota du Nord)",
"America/North_Dakota/Center": "Center (Dakota du Nord)",
"America/North_Dakota/New_Salem": "New Salem (Dakota du Nord)",
"America/Port_of_Spain": "Port-d'Espagne",
"America/Puerto_Rico": "Porto Rico",
"America/Santarem": "Santarém",
"America/Santo_Domingo": "Saint-Domingue",
"America/Sao_Paulo": "São Paulo",
"America/Scoresbysund": "Ittoqqortoormiit",
"America/St_Barthelemy": "Saint-Barthélemy",
"America/St_Johns": "Saint-Jean de Terre-Neuve",
"America/St_Kitts": "Saint-Christophe",
"America/St_Lucia": "Sainte-Lucie",
"America/St_Thomas": "Saint-Thomas",
"America/St_Vincent": "Saint-Vincent",
"America/Tegucigalpa": "Tégucigalpa",
"America/Thule": "Thulé",
"Antarctica/DumontDUrville": "Dumont d'Urville",
"Antarctica/Syowa": "Showa",
"Asia/Almaty": "Alma Ata",
"Asia/Aqtau": "Aktaou",
"Asia/Aqtobe": "Aktioubinsk",
"Asia/Ashgabat": "Achgabat",
"Asia/Atyrau": "Atyraou",
"Asia/Baghdad": "Bagdad",
"Asia/Bahrain": "Bahreïn",
"Asia/Baku": "Bakou",
"Asia/Beirut": "Beyrouth",
"Asia/Bishkek": "Bichkek",
"Asia/Chita": "Tchita",
"Asia/Choibalsan": "Tchoïbalsan",
"Asia/Damascus": "Damas",
"Asia/Dubai": "Dubaï",
"Asia/Dushanbe": "Douchanbé",
"Asia/Famagusta": "Famagouste",
"Asia/Hebron": "Hébron",
"Asia/Irkutsk": "Irkoutsk",
"Asia/Jerusalem": "Jérusalem",
"Asia/Kabul": "Kaboul",
"Asia/Kamchatka": "Kamtchatka",
"Asia/Katmandu": "Katmandou",
"Asia/Krasnoyarsk": "Krasnoïarsk",
"Asia/Kuwait": "Koweït",
"Asia/Macau": "Macao",
"Asia/Makassar": "Macassar",
"Asia/Manila": "Manille",
"Asia/Muscat": "Mascate",
"Asia/Nicosia": "Nicosie",
"Asia/Novosibirsk": "Novossibirsk",
"Asia/Oral": "Ouralsk",
"Asia/Qostanay": "Kostanaï",
"Asia/Qyzylorda": "Kzyl Orda",
"Asia/Rangoon": "Rangoun",
"Asia/Riyadh": "Riyad",
"Asia/Saigon": "Hô-Chi-Minh-Ville",
"Asia/Sakhalin": "Sakhaline",
"Asia/Samarkand": "Samarcande",
"Asia/Seoul": "Séoul",
"Asia/Singapore": "Singapour",
"Asia/Tashkent": "Tachkent",
"Asia/Tbilisi": "Tbilissi",
"Asia/Tehran": "Téhéran",
"Asia/Ulaanbaatar": "Oulan-Bator",
"Asia/Urumqi": "Ürümqi",
"Asia/Yakutsk": "Iakoutsk",
"Asia/Yekaterinburg": "Ekaterinbourg",
"Asia/Yerevan": "Erevan",
"Atlantic/Azores": "Açores",
"Atlantic/Bermuda": "Bermudes",
"Atlantic/Canary": "Îles Canaries",
"Atlantic/Cape_Verde": "Cap-Vert",
"Atlantic/Faeroe": "Féroé",
"Atlantic/Madeira": "Madère",
"Atlantic/South_Georgia": "Géorgie du Sud",
"Atlantic/St_Helena": "Sainte-Hélène",
"Australia/Adelaide": "Adélaïde",
"Etc/Unknown": "ville inconnue",
"Europe/Andorra": "Andorre",
"Europe/Athens": "Athènes",
"Europe/Brussels": "Bruxelles",
"Europe/Bucharest": "Bucarest",
"Europe/Busingen": "Büsingen",
"Europe/Copenhagen": "Copenhague",
"Europe/Guernsey": "Guernesey",
"Europe/Isle_of_Man": "Île de Man",
"Europe/Lisbon": "Lisbonne",
"Europe/London": "Londres",
"Europe/Malta": "Malte",
"Europe/Moscow": "Moscou",
"Europe/San_Marino": "Saint-Marin",
"Europe/Tirane": "Tirana",
"Europe/Ulyanovsk": "Oulianovsk",
"Europe/Uzhgorod": "Oujgorod",
"Europe/Vatican": "Le Vatican",
"Europe/Vienna": "Vienne",
"Europe/Warsaw": "Varsovie",
"Europe/Zaporozhye": "Zaporojie",
"Indian/Comoro": "Comores",
"Indian/Mahe": "Mahé",
"Indian/Mauritius": "Maurice",
"Indian/Reunion": "La Réunion",
"Pacific/Easter": "Île de Pâques",
"Pacific/Efate": "Éfaté",
"Pacific/Fiji": "Fidji",
"Pacific/Galapagos": "Galápagos",
"Pacific/Marquesas": "Marquises",
"Pacific/Noumea": "Nouméa",
"Pacific/Ponape": "Pohnpei",
"Pacific/Truk": "Chuuk"
}
}
"time_zone": {
"label": "Fuseau horaire"
},
"time_zones": {
"Africa/Addis_Ababa": "Addis-Abeba",
"Africa/Algiers": "Alger",
"Africa/Asmera": "Asmara",
"Africa/Cairo": "Le Caire",
"Africa/El_Aaiun": "Laâyoune",
"Africa/Lome": "Lomé",
"Africa/Mogadishu": "Mogadiscio",
"Africa/Ndjamena": "N’Djamena",
"Africa/Sao_Tome": "São Tomé",
"Africa/Tripoli": "Tripoli (Libye)",
"America/Araguaina": "Araguaína",
"America/Argentina/Rio_Gallegos": "Río Gallegos",
"America/Argentina/Tucuman": "Tucumán",
"America/Argentina/Ushuaia": "Ushuaïa",
"America/Asuncion": "Asunción",
"America/Bahia_Banderas": "Bahia de Banderas",
"America/Barbados": "La Barbade",
"America/Belem": "Belém",
"America/Cancun": "Cancún",
"America/Cayman": "Caïmans",
"America/Coral_Harbour": "Atikokan",
"America/Cordoba": "Córdoba",
"America/Cuiaba": "Cuiabá",
"America/Curacao": "Curaçao",
"America/Detroit": "Détroit",
"America/Dominica": "Dominique",
"America/Eirunepe": "Eirunepé",
"America/Godthab": "Nuuk",
"America/Grenada": "Grenade",
"America/Havana": "La Havane",
"America/Indiana/Knox": "Knox [Indiana]",
"America/Indiana/Marengo": "Marengo [Indiana]",
"America/Indiana/Petersburg": "Petersburg [Indiana]",
"America/Indiana/Tell_City": "Tell City [Indiana]",
"America/Indiana/Vevay": "Vevay [Indiana]",
"America/Indiana/Vincennes": "Vincennes [Indiana]",
"America/Indiana/Winamac": "Winamac [Indiana]",
"America/Jamaica": "Jamaïque",
"America/Kentucky/Monticello": "Monticello [Kentucky]",
"America/Lower_Princes": "Lower Prince’s Quarter",
"America/Maceio": "Maceió",
"America/Manaus": "Manaos",
"America/Mazatlan": "Mazatlán",
"America/Merida": "Mérida",
"America/Mexico_City": "Mexico",
"America/North_Dakota/Beulah": "Beulah (Dakota du Nord)",
"America/North_Dakota/Center": "Center (Dakota du Nord)",
"America/North_Dakota/New_Salem": "New Salem (Dakota du Nord)",
"America/Port_of_Spain": "Port-d’Espagne",
"America/Puerto_Rico": "Porto Rico",
"America/Santarem": "Santarém",
"America/Santo_Domingo": "Saint-Domingue",
"America/Sao_Paulo": "São Paulo",
"America/Scoresbysund": "Ittoqqortoormiit",
"America/St_Barthelemy": "Saint-Barthélemy",
"America/St_Johns": "Saint-Jean de Terre-Neuve",
"America/St_Kitts": "Saint-Christophe",
"America/St_Lucia": "Sainte-Lucie",
"America/St_Thomas": "Saint-Thomas",
"America/St_Vincent": "Saint-Vincent",
"America/Tegucigalpa": "Tégucigalpa",
"America/Thule": "Thulé",
"Antarctica/DumontDUrville": "Dumont d’Urville",
"Antarctica/Syowa": "Showa",
"Asia/Almaty": "Alma Ata",
"Asia/Aqtau": "Aktaou",
"Asia/Aqtobe": "Aktioubinsk",
"Asia/Ashgabat": "Achgabat",
"Asia/Atyrau": "Atyraou",
"Asia/Baghdad": "Bagdad",
"Asia/Bahrain": "Bahreïn",
"Asia/Baku": "Bakou",
"Asia/Beirut": "Beyrouth",
"Asia/Bishkek": "Bichkek",
"Asia/Chita": "Tchita",
"Asia/Choibalsan": "Tchoïbalsan",
"Asia/Damascus": "Damas",
"Asia/Dubai": "Dubaï",
"Asia/Dushanbe": "Douchanbé",
"Asia/Famagusta": "Famagouste",
"Asia/Hebron": "Hébron",
"Asia/Irkutsk": "Irkoutsk",
"Asia/Jerusalem": "Jérusalem",
"Asia/Kabul": "Kaboul",
"Asia/Kamchatka": "Kamtchatka",
"Asia/Katmandu": "Katmandou",
"Asia/Krasnoyarsk": "Krasnoïarsk",
"Asia/Kuwait": "Koweït",
"Asia/Macau": "Macao",
"Asia/Makassar": "Macassar",
"Asia/Manila": "Manille",
"Asia/Muscat": "Mascate",
"Asia/Nicosia": "Nicosie",
"Asia/Novosibirsk": "Novossibirsk",
"Asia/Oral": "Ouralsk",
"Asia/Qostanay": "Kostanaï",
"Asia/Qyzylorda": "Kzyl Orda",
"Asia/Rangoon": "Rangoun",
"Asia/Riyadh": "Riyad",
"Asia/Saigon": "Hô-Chi-Minh-Ville",
"Asia/Sakhalin": "Sakhaline",
"Asia/Samarkand": "Samarcande",
"Asia/Seoul": "Séoul",
"Asia/Singapore": "Singapour",
"Asia/Tashkent": "Tachkent",
"Asia/Tbilisi": "Tbilissi",
"Asia/Tehran": "Téhéran",
"Asia/Ulaanbaatar": "Oulan-Bator",
"Asia/Urumqi": "Ürümqi",
"Asia/Yakutsk": "Iakoutsk",
"Asia/Yekaterinburg": "Ekaterinbourg",
"Asia/Yerevan": "Erevan",
"Atlantic/Azores": "Açores",
"Atlantic/Bermuda": "Bermudes",
"Atlantic/Canary": "Îles Canaries",
"Atlantic/Cape_Verde": "Cap-Vert",
"Atlantic/Faeroe": "Féroé",
"Atlantic/Madeira": "Madère",
"Atlantic/South_Georgia": "Géorgie du Sud",
"Atlantic/St_Helena": "Sainte-Hélène",
"Australia/Adelaide": "Adélaïde",
"Etc/Unknown": "ville inconnue",
"Europe/Andorra": "Andorre",
"Europe/Athens": "Athènes",
"Europe/Brussels": "Bruxelles",
"Europe/Bucharest": "Bucarest",
"Europe/Busingen": "Büsingen",
"Europe/Copenhagen": "Copenhague",
"Europe/Guernsey": "Guernesey",
"Europe/Isle_of_Man": "Île de Man",
"Europe/Lisbon": "Lisbonne",
"Europe/London": "Londres",
"Europe/Malta": "Malte",
"Europe/Moscow": "Moscou",
"Europe/San_Marino": "Saint-Marin",
"Europe/Tirane": "Tirana",
"Europe/Ulyanovsk": "Oulianovsk",
"Europe/Uzhgorod": "Oujgorod",
"Europe/Vatican": "Le Vatican",
"Europe/Vienna": "Vienne",
"Europe/Warsaw": "Varsovie",
"Europe/Zaporozhye": "Zaporojie",
"Indian/Comoro": "Comores",
"Indian/Mahe": "Mahé",
"Indian/Mauritius": "Maurice",
"Indian/Reunion": "La Réunion",
"Pacific/Easter": "Île de Pâques",
"Pacific/Efate": "Éfaté",
"Pacific/Fiji": "Fidji",
"Pacific/Galapagos": "Galápagos",
"Pacific/Marquesas": "Marquises",
"Pacific/Noumea": "Nouméa",
"Pacific/Ponape": "Pohnpei",
"Pacific/Truk": "Chuuk"
}
}

@@ -1,2 +0,6 @@

import * as parsers from "../src/js/helpers/init";
import { parseAgendaOptions } from "../src/js/helpers/init.Agenda";
import { parseAvailabilityRulesOptions } from "../src/js/helpers/init.AvailabilityRules";
import { parseAvailabilityViewerOptions } from "../src/js/helpers/init.AvailabilityViewer";
import { parseCalendarSyncOptions } from "../src/js/helpers/init.CalendarSync";
import { parseSlotPickerOptions } from "../src/js/helpers/init.SlotPicker";

@@ -29,3 +33,3 @@ // The parsers rely on console warning and errors to

};
expect(parsers.parseAgendaOptions(input)).toEqual(expectedOutput);
expect(parseAgendaOptions(input)).toEqual(expectedOutput);
expect(console.error).toHaveBeenCalledTimes(0);

@@ -36,3 +40,3 @@ expect(console.warn).toHaveBeenCalledTimes(0);

it("fails if there is no token declared", () => {
expect(parsers.parseAgendaOptions()).toEqual(false);
expect(parseAgendaOptions()).toEqual(false);
expect(console.error).toHaveBeenCalledTimes(1);

@@ -51,5 +55,3 @@ });

};
expect(parsers.parseAgendaOptions({ demo: true })).toEqual(
expectedOutput
);
expect(parseAgendaOptions({ demo: true })).toEqual(expectedOutput);
expect(console.warn).toHaveBeenCalledTimes(2);

@@ -68,3 +70,3 @@ expect(console.error).toHaveBeenCalledTimes(0);

};
expect(parsers.parseAgendaOptions({ element_token: "TOKEN" })).toEqual(
expect(parseAgendaOptions({ element_token: "TOKEN" })).toEqual(
expectedOutput

@@ -86,3 +88,3 @@ );

expect(
parsers.parseAgendaOptions({
parseAgendaOptions({
element_token: "TOKEN",

@@ -116,3 +118,3 @@ target_id: "TARGET"

};
expect(parsers.parseSlotPickerOptions(input)).toEqual(expectedOutput);
expect(parseSlotPickerOptions(input)).toEqual(expectedOutput);
expect(console.error).toHaveBeenCalledTimes(0);

@@ -123,3 +125,3 @@ expect(console.warn).toHaveBeenCalledTimes(0);

it("fails if there is no token declared", () => {
expect(parsers.parseSlotPickerOptions()).toEqual(false);
expect(parseSlotPickerOptions()).toEqual(false);
expect(console.error).toHaveBeenCalledTimes(1);

@@ -143,3 +145,3 @@ });

expect(
parsers.parseSlotPickerOptions({
parseSlotPickerOptions({
demo: true,

@@ -167,3 +169,3 @@ availability_query: "QUERY_OBJECT"

expect(
parsers.parseSlotPickerOptions({
parseSlotPickerOptions({
availability_query: "QUERY_OBJECT",

@@ -191,3 +193,3 @@ element_token: "TOKEN"

expect(
parsers.parseSlotPickerOptions({
parseSlotPickerOptions({
availability_query: "QUERY_OBJECT",

@@ -217,3 +219,3 @@ element_token: "TOKEN",

expect(
parsers.parseSlotPickerOptions({
parseSlotPickerOptions({
availability_query: "QUERY_OBJECT",

@@ -247,3 +249,4 @@ data_center: "de",

boundsControl: true,
mode: "confirm"
mode: "confirm",
slot_selection: "available"
},

@@ -262,5 +265,3 @@ customtzid: true,

};
expect(parsers.parseAvailabilityViewerOptions(input)).toEqual(
expectedOutput
);
expect(parseAvailabilityViewerOptions(input)).toEqual(expectedOutput);
expect(console.error).toHaveBeenCalledTimes(0);

@@ -277,3 +278,3 @@ expect(console.warn).toHaveBeenCalledTimes(0);

const output = parsers.parseAvailabilityViewerOptions(input);
const output = parseAvailabilityViewerOptions(input);

@@ -289,3 +290,3 @@ expect(output.config.query).toBe(undefined);

it("fails if there is no token declared", () => {
expect(parsers.parseAvailabilityViewerOptions()).toEqual(false);
expect(parseAvailabilityViewerOptions()).toEqual(false);
expect(console.error).toHaveBeenCalledTimes(1);

@@ -295,21 +296,4 @@ });

it("continues if there is no token declared, but we're in demo mode", () => {
const expectedOutput = {
config: {
mode: "confirm"
},
customtzid: false,
const output = parseAvailabilityViewerOptions({
demo: true,
domains: {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
},
error: false,
query: "QUERY_OBJECT",
target: "TARGET",
token: false,
tzid: sniffedTimezone
};
const output = parsers.parseAvailabilityViewerOptions({
demo: true,
availability_query: "QUERY_OBJECT"

@@ -328,3 +312,3 @@ });

it("applies the default target if there is no target option", () => {
const output = parsers.parseAvailabilityViewerOptions({
const output = parseAvailabilityViewerOptions({
element_token: "TOKEN",

@@ -346,3 +330,3 @@ availability_query: "QUERY_OBJECT"

const output = parsers.parseAvailabilityViewerOptions({
const output = parseAvailabilityViewerOptions({
element_token: "TOKEN",

@@ -366,3 +350,3 @@ target_id: "TARGET",

const output = parsers.parseAvailabilityViewerOptions({
const output = parseAvailabilityViewerOptions({
data_center: "de",

@@ -382,3 +366,3 @@ element_token: "TOKEN",

it("correctly parses the config.mode", () => {
const output = parsers.parseAvailabilityViewerOptions({
const output = parseAvailabilityViewerOptions({
data_center: "de",

@@ -400,3 +384,3 @@ element_token: "TOKEN",

it("correctly parses an empty config.mode", () => {
const output = parsers.parseAvailabilityViewerOptions({
const output = parseAvailabilityViewerOptions({
element_token: "TOKEN",

@@ -416,3 +400,3 @@ target_id: "TARGET",

it("correctly parses the config.customBounds", () => {
const output = parsers.parseAvailabilityViewerOptions({
const output = parseAvailabilityViewerOptions({
data_center: "de",

@@ -434,3 +418,3 @@ element_token: "TOKEN",

it("correctly parses an empty config.customBounds", () => {
const output = parsers.parseAvailabilityViewerOptions({
const output = parseAvailabilityViewerOptions({
element_token: "TOKEN",

@@ -449,2 +433,40 @@ target_id: "TARGET",

it("correctly parses default config.slotSelection", () => {
const defaultOutput = parseAvailabilityViewerOptions({
element_token: "TOKEN",
target_id: "TARGET",
config: { slot_selection: "availability" },
availability_query: "QUERY_OBJECT"
});
expect(defaultOutput.config.slot_selection).toEqual("availability");
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly parses empty config.slotSelection", () => {
const withoutSelection = parseAvailabilityViewerOptions({
element_token: "TOKEN",
target_id: "TARGET",
availability_query: "QUERY_OBJECT"
});
expect(withoutSelection.config.slot_selection).toEqual("available");
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly parses config.slotSelection", () => {
const withSelection = parseAvailabilityViewerOptions({
element_token: "TOKEN",
target_id: "TARGET",
config: { slot_selection: "restricted" },
availability_query: "QUERY_OBJECT"
});
expect(withSelection.config.slot_selection).toEqual("restricted");
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly parses tzid option", () => {

@@ -458,3 +480,3 @@ const input = {

};
const result = parsers.parseAvailabilityViewerOptions(input);
const result = parseAvailabilityViewerOptions(input);

@@ -472,3 +494,3 @@ expect(result.customtzid).toEqual(true);

};
const result = parsers.parseAvailabilityViewerOptions(input);
const result = parseAvailabilityViewerOptions(input);

@@ -502,5 +524,3 @@ expect(result.customtzid).toEqual(false);

};
expect(parsers.parseAvailabilityRulesOptions(input)).toEqual(
expectedOutput
);
expect(parseAvailabilityRulesOptions(input)).toEqual(expectedOutput);
expect(console.error).toHaveBeenCalledTimes(0);

@@ -527,5 +547,3 @@ expect(console.warn).toHaveBeenCalledTimes(0);

};
expect(parsers.parseAvailabilityRulesOptions(input)).toEqual(
expectedOutput
);
expect(parseAvailabilityRulesOptions(input)).toEqual(expectedOutput);
expect(console.error).toHaveBeenCalledTimes(0);

@@ -536,3 +554,3 @@ expect(console.warn).toHaveBeenCalledTimes(1);

it("fails if there is no token declared", () => {
expect(parsers.parseAvailabilityRulesOptions()).toEqual(false);
expect(parseAvailabilityRulesOptions()).toEqual(false);
expect(console.error).toHaveBeenCalledTimes(1);

@@ -556,3 +574,3 @@ });

expect(
parsers.parseAvailabilityRulesOptions({
parseAvailabilityRulesOptions({
demo: true,

@@ -581,3 +599,3 @@ availability_rule_id: "RULE_ID",

expect(
parsers.parseAvailabilityRulesOptions({
parseAvailabilityRulesOptions({
element_token: "TOKEN",

@@ -606,3 +624,3 @@ availability_rule_id: "RULE_ID",

expect(
parsers.parseAvailabilityRulesOptions({
parseAvailabilityRulesOptions({
availability_rule_id: "RULE_ID",

@@ -633,3 +651,3 @@ element_token: "TOKEN",

expect(
parsers.parseAvailabilityRulesOptions({
parseAvailabilityRulesOptions({
availability_rule_id: "RULE_ID",

@@ -648,3 +666,3 @@ data_center: "de",

describe("Parsing CalendarSync options", () => {
it("works when all options are declared", () => {
it("works when all required options are declared", () => {
const input = {

@@ -675,3 +693,9 @@ authorization: {

};
expect(parsers.parseCalendarSyncOptions(input)).toEqual(expectedOutput);
const output = parseCalendarSyncOptions(input);
expect(output.authorization).toEqual(expectedOutput.authorization);
expect(output.domains).toEqual(expectedOutput.domains);
expect(output.error).toEqual(false);
expect(output.target).toEqual("TARGET");
expect(output.token).toEqual("TOKEN");
expect(console.error).toHaveBeenCalledTimes(0);

@@ -696,12 +720,17 @@ expect(console.warn).toHaveBeenCalledTimes(0);

};
expect(
parsers.parseCalendarSyncOptions({
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
target_id: "TARGET"
})
).toEqual(expectedOutput);
const output = parseCalendarSyncOptions({
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
target_id: "TARGET"
});
expect(output.authorization).toEqual(expectedOutput.authorization);
expect(output.domains).toEqual(expectedOutput.domains);
expect(output.error).toEqual(false);
expect(output.target).toEqual("TARGET");
expect(output.token).toEqual(false);
expect(console.error).toHaveBeenCalledTimes(0);

@@ -713,3 +742,3 @@ expect(console.warn).toHaveBeenCalledTimes(0);

expect(
parsers.parseCalendarSyncOptions({
parseCalendarSyncOptions({
target: "TARGET",

@@ -724,3 +753,3 @@ token: "TOKEN"

expect(
parsers.parseCalendarSyncOptions({
parseCalendarSyncOptions({
target: "TARGET",

@@ -739,3 +768,3 @@ token: "TOKEN",

expect(
parsers.parseCalendarSyncOptions({
parseCalendarSyncOptions({
target: "TARGET",

@@ -754,3 +783,3 @@ token: "TOKEN",

expect(
parsers.parseCalendarSyncOptions({
parseCalendarSyncOptions({
authorization: {

@@ -768,22 +797,13 @@ redirect_uri: "REDIRECT_URI",

it("continues if there is no token declared, but we're in demo mode", () => {
const expectedOutput = {
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
demo: true,
error: false,
domains: {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
},
target: "cronofy-element-calendar-sync",
token: false
const expectedAuthorization = {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
};
expect(
parsers.parseCalendarSyncOptions({
demo: true
})
).toEqual(expectedOutput);
const output = parseCalendarSyncOptions({
demo: true
});
expect(output.authorization).toEqual(expectedAuthorization);
expect(output.demo).toEqual(true);
expect(console.warn).toHaveBeenCalledTimes(2);

@@ -794,10 +814,3 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("applies the default target if there is no target option", () => {
const expectedOutput = {
domains: {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
},
error: false,
target: "cronofy-element-calendar-sync",
token: "TOKEN",
const output = parseCalendarSyncOptions({
authorization: {

@@ -807,14 +820,7 @@ redirect_uri: "REDIRECT_URI",

scope: "SCOPE"
}
};
expect(
parsers.parseCalendarSyncOptions({
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
element_token: "TOKEN"
})
).toEqual(expectedOutput);
},
element_token: "TOKEN"
});
expect(output.target).toEqual("cronofy-element-calendar-sync");
expect(console.warn).toHaveBeenCalledTimes(1);

@@ -825,8 +831,7 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("applies the default domains if there is no data_center option", () => {
const expectedOutput = {
domains: {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
},
error: false,
const expectedDomains = {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
};
const output = parseCalendarSyncOptions({
authorization: {

@@ -837,16 +842,7 @@ redirect_uri: "REDIRECT_URI",

},
target: "TARGET",
token: "TOKEN"
};
expect(
parsers.parseCalendarSyncOptions({
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
element_token: "TOKEN",
target_id: "TARGET"
})
).toEqual(expectedOutput);
element_token: "TOKEN",
target_id: "TARGET"
});
expect(output.domains).toEqual(expectedDomains);
expect(console.warn).toHaveBeenCalledTimes(0);

@@ -857,9 +853,41 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("creates correct domains if there is a data_center option", () => {
const expectedOutput = {
const expectedDomains = {
apiDomain: "https://api-de.cronofy.com",
appDomain: "https://app-de.cronofy.com"
};
const output = parseCalendarSyncOptions({
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
data_center: "de",
domains: {
apiDomain: "https://api-de.cronofy.com",
appDomain: "https://app-de.cronofy.com"
element_token: "TOKEN",
target_id: "TARGET"
});
expect(output.domains).toEqual(expectedDomains);
expect(output.data_center).toEqual("de");
expect(output.error).toEqual(false);
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly parses singleProfile option", () => {
const output = parseCalendarSyncOptions({
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
error: false,
single_profile: true,
element_token: "TOKEN",
target_id: "TARGET"
});
expect(output.single_profile).toEqual(true);
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly applies default for singleProfile option", () => {
const output = parseCalendarSyncOptions({
authorization: {

@@ -870,17 +898,6 @@ redirect_uri: "REDIRECT_URI",

},
target: "TARGET",
token: "TOKEN"
};
expect(
parsers.parseCalendarSyncOptions({
authorization: {
redirect_uri: "REDIRECT_URI",
client_id: "CLIENT_ID",
scope: "SCOPE"
},
data_center: "de",
element_token: "TOKEN",
target_id: "TARGET"
})
).toEqual(expectedOutput);
element_token: "TOKEN",
target_id: "TARGET"
});
expect(output.single_profile).toEqual(false);
expect(console.warn).toHaveBeenCalledTimes(0);

@@ -887,0 +904,0 @@ expect(console.error).toHaveBeenCalledTimes(0);

@@ -310,2 +310,38 @@ import * as utils from "../src/js/helpers/utils.AvailabilityViewer";

it("correctly crops non-overlapping periods", () => {
const input = {
...query,
available_periods: [
{ start: "2020-11-09T07:00:00Z", end: "2020-11-09T12:00:00Z" },
{ start: "2020-11-10T12:00:00Z", end: "2020-11-10T14:00:00Z" },
{ start: "2020-11-11T16:00:00Z", end: "2020-11-11T13:00:00Z" }
]
};
const offsetCropExtent = {
...cropExtent,
startTime: "15:00",
endTime: "17:00"
};
expect(
utils.cropQuery(input, offsetCropExtent).available_periods
).toEqual([]);
});
it("correctly crops non-overlapping but abutting periods", () => {
const input = {
...query,
available_periods: [
{ start: "2020-11-09T07:00:00Z", end: "2020-11-09T15:00:00Z" }
]
};
const offsetCropExtent = {
...cropExtent,
startTime: "15:00",
endTime: "17:00"
};
expect(
utils.cropQuery(input, offsetCropExtent).available_periods
).toEqual([]);
});
// periodOverlap

@@ -604,2 +640,117 @@ it("correctly detects overlaps", () => {

});
it("checks visibility status", () => {
const emptySlots = [
{
day: "2019-09-29",
slots: [
{
start: "2019-09-29T09:00:00Z",
end: "2019-09-29T09:15:00Z"
},
{
start: "2019-09-29T09:15:00Z",
end: "2019-09-29T09:30:00Z"
},
{
start: "2019-09-29T09:30:00Z",
end: "2019-09-29T09:45:00Z"
},
{
start: "2019-09-29T09:45:00Z",
end: "2019-09-29T10:00:00Z"
}
]
}
];
const availablePeriods = {
"2019-09-29T09:30:00Z": {
start: "2019-09-29T09:30:00Z",
end: "2019-09-29T10:30:00Z",
participants: ["PARTICIPANT_1", "PARTICIPANT_2"]
},
"2019-09-29T09:45:00Z": {
start: "2019-09-29T09:45:00Z",
end: "2019-09-29T10:45:00Z",
participants: ["PARTICIPANT_1", "PARTICIPANT_2"]
},
"2019-09-29T10:00:00Z": {
start: "2019-09-29T10:00:00Z",
end: "2019-09-29T11:00:00Z",
participants: ["PARTICIPANT_1", "PARTICIPANT_2"]
}
};
const input = [emptySlots, availablePeriods, 60, 15, false];
const checkedSlots = utils.checkWeekdaysSlotAvailability(...input);
expect(checkedSlots[0].day).toEqual("2019-09-29");
expect(checkedSlots[0].slots.length).toEqual(4);
expect(checkedSlots[0].slots[0].available).toEqual(false);
expect(checkedSlots[0].slots[1].available).toEqual(false);
expect(checkedSlots[0].slots[2].available).toEqual(true);
expect(checkedSlots[0].slots[3].available).toEqual(true);
});
it("checks visibility status with overlap", () => {
const emptySlots = [
{
day: "2019-09-29",
slots: [
{
start: "2019-09-29T09:00:00Z",
end: "2019-09-29T09:15:00Z"
},
{
start: "2019-09-29T09:15:00Z",
end: "2019-09-29T09:30:00Z"
},
{
start: "2019-09-29T09:30:00Z",
end: "2019-09-29T09:45:00Z"
},
{
start: "2019-09-29T09:45:00Z",
end: "2019-09-29T10:00:00Z"
},
{
start: "2019-09-29T10:00:00Z",
end: "2019-09-29T10:15:00Z"
},
{
start: "2019-09-29T10:15:00Z",
end: "2019-09-29T10:30:00Z"
},
{
start: "2019-09-29T10:30:00Z",
end: "2019-09-29T10:45:00Z"
},
{
start: "2019-09-29T10:45:00Z",
end: "2019-09-29T11:00:00Z"
}
]
}
];
const availablePeriods = {
"2019-09-29T09:30:00Z": {
start: "2019-09-29T09:30:00Z",
end: "2019-09-29T10:30:00Z",
participants: ["PARTICIPANT_1", "PARTICIPANT_2"]
}
};
const input = [emptySlots, availablePeriods, 60, 15, false];
const checkedSlots = utils.checkWeekdaysSlotAvailability(...input);
expect(checkedSlots[0].day).toEqual("2019-09-29");
expect(checkedSlots[0].slots.length).toEqual(8);
expect(checkedSlots[0].slots[1].available).toEqual(false);
expect(checkedSlots[0].slots[2].available).toEqual(true);
expect(checkedSlots[0].slots[3].available).toEqual(false);
expect(checkedSlots[0].slots[2].target).toEqual(false);
expect(checkedSlots[0].slots[3].target).toEqual("2019-09-29T09:30:00Z");
expect(checkedSlots[0].slots[3].targetOffset).toEqual(3);
expect(checkedSlots[0].slots[4].target).toEqual("2019-09-29T09:30:00Z");
expect(checkedSlots[0].slots[4].targetOffset).toEqual(2);
expect(checkedSlots[0].slots[5].target).toEqual("2019-09-29T09:30:00Z");
expect(checkedSlots[0].slots[5].targetOffset).toEqual(1);
expect(checkedSlots[0].slots[6].target).toEqual(false);
});
});

@@ -31,2 +31,18 @@ import React from "react";

it("builds a valid provider authorization URL in singleProfile mode", () => {
const input = {
authOptions: {
option_1: "REDIRECT_URI",
option_2: "CLIENT_ID",
option_3: "SCOPE"
},
provider: "PROVIDER",
appDomain: "http://local.cronofy.com",
singleProfile: true
};
const result =
"http://local.cronofy.com/oauth/authorize?response_type=code&provider_name=PROVIDER&avoid_linking=true&option_1=REDIRECT_URI&option_2=CLIENT_ID&option_3=SCOPE";
expect(utils.buildAuthUrl(input)).toEqual(result);
});
it("builds a valid provider authorization URL without options", () => {

@@ -55,2 +71,3 @@ const input = {

"https://app.cronofy.com",
false,
buildAuthUrl

@@ -82,2 +99,3 @@ ];

false,
false,
buildProviderData

@@ -84,0 +102,0 @@ ];

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc