Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search schema #58

Merged
merged 3 commits into from
Dec 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/adapters/search-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ var SearchIndexAdapter = DS.RESTAdapter.extend({
let url = this.buildURL(type.modelName, null, null, 'query', query);

let promise = this.ajax(url, 'GET').then(function(indexes) {

indexes.forEach(function(index) {
index.id = `${query.clusterId}/${index.name}`;
});
Expand All @@ -23,3 +22,4 @@ var SearchIndexAdapter = DS.RESTAdapter.extend({
});

export default SearchIndexAdapter;

14 changes: 14 additions & 0 deletions app/components/code-highlighter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Ember from 'ember';
/* global hljs */

export default Ember.Component.extend({
tagName: 'pre',

classNames: ['code-highlighter'],

didRender() {
let codeBlock = this.$().find('code')[0];

hljs.highlightBlock(codeBlock);
}
});
1 change: 1 addition & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for 'head'}}
<link rel="stylesheet" href="assets/ember-riak-explorer.css">
<link rel="stylesheet" href="assets/vendor.css">
{{content-for 'head-footer'}}
</head>
<body>
Expand Down
7 changes: 7 additions & 0 deletions app/pods/cluster/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ var Cluster = DS.Model.extend({
*/
searchIndexes: DS.hasMany('search-index', { async: true }),

/**
* Search schemas created on the cluster
* @property searchSchemas
* @type Array<BucketType>
*/
searchSchemas: DS.hasMany('search-schema', { async: true }),

/**
* Is this cluster in Dev Mode? Set in the Explorer config file.
* Dev mode allows expensive operations like list keys, delete bucket, etc.
Expand Down
11 changes: 7 additions & 4 deletions app/pods/cluster/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@
{{/if}}
{{/dashboard-module}}

{{#dashboard-module label='Search Indexes'}}
{{#dashboard-module label='Search Overview'}}
{{#link-to 'search-schema.create' model.id class='btn btn-small btn-primary'}}
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Create new search schema
{{/link-to}}

{{#if model.searchIndexes}}
{{search-indexes
indexes=model.searchIndexes
clusterProxyUrl=model.proxyUrl}}
{{search-indexes indexes=model.searchIndexes}}
{{else}}
<p>No search indexes found</p>
{{/if}}
Expand Down
36 changes: 17 additions & 19 deletions app/pods/search-index/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@ import DS from 'ember-data';

var SearchIndex = DS.Model.extend({
/**
* Riak cluster in the search index wascreated on
* Riak cluster the search index was created on
*
* @property cluster
* @type {DS.Model} Cluster
* @writeOnce
*/
cluster: DS.belongsTo('cluster'),
cluster: DS.belongsTo('cluster', { async: true }),

/**
* Schema the search index is using
*
* @property schema
* @type {DS.Model} Search Schema
* @writeOnce
*/
schema: DS.belongsTo('search-schema', { async: true }),

/**
* Returns the search index name/id
Expand All @@ -25,11 +34,12 @@ var SearchIndex = DS.Model.extend({
nVal: DS.attr('number', {defaultValue: 3}),

/**
* Name of the schema the index is using
* @property schema
* @type String
* Holds the value of the schema name that index is using.
* Temporary hack until basho-labs/riak_explorer#89 is completed
* @property nVal
* @type Integer
*/
schema: DS.attr('string'),
schemaRef: DS.attr('string'),

/**
* Ember.Array of bucket types on the current cluster using the index
Expand All @@ -40,19 +50,7 @@ var SearchIndex = DS.Model.extend({
let bucketTypes = this.get('cluster').get('bucketTypes');

return bucketTypes.filterBy('index.name', this.get('name'));
}.property('cluster.bucketTypes'),

/**
* Returns a formatted schema url
* @property schemaUrl
* @type String
*/
schemaUrl: function() {
let proxyURL = this.get('cluster').get('proxyUrl');
let schema = this.get('schema');

return `${proxyURL}/search/schema/${schema}`;
}.property('schema', 'cluster.proxyUrl')
}.property('cluster.bucketTypes')
});

export default SearchIndex;
4 changes: 3 additions & 1 deletion app/pods/search-index/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
<tr>
<td class="key">Schema</td>
<td class="value">
<a href={{model.schemaUrl}}>{{model.schema}}</a>
{{#link-to 'search-schema' model.cluster.id model.schema.name class='btn btn-small btn-primary'}}
{{model.schema.name}}
{{/link-to}}
</td>
</tr>
<tr>
Expand Down
6 changes: 6 additions & 0 deletions app/pods/search-schema/create/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Ember from 'ember';

export default Ember.Controller.extend({
schemaName: '',
schemaContent: ''
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This holds the temporary values of the new schema until they are ready to be sent to the server.

49 changes: 49 additions & 0 deletions app/pods/search-schema/create/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Ember from 'ember';

export default Ember.Route.extend({
model(params) {
return this.explorer.getCluster(params.clusterId, this.store);
},

actions: {
createSchema: function(clusterId, schemaName, schemaContent) {
let self = this;
let xmlDoc = null;
let url = `/riak/clusters/${clusterId}/search/schema/${schemaName}`;

try {
xmlDoc = Ember.$.parseXML(schemaContent);
} catch(error) {
// TODO: Put in proper error messaging
alert('Invalid XML. Please check and make sure schema is valid xml.');
return;
}

if (!Ember.$(xmlDoc).find('schema').attr('name')) {
// TODO: Put in proper error messaging
alert('Solr requires that the schema tag has a name attribute. Please update your xml.');
return;
}

if (!Ember.$(xmlDoc).find('schema').attr('version')) {
// TODO: Put in proper error messaging
alert('Solr requires that the schema tag has a version attribute. Please update your xml.');
return;
}

return Ember.$.ajax({
type: 'PUT',
url: url,
contentType: 'application/xml',
processData: false,
data: xmlDoc
}).then(function(data) {
self.transitionTo('search-schema', clusterId, schemaName);
}, function(error) {
// TODO: Put in proper error messaging
alert('Something went wrong, schema was not saved.');
});
}
}

});
34 changes: 34 additions & 0 deletions app/pods/search-schema/create/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div class='view-header'>
{{breadcrumb-component
clusterId=model.clusterId
pageTitle='create schema'
}}
{{view-label
pre-label='Create Schema'}}
</div>

{{#dashboard-module}}
<div class="schema-actions">
<span class="create schema-action" {{action 'createSchema' model.clusterId schemaName schemaContent}}>
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
Create Schema
</span>

{{#link-to 'cluster' model.clusterId class='cancel schema-action' }}
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
Cancel
{{/link-to}}
</div>

<form>
<div class="form-group">
<label>Schema Name</label>
{{input value=schemaName class='form-control'}}
</div>

<div class="form-group">
<label>Schema XML</label>
{{textarea value=schemaContent rows=10 class='form-control'}}
</div>
</form>
{{/dashboard-module}}
55 changes: 55 additions & 0 deletions app/pods/search-schema/edit/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Ember from 'ember';

export default Ember.Route.extend({
model(params) {
return this.explorer.getCluster(params.clusterId, this.store)
.then(function(cluster){
return cluster.get('searchSchemas').findBy('name', params.searchSchemaId);
});
},

afterModel(model, transition) {
if (!model.get('content')) {
return Ember.$.ajax({
type: 'GET',
url: model.get('url'),
dataType: 'xml'
}).then(function(data) {
let xmlString = (new XMLSerializer()).serializeToString(data);
model.set('content', xmlString);
});
}
},

actions: {
updateSchema: function(schema) {
let xmlString = schema.get('content');
let self = this;
let xmlDoc = null;
let clusterId = schema.get('cluster').get('id');
let schemaId = schema.get('name');

try {
xmlDoc = Ember.$.parseXML(xmlString);
} catch(error) {
// TODO: Put in proper error messaging
alert('Invalid XML. Please check and make sure schema is valid xml.');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These TODO items are basically a reminder that the app should have some kind of proper error messaging component. Something like a modal instead of using alert.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like a modal instead of using alert

Yeah, I've been thinking about that as well, that we need some either modal windows, or (better yet) some message/error divs under the crumb trail, etc.

Alert is totally fine for now though.

return;
}

return Ember.$.ajax({
type: 'PUT',
url: schema.get('url'),
contentType: 'application/xml',
processData: false,
data: xmlDoc
}).then(function(data) {
self.transitionTo('search-schema', clusterId, schemaId);
}, function(error) {
// TODO: Put in proper error messaging
alert('Something went wrong, schema was not saved.');
self.transitionTo('search-schema', clusterId, schemaId);
});
}
}
});
31 changes: 31 additions & 0 deletions app/pods/search-schema/edit/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class='view-header'>
{{breadcrumb-component
clusterId=model.cluster.id
pageTitle=model.name
}}
{{view-label
pre-label='Search Schema'
label=model.name}}
</div>

{{#dashboard-module}}
<div class="schema-actions">
<span class="update schema-action" {{action 'updateSchema' model}}>
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
Update Schema
</span>

{{#link-to 'search-schema' model.cluster.id model.name class='cancel schema-action' }}
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
Cancel
{{/link-to}}
</div>

<pre class="editable">
<code>
{{content-editable
value=model.content
type="html"}}
</code>
</pre>
{{/dashboard-module}}
28 changes: 28 additions & 0 deletions app/pods/search-schema/model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import DS from 'ember-data';

export default DS.Model.extend({
/**
* Riak cluster the search schema was created on
*
* @property cluster
* @type {DS.Model} Cluster
* @writeOnce
*/
cluster: DS.belongsTo('cluster', { async: true }),

name: DS.attr('string'),

content: DS.attr(),

/**
* Returns a formatted schema url
* @method url
* @returns String
*/
url: function() {
let proxyURL = this.get('cluster').get('proxyUrl');
let name = this.get('name');

return `${proxyURL}/search/schema/${name}`;
}.property('name', 'cluster.proxyUrl')
});
30 changes: 30 additions & 0 deletions app/pods/search-schema/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Ember from 'ember';
import $ from 'jquery';

export default Ember.Route.extend({
model(params) {
let self = this;

return this.explorer.getCluster(params.clusterId, this.store)
.then(function(cluster){
let schema = cluster.get('searchSchemas').findBy('name', params.searchSchemaId);

if (!schema) {
schema = self.explorer.createSchema(params.searchSchemaId, cluster, self.store);
}

return schema;
});
},

afterModel(model, transition) {
return Ember.$.ajax({
type: 'GET',
url: model.get('url'),
dataType: 'xml'
}).then(function(data) {
let xmlString = (new XMLSerializer()).serializeToString(data);
model.set('content', xmlString);
});
}
});
Loading