From 9ea920f75c5d8d087b4284468e6617c685569ecf Mon Sep 17 00:00:00 2001 From: Akaswan Date: Thu, 17 Jul 2025 09:34:28 -0500 Subject: [PATCH] Added basic list view --- src/main/components/App.tsx | 67 ++++++++++++------ src/main/components/ListView.tsx | 53 ++++++++++++++ .../components/{Table.tsx => TableView.tsx} | 0 src/main/components/TopBar.tsx | 49 ++++++++++--- src/main/main.ts | 3 +- .../views/{TableView.tsx => TableList.tsx} | 0 styles.css | 70 +++++++++++++++++++ 7 files changed, 212 insertions(+), 30 deletions(-) create mode 100644 src/main/components/ListView.tsx rename src/main/components/{Table.tsx => TableView.tsx} (100%) rename src/main/views/{TableView.tsx => TableList.tsx} (100%) diff --git a/src/main/components/App.tsx b/src/main/components/App.tsx index fe26810..6e0efad 100644 --- a/src/main/components/App.tsx +++ b/src/main/components/App.tsx @@ -1,9 +1,10 @@ /* eslint-disable no-mixed-spaces-and-tabs */ import { useEffect, useState } from "react"; -import { useTableContext } from "../views/TableView"; -import Table from "./Table"; +import { useTableContext } from "../views/TableList"; +import Table from "./TableView"; import TopBar from "./TopBar"; import { format, addDays, subDays } from "date-fns"; +import ListView from "./ListView"; export interface Project { id: number; @@ -53,6 +54,7 @@ const App: React.FC = () => { projects: Project[]; nextProjectId: number; nextTaskId: number; + viewType: number; }; const getInitialData = (): TableData => { @@ -62,13 +64,23 @@ const App: React.FC = () => { projects: [], nextProjectId: 1, nextTaskId: 1, + viewType: 0, // Default to table view } ); }; - const [projects, setProjects] = useState(() => getInitialData().projects); - const [nextProjectId, setNextProjectId] = useState(() => getInitialData().nextProjectId); - const [nextTaskId, setNextTaskId] = useState(() => getInitialData().nextTaskId); + const [projects, setProjects] = useState( + () => getInitialData().projects + ); + const [nextProjectId, setNextProjectId] = useState( + () => getInitialData().nextProjectId + ); + const [nextTaskId, setNextTaskId] = useState( + () => getInitialData().nextTaskId + ); + const [viewType, setViewType] = useState( + () => getInitialData().viewType + ); const incrementDates = () => { setDates((prevDates) => { @@ -215,7 +227,10 @@ const App: React.FC = () => { const saveSpecificData = (key: string, value: unknown): void => { setData((prevData: unknown) => { - const baseData = (typeof prevData === "object" && prevData !== null) ? prevData : {}; + const baseData = + typeof prevData === "object" && prevData !== null + ? prevData + : {}; const newData = { ...baseData, [key]: value }; return newData; }); @@ -249,22 +264,32 @@ const App: React.FC = () => { incrementDates={incrementDates} decrementDates={decrementDates} setDatesToThisWeek={setDatesToThisWeek} + viewType={viewType} + setViewType={setViewType} /> - + {viewType === 0 && ( +
+ )} + + {viewType === 1 && ( + + )} ); }; diff --git a/src/main/components/ListView.tsx b/src/main/components/ListView.tsx new file mode 100644 index 0000000..cd065a3 --- /dev/null +++ b/src/main/components/ListView.tsx @@ -0,0 +1,53 @@ +import { Project } from "./App"; +import { addDays } from "date-fns"; + +interface ListViewProps { + projects: Project[]; + dates: string[]; +} + +const isSameDay = (d1: Date, d2: Date) => { + return ( + d1.getFullYear() === d2.getFullYear() && + d1.getMonth() === d2.getMonth() && + d1.getDate() === d2.getDate() + ); +}; + +const ListView: React.FC = ({ projects, dates }) => { + const today = new Date(dates[0]); + + const todaysTasks = projects.flatMap((project) => + project.tasks + .filter((task) => isSameDay(new Date(task.date), today)) + .map((task) => ({ + ...task, + projectName: project.name, + })) + ); + + return ( +
+
+ + + + + + + + + {todaysTasks.map((task) => ( + + + + + + ))} + +
{addDays(today, 1).toDateString()}ProjectStatus
{task.name}{task.projectName}{task.status.name}
+ + ); +}; + +export default ListView; diff --git a/src/main/components/Table.tsx b/src/main/components/TableView.tsx similarity index 100% rename from src/main/components/Table.tsx rename to src/main/components/TableView.tsx diff --git a/src/main/components/TopBar.tsx b/src/main/components/TopBar.tsx index ce6758a..98fdb65 100644 --- a/src/main/components/TopBar.tsx +++ b/src/main/components/TopBar.tsx @@ -1,20 +1,53 @@ -import { ChevronLeft, ChevronRight } from "lucide-react"; +import { ChevronLeft, ChevronRight, Table2, List } from "lucide-react"; interface TopBarProps { incrementDates: () => void; decrementDates: () => void; - setDatesToThisWeek: () => void; + setDatesToThisWeek: () => void; + viewType: number; + setViewType: (viewType: number) => void; } -const TopBar: React.FC = ({ incrementDates, decrementDates, setDatesToThisWeek }) => { +const TopBar: React.FC = ({ + incrementDates, + decrementDates, + setDatesToThisWeek, + viewType, + setViewType, +}) => { + return (
+
+
setViewType(0)} + > + +
+
setViewType(1)} + > + +
+
- -
- {new Date().toDateString()} -
- + +
+ {new Date().toDateString()} +
+
); diff --git a/src/main/main.ts b/src/main/main.ts index e177b5a..ad6ce8c 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,5 +1,5 @@ import { Plugin, WorkspaceLeaf } from "obsidian"; -import { TableView, TABLE_VIEW_TYPE } from "./views/TableView"; +import { TableView, TABLE_VIEW_TYPE } from "./views/TableList"; export default class TableList extends Plugin { async onload() { @@ -10,6 +10,7 @@ export default class TableList extends Plugin { projects: [], nextProjectId: 0, nextTaskId: 0, + viewType: 0, }; this.saveData(data); diff --git a/src/main/views/TableView.tsx b/src/main/views/TableList.tsx similarity index 100% rename from src/main/views/TableView.tsx rename to src/main/views/TableList.tsx diff --git a/styles.css b/styles.css index 9013f7b..a91b3fc 100644 --- a/styles.css +++ b/styles.css @@ -19,6 +19,62 @@ width: min-content; } +.view-chooser { + position: absolute; + left: 12px; + display: flex; + align-items: center; + margin-right: 8px; +} + +.table-view-chooser{ + height: 36px; + width: 36px; + display: flex; + justify-content: center; + align-items: center; + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + border: var(--border-width) solid var(--background-modifier-border); + background-color: var(--background-secondary); +} + +.table-icon{ + height: 20px; + width: 20px; +} + +.list-view-chooser{ + height: 36px; + width: 36px; + display: flex; + justify-content: center; + align-items: center; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + border-right: var(--border-width) solid var(--background-modifier-border); + border-bottom: var(--border-width) solid var(--background-modifier-border); + border-top: var(--border-width) solid var(--background-modifier-border); + background-color: var(--background-secondary); +} + +.list-icon{ + height: 20px; + width: 20px; +} + +.table-view-chooser.unselected, +.list-view-chooser.unselected { + background-color: var(--background-secondary-alt); + opacity: 0.6; +} + +.table-view-chooser:hover, +.list-view-chooser:hover { + cursor: pointer; + background-color: var(--background-modifier-hover); +} + .date-display { width: max-content; font-weight: bold !important; @@ -216,6 +272,20 @@ background-color: var(--background-secondary); } +/* list view */ +.list-view { + padding: 16px; + display: flex; + flex-direction: column; + gap: 24px; +} + +.list-table-header { + border: var(--border-width) solid var(--background-modifier-border);; +} + + + /* Required */ .warning-container { color: var(--text-normal);