mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 03:29:02 +01:00 
			
		
		
		
	chore(client/ts): port note_icon
This commit is contained in:
		
							parent
							
								
									043d92a1ab
								
							
						
					
					
						commit
						3db93cdf24
					
				| @ -515,10 +515,10 @@ class FNote { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param [name] - label name to filter |      * @param name - label name to filter | ||||||
|      * @returns all note's labels (attributes with type label), including inherited ones |      * @returns all note's labels (attributes with type label), including inherited ones | ||||||
|      */ |      */ | ||||||
|     getOwnedLabels(name: string) { |     getOwnedLabels(name?: string) { | ||||||
|         return this.getOwnedAttributes(LABEL, name); |         return this.getOwnedAttributes(LABEL, name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ import { t } from "../services/i18n.js"; | |||||||
| import NoteContextAwareWidget from "./note_context_aware_widget.js"; | import NoteContextAwareWidget from "./note_context_aware_widget.js"; | ||||||
| import attributeService from "../services/attributes.js"; | import attributeService from "../services/attributes.js"; | ||||||
| import server from "../services/server.js"; | import server from "../services/server.js"; | ||||||
|  | import type FNote from "../entities/fnote.js"; | ||||||
|  | import type { EventData } from "../components/app_context.js"; | ||||||
| 
 | 
 | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="note-icon-widget dropdown"> | <div class="note-icon-widget dropdown"> | ||||||
| @ -79,7 +81,24 @@ const TPL = ` | |||||||
|     </div> |     </div> | ||||||
| </div>`;
 | </div>`;
 | ||||||
| 
 | 
 | ||||||
|  | interface Icon { | ||||||
|  |     className?: string; | ||||||
|  |     name: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface IconToCountCache { | ||||||
|  |     iconClassToCountMap: Record<string, number>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export default class NoteIconWidget extends NoteContextAwareWidget { | export default class NoteIconWidget extends NoteContextAwareWidget { | ||||||
|  | 
 | ||||||
|  |     private $icon!: JQuery<HTMLElement>; | ||||||
|  |     private $iconList!: JQuery<HTMLElement>; | ||||||
|  |     private $iconCategory!: JQuery<HTMLElement>; | ||||||
|  |     private $iconSearch!: JQuery<HTMLElement>; | ||||||
|  |     private $notePathList!: JQuery<HTMLElement>; | ||||||
|  |     private iconToCountCache!: Promise<IconToCountCache | null> | null; | ||||||
|  | 
 | ||||||
|     doRender() { |     doRender() { | ||||||
|         this.$widget = $(TPL); |         this.$widget = $(TPL); | ||||||
|         this.$icon = this.$widget.find("button.note-icon"); |         this.$icon = this.$widget.find("button.note-icon"); | ||||||
| @ -87,7 +106,9 @@ export default class NoteIconWidget extends NoteContextAwareWidget { | |||||||
|         this.$iconList.on("click", "span", async (e) => { |         this.$iconList.on("click", "span", async (e) => { | ||||||
|             const clazz = $(e.target).attr("class"); |             const clazz = $(e.target).attr("class"); | ||||||
| 
 | 
 | ||||||
|  |             if (this.noteId && this.note) { | ||||||
|                 await attributeService.setLabel(this.noteId, this.note.hasOwnedLabel("workspace") ? "workspaceIconClass" : "iconClass", clazz); |                 await attributeService.setLabel(this.noteId, this.note.hasOwnedLabel("workspace") ? "workspaceIconClass" : "iconClass", clazz); | ||||||
|  |             } | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         this.$iconCategory = this.$widget.find("select[name='icon-category']"); |         this.$iconCategory = this.$widget.find("select[name='icon-category']"); | ||||||
| @ -113,18 +134,18 @@ export default class NoteIconWidget extends NoteContextAwareWidget { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async refreshWithNote(note) { |     async refreshWithNote(note: FNote) { | ||||||
|         this.$icon.removeClass().addClass(`${note.getIcon()} note-icon`); |         this.$icon.removeClass().addClass(`${note.getIcon()} note-icon`); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async entitiesReloadedEvent({ loadResults }) { |     async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { | ||||||
|         if (loadResults.isNoteReloaded(this.noteId)) { |         if (this.noteId && loadResults.isNoteReloaded(this.noteId)) { | ||||||
|             this.refresh(); |             this.refresh(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         for (const attr of loadResults.getAttributeRows()) { |         for (const attr of loadResults.getAttributeRows()) { | ||||||
|             if (attr.type === "label" && ["iconClass", "workspaceIconClass"].includes(attr.name) && attributeService.isAffecting(attr, this.note)) { |             if (attr.type === "label" && ["iconClass", "workspaceIconClass"].includes(attr.name ?? "") && attributeService.isAffecting(attr, this.note)) { | ||||||
|                 this.refresh(); |                 this.refresh(); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -141,14 +162,18 @@ export default class NoteIconWidget extends NoteContextAwareWidget { | |||||||
|             this.$iconList.append( |             this.$iconList.append( | ||||||
|                 $(`<div style="text-align: center">`).append( |                 $(`<div style="text-align: center">`).append( | ||||||
|                     $(`<button class="btn btn-sm">${t("note_icon.reset-default")}</button>`).on("click", () => |                     $(`<button class="btn btn-sm">${t("note_icon.reset-default")}</button>`).on("click", () => | ||||||
|                         this.getIconLabels().forEach((label) => attributeService.removeAttributeById(this.noteId, label.attributeId)) |                         this.getIconLabels().forEach((label) => { | ||||||
|  |                             if (this.noteId) { | ||||||
|  |                                 attributeService.removeAttributeById(this.noteId, label.attributeId); | ||||||
|  |                             } | ||||||
|  |                         }) | ||||||
|                     ) |                     ) | ||||||
|                 ) |                 ) | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const categoryId = parseInt(this.$iconCategory.find("option:selected").val()); |         const categoryId = parseInt(String(this.$iconCategory.find("option:selected")?.val())); | ||||||
|         const search = this.$iconSearch.val().trim().toLowerCase(); |         const search = String(this.$iconSearch.val())?.trim()?.toLowerCase(); | ||||||
| 
 | 
 | ||||||
|         const filteredIcons = icons.filter((icon) => { |         const filteredIcons = icons.filter((icon) => { | ||||||
|             if (categoryId && icon.category_id !== categoryId) { |             if (categoryId && icon.category_id !== categoryId) { | ||||||
| @ -164,12 +189,14 @@ export default class NoteIconWidget extends NoteContextAwareWidget { | |||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|  |         if (iconToCount) { | ||||||
|             filteredIcons.sort((a, b) => { |             filteredIcons.sort((a, b) => { | ||||||
|             const countA = iconToCount[a.className] || 0; |                 const countA = iconToCount[a.className ?? ""] || 0; | ||||||
|             const countB = iconToCount[b.className] || 0; |                 const countB = iconToCount[b.className ?? ""] || 0; | ||||||
| 
 | 
 | ||||||
|                 return countB - countA; |                 return countB - countA; | ||||||
|             }); |             }); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         for (const icon of filteredIcons) { |         for (const icon of filteredIcons) { | ||||||
|             this.$iconList.append(this.renderIcon(icon)); |             this.$iconList.append(this.renderIcon(icon)); | ||||||
| @ -180,20 +207,23 @@ export default class NoteIconWidget extends NoteContextAwareWidget { | |||||||
| 
 | 
 | ||||||
|     async getIconToCountMap() { |     async getIconToCountMap() { | ||||||
|         if (!this.iconToCountCache) { |         if (!this.iconToCountCache) { | ||||||
|             this.iconToCountCache = server.get("other/icon-usage"); |             this.iconToCountCache = server.get<typeof this.iconToCountCache>("other/icon-usage"); | ||||||
|             setTimeout(() => (this.iconToCountCache = null), 20000); // invalidate cache after 20 seconds
 |             setTimeout(() => (this.iconToCountCache = null), 20000); // invalidate cache after 20 seconds
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return (await this.iconToCountCache).iconClassToCountMap; |         return (await this.iconToCountCache)?.iconClassToCountMap; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     renderIcon(icon) { |     renderIcon(icon: Icon) { | ||||||
|         return $("<span>") |         return $("<span>") | ||||||
|             .addClass("bx " + icon.className) |             .addClass("bx " + icon.className) | ||||||
|             .attr("title", icon.name); |             .attr("title", icon.name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     getIconLabels() { |     getIconLabels() { | ||||||
|  |         if (!this.note) { | ||||||
|  |             return []; | ||||||
|  |         } | ||||||
|         return this.note.getOwnedLabels().filter((label) => ["workspaceIconClass", "iconClass"].includes(label.name)); |         return this.note.getOwnedLabels().filter((label) => ["workspaceIconClass", "iconClass"].includes(label.name)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran