REFACTOR: old patterns, deprecations and dead code (#35)

This commit is contained in:
Joffrey JAFFEUX 2019-07-16 12:46:32 +02:00 committed by GitHub
parent 1f1afd0d7e
commit b9169ec28e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 306 additions and 316 deletions

View File

@ -15,19 +15,19 @@ export default Ember.Component.extend({
if (this._state !== "inDOM") { if (this._state !== "inDOM") {
return; return;
} }
const $editPane = this.$(".query-editor"); const $editPane = $(".query-editor");
if (!$editPane.length) { if (!$editPane.length) {
return; return;
} }
const oldGrippie = this.get("grippie"); const oldGrippie = this.grippie;
if (oldGrippie) { if (oldGrippie) {
oldGrippie.off("mousedown mousemove mouseup"); oldGrippie.off("mousedown mousemove mouseup");
} }
const $grippie = $editPane.find(".grippie"); const $grippie = $editPane.find(".grippie");
const $target = $editPane.find(".panels-flex"); const $target = $editPane.find(".panels-flex");
const $document = Ember.$(document); const $document = $(document);
const minWidth = $target.width(); const minWidth = $target.width();
const minHeight = $target.height(); const minHeight = $target.height();
@ -35,11 +35,11 @@ export default Ember.Component.extend({
this.set("grippie", $grippie); this.set("grippie", $grippie);
const mousemove = e => { const mousemove = e => {
const diffY = this.get("startY") - e.screenY; const diffY = this.startY - e.screenY;
const diffX = this.get("startX") - e.screenX; const diffX = this.startX - e.screenX;
const newHeight = Math.max(minHeight, this.get("startHeight") - diffY); const newHeight = Math.max(minHeight, this.startHeight - diffY);
const newWidth = Math.max(minWidth, this.get("startWidth") - diffX); const newWidth = Math.max(minWidth, this.startWidth - diffX);
$target.height(newHeight); $target.height(newHeight);
$target.width(newWidth); $target.width(newWidth);
@ -78,14 +78,16 @@ export default Ember.Component.extend({
}, },
didInsertElement() { didInsertElement() {
this._super(); this._super(...arguments);
this._bindControls(); this._bindControls();
}, },
willDestroyElement() { willDestroyElement() {
this._super(); this._super(...arguments);
if (this.get("everEditing")) {
this.get("grippie").off("mousedown"); if (this.everEditing) {
this.grippie && this.grippie.off("mousedown");
this.set("grippie", null); this.set("grippie", null);
} }
} }

View File

@ -1,8 +1,10 @@
import { default as computed } from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({ export default Ember.Component.extend({
tagName: "ol", tagName: "ol",
enuminfo: function() { @computed("col.enum")
const hash = this.get("col.enum"); enuminfo(hash) {
let result = []; let result = [];
for (let key in hash) { for (let key in hash) {
if (!hash.hasOwnProperty(key)) { if (!hash.hasOwnProperty(key)) {
@ -11,5 +13,5 @@ export default Ember.Component.extend({
result.push({ value: key, name: hash[key] }); result.push({ value: key, name: hash[key] });
} }
return result; return result;
}.property("col.enum") }
}); });

View File

@ -1,22 +1,25 @@
import { on } from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({ export default Ember.Component.extend({
classNameBindings: [":schema-table", "open"], classNameBindings: [":schema-table", "open"],
tagName: "li", tagName: "li",
open: Ember.computed.alias("table.open"), open: Ember.computed.reads("table.open"),
_bindClicks: function() { @on("didInsertElement")
const self = this; _bindClicks() {
this.$() $(this.element)
.find(".schema-table-name") .find(".schema-table-name")
.click(function(e) { .click(e => {
self.set("open", !self.get("open")); this.set("open", !this.open);
e.preventDefault(); e.preventDefault();
}); });
}.on("didInsertElement"), },
_cleanup: function() { @on("willDestroyElement")
this.$() _cleanup() {
$(this.element)
.find(".schema-table-name") .find(".schema-table-name")
.off("click"); .off("click");
}.on("willDestroyElement") }
}); });

View File

@ -1,3 +1,7 @@
import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
import debounce from "discourse/lib/debounce"; import debounce from "discourse/lib/debounce";
export default Ember.Component.extend({ export default Ember.Component.extend({
@ -7,15 +11,14 @@ export default Ember.Component.extend({
} }
}, },
transformedSchema: function() { @computed("schema")
const schema = this.get("schema"); transformedSchema(schema) {
for (let key in schema) { for (let key in schema) {
if (!schema.hasOwnProperty(key)) { if (!schema.hasOwnProperty(key)) {
continue; continue;
} }
schema[key].forEach(function(col) { schema[key].forEach(col => {
const notes_components = []; const notes_components = [];
if (col.primary) { if (col.primary) {
notes_components.push("primary key"); notes_components.push("primary key");
@ -46,17 +49,18 @@ export default Ember.Component.extend({
}); });
} }
return schema; return schema;
}.property("schema"), },
rfilter: function() { @computed("filter")
if (!Ember.isBlank(this.get("filter"))) { rfilter(filter) {
return new RegExp(this.get("filter")); if (!Ember.isBlank(filter)) {
return new RegExp(filter);
} }
}.property("filter"), },
filterTables: function(schema) { filterTables(schema) {
let tables = []; let tables = [];
const filter = this.get("rfilter"), const filter = this.rfilter,
haveFilter = !!filter; haveFilter = !!filter;
for (let key in schema) { for (let key in schema) {
@ -89,7 +93,7 @@ export default Ember.Component.extend({
} else { } else {
// filter the columns // filter the columns
let filterCols = []; let filterCols = [];
schema[key].forEach(function(col) { schema[key].forEach(col => {
if (filter.source === col.column_name) { if (filter.source === col.column_name) {
filterCols.unshift(col); filterCols.unshift(col);
} else if (filter.test(col.column_name)) { } else if (filter.test(col.column_name)) {
@ -108,20 +112,20 @@ export default Ember.Component.extend({
return tables; return tables;
}, },
@observes("filter")
triggerFilter: debounce(function() { triggerFilter: debounce(function() {
this.set( this.set("filteredTables", this.filterTables(this.transformedSchema));
"filteredTables",
this.filterTables(this.get("transformedSchema"))
);
this.set("loading", false); this.set("loading", false);
}, 500).observes("filter"), }, 500),
setLoading: function() { @observes("filter")
setLoading() {
this.set("loading", true); this.set("loading", true);
}.observes("filter"), },
init() { init() {
this._super(); this._super(...arguments);
this.set("loading", true); this.set("loading", true);
this.triggerFilter(); this.triggerFilter();
} }

View File

@ -1,3 +1,4 @@
import { on, observes } from "ember-addons/ember-computed-decorators";
import debounce from "discourse/lib/debounce"; import debounce from "discourse/lib/debounce";
import highlightSyntax from "discourse/lib/highlight-syntax"; import highlightSyntax from "discourse/lib/highlight-syntax";
import { bufferedRender } from "discourse-common/lib/buffered-render"; import { bufferedRender } from "discourse-common/lib/buffered-render";
@ -5,17 +6,19 @@ import { bufferedRender } from "discourse-common/lib/buffered-render";
export default Ember.Component.extend( export default Ember.Component.extend(
bufferedRender({ bufferedRender({
buildBuffer(buffer) { buildBuffer(buffer) {
buffer.push("<pre><code class='" + this.get("codeClass") + "'>"); buffer.push("<pre><code class='" + this.codeClass + "'>");
buffer.push(Handlebars.Utils.escapeExpression(this.get("value"))); buffer.push(Handlebars.Utils.escapeExpression(this.value));
buffer.push("</code></pre>"); buffer.push("</code></pre>");
}, },
@observes("value")
_refreshHighlight: debounce(function() { _refreshHighlight: debounce(function() {
this.rerenderBuffer(); this.rerenderBuffer();
}, 50).observes("value"), }, 50),
_applyHighlight: function() { @on("didInsertElement")
highlightSyntax(this.$()); _applyHighlight() {
}.on("didInsertElement") highlightSyntax($(this.element));
}
}) })
); );

View File

@ -1,3 +1,5 @@
import { default as computed, on, observes } from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({ export default Ember.Component.extend({
fileInput: null, fileInput: null,
loading: false, loading: false,
@ -6,80 +8,77 @@ export default Ember.Component.extend({
classNames: ["json-uploader"], classNames: ["json-uploader"],
_initialize: function() { @on("didInsertElement")
const $this = this.$(); _initialize() {
const self = this; const $this = $(this.element);
const fileInput = this.element.querySelector("#js-file-input");
this.set("fileInput", fileInput);
const $fileInput = $this.find("#js-file-input"); $(fileInput).on("change", () => this.fileSelected(this.files));
this.set("fileInput", $fileInput[0]);
$fileInput.on("change", function() { $this.on("dragover", e => {
self.fileSelected(this.files);
});
$this.on("dragover", function(e) {
if (e.preventDefault) e.preventDefault(); if (e.preventDefault) e.preventDefault();
return false; return false;
}); });
$this.on("dragenter", function(e) { $this.on("dragenter", e => {
if (e.preventDefault) e.preventDefault(); if (e.preventDefault) e.preventDefault();
self.set("hover", self.get("hover") + 1); this.set("hover", this.hover + 1);
return false; return false;
}); });
$this.on("dragleave", function(e) { $this.on("dragleave", e => {
if (e.preventDefault) e.preventDefault(); if (e.preventDefault) e.preventDefault();
self.set("hover", self.get("hover") - 1); this.set("hover", this.hover - 1);
return false; return false;
}); });
$this.on("drop", function(e) { $this.on("drop", e => {
if (e.preventDefault) e.preventDefault(); if (e.preventDefault) e.preventDefault();
self.set("hover", 0); this.set("hover", 0);
self.fileSelected(e.dataTransfer.files); this.fileSelected(e.dataTransfer.files);
return false; return false;
}); });
}.on("didInsertElement"), },
accept: function() { @computed("extension")
accept(extension) {
return ( return (
".json,application/json,application/x-javascript,text/json" + ".json,application/json,application/x-javascript,text/json" +
(this.get("extension") ? "," + this.get("extension") : "") (extension ? `,${extension}` : "")
); );
}.property("extension"), },
setReady: function() { @observes("destination", "expectedRootObjectName")
setReady() {
let parsed; let parsed;
try { try {
parsed = JSON.parse(this.get("value")); parsed = JSON.parse(this.value);
} catch (e) { } catch (e) {
this.set("ready", false); this.set("ready", false);
return; return;
} }
const rootObject = parsed[this.get("expectedRootObjectName")]; const rootObject = parsed[this.expectedRootObjectName];
if (rootObject !== null && rootObject !== undefined) { if (rootObject !== null && rootObject !== undefined) {
this.set("ready", true); this.set("ready", true);
} else { } else {
this.set("ready", false); this.set("ready", false);
} }
}.observes("destination", "expectedRootObjectName"), },
actions: { actions: {
selectFile: function() { selectFile() {
const $fileInput = $(this.get("fileInput")); $(this.fileInput).click();
$fileInput.click();
} }
}, },
fileSelected(fileList) { fileSelected(fileList) {
const self = this;
let files = []; let files = [];
for (let i = 0; i < fileList.length; i++) { for (let i = 0; i < fileList.length; i++) {
files[i] = fileList[i]; files[i] = fileList[i];
} }
const fileNameRegex = /\.(json|txt)$/; const fileNameRegex = /\.(json|txt)$/;
files = files.filter(function(file) { files = files.filter(file => {
if (fileNameRegex.test(file.name)) { if (fileNameRegex.test(file.name)) {
return true; return true;
} }
@ -92,10 +91,9 @@ export default Ember.Component.extend({
this.set("loading", true); this.set("loading", true);
let reader = new FileReader(); const reader = new FileReader();
reader.onload = function(evt) { reader.onload = evt => {
self.set("value", evt.target.result); this.setProperties({ value: evt.target.result, loading: false });
self.set("loading", false);
}; };
reader.readAsText(firstFile); reader.readAsText(firstFile);

View File

@ -1,9 +0,0 @@
export default Ember.TextField.extend({
value: function(key, value) {
if (arguments.length > 1) {
this.get("params")[this.get("pname")] = value;
}
return this.get("params")[this.get("pname")];
}.property("params", "pname")
});

View File

@ -1,4 +1,6 @@
import { default as computed } from "ember-addons/ember-computed-decorators";
// import Category from 'discourse/models/category'; // import Category from 'discourse/models/category';
const Category = Discourse.Category; const Category = Discourse.Category;
const layoutMap = { const layoutMap = {
@ -43,31 +45,29 @@ export default Ember.Component.extend({
value: Ember.computed("params", "info.identifier", { value: Ember.computed("params", "info.identifier", {
get() { get() {
return this.get("params")[this.get("info.identifier")]; return this.params[this.get("info.identifier")];
}, },
set(key, value) { set(key, value) {
this.get("params")[this.get("info.identifier")] = value.toString(); this.params[this.get("info.identifier")] = value.toString();
return value; return value;
} }
}), }),
valueBool: Ember.computed("params", "info.identifier", { valueBool: Ember.computed("params", "info.identifier", {
get() { get() {
return this.get("params")[this.get("info.identifier")] !== "false"; return this.params[this.get("info.identifier")] !== "false";
}, },
set(key, value) { set(key, value) {
value = !!value; value = !!value;
this.get("params")[this.get("info.identifier")] = value.toString(); this.params[this.get("info.identifier")] = value.toString();
return value; return value;
} }
}), }),
valid: function() { @computed("value", "info.type", "info.nullable")
const type = this.get("info.type"), valid(value, type, nullable) {
value = this.get("value"); if (Ember.isEmpty(value)) {
return nullable;
if (Ember.isEmpty(this.get("value"))) {
return this.get("info.nullable");
} }
const intVal = parseInt(value, 10); const intVal = parseInt(value, 10);
@ -88,9 +88,7 @@ export default Ember.Component.extend({
/^(-?)NaN$/i.test(value) /^(-?)NaN$/i.test(value)
); );
case "int_list": case "int_list":
return value.split(",").every(function(i) { return value.split(",").every(i => /^(-?\d+|null)$/.test(i.trim()));
return /^(-?\d+|null)$/.test(i.trim());
});
case "post_id": case "post_id":
return isPositiveInt || /\d+\/\d+(\?u=.*)?$/.test(value); return isPositiveInt || /\d+\/\d+(\?u=.*)?$/.test(value);
case "category_id": case "category_id":
@ -99,9 +97,7 @@ export default Ember.Component.extend({
} }
if (isPositiveInt) { if (isPositiveInt) {
return !!this.site.categories.find(function(c) { return !!this.site.categories.find(c => c.id === intVal);
return c.get("id") === intVal;
});
} else if (/\//.test(value)) { } else if (/\//.test(value)) {
const match = /(.*)\/(.*)/.exec(value); const match = /(.*)\/(.*)/.exec(value);
if (!match) return false; if (!match) return false;
@ -116,30 +112,30 @@ export default Ember.Component.extend({
case "group_id": case "group_id":
const groups = this.site.get("groups"); const groups = this.site.get("groups");
if (isPositiveInt) { if (isPositiveInt) {
return !!groups.find(function(g) { return !!groups.find(g => g.id === intVal);
return g.id === intVal;
});
} else { } else {
return !!groups.find(function(g) { return !!groups.find(g => g.name === value);
return g.name === value;
});
} }
} }
return true; return true;
}.property("value", "info.type", "info.nullable"), },
layoutType: function() { @computed("info.type")
const type = this.get("info.type"); layoutType(type) {
if ((type === "time" || type === "date") && !allowsInputTypeTime()) { if (
(type === "time" || type === "date") &&
!allowsInputTypeTime()
) {
return "string"; return "string";
} }
if (layoutMap[type]) { if (layoutMap[type]) {
return layoutMap[type]; return layoutMap[type];
} }
return "generic"; return "generic";
}.property("info.type"), },
layoutName: function() { @computed("layoutType")
return "admin/components/q-params/" + this.get("layoutType"); layoutName(layoutType) {
}.property("layoutType") return `admin/components/q-params/${layoutType}`;
}
}); });

View File

@ -4,7 +4,7 @@ import { getOwner } from "discourse-common/lib/get-owner";
import { default as computed } from "ember-addons/ember-computed-decorators"; import { default as computed } from "ember-addons/ember-computed-decorators";
function randomIdShort() { function randomIdShort() {
return "xxxxxxxx".replace(/[xy]/g, function() { return "xxxxxxxx".replace(/[xy]/g, () => {
/*eslint-disable*/ /*eslint-disable*/
return ((Math.random() * 16) | 0).toString(16); return ((Math.random() * 16) | 0).toString(16);
/*eslint-enable*/ /*eslint-enable*/
@ -13,7 +13,7 @@ function randomIdShort() {
function transformedRelTable(table, modelClass) { function transformedRelTable(table, modelClass) {
const result = {}; const result = {};
table.forEach(function(item) { table.forEach(item => {
if (modelClass) { if (modelClass) {
result[item.id] = modelClass.create(item); result[item.id] = modelClass.create(item);
} else { } else {
@ -33,7 +33,7 @@ const QueryResultComponent = Ember.Component.extend({
hasExplain: Ember.computed.notEmpty("content.explain"), hasExplain: Ember.computed.notEmpty("content.explain"),
@computed("content.result_count") @computed("content.result_count")
resultCount: function(count) { resultCount(count) {
if (count === this.get("content.default_limit")) { if (count === this.get("content.default_limit")) {
return I18n.t("explorer.max_result_count", { count }); return I18n.t("explorer.max_result_count", { count });
} else { } else {
@ -41,32 +41,32 @@ const QueryResultComponent = Ember.Component.extend({
} }
}, },
colCount: function() { colCount: Ember.computed.reads("content.columns.length"),
return this.get("content.columns").length;
}.property("content.columns.length"),
duration: function() { @computed("content.duration")
duration(contentDuration) {
return I18n.t("explorer.run_time", { return I18n.t("explorer.run_time", {
value: I18n.toNumber(this.get("content.duration"), { precision: 1 }) value: I18n.toNumber(contentDuration, { precision: 1 })
}); });
}.property("content.duration"), },
parameterAry: function() { @computed("params.[]")
parameterAry(params) {
let arr = []; let arr = [];
const params = this.get("params");
for (var key in params) { for (var key in params) {
if (params.hasOwnProperty(key)) { if (params.hasOwnProperty(key)) {
arr.push({ key: key, value: params[key] }); arr.push({ key, value: params[key] });
} }
} }
return arr; return arr;
}.property("params.[]"), },
columnDispNames: function() { @computed("content", "columns.[]")
if (!this.get("columns")) { columnDispNames(content, columns) {
if (!columns) {
return []; return [];
} }
return this.get("columns").map(function(colName) { return columns.map(colName => {
if (colName.endsWith("_id")) { if (colName.endsWith("_id")) {
return colName.slice(0, -3); return colName.slice(0, -3);
} }
@ -76,66 +76,70 @@ const QueryResultComponent = Ember.Component.extend({
} }
return colName; return colName;
}); });
}.property("content", "columns.[]"), },
fallbackTemplate: function() { @computed
fallbackTemplate() {
return getOwner(this).lookup("template:explorer/text.raw"); return getOwner(this).lookup("template:explorer/text.raw");
}.property(), },
columnTemplates: function() { @computed("content", "columns.[]")
const self = this; columnTemplates(content, columns) {
if (!this.get("columns")) { if (!columns) {
return []; return [];
} }
return this.get("columns").map(function(colName, idx) { return columns.map((colName, idx) => {
let viewName = "text"; let viewName = "text";
if (self.get("content.colrender")[idx]) { if (this.get("content.colrender")[idx]) {
viewName = self.get("content.colrender")[idx]; viewName = this.get("content.colrender")[idx];
} }
// After `findRawTemplates` is in stable this should be updated to use that // After `findRawTemplates` is in stable this should be updated to use that
let template = getOwner(self).lookup( let template = getOwner(this).lookup(`template:explorer/${viewName}.raw`);
"template:explorer/" + viewName + ".raw"
);
if (!template) { if (!template) {
template = Discourse.RAW_TEMPLATES[`javascripts/explorer/${viewName}`]; template = Discourse.RAW_TEMPLATES[`javascripts/explorer/${viewName}`];
} }
return { name: viewName, template }; return { name: viewName, template };
}); });
}.property("content", "columns.[]"), },
transformedUserTable: function() { @computed("content.relations.user")
return transformedRelTable(this.get("content.relations.user")); transformedUserTable(contentRelationsUser) {
}.property("content.relations.user"), return transformedRelTable(contentRelationsUser);
transformedBadgeTable: function() { },
return transformedRelTable(this.get("content.relations.badge"), Badge); @computed("content.relations.badge")
}.property("content.relations.badge"), transformedBadgeTable(contentRelationsBadge) {
transformedPostTable: function() { return transformedRelTable(contentRelationsBadge, Badge);
return transformedRelTable(this.get("content.relations.post")); },
}.property("content.relations.post"), @computed("content.relations.post")
transformedTopicTable: function() { transformedPostTable(contentRelationsPost) {
return transformedRelTable(this.get("content.relations.topic")); return transformedRelTable(contentRelationsPost);
}.property("content.relations.topic"), },
@computed("content.relations.topic")
transformedTopicTable(contentRelationsTopic) {
return transformedRelTable(contentRelationsTopic);
},
transformedGroupTable: function() { @computed("site.groups")
return transformedRelTable(this.get("site.groups")); transformedGroupTable(groups) {
}.property("site.groups"), return transformedRelTable(groups);
},
lookupUser(id) { lookupUser(id) {
return this.get("transformedUserTable")[id]; return this.transformedUserTable[id];
}, },
lookupBadge(id) { lookupBadge(id) {
return this.get("transformedBadgeTable")[id]; return this.transformedBadgeTable[id];
}, },
lookupPost(id) { lookupPost(id) {
return this.get("transformedPostTable")[id]; return this.transformedPostTable[id];
}, },
lookupTopic(id) { lookupTopic(id) {
return this.get("transformedTopicTable")[id]; return this.transformedTopicTable[id];
}, },
lookupGroup(id) { lookupGroup(id) {
return this.get("transformedGroupTable")[id]; return this.transformedGroupTable[id];
}, },
lookupCategory(id) { lookupCategory(id) {
@ -175,18 +179,16 @@ const QueryResultComponent = Ember.Component.extend({
form.appendChild(field); form.appendChild(field);
} }
addInput("params", JSON.stringify(this.get("params"))); addInput("params", JSON.stringify(this.params));
addInput("explain", this.get("hasExplain")); addInput("explain", this.hasExplain);
addInput("limit", "1000000"); addInput("limit", "1000000");
ajax("/session/csrf.json").then(function(csrf) { ajax("/session/csrf.json").then(csrf => {
addInput("authenticity_token", csrf.csrf); addInput("authenticity_token", csrf.csrf);
document.body.appendChild(form); document.body.appendChild(form);
form.submit(); form.submit();
Ember.run.next("afterRender", function() { Ember.run.schedule("afterRender", () => document.body.removeChild(form));
document.body.removeChild(form);
});
}); });
}, },

View File

@ -52,17 +52,16 @@ const QueryRowContentComponent = Ember.Component.extend(
tagName: "tr", tagName: "tr",
buildBuffer(buffer) { buildBuffer(buffer) {
const self = this; const row = this.row;
const row = this.get("row"); const parentView = this.parentView;
const parentView = self.get("parentView"); const fallback = this.fallbackTemplate;
const fallback = this.get("fallbackTemplate");
const helpers = { const helpers = {
"icon-or-image": icon_or_image_replacement, "icon-or-image": icon_or_image_replacement,
"category-link": category_badge_replacement, "category-link": category_badge_replacement,
reltime: bound_date_replacement reltime: bound_date_replacement
}; };
const parts = this.get("columnTemplates").map(function(t, idx) { const parts = this.columnTemplates.map((t, idx) => {
const value = row[idx], const value = row[idx],
id = parseInt(value); id = parseInt(value);
@ -108,7 +107,7 @@ const QueryRowContentComponent = Ember.Component.extend(
} }
}); });
buffer.push("<td>" + parts.join("</td><td>") + "</td>"); buffer.push(`<td>${parts.join("</td><td>")}</td>`);
} }
}) })
); );

View File

@ -2,7 +2,10 @@ import showModal from "discourse/lib/show-modal";
import Query from "discourse/plugins/discourse-data-explorer/discourse/models/query"; import Query from "discourse/plugins/discourse-data-explorer/discourse/models/query";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import { default as computed } from "ember-addons/ember-computed-decorators"; import {
default as computed,
observes
} from "ember-addons/ember-computed-decorators";
const NoQuery = Query.create({ name: "No queries", fake: true }); const NoQuery = Query.create({ name: "No queries", fake: true });
@ -28,69 +31,68 @@ export default Ember.Controller.extend({
sortedQueries: Ember.computed.sort("model", "sortBy"), sortedQueries: Ember.computed.sort("model", "sortBy"),
@computed("search", "sortBy") @computed("search", "sortBy")
filteredContent() { filteredContent(search) {
const regexp = new RegExp(this.get("search"), "i"); const regexp = new RegExp(search, "i");
return this.get("sortedQueries").filter(function(result) { return this.sortedQueries.filter(result => {
return ( return regexp.test(result.name) || regexp.test(result.description);
regexp.test(result.get("name")) ||
regexp.test(result.get("description"))
);
}); });
}, },
createDisabled: function() { @computed("newQueryName")
return (this.get("newQueryName") || "").trim().length === 0; createDisabled(newQueryName) {
}.property("newQueryName"), return (newQueryName || "").trim().length === 0;
},
selectedItem: function() { @computed("selectedQueryId")
const id = parseInt(this.get("selectedQueryId")); selectedItem(selectedQueryId) {
const item = this.get("model").find(q => q.get("id") === id); const id = parseInt(selectedQueryId);
const item = this.model.find(q => q.id === id);
!isNaN(id) !isNaN(id)
? this.set("showRecentQueries", false) ? this.set("showRecentQueries", false)
: this.set("showRecentQueries", true); : this.set("showRecentQueries", true);
if (id < 0) this.set("editDisabled", true); if (id < 0) this.set("editDisabled", true);
return item || NoQuery; return item || NoQuery;
}.property("selectedQueryId"), },
othersDirty: function() { @computed("selectedItem", "selectedItem.dirty")
const selected = this.get("selectedItem"); othersDirty(selectedItem) {
return !!this.get("model").find(q => q !== selected && q.get("dirty")); return !!this.model.find(q => q !== selectedItem && q.dirty);
}.property("selectedItem", "selectedItem.dirty"), },
setEverEditing: function() { @observes("editing")
if (this.get("editing") && !this.get("everEditing")) { setEverEditing() {
if (this.editing && !this.everEditing) {
this.set("everEditing", true); this.set("everEditing", true);
} }
}.observes("editing"), },
addCreatedRecord(record) { addCreatedRecord(record) {
this.get("model").pushObject(record); this.model.pushObject(record);
this.set("selectedQueryId", Ember.get(record, "id")); this.set("selectedQueryId", Ember.get(record, "id"));
this.get("selectedItem").set("dirty", false); this.selectedItem.set("dirty", false);
this.set("showResults", false); this.setProperties({
this.set("results", null); showResults: false,
this.set("editing", true); results: null,
editing: true
});
}, },
save() { save() {
const self = this;
this.set("loading", true); this.set("loading", true);
if (this.get("selectedItem.description") === "") if (this.get("selectedItem.description") === "")
this.set("selectedItem.description", ""); this.set("selectedItem.description", "");
return this.get("selectedItem") return this.selectedItem
.save() .save()
.then(function() { .then(() => {
const query = self.get("selectedItem"); const query = this.selectedItem;
query.markNotDirty(); query.markNotDirty();
self.set("editing", false); this.set("editing", false);
}) })
.catch(function(x) { .catch(x => {
popupAjaxError(x); popupAjaxError(x);
throw x; throw x;
}) })
.finally(function() { .finally(() => this.set("loading", false));
self.set("loading", false);
});
}, },
actions: { actions: {
@ -119,8 +121,7 @@ export default Ember.Controller.extend({
scrollTop() { scrollTop() {
window.scrollTo(0, 0); window.scrollTo(0, 0);
this.set("editing", false); this.setProperties({ editing: false, everEditing: false });
this.set("everEditing", false);
}, },
goHome() { goHome() {
@ -137,11 +138,11 @@ export default Ember.Controller.extend({
}, },
resetParams() { resetParams() {
this.get("selectedItem").resetParams(); this.selectedItem.resetParams();
}, },
saveDefaults() { saveDefaults() {
this.get("selectedItem").saveDefaults(); this.selectedItem.saveDefaults();
}, },
save() { save() {
@ -161,10 +162,12 @@ export default Ember.Controller.extend({
}, },
create() { create() {
const name = this.get("newQueryName").trim(); const name = this.newQueryName.trim();
this.set("loading", true); this.setProperties({
this.set("showCreate", false); loading: true,
this.set("showRecentQueries", false); showCreate: false,
showRecentQueries: false
});
this.store this.store
.createRecord("query", { name }) .createRecord("query", { name })
.save() .save()
@ -174,65 +177,50 @@ export default Ember.Controller.extend({
}, },
discard() { discard() {
const self = this;
this.set("loading", true); this.set("loading", true);
this.store this.store
.find("query", this.get("selectedItem.id")) .find("query", this.get("selectedItem.id"))
.then(function(result) { .then(result => {
const query = self.get("selectedItem"); const query = this.get("selectedItem");
query.setProperties(result.getProperties(Query.updatePropertyNames)); query.setProperties(result.getProperties(Query.updatePropertyNames));
query.markNotDirty(); query.markNotDirty();
self.set("editing", false); this.set("editing", false);
}) })
.catch(popupAjaxError) .catch(popupAjaxError)
.finally(function() { .finally(() => this.set("loading", false));
self.set("loading", false);
});
}, },
destroy() { destroy() {
const self = this; const query = this.selectedItem;
const query = this.get("selectedItem"); this.setProperties({ loading: true, showResults: false });
this.set("loading", true);
this.set("showResults", false);
this.store this.store
.destroyRecord("query", query) .destroyRecord("query", query)
.then(function() { .then(() => query.set("destroyed", true))
query.set("destroyed", true);
})
.catch(popupAjaxError) .catch(popupAjaxError)
.finally(function() { .finally(() => this.set("loading", false));
self.set("loading", false);
});
}, },
recover() { recover() {
const self = this; const query = this.selectedItem;
const query = this.get("selectedItem"); this.setProperties({ loading: true, showResults: true });
this.set("loading", true);
this.set("showResults", true);
query query
.save() .save()
.then(function() { .then(() => query.set("destroyed", false))
query.set("destroyed", false);
})
.catch(popupAjaxError) .catch(popupAjaxError)
.finally(function() { .finally(() => {
self.set("loading", false); this.set("loading", false);
}); });
}, },
run() { run() {
const self = this;
if (this.get("selectedItem.dirty")) { if (this.get("selectedItem.dirty")) {
return; return;
} }
if (this.get("runDisabled")) { if (this.runDisabled) {
return; return;
} }
this.set("loading", true); this.setProperties({ loading: true, showResults: false });
this.set("showResults", false);
ajax( ajax(
"/admin/plugins/explorer/queries/" + "/admin/plugins/explorer/queries/" +
this.get("selectedItem.id") + this.get("selectedItem.id") +
@ -241,30 +229,28 @@ export default Ember.Controller.extend({
type: "POST", type: "POST",
data: { data: {
params: JSON.stringify(this.get("selectedItem.params")), params: JSON.stringify(this.get("selectedItem.params")),
explain: this.get("explain") explain: this.explain
} }
} }
) )
.then(function(result) { .then(result => {
self.set("results", result); this.set("results", result);
if (!result.success) { if (!result.success) {
self.set("showResults", false); this.set("showResults", false);
return; return;
} }
self.set("showResults", true); this.set("showResults", true);
}) })
.catch(function(err) { .catch(err => {
self.set("showResults", false); this.set("showResults", false);
if (err.jqXHR && err.jqXHR.status === 422 && err.jqXHR.responseJSON) { if (err.jqXHR && err.jqXHR.status === 422 && err.jqXHR.responseJSON) {
self.set("results", err.jqXHR.responseJSON); this.set("results", err.jqXHR.responseJSON);
} else { } else {
popupAjaxError(err); popupAjaxError(err);
} }
}) })
.finally(function() { .finally(() => this.set("loading", false));
self.set("loading", false);
});
} }
} }
}); });

View File

@ -1,3 +1,4 @@
import { default as computed } from "ember-addons/ember-computed-decorators";
import ModalFunctionality from "discourse/mixins/modal-functionality"; import ModalFunctionality from "discourse/mixins/modal-functionality";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
@ -6,21 +7,21 @@ export default Ember.Controller.extend(ModalFunctionality, {
adminPluginsExplorer: Ember.inject.controller(), adminPluginsExplorer: Ember.inject.controller(),
ready: function() { @computed("queryFile")
ready(queryFile) {
let parsed; let parsed;
try { try {
parsed = JSON.parse(this.get("queryFile")); parsed = JSON.parse(queryFile);
} catch (e) { } catch (e) {
return false; return false;
} }
return !!parsed["query"]; return !!parsed["query"];
}.property("queryFile"), },
actions: { actions: {
doImport: function() { doImport() {
const self = this; const object = JSON.parse(this.queryFile).query;
const object = JSON.parse(this.get("queryFile")).query;
// Slight fixup before creating object // Slight fixup before creating object
object.id = 0; // 0 means no Id yet object.id = 0; // 0 means no Id yet
@ -29,11 +30,11 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.store this.store
.createRecord("query", object) .createRecord("query", object)
.save() .save()
.then(function(query) { .then(query => {
self.send("closeModal"); this.send("closeModal");
self.set("loading", false); this.set("loading", false);
const parentController = self.get("adminPluginsExplorer"); const parentController = this.adminPluginsExplorer;
parentController.addCreatedRecord(query.target); parentController.addCreatedRecord(query.target);
}) })
.catch(popupAjaxError); .catch(popupAjaxError);

View File

@ -6,12 +6,12 @@ export default {
if (!String.prototype.endsWith) { if (!String.prototype.endsWith) {
// eslint-disable-next-line no-extend-native // eslint-disable-next-line no-extend-native
String.prototype.endsWith = function(searchString, position) { String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString(); const subjectString = this.toString();
if (position === undefined || position > subjectString.length) { if (position === undefined || position > subjectString.length) {
position = subjectString.length; position = subjectString.length;
} }
position -= searchString.length; position -= searchString.length;
var lastIndex = subjectString.indexOf(searchString, position); const lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position; return lastIndex !== -1 && lastIndex === position;
}; };
} }

View File

@ -4,10 +4,10 @@
// Modified for use in Discourse // Modified for use in Discourse
export default function binarySearch(list, target, keyProp) { export default function binarySearch(list, target, keyProp) {
var min = 0; let min = 0;
var max = list.length - 1; let max = list.length - 1;
var guess; let guess;
var keyProperty = keyProp || "id"; const keyProperty = keyProp || "id";
while (min <= max) { while (min <= max) {
guess = Math.floor((min + max) / 2); guess = Math.floor((min + max) / 2);

View File

@ -1,3 +1,8 @@
import {
default as computed,
on,
observes
} from "ember-addons/ember-computed-decorators";
import RestModel from "discourse/models/rest"; import RestModel from "discourse/models/rest";
const Query = RestModel.extend({ const Query = RestModel.extend({
@ -5,34 +10,35 @@ const Query = RestModel.extend({
params: {}, params: {},
results: null, results: null,
_init: function() { @on("init")
this._super(); _init() {
this._super(...arguments);
this.set("dirty", false); this.set("dirty", false);
}.on("init"), },
_initParams: function() { @on("init")
@observes("param_info")
_initParams() {
this.resetParams(); this.resetParams();
} },
.on("init")
.observes("param_info"),
markDirty: function() { @observes("name", "description", "sql")
markDirty() {
this.set("dirty", true); this.set("dirty", true);
}.observes("name", "description", "sql"), },
markNotDirty() { markNotDirty() {
this.set("dirty", false); this.set("dirty", false);
}, },
hasParams: function() { hasParams: Ember.computed.reads("param_info.length"),
return this.get("param_info.length") > 0;
}.property("param_info"),
resetParams() { resetParams() {
const newParams = {}; const newParams = {};
const oldParams = this.get("params"); const oldParams = this.params;
const paramInfo = this.get("param_info") || []; const paramInfo = this.param_info || [];
paramInfo.forEach(function(pinfo) { paramInfo.forEach(pinfo => {
const name = pinfo.identifier; const name = pinfo.identifier;
if (oldParams[pinfo.identifier]) { if (oldParams[pinfo.identifier]) {
newParams[name] = oldParams[name]; newParams[name] = oldParams[name];
@ -47,15 +53,16 @@ const Query = RestModel.extend({
this.set("params", newParams); this.set("params", newParams);
}, },
downloadUrl: function() { @computed("id")
downloadUrl(id) {
// TODO - can we change this to use the store/adapter? // TODO - can we change this to use the store/adapter?
return Discourse.getURL( return Discourse.getURL(
"/admin/plugins/explorer/queries/" + this.get("id") + ".json?export=1" `/admin/plugins/explorer/queries/${id}.json?export=1`
); );
}.property("id"), },
createProperties() { createProperties() {
if (this.get("sql")) { if (this.sql) {
// Importing // Importing
return this.updateProperties(); return this.updateProperties();
} }
@ -63,9 +70,9 @@ const Query = RestModel.extend({
}, },
updateProperties() { updateProperties() {
let props = this.getProperties(Query.updatePropertyNames); const props = this.getProperties(Query.updatePropertyNames);
if (this.get("destroyed")) { if (this.destroyed) {
props.id = this.get("id"); props.id = this.id;
} }
return props; return props;
} }

View File

@ -20,12 +20,12 @@ export default Discourse.Route.extend({
}); });
}, },
setupController: function(controller, model) { setupController(controller, model) {
controller.setProperties(model); controller.setProperties(model);
}, },
actions: { actions: {
refreshModel: function() { refreshModel() {
this.refresh(); this.refresh();
return false; return false;
} }

View File

@ -43,7 +43,7 @@
{{d-button action=(action "goHome") icon="chevron-left" class="previous"}} {{d-button action=(action "goHome") icon="chevron-left" class="previous"}}
<h1>{{selectedItem.name}} <h1>{{selectedItem.name}}
{{#unless editDisabled}} {{#unless editDisabled}}
<a {{action "editName" class="edit-query-name"}}>{{d-icon "pencil"}}</a> <a {{action "editName" class="edit-query-name"}}>{{d-icon "pencil-alt"}}</a>
{{/unless}} {{/unless}}
</h1> </h1>
</div> </div>
@ -86,7 +86,7 @@
{{d-button action=(action "save") label="explorer.save" disabled=saveDisable}} {{d-button action=(action "save") label="explorer.save" disabled=saveDisable}}
{{else}} {{else}}
{{#unless editDisabled}} {{#unless editDisabled}}
{{d-button action=(action "editName") label="explorer.edit" icon="pencil"}} {{d-button action=(action "editName") label="explorer.edit" icon="pencil-alt"}}
{{/unless}} {{/unless}}
{{/if}} {{/if}}
{{d-button action=(action "download") label="explorer.export" disabled=runDisabled icon="download"}} {{d-button action=(action "download") label="explorer.export" disabled=runDisabled icon="download"}}
@ -99,7 +99,7 @@
{{d-button action=(action "discard") icon="undo" label="explorer.undo" disabled=saveDisabled}} {{d-button action=(action "discard") icon="undo" label="explorer.undo" disabled=saveDisabled}}
{{/if}} {{/if}}
{{#unless editDisabled}} {{#unless editDisabled}}
{{d-button action=(action "destroy") class="btn-danger" icon="trash" label="explorer.delete"}} {{d-button action=(action "destroy") class="btn-danger" icon="trash-alt" label="explorer.delete"}}
{{/unless}} {{/unless}}
{{/if}} {{/if}}
</div> </div>
@ -112,10 +112,6 @@
<div class="query-params"> <div class="query-params">
{{#each selectedItem.param_info as |pinfo|}} {{#each selectedItem.param_info as |pinfo|}}
{{param-input params=selectedItem.params info=pinfo}} {{param-input params=selectedItem.params info=pinfo}}
{{! <div class="param">
{{param-field params=selectedItem.params pname=pinfo.identifier type=pinfo.type}
<span class="param-name">{{pinfo.identifier}</span>
</div> }}
{{/each}} {{/each}}
</div> </div>
{{/if}} {{/if}}