@blazeo.com/appointment-client 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/blazeo.com-appointment-client-1.0.7.tgz +0 -0
  2. package/dist/calendar/blazeoCalendarRelationMethods.d.ts +4 -36
  3. package/dist/calendar/blazeoCalendarRelationMethods.js +0 -1
  4. package/dist/calendar/buildUnifiedCalendarView.d.ts +39 -0
  5. package/dist/calendar/buildUnifiedCalendarView.js +280 -0
  6. package/dist/calendar/calendarCreation.d.ts +27 -0
  7. package/dist/calendar/calendarCreation.js +167 -0
  8. package/dist/calendar/calendarCreationFacade.d.ts +4 -13
  9. package/dist/calendar/calendarCreationFacade.js +3 -5
  10. package/dist/calendar/createCalendar.d.ts +67 -37
  11. package/dist/calendar/createCalendar.js +1 -3
  12. package/dist/calendar/fetchCalendarDetails.d.ts +41 -18
  13. package/dist/calendar/fetchCalendarDetails.js +261 -51
  14. package/dist/calendar/fetchCalendarWithOpeningHours.d.ts +25 -21
  15. package/dist/calendar/fetchCalendarWithOpeningHours.js +114 -75
  16. package/dist/calendar/getAllParticipantOpeningHours.d.ts +22 -0
  17. package/dist/calendar/getAllParticipantOpeningHours.js +22 -0
  18. package/dist/calendar/getOpeningHours.d.ts +8 -0
  19. package/dist/calendar/getOpeningHours.js +9 -0
  20. package/dist/calendar/getParticipantOpeningHours.d.ts +37 -0
  21. package/dist/calendar/getParticipantOpeningHours.js +48 -0
  22. package/dist/calendar/getParticipants.d.ts +7 -0
  23. package/dist/calendar/getParticipants.js +13 -0
  24. package/dist/calendar/mapCalendarBoToBlazeoSnapshot.d.ts +9 -9
  25. package/dist/calendar/mapCalendarBoToBlazeoSnapshot.js +43 -43
  26. package/dist/calendar/mapCalendarToBlazeoSnapshot.d.ts +22 -3
  27. package/dist/calendar/mapCalendarToBlazeoSnapshot.js +0 -1
  28. package/dist/calendar/mapToDesiredResponse.d.ts +70 -0
  29. package/dist/calendar/mapToDesiredResponse.js +99 -0
  30. package/dist/config/applyBlazeoClientConfig.d.ts +2 -2
  31. package/dist/config/applyBlazeoClientConfig.js +13 -13
  32. package/dist/config/applyBlazeoDefaults.d.ts +0 -1
  33. package/dist/config/applyBlazeoDefaults.js +3 -3
  34. package/dist/config/blazeo.config.d.ts +10 -10
  35. package/dist/config/blazeo.config.js +10 -10
  36. package/dist/config/blazeoClientDefaults.d.ts +1 -2
  37. package/dist/config/blazeoClientDefaults.js +2 -3
  38. package/dist/config/ensureBlazeoHttpReady.d.ts +17 -0
  39. package/dist/config/ensureBlazeoHttpReady.js +31 -0
  40. package/dist/config/initializeAppointmentClient.d.ts +8 -28
  41. package/dist/config/initializeAppointmentClient.js +11 -24
  42. package/dist/config/syncBlazeoConnection.d.ts +6 -0
  43. package/dist/config/syncBlazeoConnection.js +18 -0
  44. package/dist/events/appointmentEventFacade.d.ts +55 -32
  45. package/dist/events/appointmentEventFacade.js +5 -10
  46. package/dist/events/mapAppointmentToEventSnapshot.d.ts +1 -4
  47. package/dist/events/mapAppointmentToEventSnapshot.js +0 -1
  48. package/dist/exampleData.d.ts +114 -10
  49. package/dist/exampleData.js +4 -5
  50. package/dist/facade/calendarCreationFacade.d.ts +39 -39
  51. package/dist/facade/calendarCreationFacade.js +95 -95
  52. package/dist/facade/mapCalendarBOToSnapshot.d.ts +9 -9
  53. package/dist/facade/mapCalendarBOToSnapshot.js +43 -43
  54. package/dist/facades/index.d.ts +11 -11
  55. package/dist/facades/index.js +11 -11
  56. package/dist/index.d.ts +26 -82
  57. package/dist/index.js +23 -33
  58. package/dist/models/CalendarRootModel.d.ts +36 -11
  59. package/dist/models/CalendarRootModel.js +22 -5
  60. package/dist/models/CalendarSlotModel.d.ts +8 -8
  61. package/dist/models/CalendarSlotModel.js +7 -7
  62. package/dist/models/EventModel.d.ts +10 -10
  63. package/dist/models/EventModel.js +9 -9
  64. package/dist/models/ParticipantModel.d.ts +8 -8
  65. package/dist/models/ParticipantModel.js +7 -7
  66. package/dist/models/index.d.ts +4 -4
  67. package/dist/models/index.js +4 -4
  68. package/dist/types/appointment.d.ts +27 -27
  69. package/dist/types/appointment.js +5 -5
  70. package/dist/types/calendar.d.ts +51 -51
  71. package/dist/types/calendar.js +5 -5
  72. package/dist/types/calendarBo.d.ts +61 -61
  73. package/dist/types/calendarBo.js +5 -5
  74. package/package.json +8 -2
  75. package/sample/.env.example +5 -0
  76. package/sample/build_error.txt +0 -0
  77. package/sample/demo.js +70 -0
  78. package/sample/package-lock.json +5 -2
  79. package/sample/package.json +3 -1
  80. package/sample/scripts/getInfoByCalendar.mjs +36 -0
  81. package/sample/scripts/getParticipantOpeningHours.mjs +48 -0
  82. package/sample/src/AllParticipantOpeningHoursTab.jsx +82 -0
  83. package/sample/src/App2.jsx +60 -3
  84. package/sample/src/AvailabilityTab.jsx +8 -3
  85. package/sample/src/BlazeoConnectionSettings.jsx +17 -16
  86. package/sample/src/CreateCalendarTab.jsx +23 -6
  87. package/sample/src/EventTab.jsx +31 -8
  88. package/sample/src/FetchCalendarTab.jsx +114 -38
  89. package/sample/src/OpeningHoursTab.jsx +87 -0
  90. package/sample/src/ParticipantInfoTab.jsx +77 -0
  91. package/sample/src/ParticipantOpeningHoursTab.jsx +98 -0
  92. package/sample/src/ParticipantTab.jsx +13 -4
  93. package/sample/src/blazeoBootstrap.js +30 -0
  94. package/sample/src/blazeoDemoError.js +14 -0
  95. package/sample/src/blazeoPushConnection.js +23 -0
  96. package/sample/src/main.jsx +3 -3
  97. package/sample/vite.config.js +19 -5
  98. package/src/calendar/blazeoCalendarRelationMethods.ts +19 -0
  99. package/src/calendar/buildUnifiedCalendarView.ts +345 -0
  100. package/src/calendar/calendarCreation.ts +179 -0
  101. package/src/calendar/createCalendar.ts +243 -0
  102. package/src/calendar/fetchCalendarDetails.ts +316 -0
  103. package/src/calendar/fetchCalendarWithOpeningHours.ts +130 -0
  104. package/src/calendar/getAllParticipantOpeningHours.ts +30 -0
  105. package/src/calendar/getOpeningHours.ts +10 -0
  106. package/src/calendar/getParticipantOpeningHours.ts +55 -0
  107. package/src/calendar/getParticipants.ts +17 -0
  108. package/src/calendar/mapCalendarToBlazeoSnapshot.ts +46 -0
  109. package/src/calendar/mapToDesiredResponse.ts +104 -0
  110. package/src/config/applyBlazeoDefaults.ts +14 -0
  111. package/src/config/blazeoClientDefaults.ts +11 -0
  112. package/src/config/ensureBlazeoHttpReady.ts +41 -0
  113. package/src/config/initializeAppointmentClient.ts +24 -0
  114. package/src/config/syncBlazeoConnection.ts +19 -0
  115. package/src/events/appointmentEventFacade.ts +148 -0
  116. package/src/events/mapAppointmentToEventSnapshot.ts +65 -0
  117. package/src/exampleData.ts +79 -0
  118. package/src/index.ts +51 -0
  119. package/src/models/CalendarRootModel.ts +60 -0
  120. package/tsconfig.json +16 -0
  121. package/blazeo.com-appointment-client-1.0.5.tgz +0 -0
@@ -0,0 +1,77 @@
1
+ import { useState } from "react";
2
+ import { CalendarParticipantModel, ensureBlazeoHttpReady } from "appointment-client";
3
+ import { configureBlazeoFromEffective, useBlazeoConnection } from "./BlazeoConnectionSettings.jsx";
4
+ import { mapBlazeoDemoError } from "./blazeoDemoError.js";
5
+
6
+ export function ParticipantInfoTab() {
7
+ const { effective, connectionOpts } = useBlazeoConnection();
8
+ const [calendarId, setCalendarId] = useState("");
9
+ const [busy, setBusy] = useState(false);
10
+ const [error, setError] = useState("");
11
+ const [output, setOutput] = useState("");
12
+
13
+ async function handleFetch(e) {
14
+ e.preventDefault();
15
+ setError("");
16
+ setOutput("");
17
+ const id = calendarId.trim();
18
+ if (!id) return setError("Enter a calendar id.");
19
+ if (!effective.baseUrl) return setError("Set Base URL in the connection card above.");
20
+
21
+ configureBlazeoFromEffective(effective);
22
+ ensureBlazeoHttpReady({
23
+ baseUrl: effective.baseUrl,
24
+ ...(effective.consumer ? { consumer: effective.consumer } : {}),
25
+ });
26
+ setBusy(true);
27
+ try {
28
+ const info = await CalendarParticipantModel.getInfoByCalendar(id);
29
+ setOutput(JSON.stringify({ calendarId: id, count: Array.isArray(info) ? info.length : 0, info }, null, 2));
30
+ } catch (err) {
31
+ setError(mapBlazeoDemoError(err instanceof Error ? err.message : String(err)));
32
+ } finally {
33
+ setBusy(false);
34
+ }
35
+ }
36
+
37
+ return (
38
+ <>
39
+ <div className="card">
40
+ <h2>Participant Info by Calendar</h2>
41
+ <p className="muted small">
42
+ Calls <code>CalendarParticipantModel.getInfoByCalendar(calendarId)</code>.
43
+ </p>
44
+ <form onSubmit={handleFetch} className="form">
45
+ <label className="form__label">
46
+ <span>Calendar id</span>
47
+ <input
48
+ type="text"
49
+ className="form__input"
50
+ value={calendarId}
51
+ onChange={(e) => setCalendarId(e.target.value)}
52
+ autoComplete="off"
53
+ />
54
+ </label>
55
+ <button type="submit" className="btn btn--secondary" disabled={busy}>
56
+ {busy ? "Loading…" : "Fetch participant info"}
57
+ </button>
58
+ </form>
59
+ </div>
60
+
61
+ {error ? (
62
+ <div className="card card--error" role="alert">
63
+ <h2>Error</h2>
64
+ <pre className="pre-block">{error}</pre>
65
+ </div>
66
+ ) : null}
67
+
68
+ {output ? (
69
+ <div className="card card--success">
70
+ <h2>Result</h2>
71
+ <pre className="pre-block">{output}</pre>
72
+ </div>
73
+ ) : null}
74
+ </>
75
+ );
76
+ }
77
+
@@ -0,0 +1,98 @@
1
+ import { useState } from "react";
2
+ import { ensureBlazeoHttpReady, getParticipantOpeningHours } from "appointment-client";
3
+ import { configureBlazeoFromEffective, useBlazeoConnection } from "./BlazeoConnectionSettings.jsx";
4
+ import { mapBlazeoDemoError } from "./blazeoDemoError.js";
5
+
6
+ export function ParticipantOpeningHoursTab() {
7
+ const { effective, connectionOpts } = useBlazeoConnection();
8
+ const [calendarId, setCalendarId] = useState("");
9
+ const [busy, setBusy] = useState(false);
10
+ const [error, setError] = useState("");
11
+ const [output, setOutput] = useState("");
12
+
13
+ async function handleFetch(e) {
14
+ e.preventDefault();
15
+ setError("");
16
+ setOutput("");
17
+ const id = calendarId.trim();
18
+ if (!id) return setError("Enter a calendar id.");
19
+ if (!effective.baseUrl) return setError("Set Base URL in the connection card above.");
20
+
21
+ configureBlazeoFromEffective(effective);
22
+ ensureBlazeoHttpReady({
23
+ baseUrl: effective.baseUrl,
24
+ ...(effective.consumer ? { consumer: effective.consumer } : {}),
25
+ });
26
+ setBusy(true);
27
+ try {
28
+ const result = await getParticipantOpeningHours(id, {
29
+ ...connectionOpts,
30
+ baseUrl: effective.baseUrl,
31
+ ...(effective.consumer ? { consumer: effective.consumer } : {}),
32
+ });
33
+
34
+ if (!result.meta.ok) {
35
+ setError(
36
+ mapBlazeoDemoError(result.meta.error || `Failed to fetch: ${result.meta.reason}`)
37
+ );
38
+ if (result.raw) setOutput(JSON.stringify(result.raw, null, 2));
39
+ return;
40
+ }
41
+
42
+ setOutput(JSON.stringify({
43
+ calendarId: id,
44
+ count: result.openingHours.length,
45
+ openingHours: result.openingHours,
46
+ raw: result.raw,
47
+ meta: result.meta
48
+ }, null, 2));
49
+ } catch (err) {
50
+ setError(mapBlazeoDemoError(err instanceof Error ? err.message : String(err)));
51
+ } finally {
52
+ setBusy(false);
53
+ }
54
+ }
55
+
56
+ return (
57
+ <>
58
+ <div className="card">
59
+ <h2>Participant Opening Hours (Direct)</h2>
60
+ <p className="muted small">
61
+ Calls <code>CalendarModel.get(calendarId)</code> then{" "}
62
+ <code>calendar.getParticipantOpeningHours(&#123;&#125;)</code> (API:{" "}
63
+ <code>GET /Calendar/Participant/OpeningHours/Get</code>).
64
+ </p>
65
+ <form onSubmit={handleFetch} className="form">
66
+ <label className="form__label">
67
+ <span>Calendar id</span>
68
+ <input
69
+ type="text"
70
+ className="form__input"
71
+ value={calendarId}
72
+ onChange={(e) => setCalendarId(e.target.value)}
73
+ autoComplete="off"
74
+ />
75
+ </label>
76
+ <button type="submit" className="btn btn--secondary" disabled={busy}>
77
+ {busy ? "Loading…" : "Fetch participant opening hours"}
78
+ </button>
79
+ </form>
80
+ </div>
81
+
82
+ {error ? (
83
+ <div className="card card--error" role="alert">
84
+ <h2>Error</h2>
85
+ <pre className="pre-block">{error}</pre>
86
+ </div>
87
+ ) : null}
88
+
89
+ {output ? (
90
+ <div className="card card--success">
91
+ <h2>Result</h2>
92
+ <pre className="pre-block">{output}</pre>
93
+ </div>
94
+ ) : null}
95
+ </>
96
+ );
97
+ }
98
+
@@ -1,10 +1,11 @@
1
1
  import { useMemo, useState } from "react";
2
- import { getExampleParticipants, ParticipantModel } from "appointment-client";
2
+ import { ensureBlazeoHttpReady, getExampleParticipants, getParticipants } from "appointment-client";
3
3
  import { getSnapshot, isStateTreeNode } from "mobx-state-tree";
4
4
  import {
5
5
  configureBlazeoFromEffective,
6
6
  useBlazeoConnection,
7
7
  } from "./BlazeoConnectionSettings.jsx";
8
+ import { mapBlazeoDemoError } from "./blazeoDemoError.js";
8
9
 
9
10
  function toDisplayJson(value) {
10
11
  if (value == null) return JSON.stringify(value, null, 2);
@@ -20,7 +21,7 @@ function toDisplayJson(value) {
20
21
  }
21
22
 
22
23
  export function ParticipantTab() {
23
- const { effective } = useBlazeoConnection();
24
+ const { effective, connectionOpts } = useBlazeoConnection();
24
25
  const example = useMemo(() => getExampleParticipants(), []);
25
26
  const [calendarId, setCalendarId] = useState("");
26
27
  const [busy, setBusy] = useState(false);
@@ -41,12 +42,20 @@ export function ParticipantTab() {
41
42
  return;
42
43
  }
43
44
  configureBlazeoFromEffective(effective);
45
+ ensureBlazeoHttpReady({
46
+ baseUrl: effective.baseUrl,
47
+ ...(effective.consumer ? { consumer: effective.consumer } : {}),
48
+ });
44
49
  setBusy(true);
45
50
  try {
46
- const res = await ParticipantModel.getAllByCalendar(id);
51
+ const res = await getParticipants(id, {
52
+ ...connectionOpts,
53
+ baseUrl: effective.baseUrl,
54
+ ...(effective.consumer ? { consumer: effective.consumer } : {}),
55
+ });
47
56
  setOutput(toDisplayJson(res));
48
57
  } catch (err) {
49
- setError(err instanceof Error ? err.message : String(err));
58
+ setError(mapBlazeoDemoError(err instanceof Error ? err.message : String(err)));
50
59
  } finally {
51
60
  setBusy(false);
52
61
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Runs once before React mounts. Order:
3
+ * 1. `blazeoClientDefaults.ts` (via applyBlazeoClientConfig) — optional file defaults
4
+ * 2. `VITE_BLAZEO_BASE_URL` / `VITE_BLAZEO_CONSUMER` — overrides when set
5
+ *
6
+ * Uses {@link pushBlazeoConnection} so calendar-client is configured the same way as the UI card.
7
+ */
8
+ import { applyBlazeoClientConfig } from "appointment-client";
9
+ import { pushBlazeoConnection } from "./blazeoPushConnection.js";
10
+
11
+ function normalizeBase(u) {
12
+ const t = (u ?? "").trim();
13
+ if (!t) return "";
14
+ return t.replace(/\/+$/, "");
15
+ }
16
+
17
+ export function bootstrapBlazeoClient() {
18
+ debugger;
19
+ applyBlazeoClientConfig();
20
+
21
+ const envBase = normalizeBase(import.meta.env.VITE_BLAZEO_BASE_URL ?? "");
22
+ const envConsumer = (import.meta.env.VITE_BLAZEO_CONSUMER ?? "").trim();
23
+
24
+ if (!envBase) return;
25
+
26
+ pushBlazeoConnection({
27
+ baseUrl: envBase,
28
+ ...(envConsumer ? { consumer: envConsumer } : {}),
29
+ });
30
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Maps low-level Blazeo / calendar-client errors to actionable copy for this sample.
3
+ */
4
+ export function mapBlazeoDemoError(message) {
5
+ const m = String(message ?? "");
6
+ if (
7
+ /Model env requires baseUrl|requires baseUrl\. Call configure|baseUrl is missing|Blazeo base URL is not set/i.test(
8
+ m
9
+ )
10
+ ) {
11
+ return "Blazeo Base URL is not set for API calls. Enter **Base URL** (and optional Consumer) in the **Blazeo connection** card at the top of this page, or set `blazeoClientConfig` / `VITE_BLAZEO_BASE_URL`.";
12
+ }
13
+ return m;
14
+ }
@@ -0,0 +1,23 @@
1
+ import { ensureBlazeoHttpReady, initializeAppointmentClient } from "appointment-client";
2
+ import { configure } from "@blazeo.com/calendar-client";
3
+
4
+ function normalizeBase(u) {
5
+ const t = (u ?? "").trim();
6
+ if (!t) return "";
7
+ return t.replace(/\/+$/, "");
8
+ }
9
+
10
+ /**
11
+ * Applies Base URL from the connection card. With Vite `resolve.alias` pointing
12
+ * `@blazeo.com/calendar-client` at one file, `configure` here matches `CalendarModel`'s store.
13
+ * `initializeAppointmentClient` + `ensureBlazeoHttpReady` keep `appointment-client` helpers aligned.
14
+ */
15
+ export function pushBlazeoConnection(effective) {
16
+ const baseUrl = normalizeBase(effective?.baseUrl ?? "");
17
+ if (!baseUrl) return;
18
+ const consumer = (effective?.consumer ?? "").trim() || undefined;
19
+ const cfg = { baseUrl, ...(consumer ? { consumer } : {}) };
20
+ initializeAppointmentClient(cfg);
21
+ configure(cfg);
22
+ ensureBlazeoHttpReady(cfg);
23
+ }
@@ -1,11 +1,11 @@
1
- import { applyBlazeoClientConfig } from "appointment-client";
2
1
  import { StrictMode } from "react";
3
2
  import { createRoot } from "react-dom/client";
4
3
  import { App } from "./App2.jsx";
4
+ import { bootstrapBlazeoClient } from "./blazeoBootstrap.js";
5
5
  import "./style.css";
6
6
 
7
- /** Apply file defaults (`blazeoClientDefaults.ts`) before React mounts. */
8
- applyBlazeoClientConfig();
7
+ /** Blazeo: `blazeoClientDefaults.ts` + optional `VITE_BLAZEO_*` (.env) `configure()` for calendar-client. */
8
+ bootstrapBlazeoClient();
9
9
 
10
10
  const rootEl = document.getElementById("app");
11
11
  if (!rootEl) {
@@ -1,10 +1,23 @@
1
1
  import react from "@vitejs/plugin-react";
2
2
  import { defineConfig, loadEnv } from "vite";
3
3
  import path from "path";
4
+ import fs from "fs";
4
5
  import { fileURLToPath } from "url";
5
6
 
6
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
8
 
9
+ /** Single physical entry for `@blazeo.com/calendar-client` (hoisted or nested under `file:..` parent). */
10
+ function calendarClientEntry() {
11
+ const candidates = [
12
+ path.resolve(__dirname, "node_modules/@blazeo.com/calendar-client/dist/index.mjs"),
13
+ path.resolve(__dirname, "../node_modules/@blazeo.com/calendar-client/dist/index.mjs"),
14
+ ];
15
+ for (const p of candidates) {
16
+ if (fs.existsSync(p)) return p;
17
+ }
18
+ return candidates[0];
19
+ }
20
+
8
21
  export default defineConfig(({ mode }) => {
9
22
  const env = loadEnv(mode, path.resolve(__dirname, "."), "");
10
23
  const proxyTarget = (env.VITE_DEV_PROXY_TARGET ?? "").trim().replace(/\/+$/, "");
@@ -26,13 +39,14 @@ export default defineConfig(({ mode }) => {
26
39
  plugins: [react()],
27
40
  /** Ensure one instance so `configure()` and models share the same store. */
28
41
  resolve: {
29
- preserveSymlinks: true,
42
+ // `file:..` appointment-client is symlinked; `true` can resolve the same dep twice → two `getConfig()` stores.
43
+ preserveSymlinks: false,
30
44
  dedupe: ["@blazeo.com/calendar-client", "mobx", "mobx-state-tree"],
31
45
  alias: {
32
- "@blazeo.com/calendar-client": path.resolve(
33
- __dirname,
34
- "../node_modules/@blazeo.com/calendar-client/dist/index.mjs"
35
- ),
46
+ // Ensure Vite/Rollup can always resolve the local workspace package.
47
+ // (Avoids `Failed to resolve import "appointment-client"` during dev/build.)
48
+ "appointment-client": path.resolve(__dirname, "../dist/index.js"),
49
+ "@blazeo.com/calendar-client": calendarClientEntry(),
36
50
  },
37
51
  },
38
52
  optimizeDeps: {
@@ -0,0 +1,19 @@
1
+ /** `GET /Calendar/Participant/Add` — attach `participantId` to this calendar. */
2
+ export function addParticipantToCalendar(calendar: any, participantId: string) {
3
+ return calendar.addParticipant(participantId);
4
+ }
5
+
6
+ /** `GET /Calendar/Participant/Remove` */
7
+ export function removeParticipantFromCalendar(calendar: any, participantId: string) {
8
+ return calendar.removeParticipant(participantId);
9
+ }
10
+
11
+ /** `POST /Calendar/Participant/Availability/OpeningHour/Save` — one day/slot. */
12
+ export function saveCalendarOpeningHour(calendar: any, payload: any) {
13
+ return calendar.saveOpeningHour(payload);
14
+ }
15
+
16
+ /** `POST /Calendar/Participant/Availability/OpeningHours/Save` — batch body (API-specific shape). */
17
+ export function saveCalendarOpeningHoursBatch(calendar: any, payload: any) {
18
+ return calendar.saveOpeningHours(payload);
19
+ }