refactor: make Schedules component to tsx (#1644)

This commit is contained in:
Mohamed Muhsin
2023-09-04 18:41:02 +02:00
committed by GitHub
parent 65899b0ef0
commit db07d7a73d
7 changed files with 40 additions and 19 deletions

View File

@@ -8,11 +8,11 @@ import Button from './Button';
import InputWithContent from './InputWithContent';
type SearchProps = {
inputRef: Ref<HTMLInputElement>;
inputRef?: Ref<HTMLInputElement>;
value: string;
onChange: (value: string) => unknown;
placeholder: string;
isInModal: boolean;
isInModal?: boolean;
width?: number;
};
@@ -21,7 +21,7 @@ export default function Search({
value,
onChange,
placeholder,
isInModal,
isInModal = false,
width = 250,
}: SearchProps) {
return (

View File

@@ -2,6 +2,7 @@ import React, { useState } from 'react';
import { useSchedules } from 'loot-core/src/client/data-hooks/schedules';
import { send } from 'loot-core/src/platform/client/fetch';
import { type ScheduleEntity } from 'loot-core/src/types/models';
import { useActions } from '../../hooks/useActions';
import Button from '../common/Button';
@@ -12,18 +13,18 @@ import { Page } from '../Page';
import { SchedulesTable, ROW_HEIGHT } from './SchedulesTable';
export default function Schedules() {
let { pushModal } = useActions();
let [filter, setFilter] = useState('');
const { pushModal } = useActions();
const [filter, setFilter] = useState('');
let scheduleData = useSchedules();
const scheduleData = useSchedules();
if (scheduleData == null) {
return null;
}
let { schedules, statuses } = scheduleData;
const { schedules, statuses } = scheduleData;
function onEdit(id) {
function onEdit(id: ScheduleEntity['id']) {
pushModal('schedule-edit', { id });
}
@@ -35,7 +36,8 @@ export default function Schedules() {
pushModal('schedules-discover');
}
async function onAction(name, id) {
// @todo: replace name: string with enum
async function onAction(name: string, id: ScheduleEntity['id']) {
switch (name) {
case 'post-transaction':
await send('schedule/post-transaction', { id });
@@ -44,7 +46,9 @@ export default function Schedules() {
await send('schedule/skip-next-date', { id });
break;
case 'complete':
await send('schedule/update', { schedule: { id, completed: true } });
await send('schedule/update', {
schedule: { id, completed: true },
});
break;
case 'restart':
await send('schedule/update', {
@@ -83,6 +87,9 @@ export default function Schedules() {
onSelect={onEdit}
onAction={onAction}
style={{ backgroundColor: 'white' }}
// @todo: Remove following props after typing SchedulesTable
minimal={undefined}
tableStyle={undefined}
/>
</View>

View File

@@ -18,7 +18,6 @@ export default function EncryptionSettings() {
const missingCryptoAPI = !(window.crypto && crypto.subtle);
function onChangeKey() {
// @ts-expect-error useActions() type does not properly handle overloads
pushModal('create-encryption-key', { recreate: true });
}

View File

@@ -76,7 +76,6 @@ export function loadBudget(id: string, loadingText = '', options = {}) {
);
if (showBackups) {
// @ts-expect-error manager modals are not yet typed
dispatch(pushModal('load-backup', { budgetId: id }));
}
} else {

View File

@@ -15,12 +15,15 @@ export function pushModal<M extends keyof ModalWithOptions>(
options: ModalWithOptions[M],
): PushModalAction;
export function pushModal(name: OptionlessModal): PushModalAction;
export function pushModal<M extends ModalType>(
name: M,
options?: FinanceModals[M],
): PushModalAction;
export function pushModal<M extends ModalType>(
name: M,
options?: FinanceModals[M],
): PushModalAction {
// @ts-expect-error TS is unable to determine that `name` and `options` match
let modal: M = { name, options };
const modal = { name, options };
return { type: constants.PUSH_MODAL, modal };
}

View File

@@ -2,9 +2,10 @@ import React, { createContext, useEffect, useState, useContext } from 'react';
import { type Query } from '../../shared/query';
import { getStatus, getHasTransactionsQuery } from '../../shared/schedules';
import { type ScheduleEntity } from '../../types/models';
import q, { liveQuery } from '../query-helpers';
function loadStatuses(schedules, onData) {
function loadStatuses(schedules: ScheduleEntity[], onData) {
return liveQuery(getHasTransactionsQuery(schedules), onData, {
mapper: data => {
let hasTrans = new Set(data.filter(Boolean).map(row => row.schedule));
@@ -20,8 +21,12 @@ function loadStatuses(schedules, onData) {
}
type UseSchedulesArgs = { transform?: (q: Query) => Query };
type UseSchedulesReturnType = {
schedules: ScheduleEntity[];
statuses: Record<string, ReturnType<typeof getStatus>>;
} | null;
export function useSchedules({ transform }: UseSchedulesArgs = {}) {
let [data, setData] = useState(null);
let [data, setData] = useState<UseSchedulesReturnType | null>(null);
useEffect(() => {
let query = q('schedules').select('*');
@@ -29,14 +34,16 @@ export function useSchedules({ transform }: UseSchedulesArgs = {}) {
scheduleQuery = liveQuery(
transform ? transform(query) : query,
async schedules => {
async (schedules: ScheduleEntity[]) => {
if (scheduleQuery) {
if (statusQuery) {
statusQuery.unsubscribe();
}
statusQuery = loadStatuses(schedules, statuses =>
setData({ schedules, statuses }),
statusQuery = loadStatuses(
schedules,
(statuses: Record<string, ReturnType<typeof getStatus>>) =>
setData({ schedules, statuses }),
);
}
},

View File

@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [muhsinkamil]
---
Refactor Schedules to tsx.