Added basic list view

This commit is contained in:
Akaswan 2025-07-17 09:34:28 -05:00
parent ffcd1385c0
commit 9ea920f75c
7 changed files with 212 additions and 30 deletions

View file

@ -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<Project[]>(() => getInitialData().projects);
const [nextProjectId, setNextProjectId] = useState<number>(() => getInitialData().nextProjectId);
const [nextTaskId, setNextTaskId] = useState<number>(() => getInitialData().nextTaskId);
const [projects, setProjects] = useState<Project[]>(
() => getInitialData().projects
);
const [nextProjectId, setNextProjectId] = useState<number>(
() => getInitialData().nextProjectId
);
const [nextTaskId, setNextTaskId] = useState<number>(
() => getInitialData().nextTaskId
);
const [viewType, setViewType] = useState<number>(
() => 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}
/>
<Table
projects={projects}
nextProjectId={nextProjectId}
handleProjectNameChange={handleProjectNameChange}
createNewProject={createNewProject}
dates={dates}
addTaskToProject={addTaskToProject}
removeProject={removeProject}
removeTask={removeTask}
nextTaskId={nextTaskId}
handleTaskNameChange={handleTaskNameChange}
taskStatuses={taskStatuses}
editTaskStatus={editTaskStatus}
moveTask={moveTask}
/>
{viewType === 0 && (
<Table
projects={projects}
nextProjectId={nextProjectId}
handleProjectNameChange={handleProjectNameChange}
createNewProject={createNewProject}
dates={dates}
addTaskToProject={addTaskToProject}
removeProject={removeProject}
removeTask={removeTask}
nextTaskId={nextTaskId}
handleTaskNameChange={handleTaskNameChange}
taskStatuses={taskStatuses}
editTaskStatus={editTaskStatus}
moveTask={moveTask}
/>
)}
{viewType === 1 && (
<ListView
projects={projects}
dates={dates}/>
)}
</div>
);
};

View file

@ -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<ListViewProps> = ({ 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 (
<div className="list-view">
<table className="list-table">
<thead className="list-table-header">
<tr>
<th>{addDays(today, 1).toDateString()}</th>
<th>Project</th>
<th>Status</th>
</tr>
</thead>
<tbody className="list-table-body">
{todaysTasks.map((task) => (
<tr key={task.id}>
<td>{task.name}</td>
<td>{task.projectName}</td>
<td>{task.status.name}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default ListView;

View file

@ -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<TopBarProps> = ({ incrementDates, decrementDates, setDatesToThisWeek }) => {
const TopBar: React.FC<TopBarProps> = ({
incrementDates,
decrementDates,
setDatesToThisWeek,
viewType,
setViewType,
}) => {
return (
<div className="top-bar">
<div className="view-chooser">
<div
className={`table-view-chooser ${
viewType === 0 ? "selected" : "unselected"
}`}
onClick={() => setViewType(0)}
>
<Table2 className="table-icon" />
</div>
<div
className={`list-view-chooser ${
viewType === 1 ? "selected" : "unselected"
}`}
onClick={() => setViewType(1)}
>
<List className="list-icon" />
</div>
</div>
<div className="date-increment-container">
<ChevronLeft onClick={decrementDates} className="date-increment left-increment" />
<div onClick={setDatesToThisWeek} className="date-display">
{new Date().toDateString()}
</div>
<ChevronRight onClick={incrementDates} className="date-increment right-increment" />
<ChevronLeft
onClick={decrementDates}
className="date-increment left-increment"
/>
<div onClick={setDatesToThisWeek} className="date-display">
{new Date().toDateString()}
</div>
<ChevronRight
onClick={incrementDates}
className="date-increment right-increment"
/>
</div>
</div>
);

View file

@ -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);

View file

@ -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);