Notes/src/public/app/widgets/attribute_list.js

257 lines
8.5 KiB
JavaScript
Raw Normal View History

2020-05-28 00:17:13 +02:00
import TabAwareWidget from "./tab_aware_widget.js";
import AttributeDetailWidget from "./attribute_detail.js";
2020-07-17 00:08:28 +02:00
import attributeRenderer from "../services/attribute_renderer.js";
import AttributeEditorWidget from "./attribute_editor.js";
import options from '../services/options.js';
import PromotedAttributesWidget from "./promoted_attributes.js";
2020-07-09 23:59:27 +02:00
2020-05-28 00:17:13 +02:00
const TPL = `
<div class="attribute-list">
<style>
.attribute-list {
margin-left: 7px;
margin-right: 7px;
}
.inherited-attributes-wrapper {
color: var(--muted-text-color);
max-height: 200px;
overflow: auto;
padding-bottom: 5px;
padding-left: 7px;
}
.attribute-list-editor p {
margin: 0 !important;
}
.attribute-list.error .attribute-list-editor {
border-color: red !important;
}
.attr-expander {
display: flex;
flex-direction: row;
color: var(--muted-text-color);
font-size: small;
}
.attribute-list hr {
height: 1px;
border-color: var(--main-border-color);
position: relative;
top: 4px;
margin-top: 5px;
margin-bottom: 0;
}
.attr-expander-text {
padding-left: 20px;
padding-right: 20px;
white-space: nowrap;
}
.attr-expander:hover {
cursor: pointer;
}
.attr-expander:not(.error):hover hr {
border-color: black;
}
.attr-expander:not(.error):hover .attr-expander-text {
color: black;
}
</style>
<div class="attr-expander attr-promoted-expander">
<hr class="w-100">
<div class="attr-expander-text">Promoted attributes</div>
<hr class="w-100">
</div>
<div class="all-attr-wrapper">
<div class="promoted-attributes-placeholder"></div>
<div class="attr-expander attr-owned-and-inherited-expander">
<hr class="w-100">
<div class="attr-expander-text"></div>
<hr class="w-100">
</div>
<div class="owned-and-inherited-wrapper">
<div class="attr-editor-placeholder"></div>
<hr class="w-100 attr-inherited-empty-expander" style="margin-bottom: 10px;">
<div class="attr-expander attr-inherited-expander">
<hr class="w-100">
<div class="attr-expander-text"></div>
<hr class="w-100">
</div>
<div class="inherited-attributes-wrapper"></div>
</div>
</div>
2020-05-28 00:17:13 +02:00
</div>
`;
export default class AttributeListWidget extends TabAwareWidget {
2020-05-28 00:17:13 +02:00
constructor() {
super();
this.promotedAttributesWidget = new PromotedAttributesWidget().setParent(this);
this.attributeDetailWidget = new AttributeDetailWidget().setParent(this);
2020-07-17 23:55:59 +02:00
this.attributeEditorWidget = new AttributeEditorWidget(this.attributeDetailWidget).setParent(this);
this.child(this.promotedAttributesWidget, this.attributeEditorWidget, this.attributeDetailWidget);
2020-05-28 00:17:13 +02:00
}
doRender() {
this.$widget = $(TPL);
this.$promotedExpander = this.$widget.find('.attr-promoted-expander');
this.$allAttrWrapper = this.$widget.find('.all-attr-wrapper');
this.$promotedExpander.on('click', async () => {
const collapse = this.$allAttrWrapper.is(":visible");
await options.save('promotedAttributesExpanded', !collapse);
this.triggerEvent(`promotedAttributesCollapsedStateChanged`, {collapse});
});
this.$ownedAndInheritedWrapper = this.$widget.find('.owned-and-inherited-wrapper');
this.$ownedExpander = this.$widget.find('.attr-owned-and-inherited-expander');
this.$ownedExpander.on('click', async () => {
const collapse = this.$ownedAndInheritedWrapper.is(":visible");
await options.save('attributeListExpanded', !collapse);
this.triggerEvent(`attributeListCollapsedStateChanged`, {collapse});
});
this.$ownedExpanderText = this.$ownedExpander.find('.attr-expander-text');
this.$inheritedAttributesWrapper = this.$widget.find('.inherited-attributes-wrapper');
this.$inheritedExpander = this.$widget.find('.attr-inherited-expander');
this.$inheritedExpander.on('click', () => {
if (this.$inheritedAttributesWrapper.is(":visible")) {
this.$inheritedAttributesWrapper.slideUp(200);
2020-06-24 00:02:54 +02:00
}
else {
this.$inheritedAttributesWrapper.slideDown(200);
2020-06-24 00:02:54 +02:00
}
});
this.$inheritedExpanderText = this.$inheritedExpander.find('.attr-expander-text');
this.$inheritedEmptyExpander = this.$widget.find('.attr-inherited-empty-expander');
2020-06-24 00:02:54 +02:00
this.$widget.find('.promoted-attributes-placeholder').replaceWith(this.promotedAttributesWidget.render());
2020-07-17 00:08:28 +02:00
this.$widget.find('.attr-editor-placeholder').replaceWith(this.attributeEditorWidget.render());
this.$widget.append(this.attributeDetailWidget.render());
2020-05-28 00:17:13 +02:00
}
async refreshWithNote(note) {
const hasPromotedAttrs = this.promotedAttributesWidget.getPromotedDefinitionAttributes().length > 0;
if (hasPromotedAttrs) {
this.$promotedExpander.show();
this.$allAttrWrapper.toggle(options.is('promotedAttributesExpanded'));
this.$ownedAndInheritedWrapper.hide();
this.$inheritedAttributesWrapper.hide();
}
else {
this.$promotedExpander.hide();
this.$ownedAndInheritedWrapper.toggle(options.is('attributeListExpanded'));
}
const ownedAttributes = note.getOwnedAttributes().filter(attr => !attr.isAutoLink);
2020-07-17 00:08:28 +02:00
this.$ownedExpanderText.text(ownedAttributes.length + ' owned ' + this.attrPlural(ownedAttributes.length));
2020-06-27 00:40:35 +02:00
const inheritedAttributes = note.getAttributes().filter(attr => attr.noteId !== this.noteId);
2020-07-04 00:20:23 +02:00
2020-06-27 00:40:35 +02:00
if (inheritedAttributes.length === 0) {
this.$inheritedExpander.hide();
this.$inheritedEmptyExpander.show();
}
else {
this.$inheritedExpander.show();
this.$inheritedEmptyExpander.hide();
}
2020-06-27 00:40:35 +02:00
this.$inheritedExpanderText.text(inheritedAttributes.length + ' inherited ' + this.attrPlural(inheritedAttributes.length));
this.$inheritedAttributesWrapper.empty();
2020-07-04 00:40:41 +02:00
await this.renderInheritedAttributes(inheritedAttributes, this.$inheritedAttributesWrapper);
2020-07-09 23:59:27 +02:00
}
attrPlural(number) {
return 'attribute' + (number === 1 ? '' : 's');
}
2020-07-13 23:27:23 +02:00
renderInheritedAttributes(attributes, $container) {
for (const attribute of attributes) {
const $span = $("<span>")
.on('click', e => this.attributeDetailWidget.showAttributeDetail({
attribute: {
noteId: attribute.noteId,
type: attribute.type,
name: attribute.name,
value: attribute.value
},
isOwned: false,
x: e.pageX,
y: e.pageY
}));
$container.append($span);
2020-07-17 00:08:28 +02:00
attributeRenderer.renderAttribute(attribute, $span, false);
}
2020-07-09 23:59:27 +02:00
}
2020-07-17 23:55:59 +02:00
async saveAttributesCommand() {
await this.attributeEditorWidget.save();
}
2020-07-17 23:55:59 +02:00
updateAttributeListCommand({attributes}) {
this.attributeEditorWidget.updateAttributeList(attributes);
}
/**
* This event is used to synchronize collapsed state of all the tab-cached widgets since they are all rendered
* separately but should behave uniformly for the user.
*/
attributeListCollapsedStateChangedEvent({collapse}) {
if (collapse) {
this.$ownedAndInheritedWrapper.slideUp(200);
} else {
this.$ownedAndInheritedWrapper.slideDown(200);
}
}
/**
* This event is used to synchronize collapsed state of all the tab-cached widgets since they are all rendered
* separately but should behave uniformly for the user.
*/
promotedAttributesCollapsedStateChangedEvent({collapse}) {
if (collapse) {
this.$allAttrWrapper.slideUp(200);
} else {
this.$allAttrWrapper.slideDown(200);
}
}
2020-05-28 00:17:13 +02:00
}