summaryrefslogtreecommitdiff
path: root/client/js/controls/post_metric_input_control.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/js/controls/post_metric_input_control.js')
-rw-r--r--client/js/controls/post_metric_input_control.js164
1 files changed, 164 insertions, 0 deletions
diff --git a/client/js/controls/post_metric_input_control.js b/client/js/controls/post_metric_input_control.js
new file mode 100644
index 0000000..45b6b24
--- /dev/null
+++ b/client/js/controls/post_metric_input_control.js
@@ -0,0 +1,164 @@
+'use strict';
+
+const uri = require('../util/uri.js');
+const PostMetric = require('../models/post_metric.js');
+const PostMetricRange = require('../models/post_metric_range.js');
+const events = require('../events.js');
+const views = require('../util/views.js');
+
+const mainTemplate = views.getTemplate('post-metric-input');
+const metricNodeTemplate = views.getTemplate('compact-metric-list-item');
+const postMetricNodeTemplate = views.getTemplate('compact-post-metric-list-item');
+const postMetricRangeNodeTemplate = views.getTemplate('compact-post-metric-range-list-item');
+
+class PostMetricInputControl extends events.EventTarget {
+ constructor(hostNode, ctx) {
+ super();
+ this._ctx = ctx;
+ this._post = ctx.post;
+ this._hostNode = hostNode;
+
+ // dom
+ const editAreaNode = mainTemplate({
+ tags: this._post.tags,
+ postMetrics: this._post.metrics,
+ });
+ this._editAreaNode = editAreaNode;
+ this._metricListNode = editAreaNode.querySelector('ul.compact-unset-metrics');
+ this._separatorNode = editAreaNode.querySelector('hr.separator');
+ this._postMetricListNode = editAreaNode.querySelector('ul.compact-post-metrics');
+
+ // show
+ this._hostNode.style.display = 'none';
+ this._hostNode.parentNode.insertBefore(
+ this._editAreaNode, hostNode.nextSibling);
+
+ // add existing metrics and post metrics:
+ this.refreshContent();
+ }
+
+ refreshContent() {
+ this._metricListNode.innerHTML = '';
+ for (let tag of this._post.tags.filterMetrics()) {
+ const metricNode = this._createMetricNode(tag);
+ this._metricListNode.appendChild(metricNode);
+ }
+ this._postMetricListNode.innerHTML = '';
+ for (let pm of this._post.metrics) {
+ const postMetricNode = this._createPostMetricNode(pm);
+ this._postMetricListNode.appendChild(postMetricNode);
+ }
+ for (let pmr of this._post.metricRanges) {
+ const postMetricRangeNode = this._createPostMetricRangeNode(pmr);
+ this._postMetricListNode.appendChild(postMetricRangeNode);
+ }
+ this._separatorNode.style.display =
+ this._postMetricListNode.innerHTML ? 'block' : 'none';
+ }
+
+ _createMetricNode(tag) {
+ const node = metricNodeTemplate({
+ editMode: true,
+ tag: tag,
+ post: this._post,
+ query: this._ctx.parameters.query,
+ });
+ const createExactNode = node.querySelector('a.create-exact');
+ if (this._post.metrics.hasTagName(tag.names[0])) {
+ createExactNode.style.display = 'none';
+ } else {
+ createExactNode.addEventListener('click', e => {
+ e.preventDefault();
+ this.createPostMetric(tag);
+ });
+ }
+ const createRangeNode = node.querySelector('a.create-range');
+ if (this._post.metricRanges.hasTagName(tag.names[0])) {
+ createRangeNode.style.display = 'none';
+ } else {
+ createRangeNode.addEventListener('click', e => {
+ e.preventDefault();
+ this.createPostMetricRange(tag);
+ });
+ }
+ const sortNode = node.querySelector('a.sort');
+ if (this._post.metrics.hasTagName(tag.names[0])) {
+ sortNode.style.display = 'none';
+ }
+ return node;
+ }
+
+ _createPostMetricNode(pm) {
+ const tag = this._post.tags.findByName(pm.tagName);
+ const node = postMetricNodeTemplate({
+ editMode: true,
+ postMetric: pm,
+ tag: tag,
+ });
+ node.querySelector('input[name=value]').addEventListener('change', e => {
+ pm.value = e.target.value;
+ this.dispatchEvent(new CustomEvent('change'));
+ });
+ node.querySelector('.remove-metric').addEventListener('click', e => {
+ e.preventDefault();
+ this.deletePostMetric(pm);
+ });
+ return node;
+ }
+
+ _createPostMetricRangeNode(pmr) {
+ const tag = this._post.tags.findByName(pmr.tagName);
+ const node = postMetricRangeNodeTemplate({
+ editMode: true,
+ postMetricRange: pmr,
+ tag: tag,
+ });
+ node.querySelector('input[name=low]').addEventListener('change', e => {
+ pmr.low = e.target.value;
+ this.dispatchEvent(new CustomEvent('change'));
+ });
+ node.querySelector('input[name=high]').addEventListener('change', e => {
+ pmr.high = e.target.value;
+ this.dispatchEvent(new CustomEvent('change'));
+ });
+ node.querySelector('.remove-metric').addEventListener('click', e => {
+ e.preventDefault();
+ this.deletePostMetricRange(pmr);
+ });
+ return node;
+ }
+
+ createPostMetric(tag) {
+ let postMetricRange = this._post.metricRanges.findByTagName(tag.names[0]);
+ if (postMetricRange) {
+ this._post.metricRanges.remove(postMetricRange);
+ }
+ this._post.metrics.add(PostMetric.create(this._post.id, tag));
+ this.refreshContent();
+ this.dispatchEvent(new CustomEvent('change'));
+ }
+
+ createPostMetricRange(tag) {
+ let postMetric = this._post.metrics.findByTagName(tag.names[0]);
+ if (postMetric) {
+ this._post.metrics.remove(postMetric);
+ }
+ this._post.metricRanges.add(PostMetricRange.create(this._post.id, tag));
+ this.refreshContent();
+ this.dispatchEvent(new CustomEvent('change'));
+ }
+
+ deletePostMetric(pm) {
+ this._post.metrics.remove(pm);
+ this.refreshContent();
+ this.dispatchEvent(new CustomEvent('change'));
+ }
+
+ deletePostMetricRange(pmr) {
+ this._post.metricRanges.remove(pmr);
+ this.refreshContent();
+ this.dispatchEvent(new CustomEvent('change'));
+ }
+}
+
+module.exports = PostMetricInputControl;