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.3.6 to 1.4.1

build/CronofyElements.v1.4.0.js

2

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

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

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

mode: options.config.mode,
boundsControl: options.config.boundsControl,
maxSelection: options.config.max_selection_count

@@ -185,3 +186,3 @@ ? parseInt(options.config.max_selection_count)

}
}, [weeks]);
}, [limits, weeks]);

@@ -195,2 +196,10 @@ useEffect(() => {

setTheme({ ...theme, slotHeightCalc });
if (!objectIsEmpty(rawData)) {
setStatus({
...status,
error: false,
loading: false,
preloading: true
});
}
}, [limits]);

@@ -203,3 +212,4 @@

limits,
weeks
weeks,
tzid: status.tzid
});

@@ -215,3 +225,3 @@ setSlotData(slots.slots);

<SlotsContext.Provider value={slotsForWeek}>
<LimitsContext.Provider value={limits}>
<LimitsContext.Provider value={[limits, setLimits]}>
<Container

@@ -218,0 +228,0 @@ height={"auto"}

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

import React, { useContext } from "react";
import React, { useContext, useState } from "react";
import moment from "moment-timezone";

@@ -7,4 +7,7 @@ import { css } from "react-emotion";

import { LabelsContext } from "./WeekWrapper";
import TimeSelector from "./TimeSelector";
import TimeSelectorTrigger from "./TimeSelectorTrigger";
const LabelColumn = () => {
const [selectionVisibility, setSelectionVisibility] = useState(false);
const [status, setStatus] = useContext(StatusContext);

@@ -16,2 +19,6 @@ const [theme, setTheme] = useContext(ThemeContext);

const handleCalendarSelection = () => {
setSelectionVisibility(!selectionVisibility);
};
const labelsOutput = labels.map(label => {

@@ -43,4 +50,4 @@ let labelText = null;

>
{moment
.tz(label.start, "YYYY-MM-DDTHH:mm:00Z", status.tzid)
{moment(label.start, "YYYY-MM-DDTHH:mm:00Z")
.tz(status.tzid)
.format("LT")

@@ -71,2 +78,4 @@ .replace(" ", "")}

flex-shrink: 0;
position: relative;
z-index: 2;
@media (max-width: 650px) {

@@ -77,2 +86,4 @@ position: absolute;

z-index: 4;
user-select: none;
pointer-events: none;
}

@@ -82,2 +93,10 @@ `}

>
{selectionVisibility ? (
<TimeSelector done={handleCalendarSelection} />
) : null}
{status.boundsControl ? (
<TimeSelectorTrigger
handleCalendarSelection={handleCalendarSelection}
/>
) : null}
{labelsOutput}

@@ -84,0 +103,0 @@ </div>

@@ -32,4 +32,4 @@ import React, { useState, useContext, useEffect } from "react";

const [timeDisplay, setTimeDisplay] = useState(
`${moment
.tz(slot.start, "YYYY-MM-DDTTHH:mm:00Z", status.tzid)
`${moment(slot.start, "YYYY-MM-DDTTHH:mm:00Z")
.tz(status.tzid)
.format("LT")

@@ -42,5 +42,4 @@ .replace(" ", "")} - ${moment

useEffect(() => {
const updateSlotData = () => {
const hoverTopPosition = hoverButton.current.offsetTop;
if (slot.visiblyAvailable && slot.target) {

@@ -66,22 +65,53 @@ // If the slot is "overlapped" by an available slot

});
// Update the time display if we're selecting an
// overlapping slot.
setTimeDisplay(
`${moment
.tz(targetSlot.start, "YYYY-MM-DDTTHH:mm:00Z", status.tzid)
.format("LT")
.replace(" ", "")} - ${moment
.tz(targetSlot.end, "YYYY-MM-DDTTHH:mm:00Z", status.tzid)
.format("LT")
.replace(" ", "")}`
);
} else {
setSlotData({
...slotData,
slot: {
start: slot.start,
end: slot.end,
participants: slot.participants
},
position: { y: hoverTopPosition, x: columnCount }
});
}
};
useEffect(() => {
updateSlotData();
}, [slot]);
useEffect(() => {
updateSlotData();
}, []);
useEffect(() => {
setTimeDisplay(
`${moment(slotData.slot.start, "YYYY-MM-DDTTHH:mm:00Z")
.tz(status.tzid)
.format("LT")
.replace(" ", "")} - ${moment(
slotData.slot.end,
"YYYY-MM-DDTTHH:mm:00Z"
)
.tz(status.tzid)
.format("LT")
.replace(" ", "")}`
);
}, [slotData]);
const handleHover = () => {
const availibility =
slot.visiblyAvailable && slot.target ? true : slot.available;
setHover({
times: timeDisplay,
position: slotData.position,
visible: true,
topSlot,
available: availibility,
helicopterMode: false,
hideTooltip: slot.blocked
});
};
const overSelectionLimit =

@@ -92,7 +122,7 @@ typeof status.maxSelection === "number"

const handleSelect = event => {
const handleSelect = () => {
if (overSelectionLimit || slot.blocked) {
return;
}
handleHover(event, timeDisplay);
handleHover();

@@ -143,17 +173,2 @@ if (slot.available || (slot.visiblyAvailable && slot.target)) {

const handleHover = () => {
const availibility =
slot.visiblyAvailable && slot.target ? true : slot.available;
setHover({
times: timeDisplay,
position: slotData.position,
visible: true,
topSlot,
available: availibility,
helicopterMode: false,
hideTooltip: slot.blocked
});
};
const handleLiveHover = () => {

@@ -160,0 +175,0 @@ // If we setState on MouseMove for slots, the fans on a 2019 🍏 MBP will start to

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

const Week = () => {
const limits = useContext(LimitsContext);
const [limits, setLimits] = useContext(LimitsContext);
const [slotData, setSlotData] = useContext(MasterSlotsContext);

@@ -124,2 +124,5 @@ const slots = useContext(SlotsContext);

}, [slots]);
useEffect(() => {
setSelectedSlots({});
}, [limits]);

@@ -146,2 +149,3 @@ const size = useWindowSize();

position: relative;
z-index: 1;
`}

@@ -148,0 +152,0 @@ >

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

const slots = useContext(SlotsContext);
const limits = useContext(LimitsContext);
const [limits, setLimits] = useContext(LimitsContext);

@@ -25,0 +25,0 @@ const [labels, setLabels] = useState(timeLabels(limits, slots[0].day));

@@ -207,3 +207,3 @@ export const parseConnectionDomains = (

let mode =
const mode =
typeof config.mode === "undefined" || config.mode === "default"

@@ -213,4 +213,10 @@ ? "confirm"

config = { ...config, mode };
const boundsControl =
typeof config.bounds_control === "undefined" ||
config.bounds_control === "default"
? false
: true;
config = { ...config, mode, boundsControl };
const domains = parseConnectionDomains(

@@ -225,2 +231,3 @@ options.data_center,

delete options.target_id;
delete config.bounds_control;

@@ -227,0 +234,0 @@ return { ...options, error, target, token, domains, config, query };

@@ -234,7 +234,8 @@ const moment = require("moment-timezone");

// end day to account for this.
const endDay = isEndBeforeStart
? moment(day, "YYYY-MM-DD")
.add(1, "days")
.format("YYYY-MM-DD")
: day;
const endDay =
isEndBeforeStart || limits.start === limits.end
? moment(day, "YYYY-MM-DD")
.add(1, "days")
.format("YYYY-MM-DD")
: day;

@@ -348,1 +349,14 @@ const timeLabelPeriod = {

};
export const convertUTCToLocal = (timeString, tzid) => {
const utcOffset = moment.tz(tzid).utcOffset();
const invertedOffset =
Math.sign(utcOffset) === -1 ? Math.abs(utcOffset) : 0 - utcOffset;
const offset = invertedOffset / 60;
const time = `${moment().format("YYYY-MM-DD")}T${timeString}:00Z`;
const adjusted = moment(time).subtract(offset, "hours");
const formatted = adjusted.utc().format("HH:mm");
return formatted;
};

@@ -1,3 +0,3 @@

import moment from "moment";
import { createEmptySlotsForPeriod } from "./slots";
import moment from "moment-timezone";
import { createEmptySlotsForPeriod, convertUTCToLocal } from "./slots";
import { objectToArray } from "./utils";

@@ -57,22 +57,22 @@

export const buildDayPeriod = (startTime, endTime, day) => {
// If the endTime is an earlier hour than the startTime, that means
// the period overflows a day boundary.
const isEndBeforeStart = parseInt(startTime, 10) > parseInt(endTime, 10);
export const buildDayPeriod = (startTime, endTime, day, tzid) => {
const localStart = `${day}T${convertUTCToLocal(startTime, tzid)}`;
const localEnd = `${day}T${convertUTCToLocal(endTime, tzid)}`;
const UTCStart = moment(localStart, "YYYY-MM-DDTHH:mm").utc();
const UTCEnd = moment(localEnd, "YYYY-MM-DDTHH:mm").utc();
// If the end does overflow a day boundary, we need to increment the
// end day to account for this.
const endDay = isEndBeforeStart
? moment(day, "YYYY-MM-DD")
.add(1, "days")
.format("YYYY-MM-DD")
: day;
const is24Hours = startTime === endTime;
if (is24Hours) {
UTCEnd.add(1, "days");
}
const start = moment
.utc(`${day}T${startTime}`, "YYYY-MM-DDTHH:mm")
.format(`YYYY-MM-DDTHH:mm[:00Z]`);
// An end-time of midnight will always be at the *end* of our
// target day (a.k.a. the very start of the following day)
const localMidnight = moment(`${day}T00:00`, "YYYY-MM-DDTHH:mm");
if (UTCEnd.diff(localMidnight, "minutes") === 0) {
UTCEnd.add(1, "days");
}
const end = moment
.utc(`${endDay}T${endTime}`, "YYYY-MM-DDTHH:mm")
.format(`YYYY-MM-DDTHH:mm[:00Z]`);
const start = UTCStart.format("YYYY-MM-DDTHH:mm[:00Z]");
const end = UTCEnd.format("YYYY-MM-DDTHH:mm[:00Z]");

@@ -143,4 +143,3 @@ return {

duration,
interval,
endTime
interval
) => {

@@ -190,3 +189,3 @@ const intervalsPerSlot = duration / interval;

const targetEndTime = moment(
`${day.day}T${endTime}:00`,
elementEndTime,
"YYYY-MM-DDTHH:mm:00Z"

@@ -282,3 +281,3 @@ );

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

@@ -288,3 +287,3 @@ buildPeriod = buildDayPeriod

const weekdaysEmpties = weeks.days.reduce((acc, day) => {
const dayPeriod = buildPeriod(limits.start, limits.end, day);
const dayPeriod = buildPeriod(limits.start, limits.end, day, tzid);
acc.push({

@@ -301,4 +300,3 @@ day: day,

limits.duration,
limits.interval,
limits.end
limits.interval
);

@@ -426,2 +424,3 @@

);
const endTimeRaw = moment.utc(

@@ -436,5 +435,6 @@ `${day}T${extent.endTime}:00Z`,

const endTime = isEndBeforeStart
? endTimeRaw.add(1, "days")
: endTimeRaw;
const endTime =
isEndBeforeStart || extent.startTime === extent.endTime
? endTimeRaw.add(1, "days")
: endTimeRaw;

@@ -441,0 +441,0 @@ return {

@@ -5,5 +5,7 @@ {

"confirm": "Confirm",
"end": "End",
"no_slots_found": "No slots found",
"start": "Start",
"unavailable": "Unavailable"
}
}

@@ -224,6 +224,9 @@ import * as parsers from "../src/js/helpers/init";

const input = {
availability_query: "QUERY_OBJECT",
config: {
bounds_control: true
},
data_center: "DATA_CENTER",
availability_query: "QUERY_OBJECT",
element_token: "TOKEN",
target_id: "TARGET",
element_token: "TOKEN",
tzid: "CUSTOM_TIME_ZONE"

@@ -233,2 +236,3 @@ };

config: {
boundsControl: true,
mode: "confirm"

@@ -255,26 +259,15 @@ },

it("returns an error option if there is no query present when all options are declared", () => {
it("returns an error option if there is no query present when all other required options are declared", () => {
const input = {
element_token: "TOKEN",
target_id: "TARGET",
element_token: "TOKEN",
tzid: "CUSTOM_TIME_ZONE"
};
const expectedOutput = {
config: {
mode: "confirm"
},
customtzid: true,
domains: {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
},
error: true,
query: false,
target: "TARGET",
token: "TOKEN",
tzid: "CUSTOM_TIME_ZONE"
};
expect(parsers.parseAvailabilityViewerOptions(input)).toEqual(
expectedOutput
);
const output = parsers.parseAvailabilityViewerOptions(input);
expect(output.config.query).toBe(undefined);
expect(output.token).toEqual("TOKEN");
expect(output.target).toEqual("TARGET");
expect(output.tzid).toEqual("CUSTOM_TIME_ZONE");
expect(console.error).toHaveBeenCalledTimes(1);

@@ -302,12 +295,17 @@ expect(console.warn).toHaveBeenCalledTimes(0);

query: "QUERY_OBJECT",
target: "cronofy-element-availability-viewer",
target: "TARGET",
token: false,
tzid: sniffedTimezone
};
expect(
parsers.parseAvailabilityViewerOptions({
demo: true,
availability_query: "QUERY_OBJECT"
})
).toEqual(expectedOutput);
const output = parsers.parseAvailabilityViewerOptions({
demo: true,
availability_query: "QUERY_OBJECT"
});
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.token).toEqual(false);
expect(output.target).toEqual("cronofy-element-availability-viewer");
expect(output.tzid).toEqual(sniffedTimezone);
expect(console.warn).toHaveBeenCalledTimes(2);

@@ -318,23 +316,9 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("applies the default target if there is no target option", () => {
const expectedOutput = {
config: {
mode: "confirm"
},
customtzid: false,
domains: {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
},
error: false,
query: "QUERY_OBJECT",
target: "cronofy-element-availability-viewer",
token: "TOKEN",
tzid: sniffedTimezone
};
expect(
parsers.parseAvailabilityViewerOptions({
element_token: "TOKEN",
availability_query: "QUERY_OBJECT"
})
).toEqual(expectedOutput);
const output = parsers.parseAvailabilityViewerOptions({
element_token: "TOKEN",
availability_query: "QUERY_OBJECT"
});
expect(output.token).toEqual("TOKEN");
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.target).toEqual("cronofy-element-availability-viewer");
expect(console.warn).toHaveBeenCalledTimes(1);

@@ -345,24 +329,16 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("applies the default domains if there is no data_center option", () => {
const expectedOutput = {
config: {
mode: "confirm"
},
customtzid: false,
domains: {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
},
error: false,
query: "QUERY_OBJECT",
target: "TARGET",
token: "TOKEN",
tzid: sniffedTimezone
const expectedDomains = {
apiDomain: "https://api.cronofy.com",
appDomain: "https://app.cronofy.com"
};
expect(
parsers.parseAvailabilityViewerOptions({
element_token: "TOKEN",
target_id: "TARGET",
availability_query: "QUERY_OBJECT"
})
).toEqual(expectedOutput);
const output = parsers.parseAvailabilityViewerOptions({
element_token: "TOKEN",
target_id: "TARGET",
availability_query: "QUERY_OBJECT"
});
expect(output.token).toEqual("TOKEN");
expect(output.target).toEqual("TARGET");
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.domains).toEqual(expectedDomains);
expect(console.warn).toHaveBeenCalledTimes(0);

@@ -373,26 +349,17 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("creates correct domains if there is a data_center option", () => {
const expectedOutput = {
config: {
mode: "confirm"
},
customtzid: false,
const expectedDomains = {
apiDomain: "https://api-de.cronofy.com",
appDomain: "https://app-de.cronofy.com"
};
const output = parsers.parseAvailabilityViewerOptions({
data_center: "de",
domains: {
apiDomain: "https://api-de.cronofy.com",
appDomain: "https://app-de.cronofy.com"
},
error: false,
query: "QUERY_OBJECT",
target: "TARGET",
token: "TOKEN",
tzid: sniffedTimezone
};
expect(
parsers.parseAvailabilityViewerOptions({
data_center: "de",
element_token: "TOKEN",
target_id: "TARGET",
availability_query: "QUERY_OBJECT"
})
).toEqual(expectedOutput);
element_token: "TOKEN",
target_id: "TARGET",
availability_query: "QUERY_OBJECT"
});
expect(output.token).toEqual("TOKEN");
expect(output.target).toEqual("TARGET");
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.domains).toEqual(expectedDomains);
expect(console.warn).toHaveBeenCalledTimes(0);

@@ -402,28 +369,15 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("correctly parses the extras.mode", () => {
const expectedOutput = {
config: {
mode: "multi_select"
},
customtzid: false,
it("correctly parses the config.mode", () => {
const output = parsers.parseAvailabilityViewerOptions({
data_center: "de",
domains: {
apiDomain: "https://api-de.cronofy.com",
appDomain: "https://app-de.cronofy.com"
},
error: false,
query: "QUERY_OBJECT",
target: "TARGET",
token: "TOKEN",
tzid: sniffedTimezone
};
expect(
parsers.parseAvailabilityViewerOptions({
data_center: "de",
element_token: "TOKEN",
target_id: "TARGET",
config: { mode: "multi_select" },
availability_query: "QUERY_OBJECT"
})
).toEqual(expectedOutput);
element_token: "TOKEN",
target_id: "TARGET",
config: { mode: "multi_select" },
availability_query: "QUERY_OBJECT"
});
expect(output.token).toEqual("TOKEN");
expect(output.target).toEqual("TARGET");
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.config.mode).toEqual("multi_select");
expect(console.warn).toHaveBeenCalledTimes(0);

@@ -433,2 +387,49 @@ expect(console.error).toHaveBeenCalledTimes(0);

it("correctly parses an empty config.mode", () => {
const output = parsers.parseAvailabilityViewerOptions({
element_token: "TOKEN",
target_id: "TARGET",
availability_query: "QUERY_OBJECT"
});
expect(output.token).toEqual("TOKEN");
expect(output.target).toEqual("TARGET");
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.config.mode).toEqual("confirm");
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly parses the config.customBounds", () => {
const output = parsers.parseAvailabilityViewerOptions({
data_center: "de",
element_token: "TOKEN",
target_id: "TARGET",
config: { bounds_control: true },
availability_query: "QUERY_OBJECT"
});
expect(output.token).toEqual("TOKEN");
expect(output.target).toEqual("TARGET");
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.config.boundsControl).toEqual(true);
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly parses an empty config.customBounds", () => {
const output = parsers.parseAvailabilityViewerOptions({
element_token: "TOKEN",
target_id: "TARGET",
availability_query: "QUERY_OBJECT"
});
expect(output.token).toEqual("TOKEN");
expect(output.target).toEqual("TARGET");
expect(output.query).toEqual("QUERY_OBJECT");
expect(output.config.boundsControl).toEqual(false);
expect(console.warn).toHaveBeenCalledTimes(0);
expect(console.error).toHaveBeenCalledTimes(0);
});
it("correctly parses tzid option", () => {

@@ -435,0 +436,0 @@ const input = {

@@ -8,1 +8,5 @@ global.fetch = require("jest-fetch-mock");

};
global.moment = require
.requireActual("moment-timezone")
.tz.setDefault("Etc/UTC");
import * as utils from "../src/js/helpers/utils.AvailabilityViewer";
import moment from "moment";
// import moment from "moment";

@@ -459,6 +459,6 @@ describe("Utilities: AvailabilityViewer", () => {

const input = [
{ start: "2020-11-08T06:00:00Z", end: "2020-11-08T19:00:00Z" },
{ start: "2020-11-09T06:00:00Z", end: "2020-11-09T19:00:00Z" },
{ start: "2020-11-10T06:00:00Z", end: "2020-11-10T12:00:00Z" },
{ start: "2020-11-11T06:00:00Z", end: "2020-11-11T19:00:00Z" }
{ start: "2019-11-11T06:00:00Z", end: "2019-11-11T19:00:00Z" },
{ start: "2019-11-12T06:00:00Z", end: "2019-11-12T19:00:00Z" },
{ start: "2019-11-13T06:00:00Z", end: "2019-11-13T19:00:00Z" },
{ start: "2019-11-14T06:00:00Z", end: "2019-11-14T19:00:00Z" }
];

@@ -468,12 +468,13 @@ const out = {

days: [
"2020-11-08",
"2020-11-09",
"2020-11-10",
"2020-11-11",
"2020-11-12",
"2020-11-13",
"2020-11-14"
"2019-11-10",
"2019-11-11",
"2019-11-12",
"2019-11-13",
"2019-11-14",
"2019-11-15",
"2019-11-16"
],
total: 1
};
expect(moment().utcOffset()).toEqual(0);
expect(utils.generateStaticWeeks(input)).toEqual(out);

@@ -540,3 +541,3 @@ });

it("builds a day period", () => {
const input = ["09:00", "17:00", "2020-03-20"];
const input = ["09:00", "17:00", "2020-03-20", "Etc/UTC"];
const out = {

@@ -546,11 +547,15 @@ start: "2020-03-20T09:00:00Z",

};
expect(moment().utcOffset()).toEqual(0);
expect(utils.buildDayPeriod(...input)).toEqual(out);
});
it("builds a day period that overlaps midnight", () => {
const input = ["22:00", "05:00", "2020-03-20"];
moment.tz.setDefault("America/Vancouver");
const input = ["15:00", "01:00", "2020-03-20", "America/Vancouver"];
const out = {
start: "2020-03-20T22:00:00Z",
end: "2020-03-21T05:00:00Z"
start: "2020-03-20T15:00:00Z",
end: "2020-03-21T01:00:00Z"
};
expect(moment().utcOffset()).toEqual(-420);
expect(utils.buildDayPeriod(...input)).toEqual(out);
moment.tz.setDefault("Etc/UTC");
});

@@ -557,0 +562,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

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