@openmrs/esm-appointments-app 10.0.2 → 10.0.3-pre.1

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 (391) hide show
  1. package/.turbo/turbo-build.log +6 -5
  2. package/dist/1339.js +1 -0
  3. package/dist/1339.js.map +1 -0
  4. package/dist/1465.js +1 -0
  5. package/dist/1465.js.map +1 -0
  6. package/dist/1480.js +1 -0
  7. package/dist/1480.js.map +1 -0
  8. package/dist/1646.js +1 -0
  9. package/dist/1646.js.map +1 -0
  10. package/dist/1789.js +1 -0
  11. package/dist/1789.js.map +1 -0
  12. package/dist/1869.js +1 -0
  13. package/dist/1869.js.map +1 -0
  14. package/dist/1877.js +1 -0
  15. package/dist/1877.js.map +1 -0
  16. package/dist/1884.js +1 -0
  17. package/dist/1884.js.map +1 -0
  18. package/dist/1962.js +1 -0
  19. package/dist/1962.js.map +1 -0
  20. package/dist/2317.js +1 -0
  21. package/dist/2317.js.map +1 -0
  22. package/dist/2416.js +1 -0
  23. package/dist/2416.js.map +1 -0
  24. package/dist/2495.js +1 -0
  25. package/dist/2495.js.map +1 -0
  26. package/dist/2539.js +1 -0
  27. package/dist/2539.js.map +1 -0
  28. package/dist/2620.js +1 -0
  29. package/dist/2620.js.map +1 -0
  30. package/dist/2717.js +1 -0
  31. package/dist/2717.js.map +1 -0
  32. package/dist/282.js +1 -0
  33. package/dist/282.js.map +1 -0
  34. package/dist/2881.js +1 -0
  35. package/dist/2881.js.map +1 -0
  36. package/dist/3198.js +11 -0
  37. package/dist/3198.js.map +1 -0
  38. package/dist/3220.js +1 -0
  39. package/dist/3220.js.map +1 -0
  40. package/dist/3378.js +1 -0
  41. package/dist/3378.js.map +1 -0
  42. package/dist/3720.js +1 -0
  43. package/dist/3720.js.map +1 -0
  44. package/dist/3930.js +1 -0
  45. package/dist/3930.js.map +1 -0
  46. package/dist/3963.js +1 -0
  47. package/dist/3963.js.map +1 -0
  48. package/dist/3989.js +1 -0
  49. package/dist/3989.js.map +1 -0
  50. package/dist/4106.js +1 -0
  51. package/dist/4106.js.map +1 -0
  52. package/dist/4111.js +1 -0
  53. package/dist/4111.js.map +1 -0
  54. package/dist/4307.js +1 -0
  55. package/dist/4307.js.map +1 -0
  56. package/dist/434.js +1 -0
  57. package/dist/434.js.map +1 -0
  58. package/dist/4348.js +1 -0
  59. package/dist/4348.js.map +1 -0
  60. package/dist/4383.js +1 -0
  61. package/dist/4383.js.map +1 -0
  62. package/dist/4658.js +1 -0
  63. package/dist/4658.js.map +1 -0
  64. package/dist/466.js +1 -0
  65. package/dist/466.js.map +1 -0
  66. package/dist/4928.js +1 -0
  67. package/dist/4928.js.map +1 -0
  68. package/dist/5117.js +1 -0
  69. package/dist/5117.js.map +1 -0
  70. package/dist/5132.js +1 -0
  71. package/dist/5132.js.map +1 -0
  72. package/dist/5145.js +1 -0
  73. package/dist/5145.js.map +1 -0
  74. package/dist/5503.js +1 -0
  75. package/dist/5503.js.map +1 -0
  76. package/dist/556.js +1 -0
  77. package/dist/556.js.map +1 -0
  78. package/dist/5640.js +1 -0
  79. package/dist/5640.js.map +1 -0
  80. package/dist/5644.js +1 -0
  81. package/dist/5644.js.map +1 -0
  82. package/dist/5940.js +1 -0
  83. package/dist/5940.js.map +1 -0
  84. package/dist/6047.js +1 -0
  85. package/dist/6047.js.map +1 -0
  86. package/dist/6098.js +38 -0
  87. package/dist/6098.js.map +1 -0
  88. package/dist/6236.js +1 -0
  89. package/dist/6236.js.map +1 -0
  90. package/dist/635.js +1 -0
  91. package/dist/635.js.map +1 -0
  92. package/dist/6371.js +1 -0
  93. package/dist/6371.js.map +1 -0
  94. package/dist/6377.js +1 -0
  95. package/dist/6377.js.map +1 -0
  96. package/dist/6444.js +1 -0
  97. package/dist/6444.js.map +1 -0
  98. package/dist/6508.js +1 -0
  99. package/dist/6508.js.map +1 -0
  100. package/dist/6724.js +1 -0
  101. package/dist/6724.js.map +1 -0
  102. package/dist/6789.js +1 -0
  103. package/dist/6789.js.map +1 -0
  104. package/dist/689.js +1 -0
  105. package/dist/689.js.map +1 -0
  106. package/dist/6904.js +1 -0
  107. package/dist/6904.js.map +1 -0
  108. package/dist/7045.js +1 -0
  109. package/dist/7045.js.map +1 -0
  110. package/dist/7138.js +1 -0
  111. package/dist/7138.js.map +1 -0
  112. package/dist/7159.js +1 -0
  113. package/dist/7159.js.map +1 -0
  114. package/dist/7175.js +1 -0
  115. package/dist/7175.js.map +1 -0
  116. package/dist/7182.js +1 -0
  117. package/dist/7182.js.map +1 -0
  118. package/dist/7357.js +1 -0
  119. package/dist/7357.js.map +1 -0
  120. package/dist/7609.js +1 -0
  121. package/dist/7609.js.map +1 -0
  122. package/dist/7654.js +1 -0
  123. package/dist/7654.js.map +1 -0
  124. package/dist/7742.js +1 -0
  125. package/dist/7742.js.map +1 -0
  126. package/dist/7912.js +1 -0
  127. package/dist/7912.js.map +1 -0
  128. package/dist/8063.js +1 -0
  129. package/dist/8063.js.map +1 -0
  130. package/dist/8346.js +1 -0
  131. package/dist/8346.js.map +1 -0
  132. package/dist/8358.js +1 -0
  133. package/dist/8358.js.map +1 -0
  134. package/dist/8359.js +1 -0
  135. package/dist/8359.js.map +1 -0
  136. package/dist/8695.js +1 -0
  137. package/dist/8695.js.map +1 -0
  138. package/dist/8937.js +1 -0
  139. package/dist/8937.js.map +1 -0
  140. package/dist/8981.js +1 -0
  141. package/dist/8981.js.map +1 -0
  142. package/dist/903.js +1 -0
  143. package/dist/903.js.map +1 -0
  144. package/dist/9061.js +1 -0
  145. package/dist/9061.js.map +1 -0
  146. package/dist/9072.js +1 -0
  147. package/dist/9072.js.map +1 -0
  148. package/dist/9282.js +1 -0
  149. package/dist/9282.js.map +1 -0
  150. package/dist/9399.js +1 -0
  151. package/dist/9399.js.map +1 -0
  152. package/dist/9443.js +1 -0
  153. package/dist/9443.js.map +1 -0
  154. package/dist/9581.js +1 -0
  155. package/dist/9581.js.map +1 -0
  156. package/dist/9712.js +1 -0
  157. package/dist/9712.js.map +1 -0
  158. package/dist/9771.js +1 -0
  159. package/dist/9771.js.map +1 -0
  160. package/dist/9806.js +1 -0
  161. package/dist/9806.js.map +1 -0
  162. package/dist/main.js +6 -5
  163. package/dist/main.js.map +1 -1
  164. package/dist/openmrs-esm-appointments-app.js +6 -5
  165. package/dist/openmrs-esm-appointments-app.js.buildmanifest.json +625 -620
  166. package/dist/openmrs-esm-appointments-app.js.map +1 -1
  167. package/dist/routes.json +1 -1
  168. package/package.json +3 -2
  169. package/src/appointments/appointment-tabs.component.tsx +38 -16
  170. package/src/appointments/common-components/appointments-actions.component.tsx +39 -47
  171. package/src/appointments/common-components/appointments-actions.test.tsx +52 -99
  172. package/src/appointments/common-components/appointments-table.component.tsx +109 -135
  173. package/src/appointments/common-components/appointments-table.scss +10 -6
  174. package/src/appointments/common-components/appointments-table.test.tsx +2 -9
  175. package/src/appointments/common-components/batch-change-appointment-statuses.modal.tsx +1 -1
  176. package/src/appointments/common-components/batch-change-appointment-statuses.test.tsx +8 -6
  177. package/src/appointments/common-components/checkin-button.component.tsx +60 -29
  178. package/src/appointments/common-components/end-appointment.modal.tsx +1 -1
  179. package/src/appointments/common-components/end-appointment.test.tsx +1 -1
  180. package/src/appointments/scheduled/early-appointments.component.tsx +6 -7
  181. package/src/appointments/scheduled/scheduled-appointments.component.tsx +26 -206
  182. package/src/appointments/utils.tsx +29 -16
  183. package/src/appointments.component.tsx +5 -13
  184. package/src/appointments.test.tsx +16 -4
  185. package/src/calendar/appointments-calendar-view.component.tsx +3 -12
  186. package/src/calendar/appointments-calendar-view.test.tsx +6 -1
  187. package/src/calendar/header/calendar-header.component.tsx +2 -2
  188. package/src/calendar/monthly/monthly-calendar-view.component.tsx +2 -2
  189. package/src/calendar/monthly/monthly-header.component.tsx +9 -8
  190. package/src/calendar/monthly/monthly-workload-view.component.tsx +2 -2
  191. package/src/config-schema.ts +17 -9
  192. package/src/constants.ts +12 -1
  193. package/src/form/appointments-form.resource.ts +1 -120
  194. package/src/form/appointments-form.workspace.tsx +15 -18
  195. package/src/header/appointments-header.component.tsx +27 -9
  196. package/src/helpers/functions.ts +1 -50
  197. package/src/home/home-appointments.component.tsx +17 -4
  198. package/src/hooks/useActiveVisits.ts +14 -0
  199. package/src/hooks/useAppointmentList.ts +12 -29
  200. package/src/hooks/useAppointmentService.ts +6 -1
  201. package/src/hooks/useAppointmentsAppContext.ts +19 -0
  202. package/src/hooks/useAppointmentsCalendar.ts +2 -1
  203. package/src/hooks/useMutateAppointments.ts +24 -0
  204. package/src/hooks/usePatientAppointmentHistory.ts +3 -2
  205. package/src/hooks/useSelectedDate.ts +24 -0
  206. package/src/hooks/useUnscheduledAppointments.ts +5 -1
  207. package/src/index.ts +0 -21
  208. package/src/metrics/metrics-cards/highest-volume-service.extension.tsx +27 -6
  209. package/src/metrics/metrics-cards/metrics-card.component.tsx +2 -1
  210. package/src/metrics/metrics-cards/providers-booked.extension.tsx +14 -6
  211. package/src/metrics/metrics-cards/scheduled-appointments.extension.tsx +20 -16
  212. package/src/metrics/metrics-container.component.tsx +1 -5
  213. package/src/metrics/metrics-header.component.tsx +2 -2
  214. package/src/patient-appointments/patient-appointments-detailed-summary.extension.tsx +1 -1
  215. package/src/patient-appointments/patient-upcoming-appointments-card.component.tsx +3 -4
  216. package/src/routes.json +2 -26
  217. package/src/store.ts +24 -41
  218. package/src/types/index.ts +7 -0
  219. package/src/workload/monthly-view-workload/monthly-view.component.tsx +2 -2
  220. package/src/workload/workload.component.tsx +3 -3
  221. package/src/workload/workload.resource.ts +1 -1
  222. package/translations/am.json +15 -6
  223. package/translations/ar.json +15 -6
  224. package/translations/ar_SY.json +15 -6
  225. package/translations/bn.json +15 -6
  226. package/translations/cs.json +15 -6
  227. package/translations/de.json +177 -168
  228. package/translations/en.json +15 -6
  229. package/translations/en_US.json +15 -6
  230. package/translations/es.json +15 -6
  231. package/translations/es_MX.json +15 -6
  232. package/translations/fr.json +15 -6
  233. package/translations/he.json +15 -6
  234. package/translations/hi.json +15 -6
  235. package/translations/hi_IN.json +15 -6
  236. package/translations/id.json +15 -6
  237. package/translations/it.json +15 -6
  238. package/translations/ka.json +15 -6
  239. package/translations/km.json +15 -6
  240. package/translations/ku.json +15 -6
  241. package/translations/ky.json +15 -6
  242. package/translations/lg.json +15 -6
  243. package/translations/ne.json +15 -6
  244. package/translations/pl.json +15 -6
  245. package/translations/pt.json +15 -6
  246. package/translations/pt_BR.json +15 -6
  247. package/translations/qu.json +15 -6
  248. package/translations/ro_RO.json +15 -6
  249. package/translations/ru_RU.json +15 -6
  250. package/translations/si.json +15 -6
  251. package/translations/sq.json +15 -6
  252. package/translations/sw.json +15 -6
  253. package/translations/sw_KE.json +15 -6
  254. package/translations/tr.json +15 -6
  255. package/translations/tr_TR.json +15 -6
  256. package/translations/uk.json +15 -6
  257. package/translations/uz.json +15 -6
  258. package/translations/uz@Latn.json +15 -6
  259. package/translations/uz_UZ.json +15 -6
  260. package/translations/vi.json +15 -6
  261. package/translations/zh.json +63 -54
  262. package/translations/zh_CN.json +19 -10
  263. package/translations/zh_TW.json +15 -6
  264. package/dist/1187.js +0 -1
  265. package/dist/1187.js.map +0 -1
  266. package/dist/126.js +0 -1
  267. package/dist/1499.js +0 -1
  268. package/dist/1499.js.map +0 -1
  269. package/dist/15.js +0 -1
  270. package/dist/1522.js +0 -1
  271. package/dist/1522.js.map +0 -1
  272. package/dist/1564.js +0 -1
  273. package/dist/1567.js +0 -1
  274. package/dist/1777.js +0 -1
  275. package/dist/1777.js.map +0 -1
  276. package/dist/1845.js +0 -1
  277. package/dist/1899.js +0 -1
  278. package/dist/1899.js.map +0 -1
  279. package/dist/1953.js +0 -1
  280. package/dist/2056.js +0 -11
  281. package/dist/2056.js.map +0 -1
  282. package/dist/2104.js +0 -1
  283. package/dist/2104.js.map +0 -1
  284. package/dist/215.js +0 -1
  285. package/dist/2178.js +0 -1
  286. package/dist/2417.js +0 -1
  287. package/dist/2417.js.map +0 -1
  288. package/dist/2566.js +0 -1
  289. package/dist/2586.js +0 -1
  290. package/dist/2586.js.map +0 -1
  291. package/dist/2759.js +0 -1
  292. package/dist/276.js +0 -1
  293. package/dist/276.js.map +0 -1
  294. package/dist/3089.js +0 -1
  295. package/dist/3089.js.map +0 -1
  296. package/dist/3127.js +0 -1
  297. package/dist/3127.js.map +0 -1
  298. package/dist/3230.js +0 -1
  299. package/dist/3277.js +0 -1
  300. package/dist/3277.js.map +0 -1
  301. package/dist/3441.js +0 -1
  302. package/dist/3565.js +0 -1
  303. package/dist/3571.js +0 -1
  304. package/dist/3571.js.map +0 -1
  305. package/dist/3746.js +0 -1
  306. package/dist/3925.js +0 -1
  307. package/dist/3946.js +0 -1
  308. package/dist/4085.js +0 -1
  309. package/dist/4085.js.map +0 -1
  310. package/dist/4108.js +0 -1
  311. package/dist/4108.js.map +0 -1
  312. package/dist/4448.js +0 -1
  313. package/dist/4448.js.map +0 -1
  314. package/dist/4744.js +0 -1
  315. package/dist/4744.js.map +0 -1
  316. package/dist/4809.js +0 -1
  317. package/dist/486.js +0 -1
  318. package/dist/486.js.map +0 -1
  319. package/dist/4894.js +0 -1
  320. package/dist/4970.js +0 -1
  321. package/dist/4970.js.map +0 -1
  322. package/dist/5130.js +0 -1
  323. package/dist/5187.js +0 -1
  324. package/dist/5218.js +0 -1
  325. package/dist/5218.js.map +0 -1
  326. package/dist/5327.js +0 -1
  327. package/dist/5327.js.map +0 -1
  328. package/dist/5388.js +0 -1
  329. package/dist/5388.js.map +0 -1
  330. package/dist/5491.js +0 -1
  331. package/dist/5491.js.map +0 -1
  332. package/dist/5595.js +0 -1
  333. package/dist/5657.js +0 -38
  334. package/dist/5657.js.map +0 -1
  335. package/dist/5961.js +0 -1
  336. package/dist/6133.js +0 -1
  337. package/dist/634.js +0 -1
  338. package/dist/634.js.map +0 -1
  339. package/dist/6456.js +0 -1
  340. package/dist/6466.js +0 -1
  341. package/dist/6613.js +0 -1
  342. package/dist/6783.js +0 -1
  343. package/dist/703.js +0 -1
  344. package/dist/703.js.map +0 -1
  345. package/dist/7251.js +0 -1
  346. package/dist/7251.js.map +0 -1
  347. package/dist/7348.js +0 -1
  348. package/dist/7433.js +0 -1
  349. package/dist/7433.js.map +0 -1
  350. package/dist/7513.js +0 -1
  351. package/dist/7513.js.map +0 -1
  352. package/dist/7543.js +0 -1
  353. package/dist/7607.js +0 -1
  354. package/dist/772.js +0 -1
  355. package/dist/8139.js +0 -1
  356. package/dist/8139.js.map +0 -1
  357. package/dist/8456.js +0 -1
  358. package/dist/8456.js.map +0 -1
  359. package/dist/8588.js +0 -1
  360. package/dist/8588.js.map +0 -1
  361. package/dist/8599.js +0 -1
  362. package/dist/8727.js +0 -1
  363. package/dist/8847.js +0 -1
  364. package/dist/8919.js +0 -1
  365. package/dist/8919.js.map +0 -1
  366. package/dist/9015.js +0 -1
  367. package/dist/9051.js +0 -1
  368. package/dist/9051.js.map +0 -1
  369. package/dist/906.js +0 -1
  370. package/dist/9065.js +0 -1
  371. package/dist/9182.js +0 -1
  372. package/dist/9260.js +0 -1
  373. package/dist/9260.js.map +0 -1
  374. package/dist/9327.js +0 -1
  375. package/dist/9327.js.map +0 -1
  376. package/dist/9339.js +0 -1
  377. package/dist/9453.js +0 -1
  378. package/dist/9589.js +0 -1
  379. package/dist/9589.js.map +0 -1
  380. package/dist/9650.js +0 -1
  381. package/dist/9650.js.map +0 -1
  382. package/dist/9833.js +0 -1
  383. package/dist/9833.js.map +0 -1
  384. package/dist/9920.js +0 -1
  385. package/dist/9938.js +0 -1
  386. package/dist/9943.js +0 -1
  387. package/dist/9943.js.map +0 -1
  388. package/src/appointments/scheduled/appointments-list.component.tsx +0 -51
  389. package/src/hooks/useClinicalMetrics.ts +0 -94
  390. package/src/hooks/useTodaysVisits.ts +0 -19
  391. package/src/scheduled-appointments-config-schema.ts +0 -177
@@ -1,102 +1,9 @@
1
- import { useCallback } from 'react';
2
1
  import dayjs from 'dayjs';
3
2
  import isToday from 'dayjs/plugin/isToday';
4
- import useSWR, { useSWRConfig } from 'swr';
5
3
  import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
6
- import {
7
- type AppointmentPayload,
8
- type AppointmentService,
9
- type AppointmentsFetchResponse,
10
- type RecurringAppointmentsPayload,
11
- } from '../types';
4
+ import { type AppointmentPayload, type RecurringAppointmentsPayload } from '../types';
12
5
  dayjs.extend(isToday);
13
6
 
14
- const appointmentUrlMatcher = `${restBaseUrl}/appointment`;
15
- const appointmentsSearchUrl = `${restBaseUrl}/appointments/search`;
16
-
17
- export function useMutateAppointments() {
18
- const { mutate } = useSWRConfig();
19
- // this mutate is intentionally broad because there may be many different keys that need to be invalidated when appointments are updated
20
- const mutateAppointments = useCallback(
21
- () =>
22
- mutate((key) => {
23
- return (
24
- (typeof key === 'string' && key.startsWith(appointmentUrlMatcher)) ||
25
- (Array.isArray(key) && key[0].startsWith(appointmentUrlMatcher))
26
- );
27
- }),
28
- [mutate],
29
- );
30
-
31
- return {
32
- mutateAppointments,
33
- };
34
- }
35
-
36
- export function useAppointments(patientUuid: string, startDate: string, abortController: AbortController) {
37
- /*
38
- SWR isn't meant to make POST requests for data fetching. This is a consequence of the API only exposing this resource via POST.
39
- This works but likely isn't recommended.
40
- */
41
- const fetcher = () =>
42
- openmrsFetch(appointmentsSearchUrl, {
43
- method: 'POST',
44
- signal: abortController.signal,
45
- headers: {
46
- 'Content-Type': 'application/json',
47
- },
48
- body: {
49
- patientUuid: patientUuid,
50
- startDate: startDate,
51
- },
52
- });
53
-
54
- const { data, error, isLoading, isValidating, mutate } = useSWR<AppointmentsFetchResponse, Error>(
55
- appointmentsSearchUrl,
56
- fetcher,
57
- );
58
-
59
- const appointments = data?.data?.length ? data.data : null;
60
-
61
- const pastAppointments = appointments
62
- ?.sort((a, b) => (b.startDateTime > a.startDateTime ? 1 : -1))
63
- ?.filter(({ status }) => status !== 'Cancelled')
64
- ?.filter(({ startDateTime }) =>
65
- dayjs(new Date(startDateTime).toISOString()).isBefore(new Date().setHours(0, 0, 0, 0)),
66
- );
67
-
68
- const upcomingAppointments = appointments
69
- ?.sort((a, b) => (a.startDateTime > b.startDateTime ? 1 : -1))
70
- ?.filter(({ status }) => status !== 'Cancelled')
71
- ?.filter(({ startDateTime }) => dayjs(new Date(startDateTime).toISOString()).isAfter(new Date()));
72
-
73
- const todaysAppointments = appointments
74
- ?.sort((a, b) => (a.startDateTime > b.startDateTime ? 1 : -1))
75
- ?.filter(({ status }) => status !== 'Cancelled')
76
- ?.filter(({ startDateTime }) => dayjs(new Date(startDateTime).toISOString()).isToday());
77
-
78
- return {
79
- data: data ? { pastAppointments, upcomingAppointments, todaysAppointments } : null,
80
- error,
81
- isLoading,
82
- isValidating,
83
- mutate,
84
- };
85
- }
86
-
87
- export function useAppointmentService() {
88
- const { data, error, isLoading } = useSWR<{ data: Array<AppointmentService> }, Error>(
89
- `${restBaseUrl}/appointmentService/all/full`,
90
- openmrsFetch,
91
- );
92
-
93
- return {
94
- data: data ? data.data : null,
95
- error,
96
- isLoading,
97
- };
98
- }
99
-
100
7
  export function saveAppointment(appointment: AppointmentPayload, abortController: AbortController) {
101
8
  return openmrsFetch(`${restBaseUrl}/appointment`, {
102
9
  method: 'POST',
@@ -122,32 +29,6 @@ export function saveRecurringAppointments(
122
29
  });
123
30
  }
124
31
 
125
- // TODO refactor to use SWR?
126
- export function getAppointmentsByUuid(appointmentUuid: string, abortController: AbortController) {
127
- return openmrsFetch(`${restBaseUrl}/appointments/${appointmentUuid}`, {
128
- signal: abortController.signal,
129
- });
130
- }
131
-
132
- // TODO refactor to use SWR?
133
- export function getAppointmentService(abortController: AbortController, uuid) {
134
- return openmrsFetch(`${restBaseUrl}/appointmentService?uuid=` + uuid, {
135
- signal: abortController.signal,
136
- });
137
- }
138
-
139
- export const cancelAppointment = async (toStatus: string, appointmentUuid: string) => {
140
- const omrsDateFormat = 'YYYY-MM-DDTHH:mm:ss.SSSZZ';
141
- const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
142
- const statusChangeTime = dayjs(new Date()).format(omrsDateFormat);
143
- const url = `${restBaseUrl}/appointments/${appointmentUuid}/status-change`;
144
- return await openmrsFetch(url, {
145
- body: { toStatus, onDate: statusChangeTime, timeZone: timeZone },
146
- method: 'POST',
147
- headers: { 'Content-Type': 'application/json' },
148
- });
149
- };
150
-
151
32
  export const checkAppointmentConflict = async (appointmentPayload: AppointmentPayload) => {
152
33
  return await openmrsFetch(`${restBaseUrl}/appointments/conflicts`, {
153
34
  method: 'POST',
@@ -40,17 +40,13 @@ import {
40
40
  import { z } from 'zod';
41
41
  import { type ConfigObject } from '../config-schema';
42
42
  import type { Appointment, AppointmentPayload, RecurringPattern } from '../types';
43
- import {
44
- checkAppointmentConflict,
45
- saveAppointment,
46
- saveRecurringAppointments,
47
- useAppointmentService,
48
- useMutateAppointments,
49
- } from './appointments-form.resource';
43
+ import { checkAppointmentConflict, saveAppointment, saveRecurringAppointments } from './appointments-form.resource';
44
+ import { useAppointmentServices } from '../hooks/useAppointmentService';
50
45
  import { appointmentLocationTagName, dateFormat, moduleName, weekDays } from '../constants';
51
- import { useAppointmentsStore } from '../store';
52
46
  import { useProviders } from '../hooks/useProviders';
47
+ import { useMutateAppointments } from '../hooks/useMutateAppointments';
53
48
  import Workload from '../workload/workload.component';
49
+ import { useSelectedDate } from '../hooks/useSelectedDate';
54
50
  import styles from './appointments-form.scss';
55
51
 
56
52
  interface AppointmentsFormProps {
@@ -84,8 +80,9 @@ const AppointmentsForm: React.FC<Workspace2DefinitionProps<AppointmentsFormProps
84
80
  const locations = useLocations(appointmentLocationTagName);
85
81
  const providers = useProviders();
86
82
  const session = useSession();
87
- const { selectedDate } = useAppointmentsStore();
88
- const { data: services, isLoading } = useAppointmentService();
83
+
84
+ const selectedDate = useSelectedDate();
85
+ const { serviceTypes, isLoading } = useAppointmentServices();
89
86
  const { appointmentStatuses, appointmentTypes, allowAllDayAppointments } = useConfig<ConfigObject>();
90
87
 
91
88
  const [isRecurringAppointment, setIsRecurringAppointment] = useState(false);
@@ -243,7 +240,7 @@ const AppointmentsForm: React.FC<Workspace2DefinitionProps<AppointmentsFormProps
243
240
  appointmentNote: appointment?.comments || '',
244
241
  appointmentStatus: appointment?.status || '',
245
242
  appointmentType: appointment?.appointmentKind || (appointmentTypes?.length === 1 ? appointmentTypes[0] : ''),
246
- selectedService: appointment?.service?.name || (services?.length === 1 ? services[0].name : ''),
243
+ selectedService: appointment?.service?.name || (serviceTypes?.length === 1 ? serviceTypes[0].name : ''),
247
244
  recurringPatternType: defaultRecurringPatternType,
248
245
  recurringPatternPeriod: defaultRecurringPatternPeriod,
249
246
  recurringPatternDaysOfWeek: defaultRecurringPatternDaysOfWeek,
@@ -423,7 +420,7 @@ const AppointmentsForm: React.FC<Workspace2DefinitionProps<AppointmentsFormProps
423
420
  isAllDayAppointment,
424
421
  } = data;
425
422
 
426
- const serviceUuid = services?.find((service) => service.name === selectedService)?.uuid;
423
+ const serviceUuid = serviceTypes?.find((service) => service.name === selectedService)?.uuid;
427
424
  const hoursAndMinutes = startTime.split(':').map((item) => parseInt(item, 10));
428
425
  const hours = (hoursAndMinutes[0] % 12) + (timeFormat === 'PM' ? 12 : 0);
429
426
  const minutes = hoursAndMinutes[1];
@@ -535,13 +532,13 @@ const AppointmentsForm: React.FC<Workspace2DefinitionProps<AppointmentsFormProps
535
532
  if (!isEditing) {
536
533
  setValue(
537
534
  'duration',
538
- services?.find((service) => service.name === event.target.value)?.durationMins,
535
+ serviceTypes?.find((service) => service.name === event.target.value)?.durationMins,
539
536
  );
540
537
  } else {
541
- const previousServiceDuration = services?.find(
538
+ const previousServiceDuration = serviceTypes?.find(
542
539
  (service) => service.name === getValues('selectedService'),
543
540
  )?.durationMins;
544
- const selectedServiceDuration = services?.find(
541
+ const selectedServiceDuration = serviceTypes?.find(
545
542
  (service) => service.name === event.target.value,
546
543
  )?.durationMins;
547
544
  if (selectedServiceDuration && previousServiceDuration === getValues('duration')) {
@@ -553,8 +550,8 @@ const AppointmentsForm: React.FC<Workspace2DefinitionProps<AppointmentsFormProps
553
550
  ref={ref}
554
551
  value={value}>
555
552
  <SelectItem text={t('chooseService', 'Select service')} value="" />
556
- {services?.length > 0 &&
557
- services.map((service) => (
553
+ {serviceTypes?.length > 0 &&
554
+ serviceTypes.map((service) => (
558
555
  <SelectItem key={service.uuid} text={service.name} value={service.name}>
559
556
  {service.name}
560
557
  </SelectItem>
@@ -605,7 +602,7 @@ const AppointmentsForm: React.FC<Workspace2DefinitionProps<AppointmentsFormProps
605
602
  </div>
606
603
  </FormGroup>
607
604
 
608
- <FormGroup className={styles.formGroup} legendText={t('dateTime', 'Date & Time')}>
605
+ <FormGroup className={styles.formGroup} legendText={t('dateTime', 'Appointment time')}>
609
606
  <div className={styles.dateTimeFields}>
610
607
  {isRecurringAppointment && (
611
608
  <div className={styles.inputContainer}>
@@ -1,11 +1,12 @@
1
1
  import React, { useCallback, useMemo } from 'react';
2
2
  import dayjs from 'dayjs';
3
3
  import { useTranslation } from 'react-i18next';
4
+ import { useLocation, useNavigate } from 'react-router-dom';
4
5
  import { MultiSelect } from '@carbon/react';
5
6
  import { PageHeader, PageHeaderContent, AppointmentsPictogram, OpenmrsDatePicker } from '@openmrs/esm-framework';
6
- import { omrsDateFormat } from '../constants';
7
7
  import { useAppointmentServices } from '../hooks/useAppointmentService';
8
- import { useAppointmentsStore, setSelectedDate, setAppointmentServiceTypes } from '../store';
8
+ import { useSelectedDate } from '../hooks/useSelectedDate';
9
+ import { useAppointmentsStore } from '../store';
9
10
  import styles from './appointments-header.scss';
10
11
 
11
12
  interface AppointmentHeaderProps {
@@ -15,13 +16,21 @@ interface AppointmentHeaderProps {
15
16
 
16
17
  const AppointmentsHeader: React.FC<AppointmentHeaderProps> = ({ title, showServiceTypeFilter }) => {
17
18
  const { t } = useTranslation();
18
- const { selectedDate, appointmentServiceTypes } = useAppointmentsStore();
19
+ const navigate = useNavigate();
20
+ const location = useLocation();
21
+ const { appointmentServiceTypes, setAppointmentServiceTypes } = useAppointmentsStore();
19
22
  const { serviceTypes } = useAppointmentServices();
23
+ const selectedDate = useSelectedDate();
20
24
 
21
- const handleChangeServiceTypeFilter = useCallback(({ selectedItems }) => {
22
- const selectedUuids = selectedItems.map((item) => item.id);
23
- setAppointmentServiceTypes(selectedUuids);
24
- }, []);
25
+ const selectedDateValue = useMemo(() => dayjs(selectedDate).toDate(), [selectedDate]);
26
+
27
+ const handleChangeServiceTypeFilter = useCallback(
28
+ ({ selectedItems }) => {
29
+ const selectedUuids = selectedItems.map((item) => item.id);
30
+ setAppointmentServiceTypes(selectedUuids);
31
+ },
32
+ [setAppointmentServiceTypes],
33
+ );
25
34
 
26
35
  const serviceTypeOptions = useMemo(
27
36
  () => serviceTypes?.map((item) => ({ id: item.uuid, label: item.name })) ?? [],
@@ -36,8 +45,17 @@ const AppointmentsHeader: React.FC<AppointmentHeaderProps> = ({ title, showServi
36
45
  data-testid="appointment-date-picker"
37
46
  id="appointment-date-picker"
38
47
  aria-label={t('appointmentDate', 'Appointment date')}
39
- onChange={(date) => setSelectedDate(dayjs(date).startOf('day').format(omrsDateFormat))}
40
- value={dayjs(selectedDate).toDate()}
48
+ onChange={(date) => {
49
+ if (!date) {
50
+ return;
51
+ }
52
+
53
+ const target = `/${dayjs(date).format('YYYY-MM-DD')}`;
54
+ if (!location.pathname.endsWith(target)) {
55
+ navigate(target);
56
+ }
57
+ }}
58
+ value={selectedDateValue}
41
59
  />
42
60
  {showServiceTypeFilter && (
43
61
  <MultiSelect
@@ -1,58 +1,9 @@
1
1
  import dayjs, { type Dayjs } from 'dayjs';
2
2
  import { type TFunction } from 'i18next';
3
3
  import { launchWorkspace2, type Workspace2DefinitionProps } from '@openmrs/esm-framework';
4
- import { type AppointmentSummary, type AppointmentCountMap, AppointmentStatus } from '../types';
4
+ import { AppointmentStatus } from '../types';
5
5
  import { appointmentsFormWorkspace } from '../constants';
6
6
 
7
- interface FlattenedAppointmentSummary {
8
- serviceName: string;
9
- countMap: AppointmentCountMap[];
10
- }
11
-
12
- interface ServiceLoadSummary {
13
- serviceName: string;
14
- count: number;
15
- }
16
-
17
- export const getHighestAppointmentServiceLoad = (
18
- appointmentSummary: FlattenedAppointmentSummary[] = [],
19
- ): ServiceLoadSummary | undefined => {
20
- const groupedAppointments = appointmentSummary.map(({ countMap, serviceName }) => ({
21
- serviceName: serviceName,
22
- count: countMap.reduce((accumulator, currentValue) => accumulator + currentValue.allAppointmentsCount, 0),
23
- }));
24
- if (groupedAppointments.length === 0) {
25
- return undefined;
26
- }
27
- return groupedAppointments.find((summary) => summary.count === Math.max(...groupedAppointments.map((x) => x.count)));
28
- };
29
-
30
- export const flattenAppointmentSummary = (
31
- appointmentToTransform: AppointmentSummary[],
32
- ): FlattenedAppointmentSummary[] =>
33
- appointmentToTransform.flatMap((el) => ({
34
- serviceName: el.appointmentService.name,
35
- countMap: Object.entries(el.appointmentCountMap).flatMap(([, countMap]) => countMap),
36
- }));
37
-
38
- export const getServiceCountByAppointmentType = (
39
- appointmentSummary: AppointmentSummary[],
40
- appointmentType: 'allAppointmentsCount' | 'missedAppointmentsCount',
41
- ): number => {
42
- return appointmentSummary
43
- .map((el) =>
44
- Object.values(el.appointmentCountMap).map((countMap) => {
45
- const value = countMap[appointmentType];
46
- if (typeof value === 'number') {
47
- return value;
48
- }
49
- return 0;
50
- }),
51
- )
52
- .flat(1)
53
- .reduce((count, val) => count + val, 0);
54
- };
55
-
56
7
  export const formatAMPM = (date: Date): string => {
57
8
  const hours24 = date.getHours();
58
9
  const minutes = date.getMinutes();
@@ -2,17 +2,30 @@ import React from 'react';
2
2
  import dayjs from 'dayjs';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { toOmrsIsoString } from '@openmrs/esm-framework';
5
- import AppointmentsList from '../appointments/scheduled/appointments-list.component';
5
+ import AppointmentsTable from '../appointments/common-components/appointments-table.component';
6
+ import { useAppointmentList } from '../hooks/useAppointmentList';
6
7
  import styles from './home-appointments.scss';
8
+ import { AppointmentStatus } from '../types';
7
9
 
10
+ /**
11
+ * A extension that shows today's appointments, originally meant for the home app.
12
+ */
8
13
  const HomeAppointments = () => {
9
14
  const { t } = useTranslation();
10
15
 
16
+ const today = toOmrsIsoString(dayjs().startOf('day').toDate());
17
+ const { appointmentList, isLoading } = useAppointmentList(today);
18
+
19
+ const excludeCancelledAppointments = appointmentList.filter(
20
+ (appointment) => appointment.status !== AppointmentStatus.CANCELLED,
21
+ );
22
+
11
23
  return (
12
24
  <div className={styles.container}>
13
- <AppointmentsList
14
- date={toOmrsIsoString(dayjs().startOf('day').toDate())}
15
- excludeCancelledAppointments
25
+ <AppointmentsTable
26
+ appointments={excludeCancelledAppointments}
27
+ isLoading={isLoading}
28
+ tableHeading={t('todaysAppointment', "Today's Appointments")}
16
29
  />
17
30
  </div>
18
31
  );
@@ -0,0 +1,14 @@
1
+ import useSWR from 'swr';
2
+ import { type Visit, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
3
+
4
+ /**
5
+ * Custom hook to fetch active visits from the OpenMRS REST API.
6
+ * @returns An object containing the visits, isLoading flag, and error message.
7
+ */
8
+ export const useActiveVisits = () => {
9
+ const visitsUrl = `${restBaseUrl}/visit?includeInactive=false&v=custom:(uuid,patient:(uuid),startDatetime,stopDatetime)`;
10
+ const { data, error, isLoading, mutate } = useSWR<{ data: { results: Visit[] } }>(visitsUrl, openmrsFetch);
11
+ const visits = data?.data?.results ?? [];
12
+
13
+ return { isLoading, visits, error, mutateVisits: mutate };
14
+ };
@@ -2,40 +2,23 @@ import dayjs from 'dayjs';
2
2
  import useSWR from 'swr';
3
3
  import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
4
4
  import { type AppointmentsFetchResponse } from '../types';
5
- import { useAppointmentsStore } from '../store';
5
+ import { useSelectedDate } from './useSelectedDate';
6
6
 
7
- export const useAppointmentList = (appointmentStatus: string, date?: string) => {
8
- const { selectedDate } = useAppointmentsStore();
9
- const startDate = date ? date : selectedDate;
10
- const endDate = dayjs(startDate).endOf('day').format('YYYY-MM-DDTHH:mm:ss.SSSZZ'); // TODO: fix? is this correct?
11
- const searchUrl = `${restBaseUrl}/appointments/search`;
12
- const abortController = new AbortController();
7
+ export const useAppointmentList = (date: string) => {
8
+ const startOfDay = dayjs(date).startOf('day').toISOString();
9
+ const searchUrl = `${restBaseUrl}/appointments?forDate=${startOfDay}`;
13
10
 
14
- const fetcher = ([url, startDate, endDate, status]) =>
15
- openmrsFetch(url, {
16
- method: 'POST',
17
- signal: abortController.signal,
18
- headers: {
19
- 'Content-Type': 'application/json',
20
- },
21
- body: {
22
- startDate: startDate,
23
- endDate: endDate,
24
- status: status,
25
- },
26
- });
27
-
28
- const { data, error, isLoading, mutate } = useSWR<AppointmentsFetchResponse, Error>(
29
- [searchUrl, startDate, endDate, appointmentStatus],
30
- fetcher,
31
- { errorRetryCount: 2 },
32
- );
33
-
34
- return { appointmentList: data?.data ?? [], isLoading, error, mutate };
11
+ const { data, ...rest } = useSWR<AppointmentsFetchResponse, Error>(searchUrl, openmrsFetch);
12
+ return { appointmentList: data?.data ?? [], ...rest };
35
13
  };
36
14
 
15
+ /**
16
+ * This is a non-standard API that does not come with the appointments module by default
17
+ * @param startDate
18
+ * @returns
19
+ */
37
20
  export const useEarlyAppointmentList = (startDate?: string) => {
38
- const { selectedDate } = useAppointmentsStore();
21
+ const selectedDate = useSelectedDate();
39
22
  const forDate = startDate ? startDate : selectedDate;
40
23
  const url = `${restBaseUrl}/appointment/earlyAppointment?forDate=${forDate}`;
41
24
 
@@ -1,3 +1,4 @@
1
+ import { useMemo } from 'react';
1
2
  import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
3
  import useSWR from 'swr';
3
4
  import { type AppointmentService } from '../types';
@@ -7,5 +8,9 @@ export function useAppointmentServices() {
7
8
  `${restBaseUrl}/appointmentService/all/default`,
8
9
  openmrsFetch,
9
10
  );
10
- return { serviceTypes: data?.data ?? [], isLoading, error };
11
+ const sortedServices = useMemo(
12
+ () => (data?.data ? [...data.data].sort((a, b) => a.name.localeCompare(b.name)) : []),
13
+ [data?.data],
14
+ );
15
+ return { serviceTypes: sortedServices, isLoading, error };
11
16
  }
@@ -0,0 +1,19 @@
1
+ import { useAppContext } from '@openmrs/esm-framework';
2
+ import { type AppointmentsAppContext, type Appointment } from '../types';
3
+
4
+ /**
5
+ * This hook provides a way to reuse fetched appointments data throughout the app.
6
+ * It assumes that:
7
+ * - the ScheduledAppointments component, which calls useDefinedAppContext, is mounted.
8
+ * - It is not used in an extension mounted outside the Appointments app, since it relies
9
+ * on data in useAppointmentsStore().
10
+ */
11
+ export function useAppointmentsAppContext() {
12
+ return (
13
+ useAppContext<AppointmentsAppContext>('appointments') ?? {
14
+ appointmentForSelectedDateFilteredByServiceTypes: [] as Appointment[],
15
+ error: null,
16
+ isLoading: true,
17
+ }
18
+ );
19
+ }
@@ -25,10 +25,11 @@ export const useAppointmentsCalendar = (forDate: string, period: string) => {
25
25
  openmrsFetch,
26
26
  { errorRetryCount: 2 },
27
27
  );
28
+ // Transform API response into daily appointment counts grouped by service
28
29
  const results: Array<DailyAppointmentsCountByService> = data?.data.reduce((acc, service) => {
29
30
  const serviceName = service.appointmentService.name;
30
31
  const serviceUuid = service.appointmentService.uuid;
31
- Object.entries(service.appointmentCountMap).map(([key, value]) => {
32
+ Object.entries(service.appointmentCountMap).forEach(([key, value]) => {
32
33
  const existingEntry = acc.find((entry) => entry.appointmentDate === key);
33
34
  if (existingEntry) {
34
35
  existingEntry.services.push({ serviceName, serviceUuid, count: value.allAppointmentsCount });
@@ -0,0 +1,24 @@
1
+ import { useCallback } from 'react';
2
+ import { useSWRConfig } from 'swr';
3
+ import { restBaseUrl } from '@openmrs/esm-framework';
4
+
5
+ const appointmentUrlMatcher = `${restBaseUrl}/appointment`;
6
+
7
+ export function useMutateAppointments() {
8
+ const { mutate } = useSWRConfig();
9
+ // this mutate is intentionally broad because there may be many different keys that need to be invalidated when appointments are updated
10
+ const mutateAppointments = useCallback(
11
+ () =>
12
+ mutate((key) => {
13
+ return (
14
+ (typeof key === 'string' && key.startsWith(appointmentUrlMatcher)) ||
15
+ (Array.isArray(key) && key[0].startsWith(appointmentUrlMatcher))
16
+ );
17
+ }),
18
+ [mutate],
19
+ );
20
+
21
+ return {
22
+ mutateAppointments,
23
+ };
24
+ }
@@ -2,12 +2,13 @@ import dayjs from 'dayjs';
2
2
  import useSWR from 'swr';
3
3
  import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
4
4
  import { type AppointmentsFetchResponse } from '../types';
5
- import { useAppointmentsStore } from '../store';
5
+ import { useSelectedDate } from './useSelectedDate';
6
6
 
7
7
  export function usePatientAppointmentHistory(patientUuid: string) {
8
8
  const abortController = new AbortController();
9
9
  const appointmentsSearchUrl = `${restBaseUrl}/appointments/search`;
10
- const { selectedDate } = useAppointmentsStore();
10
+
11
+ const selectedDate = useSelectedDate();
11
12
 
12
13
  const fetcher = () =>
13
14
  openmrsFetch(appointmentsSearchUrl, {
@@ -0,0 +1,24 @@
1
+ import dayjs from 'dayjs';
2
+ import { useMemo } from 'react';
3
+ import { useParams } from 'react-router-dom';
4
+
5
+ /**
6
+ * A custom hook to get the selected date from the URL parameter. Date should be in YYYY-MM-DD format,
7
+ * although looser strings accepted by dayjs is also fine. If no date is specified, it defaults to the current date.
8
+ */
9
+ export function useSelectedDate() {
10
+ const params = useParams();
11
+ return useMemo(() => {
12
+ if (params.date) {
13
+ const parsedDate = dayjs(params.date, 'YYYY-MM-DD').startOf('day');
14
+ if (!parsedDate.isValid()) {
15
+ console.warn(
16
+ `Invalid date format in URL parameter: ${params.date}. Format should be YYYY-MM-DD. Falling back to current date.`,
17
+ );
18
+ } else {
19
+ return parsedDate.format('YYYY-MM-DD');
20
+ }
21
+ }
22
+ return dayjs().startOf('day').format('YYYY-MM-DD');
23
+ }, [params]);
24
+ }
@@ -3,6 +3,7 @@ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
3
3
  import { type Identifier } from '../types';
4
4
  import { configSchema } from '../config-schema';
5
5
  import { useAppointmentsStore } from '../store';
6
+ import { useSelectedDate } from './useSelectedDate';
6
7
 
7
8
  interface UnscheduledAppointment {
8
9
  age: number;
@@ -19,8 +20,11 @@ interface UnscheduledAppointment {
19
20
  };
20
21
  }
21
22
 
23
+ /**
24
+ * This is a non-standard API that does not come with the appointments module by default
25
+ */
22
26
  export function useUnscheduledAppointments() {
23
- const { selectedDate } = useAppointmentsStore();
27
+ const selectedDate = useSelectedDate();
24
28
  // TODO/NOTE: this endpoint is not implemented in main Bahmni Appointments backend
25
29
  const url = `${restBaseUrl}/appointment/unScheduledAppointment?forDate=${selectedDate}`;
26
30
  const { data, error, isLoading } = useSWR<{ data: Array<UnscheduledAppointment> }>(url, openmrsFetch, {
package/src/index.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  createDashboard,
3
3
  defineConfigSchema,
4
- defineExtensionConfigSchema,
5
4
  getAsyncLifecycle,
6
5
  getSyncLifecycle,
7
6
  registerBreadcrumbs,
@@ -9,14 +8,6 @@ import {
9
8
  import { configSchema } from './config-schema';
10
9
  import { createDashboardLink } from './createDashboardLink';
11
10
  import { dashboardMeta, appointmentCalendarDashboardMeta, patientChartDashboardMeta } from './dashboard.meta';
12
- import {
13
- cancelledAppointmentsPanelConfigSchema,
14
- checkedInAppointmentsPanelConfigSchema,
15
- completedAppointmentsPanelConfigSchema,
16
- earlyAppointmentsPanelConfigSchema,
17
- expectedAppointmentsPanelConfigSchema,
18
- missedAppointmentsPanelConfigSchema,
19
- } from './scheduled-appointments-config-schema';
20
11
 
21
12
  const moduleName = '@openmrs/esm-appointments-app';
22
13
 
@@ -32,13 +23,6 @@ export function startupApp() {
32
23
 
33
24
  defineConfigSchema(moduleName, configSchema);
34
25
 
35
- defineExtensionConfigSchema('expected-appointments-panel', expectedAppointmentsPanelConfigSchema);
36
- defineExtensionConfigSchema('checked-in-appointments-panel', checkedInAppointmentsPanelConfigSchema);
37
- defineExtensionConfigSchema('completed-appointments-panel', completedAppointmentsPanelConfigSchema);
38
- defineExtensionConfigSchema('missed-appointments-panel', missedAppointmentsPanelConfigSchema);
39
- defineExtensionConfigSchema('cancelled-appointments-panel', cancelledAppointmentsPanelConfigSchema);
40
- defineExtensionConfigSchema('early-appointments-panel', earlyAppointmentsPanelConfigSchema);
41
-
42
26
  registerBreadcrumbs([
43
27
  {
44
28
  title: 'Appointments',
@@ -68,11 +52,6 @@ export const appointmentsDashboard = getAsyncLifecycle(() => import('./appointme
68
52
 
69
53
  export const homeAppointments = getAsyncLifecycle(() => import('./home/home-appointments.component'), options);
70
54
 
71
- export const appointmentsList = getAsyncLifecycle(
72
- () => import('./appointments/scheduled/appointments-list.component'),
73
- options,
74
- );
75
-
76
55
  export const earlyAppointments = getAsyncLifecycle(
77
56
  () => import('./appointments/scheduled/early-appointments.component'),
78
57
  options,