mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	split out attribute_editor widget, WIP
This commit is contained in:
		
							parent
							
								
									9f527f0330
								
							
						
					
					
						commit
						a94ae81c30
					
				| @ -45,13 +45,18 @@ const TPL = ` | |||||||
|         border: 1px solid var(--main-border-color); |         border: 1px solid var(--main-border-color); | ||||||
|         border-radius: 2px; |         border-radius: 2px; | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     .attribute-errors { | ||||||
|  |         color: red; | ||||||
|  |     } | ||||||
|     </style> |     </style> | ||||||
|      |      | ||||||
|     <div class="attribute-list-editor" tabindex="200"></div> |     <div class="attribute-list-editor" tabindex="200"></div> | ||||||
| 
 | 
 | ||||||
|     <div class="bx bx-save save-attributes-button" title="Save attributes <enter>, <tab>)"></div> |     <div class="bx bx-save save-attributes-button" title="Save attributes <enter>, <tab>)"></div> | ||||||
| 
 |  | ||||||
|     <div class="bx bx-plus add-new-attribute-button" title="Add a new attribute"></div> |     <div class="bx bx-plus add-new-attribute-button" title="Add a new attribute"></div> | ||||||
|  |      | ||||||
|  |     <div class="attribute-errors" style="display: none;"></div> | ||||||
| </div> | </div> | ||||||
| `;
 | `;
 | ||||||
| 
 | 
 | ||||||
| @ -171,6 +176,12 @@ const editorConfig = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default class AttributeEditorWidget extends TabAwareWidget { | export default class AttributeEditorWidget extends TabAwareWidget { | ||||||
|  |     constructor(attributeDetailWidget) { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         this.attributeDetailWidget = attributeDetailWidget; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     doRender() { |     doRender() { | ||||||
|         this.$widget = $(TPL); |         this.$widget = $(TPL); | ||||||
|         this.$editor = this.$widget.find('.attribute-list-editor'); |         this.$editor = this.$widget.find('.attribute-list-editor'); | ||||||
| @ -190,76 +201,83 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         this.$addNewAttributeButton = this.$widget.find('.add-new-attribute-button'); |         this.$addNewAttributeButton = this.$widget.find('.add-new-attribute-button'); | ||||||
|         this.$addNewAttributeButton.on('click', e => { |         this.$addNewAttributeButton.on('click', e => this.addNewAttribute(e)); | ||||||
|             contextMenuService.show({ |  | ||||||
|                 x: e.pageX, |  | ||||||
|                 y: e.pageY, |  | ||||||
|                 orientation: 'left', |  | ||||||
|                 items: [ |  | ||||||
|                     {title: "Add new label", command: "addNewLabel", uiIcon: "hash"}, |  | ||||||
|                     {title: "Add new relation", command: "addNewRelation", uiIcon: "transfer"}, |  | ||||||
|                     {title: "----"}, |  | ||||||
|                     {title: "Add new label definition", command: "addNewLabelDefinition", uiIcon: "empty"}, |  | ||||||
|                     {title: "Add new relation definition", command: "addNewRelationDefinition", uiIcon: "empty"}, |  | ||||||
|                 ], |  | ||||||
|                 selectMenuItemHandler: async ({command}) => { |  | ||||||
|                     const attrs = this.parseAttributes(); |  | ||||||
| 
 | 
 | ||||||
|                     if (!attrs) { |         this.$saveAttributesButton = this.$widget.find('.save-attributes-button'); | ||||||
|                         return; |         this.$saveAttributesButton.on('click', () => this.save()); | ||||||
|                     } |  | ||||||
| 
 | 
 | ||||||
|                     let type, name; |         this.$errors = this.$widget.find('.attribute-errors'); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|                     if (command === 'addNewLabel') { |     addNewAttribute(e) { | ||||||
|                         type = 'label'; |         contextMenuService.show({ | ||||||
|                         name = 'fillName'; |             x: e.pageX, | ||||||
|                     } |             y: e.pageY, | ||||||
|                     else if (command === 'addNewRelation') { |             orientation: 'left', | ||||||
|                         type = 'relation'; |             items: [ | ||||||
|                         name = 'fillName'; |                 {title: "Add new label", command: "addNewLabel", uiIcon: "hash"}, | ||||||
|                     } |                 {title: "Add new relation", command: "addNewRelation", uiIcon: "transfer"}, | ||||||
|                     else if (command === 'addNewLabelDefinition') { |                 {title: "----"}, | ||||||
|                         type = 'label'; |                 {title: "Add new label definition", command: "addNewLabelDefinition", uiIcon: "empty"}, | ||||||
|                         name = 'label:fillName'; |                 {title: "Add new relation definition", command: "addNewRelationDefinition", uiIcon: "empty"}, | ||||||
|                     } |             ], | ||||||
|                     else if (command === 'addNewRelationDefinition') { |             selectMenuItemHandler: ({command}) => this.handleAddNewAttributeCommand(command) | ||||||
|                         type = 'label'; |  | ||||||
|                         name = 'relation:fillName'; |  | ||||||
|                     } |  | ||||||
|                     else { |  | ||||||
|                         return; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     attrs.push({ |  | ||||||
|                         type, |  | ||||||
|                         name, |  | ||||||
|                         value: '', |  | ||||||
|                         isInheritable: false |  | ||||||
|                     }); |  | ||||||
| 
 |  | ||||||
|                     await this.renderOwnedAttributes(attrs); |  | ||||||
| 
 |  | ||||||
|                     this.$editor.scrollTop(this.$editor[0].scrollHeight); |  | ||||||
| 
 |  | ||||||
|                     const rect = this.$editor[0].getBoundingClientRect(); |  | ||||||
| 
 |  | ||||||
|                     setTimeout(() => { |  | ||||||
|                         // showing a little bit later because there's a conflict with outside click closing the attr detail
 |  | ||||||
|                         this.attributeDetailWidget.showAttributeDetail({ |  | ||||||
|                             allAttributes: attrs, |  | ||||||
|                             attribute: attrs[attrs.length - 1], |  | ||||||
|                             isOwned: true, |  | ||||||
|                             x: (rect.left + rect.right) / 2, |  | ||||||
|                             y: rect.bottom |  | ||||||
|                         }); |  | ||||||
|                     }, 100); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     async handleAddNewAttributeCommand(command) { | ||||||
|  |         const attrs = this.parseAttributes(); | ||||||
|  | 
 | ||||||
|  |         if (!attrs) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let type, name; | ||||||
|  | 
 | ||||||
|  |         if (command === 'addNewLabel') { | ||||||
|  |             type = 'label'; | ||||||
|  |             name = 'fillName'; | ||||||
|  |         } else if (command === 'addNewRelation') { | ||||||
|  |             type = 'relation'; | ||||||
|  |             name = 'fillName'; | ||||||
|  |         } else if (command === 'addNewLabelDefinition') { | ||||||
|  |             type = 'label'; | ||||||
|  |             name = 'label:fillName'; | ||||||
|  |         } else if (command === 'addNewRelationDefinition') { | ||||||
|  |             type = 'label'; | ||||||
|  |             name = 'relation:fillName'; | ||||||
|  |         } else { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         attrs.push({ | ||||||
|  |             type, | ||||||
|  |             name, | ||||||
|  |             value: '', | ||||||
|  |             isInheritable: false | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         await this.renderOwnedAttributes(attrs); | ||||||
|  | 
 | ||||||
|  |         this.$editor.scrollTop(this.$editor[0].scrollHeight); | ||||||
|  | 
 | ||||||
|  |         const rect = this.$editor[0].getBoundingClientRect(); | ||||||
|  | 
 | ||||||
|  |         setTimeout(() => { | ||||||
|  |             // showing a little bit later because there's a conflict with outside click closing the attr detail
 | ||||||
|  |             this.attributeDetailWidget.showAttributeDetail({ | ||||||
|  |                 allAttributes: attrs, | ||||||
|  |                 attribute: attrs[attrs.length - 1], | ||||||
|  |                 isOwned: true, | ||||||
|  |                 x: (rect.left + rect.right) / 2, | ||||||
|  |                 y: rect.bottom | ||||||
|  |             }); | ||||||
|  |         }, 100); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     async save() { |     async save() { | ||||||
|  |         this.$saveAttributesButton.fadeOut(); | ||||||
|  | 
 | ||||||
|         const attributes = this.parseAttributes(); |         const attributes = this.parseAttributes(); | ||||||
| 
 | 
 | ||||||
|         if (attributes) { |         if (attributes) { | ||||||
| @ -274,11 +292,7 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|             return attrs; |             return attrs; | ||||||
|         } |         } | ||||||
|         catch (e) { |         catch (e) { | ||||||
|             this.$widget.attr("title", e.message); |             this.$errors.show().text(e.message); | ||||||
|             this.$widget.addClass("error"); |  | ||||||
| 
 |  | ||||||
|             this.$ownedExpander.addClass("error"); |  | ||||||
|             this.$ownedExpanderText.text(e.message); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -300,7 +314,16 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     dataChanged() { |     dataChanged() { | ||||||
|         console.log("Data changed"); |         if (this.lastSavedContent === this.textEditor.getData()) { | ||||||
|  |             this.$saveAttributesButton.fadeOut(); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             this.$saveAttributesButton.fadeIn(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (this.$errors.is(":visible")) { | ||||||
|  |             this.$errors.slideUp(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async handleEditorClick(e) { |     async handleEditorClick(e) { | ||||||
| @ -309,7 +332,15 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|         if (pos && pos.textNode && pos.textNode.data) { |         if (pos && pos.textNode && pos.textNode.data) { | ||||||
|             const clickIndex = this.getClickIndex(pos); |             const clickIndex = this.getClickIndex(pos); | ||||||
| 
 | 
 | ||||||
|             const parsedAttrs = attributesParser.lexAndParse(this.textEditor.getData(), true); |             let parsedAttrs; | ||||||
|  | 
 | ||||||
|  |             try { | ||||||
|  |                 parsedAttrs = attributesParser.lexAndParse(this.textEditor.getData(), true); | ||||||
|  |             } | ||||||
|  |             catch (e) { | ||||||
|  |                 // the input is incorrect because user messed up with it and now needs to fix it manually
 | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             let matchedAttr = null; |             let matchedAttr = null; | ||||||
| 
 | 
 | ||||||
| @ -370,7 +401,7 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|         await this.renderOwnedAttributes(note.getOwnedAttributes()); |         await this.renderOwnedAttributes(note.getOwnedAttributes()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async renderOwnedAttributes(ownedAttributes) { |     async renderOwnedAttributes(ownedAttributes, ) { | ||||||
|         const $attributesContainer = $("<div>"); |         const $attributesContainer = $("<div>"); | ||||||
| 
 | 
 | ||||||
|         for (const attribute of ownedAttributes) { |         for (const attribute of ownedAttributes) { | ||||||
| @ -378,6 +409,10 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this.textEditor.setData($attributesContainer.html()); |         this.textEditor.setData($attributesContainer.html()); | ||||||
|  | 
 | ||||||
|  |         this.lastSavedContent = this.textEditor.getData(); | ||||||
|  | 
 | ||||||
|  |         this.$saveAttributesButton.fadeOut(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async focusOnAttributesEvent({tabId}) { |     async focusOnAttributesEvent({tabId}) { | ||||||
| @ -386,7 +421,7 @@ export default class AttributeEditorWidget extends TabAwareWidget { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     updateAttributeListCommand({attributes}) { |     updateAttributeList(attributes) { | ||||||
|         this.renderOwnedAttributes(attributes); |         this.renderOwnedAttributes(attributes); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -93,8 +93,8 @@ export default class AttributeListWidget extends TabAwareWidget { | |||||||
|     constructor() { |     constructor() { | ||||||
|         super(); |         super(); | ||||||
| 
 | 
 | ||||||
|         this.attributeEditorWidget = new AttributeEditorWidget().setParent(this); |  | ||||||
|         this.attributeDetailWidget = new AttributeDetailWidget().setParent(this); |         this.attributeDetailWidget = new AttributeDetailWidget().setParent(this); | ||||||
|  |         this.attributeEditorWidget = new AttributeEditorWidget(this.attributeDetailWidget).setParent(this); | ||||||
| 
 | 
 | ||||||
|         this.child(this.attributeEditorWidget, this.attributeDetailWidget); |         this.child(this.attributeEditorWidget, this.attributeDetailWidget); | ||||||
|     } |     } | ||||||
| @ -183,4 +183,8 @@ export default class AttributeListWidget extends TabAwareWidget { | |||||||
|             attributeRenderer.renderAttribute(attribute, $span, false); |             attributeRenderer.renderAttribute(attribute, $span, false); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     updateAttributeListCommand({attributes}) { | ||||||
|  |         this.attributeEditorWidget.updateAttributeList(attributes); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -54,7 +54,7 @@ export default class PromotedAttributesWidget extends TabAwareWidget { | |||||||
|                 const definitionType = definitionAttr.name.startsWith('label:') ? 'label' : 'relation'; |                 const definitionType = definitionAttr.name.startsWith('label:') ? 'label' : 'relation'; | ||||||
|                 const valueName = definitionAttr.name.substr(definitionType.length + 1); |                 const valueName = definitionAttr.name.substr(definitionType.length + 1); | ||||||
| 
 | 
 | ||||||
|                 let valueAttrs = attributes.filter(el => el.name === definitionAttr.name && el.type === definitionType); |                 let valueAttrs = attributes.filter(el => el.name === valueName && el.type === 'label'); | ||||||
| 
 | 
 | ||||||
|                 if (valueAttrs.length === 0) { |                 if (valueAttrs.length === 0) { | ||||||
|                     valueAttrs.push({ |                     valueAttrs.push({ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam