diff --git a/assets/javascripts/discourse/adapters/query.js.es6 b/assets/javascripts/admin/adapters/query.js.es6
similarity index 51%
rename from assets/javascripts/discourse/adapters/query.js.es6
rename to assets/javascripts/admin/adapters/query.js.es6
index 3ebcb61..cfd6d75 100644
--- a/assets/javascripts/discourse/adapters/query.js.es6
+++ b/assets/javascripts/admin/adapters/query.js.es6
@@ -1,3 +1,5 @@
import buildPluginAdapter from 'admin/adapters/build-plugin';
-export default buildPluginAdapter('explorer').extend({});
+export default buildPluginAdapter('explorer').extend({
+
+});
diff --git a/assets/javascripts/discourse/components/query-result.js.es6 b/assets/javascripts/discourse/components/query-result.js.es6
index e4e02c9..bf0658d 100644
--- a/assets/javascripts/discourse/components/query-result.js.es6
+++ b/assets/javascripts/discourse/components/query-result.js.es6
@@ -4,6 +4,7 @@ const Escape = Handlebars.Utils.escapeExpression;
import avatarTemplate from 'discourse/lib/avatar-template';
import { categoryLinkHTML } from 'discourse/helpers/category-link';
+import Badge from 'discourse/models/badge';
var defaultFallback = function(buffer, content, defaultRender) { defaultRender(buffer, content); };
@@ -16,6 +17,18 @@ function randomIdShort() {
});
}
+function transformedRelTable(table, modelClass) {
+ const result = {};
+ table.forEach(function(item) {
+ if (modelClass) {
+ result[item.id] = modelClass.create(item);
+ } else {
+ result[item.id] = item;
+ }
+ });
+ return result;
+}
+
const QueryResultComponent = Ember.Component.extend({
layoutName: 'explorer-query-result',
@@ -25,7 +38,6 @@ const QueryResultComponent = Ember.Component.extend({
explainText: Em.computed.alias('content.explain'),
hasExplain: Em.computed.notEmpty('content.explain'),
- noParams: Em.computed.empty('params'),
colCount: function() {
return this.get('content.columns').length;
}.property('content.columns.length'),
@@ -45,61 +57,68 @@ const QueryResultComponent = Ember.Component.extend({
return arr;
}.property('params.@each'),
- columnHandlers: function() {
+ columnDispNames: function() {
+ const templates = this.get('columnTemplates');
const self = this;
if (!this.get('columns')) {
return [];
}
- if (self.get('opts.notransform')) {
- return this.get('columns').map(function(colName) {
- return {
- name: colName,
- displayName: colName,
- render: defaultFallback
- };
- });
- }
return this.get('columns').map(function(colName, idx) {
- let handler = defaultFallback;
-
- if (/\$/.test(colName)) {
- var match = /(\w+)\$(\w*)/.exec(colName);
- if (match[1] && self.get('content.relations')[match[1]] && AssistedHandlers[match[1]]) {
- return {
- name: colName,
- displayName: match[2] || match[1],
- render: AssistedHandlers[match[1]]
- };
- } else if (match[1] == '') {
- // Return as "$column" for no special handling
- return {
- name: colName,
- displayName: match[2] || match[1],
- render: defaultFallback
- }
- }
- } else if (/\?column\?/.test(colName)) {
- return {
- name: "generic-column",
- displayName: I18n.t('explorer.column', {number: idx+1}),
- render: defaultFallback
- }
+ if (colName.endsWith("_id")) {
+ return colName.slice(0, -3);
}
-
- ColumnHandlers.forEach(function(handlerInfo) {
- if (handlerInfo.regex.test(colName)) {
- handler = handlerInfo.render;
- }
- });
-
- return {
- name: colName,
- displayName: colName,
- render: handler
- };
+ const dIdx = colName.indexOf('$');
+ if (dIdx >= 0) {
+ return colName.substring(dIdx + 1);
+ }
+ return colName;
});
}.property('content', 'columns.@each'),
+ columnTemplates: function() {
+ const self = this;
+ if (!this.get('columns')) {
+ return [];
+ }
+ return this.get('columns').map(function(colName, idx) {
+ let viewName = "text";
+ if (self.get('content.colrender')[idx]) {
+ viewName = self.get('content.colrender')[idx];
+ }
+ return {name: viewName, template: self.container.lookup('template:explorer/' + viewName + '.raw')};
+ });
+ }.property('content', 'columns.@each'),
+
+ transformedUserTable: function() {
+ return transformedRelTable(this.get('content.relations.user'));
+ }.property('content.relations.user'),
+ transformedBadgeTable: function() {
+ return transformedRelTable(this.get('content.relations.badge'), Badge);
+ }.property('content.relations.badge'),
+ transformedPostTable: function() {
+ return transformedRelTable(this.get('content.relations.post'));
+ }.property('content.relations.post'),
+ transformedTopicTable: function() {
+ return transformedRelTable(this.get('content.relations.topic'));
+ }.property('content.relations.topic'),
+
+ lookupUser(id) {
+ return this.get('transformedUserTable')[id];
+ },
+ lookupBadge(id) {
+ return this.get('transformedBadgeTable')[id];
+ },
+ lookupPost(id) {
+ return this.get('transformedPostTable')[id];
+ },
+ lookupTopic(id) {
+ return this.get('transformedTopicTable')[id];
+ },
+
+ lookupCategory(id) {
+ return this.site.get('categoriesById')[id];
+ },
+
downloadResult(format) {
// Create a frame to submit the form in (?)
// to avoid leaving an about:blank behind
@@ -151,181 +170,4 @@ const QueryResultComponent = Ember.Component.extend({
});
-/**
- * ColumnHandler callback arguments:
- * buffer: rendering buffer
- * content: content of the query result cell
- * defaultRender: call this wth (buffer, content) to fall back
- * extra: the entire response
- */
-
-ColumnHandlers.push({ regex: /user_id/, render: function(buffer, content, defaultRender) {
- if (!/^\d+$/.test(content)) {
- return defaultRender(buffer, content);
- }
- buffer.push("User #");
- buffer.push(content);
- buffer.push("");
-}});
-ColumnHandlers.push({ regex: /post_id/, render: function(buffer, content, defaultRender) {
- if (!/^\d+$/.test(content)) {
- return defaultRender(buffer, content);
- }
- buffer.push("Post #");
- buffer.push(content);
- buffer.push("");
-}});
-ColumnHandlers.push({ regex: /badge_id/, render: function(buffer, content, defaultRender) {
- if (!/^\d+$/.test(content)) {
- return defaultRender(buffer, content);
- }
- buffer.push("Badge #");
- buffer.push(content);
- buffer.push("");
-}});
-ColumnHandlers.push({ regex: /topic_id/, render: function(buffer, content, defaultRender) {
- if (!/^\d+$/.test(content)) {
- return defaultRender(buffer, content);
- }
- buffer.push("Topic #");
- buffer.push(content);
- buffer.push("");
-}});
-
-AssistedHandlers['reltime'] = function(buffer, content, defaultRender) {
- const parsedDate = new Date(content);
- if (!parsedDate.getTime()) {
- return defaultRender(buffer, content);
- }
-
- buffer.push(Discourse.Formatter.relativeAge(parsedDate, {format: 'medium'}));
-};
-
-AssistedHandlers['category'] = function(buffer, content, defaultRender) {
- const contentId = parseInt(content, 10);
- if (isNaN(contentId)) {
- return defaultRender(buffer, content);
- }
- const category = Discourse.Category.findById(contentId);
- if (!category) {
- return defaultRender(buffer, content);
- }
-
- const opts = {
- link: true,
- allowUncategorized: true
- };
- buffer.push(categoryLinkHTML(category, opts));
-};
-
-/**
- * Helper to wrap the handler in a function that fetches the object out of the response.
- *
- * @param name the part of the column name before the $
- * @param callback Function(buffer, object [, defaultRender])
- */
-function registerRelationAssistedHandler(name, callback) {
- AssistedHandlers[name] = function(buffer, content, defaultRender, response) {
- const contentId = parseInt(content, 10);
- if (isNaN(contentId)) {
- return defaultRender(buffer, content);
- }
- const relationObject = response.relations[name].find(function(relObj) {
- return relObj.id === contentId;
- });
- if (!relationObject) {
- Em.Logger.warn("Couldn't find " + name + " with id " + contentId + " in query response");
- return defaultRender(buffer, content);
- }
-
- callback(buffer, relationObject, defaultRender);
- }
-}
-
-registerRelationAssistedHandler('user', function(buffer, obj) {
- buffer.push("");
- buffer.push(Discourse.Utilities.avatarImg({
- size: "small",
- avatarTemplate: avatarTemplate(obj.username, obj.uploaded_avatar_id)
- }));
- buffer.push(" ");
- buffer.push(obj.username);
- buffer.push("");
-});
-
-registerRelationAssistedHandler('badge', function(buffer, obj) {
- // TODO It would be nice to be able to invoke the {{user-badge}} helper from here.
- // Looks like that would need a ContainerView
-
- /*
-
-
-
-
- Autobiographer
-
- */
-
- if (true) {
- buffer.push('');
- // icon-or-image
- if (obj.icon.indexOf('fa-') === 0) {
- buffer.push(" ");
- } else {
- buffer.push(" ");
- }
- buffer.push(Escape(obj.name));
- buffer.push("");
- }
-});
-
-registerRelationAssistedHandler('post', function(buffer, obj) {
- /*
-
- */
- buffer.push("');
-});
-
export default QueryResultComponent;
diff --git a/assets/javascripts/discourse/components/query-row-content.js.es6 b/assets/javascripts/discourse/components/query-row-content.js.es6
index 93e2d0a..a2dca18 100644
--- a/assets/javascripts/discourse/components/query-row-content.js.es6
+++ b/assets/javascripts/discourse/components/query-row-content.js.es6
@@ -1,19 +1,67 @@
+import binarySearch from 'discourse/plugins/discourse-data-explorer/discourse/lib/binary-search';
+import avatarTemplate from 'discourse/lib/avatar-template';
-const defaultRender = function(buffer, content) {
- buffer.push(Handlebars.Utils.escapeExpression(content));
-};
+function icon_or_image_replacement(str, ctx) {
+ str = Ember.get(ctx.contexts[0], str);
+ if (Ember.isEmpty(str)) { return ""; }
+
+ if (str.indexOf('fa-') === 0) {
+ return new Handlebars.SafeString("");
+ } else {
+ return new Handlebars.SafeString("
");
+ }
+}
+
+function shorthandTinyAvatar(username, uploadId, ctx) {
+ username = Ember.get(ctx.contexts[0], username);
+ uploadId = Ember.get(ctx.contexts[0], uploadId);
+ return new Handlebars.SafeString(Discourse.Utilities.avatarImg({
+ size: "tiny",
+ extraClasses: '',
+ title: username,
+ avatarTemplate: avatarTemplate(username, uploadId)
+ }));
+}
+
+const esc = Handlebars.Utils.escapeExpression;
const QueryRowContentComponent = Ember.Component.extend({
tagName: "tr",
- render(buffer) {
+ transformedUserTable: function() {
+ return transformedRelTable(this.get('extra.relations.user'));
+ }.property('extra.relations.user'),
+
+ render: function(buffer) {
+ const self = this;
const row = this.get('row');
- const response = this.get('extra');
- this.get('colRenders').forEach(function(colRender, idx) {
- buffer.push("
| {{handler.displayName}} | + {{#each columnDispNames as |col|}} +{{col}} | {{/each}}
|---|