epoch-tui 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +356 -212
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1686,51 +1686,143 @@ var useTheme = () => {
|
|
|
1686
1686
|
|
|
1687
1687
|
// src/contexts/AppContext.tsx
|
|
1688
1688
|
import {
|
|
1689
|
-
createContext as
|
|
1690
|
-
useContext as
|
|
1689
|
+
createContext as createContext4,
|
|
1690
|
+
useContext as useContext4,
|
|
1691
1691
|
useEffect as useEffect3,
|
|
1692
|
-
useState as
|
|
1692
|
+
useState as useState4,
|
|
1693
1693
|
useRef as useRef2,
|
|
1694
|
-
useCallback as
|
|
1694
|
+
useCallback as useCallback3
|
|
1695
1695
|
} from "react";
|
|
1696
|
+
|
|
1697
|
+
// src/contexts/UndoContext.tsx
|
|
1698
|
+
import { createContext as createContext3, useContext as useContext3, useState as useState3, useCallback as useCallback2 } from "react";
|
|
1696
1699
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1697
|
-
var
|
|
1700
|
+
var UndoContext = createContext3(void 0);
|
|
1701
|
+
var MAX_UNDO_STACK_SIZE = 50;
|
|
1702
|
+
function deepClone(obj) {
|
|
1703
|
+
if (obj === null || typeof obj !== "object") {
|
|
1704
|
+
return obj;
|
|
1705
|
+
}
|
|
1706
|
+
if (obj instanceof Date) {
|
|
1707
|
+
return new Date(obj.getTime());
|
|
1708
|
+
}
|
|
1709
|
+
if (Array.isArray(obj)) {
|
|
1710
|
+
return obj.map((item) => deepClone(item));
|
|
1711
|
+
}
|
|
1712
|
+
const cloned = {};
|
|
1713
|
+
for (const key in obj) {
|
|
1714
|
+
if (obj.hasOwnProperty(key)) {
|
|
1715
|
+
cloned[key] = deepClone(obj[key]);
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
return cloned;
|
|
1719
|
+
}
|
|
1720
|
+
var UndoProvider = ({ children }) => {
|
|
1721
|
+
const [undoStack, setUndoStack] = useState3([]);
|
|
1722
|
+
const pushUndoAction = useCallback2(
|
|
1723
|
+
(type, tasks, timeline) => {
|
|
1724
|
+
const action = {
|
|
1725
|
+
type,
|
|
1726
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1727
|
+
previousTasks: deepClone(tasks),
|
|
1728
|
+
previousTimeline: deepClone(timeline)
|
|
1729
|
+
};
|
|
1730
|
+
setUndoStack((prev) => {
|
|
1731
|
+
const newStack = [...prev, action];
|
|
1732
|
+
if (newStack.length > MAX_UNDO_STACK_SIZE) {
|
|
1733
|
+
newStack.shift();
|
|
1734
|
+
}
|
|
1735
|
+
return newStack;
|
|
1736
|
+
});
|
|
1737
|
+
},
|
|
1738
|
+
[]
|
|
1739
|
+
);
|
|
1740
|
+
const undo = useCallback2(() => {
|
|
1741
|
+
if (undoStack.length === 0) {
|
|
1742
|
+
return null;
|
|
1743
|
+
}
|
|
1744
|
+
const action = undoStack[undoStack.length - 1];
|
|
1745
|
+
setUndoStack((prev) => prev.slice(0, -1));
|
|
1746
|
+
return action;
|
|
1747
|
+
}, [undoStack]);
|
|
1748
|
+
const clearUndoStack = useCallback2(() => {
|
|
1749
|
+
setUndoStack([]);
|
|
1750
|
+
}, []);
|
|
1751
|
+
return /* @__PURE__ */ jsx3(
|
|
1752
|
+
UndoContext.Provider,
|
|
1753
|
+
{
|
|
1754
|
+
value: {
|
|
1755
|
+
pushUndoAction,
|
|
1756
|
+
undo,
|
|
1757
|
+
canUndo: undoStack.length > 0,
|
|
1758
|
+
clearUndoStack
|
|
1759
|
+
},
|
|
1760
|
+
children
|
|
1761
|
+
}
|
|
1762
|
+
);
|
|
1763
|
+
};
|
|
1764
|
+
var useUndo = () => {
|
|
1765
|
+
const context = useContext3(UndoContext);
|
|
1766
|
+
if (!context) {
|
|
1767
|
+
throw new Error("useUndo must be used within UndoProvider");
|
|
1768
|
+
}
|
|
1769
|
+
return context;
|
|
1770
|
+
};
|
|
1771
|
+
|
|
1772
|
+
// src/contexts/AppContext.tsx
|
|
1773
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1774
|
+
var AppContext = createContext4(void 0);
|
|
1698
1775
|
var AppProvider = ({ children }) => {
|
|
1699
1776
|
const { data, save, saveNow } = useStorage();
|
|
1777
|
+
const { pushUndoAction, undo, canUndo } = useUndo();
|
|
1700
1778
|
const today = /* @__PURE__ */ new Date();
|
|
1701
|
-
const [selectedDate, setSelectedDate] =
|
|
1779
|
+
const [selectedDate, setSelectedDate] = useState4({
|
|
1702
1780
|
year: today.getFullYear(),
|
|
1703
1781
|
month: today.getMonth(),
|
|
1704
1782
|
day: today.getDate()
|
|
1705
1783
|
});
|
|
1706
|
-
const [tasks, setTasks] =
|
|
1707
|
-
const [timeline, setTimeline] =
|
|
1784
|
+
const [tasks, setTasks] = useState4({});
|
|
1785
|
+
const [timeline, setTimeline] = useState4(
|
|
1708
1786
|
{}
|
|
1709
1787
|
);
|
|
1710
|
-
const [activePane, setActivePane] =
|
|
1711
|
-
const [showHelp, setShowHelp] =
|
|
1788
|
+
const [activePane, setActivePane] = useState4("tasks");
|
|
1789
|
+
const [showHelp, setShowHelp] = useState4(false);
|
|
1712
1790
|
const isInputModeRef = useRef2(false);
|
|
1713
|
-
const [isInputModeState, setIsInputModeState] =
|
|
1714
|
-
const [showOverview, setShowOverview] =
|
|
1715
|
-
const setIsInputMode =
|
|
1791
|
+
const [isInputModeState, setIsInputModeState] = useState4(false);
|
|
1792
|
+
const [showOverview, setShowOverview] = useState4(false);
|
|
1793
|
+
const setIsInputMode = useCallback3((mode) => {
|
|
1716
1794
|
isInputModeRef.current = mode;
|
|
1717
1795
|
setIsInputModeState(mode);
|
|
1718
1796
|
}, []);
|
|
1719
1797
|
const isInputMode = isInputModeRef.current;
|
|
1720
|
-
const [overviewMonth, setOverviewMonth] =
|
|
1798
|
+
const [overviewMonth, setOverviewMonth] = useState4({
|
|
1721
1799
|
year: today.getFullYear(),
|
|
1722
1800
|
month: today.getMonth()
|
|
1723
1801
|
});
|
|
1724
|
-
const [exitConfirmation, setExitConfirmation] =
|
|
1725
|
-
const [showThemeDialog, setShowThemeDialog] =
|
|
1726
|
-
const [showClearTimelineDialog, setShowClearTimelineDialog] =
|
|
1727
|
-
const clearTimelineForDate =
|
|
1802
|
+
const [exitConfirmation, setExitConfirmation] = useState4(false);
|
|
1803
|
+
const [showThemeDialog, setShowThemeDialog] = useState4(false);
|
|
1804
|
+
const [showClearTimelineDialog, setShowClearTimelineDialog] = useState4(false);
|
|
1805
|
+
const clearTimelineForDate = useCallback3((dateStr) => {
|
|
1806
|
+
pushUndoAction("TIMELINE_CLEAR", tasks, timeline);
|
|
1728
1807
|
setTimeline((prev) => {
|
|
1729
1808
|
const newTimeline = { ...prev };
|
|
1730
1809
|
delete newTimeline[dateStr];
|
|
1731
1810
|
return newTimeline;
|
|
1732
1811
|
});
|
|
1733
|
-
}, []);
|
|
1812
|
+
}, [pushUndoAction, tasks, timeline]);
|
|
1813
|
+
const pushUndoableAction = useCallback3(
|
|
1814
|
+
(actionType) => {
|
|
1815
|
+
pushUndoAction(actionType, tasks, timeline);
|
|
1816
|
+
},
|
|
1817
|
+
[pushUndoAction, tasks, timeline]
|
|
1818
|
+
);
|
|
1819
|
+
const performUndo = useCallback3(() => {
|
|
1820
|
+
const action = undo();
|
|
1821
|
+
if (action) {
|
|
1822
|
+
setTasks(action.previousTasks);
|
|
1823
|
+
setTimeline(action.previousTimeline);
|
|
1824
|
+
}
|
|
1825
|
+
}, [undo]);
|
|
1734
1826
|
const initialLoadDone = useRef2(false);
|
|
1735
1827
|
const dataRef = useRef2(data);
|
|
1736
1828
|
const saveRef = useRef2(save);
|
|
@@ -1754,7 +1846,7 @@ var AppProvider = ({ children }) => {
|
|
|
1754
1846
|
});
|
|
1755
1847
|
}
|
|
1756
1848
|
}, [tasks, timeline]);
|
|
1757
|
-
return /* @__PURE__ */
|
|
1849
|
+
return /* @__PURE__ */ jsx4(
|
|
1758
1850
|
AppContext.Provider,
|
|
1759
1851
|
{
|
|
1760
1852
|
value: {
|
|
@@ -1782,14 +1874,17 @@ var AppProvider = ({ children }) => {
|
|
|
1782
1874
|
setShowClearTimelineDialog,
|
|
1783
1875
|
clearTimelineForDate,
|
|
1784
1876
|
isModalOpen: showHelp || showThemeDialog || showOverview || showClearTimelineDialog,
|
|
1785
|
-
saveNow
|
|
1877
|
+
saveNow,
|
|
1878
|
+
pushUndoableAction,
|
|
1879
|
+
performUndo,
|
|
1880
|
+
canUndo
|
|
1786
1881
|
},
|
|
1787
1882
|
children
|
|
1788
1883
|
}
|
|
1789
1884
|
);
|
|
1790
1885
|
};
|
|
1791
1886
|
var useApp = () => {
|
|
1792
|
-
const context =
|
|
1887
|
+
const context = useContext4(AppContext);
|
|
1793
1888
|
if (!context) {
|
|
1794
1889
|
throw new Error("useApp must be used within AppProvider");
|
|
1795
1890
|
}
|
|
@@ -1800,7 +1895,7 @@ var useApp = () => {
|
|
|
1800
1895
|
import { useInput } from "ink";
|
|
1801
1896
|
import { useEffect as useEffect4 } from "react";
|
|
1802
1897
|
var useKeyboardNav = () => {
|
|
1803
|
-
const { showHelp, setShowHelp, activePane, setActivePane, isInputMode, showOverview, setShowOverview, overviewMonth, setOverviewMonth, exitConfirmation, setExitConfirmation, showThemeDialog, setShowThemeDialog, showClearTimelineDialog, setShowClearTimelineDialog, saveNow } = useApp();
|
|
1898
|
+
const { showHelp, setShowHelp, activePane, setActivePane, isInputMode, showOverview, setShowOverview, overviewMonth, setOverviewMonth, exitConfirmation, setExitConfirmation, showThemeDialog, setShowThemeDialog, showClearTimelineDialog, setShowClearTimelineDialog, saveNow, performUndo, canUndo } = useApp();
|
|
1804
1899
|
useEffect4(() => {
|
|
1805
1900
|
if (exitConfirmation) {
|
|
1806
1901
|
const timer = setTimeout(() => {
|
|
@@ -1840,6 +1935,10 @@ var useKeyboardNav = () => {
|
|
|
1840
1935
|
return;
|
|
1841
1936
|
}
|
|
1842
1937
|
}
|
|
1938
|
+
if (key.ctrl && input === "u" && canUndo) {
|
|
1939
|
+
performUndo();
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1843
1942
|
if (input === ":") {
|
|
1844
1943
|
setShowOverview(!showOverview);
|
|
1845
1944
|
return;
|
|
@@ -1875,11 +1974,11 @@ var useKeyboardNav = () => {
|
|
|
1875
1974
|
};
|
|
1876
1975
|
|
|
1877
1976
|
// src/hooks/useTerminalSize.ts
|
|
1878
|
-
import { useState as
|
|
1977
|
+
import { useState as useState5, useEffect as useEffect5 } from "react";
|
|
1879
1978
|
import { useStdout } from "ink";
|
|
1880
1979
|
var useTerminalSize = () => {
|
|
1881
1980
|
const { stdout } = useStdout();
|
|
1882
|
-
const [size, setSize] =
|
|
1981
|
+
const [size, setSize] = useState5({
|
|
1883
1982
|
width: stdout?.columns || 100,
|
|
1884
1983
|
height: stdout?.rows || 30
|
|
1885
1984
|
});
|
|
@@ -1905,11 +2004,11 @@ var useTerminalSize = () => {
|
|
|
1905
2004
|
|
|
1906
2005
|
// src/components/layout/ThreeColumnLayout.tsx
|
|
1907
2006
|
import { Box, Text } from "ink";
|
|
1908
|
-
import { jsx as
|
|
1909
|
-
var
|
|
1910
|
-
const
|
|
1911
|
-
const lines =
|
|
1912
|
-
return /* @__PURE__ */
|
|
2007
|
+
import { jsx as jsx5, jsxs } from "react/jsx-runtime";
|
|
2008
|
+
var ThinSeparator = ({ color, backgroundColor, height }) => {
|
|
2009
|
+
const line = "\u2502";
|
|
2010
|
+
const lines = Array(height).fill(line).join("\n");
|
|
2011
|
+
return /* @__PURE__ */ jsx5(Box, { width: 1, flexShrink: 0, backgroundColor, children: /* @__PURE__ */ jsx5(Text, { color, children: lines }) });
|
|
1913
2012
|
};
|
|
1914
2013
|
var ThreeColumnLayout = ({
|
|
1915
2014
|
leftPane,
|
|
@@ -1921,8 +2020,8 @@ var ThreeColumnLayout = ({
|
|
|
1921
2020
|
activePane
|
|
1922
2021
|
}) => {
|
|
1923
2022
|
const { theme } = useTheme();
|
|
1924
|
-
const
|
|
1925
|
-
const
|
|
2023
|
+
const leftSeparatorColor = activePane === "calendar" || activePane === "tasks" ? theme.colors.focusIndicator : theme.colors.separator;
|
|
2024
|
+
const rightSeparatorColor = activePane === "tasks" || activePane === "timeline" ? theme.colors.focusIndicator : theme.colors.separator;
|
|
1926
2025
|
const bgColor = theme.name !== "terminal" ? theme.colors.background : void 0;
|
|
1927
2026
|
return /* @__PURE__ */ jsxs(
|
|
1928
2027
|
Box,
|
|
@@ -1932,7 +2031,7 @@ var ThreeColumnLayout = ({
|
|
|
1932
2031
|
height,
|
|
1933
2032
|
backgroundColor: bgColor,
|
|
1934
2033
|
children: [
|
|
1935
|
-
/* @__PURE__ */
|
|
2034
|
+
/* @__PURE__ */ jsx5(
|
|
1936
2035
|
Box,
|
|
1937
2036
|
{
|
|
1938
2037
|
width: leftWidth,
|
|
@@ -1942,16 +2041,15 @@ var ThreeColumnLayout = ({
|
|
|
1942
2041
|
children: leftPane
|
|
1943
2042
|
}
|
|
1944
2043
|
),
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
|
|
2044
|
+
/* @__PURE__ */ jsx5(
|
|
2045
|
+
ThinSeparator,
|
|
1947
2046
|
{
|
|
1948
|
-
|
|
1949
|
-
color: activePane === "calendar" || activePane === "tasks" ? focusedColor : normalColor,
|
|
2047
|
+
color: leftSeparatorColor,
|
|
1950
2048
|
backgroundColor: bgColor,
|
|
1951
|
-
height
|
|
2049
|
+
height: height || 30
|
|
1952
2050
|
}
|
|
1953
2051
|
),
|
|
1954
|
-
/* @__PURE__ */
|
|
2052
|
+
/* @__PURE__ */ jsx5(
|
|
1955
2053
|
Box,
|
|
1956
2054
|
{
|
|
1957
2055
|
flexGrow: 1,
|
|
@@ -1961,22 +2059,22 @@ var ThreeColumnLayout = ({
|
|
|
1961
2059
|
children: centerPane
|
|
1962
2060
|
}
|
|
1963
2061
|
),
|
|
1964
|
-
/* @__PURE__ */
|
|
1965
|
-
|
|
2062
|
+
/* @__PURE__ */ jsx5(
|
|
2063
|
+
ThinSeparator,
|
|
1966
2064
|
{
|
|
1967
|
-
|
|
1968
|
-
color: activePane === "tasks" || activePane === "timeline" ? focusedColor : normalColor,
|
|
2065
|
+
color: rightSeparatorColor,
|
|
1969
2066
|
backgroundColor: bgColor,
|
|
1970
|
-
height
|
|
2067
|
+
height: height || 30
|
|
1971
2068
|
}
|
|
1972
2069
|
),
|
|
1973
|
-
/* @__PURE__ */
|
|
2070
|
+
/* @__PURE__ */ jsx5(
|
|
1974
2071
|
Box,
|
|
1975
2072
|
{
|
|
1976
2073
|
width: rightWidth,
|
|
1977
2074
|
flexShrink: 0.3,
|
|
1978
2075
|
flexDirection: "column",
|
|
1979
2076
|
backgroundColor: bgColor,
|
|
2077
|
+
overflow: "hidden",
|
|
1980
2078
|
children: rightPane
|
|
1981
2079
|
}
|
|
1982
2080
|
)
|
|
@@ -1986,7 +2084,7 @@ var ThreeColumnLayout = ({
|
|
|
1986
2084
|
};
|
|
1987
2085
|
|
|
1988
2086
|
// src/components/calendar/CalendarPane.tsx
|
|
1989
|
-
import { useState as
|
|
2087
|
+
import { useState as useState6, useEffect as useEffect6 } from "react";
|
|
1990
2088
|
import { Box as Box6, useInput as useInput2 } from "ink";
|
|
1991
2089
|
import { addDays, addWeeks, subDays, subWeeks } from "date-fns";
|
|
1992
2090
|
|
|
@@ -1995,7 +2093,7 @@ import { Box as Box2 } from "ink";
|
|
|
1995
2093
|
|
|
1996
2094
|
// src/components/common/ThemedText.tsx
|
|
1997
2095
|
import { Text as Text2 } from "ink";
|
|
1998
|
-
import { jsx as
|
|
2096
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1999
2097
|
var ThemedText = ({
|
|
2000
2098
|
children,
|
|
2001
2099
|
backgroundColor,
|
|
@@ -2003,11 +2101,11 @@ var ThemedText = ({
|
|
|
2003
2101
|
}) => {
|
|
2004
2102
|
const { theme } = useTheme();
|
|
2005
2103
|
const bgColor = backgroundColor ?? (theme.name !== "terminal" ? theme.colors.background : void 0);
|
|
2006
|
-
return /* @__PURE__ */
|
|
2104
|
+
return /* @__PURE__ */ jsx6(Text2, { ...props, backgroundColor: bgColor, children });
|
|
2007
2105
|
};
|
|
2008
2106
|
|
|
2009
2107
|
// src/components/layout/Pane.tsx
|
|
2010
|
-
import { jsx as
|
|
2108
|
+
import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2011
2109
|
var Pane = ({
|
|
2012
2110
|
children,
|
|
2013
2111
|
title,
|
|
@@ -2027,8 +2125,9 @@ var Pane = ({
|
|
|
2027
2125
|
paddingRight: 1,
|
|
2028
2126
|
paddingX: 2,
|
|
2029
2127
|
alignItems: center ? "center" : "flex-start",
|
|
2128
|
+
overflow: "hidden",
|
|
2030
2129
|
children: [
|
|
2031
|
-
title && /* @__PURE__ */
|
|
2130
|
+
title && /* @__PURE__ */ jsx7(Box2, { marginBottom: 1, children: /* @__PURE__ */ jsx7(
|
|
2032
2131
|
ThemedText,
|
|
2033
2132
|
{
|
|
2034
2133
|
backgroundColor: isFocused ? theme.colors.focusIndicator : void 0,
|
|
@@ -2037,12 +2136,13 @@ var Pane = ({
|
|
|
2037
2136
|
children: isFocused ? ` ${title.toUpperCase()} ` : title
|
|
2038
2137
|
}
|
|
2039
2138
|
) }),
|
|
2040
|
-
/* @__PURE__ */
|
|
2139
|
+
/* @__PURE__ */ jsx7(
|
|
2041
2140
|
Box2,
|
|
2042
2141
|
{
|
|
2043
2142
|
flexDirection: "column",
|
|
2044
2143
|
flexGrow: 1,
|
|
2045
|
-
|
|
2144
|
+
width: "100%",
|
|
2145
|
+
overflow: "hidden",
|
|
2046
2146
|
alignItems: center ? "center" : "flex-start",
|
|
2047
2147
|
children
|
|
2048
2148
|
}
|
|
@@ -2057,7 +2157,7 @@ import { Box as Box4 } from "ink";
|
|
|
2057
2157
|
|
|
2058
2158
|
// src/components/calendar/DayCell.tsx
|
|
2059
2159
|
import { Box as Box3 } from "ink";
|
|
2060
|
-
import { jsx as
|
|
2160
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2061
2161
|
var DayCell = ({ day }) => {
|
|
2062
2162
|
const { theme } = useTheme();
|
|
2063
2163
|
let textColor = theme.colors.calendarDayOtherMonth;
|
|
@@ -2074,7 +2174,7 @@ var DayCell = ({ day }) => {
|
|
|
2074
2174
|
const dayNum = day.date.day.toString().padStart(2, " ");
|
|
2075
2175
|
const leftBracket = isSelected ? "[" : isToday2 ? "(" : " ";
|
|
2076
2176
|
const rightBracket = isSelected ? "]" : isToday2 ? ")" : " ";
|
|
2077
|
-
return /* @__PURE__ */
|
|
2177
|
+
return /* @__PURE__ */ jsx8(Box3, { width: 4, children: /* @__PURE__ */ jsxs3(ThemedText, { color: textColor, children: [
|
|
2078
2178
|
leftBracket,
|
|
2079
2179
|
dayNum,
|
|
2080
2180
|
rightBracket
|
|
@@ -2082,22 +2182,22 @@ var DayCell = ({ day }) => {
|
|
|
2082
2182
|
};
|
|
2083
2183
|
|
|
2084
2184
|
// src/components/calendar/MonthView.tsx
|
|
2085
|
-
import { jsx as
|
|
2185
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2086
2186
|
var MonthView = ({ calendarView }) => {
|
|
2087
2187
|
const { theme } = useTheme();
|
|
2088
2188
|
const dayHeaders = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
|
2089
2189
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
2090
|
-
/* @__PURE__ */
|
|
2091
|
-
calendarView.weeks.map((week, weekIdx) => /* @__PURE__ */
|
|
2190
|
+
/* @__PURE__ */ jsx9(Box4, { marginBottom: 1, children: dayHeaders.map((day) => /* @__PURE__ */ jsx9(Box4, { width: 4, children: /* @__PURE__ */ jsx9(ThemedText, { color: theme.colors.calendarHeader, bold: true, children: day }) }, day)) }),
|
|
2191
|
+
calendarView.weeks.map((week, weekIdx) => /* @__PURE__ */ jsx9(Box4, { marginBottom: 0, children: week.map((day) => /* @__PURE__ */ jsx9(DayCell, { day }, day.dateString)) }, weekIdx))
|
|
2092
2192
|
] });
|
|
2093
2193
|
};
|
|
2094
2194
|
|
|
2095
2195
|
// src/components/common/KeyboardHints.tsx
|
|
2096
2196
|
import { Box as Box5, Text as Text3 } from "ink";
|
|
2097
|
-
import { jsx as
|
|
2197
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2098
2198
|
var KeyboardHints = ({ hints }) => {
|
|
2099
2199
|
const { theme } = useTheme();
|
|
2100
|
-
return /* @__PURE__ */
|
|
2200
|
+
return /* @__PURE__ */ jsx10(
|
|
2101
2201
|
Box5,
|
|
2102
2202
|
{
|
|
2103
2203
|
marginTop: 1,
|
|
@@ -2106,7 +2206,7 @@ var KeyboardHints = ({ hints }) => {
|
|
|
2106
2206
|
columnGap: 2,
|
|
2107
2207
|
width: "100%",
|
|
2108
2208
|
children: hints.map((hint, index) => /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
2109
|
-
/* @__PURE__ */
|
|
2209
|
+
/* @__PURE__ */ jsx10(Text3, { color: theme.colors.focusIndicator, bold: true, children: hint.key }),
|
|
2110
2210
|
/* @__PURE__ */ jsxs5(Text3, { color: theme.colors.keyboardHint, children: [
|
|
2111
2211
|
" ",
|
|
2112
2212
|
hint.description
|
|
@@ -2210,7 +2310,7 @@ var CalendarService = class {
|
|
|
2210
2310
|
var calendarService = new CalendarService();
|
|
2211
2311
|
|
|
2212
2312
|
// src/components/calendar/CalendarPane.tsx
|
|
2213
|
-
import { jsx as
|
|
2313
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2214
2314
|
var CalendarPane = () => {
|
|
2215
2315
|
const { theme } = useTheme();
|
|
2216
2316
|
const {
|
|
@@ -2221,7 +2321,7 @@ var CalendarPane = () => {
|
|
|
2221
2321
|
isModalOpen,
|
|
2222
2322
|
isInputMode
|
|
2223
2323
|
} = useApp();
|
|
2224
|
-
const [currentMonth, setCurrentMonth] =
|
|
2324
|
+
const [currentMonth, setCurrentMonth] = useState6({
|
|
2225
2325
|
year: selectedDate.year,
|
|
2226
2326
|
month: selectedDate.month
|
|
2227
2327
|
});
|
|
@@ -2307,15 +2407,15 @@ var CalendarPane = () => {
|
|
|
2307
2407
|
{ isActive: isFocused && !isInputMode }
|
|
2308
2408
|
);
|
|
2309
2409
|
const monthName = calendarService.getMonthName(currentMonth.month);
|
|
2310
|
-
return /* @__PURE__ */
|
|
2410
|
+
return /* @__PURE__ */ jsx11(
|
|
2311
2411
|
Pane,
|
|
2312
2412
|
{
|
|
2313
2413
|
title: `${monthName} ${currentMonth.year}`,
|
|
2314
2414
|
isFocused,
|
|
2315
2415
|
center: true,
|
|
2316
2416
|
children: /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", alignItems: "center", children: [
|
|
2317
|
-
/* @__PURE__ */
|
|
2318
|
-
/* @__PURE__ */
|
|
2417
|
+
/* @__PURE__ */ jsx11(MonthView, { calendarView }),
|
|
2418
|
+
/* @__PURE__ */ jsx11(
|
|
2319
2419
|
KeyboardHints,
|
|
2320
2420
|
{
|
|
2321
2421
|
hints: [
|
|
@@ -2332,13 +2432,13 @@ var CalendarPane = () => {
|
|
|
2332
2432
|
};
|
|
2333
2433
|
|
|
2334
2434
|
// src/components/tasks/TasksPane.tsx
|
|
2335
|
-
import { useState as
|
|
2435
|
+
import { useState as useState7, useEffect as useEffect8, useMemo } from "react";
|
|
2336
2436
|
import { Box as Box8, Text as Text7, useInput as useInput4 } from "ink";
|
|
2337
2437
|
|
|
2338
2438
|
// src/components/common/ControlledTextInput.tsx
|
|
2339
2439
|
import { useRef as useRef3, useEffect as useEffect7 } from "react";
|
|
2340
2440
|
import { Text as Text5, useInput as useInput3 } from "ink";
|
|
2341
|
-
import { jsx as
|
|
2441
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2342
2442
|
var ControlledTextInput = ({
|
|
2343
2443
|
value,
|
|
2344
2444
|
onChange,
|
|
@@ -2400,21 +2500,21 @@ var ControlledTextInput = ({
|
|
|
2400
2500
|
const displayValue = pendingValueRef.current || "";
|
|
2401
2501
|
const showPlaceholder = !displayValue && placeholder;
|
|
2402
2502
|
return /* @__PURE__ */ jsxs7(Text5, { children: [
|
|
2403
|
-
showPlaceholder ? /* @__PURE__ */
|
|
2404
|
-
focus && /* @__PURE__ */
|
|
2503
|
+
showPlaceholder ? /* @__PURE__ */ jsx12(Text5, { dimColor: true, color: placeholderColor, children: placeholder }) : /* @__PURE__ */ jsx12(Text5, { color, children: displayValue }),
|
|
2504
|
+
focus && /* @__PURE__ */ jsx12(Text5, { backgroundColor: cursorColor, children: " " })
|
|
2405
2505
|
] });
|
|
2406
2506
|
};
|
|
2407
2507
|
|
|
2408
2508
|
// src/components/tasks/TaskHeader.tsx
|
|
2409
2509
|
import { Box as Box7, Text as Text6 } from "ink";
|
|
2410
|
-
import { jsx as
|
|
2510
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2411
2511
|
var TaskHeader = ({
|
|
2412
2512
|
selectedDate,
|
|
2413
2513
|
completionPercentage
|
|
2414
2514
|
}) => {
|
|
2415
2515
|
const { theme } = useTheme();
|
|
2416
2516
|
return /* @__PURE__ */ jsxs8(Box7, { flexDirection: "column", marginBottom: 1, children: [
|
|
2417
|
-
/* @__PURE__ */
|
|
2517
|
+
/* @__PURE__ */ jsx13(Text6, { color: theme.colors.taskHeader, children: formatDate(selectedDate, "EEEE, MMMM d, yyyy") }),
|
|
2418
2518
|
/* @__PURE__ */ jsxs8(Text6, { color: theme.colors.taskHeader, children: [
|
|
2419
2519
|
completionPercentage,
|
|
2420
2520
|
"% completed"
|
|
@@ -2702,7 +2802,7 @@ var TimelineService = class {
|
|
|
2702
2802
|
var timelineService = new TimelineService();
|
|
2703
2803
|
|
|
2704
2804
|
// src/components/tasks/TasksPane.tsx
|
|
2705
|
-
import { Fragment, jsx as
|
|
2805
|
+
import { Fragment, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2706
2806
|
var TasksPane = () => {
|
|
2707
2807
|
const {
|
|
2708
2808
|
tasks,
|
|
@@ -2713,15 +2813,16 @@ var TasksPane = () => {
|
|
|
2713
2813
|
selectedDate,
|
|
2714
2814
|
isInputMode,
|
|
2715
2815
|
setIsInputMode,
|
|
2716
|
-
isModalOpen
|
|
2816
|
+
isModalOpen,
|
|
2817
|
+
pushUndoableAction
|
|
2717
2818
|
} = useApp();
|
|
2718
2819
|
const { theme } = useTheme();
|
|
2719
|
-
const [expandedIds, setExpandedIds] =
|
|
2720
|
-
const [selectedIndex, setSelectedIndex] =
|
|
2721
|
-
const [editMode, setEditMode] =
|
|
2722
|
-
const [editValue, setEditValue] =
|
|
2723
|
-
const [parentTaskId, setParentTaskId] =
|
|
2724
|
-
const [scrollOffset, setScrollOffset] =
|
|
2820
|
+
const [expandedIds, setExpandedIds] = useState7(/* @__PURE__ */ new Set());
|
|
2821
|
+
const [selectedIndex, setSelectedIndex] = useState7(0);
|
|
2822
|
+
const [editMode, setEditMode] = useState7("none");
|
|
2823
|
+
const [editValue, setEditValue] = useState7("");
|
|
2824
|
+
const [parentTaskId, setParentTaskId] = useState7(null);
|
|
2825
|
+
const [scrollOffset, setScrollOffset] = useState7(0);
|
|
2725
2826
|
const { height: terminalHeight } = useTerminalSize();
|
|
2726
2827
|
const visibleRows = useMemo(() => {
|
|
2727
2828
|
return Math.max(5, terminalHeight - 11);
|
|
@@ -2729,7 +2830,7 @@ var TasksPane = () => {
|
|
|
2729
2830
|
const dateStr = getDateString(
|
|
2730
2831
|
new Date(selectedDate.year, selectedDate.month, selectedDate.day)
|
|
2731
2832
|
);
|
|
2732
|
-
const dayTasks = tasks[dateStr] || [];
|
|
2833
|
+
const dayTasks = useMemo(() => tasks[dateStr] || [], [tasks, dateStr]);
|
|
2733
2834
|
const stats = taskService.getTaskStats(tasks, dateStr);
|
|
2734
2835
|
const isFocused = activePane === "tasks" && !isModalOpen;
|
|
2735
2836
|
const flatTasks = useMemo(() => {
|
|
@@ -2758,7 +2859,13 @@ var TasksPane = () => {
|
|
|
2758
2859
|
}
|
|
2759
2860
|
};
|
|
2760
2861
|
collectParents(dayTasks);
|
|
2761
|
-
setExpandedIds(
|
|
2862
|
+
setExpandedIds((prev) => {
|
|
2863
|
+
if (prev.size !== allParentIds.size) return allParentIds;
|
|
2864
|
+
for (const id of allParentIds) {
|
|
2865
|
+
if (!prev.has(id)) return allParentIds;
|
|
2866
|
+
}
|
|
2867
|
+
return prev;
|
|
2868
|
+
});
|
|
2762
2869
|
}, [dayTasks]);
|
|
2763
2870
|
useEffect8(() => {
|
|
2764
2871
|
setSelectedIndex(0);
|
|
@@ -2770,12 +2877,15 @@ var TasksPane = () => {
|
|
|
2770
2877
|
}
|
|
2771
2878
|
}, [flatTasks.length, selectedIndex]);
|
|
2772
2879
|
useEffect8(() => {
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2880
|
+
setScrollOffset((currentOffset) => {
|
|
2881
|
+
if (selectedIndex < currentOffset) {
|
|
2882
|
+
return selectedIndex;
|
|
2883
|
+
} else if (selectedIndex >= currentOffset + visibleRows) {
|
|
2884
|
+
return selectedIndex - visibleRows + 1;
|
|
2885
|
+
}
|
|
2886
|
+
return currentOffset;
|
|
2887
|
+
});
|
|
2888
|
+
}, [selectedIndex, visibleRows]);
|
|
2779
2889
|
useEffect8(() => {
|
|
2780
2890
|
setScrollOffset(0);
|
|
2781
2891
|
}, [dateStr]);
|
|
@@ -2803,6 +2913,7 @@ var TasksPane = () => {
|
|
|
2803
2913
|
const handleDeleteTask = () => {
|
|
2804
2914
|
if (selectedTaskId) {
|
|
2805
2915
|
try {
|
|
2916
|
+
pushUndoableAction("TASK_DELETE");
|
|
2806
2917
|
const updated = taskService.deleteTask(tasks, selectedTaskId);
|
|
2807
2918
|
setTasks(updated);
|
|
2808
2919
|
const updatedTimeline = timelineService.removeEventsByTaskId(
|
|
@@ -2818,6 +2929,7 @@ var TasksPane = () => {
|
|
|
2818
2929
|
const handleChangeState = (newState) => {
|
|
2819
2930
|
if (selectedTaskId && selectedTask) {
|
|
2820
2931
|
try {
|
|
2932
|
+
pushUndoableAction("TASK_UPDATE");
|
|
2821
2933
|
const previousState = selectedTask.state;
|
|
2822
2934
|
const updated = taskService.changeTaskState(
|
|
2823
2935
|
tasks,
|
|
@@ -2880,6 +2992,7 @@ var TasksPane = () => {
|
|
|
2880
2992
|
}
|
|
2881
2993
|
try {
|
|
2882
2994
|
if (editMode === "add") {
|
|
2995
|
+
pushUndoableAction("TASK_ADD");
|
|
2883
2996
|
const newTask = taskService.createTask(trimmed, dateStr);
|
|
2884
2997
|
const newTasks = {
|
|
2885
2998
|
...tasks,
|
|
@@ -2888,6 +3001,7 @@ var TasksPane = () => {
|
|
|
2888
3001
|
setTasks(newTasks);
|
|
2889
3002
|
setSelectedIndex(flatTasks.length);
|
|
2890
3003
|
} else if (editMode === "addSubtask" && parentTaskId) {
|
|
3004
|
+
pushUndoableAction("TASK_ADD");
|
|
2891
3005
|
const updated = taskService.addSubtask(tasks, parentTaskId, trimmed);
|
|
2892
3006
|
setTasks(updated);
|
|
2893
3007
|
const parentIndex = flatTasks.findIndex(
|
|
@@ -2897,6 +3011,7 @@ var TasksPane = () => {
|
|
|
2897
3011
|
setSelectedIndex(parentIndex + 1);
|
|
2898
3012
|
}
|
|
2899
3013
|
} else if (editMode === "edit" && selectedTaskId) {
|
|
3014
|
+
pushUndoableAction("TASK_UPDATE");
|
|
2900
3015
|
const updated = taskService.updateTask(tasks, selectedTaskId, {
|
|
2901
3016
|
title: trimmed
|
|
2902
3017
|
});
|
|
@@ -3015,6 +3130,7 @@ var TasksPane = () => {
|
|
|
3015
3130
|
}
|
|
3016
3131
|
if (input === "s" && selectedTask) {
|
|
3017
3132
|
try {
|
|
3133
|
+
pushUndoableAction("TASK_UPDATE");
|
|
3018
3134
|
if (selectedTask.startTime && !selectedTask.endTime) {
|
|
3019
3135
|
const updated = taskService.updateTask(tasks, selectedTaskId, {
|
|
3020
3136
|
startTime: void 0
|
|
@@ -3054,8 +3170,8 @@ var TasksPane = () => {
|
|
|
3054
3170
|
},
|
|
3055
3171
|
{ isActive: isFocused && editMode === "none" }
|
|
3056
3172
|
);
|
|
3057
|
-
return /* @__PURE__ */
|
|
3058
|
-
/* @__PURE__ */
|
|
3173
|
+
return /* @__PURE__ */ jsx14(Pane, { title: "Tasks", isFocused, children: /* @__PURE__ */ jsxs9(Box8, { flexDirection: "column", flexGrow: 1, width: "100%", children: [
|
|
3174
|
+
/* @__PURE__ */ jsx14(
|
|
3059
3175
|
TaskHeader,
|
|
3060
3176
|
{
|
|
3061
3177
|
selectedDate: new Date(selectedDate.year, selectedDate.month, selectedDate.day),
|
|
@@ -3063,8 +3179,8 @@ var TasksPane = () => {
|
|
|
3063
3179
|
}
|
|
3064
3180
|
),
|
|
3065
3181
|
editMode === "add" && /* @__PURE__ */ jsxs9(Box8, { marginY: 1, children: [
|
|
3066
|
-
/* @__PURE__ */
|
|
3067
|
-
/* @__PURE__ */
|
|
3182
|
+
/* @__PURE__ */ jsx14(Text7, { color: theme.colors.focusIndicator, children: "> " }),
|
|
3183
|
+
/* @__PURE__ */ jsx14(
|
|
3068
3184
|
ControlledTextInput,
|
|
3069
3185
|
{
|
|
3070
3186
|
value: editValue,
|
|
@@ -3079,9 +3195,9 @@ var TasksPane = () => {
|
|
|
3079
3195
|
)
|
|
3080
3196
|
] }),
|
|
3081
3197
|
editMode === "addSubtask" && /* @__PURE__ */ jsxs9(Box8, { marginY: 1, children: [
|
|
3082
|
-
/* @__PURE__ */
|
|
3083
|
-
/* @__PURE__ */
|
|
3084
|
-
/* @__PURE__ */
|
|
3198
|
+
/* @__PURE__ */ jsx14(Text7, { color: theme.colors.focusIndicator, children: "> " }),
|
|
3199
|
+
/* @__PURE__ */ jsx14(Text7, { color: theme.colors.keyboardHint, children: " " }),
|
|
3200
|
+
/* @__PURE__ */ jsx14(
|
|
3085
3201
|
ControlledTextInput,
|
|
3086
3202
|
{
|
|
3087
3203
|
value: editValue,
|
|
@@ -3095,8 +3211,8 @@ var TasksPane = () => {
|
|
|
3095
3211
|
}
|
|
3096
3212
|
)
|
|
3097
3213
|
] }),
|
|
3098
|
-
dayTasks.length === 0 && editMode !== "add" && editMode !== "addSubtask" ? /* @__PURE__ */
|
|
3099
|
-
scrollOffset > 0 && /* @__PURE__ */
|
|
3214
|
+
dayTasks.length === 0 && editMode !== "add" && editMode !== "addSubtask" ? /* @__PURE__ */ jsx14(Box8, { marginY: 1, children: /* @__PURE__ */ jsx14(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "No tasks. Press 'a' to add one." }) }) : /* @__PURE__ */ jsxs9(Box8, { flexDirection: "column", marginY: 1, paddingRight: 2, children: [
|
|
3215
|
+
scrollOffset > 0 && /* @__PURE__ */ jsx14(Box8, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx14(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
|
|
3100
3216
|
flatTasks.slice(scrollOffset, scrollOffset + visibleRows).map(({ task, depth }, sliceIndex) => {
|
|
3101
3217
|
const index = scrollOffset + sliceIndex;
|
|
3102
3218
|
const isSelected = index === selectedIndex;
|
|
@@ -3104,8 +3220,8 @@ var TasksPane = () => {
|
|
|
3104
3220
|
const isEditing = editMode === "edit" && isSelected;
|
|
3105
3221
|
if (isEditing) {
|
|
3106
3222
|
return /* @__PURE__ */ jsxs9(Box8, { children: [
|
|
3107
|
-
/* @__PURE__ */
|
|
3108
|
-
/* @__PURE__ */
|
|
3223
|
+
/* @__PURE__ */ jsx14(Text7, { color: theme.colors.focusIndicator, children: "> " }),
|
|
3224
|
+
/* @__PURE__ */ jsx14(
|
|
3109
3225
|
ControlledTextInput,
|
|
3110
3226
|
{
|
|
3111
3227
|
value: editValue,
|
|
@@ -3120,28 +3236,28 @@ var TasksPane = () => {
|
|
|
3120
3236
|
] }, task.id);
|
|
3121
3237
|
}
|
|
3122
3238
|
return /* @__PURE__ */ jsxs9(Box8, { children: [
|
|
3123
|
-
/* @__PURE__ */
|
|
3239
|
+
/* @__PURE__ */ jsx14(
|
|
3124
3240
|
Text7,
|
|
3125
3241
|
{
|
|
3126
3242
|
color: isSelected ? theme.colors.focusIndicator : theme.colors.foreground,
|
|
3127
3243
|
children: isSelected ? ">" : " "
|
|
3128
3244
|
}
|
|
3129
3245
|
),
|
|
3130
|
-
/* @__PURE__ */
|
|
3131
|
-
/* @__PURE__ */
|
|
3132
|
-
/* @__PURE__ */
|
|
3246
|
+
/* @__PURE__ */ jsx14(Text7, { children: " " }),
|
|
3247
|
+
/* @__PURE__ */ jsx14(Text7, { children: " ".repeat(depth) }),
|
|
3248
|
+
/* @__PURE__ */ jsx14(
|
|
3133
3249
|
Text7,
|
|
3134
3250
|
{
|
|
3135
3251
|
color: isSelected ? theme.colors.focusIndicator : getStateColor(task.state, theme),
|
|
3136
3252
|
children: getCheckbox(task.state)
|
|
3137
3253
|
}
|
|
3138
3254
|
),
|
|
3139
|
-
/* @__PURE__ */
|
|
3255
|
+
/* @__PURE__ */ jsx14(Text7, { children: " " }),
|
|
3140
3256
|
task.children.length > 0 && /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
3141
|
-
/* @__PURE__ */
|
|
3142
|
-
/* @__PURE__ */
|
|
3257
|
+
/* @__PURE__ */ jsx14(Text7, { color: theme.colors.foreground, children: isExpanded ? "\u25BC" : "\u25B6" }),
|
|
3258
|
+
/* @__PURE__ */ jsx14(Text7, { children: " " })
|
|
3143
3259
|
] }),
|
|
3144
|
-
/* @__PURE__ */
|
|
3260
|
+
/* @__PURE__ */ jsx14(
|
|
3145
3261
|
Text7,
|
|
3146
3262
|
{
|
|
3147
3263
|
color: isSelected ? theme.colors.focusIndicator : getStateColor(task.state, theme),
|
|
@@ -3162,9 +3278,9 @@ var TasksPane = () => {
|
|
|
3162
3278
|
)
|
|
3163
3279
|
] }, task.id);
|
|
3164
3280
|
}),
|
|
3165
|
-
scrollOffset + visibleRows < flatTasks.length && /* @__PURE__ */
|
|
3281
|
+
scrollOffset + visibleRows < flatTasks.length && /* @__PURE__ */ jsx14(Box8, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx14(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
|
|
3166
3282
|
] }),
|
|
3167
|
-
/* @__PURE__ */
|
|
3283
|
+
/* @__PURE__ */ jsx14(
|
|
3168
3284
|
KeyboardHints,
|
|
3169
3285
|
{
|
|
3170
3286
|
hints: [
|
|
@@ -3207,12 +3323,12 @@ function getStateColor(state, theme) {
|
|
|
3207
3323
|
}
|
|
3208
3324
|
|
|
3209
3325
|
// src/components/timeline/TimelinePane.tsx
|
|
3210
|
-
import { useState as
|
|
3326
|
+
import { useState as useState8, useEffect as useEffect9, useMemo as useMemo2 } from "react";
|
|
3211
3327
|
import { Box as Box10, Text as Text9, useInput as useInput5 } from "ink";
|
|
3212
3328
|
|
|
3213
3329
|
// src/components/timeline/TimelineEntry.tsx
|
|
3214
3330
|
import { Box as Box9, Text as Text8 } from "ink";
|
|
3215
|
-
import { jsx as
|
|
3331
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3216
3332
|
var TimelineEntry = ({
|
|
3217
3333
|
event,
|
|
3218
3334
|
isLast,
|
|
@@ -3237,33 +3353,32 @@ var TimelineEntry = ({
|
|
|
3237
3353
|
const isFilledCircle = ["completed", "delegated", "delayed"].includes(
|
|
3238
3354
|
event.type
|
|
3239
3355
|
);
|
|
3240
|
-
return /* @__PURE__ */ jsxs10(Box9, { flexDirection: "column", children: [
|
|
3241
|
-
/* @__PURE__ */ jsxs10(Box9, { children: [
|
|
3242
|
-
/* @__PURE__ */
|
|
3243
|
-
/* @__PURE__ */ jsxs10(Box9, { flexDirection: "column", flexGrow: 1, children: [
|
|
3244
|
-
/* @__PURE__ */
|
|
3356
|
+
return /* @__PURE__ */ jsxs10(Box9, { flexDirection: "column", width: "100%", children: [
|
|
3357
|
+
/* @__PURE__ */ jsxs10(Box9, { width: "100%", children: [
|
|
3358
|
+
/* @__PURE__ */ jsx15(Box9, { width: 3, flexShrink: 0, justifyContent: "center", children: /* @__PURE__ */ jsx15(Text8, { color, children: isFilledCircle ? "\u25CF" : "\u25CB" }) }),
|
|
3359
|
+
/* @__PURE__ */ jsxs10(Box9, { flexDirection: "column", flexGrow: 1, flexShrink: 1, minWidth: 0, children: [
|
|
3360
|
+
/* @__PURE__ */ jsxs10(Text8, { wrap: "wrap", color: theme.colors.foreground, children: [
|
|
3245
3361
|
/* @__PURE__ */ jsxs10(Text8, { color, bold: true, children: [
|
|
3246
3362
|
typeStr,
|
|
3247
3363
|
":"
|
|
3248
3364
|
] }),
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
] }) }),
|
|
3254
|
-
/* @__PURE__ */ jsx14(Box9, { children: /* @__PURE__ */ jsx14(Text8, { color: theme.colors.keyboardHint, dimColor: true, children: timeStr }) })
|
|
3365
|
+
" ",
|
|
3366
|
+
event.taskTitle
|
|
3367
|
+
] }),
|
|
3368
|
+
/* @__PURE__ */ jsx15(Text8, { color: theme.colors.keyboardHint, dimColor: true, children: timeStr })
|
|
3255
3369
|
] })
|
|
3256
3370
|
] }),
|
|
3257
|
-
!isLast && /* @__PURE__ */
|
|
3371
|
+
!isLast && /* @__PURE__ */ jsx15(Box9, { children: /* @__PURE__ */ jsx15(Box9, { width: 3, justifyContent: "center", children: /* @__PURE__ */ jsx15(Text8, { color: hasNextSameTask ? color : theme.colors.border, children: "\u2502" }) }) })
|
|
3258
3372
|
] });
|
|
3259
3373
|
};
|
|
3260
3374
|
|
|
3261
3375
|
// src/components/timeline/TimelinePane.tsx
|
|
3262
|
-
import { jsx as
|
|
3376
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3263
3377
|
var TimelinePane = () => {
|
|
3264
3378
|
const { theme } = useTheme();
|
|
3265
3379
|
const {
|
|
3266
3380
|
selectedDate,
|
|
3381
|
+
tasks,
|
|
3267
3382
|
timeline,
|
|
3268
3383
|
setTimeline,
|
|
3269
3384
|
activePane,
|
|
@@ -3271,15 +3386,49 @@ var TimelinePane = () => {
|
|
|
3271
3386
|
isInputMode
|
|
3272
3387
|
} = useApp();
|
|
3273
3388
|
const isFocused = activePane === "timeline" && !isModalOpen;
|
|
3274
|
-
const [scrollOffset, setScrollOffset] =
|
|
3389
|
+
const [scrollOffset, setScrollOffset] = useState8(0);
|
|
3275
3390
|
const { height: terminalHeight } = useTerminalSize();
|
|
3276
3391
|
const visibleRows = useMemo2(() => {
|
|
3277
|
-
|
|
3392
|
+
const availableHeight = Math.max(8, terminalHeight - 8);
|
|
3393
|
+
return Math.max(3, Math.floor(availableHeight / 4));
|
|
3278
3394
|
}, [terminalHeight]);
|
|
3279
3395
|
const dateStr = getDateString(
|
|
3280
3396
|
new Date(selectedDate.year, selectedDate.month, selectedDate.day)
|
|
3281
3397
|
);
|
|
3282
3398
|
const dayEvents = timeline[dateStr] || [];
|
|
3399
|
+
const dayTasks = tasks[dateStr] || [];
|
|
3400
|
+
const taskHierarchyMap = useMemo2(() => {
|
|
3401
|
+
const map = /* @__PURE__ */ new Map();
|
|
3402
|
+
const traverse = (taskList, parentId) => {
|
|
3403
|
+
taskList.forEach((task) => {
|
|
3404
|
+
map.set(task.id, parentId);
|
|
3405
|
+
traverse(task.children, task.id);
|
|
3406
|
+
});
|
|
3407
|
+
};
|
|
3408
|
+
traverse(dayTasks);
|
|
3409
|
+
return map;
|
|
3410
|
+
}, [dayTasks]);
|
|
3411
|
+
const isAncestor = (taskAId, taskBId) => {
|
|
3412
|
+
let currentId = taskBId;
|
|
3413
|
+
while (currentId) {
|
|
3414
|
+
const parentId = taskHierarchyMap.get(currentId);
|
|
3415
|
+
if (!parentId) break;
|
|
3416
|
+
if (parentId === taskAId) return true;
|
|
3417
|
+
currentId = parentId;
|
|
3418
|
+
}
|
|
3419
|
+
return false;
|
|
3420
|
+
};
|
|
3421
|
+
const getTaskDepth = (taskId) => {
|
|
3422
|
+
let depth = 0;
|
|
3423
|
+
let currentId = taskId;
|
|
3424
|
+
while (currentId) {
|
|
3425
|
+
const parentId = taskHierarchyMap.get(currentId);
|
|
3426
|
+
if (!parentId) break;
|
|
3427
|
+
depth++;
|
|
3428
|
+
currentId = parentId;
|
|
3429
|
+
}
|
|
3430
|
+
return depth;
|
|
3431
|
+
};
|
|
3283
3432
|
const sortedEvents = useMemo2(() => {
|
|
3284
3433
|
const eventsByTask = /* @__PURE__ */ new Map();
|
|
3285
3434
|
dayEvents.forEach((event) => {
|
|
@@ -3291,14 +3440,19 @@ var TimelinePane = () => {
|
|
|
3291
3440
|
events.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
3292
3441
|
});
|
|
3293
3442
|
const taskGroups = Array.from(eventsByTask.entries()).sort(
|
|
3294
|
-
([, eventsA], [, eventsB]) => {
|
|
3443
|
+
([taskIdA, eventsA], [taskIdB, eventsB]) => {
|
|
3444
|
+
if (isAncestor(taskIdA, taskIdB)) return -1;
|
|
3445
|
+
if (isAncestor(taskIdB, taskIdA)) return 1;
|
|
3446
|
+
const depthA = getTaskDepth(taskIdA);
|
|
3447
|
+
const depthB = getTaskDepth(taskIdB);
|
|
3448
|
+
if (depthA !== depthB) return depthA - depthB;
|
|
3295
3449
|
const earliestA = eventsA[0]?.timestamp.getTime() || 0;
|
|
3296
3450
|
const earliestB = eventsB[0]?.timestamp.getTime() || 0;
|
|
3297
3451
|
return earliestA - earliestB;
|
|
3298
3452
|
}
|
|
3299
3453
|
);
|
|
3300
3454
|
return taskGroups.flatMap(([, events]) => events);
|
|
3301
|
-
}, [dayEvents]);
|
|
3455
|
+
}, [dayEvents, taskHierarchyMap]);
|
|
3302
3456
|
useEffect9(() => {
|
|
3303
3457
|
setScrollOffset(0);
|
|
3304
3458
|
}, [dateStr]);
|
|
@@ -3321,17 +3475,6 @@ var TimelinePane = () => {
|
|
|
3321
3475
|
)
|
|
3322
3476
|
);
|
|
3323
3477
|
}
|
|
3324
|
-
if (input === "u" && key.ctrl) {
|
|
3325
|
-
setScrollOffset(
|
|
3326
|
-
(prev) => Math.max(prev - Math.floor(visibleRows / 2), 0)
|
|
3327
|
-
);
|
|
3328
|
-
}
|
|
3329
|
-
if (input === "C") {
|
|
3330
|
-
setTimeline({
|
|
3331
|
-
...timeline,
|
|
3332
|
-
[dateStr]: []
|
|
3333
|
-
});
|
|
3334
|
-
}
|
|
3335
3478
|
},
|
|
3336
3479
|
{ isActive: isFocused && !isInputMode }
|
|
3337
3480
|
);
|
|
@@ -3341,18 +3484,18 @@ var TimelinePane = () => {
|
|
|
3341
3484
|
);
|
|
3342
3485
|
const canScrollUp = scrollOffset > 0;
|
|
3343
3486
|
const canScrollDown = scrollOffset + visibleRows < sortedEvents.length;
|
|
3344
|
-
return /* @__PURE__ */
|
|
3487
|
+
return /* @__PURE__ */ jsx16(Pane, { title: "Timeline", isFocused, children: /* @__PURE__ */ jsxs11(Box10, { flexDirection: "column", flexGrow: 1, width: "100%", overflow: "hidden", children: [
|
|
3345
3488
|
sortedEvents.length === 0 ? /* @__PURE__ */ jsxs11(Box10, { marginY: 1, flexDirection: "column", children: [
|
|
3346
|
-
/* @__PURE__ */
|
|
3347
|
-
/* @__PURE__ */
|
|
3348
|
-
] }) : /* @__PURE__ */ jsxs11(Box10, { flexDirection: "column", children: [
|
|
3349
|
-
canScrollUp && /* @__PURE__ */
|
|
3350
|
-
/* @__PURE__ */
|
|
3489
|
+
/* @__PURE__ */ jsx16(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "No activities yet." }),
|
|
3490
|
+
/* @__PURE__ */ jsx16(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "Press 's' to start a task." })
|
|
3491
|
+
] }) : /* @__PURE__ */ jsxs11(Box10, { flexDirection: "column", width: "100%", overflow: "hidden", children: [
|
|
3492
|
+
canScrollUp && /* @__PURE__ */ jsx16(Box10, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx16(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
|
|
3493
|
+
/* @__PURE__ */ jsx16(Box10, { flexDirection: "column", width: "100%", overflow: "hidden", children: visibleEvents.map((event, index) => {
|
|
3351
3494
|
const globalIndex = scrollOffset + index;
|
|
3352
3495
|
const isLast = globalIndex === sortedEvents.length - 1;
|
|
3353
3496
|
const nextEvent = sortedEvents[globalIndex + 1];
|
|
3354
3497
|
const hasNextSameTask = nextEvent && nextEvent.taskId === event.taskId;
|
|
3355
|
-
return /* @__PURE__ */
|
|
3498
|
+
return /* @__PURE__ */ jsx16(
|
|
3356
3499
|
TimelineEntry,
|
|
3357
3500
|
{
|
|
3358
3501
|
event,
|
|
@@ -3362,9 +3505,9 @@ var TimelinePane = () => {
|
|
|
3362
3505
|
event.id
|
|
3363
3506
|
);
|
|
3364
3507
|
}) }),
|
|
3365
|
-
canScrollDown && /* @__PURE__ */
|
|
3508
|
+
canScrollDown && /* @__PURE__ */ jsx16(Box10, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx16(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
|
|
3366
3509
|
] }),
|
|
3367
|
-
/* @__PURE__ */
|
|
3510
|
+
/* @__PURE__ */ jsx16(
|
|
3368
3511
|
KeyboardHints,
|
|
3369
3512
|
{
|
|
3370
3513
|
hints: [
|
|
@@ -3384,7 +3527,7 @@ import { Box as Box12, useStdout as useStdout3 } from "ink";
|
|
|
3384
3527
|
|
|
3385
3528
|
// src/components/common/FullscreenBackground.tsx
|
|
3386
3529
|
import { Box as Box11, useStdout as useStdout2 } from "ink";
|
|
3387
|
-
import { jsx as
|
|
3530
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
3388
3531
|
var FullscreenBackground = ({
|
|
3389
3532
|
children,
|
|
3390
3533
|
backgroundColor
|
|
@@ -3392,7 +3535,7 @@ var FullscreenBackground = ({
|
|
|
3392
3535
|
const { stdout } = useStdout2();
|
|
3393
3536
|
const width = stdout?.columns || 100;
|
|
3394
3537
|
const height = stdout?.rows || 30;
|
|
3395
|
-
return /* @__PURE__ */
|
|
3538
|
+
return /* @__PURE__ */ jsx17(
|
|
3396
3539
|
Box11,
|
|
3397
3540
|
{
|
|
3398
3541
|
flexDirection: "column",
|
|
@@ -3405,17 +3548,17 @@ var FullscreenBackground = ({
|
|
|
3405
3548
|
};
|
|
3406
3549
|
|
|
3407
3550
|
// src/components/common/Modal.tsx
|
|
3408
|
-
import { jsx as
|
|
3551
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
3409
3552
|
var Modal = ({ children }) => {
|
|
3410
3553
|
const { theme } = useTheme();
|
|
3411
3554
|
const { stdout } = useStdout3();
|
|
3412
3555
|
const width = stdout?.columns || 100;
|
|
3413
3556
|
const height = stdout?.rows || 30;
|
|
3414
|
-
return /* @__PURE__ */
|
|
3557
|
+
return /* @__PURE__ */ jsx18(
|
|
3415
3558
|
FullscreenBackground,
|
|
3416
3559
|
{
|
|
3417
3560
|
backgroundColor: theme.colors.modalOverlay || "black",
|
|
3418
|
-
children: /* @__PURE__ */
|
|
3561
|
+
children: /* @__PURE__ */ jsx18(
|
|
3419
3562
|
Box12,
|
|
3420
3563
|
{
|
|
3421
3564
|
flexDirection: "column",
|
|
@@ -3431,11 +3574,12 @@ var Modal = ({ children }) => {
|
|
|
3431
3574
|
};
|
|
3432
3575
|
|
|
3433
3576
|
// src/components/common/HelpDialog.tsx
|
|
3434
|
-
import { Fragment as Fragment2, jsx as
|
|
3577
|
+
import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3435
3578
|
var HelpDialog = () => {
|
|
3436
3579
|
const { theme } = useTheme();
|
|
3437
3580
|
const shortcuts = [
|
|
3438
3581
|
{ key: "Ctrl+C (twice)", action: "Quit application" },
|
|
3582
|
+
{ key: "Ctrl+U", action: "Undo last action" },
|
|
3439
3583
|
{ key: "?", action: "Toggle help dialog" },
|
|
3440
3584
|
{ key: "Shift+;", action: "Show month overview" },
|
|
3441
3585
|
{ key: "t", action: "Select theme" },
|
|
@@ -3464,7 +3608,7 @@ var HelpDialog = () => {
|
|
|
3464
3608
|
{ key: "j/k", action: "Scroll timeline" },
|
|
3465
3609
|
{ key: "Shift+C", action: "Clear timeline" }
|
|
3466
3610
|
];
|
|
3467
|
-
return /* @__PURE__ */
|
|
3611
|
+
return /* @__PURE__ */ jsx19(Modal, { children: /* @__PURE__ */ jsxs12(
|
|
3468
3612
|
Box13,
|
|
3469
3613
|
{
|
|
3470
3614
|
flexDirection: "column",
|
|
@@ -3474,26 +3618,26 @@ var HelpDialog = () => {
|
|
|
3474
3618
|
paddingY: 1,
|
|
3475
3619
|
backgroundColor: theme.colors.modalBackground || theme.colors.background,
|
|
3476
3620
|
children: [
|
|
3477
|
-
/* @__PURE__ */
|
|
3478
|
-
/* @__PURE__ */
|
|
3479
|
-
/* @__PURE__ */
|
|
3480
|
-
/* @__PURE__ */
|
|
3481
|
-
] }) : /* @__PURE__ */
|
|
3482
|
-
/* @__PURE__ */
|
|
3621
|
+
/* @__PURE__ */ jsx19(Text10, { bold: true, color: theme.colors.calendarHeader, children: "Keyboard Shortcuts" }),
|
|
3622
|
+
/* @__PURE__ */ jsx19(Box13, { flexDirection: "column", marginTop: 1, children: shortcuts.map((item, idx) => /* @__PURE__ */ jsx19(Box13, { marginY: 0, children: item.key ? /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
3623
|
+
/* @__PURE__ */ jsx19(Box13, { width: 20, children: /* @__PURE__ */ jsx19(Text10, { color: theme.colors.timelineEventStarted, children: item.key }) }),
|
|
3624
|
+
/* @__PURE__ */ jsx19(Text10, { color: theme.colors.foreground, children: item.action })
|
|
3625
|
+
] }) : /* @__PURE__ */ jsx19(Text10, { color: theme.colors.separator, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) }, idx)) }),
|
|
3626
|
+
/* @__PURE__ */ jsx19(Box13, { marginY: 1, children: /* @__PURE__ */ jsx19(Text10, { color: theme.colors.keyboardHint, dimColor: true, children: "Press '?' to close" }) })
|
|
3483
3627
|
]
|
|
3484
3628
|
}
|
|
3485
3629
|
) });
|
|
3486
3630
|
};
|
|
3487
3631
|
|
|
3488
3632
|
// src/components/common/ThemeDialog.tsx
|
|
3489
|
-
import { useState as
|
|
3633
|
+
import { useState as useState9, useMemo as useMemo3, useEffect as useEffect10 } from "react";
|
|
3490
3634
|
import { Box as Box14, Text as Text11, useInput as useInput6 } from "ink";
|
|
3491
|
-
import { jsx as
|
|
3635
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3492
3636
|
var ThemeDialog = () => {
|
|
3493
3637
|
const { theme, setTheme, themeName } = useTheme();
|
|
3494
3638
|
const { setShowThemeDialog } = useApp();
|
|
3495
|
-
const [searchQuery, setSearchQuery] =
|
|
3496
|
-
const [focusMode, setFocusMode] =
|
|
3639
|
+
const [searchQuery, setSearchQuery] = useState9("");
|
|
3640
|
+
const [focusMode, setFocusMode] = useState9("search");
|
|
3497
3641
|
const lightThemes2 = useMemo3(() => getLightThemeNames(), []);
|
|
3498
3642
|
const darkThemes2 = useMemo3(() => getDarkThemeNames(), []);
|
|
3499
3643
|
const allThemes = useMemo3(() => {
|
|
@@ -3527,7 +3671,7 @@ var ThemeDialog = () => {
|
|
|
3527
3671
|
const idx = themeItems.findIndex((item) => item.value === themeName);
|
|
3528
3672
|
return idx >= 0 ? idx : 0;
|
|
3529
3673
|
}, [themeItems, themeName]);
|
|
3530
|
-
const [selectedIndex, setSelectedIndex] =
|
|
3674
|
+
const [selectedIndex, setSelectedIndex] = useState9(initialIndex);
|
|
3531
3675
|
useEffect10(() => {
|
|
3532
3676
|
setSelectedIndex(0);
|
|
3533
3677
|
}, [searchQuery]);
|
|
@@ -3574,7 +3718,7 @@ var ThemeDialog = () => {
|
|
|
3574
3718
|
const formatThemeName = (name) => {
|
|
3575
3719
|
return name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
3576
3720
|
};
|
|
3577
|
-
return /* @__PURE__ */
|
|
3721
|
+
return /* @__PURE__ */ jsx20(Modal, { children: /* @__PURE__ */ jsxs13(
|
|
3578
3722
|
Box14,
|
|
3579
3723
|
{
|
|
3580
3724
|
flexDirection: "column",
|
|
@@ -3585,13 +3729,13 @@ var ThemeDialog = () => {
|
|
|
3585
3729
|
width: 44,
|
|
3586
3730
|
backgroundColor: theme.colors.modalBackground || theme.colors.background,
|
|
3587
3731
|
children: [
|
|
3588
|
-
/* @__PURE__ */
|
|
3732
|
+
/* @__PURE__ */ jsx20(Text11, { bold: true, color: theme.colors.calendarHeader, underline: true, children: "Select Theme" }),
|
|
3589
3733
|
/* @__PURE__ */ jsxs13(Box14, { marginTop: 1, flexDirection: "row", alignItems: "center", children: [
|
|
3590
3734
|
/* @__PURE__ */ jsxs13(Text11, { color: theme.colors.foreground, dimColor: true, children: [
|
|
3591
3735
|
"Search:",
|
|
3592
3736
|
" "
|
|
3593
3737
|
] }),
|
|
3594
|
-
/* @__PURE__ */
|
|
3738
|
+
/* @__PURE__ */ jsx20(
|
|
3595
3739
|
ControlledTextInput,
|
|
3596
3740
|
{
|
|
3597
3741
|
value: searchQuery,
|
|
@@ -3609,21 +3753,21 @@ var ThemeDialog = () => {
|
|
|
3609
3753
|
}
|
|
3610
3754
|
)
|
|
3611
3755
|
] }),
|
|
3612
|
-
/* @__PURE__ */
|
|
3756
|
+
/* @__PURE__ */ jsx20(Box14, { flexDirection: "column", marginTop: 1, children: allThemes.map((item, idx) => {
|
|
3613
3757
|
if (item.type === "separator") {
|
|
3614
|
-
return /* @__PURE__ */
|
|
3758
|
+
return /* @__PURE__ */ jsx20(
|
|
3615
3759
|
Box14,
|
|
3616
3760
|
{
|
|
3617
3761
|
marginTop: idx > 0 ? 1 : 0,
|
|
3618
3762
|
marginBottom: 0,
|
|
3619
|
-
children: /* @__PURE__ */
|
|
3763
|
+
children: /* @__PURE__ */ jsx20(Text11, { bold: true, color: theme.colors.calendarHeader, dimColor: true, children: item.value })
|
|
3620
3764
|
},
|
|
3621
3765
|
`sep-${idx}`
|
|
3622
3766
|
);
|
|
3623
3767
|
}
|
|
3624
3768
|
const isSelected = item.value === selectedThemeName;
|
|
3625
3769
|
const isCurrent = item.value === themeName;
|
|
3626
|
-
return /* @__PURE__ */
|
|
3770
|
+
return /* @__PURE__ */ jsx20(Box14, { paddingLeft: 1, children: /* @__PURE__ */ jsxs13(
|
|
3627
3771
|
Text11,
|
|
3628
3772
|
{
|
|
3629
3773
|
color: isSelected ? theme.colors.focusIndicator : theme.colors.foreground,
|
|
@@ -3636,7 +3780,7 @@ var ThemeDialog = () => {
|
|
|
3636
3780
|
}
|
|
3637
3781
|
) }, item.value);
|
|
3638
3782
|
}) }),
|
|
3639
|
-
/* @__PURE__ */
|
|
3783
|
+
/* @__PURE__ */ jsx20(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx20(Text11, { color: theme.colors.keyboardHint, dimColor: true, children: focusMode === "search" ? "Type to search \u2022 \u2193 to navigate list \u2022 Esc to close" : "\u2191/\u2193 or k/j to navigate \u2022 Enter to select \u2022 Esc to close" }) })
|
|
3640
3784
|
]
|
|
3641
3785
|
}
|
|
3642
3786
|
) });
|
|
@@ -3645,7 +3789,7 @@ var ThemeDialog = () => {
|
|
|
3645
3789
|
// src/components/common/ClearTimelineDialog.tsx
|
|
3646
3790
|
import { Box as Box15, Text as Text12, useInput as useInput7 } from "ink";
|
|
3647
3791
|
import { format as format2 } from "date-fns";
|
|
3648
|
-
import { jsx as
|
|
3792
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3649
3793
|
var ClearTimelineDialog = () => {
|
|
3650
3794
|
const { theme } = useTheme();
|
|
3651
3795
|
const {
|
|
@@ -3672,7 +3816,7 @@ var ClearTimelineDialog = () => {
|
|
|
3672
3816
|
handleCancel();
|
|
3673
3817
|
}
|
|
3674
3818
|
});
|
|
3675
|
-
return /* @__PURE__ */
|
|
3819
|
+
return /* @__PURE__ */ jsx21(Modal, { children: /* @__PURE__ */ jsxs14(
|
|
3676
3820
|
Box15,
|
|
3677
3821
|
{
|
|
3678
3822
|
flexDirection: "column",
|
|
@@ -3682,39 +3826,39 @@ var ClearTimelineDialog = () => {
|
|
|
3682
3826
|
paddingY: 2,
|
|
3683
3827
|
backgroundColor: theme.colors.modalBackground || theme.colors.background,
|
|
3684
3828
|
children: [
|
|
3685
|
-
/* @__PURE__ */
|
|
3829
|
+
/* @__PURE__ */ jsx21(Box15, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx21(Text12, { bold: true, color: theme.colors.taskStateDelayed, children: "Clear Timeline" }) }),
|
|
3686
3830
|
/* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", marginY: 1, children: [
|
|
3687
|
-
/* @__PURE__ */
|
|
3688
|
-
/* @__PURE__ */
|
|
3831
|
+
/* @__PURE__ */ jsx21(Text12, { color: theme.colors.foreground, children: "You are about to clear the timeline for" }),
|
|
3832
|
+
/* @__PURE__ */ jsx21(Box15, { justifyContent: "center", marginY: 1, children: /* @__PURE__ */ jsx21(Text12, { bold: true, color: theme.colors.calendarHeader, children: formattedDate }) }),
|
|
3689
3833
|
eventCount > 0 ? /* @__PURE__ */ jsxs14(Text12, { color: theme.colors.keyboardHint, children: [
|
|
3690
3834
|
"This will remove ",
|
|
3691
3835
|
eventCount,
|
|
3692
3836
|
" event",
|
|
3693
3837
|
eventCount !== 1 ? "s" : "",
|
|
3694
3838
|
" from the timeline."
|
|
3695
|
-
] }) : /* @__PURE__ */
|
|
3839
|
+
] }) : /* @__PURE__ */ jsx21(Text12, { color: theme.colors.keyboardHint, dimColor: true, children: "The timeline is already empty." })
|
|
3696
3840
|
] }),
|
|
3697
3841
|
/* @__PURE__ */ jsxs14(Box15, { marginTop: 2, justifyContent: "center", children: [
|
|
3698
|
-
/* @__PURE__ */
|
|
3699
|
-
/* @__PURE__ */
|
|
3700
|
-
/* @__PURE__ */
|
|
3701
|
-
/* @__PURE__ */
|
|
3842
|
+
/* @__PURE__ */ jsx21(Text12, { color: theme.colors.foreground, children: "Are you sure? " }),
|
|
3843
|
+
/* @__PURE__ */ jsx21(Text12, { color: theme.colors.taskStateCompleted, bold: true, children: "[Y]es" }),
|
|
3844
|
+
/* @__PURE__ */ jsx21(Text12, { color: theme.colors.foreground, children: " / " }),
|
|
3845
|
+
/* @__PURE__ */ jsx21(Text12, { color: theme.colors.taskStateDelayed, bold: true, children: "[N]o" })
|
|
3702
3846
|
] }),
|
|
3703
|
-
/* @__PURE__ */
|
|
3847
|
+
/* @__PURE__ */ jsx21(Box15, { marginTop: 2, justifyContent: "center", children: /* @__PURE__ */ jsx21(Text12, { color: theme.colors.keyboardHint, dimColor: true, children: "Press Y to confirm, N or Esc to cancel" }) })
|
|
3704
3848
|
]
|
|
3705
3849
|
}
|
|
3706
3850
|
) });
|
|
3707
3851
|
};
|
|
3708
3852
|
|
|
3709
3853
|
// src/components/overview/OverviewScreen.tsx
|
|
3710
|
-
import
|
|
3854
|
+
import React10, { useMemo as useMemo4 } from "react";
|
|
3711
3855
|
import { Box as Box16, Text as Text13, useInput as useInput8 } from "ink";
|
|
3712
3856
|
import { startOfMonth as startOfMonth2, endOfMonth as endOfMonth2, eachDayOfInterval as eachDayOfInterval2 } from "date-fns";
|
|
3713
|
-
import { jsx as
|
|
3857
|
+
import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3714
3858
|
var OverviewScreen = () => {
|
|
3715
3859
|
const { theme } = useTheme();
|
|
3716
3860
|
const { tasks, overviewMonth, setOverviewMonth, setShowOverview } = useApp();
|
|
3717
|
-
const [scrollOffset, setScrollOffset] =
|
|
3861
|
+
const [scrollOffset, setScrollOffset] = React10.useState(0);
|
|
3718
3862
|
const { height: terminalHeight } = useTerminalSize();
|
|
3719
3863
|
const visibleRows = useMemo4(() => {
|
|
3720
3864
|
return Math.max(2, Math.floor((terminalHeight - 9) / 3));
|
|
@@ -3750,7 +3894,7 @@ var OverviewScreen = () => {
|
|
|
3750
3894
|
setOverviewMonth({ ...overviewMonth, month: newMonth });
|
|
3751
3895
|
}
|
|
3752
3896
|
};
|
|
3753
|
-
|
|
3897
|
+
React10.useEffect(() => {
|
|
3754
3898
|
setScrollOffset(0);
|
|
3755
3899
|
}, [overviewMonth]);
|
|
3756
3900
|
useInput8((input, key) => {
|
|
@@ -3791,18 +3935,18 @@ var OverviewScreen = () => {
|
|
|
3791
3935
|
const canScrollDown = scrollOffset + visibleRows < rows;
|
|
3792
3936
|
return /* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", padding: 1, width: "100%", height: "100%", children: [
|
|
3793
3937
|
/* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", marginBottom: 1, children: [
|
|
3794
|
-
/* @__PURE__ */
|
|
3795
|
-
/* @__PURE__ */
|
|
3938
|
+
/* @__PURE__ */ jsx22(Text13, { bold: true, color: theme.colors.focusIndicator, children: "Overview" }),
|
|
3939
|
+
/* @__PURE__ */ jsx22(Text13, { color: theme.colors.foreground, children: monthName })
|
|
3796
3940
|
] }),
|
|
3797
3941
|
/* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", flexGrow: 1, children: [
|
|
3798
|
-
canScrollUp && /* @__PURE__ */
|
|
3942
|
+
canScrollUp && /* @__PURE__ */ jsx22(Box16, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx22(Text13, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
|
|
3799
3943
|
visibleRowData.map((_, index) => {
|
|
3800
3944
|
const rowIndex = scrollOffset + index;
|
|
3801
|
-
return /* @__PURE__ */
|
|
3945
|
+
return /* @__PURE__ */ jsx22(Box16, { flexDirection: "row", marginBottom: 1, children: Array.from({ length: columns }).map((_2, colIndex) => {
|
|
3802
3946
|
const dateIndex = rowIndex * columns + colIndex;
|
|
3803
3947
|
const date = monthDates[dateIndex];
|
|
3804
3948
|
if (!date) {
|
|
3805
|
-
return /* @__PURE__ */
|
|
3949
|
+
return /* @__PURE__ */ jsx22(
|
|
3806
3950
|
Box16,
|
|
3807
3951
|
{
|
|
3808
3952
|
flexDirection: "column",
|
|
@@ -3831,9 +3975,9 @@ var OverviewScreen = () => {
|
|
|
3831
3975
|
flexBasis: 0,
|
|
3832
3976
|
marginRight: colIndex === columns - 1 ? 0 : 2,
|
|
3833
3977
|
children: [
|
|
3834
|
-
/* @__PURE__ */
|
|
3978
|
+
/* @__PURE__ */ jsx22(Text13, { bold: true, color: theme.colors.calendarSelected, children: formatDate(date, "do MMM") }),
|
|
3835
3979
|
/* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", children: [
|
|
3836
|
-
flatTasksWithDepth.length === 0 ? /* @__PURE__ */
|
|
3980
|
+
flatTasksWithDepth.length === 0 ? /* @__PURE__ */ jsx22(Text13, { dimColor: true, color: theme.colors.keyboardHint, children: "No tasks" }) : flatTasksWithDepth.slice(0, 10).map(({ task, depth }) => /* @__PURE__ */ jsx22(
|
|
3837
3981
|
TaskItem,
|
|
3838
3982
|
{
|
|
3839
3983
|
task,
|
|
@@ -3854,9 +3998,9 @@ var OverviewScreen = () => {
|
|
|
3854
3998
|
);
|
|
3855
3999
|
}) }, rowIndex);
|
|
3856
4000
|
}),
|
|
3857
|
-
canScrollDown && /* @__PURE__ */
|
|
4001
|
+
canScrollDown && /* @__PURE__ */ jsx22(Box16, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx22(Text13, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
|
|
3858
4002
|
] }),
|
|
3859
|
-
/* @__PURE__ */
|
|
4003
|
+
/* @__PURE__ */ jsx22(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx22(Text13, { color: theme.colors.keyboardHint, dimColor: true, children: "n/p or \u2190/\u2192: month | j/k or \u2193/\u2191: scroll | Esc: close | Shift+;: toggle" }) })
|
|
3860
4004
|
] });
|
|
3861
4005
|
};
|
|
3862
4006
|
var TaskItem = ({ task, theme, depth }) => {
|
|
@@ -3867,8 +4011,8 @@ var TaskItem = ({ task, theme, depth }) => {
|
|
|
3867
4011
|
checkbox,
|
|
3868
4012
|
" "
|
|
3869
4013
|
] }),
|
|
3870
|
-
depth > 0 && /* @__PURE__ */
|
|
3871
|
-
/* @__PURE__ */
|
|
4014
|
+
depth > 0 && /* @__PURE__ */ jsx22(Text13, { children: " ".repeat(depth) }),
|
|
4015
|
+
/* @__PURE__ */ jsx22(
|
|
3872
4016
|
Text13,
|
|
3873
4017
|
{
|
|
3874
4018
|
color,
|
|
@@ -3902,7 +4046,7 @@ function getStateColor2(state, theme) {
|
|
|
3902
4046
|
}
|
|
3903
4047
|
|
|
3904
4048
|
// src/App.tsx
|
|
3905
|
-
import { jsx as
|
|
4049
|
+
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3906
4050
|
var AppContent = () => {
|
|
3907
4051
|
const {
|
|
3908
4052
|
showHelp,
|
|
@@ -3916,26 +4060,26 @@ var AppContent = () => {
|
|
|
3916
4060
|
useKeyboardNav();
|
|
3917
4061
|
const { width, height } = useTerminalSize();
|
|
3918
4062
|
if (showThemeDialog) {
|
|
3919
|
-
return /* @__PURE__ */
|
|
4063
|
+
return /* @__PURE__ */ jsx23(ThemeDialog, {});
|
|
3920
4064
|
}
|
|
3921
4065
|
if (showHelp) {
|
|
3922
|
-
return /* @__PURE__ */
|
|
4066
|
+
return /* @__PURE__ */ jsx23(HelpDialog, {});
|
|
3923
4067
|
}
|
|
3924
4068
|
if (showClearTimelineDialog) {
|
|
3925
|
-
return /* @__PURE__ */
|
|
4069
|
+
return /* @__PURE__ */ jsx23(ClearTimelineDialog, {});
|
|
3926
4070
|
}
|
|
3927
|
-
return /* @__PURE__ */
|
|
3928
|
-
showOverview ? /* @__PURE__ */
|
|
4071
|
+
return /* @__PURE__ */ jsx23(FullscreenBackground, { backgroundColor: theme.colors.background || "black", children: /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", width, height, padding: 1, backgroundColor: theme.colors.background, children: [
|
|
4072
|
+
showOverview ? /* @__PURE__ */ jsx23(OverviewScreen, {}) : /* @__PURE__ */ jsx23(
|
|
3929
4073
|
ThreeColumnLayout,
|
|
3930
4074
|
{
|
|
3931
|
-
leftPane: /* @__PURE__ */
|
|
3932
|
-
centerPane: /* @__PURE__ */
|
|
3933
|
-
rightPane: /* @__PURE__ */
|
|
4075
|
+
leftPane: /* @__PURE__ */ jsx23(CalendarPane, {}),
|
|
4076
|
+
centerPane: /* @__PURE__ */ jsx23(TasksPane, {}),
|
|
4077
|
+
rightPane: /* @__PURE__ */ jsx23(TimelinePane, {}),
|
|
3934
4078
|
activePane,
|
|
3935
4079
|
height: height - 2
|
|
3936
4080
|
}
|
|
3937
4081
|
),
|
|
3938
|
-
exitConfirmation && /* @__PURE__ */
|
|
4082
|
+
exitConfirmation && /* @__PURE__ */ jsx23(Box17, { width: "100%", justifyContent: "center", paddingY: 1, children: /* @__PURE__ */ jsxs16(Text14, { backgroundColor: "red", color: "white", bold: true, children: [
|
|
3939
4083
|
" ",
|
|
3940
4084
|
"Press Ctrl+C again to exit Epoch",
|
|
3941
4085
|
" "
|
|
@@ -3943,12 +4087,12 @@ var AppContent = () => {
|
|
|
3943
4087
|
] }) });
|
|
3944
4088
|
};
|
|
3945
4089
|
var App = () => {
|
|
3946
|
-
return /* @__PURE__ */
|
|
4090
|
+
return /* @__PURE__ */ jsx23(StorageProvider, { children: /* @__PURE__ */ jsx23(ThemeProvider, { initialTheme: "dark", children: /* @__PURE__ */ jsx23(UndoProvider, { children: /* @__PURE__ */ jsx23(AppProvider, { children: /* @__PURE__ */ jsx23(AppContent, {}) }) }) }) });
|
|
3947
4091
|
};
|
|
3948
4092
|
var App_default = App;
|
|
3949
4093
|
|
|
3950
4094
|
// src/index.tsx
|
|
3951
|
-
import { jsx as
|
|
4095
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3952
4096
|
console.clear();
|
|
3953
|
-
var app = render(/* @__PURE__ */
|
|
4097
|
+
var app = render(/* @__PURE__ */ jsx24(App_default, {}), { exitOnCtrlC: false });
|
|
3954
4098
|
global.__inkApp = app;
|