import server from "../../services/server.js"; import ws from "../../services/ws.js"; import treeService from "../../services/tree.js"; import noteAutocompleteService from "../../services/note_autocomplete.js"; import NoteContextAwareWidget from "../note_context_aware_widget.js"; import attributeService from "../../services/attributes.js"; const TPL = `
`; export default class PromotedAttributesWidget extends NoteContextAwareWidget { get name() { return "promotedAttributes"; } get toggleCommand() { return "toggleRibbonTabPromotedAttributes"; } doRender() { this.$widget = $(TPL); this.contentSized(); this.$container = this.$widget.find(".promoted-attributes-container"); } getTitle(note) { const promotedDefAttrs = note.getPromotedDefinitionAttributes(); if (promotedDefAttrs.length === 0) { return {show: false}; } return { show: true, activate: true, title: "Promoted Attributes", icon: "bx bx-table" }; } async refreshWithNote(note) { this.$container.empty(); const promotedDefAttrs = note.getPromotedDefinitionAttributes(); const ownedAttributes = note.getOwnedAttributes(); // attrs are not resorted if position changes after the initial load // promoted attrs are sorted primarily by order of definitions, but with multi-valued promoted attrs // the order of attributes is important as well ownedAttributes.sort((a, b) => a.position < b.position ? -1 : 1); if (promotedDefAttrs.length === 0) { this.toggleInt(false); return; } const $cells = []; for (const definitionAttr of promotedDefAttrs) { const valueType = definitionAttr.name.startsWith('label:') ? 'label' : 'relation'; const valueName = definitionAttr.name.substr(valueType.length + 1); let valueAttrs = ownedAttributes.filter(el => el.name === valueName && el.type === valueType); if (valueAttrs.length === 0) { valueAttrs.push({ attributeId: "", type: valueType, name: valueName, value: "" }); } if (definitionAttr.getDefinition().multiplicity === 'single') { valueAttrs = valueAttrs.slice(0, 1); } for (const valueAttr of valueAttrs) { const $cell = await this.createPromotedAttributeCell(definitionAttr, valueAttr, valueName); $cells.push($cell); } } // we replace the whole content in one step, so there can't be any race conditions // (previously we saw promoted attributes doubling) this.$container.empty().append(...$cells); this.toggleInt(true); } async createPromotedAttributeCell(definitionAttr, valueAttr, valueName) { const definition = definitionAttr.getDefinition(); const $input = $("") .prop("tabindex", 200 + definitionAttr.position) .attr("data-attribute-id", valueAttr.noteId === this.noteId ? valueAttr.attributeId : '') // if not owned, we'll force creation of a new attribute instead of updating the inherited one .attr("data-attribute-type", valueAttr.type) .attr("data-attribute-name", valueAttr.name) .prop("value", valueAttr.value) .addClass("form-control") .addClass("promoted-attribute-input") .on('change', event => this.promotedAttributeChanged(event)); const $actionCell = $("
"); const $multiplicityCell = $("") .addClass("multiplicity") .attr("nowrap", true); const $wrapper = $('