@openmrs/esm-appointments-app 4.3.1-pre.1410 → 4.3.1-pre.1413

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 (55) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/dist/210.js +1 -0
  3. package/dist/210.js.map +1 -0
  4. package/dist/437.js +1 -1
  5. package/dist/437.js.map +1 -1
  6. package/dist/574.js +1 -1
  7. package/dist/905.js +1 -1
  8. package/dist/905.js.map +1 -1
  9. package/dist/openmrs-esm-appointments-app.js.buildmanifest.json +32 -32
  10. package/package.json +2 -2
  11. package/src/appointments/common-components/appointments-base-table.component.tsx +4 -0
  12. package/src/appointments/scheduled/scheduled-appointments.component.tsx +5 -1
  13. package/src/appointments-calendar/{appointments-calendar-list-view.scss → appointments-calendar-view-view.scss} +5 -1
  14. package/src/appointments-calendar/appointments-calendar-view.component.tsx +30 -0
  15. package/src/appointments-calendar/{appointments-calendar-list.test.tsx → appointments-calendar-view.test.tsx} +3 -5
  16. package/src/appointments-calendar/calendar-view.component.tsx +31 -0
  17. package/src/appointments-calendar/{daily-calendar-view.component.tsx → daily/daily-calendar-view.component.tsx} +2 -2
  18. package/src/appointments-calendar/{daily-header.component.tsx → daily/daily-header.component.tsx} +1 -2
  19. package/src/appointments-calendar/{daily-view-workload.component.tsx → daily/daily-view-workload.component.tsx} +3 -3
  20. package/src/appointments-calendar/header/calendar-header.component.tsx +75 -0
  21. package/src/appointments-calendar/{monthly-calendar-view.component.tsx → monthly/monthly-calendar-view.component.tsx} +9 -8
  22. package/src/appointments-calendar/{monthly-header.module.tsx → monthly/monthly-header.module.tsx} +2 -2
  23. package/src/appointments-calendar/monthly/monthly-view-workload.component.tsx +60 -0
  24. package/src/appointments-calendar/{calendar-patient-list → patient-list}/calendar-patient-list.component.tsx +7 -14
  25. package/src/appointments-calendar/{weekly-calendar-view.component.tsx → weekly/weekly-calendar-view.component.tsx} +2 -2
  26. package/src/appointments-calendar/{weekly-header.component.tsx → weekly/weekly-header.component.tsx} +2 -2
  27. package/src/appointments-calendar/{weekly-view-workload.component.tsx → weekly/weekly-view-workload.component.tsx} +6 -5
  28. package/src/appointments-metrics/appointments-metrics.component.tsx +15 -13
  29. package/src/appointments-metrics/metrics-card.component.tsx +1 -1
  30. package/src/appointments.component.tsx +2 -2
  31. package/src/hooks/useAppointmentList.tsx +4 -1
  32. package/src/hooks/useAppointmentsCalendar.tsx +1 -0
  33. package/src/hooks/useOverlay.tsx +15 -13
  34. package/src/hooks/useUnscheduledAppointments.tsx +1 -1
  35. package/src/overlay.component.tsx +13 -11
  36. package/translations/en.json +0 -9
  37. package/dist/120.js +0 -1
  38. package/dist/120.js.map +0 -1
  39. package/src/appointments-calendar/appointments-calendar-list-view.component.tsx +0 -52
  40. package/src/appointments-calendar/calendar-header.component.tsx +0 -54
  41. package/src/appointments-calendar/monthly-view-workload.component.tsx +0 -64
  42. package/src/patient-search/patient-scheduled-visits.component.tsx +0 -193
  43. package/src/patient-search/patient-scheduled-visits.scss +0 -122
  44. /package/src/appointments-calendar/{daily-calendar.scss → daily/daily-calendar.scss} +0 -0
  45. /package/src/appointments-calendar/{daily-header.scss → daily/daily-header.scss} +0 -0
  46. /package/src/appointments-calendar/{daily-workload-module.scss → daily/daily-workload-module.scss} +0 -0
  47. /package/src/appointments-calendar/{days-of-week.component.tsx → daily/days-of-week.component.tsx} +0 -0
  48. /package/src/appointments-calendar/{days-of-week.scss → daily/days-of-week.scss} +0 -0
  49. /package/src/appointments-calendar/{calendar-header.scss → header/calendar-header.scss} +0 -0
  50. /package/src/appointments-calendar/{monthly-header.module.scss → monthly/monthly-header.module.scss} +0 -0
  51. /package/src/appointments-calendar/{monthly-view-workload.scss → monthly/monthly-view-workload.scss} +0 -0
  52. /package/src/appointments-calendar/{calendar-patient-list → patient-list}/calenar-patient-list.scss +0 -0
  53. /package/src/appointments-calendar/{weekly-calendar.scss → weekly/weekly-calendar.scss} +0 -0
  54. /package/src/appointments-calendar/{weekly-header.scss → weekly/weekly-header.scss} +0 -0
  55. /package/src/appointments-calendar/{weekly-workload-module.scss → weekly/weekly-workload-module.scss} +0 -0
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+ import dayjs from 'dayjs';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { navigate, useLayoutType } from '@openmrs/esm-framework';
5
+ import { isSameMonth } from '../../helpers';
6
+ import { spaBasePath } from '../../constants';
7
+ import styles from './monthly-view-workload.scss';
8
+
9
+ const colorCoding = { HIV: 'red', 'Lab testing': 'purple', Refill: 'blue' };
10
+
11
+ const MonthlyWorkload = ({ type, dateTime, currentDate, events }) => {
12
+ const layout = useLayoutType();
13
+ const { t } = useTranslation();
14
+
15
+ const currentData = events?.find(
16
+ (event) => dayjs(event.appointmentDate)?.format('YYYY-MM-DD') === dayjs(dateTime)?.format('YYYY-MM-DD'),
17
+ );
18
+
19
+ const serviceAreaOnClick = (serviceName) => {
20
+ navigate({ to: `${spaBasePath}/appointments/list/${dateTime}/${serviceName}` });
21
+ };
22
+
23
+ return (
24
+ <div
25
+ className={`${styles[isSameMonth(dateTime, currentDate) ? 'monthly-cell' : 'monthly-cell-disabled']} ${
26
+ currentData?.service ? styles.greyBackground : ''
27
+ } ${layout === 'small-desktop' ? styles.smallDesktop : styles.largeDesktop}`}>
28
+ {type === 'monthly' && isSameMonth(dateTime, currentDate) && (
29
+ <p>
30
+ <b>{dateTime.format('D')}</b>
31
+ {currentData?.service && (
32
+ <div className={styles.currentData}>
33
+ {currentData.service.map(({ serviceName, count }) => (
34
+ <div
35
+ key={serviceName}
36
+ role="button"
37
+ tabIndex={0}
38
+ onClick={() => serviceAreaOnClick(serviceName)}
39
+ className={`${styles.serviceArea} ${styles[colorCoding[serviceName]]}`}>
40
+ <span>{serviceName}</span>
41
+ <span>{count}</span>
42
+ </div>
43
+ ))}
44
+ <div
45
+ role="button"
46
+ tabIndex={0}
47
+ onClick={() => serviceAreaOnClick('Total')}
48
+ className={`${styles.serviceArea} ${styles.green}`}>
49
+ <span>{t('total', 'Total')}</span>
50
+ <span>{currentData?.service.reduce((sum, { count = 0 }) => sum + count, 0)}</span>
51
+ </div>
52
+ </div>
53
+ )}
54
+ </p>
55
+ )}
56
+ </div>
57
+ );
58
+ };
59
+
60
+ export default MonthlyWorkload;
@@ -52,20 +52,13 @@ const CalendarPatientList: React.FC<CalendarPatientListProps> = () => {
52
52
  },
53
53
  ];
54
54
 
55
- const rowData =
56
- serviceName !== 'Total'
57
- ? appointments
58
- ?.map((appointment) => ({
59
- id: `${appointment.identifier}`,
60
- ...appointment,
61
- dateTime: formatDatetime(new Date(appointment.dateTime)),
62
- }))
63
- .filter(({ serviceType }) => serviceName === serviceType)
64
- : appointments?.map((appointment) => ({
65
- id: `${appointment.identifier}`,
66
- ...appointment,
67
- dateTime: formatDatetime(new Date(appointment.dateTime)),
68
- }));
55
+ const rowData = appointments
56
+ ?.filter(({ serviceType }) => serviceName === 'Total' || serviceName === serviceType)
57
+ .map((appointment) => ({
58
+ id: `${appointment.identifier}`,
59
+ ...appointment,
60
+ dateTime: formatDatetime(new Date(appointment.dateTime)),
61
+ }));
69
62
 
70
63
  if (isLoading) {
71
64
  return (
@@ -2,8 +2,8 @@ import React from 'react';
2
2
  import dayjs, { Dayjs } from 'dayjs';
3
3
  import isBetween from 'dayjs/plugin/isBetween';
4
4
  import styles from './weekly-calendar.scss';
5
- import { CalendarType } from '../types';
6
- import { isSameMonth, weekAllDays, weekDays } from '../helpers';
5
+ import { CalendarType } from '../../types';
6
+ import { isSameMonth, weekAllDays, weekDays } from '../../helpers';
7
7
  import WeeklyWorkloadView from './weekly-view-workload.component';
8
8
  import WeeklyHeader from './weekly-header.component';
9
9
  dayjs.extend(isBetween);
@@ -2,9 +2,9 @@ import { Button } from '@carbon/react';
2
2
  import { Dayjs } from 'dayjs';
3
3
  import React from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
- import { weekDays } from '../helpers';
6
- import { CalendarType } from '../types';
7
5
  import styles from './weekly-header.scss';
6
+ import { weekDays } from '../../helpers';
7
+ import { CalendarType } from '../../types';
8
8
 
9
9
  const Format = {
10
10
  monthly: 'month',
@@ -1,11 +1,12 @@
1
- import dayjs, { Dayjs } from 'dayjs';
2
- import styles from './weekly-workload-module.scss';
3
1
  import React from 'react';
4
- import { CalendarType } from '../types';
5
- import { isSameMonth } from '../helpers';
2
+ import dayjs, { Dayjs } from 'dayjs';
6
3
  import { navigate, useLayoutType } from '@openmrs/esm-framework';
7
4
  import { useTranslation } from 'react-i18next';
8
- import { spaBasePath } from '../constants';
5
+
6
+ import styles from './weekly-workload-module.scss';
7
+ import { spaBasePath } from '../../constants';
8
+ import { isSameMonth } from '../../helpers';
9
+ import { CalendarType } from '../../types';
9
10
 
10
11
  interface WeeklyCellProps {
11
12
  type: CalendarType;
@@ -10,23 +10,28 @@ import styles from './appointments-metrics.scss';
10
10
 
11
11
  const AppointmentsMetrics: React.FC<{ serviceUuid: string }> = ({ serviceUuid }) => {
12
12
  const { t } = useTranslation();
13
- const { highestServiceLoad, error } = useClinicalMetrics();
14
- const { totalProviders, isLoading: loading } = useAllAppointmentsByDate();
13
+
14
+ const { highestServiceLoad, error: clinicalMetricsError } = useClinicalMetrics();
15
+ const { totalProviders, isLoading: allAppointmentsLoading } = useAllAppointmentsByDate();
15
16
  const { totalScheduledAppointments } = useScheduledAppointment(serviceUuid);
17
+
16
18
  const startDate = useAppointmentDate();
17
19
  const formattedStartDate = formatDate(parseDate(startDate), { mode: 'standard', time: false });
20
+
18
21
  const { appointmentList: arrivedAppointments } = useAppointmentList('Honoured');
19
22
  const { appointmentList: pendingAppointments } = useAppointmentList('Pending');
20
- const filteredArrivedAppointment = serviceUuid
21
- ? arrivedAppointments.filter((arrivedAppt) => arrivedAppt.serviceTypeUuid === serviceUuid)
22
- : arrivedAppointments;
23
23
 
24
- const filteredPendingAppointment = serviceUuid
25
- ? pendingAppointments.filter((arrivedAppt) => arrivedAppt.serviceTypeUuid === serviceUuid)
24
+ const filteredArrivedAppointments = serviceUuid
25
+ ? arrivedAppointments.filter(({ serviceTypeUuid }) => serviceTypeUuid === serviceUuid)
26
+ : arrivedAppointments;
27
+ const filteredPendingAppointments = serviceUuid
28
+ ? pendingAppointments.filter(({ serviceTypeUuid }) => serviceTypeUuid === serviceUuid)
26
29
  : pendingAppointments;
27
30
 
28
- if (error) {
29
- <ErrorState headerTitle={t('appointmentMetricsLoadError')} error={error} />;
31
+ if (clinicalMetricsError) {
32
+ return (
33
+ <ErrorState headerTitle={t('appointmentMetricsLoadError', 'Metrics load error')} error={clinicalMetricsError} />
34
+ );
30
35
  }
31
36
 
32
37
  return (
@@ -37,8 +42,7 @@ const AppointmentsMetrics: React.FC<{ serviceUuid: string }> = ({ serviceUuid })
37
42
  label={t('patients', 'Patients')}
38
43
  value={totalScheduledAppointments}
39
44
  headerLabel={t('scheduledAppointments', 'Scheduled appointments')}
40
- view=""
41
- count={{ pendingAppointments: filteredPendingAppointment, arrivedAppointments: filteredArrivedAppointment }}
45
+ count={{ pendingAppointments: filteredPendingAppointments, arrivedAppointments: filteredArrivedAppointments }}
42
46
  appointmentDate={startDate}
43
47
  />
44
48
  <MetricsCard
@@ -47,13 +51,11 @@ const AppointmentsMetrics: React.FC<{ serviceUuid: string }> = ({ serviceUuid })
47
51
  }
48
52
  value={highestServiceLoad?.count ?? '--'}
49
53
  headerLabel={t('highestServiceVolume', 'High volume service: {time}', { time: formattedStartDate })}
50
- view=""
51
54
  />
52
55
  <MetricsCard
53
56
  label={t('providers', 'Providers')}
54
57
  value={totalProviders}
55
58
  headerLabel={t('providersAvailableToday', 'Providers available: {time}', { time: formattedStartDate })}
56
- view=""
57
59
  />
58
60
  </div>
59
61
  </>
@@ -15,7 +15,7 @@ interface MetricsCardProps {
15
15
  value: number;
16
16
  headerLabel: string;
17
17
  children?: React.ReactNode;
18
- view: string;
18
+ view?: string;
19
19
  count?: { pendingAppointments: Array<any>; arrivedAppointments: Array<any> };
20
20
  appointmentDate?: string;
21
21
  }
@@ -4,8 +4,8 @@ import AppointmentList from './appointments/appointment-tabs.component';
4
4
  import ClinicMetrics from './appointments-metrics/appointments-metrics.component';
5
5
  import AppointmentsHeader from './appointments-header/appointments-header.component';
6
6
  import Overlay from './overlay.component';
7
- import AppointmentsCalendarListView from './appointments-calendar/appointments-calendar-list-view.component';
8
- import CalendarPatientList from './appointments-calendar/calendar-patient-list/calendar-patient-list.component';
7
+ import AppointmentsCalendarListView from './appointments-calendar/appointments-calendar-view.component';
8
+ import CalendarPatientList from './appointments-calendar/patient-list/calendar-patient-list.component';
9
9
 
10
10
  const ClinicalAppointments: React.FC = () => {
11
11
  const { t } = useTranslation();
@@ -28,6 +28,7 @@ export const useAppointmentList = (appointmentStatus: string, startDate?: string
28
28
  const { data, error, isLoading } = useSWR<{ data: Array<AppointmentPatientList> }>(
29
29
  appointmentStatus ? url : null,
30
30
  openmrsFetch,
31
+ { errorRetryCount: 2 },
31
32
  );
32
33
  const appointments = data?.data?.map((appointment) => ({
33
34
  name: appointment.patient.name,
@@ -49,7 +50,9 @@ export const useEarlyAppointmentList = (startDate?: string) => {
49
50
  const forDate = startDate ? startDate : appointmentDate;
50
51
  const url = `/ws/rest/v1/appointment/earlyAppointment?forDate=${forDate}`;
51
52
 
52
- const { data, error, isLoading } = useSWR<{ data: Array<AppointmentPatientList> }>(url, openmrsFetch);
53
+ const { data, error, isLoading } = useSWR<{ data: Array<AppointmentPatientList> }>(url, openmrsFetch, {
54
+ errorRetryCount: 2,
55
+ });
53
56
  const appointments = data?.data?.map((appointment) => ({
54
57
  name: appointment.patient.name,
55
58
  patientUuid: appointment.patient.uuid,
@@ -23,6 +23,7 @@ export const useAppointmentsCalendar = (forDate: string, period: string) => {
23
23
  const { data, error, isLoading } = useSWR<{ data: Array<CalendarEvent> }>(
24
24
  startDate && endDate ? url : null,
25
25
  openmrsFetch,
26
+ { errorRetryCount: 2 },
26
27
  );
27
28
  const results =
28
29
  data?.data.map((event) => ({
@@ -1,25 +1,24 @@
1
1
  import { getGlobalStore } from '@openmrs/esm-framework';
2
- import { useEffect, useState } from 'react';
2
+ import { useCallback, useEffect, useState } from 'react';
3
3
 
4
- interface OverlayStore {
4
+ export interface OverlayStore {
5
5
  isOverlayOpen: boolean;
6
- // TODO: Fix this more conclusively
7
6
  component?: any;
8
7
  header: string;
9
8
  }
10
9
 
11
- const initialState = { isOverlayOpen: false, component: Function, header: '' };
10
+ const initialState: OverlayStore = { isOverlayOpen: false, header: '' };
12
11
 
13
12
  const getOverlayStore = () => {
14
13
  return getGlobalStore('appointment-store', initialState);
15
14
  };
16
15
 
17
- export const launchOverlay = (headerTitle: string, componentToRender) => {
16
+ export const launchOverlay = (headerTitle: string, componentToRender: any) => {
18
17
  const store = getOverlayStore();
19
18
  store.setState({ isOverlayOpen: true, component: componentToRender, header: headerTitle });
20
19
  };
21
20
 
22
- export const closeOverlay = () => {
21
+ export const closeOverlay = (): void => {
23
22
  const store = getOverlayStore();
24
23
  store.setState({ component: null, isOverlayOpen: false });
25
24
  };
@@ -27,17 +26,20 @@ export const closeOverlay = () => {
27
26
  export const useOverlay = () => {
28
27
  const [overlay, setOverlay] = useState<OverlayStore>();
29
28
 
29
+ const update = useCallback((state: OverlayStore) => {
30
+ setOverlay(state);
31
+ }, []);
32
+
30
33
  useEffect(() => {
31
- function update(state: OverlayStore) {
32
- setOverlay(state);
33
- }
34
34
  update(getOverlayStore().getState());
35
35
  getOverlayStore().subscribe(update);
36
- }, []);
36
+ }, [update]);
37
+
38
+ const { isOverlayOpen, component, header } = overlay ?? {};
37
39
 
38
40
  return {
39
- isOverlayOpen: overlay?.isOverlayOpen,
40
- component: overlay?.component,
41
- header: overlay?.header,
41
+ isOverlayOpen,
42
+ component,
43
+ header,
42
44
  };
43
45
  };
@@ -15,6 +15,6 @@ export interface Response {
15
15
  export function useUnscheduledAppointments() {
16
16
  const fromData = useAppointmentDate();
17
17
  const url = `/ws/rest/v1/appointment/unScheduledAppointment?forDate=${fromData}`;
18
- const { data, error, isLoading } = useSWR<{ data: Array<Response> }>(url, openmrsFetch);
18
+ const { data, error, isLoading } = useSWR<{ data: Array<Response> }>(url, openmrsFetch, { errorRetryCount: 2 });
19
19
  return { isLoading, data: data?.data ?? [], error };
20
20
  }
@@ -8,19 +8,12 @@ import styles from './overlay.scss';
8
8
  const Overlay: React.FC = () => {
9
9
  const { header, component, isOverlayOpen } = useOverlay();
10
10
  const layout = useLayoutType();
11
-
11
+ const overlayClass = layout !== 'tablet' ? styles.desktopOverlay : styles.tabletOverlay;
12
12
  return (
13
13
  <>
14
14
  {isOverlayOpen && (
15
- <div className={layout !== 'tablet' ? styles.desktopOverlay : styles.tabletOverlay}>
16
- {layout !== 'tablet' ? (
17
- <div className={styles.desktopHeader}>
18
- <div className={styles.headerContent}>{header}</div>
19
- <Button className={styles.closePanelButton} onClick={() => closeOverlay()} kind="ghost" hasIconOnly>
20
- <Close size={16} />
21
- </Button>
22
- </div>
23
- ) : (
15
+ <div className={overlayClass}>
16
+ {layout === 'tablet' && (
24
17
  <Header onClick={() => closeOverlay()} aria-label="Tablet overlay" className={styles.tabletOverlayHeader}>
25
18
  <Button hasIconOnly>
26
19
  <ArrowLeft size={16} />
@@ -28,7 +21,16 @@ const Overlay: React.FC = () => {
28
21
  <div className={styles.headerContent}>{header}</div>
29
22
  </Header>
30
23
  )}
31
- <div>{component}</div>
24
+
25
+ {layout !== 'tablet' && (
26
+ <div className={styles.desktopHeader}>
27
+ <div className={styles.headerContent}>{header}</div>
28
+ <Button className={styles.closePanelButton} onClick={() => closeOverlay()} kind="ghost" hasIconOnly>
29
+ <Close size={16} />
30
+ </Button>
31
+ </div>
32
+ )}
33
+ {component}
32
34
  </div>
33
35
  )}
34
36
  </>
@@ -5,7 +5,6 @@
5
5
  "addPatientToQueue": "Add patient to queue",
6
6
  "age": "Age",
7
7
  "all": "All",
8
- "anotherVisitType": "Start another visit type",
9
8
  "appointmentCancelError": "Error cancelling appointment",
10
9
  "appointmentCancelled": "Appointment Cancelled",
11
10
  "appointmentColor": "Appointment color",
@@ -27,7 +26,6 @@
27
26
  "appointmentServiceCreate": "Appointment service created successfully",
28
27
  "appointmentServiceName": "Appointment service name",
29
28
  "back": "Back",
30
- "backToSearchResults": "Back to search results",
31
29
  "calendar": "Calendar",
32
30
  "cameEarly": "Came Early",
33
31
  "cancel": "Cancel",
@@ -57,7 +55,6 @@
57
55
  "durationMins": "Duration min",
58
56
  "editAppointment": "Edit Appointment",
59
57
  "editAppointments": "Edit Appointment",
60
- "emergency": "Emergency",
61
58
  "emptyStateText": "There are no {displayText} to display",
62
59
  "encounters": "Encounters",
63
60
  "encounterType": "Encounter type",
@@ -65,8 +62,6 @@
65
62
  "errorMessage": "Error canceling the appointment",
66
63
  "facility": "Facility",
67
64
  "filter": "Filter",
68
- "futureScheduledVisits": " {count, plural, one{{count} visit} other{{count} visits}} scheduled for dates in the future",
69
- "futureScheduledVisits_plural": "",
70
65
  "gender": "Gender",
71
66
  "getAppointmentReminder": "Would you like to get a reminder about this appointment?",
72
67
  "highestServiceVolume": "High volume service: {time}",
@@ -89,7 +84,6 @@
89
84
  "noPreviousVisitFound": "No previous visit found",
90
85
  "notArrived": "Not arrived",
91
86
  "notes": "Notes",
92
- "notUrgent": "Not Urgent",
93
87
  "or": "or",
94
88
  "patientDetails": "Patient Details",
95
89
  "patientName": "Patient name",
@@ -97,15 +91,12 @@
97
91
  "patientSearch": "Patient search",
98
92
  "phoneNumber": "Phone number",
99
93
  "prev": "Prev",
100
- "priority": "Priority",
101
94
  "provider": "Provider",
102
95
  "providers": "Providers",
103
96
  "providersAvailableToday": "Providers available: {time}",
104
97
  "queueAddedSuccessfully": "",
105
98
  "queueEntryError": "Error adding patient to the queue",
106
99
  "reasonForChanges": "Reason For Changes",
107
- "recentScheduledVisits": "{count, plural, one{{count} visit} other{{count} visits}} scheduled for +/- 7 days",
108
- "recentScheduledVisits_plural": "",
109
100
  "rescheduled": "Rescheduled",
110
101
  "save": "Save",
111
102
  "scheduled": "Scheduled",