Skip to content

Commit

Permalink
feat(schedules): weekend meeting autofill
Browse files Browse the repository at this point in the history
  • Loading branch information
rhahao committed Aug 3, 2024
1 parent 35fee1a commit 1ce952a
Show file tree
Hide file tree
Showing 4 changed files with 252 additions and 5 deletions.
209 changes: 208 additions & 1 deletion src/features/meetings/schedule_autofill/useScheduleAutofill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
midweekMeetingClassCountState,
midweekMeetingOpeningPrayerAutoAssign,
userDataViewState,
weekendMeetingOpeningPrayerAutoAssignState,
} from '@states/settings';
import {
schedulesAutofillSaveAssignment,
Expand All @@ -27,6 +28,7 @@ import {
sourcesCheckLCElderAssignment,
} from '@services/app/sources';
import { dbSchedBulkUpdate } from '@services/dexie/schedules';
import { personsState } from '@states/persons';

const useScheduleAutofill = (
meeting: ScheduleAutofillType['meeting'],
Expand All @@ -38,14 +40,18 @@ const useScheduleAutofill = (
assignmentsHistoryState
);

const persons = useRecoilValue(personsState);
const schedules = useRecoilValue(schedulesState);
const sources = useRecoilValue(sourcesState);
const dataView = useRecoilValue(userDataViewState);
const classCount = useRecoilValue(midweekMeetingClassCountState);
const lang = useRecoilValue(JWLangState);
const mmOpenPrayerAuto = useRecoilValue(
midweekMeetingOpeningPrayerAutoAssign
);
const lang = useRecoilValue(JWLangState);
const wmOpenPrayerAuto = useRecoilValue(
weekendMeetingOpeningPrayerAutoAssignState
);

const [startWeek, setStartWeek] = useState('');
const [endWeek, setEndWeek] = useState('');
Expand Down Expand Up @@ -646,6 +652,203 @@ const useScheduleAutofill = (
setAssignmentsHistory(history);
};

const handleAutofillWeekend = async (weeksList: SchedWeekType[]) => {
let main = '';
let selected: PersonType;

// create a shallow copy of schedules and history to improve autofill speed
const weeksAutofill = structuredClone(weeksList);
const historyAutofill = structuredClone(assignmentsHistory);

// #region Assign Speakers
for await (const schedule of weeksAutofill) {
const weekType =
schedule.midweek_meeting.week_type.find(
(record) => record.type === dataView
).value || Week.NORMAL;

const noMeeting =
weekType === Week.ASSEMBLY ||
weekType == Week.CONVENTION ||
weekType === Week.MEMORIAL ||
weekType === Week.NO_MEETING;

if (!noMeeting) {
if (weekType !== Week.CO_VISIT) {
const talkType =
schedule.weekend_meeting.public_talk_type.find(
(record) => record.type === dataView
).value || 'localSpeaker';

if (talkType === 'localSpeaker') {
// #region Speaker 1
main =
schedule.weekend_meeting.speaker.part_1.find(
(record) => record.type === dataView
)?.value || '';

if (main.length === 0) {
selected = await schedulesSelectRandomPerson({
type: AssignmentCode.WM_SpeakerSymposium,
week: schedule.weekOf,
history: historyAutofill,
});

if (selected) {
await schedulesAutofillSaveAssignment({
assignment: 'WM_Speaker_Part1',
history: historyAutofill,
schedule,
value: selected,
});
}
}
// #endregion

// #region Speaker 2
if (selected) {
const speaker1 = persons.find(
(record) => record.person_uid === selected.person_uid
);
const speakerSymposium = speaker1.person_data.assignments.find(
(record) =>
record._deleted === false &&
record.code === AssignmentCode.WM_SpeakerSymposium
);

if (speakerSymposium) {
main =
schedule.weekend_meeting.speaker.part_2.find(
(record) => record.type === dataView
)?.value || '';

if (main.length === 0) {
selected = await schedulesSelectRandomPerson({
type: AssignmentCode.WM_Speaker,
week: schedule.weekOf,
history: historyAutofill,
});

if (selected) {
await schedulesAutofillSaveAssignment({
assignment: 'WM_Speaker_Part2',
history: historyAutofill,
schedule,
value: selected,
});
}
}
}
}

// #endregion
}
}
}
}
// #endregion

// #region Assign other parts
for await (const schedule of weeksAutofill) {
const weekType =
schedule.midweek_meeting.week_type.find(
(record) => record.type === dataView
).value || Week.NORMAL;

const noMeeting =
weekType === Week.ASSEMBLY ||
weekType == Week.CONVENTION ||
weekType === Week.MEMORIAL ||
weekType === Week.NO_MEETING;

if (!noMeeting) {
// #region Chairman
main =
schedule.weekend_meeting.chairman.find(
(record) => record.type === dataView
)?.value || '';

if (main.length === 0) {
selected = await schedulesSelectRandomPerson({
type: AssignmentCode.WM_Chairman,
week: schedule.weekOf,
history: historyAutofill,
});

if (selected) {
await schedulesAutofillSaveAssignment({
assignment: 'WM_Chairman',
history: historyAutofill,
schedule,
value: selected,
});
}
}
// #endregion

// #region Opening Prayer
if (!wmOpenPrayerAuto) {
main =
schedule.weekend_meeting.opening_prayer.find(
(record) => record.type === dataView
)?.value || '';

if (main.length === 0) {
selected = await schedulesSelectRandomPerson({
type: AssignmentCode.WM_Prayer,
week: schedule.weekOf,
history: historyAutofill,
});

if (selected) {
await schedulesAutofillSaveAssignment({
assignment: 'WM_OpeningPrayer',
history: historyAutofill,
schedule,
value: selected,
});
}
}
}
// #endregion

// #region Opening Prayer
if (weekType !== Week.CO_VISIT) {
main =
schedule.weekend_meeting.wt_study.reader.find(
(record) => record.type === dataView
)?.value || '';

if (main.length === 0) {
selected = await schedulesSelectRandomPerson({
type: AssignmentCode.WM_WTStudyReader,
week: schedule.weekOf,
history: historyAutofill,
});

if (selected) {
await schedulesAutofillSaveAssignment({
assignment: 'WM_WTStudy_Reader',
history: historyAutofill,
schedule,
value: selected,
});
}
}
}
// #endregion
}
}
// #endregion

// save shallow copy to indexeddb
await dbSchedBulkUpdate(weeksAutofill);

// update assignments history
const history = await schedulesBuildHistoryList();
setAssignmentsHistory(history);
};

const handleStartAutoFill = async () => {
if (startWeek.length === 0 || endWeek.length === 0) return;

Expand All @@ -660,6 +863,10 @@ const useScheduleAutofill = (
await handleAutofillMidweek(weeksList);
}

if (meeting === 'weekend') {
await handleAutofillWeekend(weeksList);
}

setIsProcessing(false);
onClose?.();
} catch (error) {
Expand Down
19 changes: 16 additions & 3 deletions src/pages/meetings/weekend/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box } from '@mui/material';
import { IconGenerate, IconPrint, IconPublish } from '@components/icons';
import { WeekSelector } from '@features/index';
import { ScheduleAutofillDialog, WeekSelector } from '@features/index';
import { useAppTranslation, useBreakpoints } from '@hooks/index';
import useWeekend from './useWeekend';
import Button from '@components/button';
Expand All @@ -12,7 +12,8 @@ const WeekendMeeting = () => {

const { desktopUp } = useBreakpoints();

const { hasWeeks } = useWeekend();
const { hasWeeks, openAutofill, handleCloseAutofill, handleOpenAutofill } =
useWeekend();

return (
<Box
Expand All @@ -22,6 +23,14 @@ const WeekendMeeting = () => {
flexDirection: 'column',
}}
>
{openAutofill && (
<ScheduleAutofillDialog
meeting="weekend"
open={openAutofill}
onClose={handleCloseAutofill}
/>
)}

<PageTitle
title={t('tr_weekendMeeting')}
buttons={
Expand All @@ -30,7 +39,11 @@ const WeekendMeeting = () => {
<Button variant="secondary" startIcon={<IconPrint />}>
{t('tr_export')}
</Button>
<Button variant="secondary" startIcon={<IconGenerate />}>
<Button
variant="secondary"
startIcon={<IconGenerate />}
onClick={handleOpenAutofill}
>
{t('tr_autofill')}
</Button>
<Button variant="main" startIcon={<IconPublish />}>
Expand Down
22 changes: 21 additions & 1 deletion src/pages/meetings/weekend/useWeekend.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import { sourcesFormattedState } from '@states/sources';

const useWeekend = () => {
const sources = useRecoilValue(sourcesFormattedState);

const [openAutofill, setOpenAutofill] = useState(false);
const [openExport, setOpenExport] = useState(false);

const hasWeeks = sources.length > 0;

return { hasWeeks };
const handleOpenAutofill = () => setOpenAutofill(true);

const handleCloseAutofill = () => setOpenAutofill(false);

const handleOpenExport = () => setOpenExport(true);

const handleCloseExport = () => setOpenExport(false);

return {
hasWeeks,
handleCloseAutofill,
handleOpenAutofill,
openAutofill,
openExport,
handleOpenExport,
handleCloseExport,
};
};

export default useWeekend;
7 changes: 7 additions & 0 deletions src/services/app/schedules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,13 @@ export const schedulesSelectRandomPerson = async (data: {
);
}

if (data.type === AssignmentCode.WM_SpeakerSymposium) {
personsElligible = applyAssignmentFilters(persons, [
data.type,
AssignmentCode.WM_Speaker,
]);
}

if (personsElligible.length > 0) {
// 1st rule: no part
selected = await schedulesPersonNoPart({
Expand Down

0 comments on commit 1ce952a

Please sign in to comment.