aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorHunternif2019-04-16 22:09:04 +0700
committerHunternif2019-04-16 22:09:04 +0700
commit9f673a39bfad299c101469f38d8838d7d266279e (patch)
tree5741a2725cb456a848f3209b1079f9d01c91ba33 /client
parent2307abc8aa27781a3e44930599141a778f09f800 (diff)
POC create metric in tag edit view.
Diffstat (limited to 'client')
-rw-r--r--client/html/tag.tpl3
-rw-r--r--client/html/tag_metric.tpl24
-rw-r--r--client/js/controllers/tag_controller.js25
-rw-r--r--client/js/models/metric.js70
-rw-r--r--client/js/models/tag.js3
-rw-r--r--client/js/views/tag_metric_view.js53
-rw-r--r--client/js/views/tag_view.js13
7 files changed, 191 insertions, 0 deletions
diff --git a/client/html/tag.tpl b/client/html/tag.tpl
index 497790e..fc3d81c 100644
--- a/client/html/tag.tpl
+++ b/client/html/tag.tpl
@@ -6,6 +6,9 @@
--><% if (ctx.canEditAnything) { %><!--
--><li data-name='edit'><a href='<%- ctx.formatClientLink('tag', ctx.tag.names[0], 'edit') %>'>Edit</a></li><!--
--><% } %><!--
+ --><% if (ctx.tag.metric || ctx.canCreateMetric) { %><!--
+ --><li data-name='merge'><a href='<%- ctx.formatClientLink('tag', ctx.tag.names[0], 'metric') %>'>Metric</a></li><!--
+ --><% } %><!--
--><% if (ctx.canMerge) { %><!--
--><li data-name='merge'><a href='<%- ctx.formatClientLink('tag', ctx.tag.names[0], 'merge') %>'>Merge with&hellip;</a></li><!--
--><% } %><!--
diff --git a/client/html/tag_metric.tpl b/client/html/tag_metric.tpl
new file mode 100644
index 0000000..b25ebff
--- /dev/null
+++ b/client/html/tag_metric.tpl
@@ -0,0 +1,24 @@
+<div class='tag-metric'>
+ <form class='horizontal edit-metric'>
+ <%= ctx.makeNumericInput({
+ text: 'Minimum',
+ name: 'metric-min',
+ value: ctx.metricMin,
+ enabled: ctx.canEditMetricBounds,
+ }) %>
+ <%= ctx.makeNumericInput({
+ text: 'Maximum',
+ name: 'metric-max',
+ value: ctx.metricMax,
+ enabled: ctx.canEditMetricBounds,
+ }) %>
+
+ <div class='buttons'>
+ <% if (!ctx.tag.metric && ctx.canCreateMetric) { %>
+ <input type='submit' >Create metric</input>
+ <% } else if (ctx.tag.metric && ctx.canEditMetricBounds) { %>
+ <input type='submit' >Update metric</input>
+ <% } %>
+ </div>
+ </form>
+</div> \ No newline at end of file
diff --git a/client/js/controllers/tag_controller.js b/client/js/controllers/tag_controller.js
index d64ab22..c3a4c91 100644
--- a/client/js/controllers/tag_controller.js
+++ b/client/js/controllers/tag_controller.js
@@ -6,6 +6,7 @@ const misc = require('../util/misc.js');
const uri = require('../util/uri.js');
const Tag = require('../models/tag.js');
const TagCategoryList = require('../models/tag_category_list.js');
+const Metric = require('../models/metric.js');
const topNavigation = require('../models/top_navigation.js');
const TagView = require('../views/tag_view.js');
const EmptyView = require('../views/empty_view.js');
@@ -44,6 +45,8 @@ class TagController {
canEditImplications: api.hasPrivilege('tags:edit:implications'),
canEditSuggestions: api.hasPrivilege('tags:edit:suggestions'),
canEditDescription: api.hasPrivilege('tags:edit:description'),
+ canCreateMetric: api.hasPrivilege('metrics:create'),
+ canEditMetricBounds: api.hasPrivilege('metrics:edit:bounds'),
canMerge: api.hasPrivilege('tags:merge'),
canDelete: api.hasPrivilege('tags:delete'),
categories: categories,
@@ -54,6 +57,8 @@ class TagController {
this._view.addEventListener('submit', e => this._evtUpdate(e));
this._view.addEventListener('merge', e => this._evtMerge(e));
this._view.addEventListener('delete', e => this._evtDelete(e));
+ this._view.addEventListener('metricCreate', e => this._evtMetricCreate(e));
+ this._view.addEventListener('metricUpdate', e => this._evtMetricUpdate(e));
}, error => {
this._view = new EmptyView();
this._view.showError(error.message);
@@ -94,6 +99,26 @@ class TagController {
});
}
+ _evtMetricCreate(e) {
+ this._view.clearMessages();
+ this._view.disableForm();
+ const metric = new Metric();
+ metric.min = e.detail.metricMin;
+ metric.max = e.detail.metricMax;
+ //TODO create metrics via updating tags instead
+ metric.save().then(() => {
+ this._view.showSuccess('Metric created.');
+ this._view.enableForm();
+ }, error => {
+ this._view.showError(error.message);
+ this._view.enableForm();
+ });
+ }
+
+ _evtMetricUpdate(e) {
+ //TODO update metric
+ }
+
_evtMerge(e) {
this._view.clearMessages();
this._view.disableForm();
diff --git a/client/js/models/metric.js b/client/js/models/metric.js
new file mode 100644
index 0000000..2095999
--- /dev/null
+++ b/client/js/models/metric.js
@@ -0,0 +1,70 @@
+'use strict';
+
+const api = require('../api.js');
+const uri = require('../util/uri.js');
+const events = require('../events.js');
+const misc = require('../util/misc.js');
+
+class Metric extends events.EventTarget {
+ constructor() {
+ super();
+ this._orig = {};
+
+ this._updateFromResponse({});
+ }
+
+ get min() { return this._min; }
+ get max() { return this._max; }
+
+ set min(value) { this._min = value; }
+ set max(value) { this._max = value; }
+
+ static fromResponse(response) {
+ const ret = new Metric();
+ ret._updateFromResponse(response);
+ return ret;
+ }
+
+ static get(name) {
+ //TODO get metric. Or only via tag?
+ return api.get(uri.formatApiLink('metric', name))
+ .then(response => {
+ return Promise.resolve(Metric.fromResponse(response));
+ });
+ }
+
+ save() {
+ const detail = {version: this._version};
+
+ if (this._min !== this._orig._min) {
+ detail.min = this._min;
+ }
+ if (this._max !== this._orig._max) {
+ detail.max = this._max;
+ }
+
+ return api.post(uri.formatApiLink('metrics'), detail)
+ .then(response => {
+ this._updateFromResponse(response);
+ this.dispatchEvent(new CustomEvent('change', {
+ detail: {
+ metric: this,
+ },
+ }));
+ return Promise.resolve();
+ });
+ }
+
+ _updateFromResponse(response) {
+ const map = {
+ _version: response.version,
+ _min: response.min,
+ _max: response.max,
+ };
+
+ Object.assign(this, map);
+ Object.assign(this._orig, map);
+ }
+}
+
+module.exports = Metric;
diff --git a/client/js/models/tag.js b/client/js/models/tag.js
index c743554..dcf95de 100644
--- a/client/js/models/tag.js
+++ b/client/js/models/tag.js
@@ -28,10 +28,12 @@ class Tag extends events.EventTarget {
get postCount() { return this._postCount; }
get creationTime() { return this._creationTime; }
get lastEditTime() { return this._lastEditTime; }
+ get metric() { return this._metric; }
set names(value) { this._names = value; }
set category(value) { this._category = value; }
set description(value) { this._description = value; }
+ set metric(value) { this._metric = value; }
static fromResponse(response) {
const ret = new Tag();
@@ -135,6 +137,7 @@ class Tag extends events.EventTarget {
_creationTime: response.creationTime,
_lastEditTime: response.lastEditTime,
_postCount: response.usages || 0,
+ _metric: response.metric,
};
for (let obj of [this, this._orig]) {
diff --git a/client/js/views/tag_metric_view.js b/client/js/views/tag_metric_view.js
new file mode 100644
index 0000000..01f2607
--- /dev/null
+++ b/client/js/views/tag_metric_view.js
@@ -0,0 +1,53 @@
+'use strict';
+
+const events = require('../events.js');
+const api = require('../api.js');
+const views = require('../util/views.js');
+const Metric = require('../models/metric.js');
+
+const template = views.getTemplate('tag-metric');
+
+class TagMetricView extends events.EventTarget {
+ constructor(ctx) {
+ super();
+
+ this._tag = ctx.tag;
+ this._hostNode = ctx.hostNode;
+
+ if (ctx.tag.metric) {
+ ctx.metricMin = ctx.tag.metric.min;
+ ctx.metricMax = ctx.tag.metric.max;
+ } else {
+ // default new values
+ ctx.metricMin = 0;
+ ctx.metricMax = 10;
+ }
+
+ this._formNode.addEventListener('submit', e => this._evtSubmit(e));
+ }
+
+ _evtSubmit(e) {
+ e.preventDefault();
+ this.dispatchEvent(new CustomEvent('submit', {
+ detail: {
+ tag: this._tag,
+ metricMin: this._minFieldNode.value,
+ metricMax: this._maxFieldNode.value,
+ },
+ }));
+ }
+
+ get _formNode() {
+ return this._hostNode.querySelector('form');
+ }
+
+ get _minFieldNode() {
+ return this._formNode.querySelector('input[name=metric-min]');
+ }
+
+ get _maxFieldNode() {
+ return this._formNode.querySelector('input[name=metric-max]');
+ }
+}
+
+module.exports = TagMetricView;
diff --git a/client/js/views/tag_view.js b/client/js/views/tag_view.js
index c3457bc..20a1a97 100644
--- a/client/js/views/tag_view.js
+++ b/client/js/views/tag_view.js
@@ -4,6 +4,7 @@ const events = require('../events.js');
const views = require('../util/views.js');
const TagSummaryView = require('./tag_summary_view.js');
const TagEditView = require('./tag_edit_view.js');
+const TagMetricView = require('./tag_metric_view.js');
const TagMergeView = require('./tag_merge_view.js');
const TagDeleteView = require('./tag_delete_view.js');
const EmptyView = require('../views/empty_view.js');
@@ -47,6 +48,18 @@ class TagView extends events.EventTarget {
events.proxyEvent(this._view, this, 'submit');
}
+ } else if (ctx.section === 'metric') {
+ const metricExists = this._ctx.tag.metric;
+ if (!metricExists && !this._ctx.canCreateMetric) {
+ this._view = new EmptyView();
+ this._view.showError(
+ 'You don\'t have privileges to create metrics.');
+ } else {
+ this._view = new TagMetricView(ctx);
+ events.proxyEvent(this._view, this, 'submit',
+ metricExists ? 'metricUpdate' : 'metricCreate');
+ }
+
} else if (ctx.section === 'merge') {
if (!this._ctx.canMerge) {
this._view = new EmptyView();

© 2015 - 2026 Jakob L. Kreuze