mirror of
https://github.com/sechan100/daily-routine-2.git
synced 2026-07-22 05:37:51 +00:00
fix: routine properties의 finished를 enable로 변경하고 delete를 복구
This commit is contained in:
parent
db402b97ef
commit
f12e70530f
6 changed files with 65 additions and 42 deletions
|
|
@ -25,19 +25,16 @@ const validateName = ({
|
|||
*/
|
||||
const validateRoutineProperties = (p: any): Result<RoutineProperties, string> => {
|
||||
if(typeof p !== 'object'){
|
||||
return err('RoutineProperties validation target is not object.');
|
||||
}
|
||||
const propsErr = (propertyName: string, value: any, msg?: string): Err<RoutineProperties, string> => {
|
||||
return err(`[Invalid RoutineProperties]: ${msg??"invalid format"}(${propertyName}: ${value})`);
|
||||
return err('Internal error: Invalid frontmatter format');
|
||||
}
|
||||
|
||||
if(
|
||||
'order' in p &&
|
||||
typeof p.order === 'number'
|
||||
){
|
||||
if(p.order < 0) return propsErr('order', p.order, "Order must be a non-negative integer.");
|
||||
if(p.order < 0) return err("Order must be a non-negative integer.");
|
||||
} else {
|
||||
return propsErr('order', p.order);
|
||||
return err("property 'order' is missing or not a number.");
|
||||
}
|
||||
|
||||
if(
|
||||
|
|
@ -46,7 +43,7 @@ const validateRoutineProperties = (p: any): Result<RoutineProperties, string> =>
|
|||
){
|
||||
//
|
||||
} else {
|
||||
return propsErr('group', p.group);
|
||||
return err("property 'group' is missing or not a existing group name.");
|
||||
}
|
||||
|
||||
if(
|
||||
|
|
@ -55,16 +52,16 @@ const validateRoutineProperties = (p: any): Result<RoutineProperties, string> =>
|
|||
){
|
||||
//
|
||||
} else {
|
||||
return propsErr('showOnCalendar', p.showOnCalendar);
|
||||
return err("property 'showOnCalendar' is missing or not a boolean.");
|
||||
}
|
||||
|
||||
if(
|
||||
'activeCriteria' in p &&
|
||||
typeof p.activeCriteria === 'string'
|
||||
){
|
||||
if(!["week", "month"].includes(p.activeCriteria)) return propsErr('activeCriteria', p.activeCriteria);
|
||||
if(!["week", "month"].includes(p.activeCriteria)) return err("property 'activeCriteria' must be either 'week' or 'month'");
|
||||
} else {
|
||||
return propsErr('activeCriteria', p.activeCriteria);
|
||||
return err("property 'activeCriteria' is missing or not a string.");
|
||||
}
|
||||
|
||||
if(
|
||||
|
|
@ -72,11 +69,10 @@ const validateRoutineProperties = (p: any): Result<RoutineProperties, string> =>
|
|||
Array.isArray(p.daysOfWeek)
|
||||
){
|
||||
for(const d of p.daysOfWeek){
|
||||
if(typeof d !== 'string') return propsErr('daysOfWeek', p.daysOfWeek, `Invalid day of week: ${d}`);
|
||||
if(!keys(DayOfWeek).includes(d)) return propsErr('daysOfWeek', p.daysOfWeek, `Invalid day of week: ${d}`);
|
||||
if(!keys(DayOfWeek).includes(d)) return err(`Invalid property 'dayOfWeek': ${d}`);
|
||||
}
|
||||
} else {
|
||||
return propsErr('daysOfWeek', p.daysOfWeek);
|
||||
return err("property 'daysOfWeek' is missing or not an array of dayOfWeek.");
|
||||
}
|
||||
|
||||
if(
|
||||
|
|
@ -84,20 +80,20 @@ const validateRoutineProperties = (p: any): Result<RoutineProperties, string> =>
|
|||
Array.isArray(p.daysOfMonth)
|
||||
){
|
||||
for(const d of p.daysOfMonth){
|
||||
if(typeof d !== 'number') return propsErr('daysOfMonth', p.daysOfMonth, `Invalid day of month: ${d}`);
|
||||
if(d < 0 || d > 31) return propsErr('daysOfMonth', p.daysOfMonth, `Range of day of month is 0~31: ${d}`);
|
||||
if(typeof d !== 'number') return err(`property 'DayOfMonth' must be a number: ${d}`);
|
||||
if(d < 0 || d > 31) return err(`property 'DayOfMonth' must be between 0 and 31: ${d}`);
|
||||
}
|
||||
} else {
|
||||
return propsErr('daysOfMonth', p.daysOfMonth);
|
||||
return err("property 'daysOfMonth' is missing or not an array of number.");
|
||||
}
|
||||
|
||||
if(
|
||||
'finished' in p &&
|
||||
typeof p.finished === 'boolean'
|
||||
'enabled' in p &&
|
||||
typeof p.enabled === 'boolean'
|
||||
){
|
||||
//
|
||||
} else {
|
||||
return propsErr('finished', p.finished);
|
||||
return err("property 'enabled' is missing or not a boolean.");
|
||||
}
|
||||
|
||||
return ok(p as RoutineProperties);
|
||||
|
|
@ -109,7 +105,7 @@ const validateRoutineProperties = (p: any): Result<RoutineProperties, string> =>
|
|||
const isDueTo = (routine: Routine, day: Day): boolean => {
|
||||
const p = routine.properties;
|
||||
|
||||
if(p.finished) return false;
|
||||
if(!p.enabled) return false;
|
||||
|
||||
if(p.activeCriteria === "month"){
|
||||
const days = Array.from(p.daysOfMonth);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export type RoutineProperties = {
|
|||
activeCriteria: "week" | "month";
|
||||
daysOfWeek: DayOfWeek[];
|
||||
daysOfMonth: number[];
|
||||
finished: boolean;
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export type RoutineGroup = RoutineElement & {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ensureArchive } from "@entities/archives";
|
||||
import { compose } from "@shared/utils/compose";
|
||||
import { fileAccessor } from "@shared/file/file-accessor";
|
||||
import { stringifyYaml, TFile } from "obsidian";
|
||||
import { Notice, stringifyYaml, TFile } from "obsidian";
|
||||
import { GROUP_PREFIX, ROUTINE_PATH } from "./utils";
|
||||
import { parseFrontmatter } from "@shared/file/parse-frontmatter";
|
||||
import { RoutineEntity } from "../domain/routine";
|
||||
|
|
@ -12,7 +12,10 @@ import { Routine } from "../domain/routine.type";
|
|||
const parse = async (file: TFile): Promise<Routine> => {
|
||||
const content = await fileAccessor.readFileAsReadonly(file);
|
||||
const result = RoutineEntity.validateRoutineProperties(parseFrontmatter(content));
|
||||
if(result.isErr()) throw new Error(`[Routine '${file.basename}' Parse Error] ${result.error}`);
|
||||
if(result.isErr()){
|
||||
new Notice(`Routine '${file.basename}' frontmatter error: ${result.error}`);
|
||||
throw new Error(`[Routine '${file.basename}' Parse Error] ${result.error}`);
|
||||
}
|
||||
return {
|
||||
name: file.basename,
|
||||
routineElementType: "routine",
|
||||
|
|
@ -32,7 +35,7 @@ export interface RoutineQuery {
|
|||
}
|
||||
export interface RoutineRepository extends RoutineQuery {
|
||||
persist(entity: Routine): Promise<boolean>;
|
||||
finish(routineName: string): Promise<void>;
|
||||
delete(routineName: string): Promise<void>;
|
||||
changeName(originalName: string, newName: string): Promise<void>;
|
||||
update(routine: Routine): Promise<Routine>;
|
||||
updateAll(routines: Routine[]): Promise<Routine[]>;
|
||||
|
|
@ -66,11 +69,14 @@ export const routineRepository: RoutineRepository = {
|
|||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
async finish(routineName: string){
|
||||
const routine = await routineRepository.load(routineName);
|
||||
routine.properties.finished = true;
|
||||
await routineRepository.update(routine);
|
||||
|
||||
async delete(routineName: string){
|
||||
const composed = compose(
|
||||
fileAccessor.deleteFile,
|
||||
fileAccessor.loadFile,
|
||||
ROUTINE_PATH
|
||||
);
|
||||
await composed(routineName);
|
||||
},
|
||||
|
||||
async changeName(originalName: string, newName: string){
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export const createNewRoutine = (): Routine => {
|
|||
activeCriteria: "week",
|
||||
daysOfWeek: Day.getDaysOfWeek(),
|
||||
daysOfMonth: [Day.now().date],
|
||||
finished: false
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,18 +19,34 @@ export const RoutineTaskWidget = React.memo(({ task, parent }: RoutineTaskProps)
|
|||
const { mergeNotes } = useRoutineMutationMerge();
|
||||
const { note, setNote } = useRoutineNote();
|
||||
|
||||
const finishRoutine = useCallback(async () => {
|
||||
const finishConfirm = await doConfirm({
|
||||
title: "Finish Routine",
|
||||
confirmText: "Finish",
|
||||
description: `Are you sure you want to finish the routine ${task.name}?`,
|
||||
const disableRoutine = useCallback(async () => {
|
||||
const disableConfirm = await doConfirm({
|
||||
title: "Disable Routine",
|
||||
confirmText: "Disable",
|
||||
description: `Are you sure you want to disable the routine ${task.name}?`,
|
||||
confirmBtnVariant: "accent"
|
||||
})
|
||||
if(!finishConfirm) return;
|
||||
if(!disableConfirm) return;
|
||||
|
||||
await routineRepository.finish(task.name);
|
||||
const routine = await routineRepository.load(task.name);
|
||||
routine.properties.enabled = false;
|
||||
await routineRepository.update(routine);
|
||||
mergeNotes();
|
||||
new Notice(`Routine ${task.name} has been finished 🪄`);
|
||||
new Notice(`Routine '${task.name}' disabled.`);
|
||||
}, [mergeNotes, task.name])
|
||||
|
||||
const deleteRoutine = useCallback(async () => {
|
||||
const deleteConfirm = await doConfirm({
|
||||
title: "Delete Routine",
|
||||
confirmText: "Delete",
|
||||
description: `Are you sure you want to delete the routine ${task.name}?`,
|
||||
confirmBtnVariant: "destructive"
|
||||
})
|
||||
if(!deleteConfirm) return;
|
||||
|
||||
await routineRepository.delete(task.name);
|
||||
mergeNotes();
|
||||
new Notice(`Routine '${task.name}' deleted.`);
|
||||
}, [mergeNotes, task.name])
|
||||
|
||||
const onOptionMenu = useCallback((m: Menu) => {
|
||||
|
|
@ -51,11 +67,16 @@ export const RoutineTaskWidget = React.memo(({ task, parent }: RoutineTaskProps)
|
|||
});
|
||||
})
|
||||
m.addItem(i => {
|
||||
i.setTitle("Finish");
|
||||
i.setTitle("Disable");
|
||||
i.setIcon("alarm-clock-off");
|
||||
i.onClick(finishRoutine);
|
||||
i.onClick(disableRoutine);
|
||||
})
|
||||
}, [RoutineOptionModal, finishRoutine, note, setNote, task.name])
|
||||
m.addItem(i => {
|
||||
i.setTitle("Delete");
|
||||
i.setIcon("trash");
|
||||
i.onClick(deleteRoutine);
|
||||
})
|
||||
}, [RoutineOptionModal, deleteRoutine, disableRoutine, note, setNote, task.name])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export const deleteGroup = async (note: RoutineNote, groupName: string, deleteSu
|
|||
if(deleteSubTasks){
|
||||
const deleteTargets = routines.filter(routine => routine.properties.group === groupName);
|
||||
for(const target of deleteTargets){
|
||||
await routineRepository.finish(target.name);
|
||||
await routineRepository.delete(target.name);
|
||||
}
|
||||
} else {
|
||||
const ungroupTarget = routines.filter(routine => routine.properties.group === groupName);
|
||||
|
|
|
|||
Loading…
Reference in a new issue