mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	attributes and children overview working again
This commit is contained in:
		
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "version": "0.31.4", |   "version": "0.31.5", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|   | |||||||
| @@ -152,8 +152,6 @@ noteTooltipService.setupGlobalTooltip(); | |||||||
|  |  | ||||||
| bundle.executeStartupBundles(); | bundle.executeStartupBundles(); | ||||||
|  |  | ||||||
| noteTypeService.init(); |  | ||||||
|  |  | ||||||
| linkService.init(); | linkService.init(); | ||||||
|  |  | ||||||
| noteAutocompleteService.init(); | noteAutocompleteService.init(); | ||||||
|   | |||||||
| @@ -2,7 +2,6 @@ import noteDetailService from '../services/note_detail.js'; | |||||||
| import server from '../services/server.js'; | import server from '../services/server.js'; | ||||||
| import infoService from "../services/info.js"; | import infoService from "../services/info.js"; | ||||||
| import treeUtils from "../services/tree_utils.js"; | import treeUtils from "../services/tree_utils.js"; | ||||||
| import attributeService from "../services/attributes.js"; |  | ||||||
| import attributeAutocompleteService from "../services/attribute_autocomplete.js"; | import attributeAutocompleteService from "../services/attribute_autocomplete.js"; | ||||||
|  |  | ||||||
| const $dialog = $("#attributes-dialog"); | const $dialog = $("#attributes-dialog"); | ||||||
| @@ -168,7 +167,9 @@ function AttributesModel() { | |||||||
|  |  | ||||||
|         infoService.showMessage("Attributes have been saved."); |         infoService.showMessage("Attributes have been saved."); | ||||||
|  |  | ||||||
|         attributeService.refreshAttributes(); |         const ctx = noteDetailService.getActiveContext(); | ||||||
|  |  | ||||||
|  |         ctx.attributes.refreshAttributes(); | ||||||
|  |  | ||||||
|         noteDetailService.reload(); |         noteDetailService.reload(); | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -4,48 +4,50 @@ import messagingService from "./messaging.js"; | |||||||
| import treeUtils from "./tree_utils.js"; | import treeUtils from "./tree_utils.js"; | ||||||
| import noteAutocompleteService from "./note_autocomplete.js"; | import noteAutocompleteService from "./note_autocomplete.js"; | ||||||
| import linkService from "./link.js"; | import linkService from "./link.js"; | ||||||
| import noteDetailService from "./note_detail.js"; |  | ||||||
|  |  | ||||||
| const $attributeList = $("#attribute-list"); | class Attributes { | ||||||
| const $attributeListInner = $("#attribute-list-inner"); |     /** | ||||||
| const $promotedAttributesContainer = $("#note-detail-promoted-attributes"); |      * @param {NoteContext} ctx | ||||||
| const $savedIndicator = $(".saved-indicator"); |      */ | ||||||
|  |     constructor(ctx) { | ||||||
| let attributePromise; |         this.ctx = ctx; | ||||||
|  |         this.$attributeList = ctx.$noteTabContent.find(".attribute-list"); | ||||||
| function invalidateAttributes() { |         this.$attributeListInner = ctx.$noteTabContent.find(".attribute-list-inner"); | ||||||
|     attributePromise = null; |         this.$promotedAttributesContainer = ctx.$noteTabContent.find(".note-detail-promoted-attributes"); | ||||||
| } |         this.$savedIndicator = ctx.$noteTabContent.find(".saved-indicator"); | ||||||
|  |         this.attributePromise = null; | ||||||
| function reloadAttributes() { |  | ||||||
|     attributePromise = server.get('notes/' + noteDetailService.getActiveNoteId() + '/attributes'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| async function refreshAttributes() { |  | ||||||
|     reloadAttributes(); |  | ||||||
|  |  | ||||||
|     await showAttributes(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| async function getAttributes() { |  | ||||||
|     if (!attributePromise) { |  | ||||||
|         reloadAttributes(); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return await attributePromise; |     invalidateAttributes() { | ||||||
| } |         this.attributePromise = null; | ||||||
|  |     } | ||||||
|  |  | ||||||
| async function showAttributes() { |     reloadAttributes() { | ||||||
|     // FIXME tabs |         this.attributePromise = server.get(`notes/${this.ctx.note.noteId}/attributes`); | ||||||
|     return; |     } | ||||||
|  |  | ||||||
|     $promotedAttributesContainer.empty(); |     async refreshAttributes() { | ||||||
|     $attributeList.hide(); |         this.reloadAttributes(); | ||||||
|     $attributeListInner.empty(); |  | ||||||
|  |  | ||||||
|     const note = noteDetailService.getActiveNote(); |         await this.showAttributes(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const attributes = await attributePromise; |     async getAttributes() { | ||||||
|  |         if (!this.attributePromise) { | ||||||
|  |             this.reloadAttributes(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return await this.attributePromise; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async showAttributes() { | ||||||
|  |         this.$promotedAttributesContainer.empty(); | ||||||
|  |         this.$attributeList.hide(); | ||||||
|  |         this.$attributeListInner.empty(); | ||||||
|  |  | ||||||
|  |         const note = this.ctx.note; | ||||||
|  |  | ||||||
|  |         const attributes = await this.getAttributes(); | ||||||
|  |  | ||||||
|         const promoted = attributes.filter(attr => |         const promoted = attributes.filter(attr => | ||||||
|             (attr.type === 'label-definition' || attr.type === 'relation-definition') |             (attr.type === 'label-definition' || attr.type === 'relation-definition') | ||||||
| @@ -77,7 +79,7 @@ async function showAttributes() { | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 for (const valueAttr of valueAttrs) { |                 for (const valueAttr of valueAttrs) { | ||||||
|                 const $tr = await createPromotedAttributeRow(definitionAttr, valueAttr); |                     const $tr = await this.createPromotedAttributeRow(definitionAttr, valueAttr); | ||||||
|  |  | ||||||
|                     $tbody.append($tr); |                     $tbody.append($tr); | ||||||
|                 } |                 } | ||||||
| @@ -85,7 +87,7 @@ async function showAttributes() { | |||||||
|  |  | ||||||
|             // we replace the whole content in one step so there can't be any race conditions |             // we replace the whole content in one step so there can't be any race conditions | ||||||
|             // (previously we saw promoted attributes doubling) |             // (previously we saw promoted attributes doubling) | ||||||
|         $promotedAttributesContainer.empty().append($tbody); |             this.$promotedAttributesContainer.empty().append($tbody); | ||||||
|         } |         } | ||||||
|         else if (note.type !== 'relation-map') { |         else if (note.type !== 'relation-map') { | ||||||
|             // display only "own" notes |             // display only "own" notes | ||||||
| @@ -94,34 +96,34 @@ async function showAttributes() { | |||||||
|             if (ownedAttributes.length > 0) { |             if (ownedAttributes.length > 0) { | ||||||
|                 for (const attribute of ownedAttributes) { |                 for (const attribute of ownedAttributes) { | ||||||
|                     if (attribute.type === 'label') { |                     if (attribute.type === 'label') { | ||||||
|                     $attributeListInner.append(utils.formatLabel(attribute) + " "); |                         this.$attributeListInner.append(utils.formatLabel(attribute) + " "); | ||||||
|                     } |                     } | ||||||
|                     else if (attribute.type === 'relation') { |                     else if (attribute.type === 'relation') { | ||||||
|                         if (attribute.value) { |                         if (attribute.value) { | ||||||
|                         $attributeListInner.append('@' + attribute.name + "="); |                             this.$attributeListInner.append('@' + attribute.name + "="); | ||||||
|                         $attributeListInner.append(await linkService.createNoteLink(attribute.value)); |                             this.$attributeListInner.append(await linkService.createNoteLink(attribute.value)); | ||||||
|                         $attributeListInner.append(" "); |                             this.$attributeListInner.append(" "); | ||||||
|                         } |                         } | ||||||
|                         else { |                         else { | ||||||
|                             messagingService.logError(`Relation ${attribute.attributeId} has empty target`); |                             messagingService.logError(`Relation ${attribute.attributeId} has empty target`); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     else if (attribute.type === 'label-definition' || attribute.type === 'relation-definition') { |                     else if (attribute.type === 'label-definition' || attribute.type === 'relation-definition') { | ||||||
|                     $attributeListInner.append(attribute.name + " definition "); |                         this.$attributeListInner.append(attribute.name + " definition "); | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         messagingService.logError("Unknown attr type: " + attribute.type); |                         messagingService.logError("Unknown attr type: " + attribute.type); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|             $attributeList.show(); |                 this.$attributeList.show(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return attributes; |         return attributes; | ||||||
| } |     } | ||||||
|  |  | ||||||
| async function createPromotedAttributeRow(definitionAttr, valueAttr) { |     async createPromotedAttributeRow(definitionAttr, valueAttr) { | ||||||
|         const definition = definitionAttr.value; |         const definition = definitionAttr.value; | ||||||
|         const $tr = $("<tr>"); |         const $tr = $("<tr>"); | ||||||
|         const $labelCell = $("<th>").append(valueAttr.name); |         const $labelCell = $("<th>").append(valueAttr.name); | ||||||
| @@ -133,7 +135,7 @@ async function createPromotedAttributeRow(definitionAttr, valueAttr) { | |||||||
|             .prop("value", valueAttr.value) |             .prop("value", valueAttr.value) | ||||||
|             .addClass("form-control") |             .addClass("form-control") | ||||||
|             .addClass("promoted-attribute-input") |             .addClass("promoted-attribute-input") | ||||||
|         .change(promotedAttributeChanged); |             .change(event => this.promotedAttributeChanged(event)); | ||||||
|  |  | ||||||
|         const $inputCell = $("<td>").append($("<div>").addClass("input-group").append($input)); |         const $inputCell = $("<td>").append($("<div>").addClass("input-group").append($input)); | ||||||
|  |  | ||||||
| @@ -224,8 +226,8 @@ async function createPromotedAttributeRow(definitionAttr, valueAttr) { | |||||||
|             // no need to wait for this |             // no need to wait for this | ||||||
|             noteAutocompleteService.initNoteAutocomplete($input); |             noteAutocompleteService.initNoteAutocomplete($input); | ||||||
|  |  | ||||||
|         $input.on('autocomplete:selected', function(event, suggestion, dataset) { |             $input.on('autocomplete:selected', (event, suggestion, dataset) => { | ||||||
|             promotedAttributeChanged(event); |                 this.promotedAttributeChanged(event); | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             $input.setSelectedPath(valueAttr.value); |             $input.setSelectedPath(valueAttr.value); | ||||||
| @@ -240,7 +242,7 @@ async function createPromotedAttributeRow(definitionAttr, valueAttr) { | |||||||
|                 .addClass("jam jam-plus pointer") |                 .addClass("jam jam-plus pointer") | ||||||
|                 .prop("title", "Add new attribute") |                 .prop("title", "Add new attribute") | ||||||
|                 .click(async () => { |                 .click(async () => { | ||||||
|                 const $new = await createPromotedAttributeRow(definitionAttr, { |                     const $new = await this.createPromotedAttributeRow(definitionAttr, { | ||||||
|                         attributeId: "", |                         attributeId: "", | ||||||
|                         type: valueAttr.type, |                         type: valueAttr.type, | ||||||
|                         name: definitionAttr.name, |                         name: definitionAttr.name, | ||||||
| @@ -267,9 +269,9 @@ async function createPromotedAttributeRow(definitionAttr, valueAttr) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $tr; |         return $tr; | ||||||
| } |     } | ||||||
|  |  | ||||||
| async function promotedAttributeChanged(event) { |     async promotedAttributeChanged(event) { | ||||||
|         const $attr = $(event.target); |         const $attr = $(event.target); | ||||||
|  |  | ||||||
|         let value; |         let value; | ||||||
| @@ -286,7 +288,7 @@ async function promotedAttributeChanged(event) { | |||||||
|             value = $attr.val(); |             value = $attr.val(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     const result = await server.put("notes/" + noteDetailService.getActiveNoteId() + "/attribute", { |         const result = await server.put(`notes/${this.ctx.note.noteId}/attribute`, { | ||||||
|             attributeId: $attr.prop("attribute-id"), |             attributeId: $attr.prop("attribute-id"), | ||||||
|             type: $attr.prop("attribute-type"), |             type: $attr.prop("attribute-type"), | ||||||
|             name: $attr.prop("attribute-name"), |             name: $attr.prop("attribute-name"), | ||||||
| @@ -297,15 +299,11 @@ async function promotedAttributeChanged(event) { | |||||||
|  |  | ||||||
|         // animate only if it's not being animated already, this is important especially for e.g. number inputs |         // animate only if it's not being animated already, this is important especially for e.g. number inputs | ||||||
|         // which can be changed many times in a second by clicking on higher/lower buttons. |         // which can be changed many times in a second by clicking on higher/lower buttons. | ||||||
|     if ($savedIndicator.queue().length === 0) { |         if (this.$savedIndicator.queue().length === 0) { | ||||||
|         $savedIndicator.fadeOut(); |             this.$savedIndicator.fadeOut(); | ||||||
|         $savedIndicator.fadeIn(); |             this.$savedIndicator.fadeIn(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| export default { | export default Attributes; | ||||||
|     getAttributes, |  | ||||||
|     showAttributes, |  | ||||||
|     refreshAttributes, |  | ||||||
|     invalidateAttributes |  | ||||||
| } |  | ||||||
| @@ -2,9 +2,11 @@ import treeService from "./tree.js"; | |||||||
| import protectedSessionHolder from "./protected_session_holder.js"; | import protectedSessionHolder from "./protected_session_holder.js"; | ||||||
| import server from "./server.js"; | import server from "./server.js"; | ||||||
| import bundleService from "./bundle.js"; | import bundleService from "./bundle.js"; | ||||||
| import attributeService from "./attributes.js"; | import Attributes from "./attributes.js"; | ||||||
| import treeUtils from "./tree_utils.js"; | import treeUtils from "./tree_utils.js"; | ||||||
| import utils from "./utils.js"; | import utils from "./utils.js"; | ||||||
|  | import {NoteTypeContext} from "./note_type.js"; | ||||||
|  | import noteDetailService from "./note_detail.js"; | ||||||
| import noteDetailCode from "./note_detail_code.js"; | import noteDetailCode from "./note_detail_code.js"; | ||||||
| import noteDetailText from "./note_detail_text.js"; | import noteDetailText from "./note_detail_text.js"; | ||||||
| import noteDetailFile from "./note_detail_file.js"; | import noteDetailFile from "./note_detail_file.js"; | ||||||
| @@ -44,6 +46,8 @@ class NoteContext { | |||||||
|         this.$savedIndicator = this.$noteTabContent.find(".saved-indicator"); |         this.$savedIndicator = this.$noteTabContent.find(".saved-indicator"); | ||||||
|         this.noteChangeDisabled = false; |         this.noteChangeDisabled = false; | ||||||
|         this.isNoteChanged = false; |         this.isNoteChanged = false; | ||||||
|  |         this.attributes = new Attributes(this); | ||||||
|  |         this.noteType = new NoteTypeContext(this); | ||||||
|         this.components = {}; |         this.components = {}; | ||||||
|  |  | ||||||
|         this.$noteTitle.on('input', () => { |         this.$noteTitle.on('input', () => { | ||||||
| @@ -70,6 +74,8 @@ class NoteContext { | |||||||
|         this.$noteTabContent.attr('data-note-id', note.noteId); |         this.$noteTabContent.attr('data-note-id', note.noteId); | ||||||
|  |  | ||||||
|         chromeTabs.updateTab(this.tab, {title: note.title}); |         chromeTabs.updateTab(this.tab, {title: note.title}); | ||||||
|  |  | ||||||
|  |         this.attributes.invalidateAttributes(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     getComponent(type) { |     getComponent(type) { | ||||||
| @@ -90,7 +96,7 @@ class NoteContext { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.note.title = this.$noteTitle.val(); |         this.note.title = this.$noteTitle.val(); | ||||||
|         this.note.content = getActiveNoteContent(this.note); |         this.note.content = noteDetailService.getActiveNoteContent(); | ||||||
|  |  | ||||||
|         // it's important to set the flag back to false immediatelly after retrieving title and content |         // it's important to set the flag back to false immediatelly after retrieving title and content | ||||||
|         // otherwise we might overwrite another change (especially async code) |         // otherwise we might overwrite another change (especially async code) | ||||||
| @@ -127,9 +133,7 @@ class NoteContext { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async showChildrenOverview() { |     async showChildrenOverview() { | ||||||
|         return; // FIXME |         const attributes = await this.attributes.getAttributes(); | ||||||
|  |  | ||||||
|         const attributes = await attributeService.getAttributes(); |  | ||||||
|         const hideChildrenOverview = attributes.some(attr => attr.type === 'label' && attr.name === 'hideChildrenOverview') |         const hideChildrenOverview = attributes.some(attr => attr.type === 'label' && attr.name === 'hideChildrenOverview') | ||||||
|             || this.note.type === 'relation-map' |             || this.note.type === 'relation-map' | ||||||
|             || this.note.type === 'image' |             || this.note.type === 'image' | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ import infoService from "./info.js"; | |||||||
| import treeCache from "./tree_cache.js"; | import treeCache from "./tree_cache.js"; | ||||||
| import NoteFull from "../entities/note_full.js"; | import NoteFull from "../entities/note_full.js"; | ||||||
| import bundleService from "./bundle.js"; | import bundleService from "./bundle.js"; | ||||||
| import attributeService from "./attributes.js"; |  | ||||||
| import utils from "./utils.js"; | import utils from "./utils.js"; | ||||||
| import importDialog from "../dialogs/import.js"; | import importDialog from "../dialogs/import.js"; | ||||||
|  |  | ||||||
| @@ -167,8 +166,8 @@ async function loadNoteDetail(noteId, newTab = false) { | |||||||
|         ctx.$noteTitle.val(ctx.note.title); |         ctx.$noteTitle.val(ctx.note.title); | ||||||
|  |  | ||||||
|         if (utils.isDesktop()) { |         if (utils.isDesktop()) { | ||||||
|             noteTypeService.setNoteType(ctx.note.type); |             ctx.noteType.type(ctx.note.type); | ||||||
|             noteTypeService.setNoteMime(ctx.note.mime); |             ctx.noteType.mime(ctx.note.mime); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const componentType in ctx.components) { |         for (const componentType in ctx.components) { | ||||||
| @@ -204,11 +203,11 @@ async function loadNoteDetail(noteId, newTab = false) { | |||||||
|  |  | ||||||
|     await bundleService.executeRelationBundles(ctx.note, 'runOnNoteView'); |     await bundleService.executeRelationBundles(ctx.note, 'runOnNoteView'); | ||||||
|  |  | ||||||
|     // if (utils.isDesktop()) { |     if (utils.isDesktop()) { | ||||||
|     //     await attributeService.showAttributes(); |         await ctx.attributes.showAttributes(); | ||||||
|     // |  | ||||||
|     //     await ctx.showChildrenOverview(); |         await ctx.showChildrenOverview(); | ||||||
|     // } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| async function loadNote(noteId) { | async function loadNote(noteId) { | ||||||
| @@ -293,5 +292,6 @@ export default { | |||||||
|     focusAndSelectTitle, |     focusAndSelectTitle, | ||||||
|     saveNotesIfChanged, |     saveNotesIfChanged, | ||||||
|     onNoteChange, |     onNoteChange, | ||||||
|     addDetailLoadedListener |     addDetailLoadedListener, | ||||||
|  |     getActiveContext | ||||||
| }; | }; | ||||||
| @@ -8,6 +8,7 @@ class NoteDetailImage { | |||||||
|      * @param {NoteContext} ctx |      * @param {NoteContext} ctx | ||||||
|      */ |      */ | ||||||
|     constructor(ctx) { |     constructor(ctx) { | ||||||
|  |         this.ctx = ctx; | ||||||
|         this.$component = ctx.$noteTabContent.find('.note-detail-image'); |         this.$component = ctx.$noteTabContent.find('.note-detail-image'); | ||||||
|         this.$imageWrapper = ctx.$noteTabContent.find('.note-detail-image-wrapper'); |         this.$imageWrapper = ctx.$noteTabContent.find('.note-detail-image-wrapper'); | ||||||
|         this.$imageView = ctx.$noteTabContent.find('.note-detail-image-view'); |         this.$imageView = ctx.$noteTabContent.find('.note-detail-image-view'); | ||||||
| @@ -42,18 +43,16 @@ class NoteDetailImage { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async show() { |     async show() { | ||||||
|         const activeNote = noteDetailService.getActiveNote(); |         const attributes = await server.get('notes/' + this.ctx.note.noteId + '/attributes'); | ||||||
|  |  | ||||||
|         const attributes = await server.get('notes/' + activeNote.noteId + '/attributes'); |  | ||||||
|         const attributeMap = utils.toObject(attributes, l => [l.name, l.value]); |         const attributeMap = utils.toObject(attributes, l => [l.name, l.value]); | ||||||
|  |  | ||||||
|         this.$component.show(); |         this.$component.show(); | ||||||
|  |  | ||||||
|         this.$fileName.text(attributeMap.originalFileName || "?"); |         this.$fileName.text(attributeMap.originalFileName || "?"); | ||||||
|         this.$fileSize.text((attributeMap.fileSize || "?") + " bytes"); |         this.$fileSize.text((attributeMap.fileSize || "?") + " bytes"); | ||||||
|         this.$fileType.text(activeNote.mime); |         this.$fileType.text(this.ctx.note.mime); | ||||||
|  |  | ||||||
|         this.$imageView.prop("src", `api/images/${activeNote.noteId}/${activeNote.title}`); |         this.$imageView.prop("src", `api/images/${this.ctx.note.noteId}/${this.ctx.note.title}`); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     selectImage(element) { |     selectImage(element) { | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| import libraryLoader from "./library_loader.js"; | import libraryLoader from "./library_loader.js"; | ||||||
| import noteDetailService from './note_detail.js'; |  | ||||||
| import treeService from './tree.js'; | import treeService from './tree.js'; | ||||||
| import attributeService from "./attributes.js"; |  | ||||||
|  |  | ||||||
| class NoteDetailText { | class NoteDetailText { | ||||||
|     /** |     /** | ||||||
| @@ -69,7 +67,7 @@ class NoteDetailText { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async isReadOnly() { |     async isReadOnly() { | ||||||
|         const attributes = await attributeService.getAttributes(); |         const attributes = await this.ctx.attributes.getAttributes(); | ||||||
|  |  | ||||||
|         return attributes.some(attr => attr.type === 'label' && attr.name === 'readOnly'); |         return attributes.some(attr => attr.type === 'label' && attr.name === 'readOnly'); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -4,10 +4,6 @@ import server from './server.js'; | |||||||
| import infoService from "./info.js"; | import infoService from "./info.js"; | ||||||
| import confirmDialog from "../dialogs/confirm.js"; | import confirmDialog from "../dialogs/confirm.js"; | ||||||
|  |  | ||||||
| const $executeScriptButton = $("#execute-script-button"); |  | ||||||
| const $toggleEditButton = $('#toggle-edit-button'); |  | ||||||
| const $renderButton = $('#render-button'); |  | ||||||
|  |  | ||||||
| const DEFAULT_MIME_TYPES = [ | const DEFAULT_MIME_TYPES = [ | ||||||
|     { mime: 'text/x-csrc', title: 'C' }, |     { mime: 'text/x-csrc', title: 'C' }, | ||||||
|     { mime: 'text/x-c++src', title: 'C++' }, |     { mime: 'text/x-c++src', title: 'C++' }, | ||||||
| @@ -45,15 +41,24 @@ const DEFAULT_MIME_TYPES = [ | |||||||
|     { mime: 'text/x-yaml', title: 'YAML' } |     { mime: 'text/x-yaml', title: 'YAML' } | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| let noteTypeModel; | let mimeTypes = DEFAULT_MIME_TYPES; | ||||||
|  |  | ||||||
| function NoteTypeModel() { | /** | ||||||
|  |  * @param {NoteContext} ctx | ||||||
|  |  * @constructor | ||||||
|  |  */ | ||||||
|  | function NoteTypeContext(ctx) { | ||||||
|     const self = this; |     const self = this; | ||||||
|  |  | ||||||
|  |     this.$executeScriptButton = ctx.$noteTabContent.find(".execute-script-button"); | ||||||
|  |     this.$toggleEditButton = ctx.$noteTabContent.find('.toggle-edit-button'); | ||||||
|  |     this.$renderButton = ctx.$noteTabContent.find('.render-button'); | ||||||
|  |  | ||||||
|  |     this.ctx = ctx; | ||||||
|     this.type = ko.observable('text'); |     this.type = ko.observable('text'); | ||||||
|     this.mime = ko.observable(''); |     this.mime = ko.observable(''); | ||||||
|  |  | ||||||
|     this.codeMimeTypes = ko.observableArray(DEFAULT_MIME_TYPES); |     this.codeMimeTypes = ko.observableArray(mimeTypes); | ||||||
|  |  | ||||||
|     this.typeString = function() { |     this.typeString = function() { | ||||||
|         const type = self.type(); |         const type = self.type(); | ||||||
| @@ -97,9 +102,7 @@ function NoteTypeModel() { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     async function save() { |     async function save() { | ||||||
|         const note = noteDetailService.getActiveNote(); |         await server.put('notes/' + self.ctx.note.noteId | ||||||
|  |  | ||||||
|         await server.put('notes/' + note.noteId |  | ||||||
|             + '/type/' + encodeURIComponent(self.type()) |             + '/type/' + encodeURIComponent(self.type()) | ||||||
|             + '/mime/' + encodeURIComponent(self.mime())); |             + '/mime/' + encodeURIComponent(self.mime())); | ||||||
|  |  | ||||||
| @@ -175,32 +178,21 @@ function NoteTypeModel() { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     this.updateExecuteScriptButtonVisibility = function() { |     this.updateExecuteScriptButtonVisibility = function() { | ||||||
|         $executeScriptButton.toggle(self.mime().startsWith('application/javascript')); |         self.$executeScriptButton.toggle(self.mime().startsWith('application/javascript')); | ||||||
|  |  | ||||||
|         $toggleEditButton.toggle(self.type() === 'render'); |         self.$toggleEditButton.toggle(self.type() === 'render'); | ||||||
|         $renderButton.toggle(self.type() === 'render'); |         self.$renderButton.toggle(self.type() === 'render'); | ||||||
|     } |     }; | ||||||
| } |  | ||||||
|  |  | ||||||
| function init() { |     ko.applyBindings(this, ctx.$noteTabContent.find('.note-type-wrapper')[0]) | ||||||
|     noteTypeModel = new NoteTypeModel(); |  | ||||||
|  |  | ||||||
|     ko.applyBindings(noteTypeModel, document.getElementById('note-type-wrapper')); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|     getNoteType: () => noteTypeModel.type(), |  | ||||||
|     setNoteType: type => noteTypeModel.type(type), |  | ||||||
|  |  | ||||||
|     getNoteMime: () => noteTypeModel.mime(), |  | ||||||
|     setNoteMime: mime => { |  | ||||||
|         noteTypeModel.mime(mime); |  | ||||||
|  |  | ||||||
|         noteTypeModel.updateExecuteScriptButtonVisibility(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getDefaultCodeMimeTypes: () => DEFAULT_MIME_TYPES.slice(), |     getDefaultCodeMimeTypes: () => DEFAULT_MIME_TYPES.slice(), | ||||||
|     getCodeMimeTypes: () => noteTypeModel.codeMimeTypes(), |     getCodeMimeTypes: () => mimeTypes, | ||||||
|     setCodeMimeTypes: types => noteTypeModel.codeMimeTypes(types), |     setCodeMimeTypes: types => { mimeTypes = types; } | ||||||
|     init | }; | ||||||
|  |  | ||||||
|  | export { | ||||||
|  |     NoteTypeContext | ||||||
| }; | }; | ||||||
| @@ -412,7 +412,7 @@ div.ui-tooltip { | |||||||
|     font-size: larger; |     font-size: larger; | ||||||
| } | } | ||||||
|  |  | ||||||
| #children-overview { | .children-overview { | ||||||
|     flex-grow: 1000; |     flex-grow: 1000; | ||||||
|     flex-shrink: 1000; |     flex-shrink: 1000; | ||||||
|     flex-basis: 0; |     flex-basis: 0; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user