Skip to content

Commit 9892f43

Browse files
committed
Release version 2.5.0
2 parents efa109c + 4e54e3d commit 9892f43

File tree

12 files changed

+273
-9424
lines changed

12 files changed

+273
-9424
lines changed

app/app.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,4 +2972,48 @@ describe("filter bar", () => {
29722972
});
29732973
});
29742974
});
2975+
2976+
describe("ready filter is never shown in stalled tab", () => {
2977+
describe("in example with ready project and stalled subtask", () => {
2978+
const example = updateAll(empty, [
2979+
switchToFilter("all"),
2980+
addTask("Project", "project"),
2981+
addTask("Task 1", 1),
2982+
addTask("Task 2", 1, "ready"),
2983+
switchToFilter("stalled"),
2984+
]);
2985+
2986+
test("the correct tasks are shown in the stalled view", () => {
2987+
expect(tasks(example, ["title", "indentation", "badges"])).toEqual([
2988+
{title: "Project", indentation: 0, badges: ["project", "ready"]},
2989+
{title: "Task 1", indentation: 1, badges: ["stalled"]},
2990+
]);
2991+
});
2992+
2993+
test("the ready filter is not available in the filter bar", () => {
2994+
expect(filterBarHas(view(example), "Ready")).toBe(false);
2995+
});
2996+
});
2997+
2998+
describe("in example with non-project parent task that has both stalled and ready subtask", () => {
2999+
const example = updateAll(empty, [
3000+
switchToFilter("all"),
3001+
addTask("Task 1", 0),
3002+
addTask("Task 2", 1, "ready"),
3003+
addTask("Task 3", 1),
3004+
switchToFilter("stalled"),
3005+
]);
3006+
3007+
test("the correct tasks are shown in the stalled view", () => {
3008+
expect(tasks(example, ["title", "indentation", "badges"])).toEqual([
3009+
{title: "Task 1", indentation: 0, badges: []},
3010+
{title: "Task 3", indentation: 1, badges: ["stalled"]},
3011+
]);
3012+
});
3013+
3014+
test("the ready filter is not available in the filter bar", () => {
3015+
expect(filterBarHas(view(example), "Ready")).toBe(false);
3016+
});
3017+
});
3018+
});
29753019
});

app/app.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as Tasks from "./tasks";
33
import * as TaskEditor from "./task-editor";
44
import * as Drag from "./drag";
55
import * as Storage from "./storage";
6+
import * as Ui from "./ui";
67

78
type TextFieldId = "addTitle";
89

@@ -61,6 +62,7 @@ export type FilterIndicator =
6162

6263
export type FilterView = {
6364
label: string;
65+
icon: Ui.Icon;
6466
filter: Tasks.FilterId;
6567
selected: boolean;
6668
dropTarget: DropId | null;
@@ -72,7 +74,7 @@ export type SideBarSectionView = {title: string; filter: Tasks.FilterId; filters
7274
export type FileControlsView = "saveLoad" | null;
7375

7476
export type FilterBarView = {
75-
filters: {id: string; label: string; state: "neutral" | "include" | "exclude"}[];
77+
filters: {id: string; label: string; state: "neutral" | "include" | "exclude"; icon?: Ui.Icon}[];
7678
};
7779

7880
type DragInvariantView = Pick<View, "fileControls" | "addTask" | "sideBar" | "filterBar" | "editor">;
@@ -102,9 +104,16 @@ function viewFilterBar(state: State & {today: Date}): FilterBarView {
102104
return id;
103105
}
104106

107+
function filterIcon(id: Tasks.SubtaskFilter["id"]): Ui.Icon | undefined {
108+
if (id === "paused") return "paused";
109+
if (id === "done") return "completed";
110+
if (id === "ready") return "ready";
111+
return undefined;
112+
}
113+
105114
function filterViews(id: Tasks.SubtaskFilter["id"]) {
106115
return filterState(id) !== "neutral" || Tasks.isSubtaskFilterRelevant(state, id)
107-
? [{id: id, label: filterLabel(id), state: filterState(id)}]
116+
? [{id: id, label: filterLabel(id), icon: filterIcon(id), state: filterState(id)}]
108117
: [];
109118
}
110119

@@ -129,8 +138,25 @@ function viewSideBar(state: State & {today: Date}) {
129138
return {type: "text" as const, text: count.toString(), color: opts.counter};
130139
}
131140

141+
const icon: Ui.Icon =
142+
typeof filter === "object"
143+
? "project"
144+
: (
145+
{
146+
"all": "allTasks",
147+
"today": "today",
148+
"ready": "ready",
149+
"stalled": "stalled",
150+
"paused": "paused",
151+
"done": "completed",
152+
"not-done": "unfinished",
153+
"archive": "archive",
154+
} as const
155+
)[filter];
156+
132157
return {
133158
label: Tasks.filterTitle(state.tasks, filter),
159+
icon,
134160
filter,
135161
selected: Tasks.isSubfilter(state, state.filter, filter),
136162
dropTarget: {type: "filter", id: filter},

app/main.module.scss

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
.sidebar {
6262
grid-area: sidebar;
63-
background-color: #f0f0f0;
63+
background-color: #f4f4f4;
6464
border-right: 1px solid #00000020;
6565

6666
padding-bottom: 1em;
@@ -268,7 +268,7 @@
268268

269269
color: #888;
270270

271-
background-color: #f8f8f8;
271+
background-color: #f6f6f6;
272272

273273
border-bottom: 1px solid #aaa;
274274

@@ -279,30 +279,31 @@
279279
display: inline-block;
280280
transition: margin-left 100ms ease-out;
281281

282-
overflow: hidden;
283-
text-overflow: ellipsis;
284-
white-space: nowrap;
282+
.labelText {
283+
// Leave a little space between label and indicator when label is cut off.
284+
padding-right: 0.25em;
285+
286+
overflow: hidden;
287+
text-overflow: ellipsis;
288+
white-space: nowrap;
289+
}
285290
}
286291

287292
&:active .label {
288293
margin-left: -6px;
289294
}
290295

291296
&:hover, &:active {
292-
background-color: #f4f4f4;
297+
background-color: #f2f2f2;
293298
}
294299

295300
&.selected {
296301
color: #666;
297302
font-weight: 500;
298-
background-color: #f0f0f0;
303+
background-color: #e8e8e8;
299304

300305
&:hover {
301-
background-color: #ececec;
302-
}
303-
304-
.label {
305-
margin-left: 1em;
306+
background-color: #e4e4e4;
306307
}
307308
}
308309

app/main.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as Drag from "./drag";
77
import {TaskList} from "./task-list";
88

99
import * as style from "./main.module.scss";
10-
import {Button} from "./ui";
10+
import {Button, IconLabel} from "./ui";
1111

1212
function AddTask(props: {view: App.View["addTask"]; send(ev: App.Event): void}) {
1313
return (
@@ -51,7 +51,11 @@ function Filter(props: {
5151
onClick={() => props.send({tag: "selectFilter", filter: props.filter.filter})}
5252
className={props.filter.selected ? style.selected : ""}
5353
>
54-
<span className={style.label}>{props.filter.label}</span>
54+
<span className={style.label}>
55+
<IconLabel extraSpace icon={props.filter.icon}>
56+
<span className={style.labelText}>{props.filter.label}</span>
57+
</IconLabel>
58+
</span>
5559
<Indicator indicator={props.filter.indicator} />
5660
</button>
5761
);
@@ -174,7 +178,7 @@ function FilterButton(props: {filter: App.FilterBarView["filters"][number]; send
174178
}}
175179
onContextMenu={(ev) => ev.preventDefault()}
176180
>
177-
{props.filter.label}
181+
<IconLabel icon={props.filter.icon}>{props.filter.label}</IconLabel>
178182
</button>
179183
</div>
180184
);

0 commit comments

Comments
 (0)