mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-12 20:02:28 +08:00
Merge pull request #1366 from rom1dep/calendar_enh_displayed
feat(calendar) improvements
This commit is contained in:
commit
9b217a5b82
@ -138,7 +138,7 @@ export default class CalendarView extends ViewMode {
|
|||||||
|
|
||||||
// Promoted attributes
|
// Promoted attributes
|
||||||
if (promotedAttributes) {
|
if (promotedAttributes) {
|
||||||
for (const [name, value] of Object.entries(promotedAttributes)) {
|
for (const [name, value] of promotedAttributes) {
|
||||||
html += `\
|
html += `\
|
||||||
<div class="promoted-attribute">
|
<div class="promoted-attribute">
|
||||||
<span class="promoted-attribute-name">${name}</span>: <span class="promoted-attribute-value">${value}</span>
|
<span class="promoted-attribute-name">${name}</span>: <span class="promoted-attribute-value">${value}</span>
|
||||||
@ -229,8 +229,13 @@ export default class CalendarView extends ViewMode {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes.setAttribute(note, "label", "startDate", startDate);
|
// Since they can be customized via calendar:startDate=$foo and calendar:endDate=$bar we need to determine the
|
||||||
attributes.setAttribute(note, "label", "endDate", endDate);
|
// attributes to be effectively updated
|
||||||
|
const startAttribute = note.getAttributes("label").filter(attr => attr.name == "calendar:startDate").shift()?.value||"startDate"
|
||||||
|
const endAttribute = note.getAttributes("label").filter(attr => attr.name == "calendar:endDate").shift()?.value||"endDate"
|
||||||
|
|
||||||
|
attributes.setAttribute(note, "label", startAttribute, startDate);
|
||||||
|
attributes.setAttribute(note, "label", endAttribute, endDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEntitiesReloaded({ loadResults }: EventData<"entitiesReloaded">) {
|
onEntitiesReloaded({ loadResults }: EventData<"entitiesReloaded">) {
|
||||||
@ -321,7 +326,7 @@ export default class CalendarView extends ViewMode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the user to customize the attribute from which to obtain a particular value. For example, if `customLabelNameAttribute` is `calendar:startDate`
|
* Allows the user to customize the attribute from which to obtain a particular value. For example, if `customLabelNameAttribute` is `calendar:startDate`
|
||||||
* and `defaultLabelName` is `startDate` and the note at hand has `#calendar:startDate=#myStartDate #myStartDate=2025-02-26` then the value returned will
|
* and `defaultLabelName` is `startDate` and the note at hand has `#calendar:startDate=myStartDate #myStartDate=2025-02-26` then the value returned will
|
||||||
* be `2025-02-26`. If there is no custom attribute value, then the value of the default attribute is returned instead (e.g. `#startDate`).
|
* be `2025-02-26`. If there is no custom attribute value, then the value of the default attribute is returned instead (e.g. `#startDate`).
|
||||||
*
|
*
|
||||||
* @param note the note from which to read the values.
|
* @param note the note from which to read the values.
|
||||||
@ -331,8 +336,8 @@ export default class CalendarView extends ViewMode {
|
|||||||
*/
|
*/
|
||||||
static #getCustomisableLabel(note: FNote, defaultLabelName: string, customLabelNameAttribute: string) {
|
static #getCustomisableLabel(note: FNote, defaultLabelName: string, customLabelNameAttribute: string) {
|
||||||
const customAttributeName = note.getLabelValue(customLabelNameAttribute);
|
const customAttributeName = note.getLabelValue(customLabelNameAttribute);
|
||||||
if (customAttributeName?.startsWith("#")) {
|
if (customAttributeName) {
|
||||||
const customValue = note.getLabelValue(customAttributeName.substring(1));
|
const customValue = note.getLabelValue(customAttributeName);
|
||||||
if (customValue) {
|
if (customValue) {
|
||||||
return customValue;
|
return customValue;
|
||||||
}
|
}
|
||||||
@ -342,15 +347,15 @@ export default class CalendarView extends ViewMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async buildEvent(note: FNote, startDate: string, endDate?: string | null) {
|
static async buildEvent(note: FNote, startDate: string, endDate?: string | null) {
|
||||||
const customTitle = note.getLabelValue("calendar:title");
|
const customTitleAttributeName = note.getLabelValue("calendar:title");
|
||||||
const titles = await CalendarView.#parseCustomTitle(customTitle, note);
|
const titles = await CalendarView.#parseCustomTitle(customTitleAttributeName, note);
|
||||||
const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color");
|
const color = note.getLabelValue("calendar:color") ?? note.getLabelValue("color");
|
||||||
const events: EventInput[] = [];
|
const events: EventInput[] = [];
|
||||||
|
|
||||||
const calendarPromotedAttributes = note.getLabelValue("calendar:promotedAttributes");
|
const calendarDisplayedAttributes = note.getLabelValue("calendar:displayedAttributes")?.split(",");
|
||||||
let promotedAttributesData = null;
|
let displayedAttributesData: Array<[string, string]> | null = null;
|
||||||
if (calendarPromotedAttributes) {
|
if (calendarDisplayedAttributes) {
|
||||||
promotedAttributesData = await this.#buildPromotedAttributes(note, calendarPromotedAttributes);
|
displayedAttributesData = await this.#buildDisplayedAttributes(note, calendarDisplayedAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const title of titles) {
|
for (const title of titles) {
|
||||||
@ -361,7 +366,7 @@ export default class CalendarView extends ViewMode {
|
|||||||
noteId: note.noteId,
|
noteId: note.noteId,
|
||||||
color: color ?? undefined,
|
color: color ?? undefined,
|
||||||
iconClass: note.getLabelValue("iconClass"),
|
iconClass: note.getLabelValue("iconClass"),
|
||||||
promotedAttributes: promotedAttributesData
|
promotedAttributes: displayedAttributesData
|
||||||
};
|
};
|
||||||
|
|
||||||
const endDateOffset = CalendarView.#offsetDate(endDate ?? startDate, 1);
|
const endDateOffset = CalendarView.#offsetDate(endDate ?? startDate, 1);
|
||||||
@ -373,48 +378,25 @@ export default class CalendarView extends ViewMode {
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async #buildPromotedAttributes(note: FNote, calendarPromotedAttributes: string) {
|
static async #buildDisplayedAttributes(note: FNote, calendarDisplayedAttributes: string[]) {
|
||||||
const promotedAttributeNames = calendarPromotedAttributes.split(",");
|
const filteredDisplayedAttributes = note.getAttributes().filter((attr): boolean => calendarDisplayedAttributes.includes(attr.name))
|
||||||
const filteredPromotedAttributes = note.getPromotedDefinitionAttributes().filter((attr) => promotedAttributeNames.includes(attr.name));
|
const result: Array<[string, string]> = [];
|
||||||
const result: Record<string, string> = {};
|
|
||||||
|
|
||||||
for (const promotedAttribute of filteredPromotedAttributes) {
|
for (const attribute of filteredDisplayedAttributes) {
|
||||||
const [type, name] = promotedAttribute.name.split(":", 2);
|
if (attribute.type === "label") result.push([attribute.name, attribute.value]);
|
||||||
const definition = promotedAttribute.getDefinition();
|
else result.push([attribute.name, (await attribute.getTargetNote())?.title || ""])
|
||||||
|
|
||||||
if (definition.multiplicity !== "single") {
|
|
||||||
// TODO: Add support for multiple definitions.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let value: string | undefined | null = null;
|
|
||||||
|
|
||||||
if (type === "label" && note.hasLabel(name)) {
|
|
||||||
value = note.getLabelValue(name);
|
|
||||||
} else if (type === "relation" && note.hasRelation(name)) {
|
|
||||||
const targetNote = await note.getRelationTarget(name);
|
|
||||||
value = targetNote?.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
const friendlyName = definition.promotedAlias ?? name;
|
|
||||||
if (friendlyName && value) {
|
|
||||||
result[friendlyName] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async #parseCustomTitle(customTitleValue: string | null, note: FNote, allowRelations = true): Promise<string[]> {
|
static async #parseCustomTitle(customTitlettributeName: string | null, note: FNote, allowRelations = true): Promise<string[]> {
|
||||||
if (customTitleValue) {
|
if (customTitlettributeName) {
|
||||||
const attributeName = customTitleValue.substring(1);
|
const labelValue = note.getAttributeValue("label", customTitlettributeName);
|
||||||
if (customTitleValue.startsWith("#")) {
|
if (labelValue) return [labelValue];
|
||||||
const labelValue = note.getAttributeValue("label", attributeName);
|
|
||||||
if (labelValue) {
|
if (allowRelations) {
|
||||||
return [labelValue];
|
const relations = note.getRelations(customTitlettributeName);
|
||||||
}
|
|
||||||
} else if (allowRelations && customTitleValue.startsWith("~")) {
|
|
||||||
const relations = note.getRelations(attributeName);
|
|
||||||
if (relations.length > 0) {
|
if (relations.length > 0) {
|
||||||
const noteIds = relations.map((r) => r.targetNoteId);
|
const noteIds = relations.map((r) => r.targetNoteId);
|
||||||
const notesFromRelation = await froca.getNotes(noteIds);
|
const notesFromRelation = await froca.getNotes(noteIds);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user