run Prettier

This commit is contained in:
Rishabh Nambiar 2018-10-10 17:26:23 +05:30
parent b352e747c7
commit 9d7db064af
18 changed files with 543 additions and 460 deletions

View File

@ -1,5 +1,3 @@
import buildPluginAdapter from 'admin/adapters/build-plugin'; import buildPluginAdapter from "admin/adapters/build-plugin";
export default buildPluginAdapter('explorer').extend({ export default buildPluginAdapter("explorer").extend({});
});

View File

@ -1,61 +1,60 @@
import { observes } from 'ember-addons/ember-computed-decorators'; import { observes } from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({ export default Ember.Component.extend({
@observes("hideSchema")
@observes('hideSchema')
_onHideSchema() { _onHideSchema() {
this.appEvents.trigger('ace:resize'); this.appEvents.trigger("ace:resize");
}, },
@observes('everEditing') @observes("everEditing")
_onInsertEditor() { _onInsertEditor() {
Ember.run.schedule('afterRender', this, () => this._bindControls()); Ember.run.schedule("afterRender", this, () => this._bindControls());
}, },
_bindControls() { _bindControls() {
if (this._state !== "inDOM") { if (this._state !== "inDOM") {
return; return;
} }
const $editPane = this.$().find('.query-editor'); const $editPane = this.$().find(".query-editor");
if (!$editPane.length) { if (!$editPane.length) {
return; return;
} }
const oldGrippie = this.get('grippie'); const oldGrippie = this.get("grippie");
if (oldGrippie) { if (oldGrippie) {
oldGrippie.off('mousedown mousemove mouseup'); oldGrippie.off("mousedown mousemove mouseup");
$editPane.off('mousemove mouseup'); $editPane.off("mousemove mouseup");
} }
const $grippie = $editPane.find('.grippie'); const $grippie = $editPane.find(".grippie");
const $targets = $editPane.find('.ace-wrapper,.grippie-target'); const $targets = $editPane.find(".ace-wrapper,.grippie-target");
const $body = $('body'); const $body = $("body");
const self = this; const self = this;
this.set('grippie', $grippie); this.set("grippie", $grippie);
const mousemove = function(e) { const mousemove = function(e) {
const diff = self.get('startY') - e.screenY; const diff = self.get("startY") - e.screenY;
const newHeight = self.get('startSize') - diff; const newHeight = self.get("startSize") - diff;
//Em.Logger.debug("new height", newHeight); //Em.Logger.debug("new height", newHeight);
$targets.height(newHeight); $targets.height(newHeight);
self.appEvents.trigger('ace:resize'); self.appEvents.trigger("ace:resize");
}; };
let mouseup; let mouseup;
mouseup = function(e) { mouseup = function(e) {
mousemove(e); mousemove(e);
$body.off('mousemove', mousemove); $body.off("mousemove", mousemove);
$body.off('mouseup', mouseup); $body.off("mouseup", mouseup);
self.set('startY', null); self.set("startY", null);
self.set('startSize', null); self.set("startSize", null);
}; };
$grippie.on('mousedown', function(e) { $grippie.on("mousedown", function(e) {
self.set('startY', e.screenY); self.set("startY", e.screenY);
self.set('startSize', $targets.height()); self.set("startSize", $targets.height());
$body.on('mousemove', mousemove); $body.on("mousemove", mousemove);
$body.on('mouseup', mouseup); $body.on("mouseup", mouseup);
e.preventDefault(); e.preventDefault();
}); });
}, },
@ -67,10 +66,9 @@ export default Ember.Component.extend({
willDestroyElement() { willDestroyElement() {
this._super(); this._super();
if (this.get('everEditing')) { if (this.get("everEditing")) {
this.get('grippie').off('mousedown'); this.get("grippie").off("mousedown");
this.set('grippie', null); this.set("grippie", null);
} }
} }
}); });

View File

@ -1,13 +1,15 @@
export default Ember.Component.extend({ export default Ember.Component.extend({
tagName: 'ol', tagName: "ol",
enuminfo: function() { enuminfo: function() {
const hash = this.get('col.enum'); const hash = this.get("col.enum");
let result = []; let result = [];
for (let key in hash) { for (let key in hash) {
if (!hash.hasOwnProperty(key)) { continue; } if (!hash.hasOwnProperty(key)) {
result.push({value: key, name: hash[key]}); continue;
}
result.push({ value: key, name: hash[key] });
} }
return result; return result;
}.property('col.enum') }.property("col.enum")
}); });

View File

@ -1,18 +1,22 @@
export default Ember.Component.extend({ export default Ember.Component.extend({
classNameBindings: [':schema-table', 'open'], classNameBindings: [":schema-table", "open"],
tagName: 'li', tagName: "li",
open: Em.computed.alias('table.open'), open: Em.computed.alias("table.open"),
_bindClicks: function() { _bindClicks: function() {
const self = this; const self = this;
this.$().find('.schema-table-name').click(function(e) { this.$()
self.set('open', !self.get('open')); .find(".schema-table-name")
e.preventDefault(); .click(function(e) {
}); self.set("open", !self.get("open"));
}.on('didInsertElement'), e.preventDefault();
});
}.on("didInsertElement"),
_cleanup: function() { _cleanup: function() {
this.$().find('.schema-table-name').off('click'); this.$()
}.on('willDestroyElement') .find(".schema-table-name")
.off("click");
}.on("willDestroyElement")
}); });

View File

@ -1,18 +1,17 @@
import debounce from 'discourse/lib/debounce'; import debounce from "discourse/lib/debounce";
export default Ember.Component.extend({ export default Ember.Component.extend({
actions: { actions: {
expandSchema() { expandSchema() {
this.set('hideSchema', false); this.set("hideSchema", false);
}, },
collapseSchema() { collapseSchema() {
this.set('hideSchema', true); this.set("hideSchema", true);
} }
}, },
transformedSchema: function() { transformedSchema: function() {
const schema = this.get('schema'); const schema = this.get("schema");
for (let key in schema) { for (let key in schema) {
if (!schema.hasOwnProperty(key)) { if (!schema.hasOwnProperty(key)) {
@ -47,21 +46,20 @@ export default Ember.Component.extend({
} }
col.havetypeinfo = !!(col.notes || col.enum || col.column_desc); col.havetypeinfo = !!(col.notes || col.enum || col.column_desc);
}); });
} }
return schema; return schema;
}.property('schema'), }.property("schema"),
rfilter: function() { rfilter: function() {
if (!Em.isBlank(this.get('filter'))) { if (!Em.isBlank(this.get("filter"))) {
return new RegExp(this.get('filter')); return new RegExp(this.get("filter"));
} }
}.property('filter'), }.property("filter"),
filterTables: function(schema) { filterTables: function(schema) {
let tables = []; let tables = [];
const filter = this.get('rfilter'), const filter = this.get("rfilter"),
haveFilter = !!filter; haveFilter = !!filter;
for (let key in schema) { for (let key in schema) {
@ -114,17 +112,20 @@ export default Ember.Component.extend({
}, },
triggerFilter: debounce(function() { triggerFilter: debounce(function() {
this.set('filteredTables', this.filterTables(this.get('transformedSchema'))); this.set(
this.set('loading', false); "filteredTables",
}, 500).observes('filter'), this.filterTables(this.get("transformedSchema"))
);
this.set("loading", false);
}, 500).observes("filter"),
setLoading: function() { setLoading: function() {
this.set('loading', true); this.set("loading", true);
}.observes('filter'), }.observes("filter"),
init() { init() {
this._super(); this._super();
this.set('loading', true); this.set("loading", true);
this.triggerFilter(); this.triggerFilter();
} }
}); });

View File

@ -1,19 +1,21 @@
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";
export default Ember.Component.extend(bufferedRender({ export default Ember.Component.extend(
buildBuffer(buffer) { bufferedRender({
buffer.push("<pre><code class='" + this.get('codeClass') + "'>"); buildBuffer(buffer) {
buffer.push(Handlebars.Utils.escapeExpression(this.get('value'))); buffer.push("<pre><code class='" + this.get("codeClass") + "'>");
buffer.push("</code></pre>"); buffer.push(Handlebars.Utils.escapeExpression(this.get("value")));
}, buffer.push("</code></pre>");
},
_refreshHighlight: debounce(function() { _refreshHighlight: debounce(function() {
this.rerenderBuffer(); this.rerenderBuffer();
}, 50).observes('value'), }, 50).observes("value"),
_applyHighlight: function() { _applyHighlight: function() {
highlightSyntax(this.$()); highlightSyntax(this.$());
}.on('didInsertElement') }.on("didInsertElement")
})); })
);

View File

@ -4,68 +4,70 @@ export default Ember.Component.extend({
expectedRootObjectName: null, expectedRootObjectName: null,
hover: 0, hover: 0,
classNames: ['json-uploader'], classNames: ["json-uploader"],
_initialize: function() { _initialize: function() {
const $this = this.$(); const $this = this.$();
const self = this; const self = this;
const $fileInput = $this.find('#js-file-input'); const $fileInput = $this.find("#js-file-input");
this.set('fileInput', $fileInput[0]); this.set("fileInput", $fileInput[0]);
$fileInput.on('change', function() { $fileInput.on("change", function() {
self.fileSelected(this.files); self.fileSelected(this.files);
}); });
$this.on('dragover', function(e) { $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", function(e) {
if (e.preventDefault) e.preventDefault(); if (e.preventDefault) e.preventDefault();
self.set('hover', self.get('hover') + 1); self.set("hover", self.get("hover") + 1);
return false; return false;
}); });
$this.on('dragleave', function(e) { $this.on("dragleave", function(e) {
if (e.preventDefault) e.preventDefault(); if (e.preventDefault) e.preventDefault();
self.set('hover', self.get('hover') - 1); self.set("hover", self.get("hover") - 1);
return false; return false;
}); });
$this.on('drop', function(e) { $this.on("drop", function(e) {
if (e.preventDefault) e.preventDefault(); if (e.preventDefault) e.preventDefault();
self.set('hover', 0); self.set("hover", 0);
self.fileSelected(e.dataTransfer.files); self.fileSelected(e.dataTransfer.files);
return false; return false;
}); });
}.on("didInsertElement"),
}.on('didInsertElement'),
accept: function() { accept: function() {
return ".json,application/json,application/x-javascript,text/json" + (this.get('extension') ? "," + this.get('extension') : ""); return (
}.property('extension'), ".json,application/json,application/x-javascript,text/json" +
(this.get("extension") ? "," + this.get("extension") : "")
);
}.property("extension"),
setReady: function() { setReady: function() {
let parsed; let parsed;
try { try {
parsed = JSON.parse(this.get('value')); parsed = JSON.parse(this.get("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.get("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'), }.observes("destination", "expectedRootObjectName"),
actions: { actions: {
selectFile: function() { selectFile: function() {
const $fileInput = $(this.get('fileInput')); const $fileInput = $(this.get("fileInput"));
$fileInput.click(); $fileInput.click();
} }
}, },
@ -88,15 +90,14 @@ export default Ember.Component.extend({
}); });
const firstFile = fileList[0]; const firstFile = fileList[0];
this.set('loading', true); this.set("loading", true);
let reader = new FileReader(); let reader = new FileReader();
reader.onload = function(evt) { reader.onload = function(evt) {
self.set('value', evt.target.result); self.set("value", evt.target.result);
self.set('loading', false); self.set("loading", false);
}; };
reader.readAsText(firstFile); reader.readAsText(firstFile);
} }
}); });

View File

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

View File

@ -2,30 +2,30 @@
const Category = Discourse.Category; const Category = Discourse.Category;
const layoutMap = { const layoutMap = {
int: 'int', int: "int",
bigint: 'int', bigint: "int",
boolean: 'boolean', boolean: "boolean",
string: 'generic', string: "generic",
time: 'generic', time: "generic",
date: 'generic', date: "generic",
datetime: 'generic', datetime: "generic",
double: 'string', double: "string",
user_id: 'user_id', user_id: "user_id",
post_id: 'string', post_id: "string",
topic_id: 'generic', topic_id: "generic",
category_id: 'generic', category_id: "generic",
group_id: 'generic', group_id: "generic",
badge_id: 'generic', badge_id: "generic",
int_list: 'generic', int_list: "generic",
string_list: 'generic', string_list: "generic",
user_list: 'user_list' user_list: "user_list"
}; };
function allowsInputTypeTime() { function allowsInputTypeTime() {
try { try {
const inp = document.createElement('input'); const inp = document.createElement("input");
inp.attributes.type = 'time'; inp.attributes.type = "time";
inp.attributes.type = 'date'; inp.attributes.type = "date";
return true; return true;
} catch (e) { } catch (e) {
return false; return false;
@ -33,77 +33,88 @@ function allowsInputTypeTime() {
} }
export default Ember.Component.extend({ export default Ember.Component.extend({
classNameBindings: ["valid:valid:invalid", ":param"],
classNameBindings: ['valid:valid:invalid', ':param'], boolTypes: [
{ name: I18n.t("explorer.types.bool.true"), id: "Y" },
{ name: I18n.t("explorer.types.bool.false"), id: "N" },
{ name: I18n.t("explorer.types.bool.null_"), id: "#null" }
],
boolTypes: [ {name: I18n.t('explorer.types.bool.true'), id: 'Y'}, {name: I18n.t('explorer.types.bool.false'), id: 'N'}, {name: I18n.t('explorer.types.bool.null_'), id: '#null'} ], value: Ember.computed("params", "info.identifier", {
value: Ember.computed('params', 'info.identifier', {
get() { get() {
return this.get('params')[this.get('info.identifier')]; return this.get("params")[this.get("info.identifier")];
}, },
set(key, value) { set(key, value) {
this.get('params')[this.get('info.identifier')] = value.toString(); this.get("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.get("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.get("params")[this.get("info.identifier")] = value.toString();
return value; return value;
} }
}), }),
valid: function() { valid: function() {
const type = this.get('info.type'), const type = this.get("info.type"),
value = this.get('value'); value = this.get("value");
if (Em.isEmpty(this.get('value'))) { if (Em.isEmpty(this.get("value"))) {
return this.get('info.nullable'); return this.get("info.nullable");
} }
const intVal = parseInt(value, 10); const intVal = parseInt(value, 10);
const intValid = !isNaN(intVal) && intVal < 2147483648 && intVal > -2147483649; const intValid =
!isNaN(intVal) && intVal < 2147483648 && intVal > -2147483649;
const isPositiveInt = /^\d+$/.test(value); const isPositiveInt = /^\d+$/.test(value);
switch (type) { switch (type) {
case 'int': case "int":
return /^-?\d+$/.test(value) && intValid; return /^-?\d+$/.test(value) && intValid;
case 'bigint': case "bigint":
return /^-?\d+$/.test(value) && !isNaN(intVal); return /^-?\d+$/.test(value) && !isNaN(intVal);
case 'boolean': case "boolean":
return /^Y|N|#null|true|false/.test(value); return /^Y|N|#null|true|false/.test(value);
case 'double': case "double":
return !isNaN(parseFloat(value)) || /^(-?)Inf(inity)?$/i.test(value) || /^(-?)NaN$/i.test(value); return (
case 'int_list': !isNaN(parseFloat(value)) ||
return value.split(',').every(function(i) { /^(-?)Inf(inity)?$/i.test(value) ||
/^(-?)NaN$/i.test(value)
);
case "int_list":
return value.split(",").every(function(i) {
return /^(-?\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":
if (!isPositiveInt && value !== value.dasherize()) { if (!isPositiveInt && value !== value.dasherize()) {
this.set('value', value.dasherize()); this.set("value", value.dasherize());
} }
if (isPositiveInt) { if (isPositiveInt) {
return !!this.site.categories.find(function(c) { return !!this.site.categories.find(function(c) {
return c.get('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;
const result = Category.findBySlug(match[2].dasherize(), match[1].dasherize()); const result = Category.findBySlug(
match[2].dasherize(),
match[1].dasherize()
);
return !!result; return !!result;
} else { } else {
return !!Category.findBySlug(value.dasherize()); return !!Category.findBySlug(value.dasherize());
} }
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(function(g) {
return g.id === intVal; return g.id === intVal;
@ -115,20 +126,20 @@ export default Ember.Component.extend({
} }
} }
return true; return true;
}.property('value', 'info.type', 'info.nullable'), }.property("value", "info.type", "info.nullable"),
layoutType: function() { layoutType: function() {
const type = this.get('info.type'); const type = this.get("info.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'), }.property("info.type"),
layoutName: function() { layoutName: function() {
return "admin/components/q-params/" + this.get('layoutType'); return "admin/components/q-params/" + this.get("layoutType");
}.property('layoutType') }.property("layoutType")
}); });

View File

@ -1,12 +1,12 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from "discourse/lib/ajax";
import Badge from 'discourse/models/badge'; import Badge from "discourse/models/badge";
import { getOwner } from 'discourse-common/lib/get-owner'; 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, function() {
/*eslint-disable*/ /*eslint-disable*/
return (Math.random() * 16 | 0).toString(16); return ((Math.random() * 16) | 0).toString(16);
/*eslint-enable*/ /*eslint-enable*/
}); });
} }
@ -24,153 +24,167 @@ function transformedRelTable(table, modelClass) {
} }
const QueryResultComponent = Ember.Component.extend({ const QueryResultComponent = Ember.Component.extend({
layoutName: 'explorer-query-result', layoutName: "explorer-query-result",
rows: Em.computed.alias('content.rows'), rows: Em.computed.alias("content.rows"),
columns: Em.computed.alias('content.columns'), columns: Em.computed.alias("content.columns"),
params: Em.computed.alias('content.params'), params: Em.computed.alias("content.params"),
explainText: Em.computed.alias('content.explain'), explainText: Em.computed.alias("content.explain"),
hasExplain: Em.computed.notEmpty('content.explain'), hasExplain: Em.computed.notEmpty("content.explain"),
@computed('content.result_count') @computed("content.result_count")
resultCount: function(count) { resultCount: function(count) {
if (count === 1000) { if (count === 1000) {
return I18n.t('explorer.max_result_count', { count }); return I18n.t("explorer.max_result_count", { count });
} else { } else {
return I18n.t('explorer.result_count', { count }); return I18n.t("explorer.result_count", { count });
} }
}, },
colCount: function() { colCount: function() {
return this.get('content.columns').length; return this.get("content.columns").length;
}.property('content.columns.length'), }.property("content.columns.length"),
duration: function() { duration: function() {
return I18n.t('explorer.run_time', {value: I18n.toNumber(this.get('content.duration'), {precision: 1})}); return I18n.t("explorer.run_time", {
}.property('content.duration'), value: I18n.toNumber(this.get("content.duration"), { precision: 1 })
});
}.property("content.duration"),
parameterAry: function() { parameterAry: function() {
let arr = []; let arr = [];
const params = this.get('params'); 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: key, value: params[key] });
} }
} }
return arr; return arr;
}.property('params.@each'), }.property("params.@each"),
columnDispNames: function() { columnDispNames: function() {
if (!this.get('columns')) { if (!this.get("columns")) {
return []; return [];
} }
return this.get('columns').map(function(colName) { return this.get("columns").map(function(colName) {
if (colName.endsWith("_id")) { if (colName.endsWith("_id")) {
return colName.slice(0, -3); return colName.slice(0, -3);
} }
const dIdx = colName.indexOf('$'); const dIdx = colName.indexOf("$");
if (dIdx >= 0) { if (dIdx >= 0) {
return colName.substring(dIdx + 1); return colName.substring(dIdx + 1);
} }
return colName; return colName;
}); });
}.property('content', 'columns.@each'), }.property("content", "columns.@each"),
fallbackTemplate: function() { fallbackTemplate: function() {
return getOwner(this).lookup('template:explorer/text.raw'); return getOwner(this).lookup("template:explorer/text.raw");
}.property(), }.property(),
columnTemplates: function() { columnTemplates: function() {
const self = this; const self = this;
if (!this.get('columns')) { if (!this.get("columns")) {
return []; return [];
} }
return this.get('columns').map(function(colName, idx) { return this.get("columns").map(function(colName, idx) {
let viewName = "text"; let viewName = "text";
if (self.get('content.colrender')[idx]) { if (self.get("content.colrender")[idx]) {
viewName = self.get('content.colrender')[idx]; viewName = self.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('template:explorer/' + viewName + '.raw'); let template = getOwner(self).lookup(
"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.@each'), }.property("content", "columns.@each"),
transformedUserTable: function() { transformedUserTable: function() {
return transformedRelTable(this.get('content.relations.user')); return transformedRelTable(this.get("content.relations.user"));
}.property('content.relations.user'), }.property("content.relations.user"),
transformedBadgeTable: function() { transformedBadgeTable: function() {
return transformedRelTable(this.get('content.relations.badge'), Badge); return transformedRelTable(this.get("content.relations.badge"), Badge);
}.property('content.relations.badge'), }.property("content.relations.badge"),
transformedPostTable: function() { transformedPostTable: function() {
return transformedRelTable(this.get('content.relations.post')); return transformedRelTable(this.get("content.relations.post"));
}.property('content.relations.post'), }.property("content.relations.post"),
transformedTopicTable: function() { transformedTopicTable: function() {
return transformedRelTable(this.get('content.relations.topic')); return transformedRelTable(this.get("content.relations.topic"));
}.property('content.relations.topic'), }.property("content.relations.topic"),
transformedGroupTable: function() { transformedGroupTable: function() {
return transformedRelTable(this.get('site.groups')); return transformedRelTable(this.get("site.groups"));
}.property('site.groups'), }.property("site.groups"),
lookupUser(id) { lookupUser(id) {
return this.get('transformedUserTable')[id]; return this.get("transformedUserTable")[id];
}, },
lookupBadge(id) { lookupBadge(id) {
return this.get('transformedBadgeTable')[id]; return this.get("transformedBadgeTable")[id];
}, },
lookupPost(id) { lookupPost(id) {
return this.get('transformedPostTable')[id]; return this.get("transformedPostTable")[id];
}, },
lookupTopic(id) { lookupTopic(id) {
return this.get('transformedTopicTable')[id]; return this.get("transformedTopicTable")[id];
}, },
lookupGroup(id) { lookupGroup(id) {
return this.get('transformedGroupTable')[id]; return this.get("transformedGroupTable")[id];
}, },
lookupCategory(id) { lookupCategory(id) {
return this.site.get('categoriesById')[id]; return this.site.get("categoriesById")[id];
}, },
downloadResult(format) { downloadResult(format) {
// Create a frame to submit the form in (?) // Create a frame to submit the form in (?)
// to avoid leaving an about:blank behind // to avoid leaving an about:blank behind
let windowName = randomIdShort(); let windowName = randomIdShort();
const newWindowContents = "<style>body{font-size:36px;display:flex;justify-content:center;align-items:center;}</style><body>Click anywhere to close this window once the download finishes.<script>window.onclick=function(){window.close()};</script>"; const newWindowContents =
"<style>body{font-size:36px;display:flex;justify-content:center;align-items:center;}</style><body>Click anywhere to close this window once the download finishes.<script>window.onclick=function(){window.close()};</script>";
window.open('data:text/html;base64,' + btoa(newWindowContents), windowName); window.open("data:text/html;base64," + btoa(newWindowContents), windowName);
let form = document.createElement("form"); let form = document.createElement("form");
form.setAttribute('id', 'query-download-result'); form.setAttribute("id", "query-download-result");
form.setAttribute('method', 'post'); form.setAttribute("method", "post");
form.setAttribute('action', Discourse.getURL('/admin/plugins/explorer/queries/' + this.get('query.id') + '/run.' + format + '?download=1')); form.setAttribute(
form.setAttribute('target', windowName); "action",
form.setAttribute('style', 'display:none;'); Discourse.getURL(
"/admin/plugins/explorer/queries/" +
this.get("query.id") +
"/run." +
format +
"?download=1"
)
);
form.setAttribute("target", windowName);
form.setAttribute("style", "display:none;");
function addInput(name, value) { function addInput(name, value) {
let field; let field;
field = document.createElement('input'); field = document.createElement("input");
field.setAttribute('name', name); field.setAttribute("name", name);
field.setAttribute('value', value); field.setAttribute("value", value);
form.appendChild(field); form.appendChild(field);
} }
addInput('params', JSON.stringify(this.get('params'))); addInput("params", JSON.stringify(this.get("params")));
addInput('explain', this.get('hasExplain')); addInput("explain", this.get("hasExplain"));
addInput('limit', '1000000'); addInput("limit", "1000000");
ajax('/session/csrf.json').then(function(csrf) { ajax("/session/csrf.json").then(function(csrf) {
addInput('authenticity_token', csrf.csrf); addInput("authenticity_token", csrf.csrf);
document.body.appendChild(form); document.body.appendChild(form);
form.submit(); form.submit();
Em.run.next('afterRender', function() { Em.run.next("afterRender", function() {
document.body.removeChild(form); document.body.removeChild(form);
}); });
}); });
@ -178,13 +192,12 @@ const QueryResultComponent = Ember.Component.extend({
actions: { actions: {
downloadResultJson() { downloadResultJson() {
this.downloadResult('json'); this.downloadResult("json");
}, },
downloadResultCsv() { downloadResultCsv() {
this.downloadResult('csv'); this.downloadResult("csv");
} }
} }
}); });
export default QueryResultComponent; export default QueryResultComponent;

View File

@ -1,12 +1,14 @@
import { categoryLinkHTML } from 'discourse/helpers/category-link'; import { categoryLinkHTML } from "discourse/helpers/category-link";
import { autoUpdatingRelativeAge } from 'discourse/lib/formatter'; import { autoUpdatingRelativeAge } from "discourse/lib/formatter";
import { bufferedRender } from 'discourse-common/lib/buffered-render'; import { bufferedRender } from "discourse-common/lib/buffered-render";
function icon_or_image_replacement(str, ctx) { function icon_or_image_replacement(str, ctx) {
str = Ember.get(ctx.contexts[0], str); str = Ember.get(ctx.contexts[0], str);
if (Ember.isEmpty(str)) { return ""; } if (Ember.isEmpty(str)) {
return "";
}
if (str.indexOf('fa-') === 0) { if (str.indexOf("fa-") === 0) {
return new Handlebars.SafeString("<i class='fa " + str + "'></i>"); return new Handlebars.SafeString("<i class='fa " + str + "'></i>");
} else { } else {
return new Handlebars.SafeString("<img src='" + str + "'>"); return new Handlebars.SafeString("<img src='" + str + "'>");
@ -16,64 +18,78 @@ function icon_or_image_replacement(str, ctx) {
function category_badge_replacement(str, ctx) { function category_badge_replacement(str, ctx) {
const category = Ember.get(ctx.contexts[0], str); const category = Ember.get(ctx.contexts[0], str);
return categoryLinkHTML(category, { return categoryLinkHTML(category, {
allowUncategorized: true, allowUncategorized: true
}); });
} }
function bound_date_replacement(str, ctx) { function bound_date_replacement(str, ctx) {
const value = Ember.get(ctx.contexts[0], str); const value = Ember.get(ctx.contexts[0], str);
return new Handlebars.SafeString(autoUpdatingRelativeAge(new Date(value), {title: true })); return new Handlebars.SafeString(
autoUpdatingRelativeAge(new Date(value), { title: true })
);
} }
const esc = Handlebars.Utils.escapeExpression; const esc = Handlebars.Utils.escapeExpression;
const QueryRowContentComponent = Ember.Component.extend(bufferedRender({ const QueryRowContentComponent = Ember.Component.extend(
tagName: "tr", bufferedRender({
tagName: "tr",
buildBuffer(buffer) { buildBuffer(buffer) {
const self = this; const self = this;
const row = this.get('row'); const row = this.get("row");
const parentView = self.get('parentView'); const parentView = self.get("parentView");
const fallback = this.get('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.get("columnTemplates").map(function(t, idx) {
const value = row[idx], const value = row[idx],
id = parseInt(value); id = parseInt(value);
const ctx = {value, id, baseuri: Discourse.BaseUri === '/' ? '' : Discourse.BaseUri }; const ctx = {
const params = {}; value,
id,
baseuri: Discourse.BaseUri === "/" ? "" : Discourse.BaseUri
};
const params = {};
if (row[idx] === null) { if (row[idx] === null) {
return "NULL"; return "NULL";
} else if (t.name === "text") { } else if (t.name === "text") {
return esc(row[idx]); return esc(row[idx]);
} }
const lookupFunc = parentView[`lookup${t.name.capitalize()}`]; const lookupFunc = parentView[`lookup${t.name.capitalize()}`];
if (lookupFunc) { if (lookupFunc) {
ctx[t.name] = parentView[`lookup${t.name.capitalize()}`](id); ctx[t.name] = parentView[`lookup${t.name.capitalize()}`](id);
} }
if (t.name === "category" || t.name === "badge" || t.name === "reltime") { if (
// only replace helpers if needed t.name === "category" ||
params.helpers = helpers; t.name === "badge" ||
} t.name === "reltime"
) {
// only replace helpers if needed
params.helpers = helpers;
}
try { try {
return new Handlebars.SafeString((t.template || fallback)(ctx, params)); return new Handlebars.SafeString(
} catch (e) { (t.template || fallback)(ctx, params)
console.error(e); );
return "error"; } catch (e) {
} console.error(e);
}); return "error";
}
});
buffer.push("<td>" + parts.join("</td><td>") + "</td>"); buffer.push("<td>" + parts.join("</td><td>") + "</td>");
} }
})); })
);
export default QueryRowContentComponent; export default QueryRowContentComponent;

View File

@ -1,9 +1,9 @@
import showModal from 'discourse/lib/show-modal'; 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";
const NoQuery = Query.create({name: "No queries", fake: true}); const NoQuery = Query.create({ name: "No queries", fake: true });
export default Ember.Controller.extend({ export default Ember.Controller.extend({
queryParams: { selectedQueryId: "id" }, queryParams: { selectedQueryId: "id" },
@ -14,90 +14,97 @@ export default Ember.Controller.extend({
loading: false, loading: false,
explain: false, explain: false,
saveDisabled: Ember.computed.not('selectedItem.dirty'), saveDisabled: Ember.computed.not("selectedItem.dirty"),
runDisabled: Ember.computed.alias('selectedItem.dirty'), runDisabled: Ember.computed.alias("selectedItem.dirty"),
results: Em.computed.alias('selectedItem.results'), results: Em.computed.alias("selectedItem.results"),
asc: null, asc: null,
order: null, order: null,
editing: false, editing: false,
everEditing: false, everEditing: false,
showRecentQueries: true, showRecentQueries: true,
sortBy: ['last_run_at:desc'], sortBy: ["last_run_at:desc"],
sortedQueries: Em.computed.sort('model', 'sortBy'), sortedQueries: Em.computed.sort("model", "sortBy"),
createDisabled: function() { createDisabled: function() {
return (this.get('newQueryName') || "").trim().length === 0; return (this.get("newQueryName") || "").trim().length === 0;
}.property('newQueryName'), }.property("newQueryName"),
selectedItem: function() { selectedItem: function() {
const id = parseInt(this.get('selectedQueryId')); const id = parseInt(this.get("selectedQueryId"));
const item = this.get('content').find(q => q.get('id') === id); const item = this.get("content").find(q => q.get("id") === id);
!isNaN(id) ? this.set('showRecentQueries', false) : this.set('showRecentQueries', true); !isNaN(id)
if (id < 0) this.set('editDisabled', true); ? this.set("showRecentQueries", false)
: this.set("showRecentQueries", true);
if (id < 0) this.set("editDisabled", true);
return item || NoQuery; return item || NoQuery;
}.property('selectedQueryId'), }.property("selectedQueryId"),
othersDirty: function() { othersDirty: function() {
const selected = this.get('selectedItem'); const selected = this.get("selectedItem");
return !!this.get('content').find(q => q !== selected && q.get('dirty')); return !!this.get("content").find(q => q !== selected && q.get("dirty"));
}.property('selectedItem', 'selectedItem.dirty'), }.property("selectedItem", "selectedItem.dirty"),
setEverEditing: function() { setEverEditing: function() {
if (this.get('editing') && !this.get('everEditing')) { if (this.get("editing") && !this.get("everEditing")) {
this.set('everEditing', true); this.set("everEditing", true);
} }
}.observes('editing'), }.observes("editing"),
addCreatedRecord(record) { addCreatedRecord(record) {
this.get('model').pushObject(record); this.get("model").pushObject(record);
this.set('selectedQueryId', Ember.get(record, 'id')); this.set("selectedQueryId", Ember.get(record, "id"));
this.get('selectedItem').set('dirty', false); this.get("selectedItem").set("dirty", false);
this.set('showResults', false); this.set("showResults", false);
this.set('results', null); this.set("results", null);
this.set('editing', true); this.set("editing", true);
}, },
save() { save() {
const self = this; const self = this;
this.set('loading', true); this.set("loading", true);
if (this.get('selectedItem.description') === '') this.set('selectedItem.description', ''); if (this.get("selectedItem.description") === "")
return this.get('selectedItem').save().then(function() { this.set("selectedItem.description", "");
const query = self.get('selectedItem'); return this.get("selectedItem")
query.markNotDirty(); .save()
self.set('editing', false); .then(function() {
}).catch(function(x) { const query = self.get("selectedItem");
popupAjaxError(x); query.markNotDirty();
throw x; self.set("editing", false);
}).finally(function() { })
self.set('loading', false); .catch(function(x) {
}); popupAjaxError(x);
throw x;
})
.finally(function() {
self.set("loading", false);
});
}, },
actions: { actions: {
dummy() {}, dummy() {},
importQuery() { importQuery() {
showModal('import-query'); showModal("import-query");
this.set('showCreate', false); this.set("showCreate", false);
}, },
showCreate() { showCreate() {
this.set('showCreate', true); this.set("showCreate", true);
}, },
editName() { editName() {
this.set('editing', true); this.set("editing", true);
}, },
download() { download() {
window.open(this.get('selectedItem.downloadUrl'), "_blank"); window.open(this.get("selectedItem.downloadUrl"), "_blank");
}, },
scrollTop() { scrollTop() {
window.scrollTo(0,0); window.scrollTo(0, 0);
this.set('editing', false); this.set("editing", false);
this.set('everEditing', false); this.set("everEditing", false);
}, },
goHome() { goHome() {
@ -107,18 +114,18 @@ export default Ember.Controller.extend({
showResults: false, showResults: false,
editDisabled: false, editDisabled: false,
selectedQueryId: null, selectedQueryId: null,
sortBy: ['last_run_at:desc'] sortBy: ["last_run_at:desc"]
}); });
this.send('refreshModel'); this.send("refreshModel");
this.transitionToRoute('adminPlugins.explorer'); this.transitionToRoute("adminPlugins.explorer");
}, },
resetParams() { resetParams() {
this.get('selectedItem').resetParams(); this.get("selectedItem").resetParams();
}, },
saveDefaults() { saveDefaults() {
this.get('selectedItem').saveDefaults(); this.get("selectedItem").saveDefaults();
}, },
save() { save() {
@ -126,102 +133,122 @@ export default Ember.Controller.extend({
}, },
saverun() { saverun() {
this.save().then(() => this.send('run')); this.save().then(() => this.send("run"));
}, },
sortByProperty(property) { sortByProperty(property) {
if (this.sortBy[0] === `${property}:desc`) { if (this.sortBy[0] === `${property}:desc`) {
this.set('sortBy', [`${property}:asc`]); this.set("sortBy", [`${property}:asc`]);
} else { } else {
this.set('sortBy', [`${property}:desc`]); this.set("sortBy", [`${property}:desc`]);
} }
}, },
create() { create() {
const name = this.get("newQueryName").trim(); const name = this.get("newQueryName").trim();
this.set('loading', true); this.set("loading", true);
this.set('showCreate', false); this.set("showCreate", false);
this.set('showRecentQueries', false); this.set("showRecentQueries", false);
this.store this.store
.createRecord('query', { name }) .createRecord("query", { name })
.save() .save()
.then(result => this.addCreatedRecord(result.target) ) .then(result => this.addCreatedRecord(result.target))
.catch(popupAjaxError) .catch(popupAjaxError)
.finally(() => this.set('loading', false)); .finally(() => this.set("loading", false));
}, },
discard() { discard() {
const self = this; const self = this;
this.set('loading', true); this.set("loading", true);
this.store.find('query', this.get('selectedItem.id')).then(function(result) { this.store
const query = self.get('selectedItem'); .find("query", this.get("selectedItem.id"))
query.setProperties(result.getProperties(Query.updatePropertyNames)); .then(function(result) {
query.markNotDirty(); const query = self.get("selectedItem");
self.set('editing', false); query.setProperties(result.getProperties(Query.updatePropertyNames));
}).catch(popupAjaxError).finally(function() { query.markNotDirty();
self.set('loading', false); self.set("editing", false);
}); })
.catch(popupAjaxError)
.finally(function() {
self.set("loading", false);
});
}, },
destroy() { destroy() {
const self = this; const self = this;
const query = this.get('selectedItem'); const query = this.get("selectedItem");
this.set('loading', true); this.set("loading", true);
this.set('showResults', false); this.set("showResults", false);
this.store.destroyRecord('query', query).then(function() { this.store
query.set('destroyed', true); .destroyRecord("query", query)
}).catch(popupAjaxError).finally(function() { .then(function() {
self.set('loading', false); query.set("destroyed", true);
}); })
.catch(popupAjaxError)
.finally(function() {
self.set("loading", false);
});
}, },
recover() { recover() {
const self = this; const self = this;
const query = this.get('selectedItem'); const query = this.get("selectedItem");
this.set('loading', true); this.set("loading", true);
this.set('showResults', true); this.set("showResults", true);
query.save().then(function() { query
query.set('destroyed', false); .save()
}).catch(popupAjaxError).finally(function() { .then(function() {
self.set('loading', false); query.set("destroyed", false);
}); })
.catch(popupAjaxError)
.finally(function() {
self.set("loading", false);
});
}, },
run() { run() {
const self = this; const self = this;
if (this.get('selectedItem.dirty')) { if (this.get("selectedItem.dirty")) {
return; return;
} }
if (this.get('runDisabled')) { if (this.get("runDisabled")) {
return; return;
} }
this.set('loading', true); this.set("loading", true);
this.set('showResults', false); this.set("showResults", false);
ajax("/admin/plugins/explorer/queries/" + this.get('selectedItem.id') + "/run", { ajax(
type: "POST", "/admin/plugins/explorer/queries/" +
data: { this.get("selectedItem.id") +
params: JSON.stringify(this.get('selectedItem.params')), "/run",
explain: this.get('explain') {
} type: "POST",
}).then(function(result) { data: {
self.set('results', result); params: JSON.stringify(this.get("selectedItem.params")),
if (!result.success) { explain: this.get("explain")
self.set('showResults', false); }
return;
} }
)
.then(function(result) {
self.set("results", result);
if (!result.success) {
self.set("showResults", false);
return;
}
self.set('showResults', true); self.set("showResults", true);
}).catch(function(err) { })
self.set('showResults', false); .catch(function(err) {
if (err.jqXHR && err.jqXHR.status === 422 && err.jqXHR.responseJSON) { self.set("showResults", false);
self.set('results', err.jqXHR.responseJSON); if (err.jqXHR && err.jqXHR.status === 422 && err.jqXHR.responseJSON) {
} else { self.set("results", err.jqXHR.responseJSON);
popupAjaxError(err); } else {
} popupAjaxError(err);
}).finally(function() { }
self.set('loading', false); })
}); .finally(function() {
self.set("loading", false);
});
} }
} }
}); });

View File

@ -1,39 +1,42 @@
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";
export default Ember.Controller.extend(ModalFunctionality, { export default Ember.Controller.extend(ModalFunctionality, {
notReady: Em.computed.not('ready'), notReady: Em.computed.not("ready"),
adminPluginsExplorer: Ember.inject.controller(), adminPluginsExplorer: Ember.inject.controller(),
ready: function() { ready: function() {
let parsed; let parsed;
try { try {
parsed = JSON.parse(this.get('queryFile')); parsed = JSON.parse(this.get("queryFile"));
} catch (e) { } catch (e) {
return false; return false;
} }
return !!parsed["query"]; return !!parsed["query"];
}.property('queryFile'), }.property("queryFile"),
actions: { actions: {
doImport: function() { doImport: function() {
const self = this; const self = this;
const object = JSON.parse(this.get('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
this.set('loading', true); this.set("loading", true);
this.store.createRecord('query', object).save().then(function(query) { this.store
self.send('closeModal'); .createRecord("query", object)
self.set('loading', false); .save()
.then(function(query) {
self.send("closeModal");
self.set("loading", false);
const parentController = self.get('adminPluginsExplorer'); const parentController = self.get("adminPluginsExplorer");
parentController.addCreatedRecord(query.target); parentController.addCreatedRecord(query.target);
}).catch(popupAjaxError); })
.catch(popupAjaxError);
} }
} }
}); });

View File

@ -1,7 +1,7 @@
export default { export default {
resource: 'admin.adminPlugins', resource: "admin.adminPlugins",
path: '/plugins', path: "/plugins",
map() { map() {
this.route('explorer'); this.route("explorer");
} }
}; };

View File

@ -1,11 +1,11 @@
export default { export default {
name: 'initialize-data-explorer', name: "initialize-data-explorer",
initialize(container) { initialize(container) {
container.lookup('store:main').addPluralization('query', 'queries'); container.lookup("store:main").addPluralization("query", "queries");
if (!String.prototype.endsWith) { if (!String.prototype.endsWith) {
String.prototype.endsWith = function(searchString, position) { // eslint-disable-line no-extend-native String.prototype.endsWith = function(searchString, position) {
// eslint-disable-line no-extend-native
var subjectString = this.toString(); var subjectString = this.toString();
if (position === undefined || position > subjectString.length) { if (position === undefined || position > subjectString.length) {
position = subjectString.length; position = subjectString.length;

View File

@ -14,12 +14,10 @@ export default function binarySearch(list, target, keyProp) {
if (Em.get(list[guess], keyProperty) === target) { if (Em.get(list[guess], keyProperty) === target) {
return guess; return guess;
} } else {
else {
if (Em.get(list[guess], keyProperty) < target) { if (Em.get(list[guess], keyProperty) < target) {
min = guess + 1; min = guess + 1;
} } else {
else {
max = guess - 1; max = guess - 1;
} }
} }

View File

@ -1,4 +1,4 @@
import RestModel from 'discourse/models/rest'; import RestModel from "discourse/models/rest";
const Query = RestModel.extend({ const Query = RestModel.extend({
dirty: false, dirty: false,
@ -7,62 +7,66 @@ const Query = RestModel.extend({
_init: function() { _init: function() {
this._super(); this._super();
this.set('dirty', false); this.set("dirty", false);
}.on('init'), }.on("init"),
_initParams: function() { _initParams: function() {
this.resetParams(); this.resetParams();
}.on('init').observes('param_info'), }
.on("init")
.observes("param_info"),
markDirty: function() { markDirty: function() {
this.set('dirty', true); this.set("dirty", true);
}.observes('name', 'description', 'sql'), }.observes("name", "description", "sql"),
markNotDirty() { markNotDirty() {
this.set('dirty', false); this.set("dirty", false);
}, },
hasParams: function() { hasParams: function() {
return this.get('param_info.length') > 0; return this.get("param_info.length") > 0;
}.property('param_info'), }.property("param_info"),
resetParams() { resetParams() {
const newParams = {}; const newParams = {};
const oldParams = this.get('params'); const oldParams = this.get("params");
const paramInfo = this.get('param_info') || []; const paramInfo = this.get("param_info") || [];
paramInfo.forEach(function(pinfo) { paramInfo.forEach(function(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];
} else if (pinfo['default'] !== null) { } else if (pinfo["default"] !== null) {
newParams[name] = pinfo['default']; newParams[name] = pinfo["default"];
} else if (pinfo['type'] === 'boolean') { } else if (pinfo["type"] === "boolean") {
newParams[name] = 'false'; newParams[name] = "false";
} else { } else {
newParams[name] = ''; newParams[name] = "";
} }
}); });
this.set('params', newParams); this.set("params", newParams);
}, },
downloadUrl: function() { downloadUrl: function() {
// TODO - can we change this to use the store/adapter? // TODO - can we change this to use the store/adapter?
return Discourse.getURL("/admin/plugins/explorer/queries/" + this.get('id') + ".json?export=1"); return Discourse.getURL(
}.property('id'), "/admin/plugins/explorer/queries/" + this.get("id") + ".json?export=1"
);
}.property("id"),
listName: function() { listName: function() {
let name = this.get('name'); let name = this.get("name");
if (this.get('dirty')) { if (this.get("dirty")) {
name += " (*)"; name += " (*)";
} }
if (this.get('destroyed')) { if (this.get("destroyed")) {
name += " (deleted)"; name += " (deleted)";
} }
return name; return name;
}.property('name', 'dirty', 'destroyed'), }.property("name", "dirty", "destroyed"),
createProperties() { createProperties() {
if (this.get('sql')) { if (this.get("sql")) {
// Importing // Importing
return this.updateProperties(); return this.updateProperties();
} }
@ -71,8 +75,8 @@ const Query = RestModel.extend({
updateProperties() { updateProperties() {
let props = this.getProperties(Query.updatePropertyNames); let props = this.getProperties(Query.updatePropertyNames);
if (this.get('destroyed')) { if (this.get("destroyed")) {
props.id = this.get('id'); props.id = this.get("id");
} }
return props; return props;
} }

View File

@ -1,19 +1,23 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from "discourse/lib/ajax";
export default Discourse.Route.extend({ export default Discourse.Route.extend({
controllerName: 'admin-plugins-explorer', controllerName: "admin-plugins-explorer",
model() { model() {
const p1 = this.store.findAll('query'); const p1 = this.store.findAll("query");
const p2 = ajax('/admin/plugins/explorer/schema.json', {cache: true}); const p2 = ajax("/admin/plugins/explorer/schema.json", { cache: true });
return p1.then(model => { return p1
model.forEach(query => query.markNotDirty()); .then(model => {
model.forEach(query => query.markNotDirty());
return p2.then(schema => {return {model, schema};}); return p2.then(schema => {
}).catch(() => { return { model, schema };
p2.catch(() => {}); });
return { model: null, schema: null, disallow: true }; })
}); .catch(() => {
p2.catch(() => {});
return { model: null, schema: null, disallow: true };
});
}, },
setupController: function(controller, model) { setupController: function(controller, model) {
@ -21,7 +25,8 @@ export default Discourse.Route.extend({
}, },
actions: { actions: {
refreshModel: function() { refreshModel: function() {
this.refresh(); this.refresh();
}
} }
}}); });