node-red-node-watson
Version:
A collection of Node-RED nodes for IBM Watson services
714 lines (616 loc) • 26.4 kB
HTML
<!--
Copyright 2016, 2022 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script type="text/x-red" data-template-name="watson-discovery-v1-query-builder">
<div id="credentials-check" class="form-row">
<div class="form-tips">
<i class="fa fa-question-circle"></i><b> Please wait: </b> Checking for bound service credentials...
</div>
</div>
<div id="credentials-not-found" class="form-row">
<div class="form-tips">
<i class="fa fa-question-circle"></i><b> Could not bind to service.
</b> This node can not be further configured without a valid service.
Try entering valid credentials?
</div>
</div>
<div id="something-went-wrong" class="form-row">
<div class="form-tips">
<div>
<input disabled type="text" id="node-input-errorwarning"/>
</div>
</div>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row credentials" style="display: none;">
<label for="node-input-apikey"><i class="fa fa-key"></i> API Key</label>
<input type="password" id="node-input-apikey" placeholder="API Key"></input>
</div>
<div class="form-row credentials">
<label for="node-input-service-endpoint"><i class="fa fa-tag"></i> Service Endpoint</label>
<input type="text" id="node-input-service-endpoint" placeholder="https://gateway.watsonplatform.net/discovery/api">
</div>
<div class="form-row">
<label for="node-input-environment"><i class="fa fa-book"></i> Environment</label>
<select type="text" id="node-input-environment" style="display: inline-block; vertical-align:middle; width: 70%;">
</select>
</div>
<div>
<input type="hidden" id="node-input-environmenthidden"/>
</div>
<div class="form-row">
<label for="node-input-collection"><i class="fa fa-book"></i> Collection</label>
<select type="text" id="node-input-collection" style="display: inline-block; vertical-align:middle; width: 70%;">
</select>
</div>
<div>
<input type="hidden" id="node-input-collectionhidden"/>
</div>
<div class="form-row">
<label> </label>
<input type="checkbox" id="node-input-passages" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-input-passages" style="width: 70%;"> Passages</label>
</div>
<div>
<input type="hidden" id="node-input-passageshidden"/>
</div>
<div class="form-row">
<label> </label>
<input type="checkbox" id="node-input-nlp_query" style="display: inline-block; width: auto; vertical-align: top;">
<label for="node-input-nlp_query" style="width: 70%;"> Query in Plain Language</label>
</div>
<div>
<input type="hidden" id="node-input-nlp_queryhidden"/>
</div>
<div class="form-row">
<label for="node-input-querynlp"><i class="fa fa-book"></i> NLP Query </label>
<input type="text" id="node-input-querynlp" placeholder="">
</div>
<div>
<input type="hidden" id="node-input-querynlphidden"/>
</div>
<div class="form-row">
<label for="node-input-query1"><i class="fa fa-book"></i> Query Key 1</label>
<select type="text" id="node-input-query1" style="display: inline-block; vertical-align:middle; width: 70%;">
</select>
<input type="text" id="node-input-queryvalue1" placeholder="">
</div>
<div>
<input type="hidden" id="node-input-query1hidden"/>
<input type="hidden" id="node-input-queryvalue1hidden"/>
</div>
<div class="form-row">
<label for="node-input-query2"><i class="fa fa-book"></i> Query Key 2</label>
<select type="text" id="node-input-query2" style="display: inline-block; vertical-align:middle; width: 70%;">
</select>
<input type="text" id="node-input-queryvalue2" placeholder="">
</div>
<div>
<input type="hidden" id="node-input-query2hidden"/>
<input type="hidden" id="node-input-queryvalue2hidden"/>
</div>
<div class="form-row">
<label for="node-input-query3"><i class="fa fa-book"></i> Query Key 3</label>
<select type="text" id="node-input-query3" style="display: inline-block; vertical-align:middle; width: 70%;">
</select>
<input type="text" id="node-input-queryvalue3" placeholder="">
</div>
<div>
<input type="hidden" id="node-input-query3hidden"/>
<input type="hidden" id="node-input-queryvalue3hidden"/>
</div>
</script>
<script type="text/x-red" data-help-name="watson-discovery-v1-query-builder">
<p>This is the Query Builder Node for the V1 Watson Discovery service.</p>
<p>Use this node upflow of a Watson Discovery Node to build the query to be used
by the Discovery Node</p>
<p>The node fetches the searchable fields in the collection and allows you to
set upto 3 query search items.
</p>
<p>The output from the Node is an object in <code>msg.discoveryparams</code>
that the Watson Discovery Node uses as override settings.
</p>
<p>For more information about the Discovery service,
read the service <a href="https://console.bluemix.net/docs/services/discovery/index.html">documentation</a>.</p>
</script>
<script type="text/javascript">
// Need to simulate a namespace, so that some of the variables don't leak across nodes
function DiscoveryQueryBuilderV1 () {}
// This is the namespace for this version of this Node.
var disQB = new DiscoveryQueryBuilderV1();
disQB.environments = null;
disQB.collections = {};
disQB.schemas = {};
// Initially assume that we dont have credentials and that neither system
// nor local set have been provided.
disQB.have_credentials = false;
disQB.using_local_credentials = true;
disQB.environment_selected = $('#node-input-environmenthidden').val();
disQB.collection_selected = $('#node-input-collectionhidden').val();
disQB.query1_selected = $('#node-input-query1hidden').val();
disQB.query2_selected = $('#node-input-query2hidden').val();
disQB.query3_selected = $('#node-input-query3hidden').val();
disQB.passages_selected = $('#node-input-passageshidden').val();
disQB.nlp_query_selected = $('#node-input-nlp_queryhidden').val();
// Nothing is to be shown unless the values to show in the listCollections
// can be obtained from the service.
disQB.hideAll = function() {
$('#credentials-not-found').show();
//disQB.hideSelectedFields(fields);
$('#something-went-wrong').hide();
$('#node-input-environment').parent().hide();
$('#node-input-collection').parent().hide();
$('#node-input-querynlp').parent().hide();
$('#node-input-query1').parent().hide();
$('#node-input-query2').parent().hide();
$('#node-input-query3').parent().hide();
};
disQB.showSelectedFields = function(fields) {
for (i = 0; i < fields.length; i++) {
$(fields[i]).parent().show();
}
}
disQB.hideSelectedFields = function(fields) {
for (i = 0; i < fields.length; i++) {
$(fields[i]).parent().hide();
}
}
// Set up listeners for the select lists to determine if the subsequent
// list boxes need refreshing. ie. A change in selected Envionment, needs
// the collection list to be revised. A change in selected collection, needs
// the schema lists to be revised.
disQB.UIListeners = function () {
$('#node-input-apikey').change(function(val){
disQB.getCredentials();
});
$('#node-input-environment').change(function (val) {
disQB.environment_selected = $('#node-input-environment').val();
if (disQB.environment_selected &&
!disQB.collectionCheck()) {
disQB.getCollections();
}
else if (disQB.environment_selected) {
disQB.populateCollections();
}
});
$('#node-input-collection').change(function (val) {
disQB.collection_selected = $('#node-input-collection').val();
if (disQB.collection_selected &&
!disQB.schemaCheck()) {
disQB.getSchemas();
}
else if (disQB.collection_selected) {
disQB.populateSchemas();
}
});
$('#node-input-query1').change(function (val) {
disQB.query1_selected = $('#node-input-query1').val();
});
$('#node-input-query2').change(function (val) {
disQB.query2_selected = $('#node-input-query2').val();
});
$('#node-input-query3').change(function (val) {
disQB.query3_selected = $('#node-input-query3').val();
});
$('input#node-input-nlp_query').change(function () {
var checked = $('input#node-input-nlp_query').prop('checked');
if (checked) {
$('#node-input-querynlp').parent().show();
$('#node-input-query1').parent().hide();
$('#node-input-query2').parent().hide();
$('#node-input-query3').parent().hide();
} else {
$('#node-input-querynlp').parent().hide();
$('#node-input-query1').parent().show();
$('#node-input-query2').parent().show();
$('#node-input-query3').parent().show();
}
});
}
// The dialog is about to be shown.
disQB.checkForPrepare = function () {
disQB.hideAll();
disQB.UIListeners();
};
// Search the cache for a collection
disQB.collectionCheckForEnv = function (env) {
var coll = null;
if (disQB.collections && disQB.collections[env])
{
coll = disQB.collections[env];
}
return coll;
}
// Search the collection cache for the selected envrionment
disQB.collectionCheck = function () {
return disQB.collectionCheckForEnv(disQB.environment_selected);
}
// Search for a collection schema
disQB.schemaCheckForCollection = function (coll) {
var schema = null;
if (disQB.schemas && disQB.schemas[coll])
{
schema = disQB.schemas[coll];
}
return schema;
}
// Search the schema cache for the selected collection.
disQB.schemaCheck = function () {
return disQB.schemaCheckForCollection(disQB.collection_selected);
}
// Fill up the Envrionment switch list
disQB.populateEnvironments = function() {
if (disQB.environments && disQB.environments.length) {
$('select#node-input-environment').empty();
disQB.environments.forEach(function(env) {
var selectedText = '';
if (disQB.environment_selected === env.environment_id) {
selectedText = 'selected="selected"';
}
$('select#node-input-environment')
.append('<option value='
+ '"' + env.environment_id + '"'
+ selectedText
+ '>'
+ env.name
+ '</option>');
});
if (!disQB.collectionCheck()) {
disQB.getCollections();
}
}
};
// Fill up the collection switch list
disQB.populateCollections = function() {
var coll = disQB.collectionCheck();
if (coll && coll.length) {
$('select#node-input-collection').empty();
coll.forEach(function(c) {
var selectedText = '';
if (disQB.collection_selected === c.collection_id) {
selectedText = 'selected="selected"';
}
$('select#node-input-collection')
.append('<option value='
+ '"' + c.collection_id + '"'
+ selectedText
+ '>'
+ c.name
+ '</option>');
});
if (!disQB.schemaCheck()) {
disQB.getSchemas();
}
}
};
// Fill up the 3 schema switch lists
disQB.populateSchemas = function() {
var schema = disQB.schemaCheck();
if (schema && schema.length) {
$('select#node-input-query1').empty();
$('select#node-input-query2').empty();
$('select#node-input-query3').empty();
schema.forEach(function(s) {
var selected1Text = '';
var selected2Text = '';
var selected3Text = '';
if (disQB.query1_selected === s) {
selected1Text = 'selected="selected"';
}
if (disQB.query2_selected === s) {
selected2Text = 'selected="selected"';
}
if (disQB.query3_selected === s) {
selected3Text = 'selected="selected"';
}
$('select#node-input-query1')
.append('<option value='
+ '"' + s + '"'
+ selected1Text
+ '>'
+ s
+ '</option>');
$('select#node-input-query2')
.append('<option value='
+ '"' + s + '"'
+ selected2Text
+ '>'
+ s
+ '</option>');
$('select#node-input-query3')
.append('<option value='
+ '"' + s + '"'
+ selected3Text
+ '>'
+ s
+ '</option>');
});
}
};
// If we have a list of envrionments, then the
// environment switch list can be shown.
disQB.showEnvironments = function () {
if (disQB.environments) {
$('select#node-input-environment').parent().show();
disQB.populateEnvironments();
}
}
// If we have a collection for the envrionment, then the
// collection switch list can be shown.
disQB.showCollections = function () {
if (disQB.collections && disQB.collectionCheck()) {
$('select#node-input-collection').parent().show();
disQB.populateCollections();
}
}
// If we have a schema for the collection, then the
// three query switch lists can be shown.
disQB.showSchemas = function () {
if (disQB.schemas && disQB.schemaCheck()) {
var checked = $('input#node-input-nlp_query').prop('checked');
if (!checked) {
$('select#node-input-query1').parent().show();
$('select#node-input-query2').parent().show();
$('select#node-input-query3').parent().show();
}
disQB.populateSchemas();
}
}
// Retrieve the available environments from the server, if data is returned, then
// can enable the dynamic selection fields.
disQB.getEnvironments = function () {
var k = $('#node-input-apikey').val();
var creds = {key: k};
creds.endpoint = $('#node-input-service-endpoint').val();
$.getJSON('watson-discovery-v1-query-builder/environments', creds
).done(function (data) {
$('#something-went-wrong').hide();
if (data.error) {
$('#something-went-wrong').show();
$('input#node-input-errorwarning').val(data.error);
}
else {
$('#credentials-not-found').hide();
disQB.environments = data;
disQB.have_credentials = true;
disQB.showEnvironments();
}
}).fail(function (err) {
var txt = 'Got server error ';
if (err.status) {
txt += '(' + err.status + ') '
}
txt += 'when trying to retrieve available envrionments';
$('#something-went-wrong').show();
$('input#node-input-errorwarning').val(txt);
}).always(function () {
});
}
// Retrieve the available collections in the selected envrionment from the server,
// if data is returned, then can enable the dynamic selection fields.
disQB.getCollections = function () {
var k = $('#node-input-apikey').val();
var creds = {key: k};
creds.endpoint = $('#node-input-service-endpoint').val();
creds.environment_id = disQB.environment_selected;
$.getJSON('watson-discovery-v1-query-builder/collections', creds
).done(function (data) {
$('#something-went-wrong').hide();
if (data.error) {
$('#something-went-wrong').show();
$('input#node-input-errorwarning').val(data.error);
}
else {
disQB.collections[disQB.environment_selected] = data;
disQB.showCollections();
}
}).fail(function (err) {
var txt = 'Got server error ';
if (err.status) {
txt += '(' + err.status + ') '
}
txt += 'when trying to retrieve available collections';
$('#something-went-wrong').show();
$('input#node-input-errorwarning').val(txt);
}).always(function () {
});
}
// Retrieve the available collections in the selected envrionment from the server,
// if data is returned, then can enable the dynamic selection fields.
disQB.getSchemas = function () {
var k = $('#node-input-apikey').val();
var creds = {key: k};
creds.endpoint = $('#node-input-service-endpoint').val();
creds.environment_id = disQB.environment_selected;
creds.collection_id = disQB.collection_selected;
$.getJSON('watson-discovery-v1-query-builder/schemas', creds
).done(function (data) {
$('#something-went-wrong').hide();
if (data.error) {
$('#something-went-wrong').show();
$('input#node-input-errorwarning').val(data.error);
}
else {
disQB.schemas[disQB.collection_selected] = data;
disQB.showSchemas();
}
}).fail(function (err) {
var txt = 'Got server error ';
if (err.status) {
txt += '(' + err.status + ') '
}
txt += 'when trying to retrieve available schemas for collection';
$('#something-went-wrong').show();
$('input#node-input-errorwarning').val(txt);
}).always(function () {
});
}
// Simple check that is only invoked if the service is not bound into bluemix.
// In this case the user has to provide credentials. Once there are credentials,
// then the discovery environments are retrieved.
disQB.getCredentials = function () {
var k = $('#node-input-apikey').val();
if ( (k && k.length) ) {
if (!disQB.environments) {
disQB.getEnvironments();
}
}
}
// The dynamic nature of the selection fields in this node has caused problems.
// Whenever there is a fetch for the models, on a page refresh or applicaiton
// restart, the settings for the dynamic fields are lost.
// So hidden (text) fields are being used to squirrel away the values, so that
// they can be restored.
disQB.restoreHidden = function () {
disQB.environment_selected = $('#node-input-environmenthidden').val();
$('#node-input-environment').val(disQB.environment_selected);
disQB.collection_selected = $('#node-input-collectionhidden').val();
$('#node-input-collection').val(disQB.collection_selected);
disQB.querynlp_selected = $('#node-input-querynlphidden').val();
$('#node-input-querynlp').val(disQB.querynlp_selected);
disQB.query1_selected = $('#node-input-query1hidden').val();
$('#node-input-query1').val(disQB.query1_selected);
disQB.queryvalue1_selected = $('#node-input-queryvalue1hidden').val();
$('#node-input-queryvalue1').val(disQB.queryvalue1_selected);
disQB.query2_selected = $('#node-input-query2hidden').val();
$('#node-input-query2').val(disQB.query2_selected);
disQB.queryvalue2_selected = $('#node-input-queryvalue2hidden').val();
$('#node-input-queryvalue2').val(disQB.queryvalue2_selected);
disQB.query3_selected = $('#node-input-query3hidden').val();
$('#node-input-query3').val(disQB.query3_selected);
disQB.queryvalue3_selected = $('#node-input-queryvalue3hidden').val();
$('#node-input-queryvalue3').val(disQB.queryvalue3_selected);
disQB.passages_selected = $('#node-input-passageshidden').val();
$('#node-input-passages').val(disQB.passages_selected);
disQB.nlp_query_selected = $('#node-input-nlp_queryhidden').val();
$('#node-input-nlp_query').val(disQB.nlp_query_selected);
}
// This is the on edit prepare function, which will be invoked everytime the dialog is shown.
function disQBoneditprepare() {
disQB.hideAll();
disQB.restoreHidden();
disQB.checkForPrepare();
if (!disQB.have_credentials) {
$.getJSON('watson-discovery-v1-query-builder/vcap/')
.done(function (service) {
$('.credentials').toggle(!service);
// for some reason the getJSON resets the vars so need to restoreHidden again
// so again.
disQB.have_credentials = true;
disQB.restoreHidden();
if (!service) {
// no bound service, so check local settings to see if they are valid
disQB.using_local_credentials = true;
disQB.getCredentials();
} else {
// credentials are only valid if we can get hold of the models using them
disQB.using_local_credentials = false;
if (!disQB.environments) {disQB.getEnvironments();}
}
})
.fail(function () {
$('.credentials').show();
}).always(function () {
$('#credentials-check').hide();
})
}
// credentials can be set during the disQBoneditprepare process, so check again.
if (disQB.have_credentials || disQB.using_local_credentials)
{
$('#credentials-check').hide();
if (disQB.have_credentials) {
$('#credentials-not-found').hide();
}
if (disQB.using_local_credentials) {
$('.credentials').show();
}
disQB.showEnvironments();
disQB.showCollections();
disQB.showSchemas();
}
}
// Save the values in the dyanmic lists to the hidden fields.
function disQoneditsave(){
disQB.environment_selected = $('#node-input-environment').val();
$('#node-input-environmenthidden').val(disQB.environment_selected);
disQB.collection_selected = $('#node-input-collection').val();
$('#node-input-collectionhidden').val(disQB.collection_selected);
disQB.querynlp_selected = $('#node-input-querynlp').val();
$('#node-input-querynlphidden').val(disQB.querynlp_selected);
disQB.query1_selected = $('#node-input-query1').val();
$('#node-input-query1hidden').val(disQB.query1_selected);
disQB.queryvalue1_selected = $('#node-input-queryvalue1').val();
$('#node-input-queryvalue1hidden').val(disQB.queryvalue1_selected);
disQB.query2_selected = $('#node-input-query2').val();
$('#node-input-query2hidden').val(disQB.query2_selected);
disQB.queryvalue2_selected = $('#node-input-queryvalue2').val();
$('#node-input-queryvalue2hidden').val(disQB.queryvalue2_selected);
disQB.query3_selected = $('#node-input-query3').val();
$('#node-input-query3hidden').val(disQB.query3_selected);
disQB.queryvalue3_selected = $('#node-input-queryvalue3').val();
$('#node-input-queryvalue3hidden').val(disQB.queryvalue3_selected);
disQB.passages_selected = $('#node-input-passages').val();
$('#node-input-passageshidden').val(disQB.passages_selected);
disQB.nlp_query_selected = $('#node-input-nlp_query').val();
$('#node-input-nlp_queryhidden').val(disQB.nlp_query_selected);
}
(function() {
RED.nodes.registerType('watson-discovery-v1-query-builder', {
category: 'IBM Watson',
defaults: {
name: {value: ''},
apikey: {type:'password'},
environment: {value: ''},
environmenthidden: {value: ''},
collection: {value: ''},
collectionhidden: {value: ''},
nlp_query: {value: 'true'},
nlp_queryhidden: {value: 'true'},
querynlp: {value: ''},
querynlphidden: {value: ''},
query1: {value: ''},
query1hidden: {value: ''},
queryvalue1: {value: ''},
queryvalue1hidden: {value: ''},
query2: {value: ''},
query2hidden: {value: ''},
queryvalue2: {value: ''},
queryvalue2hidden: {value: ''},
query3: {value: ''},
query3hidden: {value: ''},
queryvalue3: {value: ''},
queryvalue3hidden: {value: ''},
passages: {value: false},
passageshidden: {value: false},
'service-endpoint' :{value: ''}
},
credentials: {
},
color: "rgb(200,140,80)",
inputs: 1,
outputs: 1,
icon: "discovery.png",
paletteLabel: "discovery query builder",
label: function() {
return this.name || "discovery query builder";
},
labelStyle: function() {
return this.name ? "node_label_italic" : "";
},
oneditprepare: disQBoneditprepare,
oneditsave: disQoneditsave
});
})();
</script>