mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
Merge pull request #1261 from rom1dep/calendar_enh_attributes
feat(view/calendar): let the user specify attributes to be promoted o…
This commit is contained in:
commit
143b91936c
@ -48,6 +48,11 @@ const TPL = `
|
|||||||
.calendar-container .fc-button {
|
.calendar-container .fc-button {
|
||||||
padding: 0.2em 0.5em;
|
padding: 0.2em 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.calendar-container .promoted-attribute {
|
||||||
|
font-size: 0.85em;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="calendar-container">
|
<div class="calendar-container">
|
||||||
@ -119,13 +124,24 @@ export default class CalendarView extends ViewMode {
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
eventContent: (e => {
|
eventContent: (e => {
|
||||||
let html = "";
|
let html = "";
|
||||||
|
const { iconClass, promotedAttributes } = e.event.extendedProps;
|
||||||
|
|
||||||
const iconClass = e.event.extendedProps.iconClass;
|
// Title and icon
|
||||||
if (iconClass) {
|
if (iconClass) {
|
||||||
html += `<span class="${iconClass}"></span> `;
|
html += `<span class="${iconClass}"></span> `;
|
||||||
}
|
}
|
||||||
|
|
||||||
html += utils.escapeHtml(e.event.title);
|
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 };
|
return { html };
|
||||||
}),
|
}),
|
||||||
dateClick: async (e) => {
|
dateClick: async (e) => {
|
||||||
@ -279,7 +295,7 @@ export default class CalendarView extends ViewMode {
|
|||||||
const events: EventSourceInput = [];
|
const events: EventSourceInput = [];
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
let startDate = note.getLabelValue("startDate");
|
const startDate = note.getLabelValue("startDate");
|
||||||
|
|
||||||
if (note.hasChildren()) {
|
if (note.hasChildren()) {
|
||||||
const childrenEventData = await this.#buildEvents(note.getChildNoteIds());
|
const childrenEventData = await this.#buildEvents(note.getChildNoteIds());
|
||||||
@ -304,6 +320,13 @@ export default class CalendarView extends ViewMode {
|
|||||||
const titles = await CalendarView.#parseCustomTitle(customTitle, note);
|
const titles = await CalendarView.#parseCustomTitle(customTitle, 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");
|
||||||
|
let promotedAttributesData = null;
|
||||||
|
if (calendarPromotedAttributes) {
|
||||||
|
promotedAttributesData = await this.#buildPromotedAttributes(note, calendarPromotedAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
for (const title of titles) {
|
for (const title of titles) {
|
||||||
const eventData: EventInput = {
|
const eventData: EventInput = {
|
||||||
title: title,
|
title: title,
|
||||||
@ -311,7 +334,8 @@ export default class CalendarView extends ViewMode {
|
|||||||
url: `#${note.noteId}`,
|
url: `#${note.noteId}`,
|
||||||
noteId: note.noteId,
|
noteId: note.noteId,
|
||||||
color: color ?? undefined,
|
color: color ?? undefined,
|
||||||
iconClass: note.getLabelValue("iconClass")
|
iconClass: note.getLabelValue("iconClass"),
|
||||||
|
promotedAttributes: promotedAttributesData
|
||||||
};
|
};
|
||||||
|
|
||||||
const endDateOffset = CalendarView.#offsetDate(endDate ?? startDate, 1);
|
const endDateOffset = CalendarView.#offsetDate(endDate ?? startDate, 1);
|
||||||
@ -323,6 +347,35 @@ export default class CalendarView extends ViewMode {
|
|||||||
return events;
|
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[]> {
|
static async #parseCustomTitle(customTitleValue: string | null, note: FNote, allowRelations = true): Promise<string[]> {
|
||||||
if (customTitleValue) {
|
if (customTitleValue) {
|
||||||
const attributeName = customTitleValue.substring(1);
|
const attributeName = customTitleValue.substring(1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user