Skip to content

Commit 0cd3288

Browse files
committed
fix: wrong metadata issue with 9.0.0
1 parent 5e7f28e commit 0cd3288

5 files changed

Lines changed: 10404 additions & 102 deletions

File tree

src/components/kanban/kanban-card.ts

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,9 @@ export class KanbanCardComponent extends Component {
4747
if (this.task.completed) {
4848
this.element.classList.add("task-completed");
4949
}
50-
if (this.task.metadata.priority) {
51-
this.element.classList.add(
52-
`priority-${this.task.metadata.priority}`
53-
);
50+
const metadata = this.task.metadata || {};
51+
if (metadata.priority) {
52+
this.element.classList.add(`priority-${metadata.priority}`);
5453
}
5554

5655
// --- Card Content ---
@@ -135,31 +134,32 @@ export class KanbanCardComponent extends Component {
135134
private renderMetadata() {
136135
this.metadataEl.empty();
137136

137+
const metadata = this.task.metadata || {};
138138
// Display dates (similar to TaskListItemComponent)
139139
if (!this.task.completed) {
140-
if (this.task.metadata.dueDate) this.renderDueDate();
140+
if (metadata.dueDate) this.renderDueDate();
141141
// Add scheduled, start dates if needed
142142
} else {
143-
if (this.task.metadata.completedDate) this.renderCompletionDate();
143+
if (metadata.completedDate) this.renderCompletionDate();
144144
// Add created date if needed
145145
}
146146

147147
// Project (if not grouped by project already) - Kanban might inherently group by status
148148
if (getEffectiveProject(this.task)) this.renderProject();
149149

150150
// Tags
151-
if (this.task.metadata.tags && this.task.metadata.tags.length > 0)
152-
this.renderTags();
151+
if (metadata.tags && metadata.tags.length > 0) this.renderTags();
153152

154153
// Priority
155-
if (this.task.metadata.priority) this.renderPriority();
154+
if (metadata.priority) this.renderPriority();
156155
}
157156

158157
private renderDueDate() {
159158
const dueEl = this.metadataEl.createEl("div", {
160159
cls: ["task-date", "task-due-date"],
161160
});
162-
const dueDate = new Date(this.task.metadata.dueDate || "");
161+
const metadata = this.task.metadata || {};
162+
const dueDate = new Date(metadata.dueDate || "");
163163
const today = new Date();
164164
today.setHours(0, 0, 0, 0);
165165
const tomorrow = new Date(today);
@@ -191,7 +191,8 @@ export class KanbanCardComponent extends Component {
191191
const completedEl = this.metadataEl.createEl("div", {
192192
cls: ["task-date", "task-done-date"],
193193
});
194-
const completedDate = new Date(this.task.metadata.completedDate || "");
194+
const metadata = this.task.metadata || {};
195+
const completedDate = new Date(metadata.completedDate || "");
195196
completedEl.textContent = `Done: ${completedDate.toLocaleDateString(
196197
undefined,
197198
{ month: "short", day: "numeric" }
@@ -211,11 +212,12 @@ export class KanbanCardComponent extends Component {
211212
});
212213

213214
// Add visual indicator for tgProject
214-
if (!this.task.metadata.project && this.task.metadata.tgProject) {
215+
const metadata = this.task.metadata || {};
216+
if (!metadata.project && metadata.tgProject) {
215217
projectEl.addClass("task-project-tg");
216-
projectEl.title = `Project from ${
217-
this.task.metadata.tgProject.type
218-
}: ${this.task.metadata.tgProject.source || ""}`;
218+
projectEl.title = `Project from ${metadata.tgProject.type}: ${
219+
metadata.tgProject.source || ""
220+
}`;
219221
}
220222

221223
projectEl.textContent = effectiveProject;
@@ -234,7 +236,8 @@ export class KanbanCardComponent extends Component {
234236
const tagsContainer = this.metadataEl.createEl("div", {
235237
cls: "task-tags-container",
236238
});
237-
this.task.metadata.tags.forEach((tag) => {
239+
const metadata = this.task.metadata || {};
240+
(metadata.tags || []).forEach((tag) => {
238241
// Skip non-string tags
239242
if (typeof tag !== "string") {
240243
return;
@@ -263,29 +266,23 @@ export class KanbanCardComponent extends Component {
263266
}
264267

265268
private renderPriority() {
269+
const metadata = this.task.metadata || {};
266270
const priorityEl = this.metadataEl.createDiv({
267271
cls: [
268272
"task-priority",
269-
`priority-${this.task.metadata.priority}`,
273+
`priority-${metadata.priority}`,
270274
"clickable-metadata",
271275
],
272276
});
273-
priorityEl.textContent = `${"!".repeat(
274-
this.task.metadata.priority || 0
275-
)}`;
276-
priorityEl.setAttribute(
277-
"aria-label",
278-
`Priority ${this.task.metadata.priority}`
279-
);
277+
priorityEl.textContent = `${"!".repeat(metadata.priority || 0)}`;
278+
priorityEl.setAttribute("aria-label", `Priority ${metadata.priority}`);
280279

281280
// Make priority clickable for filtering
282281
this.registerDomEvent(priorityEl, "click", (ev) => {
283282
ev.stopPropagation();
284-
if (this.params.onFilterApply && this.task.metadata.priority) {
283+
if (this.params.onFilterApply && metadata.priority) {
285284
// Convert numeric priority to icon representation for filter compatibility
286-
const priorityIcon = this.getPriorityIcon(
287-
this.task.metadata.priority
288-
);
285+
const priorityIcon = this.getPriorityIcon(metadata.priority);
289286
this.params.onFilterApply("priority", priorityIcon);
290287
}
291288
});
@@ -336,19 +333,20 @@ export class KanbanCardComponent extends Component {
336333
const oldTask = this.task;
337334
this.task = newTask;
338335

336+
const oldMetadata = oldTask.metadata || {};
337+
const newMetadata = newTask.metadata || {};
338+
339339
// Update classes
340340
if (oldTask.completed !== newTask.completed) {
341341
this.element.classList.toggle("task-completed", newTask.completed);
342342
}
343-
if (oldTask.metadata.priority !== newTask.metadata.priority) {
344-
if (oldTask.metadata.priority)
343+
if (oldMetadata.priority !== newMetadata.priority) {
344+
if (oldMetadata.priority)
345345
this.element.classList.remove(
346-
`priority-${oldTask.metadata.priority}`
347-
);
348-
if (newTask.metadata.priority)
349-
this.element.classList.add(
350-
`priority-${newTask.metadata.priority}`
346+
`priority-${oldMetadata.priority}`
351347
);
348+
if (newMetadata.priority)
349+
this.element.classList.add(`priority-${newMetadata.priority}`);
352350
}
353351

354352
// Re-render content and metadata if needed
@@ -361,12 +359,11 @@ export class KanbanCardComponent extends Component {
361359
}
362360
// Check if metadata-relevant fields changed
363361
if (
364-
oldTask.metadata.dueDate !== newTask.metadata.dueDate ||
365-
oldTask.metadata.completedDate !== newTask.metadata.completedDate ||
366-
oldTask.metadata.tags?.join(",") !==
367-
newTask.metadata.tags?.join(",") || // Simple comparison
368-
oldTask.metadata.priority !== newTask.metadata.priority ||
369-
oldTask.metadata.project !== newTask.metadata.project
362+
oldMetadata.dueDate !== newMetadata.dueDate ||
363+
oldMetadata.completedDate !== newMetadata.completedDate ||
364+
oldMetadata.tags?.join(",") !== newMetadata.tags?.join(",") || // Simple comparison
365+
oldMetadata.priority !== newMetadata.priority ||
366+
oldMetadata.project !== newMetadata.project
370367
) {
371368
this.renderMetadata();
372369
}

src/components/kanban/kanban.ts

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,9 @@ export class KanbanComponent extends Component {
578578
// Get unique tags from all tasks
579579
const allTags = new Set<string>();
580580
this.tasks.forEach((task) => {
581-
if (task.metadata.tags) {
582-
task.metadata.tags.forEach((tag) => {
581+
const metadata = task.metadata || {};
582+
if (metadata.tags) {
583+
metadata.tags.forEach((tag) => {
583584
// Skip non-string tags
584585
if (typeof tag === "string") {
585586
allTags.add(tag);
@@ -624,8 +625,9 @@ export class KanbanComponent extends Component {
624625
// Get unique contexts from all tasks
625626
const allContexts = new Set<string>();
626627
this.tasks.forEach((task) => {
627-
if (task.metadata.context) {
628-
allContexts.add(task.metadata.context);
628+
const metadata = task.metadata || {};
629+
if (metadata.context) {
630+
allContexts.add(metadata.context);
629631
}
630632
});
631633
const contextColumns = Array.from(allContexts).map(
@@ -723,34 +725,38 @@ export class KanbanComponent extends Component {
723725
const { field, order } = sortOption;
724726
let comparison = 0;
725727

728+
// Ensure both tasks have metadata property
729+
const metadataA = a.metadata || {};
730+
const metadataB = b.metadata || {};
731+
726732
switch (field) {
727733
case "priority":
728-
const priorityA = a.metadata.priority ?? 0;
729-
const priorityB = b.metadata.priority ?? 0;
734+
const priorityA = metadataA.priority ?? 0;
735+
const priorityB = metadataB.priority ?? 0;
730736
comparison = priorityA - priorityB;
731737
break;
732738
case "dueDate":
733-
const dueDateA = a.metadata.dueDate ?? Number.MAX_SAFE_INTEGER;
734-
const dueDateB = b.metadata.dueDate ?? Number.MAX_SAFE_INTEGER;
739+
const dueDateA = metadataA.dueDate ?? Number.MAX_SAFE_INTEGER;
740+
const dueDateB = metadataB.dueDate ?? Number.MAX_SAFE_INTEGER;
735741
comparison = dueDateA - dueDateB;
736742
break;
737743
case "scheduledDate":
738744
const scheduledA =
739-
a.metadata.scheduledDate ?? Number.MAX_SAFE_INTEGER;
745+
metadataA.scheduledDate ?? Number.MAX_SAFE_INTEGER;
740746
const scheduledB =
741-
b.metadata.scheduledDate ?? Number.MAX_SAFE_INTEGER;
747+
metadataB.scheduledDate ?? Number.MAX_SAFE_INTEGER;
742748
comparison = scheduledA - scheduledB;
743749
break;
744750
case "startDate":
745-
const startA = a.metadata.startDate ?? Number.MAX_SAFE_INTEGER;
746-
const startB = b.metadata.startDate ?? Number.MAX_SAFE_INTEGER;
751+
const startA = metadataA.startDate ?? Number.MAX_SAFE_INTEGER;
752+
const startB = metadataB.startDate ?? Number.MAX_SAFE_INTEGER;
747753
comparison = startA - startB;
748754
break;
749755
case "createdDate":
750756
const createdA =
751-
a.metadata.createdDate ?? Number.MAX_SAFE_INTEGER;
757+
metadataA.createdDate ?? Number.MAX_SAFE_INTEGER;
752758
const createdB =
753-
b.metadata.createdDate ?? Number.MAX_SAFE_INTEGER;
759+
metadataB.createdDate ?? Number.MAX_SAFE_INTEGER;
754760
comparison = createdA - createdB;
755761
break;
756762
}
@@ -936,6 +942,8 @@ export class KanbanComponent extends Component {
936942
return;
937943
}
938944

945+
taskToUpdate.metadata = taskToUpdate.metadata || {};
946+
939947
// Create updated task object
940948
const updatedTask = { ...taskToUpdate };
941949

@@ -1013,7 +1021,9 @@ export class KanbanComponent extends Component {
10131021
// Only update project if it's not a read-only tgProject
10141022
if (!isProjectReadonly(taskToUpdate)) {
10151023
updatedTask.metadata.project =
1016-
newValue === null || newValue === "" ? undefined : newValue;
1024+
newValue === null || newValue === ""
1025+
? undefined
1026+
: newValue;
10171027
}
10181028
break;
10191029
case "context":
@@ -1060,22 +1070,20 @@ export class KanbanComponent extends Component {
10601070
private getTasksForProperty(groupBy: string, value: any): Task[] {
10611071
// Filter tasks based on the groupBy property and value
10621072
const tasksForProperty = this.tasks.filter((task) => {
1073+
const metadata = task.metadata || {};
10631074
switch (groupBy) {
10641075
case "priority":
10651076
if (value === null || value === "") {
1066-
return !task.metadata.priority;
1077+
return !metadata.priority;
10671078
}
1068-
return task.metadata.priority === value;
1079+
return metadata.priority === value;
10691080
case "tags":
10701081
if (value === null || value === "") {
1071-
return (
1072-
!task.metadata.tags ||
1073-
task.metadata.tags.length === 0
1074-
);
1082+
return !metadata.tags || metadata.tags.length === 0;
10751083
}
10761084
return (
1077-
task.metadata.tags &&
1078-
task.metadata.tags.some(
1085+
metadata.tags &&
1086+
metadata.tags.some(
10791087
(tag) => typeof tag === "string" && tag === value
10801088
)
10811089
);
@@ -1086,9 +1094,9 @@ export class KanbanComponent extends Component {
10861094
return getEffectiveProject(task) === value;
10871095
case "context":
10881096
if (value === null || value === "") {
1089-
return !task.metadata.context;
1097+
return !metadata.context;
10901098
}
1091-
return task.metadata.context === value;
1099+
return metadata.context === value;
10921100
case "dueDate":
10931101
case "scheduledDate":
10941102
case "startDate":
@@ -1125,16 +1133,17 @@ export class KanbanComponent extends Component {
11251133
today.getTime() + 14 * 24 * 60 * 60 * 1000
11261134
);
11271135

1136+
const metadata = task.metadata || {};
11281137
let taskDate: number | undefined;
11291138
switch (dateField) {
11301139
case "dueDate":
1131-
taskDate = task.metadata.dueDate;
1140+
taskDate = metadata.dueDate;
11321141
break;
11331142
case "scheduledDate":
1134-
taskDate = task.metadata.scheduledDate;
1143+
taskDate = metadata.scheduledDate;
11351144
break;
11361145
case "startDate":
1137-
taskDate = task.metadata.startDate;
1146+
taskDate = metadata.startDate;
11381147
break;
11391148
}
11401149

@@ -1270,6 +1279,7 @@ export class KanbanComponent extends Component {
12701279

12711280
private getTaskOriginalColumnValue(task: Task, groupBy: string): any {
12721281
// Determine which column the task currently belongs to based on its properties
1282+
const metadata = task.metadata || {};
12731283
switch (groupBy) {
12741284
case "tags":
12751285
// For tags, find which tag column this task would be in
@@ -1287,17 +1297,14 @@ export class KanbanComponent extends Component {
12871297
for (const column of kanbanConfig.customColumns) {
12881298
if (column.value === "" || column.value === null) {
12891299
// "No Tags" column
1290-
if (
1291-
!task.metadata.tags ||
1292-
task.metadata.tags.length === 0
1293-
) {
1300+
if (!metadata.tags || metadata.tags.length === 0) {
12941301
return "";
12951302
}
12961303
} else {
12971304
// Specific tag column
12981305
if (
1299-
task.metadata.tags &&
1300-
task.metadata.tags.some(
1306+
metadata.tags &&
1307+
metadata.tags.some(
13011308
(tag) =>
13021309
typeof tag === "string" &&
13031310
tag === column.value
@@ -1309,14 +1316,11 @@ export class KanbanComponent extends Component {
13091316
}
13101317
} else {
13111318
// Use default columns - find the first tag that matches existing columns
1312-
if (
1313-
!task.metadata.tags ||
1314-
task.metadata.tags.length === 0
1315-
) {
1319+
if (!metadata.tags || metadata.tags.length === 0) {
13161320
return "";
13171321
}
13181322
// Return the first string tag (for simplicity, as we need to determine which column it came from)
1319-
const firstStringTag = task.metadata.tags.find(
1323+
const firstStringTag = metadata.tags.find(
13201324
(tag) => typeof tag === "string"
13211325
);
13221326
return firstStringTag || "";
@@ -1325,15 +1329,15 @@ export class KanbanComponent extends Component {
13251329
case "project":
13261330
return getEffectiveProject(task) || "";
13271331
case "context":
1328-
return task.metadata.context || "";
1332+
return metadata.context || "";
13291333
case "priority":
1330-
return task.metadata.priority || null;
1334+
return metadata.priority || null;
13311335
case "dueDate":
1332-
return this.getDateCategory(task.metadata.dueDate);
1336+
return this.getDateCategory(metadata.dueDate);
13331337
case "scheduledDate":
1334-
return this.getDateCategory(task.metadata.scheduledDate);
1338+
return this.getDateCategory(metadata.scheduledDate);
13351339
case "startDate":
1336-
return this.getDateCategory(task.metadata.startDate);
1340+
return this.getDateCategory(metadata.startDate);
13371341
case "filePath":
13381342
return task.filePath;
13391343
default:

0 commit comments

Comments
 (0)