Calendar Card: New Card (#5813)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Zack Arnett 2020-08-24 12:59:50 -05:00 committed by GitHub
parent 06a25284e8
commit dae42b1bd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 619 additions and 77 deletions

View File

@ -23,8 +23,11 @@
"license": "Apache-2.0",
"dependencies": {
"@formatjs/intl-pluralrules": "^1.5.8",
"@fullcalendar/core": "^5.0.0-beta.2",
"@fullcalendar/daygrid": "^5.0.0-beta.2",
"@fullcalendar/common": "5.1.0",
"@fullcalendar/core": "5.1.0",
"@fullcalendar/daygrid": "5.1.0",
"@fullcalendar/interaction": "5.1.0",
"@fullcalendar/list": "5.1.0",
"@material/chips": "=8.0.0-canary.096a7a066.0",
"@material/circular-progress": "=8.0.0-canary.a78ceb112.0",
"@material/mwc-button": "^0.18.0",

View File

@ -1,3 +1,4 @@
import "@material/mwc-icon-button/mwc-icon-button";
import {
customElement,
html,
@ -8,14 +9,14 @@ import {
css,
} from "lit-element";
import "./ha-icon-button";
import { fireEvent } from "../common/dom/fire_event";
import type { ToggleButton } from "../types";
import "./ha-svg-icon";
@customElement("ha-button-toggle-group")
export class HaButtonToggleGroup extends LitElement {
@property() public buttons!: ToggleButton[];
@property({ attribute: false }) public buttons!: ToggleButton[];
@property() public active?: string;
@ -23,14 +24,16 @@ export class HaButtonToggleGroup extends LitElement {
return html`
<div>
${this.buttons.map(
(button) => html` <ha-icon-button
.label=${button.label}
.icon=${button.icon}
.value=${button.value}
?active=${this.active === button.value}
@click=${this._handleClick}
>
</ha-icon-button>`
(button) => html`
<mwc-icon-button
.label=${button.label}
.value=${button.value}
?active=${this.active === button.value}
@click=${this._handleClick}
>
<ha-svg-icon .path=${button.iconPath}></ha-svg-icon>
</mwc-icon-button>
`
)}
</div>
`;
@ -48,12 +51,13 @@ export class HaButtonToggleGroup extends LitElement {
--mdc-icon-button-size: var(--button-toggle-size, 36px);
--mdc-icon-size: var(--button-toggle-icon-size, 20px);
}
ha-icon-button {
mwc-icon-button {
border: 1px solid var(--primary-color);
border-right-width: 0px;
position: relative;
cursor: pointer;
}
ha-icon-button::before {
mwc-icon-button::before {
top: 0;
left: 0;
width: 100%;
@ -65,22 +69,26 @@ export class HaButtonToggleGroup extends LitElement {
content: "";
transition: opacity 15ms linear, background-color 15ms linear;
}
ha-icon-button[active]::before {
mwc-icon-button[active]::before {
opacity: var(--mdc-icon-button-ripple-opacity, 0.12);
}
ha-icon-button:first-child {
mwc-icon-button:first-child {
border-radius: 4px 0 0 4px;
}
ha-icon-button:last-child {
mwc-icon-button:last-child {
border-radius: 0 4px 4px 0;
border-right-width: 1px;
}
mwc-icon-button:only-child {
border-radius: 4px;
border-right-width: 1px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-button-toggle-button": HaButtonToggleGroup;
"ha-button-toggle-group": HaButtonToggleGroup;
}
}

View File

@ -1,3 +1,4 @@
import "@material/mwc-button";
import {
property,
internalProperty,
@ -9,13 +10,19 @@ import {
unsafeCSS,
TemplateResult,
} from "lit-element";
import { mdiViewModule, mdiViewWeek, mdiViewDay, mdiViewAgenda } from "@mdi/js";
import { Calendar } from "@fullcalendar/core";
import type { CalendarOptions } from "@fullcalendar/core";
import dayGridPlugin from "@fullcalendar/daygrid";
import listPlugin from "@fullcalendar/list";
import interactionPlugin from "@fullcalendar/interaction";
// @ts-ignore
import fullcalendarStyle from "@fullcalendar/core/main.css";
import fullcalendarStyle from "@fullcalendar/common/main.css";
// @ts-ignore
import daygridStyle from "@fullcalendar/daygrid/main.css";
import "@material/mwc-button";
// @ts-ignore
import listStyle from "@fullcalendar/list/main.css";
import memoize from "memoize-one";
import "../../components/ha-icon-button";
import "../../components/ha-button-toggle-group";
@ -25,43 +32,56 @@ import type {
CalendarEvent,
ToggleButton,
HomeAssistant,
FullCalendarView,
} from "../../types";
import { fireEvent } from "../../common/dom/fire_event";
import { haStyle } from "../../resources/styles";
declare global {
interface HTMLElementTagNameMap {
"ha-full-calendar": HAFullCalendar;
}
interface HASSDomEvents {
"view-changed": CalendarViewChanged;
}
}
const fullCalendarConfig = {
const defaultFullCalendarConfig: CalendarOptions = {
headerToolbar: false,
plugins: [dayGridPlugin],
plugins: [dayGridPlugin, listPlugin, interactionPlugin],
initialView: "dayGridMonth",
dayMaxEventRows: true,
height: "parent",
eventDisplay: "list-item",
};
const viewButtons: ToggleButton[] = [
{ label: "Month View", value: "dayGridMonth", icon: "hass:view-module" },
{ label: "Week View", value: "dayGridWeek", icon: "hass:view-week" },
{ label: "Day View", value: "dayGridDay", icon: "hass:view-day" },
{ label: "Month View", value: "dayGridMonth", iconPath: mdiViewModule },
{ label: "Week View", value: "dayGridWeek", iconPath: mdiViewWeek },
{ label: "Day View", value: "dayGridDay", iconPath: mdiViewDay },
{ label: "List View", value: "listWeek", iconPath: mdiViewAgenda },
];
class HAFullCalendar extends LitElement {
public hass!: HomeAssistant;
@property() public events: CalendarEvent[] = [];
@property({ type: Boolean, reflect: true }) public narrow = false;
@property({ type: Boolean, reflect: true })
public narrow!: boolean;
@property({ attribute: false }) public events: CalendarEvent[] = [];
@property({ attribute: false }) public views: FullCalendarView[] = [
"dayGridMonth",
"dayGridWeek",
"dayGridDay",
];
@internalProperty() private calendar?: Calendar;
@internalProperty() private _activeView = "dayGridMonth";
@internalProperty() private _activeView: FullCalendarView = "dayGridMonth";
protected render(): TemplateResult {
const viewToggleButtons = this._viewToggleButtons(this.views);
return html`
${this.calendar
? html`
@ -96,27 +116,12 @@ class HAFullCalendar extends LitElement {
${this.calendar.view.title}
</h1>
<ha-button-toggle-group
.buttons=${viewButtons}
.buttons=${viewToggleButtons}
.active=${this._activeView}
@value-changed=${this._handleView}
></ha-button-toggle-group>
`
: html`
<div class="controls">
<mwc-button
outlined
class="today"
@click=${this._handleToday}
>${this.hass.localize(
"ui.panel.calendar.today"
)}</mwc-button
>
<ha-button-toggle-group
.buttons=${viewButtons}
.active=${this._activeView}
@value-changed=${this._handleView}
></ha-button-toggle-group>
</div>
<div class="controls">
<h1>
${this.calendar.view.title}
@ -138,6 +143,21 @@ class HAFullCalendar extends LitElement {
</ha-icon-button>
</div>
</div>
<div class="controls">
<mwc-button
outlined
class="today"
@click=${this._handleToday}
>${this.hass.localize(
"ui.panel.calendar.today"
)}</mwc-button
>
<ha-button-toggle-group
.buttons=${viewToggleButtons}
.active=${this._activeView}
@value-changed=${this._handleView}
></ha-button-toggle-group>
</div>
`}
</div>
`
@ -157,14 +177,25 @@ class HAFullCalendar extends LitElement {
this.calendar.removeAllEventSources();
this.calendar.addEventSource(this.events);
}
if (changedProps.has("views") && !this.views.includes(this._activeView)) {
this._activeView = this.views[0];
this.calendar!.changeView(this._activeView);
this._fireViewChanged();
}
}
protected firstUpdated(): void {
const config = { ...fullCalendarConfig, locale: this.hass.language };
const config: CalendarOptions = {
...defaultFullCalendarConfig,
locale: this.hass.language,
};
config.dateClick = this._handleDateClick;
config.eventClick = this._handleEventClick;
this.calendar = new Calendar(
this.shadowRoot!.getElementById("calendar")!,
// @ts-ignore
config
);
@ -172,6 +203,25 @@ class HAFullCalendar extends LitElement {
this._fireViewChanged();
}
private _handleEventClick(info): void {
if (info.view.type !== "dayGridMonth") {
return;
}
this._activeView = "dayGridDay";
this.calendar!.changeView("dayGridDay");
this.calendar!.gotoDate(info.event.startStr);
}
private _handleDateClick(info): void {
if (info.view.type !== "dayGridMonth") {
return;
}
this._activeView = "dayGridDay";
this.calendar!.changeView("dayGridDay");
this.calendar!.gotoDate(info.dateStr);
}
private _handleNext(): void {
this.calendar!.next();
this._fireViewChanged();
@ -201,14 +251,21 @@ class HAFullCalendar extends LitElement {
});
}
private _viewToggleButtons = memoize((views) =>
viewButtons.filter((button) =>
views.includes(button.value as FullCalendarView)
)
);
static get styles(): CSSResult[] {
return [
haStyle,
css`
${unsafeCSS(fullcalendarStyle)}
${unsafeCSS(daygridStyle)}
:host {
${unsafeCSS(listStyle)}
:host {
display: flex;
flex-direction: column;
--fc-theme-standard-border-color: var(--divider-color);
@ -262,6 +319,15 @@ class HAFullCalendar extends LitElement {
#calendar {
flex-grow: 1;
background-color: var(--card-background-color);
min-height: 400px;
--fc-neutral-bg-color: var(--card-background-color);
--fc-list-event-hover-bg-color: var(--card-background-color);
--fc-theme-standard-border-color: var(--divider-color);
--fc-border-color: var(--divider-color);
}
a {
color: inherit !important;
}
.fc-theme-standard .fc-scrollgrid {
@ -273,15 +339,20 @@ class HAFullCalendar extends LitElement {
}
th.fc-col-header-cell.fc-day {
color: #70757a;
color: var(--secondary-text-color);
font-size: 11px;
font-weight: 400;
text-transform: uppercase;
}
.fc-daygrid-dot-event:hover {
background-color: inherit
}
.fc-daygrid-day-top {
text-align: center;
padding-top: 8px;
padding-top: 5px;
justify-content: center;
}
table.fc-scrollgrid-sync-table
@ -296,13 +367,21 @@ class HAFullCalendar extends LitElement {
font-size: 12px;
}
td.fc-day-today {
.fc .fc-daygrid-day-number {
padding: 3px !important;
}
.fc .fc-daygrid-day.fc-day-today {
background: inherit;
}
td.fc-day-today .fc-daygrid-day-top {
padding-top: 4px;
}
td.fc-day-today .fc-daygrid-day-number {
height: 24px;
color: var(--text-primary-color);
color: var(--text-primary-color) !important;
background-color: var(--primary-color);
border-radius: 50%;
display: inline-block;
@ -342,6 +421,66 @@ class HAFullCalendar extends LitElement {
.fc-popover-header {
background-color: var(--secondary-background-color) !important;
}
.fc-theme-standard .fc-list-day-frame {
background-color: transparent;
}
.fc-list.fc-view,
.fc-list-event.fc-event td {
border: none;
}
.fc-list-day.fc-day th {
border-bottom: none;
border-top: 1px solid var(--fc-theme-standard-border-color, #ddd) !important;
}
.fc-list-day-text {
font-size: 16px;
font-weight: 400;
}
.fc-list-day-side-text {
font-weight: 400;
font-size: 16px;
color: var(--primary-color);
}
.fc-list-table td,
.fc-list-day-frame {
padding-top: 12px;
padding-bottom: 12px;
}
:host([narrow]) .fc-dayGridMonth-view
.fc-daygrid-dot-event
.fc-event-time,
:host([narrow]) .fc-dayGridMonth-view
.fc-daygrid-dot-event
.fc-event-title,
:host([narrow]) .fc-dayGridMonth-view .fc-daygrid-day-bottom {
display: none;
}
:host([narrow]) .fc .fc-dayGridMonth-view .fc-daygrid-event-harness-abs {
visibility: visible !important;
position: static;
}
:host([narrow]) .fc-dayGridMonth-view .fc-daygrid-day-events {
display: flex;
min-height: 2em !important;
justify-content: center;
flex-wrap: wrap;
max-height: 2em;
height: 2em;
overflow: hidden;
}
:host([narrow]) .fc-dayGridMonth-view .fc-scrollgrid-sync-table {
overflow: hidden;
}
`,
];
}

View File

@ -53,12 +53,6 @@ class PanelCalendar extends LitElement {
selected: true,
calendar,
}));
if (!this._start || !this._end) {
return;
}
this._fetchEvents(this._start, this._end, this._selectedCalendars);
}
protected render(): TemplateResult {
@ -88,8 +82,8 @@ class PanelCalendar extends LitElement {
<mwc-formfield .label=${selCal.calendar.name}>
<mwc-checkbox
style=${styleMap({
"--mdc-theme-secondary":
selCal.calendar.backgroundColor,
"--mdc-theme-secondary": selCal.calendar
.backgroundColor!,
})}
.value=${selCal.calendar.entity_id}
.checked=${selCal.selected}

View File

@ -0,0 +1,213 @@
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
PropertyValues,
TemplateResult,
internalProperty,
} from "lit-element";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../calendar/ha-full-calendar";
import type {
HomeAssistant,
CalendarEvent,
Calendar,
CalendarViewChanged,
FullCalendarView,
} from "../../../types";
import type { LovelaceCard, LovelaceCardEditor } from "../types";
import type { CalendarCardConfig } from "./types";
import { findEntities } from "../common/find-entites";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import "../components/hui-warning";
import { fetchCalendarEvents } from "../../../data/calendar";
import { HASSDomEvent } from "../../../common/dom/fire_event";
import { HA_COLOR_PALETTE } from "../../../common/const";
import { debounce } from "../../../common/util/debounce";
import { installResizeObserver } from "../common/install-resize-observer";
@customElement("hui-calendar-card")
export class HuiCalendarCard extends LitElement implements LovelaceCard {
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import(
/* webpackChunkName: "hui-calendar-card-editor" */ "../editor/config-elements/hui-calendar-card-editor"
);
return document.createElement("hui-calendar-card-editor");
}
public static getStubConfig(
hass: HomeAssistant,
entities: string[],
entitiesFill: string[]
) {
const includeDomains = ["calendar"];
const maxEntities = 2;
const foundEntities = findEntities(
hass,
maxEntities,
entities,
entitiesFill,
includeDomains
);
return {
entities: foundEntities,
};
}
@property({ attribute: false }) public hass?: HomeAssistant;
@property({ attribute: false }) public _events: CalendarEvent[] = [];
@internalProperty() private _config?: CalendarCardConfig;
@internalProperty() private _calendars: Calendar[] = [];
@internalProperty() private _narrow = false;
@internalProperty() private _veryNarrow = false;
private _resizeObserver?: ResizeObserver;
public setConfig(config: CalendarCardConfig): void {
if (!config.entities) {
throw new Error("Entities must be defined");
}
if (config.entities && !Array.isArray(config.entities)) {
throw new Error("Entities need to be an array");
}
this._calendars = config!.entities.map((entity, idx) => {
return {
entity_id: entity,
backgroundColor: `#${HA_COLOR_PALETTE[idx % HA_COLOR_PALETTE.length]}`,
};
});
this._config = config;
}
public getCardSize(): number {
return 4;
}
public connectedCallback(): void {
super.connectedCallback();
this.updateComplete.then(() => this._attachObserver());
}
public disconnectedCallback(): void {
if (this._resizeObserver) {
this._resizeObserver.disconnect();
}
}
protected render(): TemplateResult {
if (!this._config || !this.hass || !this._calendars.length) {
return html``;
}
const views: FullCalendarView[] = this._veryNarrow
? ["listWeek"]
: ["listWeek", "dayGridMonth", "dayGridDay"];
return html`
<ha-card>
<div class="header">${this._config.title}</div>
<ha-full-calendar
.narrow=${this._narrow}
.events=${this._events}
.hass=${this.hass}
.views=${views}
@view-changed=${this._handleViewChanged}
></ha-full-calendar>
</ha-card>
`;
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
if (!this._config || !this.hass) {
return;
}
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
const oldConfig = changedProps.get("_config") as
| CalendarCardConfig
| undefined;
if (
!oldHass ||
!oldConfig ||
(changedProps.has("hass") && oldHass.themes !== this.hass.themes) ||
(changedProps.has("_config") && oldConfig.theme !== this._config.theme)
) {
applyThemesOnElement(this, this.hass.themes, this._config!.theme);
}
}
private async _handleViewChanged(
ev: HASSDomEvent<CalendarViewChanged>
): Promise<void> {
this._events = await fetchCalendarEvents(
this.hass!,
ev.detail.start,
ev.detail.end,
this._calendars
);
}
private _measureCard() {
const card = this.shadowRoot!.querySelector("ha-card");
if (!card) {
return;
}
this._narrow = card.offsetWidth < 870;
this._veryNarrow = card.offsetWidth < 350;
}
private async _attachObserver(): Promise<void> {
if (!this._resizeObserver) {
await installResizeObserver();
this._resizeObserver = new ResizeObserver(
debounce(() => this._measureCard(), 250, false)
);
}
const card = this.shadowRoot!.querySelector("ha-card");
// If we show an error or warning there is no ha-card
if (!card) {
return;
}
this._resizeObserver.observe(card);
}
static get styles(): CSSResult {
return css`
ha-card {
position: relative;
padding: 0 8px 8px;
}
.header {
color: var(--ha-card-header-color, --primary-text-color);
font-size: var(--ha-card-header-font-size, 24px);
line-height: 1.2;
padding-top: 16px;
padding-left: 8px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-calendar-card": HuiCalendarCard;
}
}

View File

@ -12,6 +12,12 @@ export interface AlarmPanelCardConfig extends LovelaceCardConfig {
theme?: string;
}
export interface CalendarCardConfig extends LovelaceCardConfig {
entities: string[];
title?: string;
theme?: string;
}
export interface ConditionalCardConfig extends LovelaceCardConfig {
card: LovelaceCardConfig;
conditions: Condition[];

View File

@ -1,5 +1,6 @@
import { LovelaceCardConfig } from "../../../data/lovelace";
import "../cards/hui-button-card";
import "../cards/hui-calendar-card";
import "../cards/hui-entities-card";
import "../cards/hui-entity-button-card";
import "../cards/hui-entity-card";
@ -52,6 +53,7 @@ const LAZY_LOAD_TYPES = {
map: () => import("../cards/hui-map-card"),
markdown: () => import("../cards/hui-markdown-card"),
picture: () => import("../cards/hui-picture-card"),
calendar: () => import("../cards/hui-calendar-card"),
};
// This will not return an error card but will throw the error

View File

@ -0,0 +1,133 @@
import {
customElement,
html,
LitElement,
property,
TemplateResult,
internalProperty,
} from "lit-element";
import { fireEvent } from "../../../../common/dom/fire_event";
import type { HomeAssistant } from "../../../../types";
import type { CalendarCardConfig } from "../../cards/types";
import "../../components/hui-entity-editor";
import "../../../../components/entity/ha-entities-picker";
import "../../components/hui-theme-select-editor";
import type { LovelaceCardEditor } from "../../types";
import type { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
import {
string,
optional,
object,
boolean,
array,
union,
assert,
} from "superstruct";
const cardConfigStruct = object({
type: string(),
title: optional(union([string(), boolean()])),
theme: optional(string()),
entities: array(string()),
});
@customElement("hui-calendar-card-editor")
export class HuiCalendarCardEditor extends LitElement
implements LovelaceCardEditor {
@property({ attribute: false }) public hass?: HomeAssistant;
@property({ attribute: false }) private _config?: CalendarCardConfig;
@internalProperty() private _configEntities?: string[];
public setConfig(config: CalendarCardConfig): void {
assert(config, cardConfigStruct);
this._config = config;
this._configEntities = config.entities;
}
get _title(): string {
return this._config!.title || "";
}
get _theme(): string {
return this._config!.theme || "";
}
protected render(): TemplateResult {
if (!this.hass || !this._config) {
return html``;
}
return html`
${configElementStyle}
<div class="card-config">
<div class="side-by-side">
<paper-input
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.title"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._title}
.configValue=${"title"}
@value-changed=${this._valueChanged}
></paper-input>
<hui-theme-select-editor
.hass=${this.hass}
.value=${this._theme}
.configValue=${"theme"}
@value-changed=${this._valueChanged}
></hui-theme-select-editor>
</div>
</div>
<h3>
${"Calendar Entities" +
" (" +
this.hass!.localize("ui.panel.lovelace.editor.card.config.required") +
")"}
</h3>
<ha-entities-picker
.hass=${this.hass!}
.value=${this._configEntities}
.includeDomains=${["calendar"]}
@value-changed=${this._valueChanged}
>
</ha-entities-picker>
`;
}
private _valueChanged(ev: EntitiesEditorEvent | CustomEvent): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.target! as EditorTarget;
if (this[`_${target.configValue}`] === target.value) {
return;
}
if (ev.detail && ev.detail.value && Array.isArray(ev.detail.value)) {
this._config = { ...this._config, entities: ev.detail.value };
} else if (target.configValue) {
if (target.value === "") {
delete this._config[target.configValue!];
} else {
this._config = {
...this._config,
[target.configValue]: target.value,
};
}
}
fireEvent(this, "config-changed", { config: this._config });
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-calendar-card-editor": HuiCalendarCardEditor;
}
}

View File

@ -9,6 +9,10 @@ export const coreCards: Card[] = [
type: "button",
showElement: true,
},
{
type: "calendar",
showElement: true,
},
{
type: "entities",
showElement: true,

View File

@ -2134,6 +2134,10 @@
"available_states": "Available States",
"description": "The Alarm Panel card allows you to Arm and Disarm your alarm control panel integrations."
},
"calendar": {
"name": "Calendar",
"description": "The Calendar card displays a calendar including day, week and list views"
},
"conditional": {
"name": "Conditional",
"description": "The Conditional card displays another card based on entity states.",

View File

@ -118,8 +118,8 @@ export interface Panels {
export interface Calendar {
entity_id: string;
name: string;
backgroundColor: string;
name?: string;
backgroundColor?: string;
}
export interface SelectedCalendar {
@ -144,9 +144,15 @@ export interface CalendarViewChanged {
view: string;
}
export type FullCalendarView =
| "dayGridMonth"
| "dayGridWeek"
| "dayGridDay"
| "listWeek";
export interface ToggleButton {
label?: string;
icon: string;
label: string;
iconPath: string;
value: string;
}

View File

@ -1184,20 +1184,45 @@
resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.2.5.tgz#eaafd94df3d102ee13e54e80f992a33868a6b1e8"
integrity sha512-p7gcmazKROteL4IECCp03Qrs790fZ8tbemUAjQu0+K0AaAlK49rI1SIFFq3LzDUAqXIshV95JJhRe/yXxkal5g==
"@fullcalendar/core@^5.0.0-beta.2":
version "5.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@fullcalendar/core/-/core-5.0.0-beta.2.tgz#30a9cbbbf2d6476568f53cfa1c0746d06daa9660"
integrity sha512-9U/kk8Y4ackY1XZ1PHvX8rG1olixoKveStXdDsX3FCtKATR8fA/O+4Pd5qyH7nGcih8TrgreUjZ+dB+DEaomqQ==
"@fullcalendar/common@5.1.0", "@fullcalendar/common@~5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/common/-/common-5.1.0.tgz#a45e01ebdcf00654f4d45f0457926cf2f5909820"
integrity sha512-ubwf9T0BDocGLh0AK8achrmc0siQdrp3Wn6Rmg/Ht4/WnwBtjc5gumzJ0ezG/xHE0GWG+Pz6Tm0IJF/jE7NJHw==
dependencies:
preact "^10.0.5"
tslib "^1.9.3"
tslib "^2.0.0"
"@fullcalendar/daygrid@^5.0.0-beta.2":
version "5.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@fullcalendar/daygrid/-/daygrid-5.0.0-beta.2.tgz#fae2a7cba8a6afc23c9d6faaa88150d820e59a73"
integrity sha512-Dd2VLsMPWPH1W1HQ+K1iftHVXF1MYOM/lo33FUdFKM8jc0MHnF620TVyOgPojAC26u2hApbURKIY2eY87vFulg==
"@fullcalendar/core@5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/core/-/core-5.1.0.tgz#0d9813b0564f24fe6285e31f8313d9366c6db411"
integrity sha512-C9OA9LHD1zgfcMABQ17TaxvAO/iubYFLDrgTIRCe77LatC0G36UBafthevUlMRqCR6rt5SBcw0oBt23HqSJO3A==
dependencies:
tslib "^1.9.3"
"@fullcalendar/common" "~5.1.0"
preact "^10.0.5"
tslib "^2.0.0"
"@fullcalendar/daygrid@5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/daygrid/-/daygrid-5.1.0.tgz#4f8cb30e99ff00600f064645942d21e8f668c946"
integrity sha512-zdO/EFer8wWrr+kvkMfyizPi/F7yvOCpGOb6Arz6QqyOgFl1ffNUQoRf1iQf7h2PnIEvZWZdZs+3wuMwwmhb3g==
dependencies:
"@fullcalendar/common" "~5.1.0"
tslib "^2.0.0"
"@fullcalendar/interaction@5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/interaction/-/interaction-5.1.0.tgz#0e7c6fe17bf8532de2c994bde5fc6e9220c71a89"
integrity sha512-RuCtsVFXvGYk4vYz3Aq9+G8SMOG6iX+xNJmHELdmPfAatHTVyUSCD4GznxR1/fzUu74mb98X01DVkLwSB+78oA==
dependencies:
"@fullcalendar/common" "~5.1.0"
tslib "^2.0.0"
"@fullcalendar/list@5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@fullcalendar/list/-/list-5.1.0.tgz#e08b011cce8259fdee46ef8737bf98b31e6eac1a"
integrity sha512-FDLsInaLv0H/BwpoJ4RbC69M8yoJ3xoRnkulChAzhIBrwXAKOHJth5P+iNFJVVYI7DaPgSi0BzEwiu0dJdStHQ==
dependencies:
"@fullcalendar/common" "~5.1.0"
tslib "^2.0.0"
"@gfx/zopfli@^1.0.9":
version "1.0.11"
@ -11747,6 +11772,11 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
tslib@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.0.tgz#18d13fc2dce04051e20f074cc8387fd8089ce4f3"
integrity sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==
tsutils@^3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"