mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 10:02:59 +08:00
fix(view/calendar): add basic support for promoted attributes
This commit is contained in:
parent
249c42e781
commit
07147bf857
@ -48,6 +48,11 @@ const TPL = `
|
||||
.calendar-container .fc-button {
|
||||
padding: 0.2em 0.5em;
|
||||
}
|
||||
|
||||
.calendar-container .promoted-attribute {
|
||||
font-size: 0.85em;
|
||||
opacity: 0.85;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="calendar-container">
|
||||
@ -119,13 +124,24 @@ export default class CalendarView extends ViewMode {
|
||||
height: "100%",
|
||||
eventContent: (e => {
|
||||
let html = "";
|
||||
const { iconClass, promotedAttributes } = e.event.extendedProps;
|
||||
|
||||
const iconClass = e.event.extendedProps.iconClass;
|
||||
// Title and icon
|
||||
if (iconClass) {
|
||||
html += `<span class="${iconClass}"></span> `;
|
||||
}
|
||||
|
||||
html += utils.escapeHtml(e.event.title);
|
||||
|
||||
// Promoted attributes
|
||||
if (promotedAttributes) {
|
||||
for (const [ name, value ] of Object.entries(promotedAttributes)) {
|
||||
html += `\
|
||||
<div class="promoted-attribute">
|
||||
<span class="promoted-attribute-name">${name}</span>: <span class="promoted-attribute-value">${value}</span>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
return { html };
|
||||
}),
|
||||
dateClick: async (e) => {
|
||||
@ -306,27 +322,22 @@ export default class CalendarView extends ViewMode {
|
||||
const events: EventInput[] = [];
|
||||
// the user can specify one or multiple attributes to be promoted onto the calendar view by setting `#calendar:promotedAttributes` at the note level
|
||||
// their values will then be rentered into the event title and appear as "[eventIcon] $eventTitle [#promotedAttributeX=valueX] [#promotedAttributeY=valueY]"
|
||||
const promotedAttrs = note
|
||||
.getAttributes()
|
||||
.filter((attr) => attr.type == "label" && attr.name == "calendar:promotedAttribute")
|
||||
.map((attr) => attr.value.substring(1));
|
||||
let titleExtended = "";
|
||||
if (promotedAttrs && promotedAttrs.length) {
|
||||
const promotedValues = note
|
||||
.getAttributes()
|
||||
.filter((attr) => promotedAttrs.includes(attr.name))
|
||||
.map((attr) => [attr.name, attr.value]);
|
||||
for (const defined of promotedValues) titleExtended = titleExtended + ` [#${defined[0]}="${defined[1]}"]`;
|
||||
|
||||
const calendarPromotedAttributes = note.getLabelValue("calendar:promotedAttributes");
|
||||
let promotedAttributesData = null;
|
||||
if (calendarPromotedAttributes) {
|
||||
promotedAttributesData = await this.#buildPromotedAttributes(note, calendarPromotedAttributes);
|
||||
}
|
||||
|
||||
for (const title of titles) {
|
||||
const eventData: EventInput = {
|
||||
title: title + titleExtended,
|
||||
title: title,
|
||||
start: startDate,
|
||||
url: `#${note.noteId}`,
|
||||
noteId: note.noteId,
|
||||
color: color ?? undefined,
|
||||
iconClass: note.getLabelValue("iconClass")
|
||||
iconClass: note.getLabelValue("iconClass"),
|
||||
promotedAttributes: promotedAttributesData
|
||||
};
|
||||
|
||||
const endDateOffset = CalendarView.#offsetDate(endDate ?? startDate, 1);
|
||||
@ -338,6 +349,35 @@ export default class CalendarView extends ViewMode {
|
||||
return events;
|
||||
}
|
||||
|
||||
static async #buildPromotedAttributes(note: FNote, calendarPromotedAttributes: string) {
|
||||
const promotedAttributeNames = calendarPromotedAttributes.split(",");
|
||||
const filteredPromotedAttributes = note.getPromotedDefinitionAttributes().filter((attr) => promotedAttributeNames.includes(attr.name));
|
||||
const result: Record<string, string> = {};
|
||||
|
||||
for (const promotedAttribute of filteredPromotedAttributes) {
|
||||
const [ type, name ] = promotedAttribute.name.split(":", 2);
|
||||
const definition = promotedAttribute.getDefinition();
|
||||
|
||||
if (definition.multiplicity !== "single") {
|
||||
// TODO: Add support for multiple definitions.
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Add support for relations
|
||||
if (type !== "label" || !note.hasLabel(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = note.getLabelValue(name);
|
||||
const friendlyName = definition.promotedAlias ?? name;
|
||||
if (friendlyName && value) {
|
||||
result[friendlyName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static async #parseCustomTitle(customTitleValue: string | null, note: FNote, allowRelations = true): Promise<string[]> {
|
||||
if (customTitleValue) {
|
||||
const attributeName = customTitleValue.substring(1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user