mirror of
https://github.com/akaswan/table-list.git
synced 2026-07-22 05:49:21 +00:00
Added basic list view
This commit is contained in:
parent
ffcd1385c0
commit
9ea920f75c
7 changed files with 212 additions and 30 deletions
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
53
src/main/components/ListView.tsx
Normal file
53
src/main/components/ListView.tsx
Normal 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;
|
||||
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
70
styles.css
70
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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue