Archive for the ‘Node’ Category

NodeJS ReactJS, NOT using Isomorphic-fetch, using jQuery JSONP GET -> Oracle Service Cloud Article Feedback ci/ajaxCustom Endpoint

Friday, June 23rd, 2017

app.js

'use strict';

const compression = require('compression');
const express = require('express');
const next = require('next');
const path = require('path');
const fetch = require('isomorphic-fetch');

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const auth = '...';
const site = 'help-*-*';
const server = express();

class GetHelp {
constructor() {

this.initApp();
}

/*
Start express application and express healthcheck.
*/
initApp() {
app.prepare().then(() => {

/*
* API Server
*/

server.get('/api/search/:searchTerm', (req, res, next) => {
const searchTerm = req.params.searchTerm;
var endpoint = `services/rest/connect/v1.3/analyticsReportResults`;

fetch(
`https://${auth}@${site}.....com/${endpoint}`, {
method: 'POST',
mode: 'no-cors',
body: JSON.stringify({
"id": 178394,
"filters": [{
"name": "os_search",
"values": [
searchTerm
]
}]
})
})
.then(function(res) { return res.json(); })
.then(function(data) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ article: data }));
});
});

server.get('/api/article/:articleId', (req, res, next) => {
const articleId = req.params.articleId;
var endpoint = "";
if (parseInt(articleId)) {
endpoint = `/services/rest/connect/v1.3/answers/${articleId}/?fields=solution,summary`;
} else {
endpoint = `/services/rest/connect/v1.3/queryResults/?query=select summary,solution from answers where customFields.c.slug='${articleId}'and customFields.c.lang_id=2035 and language=1 and AccessLevels.NamedIDList.ID=11`;
}

fetch(
`https://${auth}@${site}.....com/${endpoint}`, {
method: 'GET',
mode: 'no-cors',
})
.then(function(res) { return res.json(); })
.then(function(data) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ article: data }));
});
});

var endpoint = "services/rest/connect/v1.3/queryResults/?query=select lookupName,value from messageBases ";
endpoint += "where lookupName in (" + msgToGet + ")";

fetch(
`https://${auth}@${site}.....com/${endpoint}`, {
method: 'GET',
mode: 'no-cors',
})
.then(function(res) { return res.json(); })
.then(function(data) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ messageBase: data }));
});
});

/*
* APP Routes
*/

server.get('/search/:searchTerm/page/:page', (req, res) => {
const params = { searchTerm: req.params.searchTerm, page: req.params.page }
return app.render(req, res, '/search', params);
});

server.get('/article/:articleId', (req, res) => {
const params = { articleId: req.params.articleId }
return app.render(req, res, '/article', params);
});

server.get('*', (req, res) => {
return handle(req, res);
});

server.listen(8080, 'local-www....dev.com', () => {
this.initHealthcheck();
});
});
}

}

module.exports = new GetHelp();

/components/StarRating.js

</pre></pre>
import React from 'react';

import Link from '../components/Link';

import Router from 'next/router'

import 'isomorphic-fetch';

import Modal from 'react-modal';

&nbsp;

&nbsp;

const site = 'help-en-us';

const customStyles = {

content : {

top: '50%',

left: '50%',

right: 'auto',

bottom: 'auto',

marginRight: '-50%',

transform: 'translate(-50%, -50%)'

}

};

&nbsp;

&nbsp;

export default class extends React.Component {

constructor(props) {

super(props);

this.state = {

starRating: 0,

articleId: this.props.articleId,

thankYou: false,

showStars: true

};

&nbsp;

&nbsp;

this.handleStar = this.handleStar.bind(this);

this.submitRating = this.submitRating.bind(this);

this.getToken = this.getToken.bind(this);

this.onKeyPress = this.onKeyPress.bind(this);

this.openModal = this.openModal.bind(this);

this.afterOpenModal = this.afterOpenModal.bind(this);

this.closeModal = this.closeModal.bind(this);

this.cancelModal = this.cancelModal.bind(this);

this.submitAnswerFeedback = this.submitAnswerFeedback.bind(this);

this.getToken = this.getToken.bind(this);

}

&nbsp;

&nbsp;

async submitRating(rating) {

let result = await $.ajax({

url: `http://${site}.....com/ci/ajaxCustom/submitAnswerRating`,

data: `a_id=${this.props.articleId}&amp;amp;rate=${rating}&amp;amp;options_count=5`,

dataType: 'jsonp',

jsonpCallback: 'submitAnswerRating',

success: function(response){

console.log(response.submitted);

}

});

let flag = await result;

return flag

};

&nbsp;

&nbsp;

async getToken(rating){

let result = await $.ajax({

url: `http://${site}.....com/ci/ajaxCustom/getNewFormToken`,

data: `formToken=${Math.random().toString(36).substr(2)}`,

dataType: 'jsonp',

jsonpCallback: 'getNewFormToken',

success: function(response){

//console.log(typeof(response.newToken));

return response;

}

});

let token = await result;

return token

};

&nbsp;

&nbsp;

async submitAnswerFeedback(){

let a_id = this.props.articleId;

let rating = this.state.starRating;

let feedbackMessageValue = this.state.feedbackMessageValue;

let token = this.state.token;

console.log('sAF: ' + token);

&nbsp;

&nbsp;

let result = await $.ajax({

url: `http://${site}.....com/ci/ajaxCustom/submitAnswerFeedback`,

data: `a_id=${a_id}&amp;amp;rate=${rating}&amp;amp;message=${feedbackMessageValue}&amp;amp;f_tok=${token}`,

dataType: 'jsonp',

jsonpCallback: 'submitAnswerFeedback',

success: function(response){

console.log(response);

}

});

&nbsp;

&nbsp;

let message = await result;

this.closeModal();

&nbsp;

&nbsp;

return message

};

&nbsp;

&nbsp;

async handleStar(rating){

// submit the star rating clicked

let ratingSubmitted = await this.submitRating(rating);

if(rating >= 3){

// submitted, and done

this.setState({

thankYou: true,

starRating: rating,

ratingSubmitted: ratingSubmitted,

showStars: false

})

} else {

// less than 3, so get a token, and open popup

let token = await this.getToken(rating);

console.log('obj: ' + token.newToken);

console.log(typeof(token.newToken));

this.openModal();

this.setState({

thankYou: true,

starRating: rating,

ratingSubmitted: ratingSubmitted,

token: token.newToken,

showStars: false

})

}

}

&nbsp;

&nbsp;

onKeyPress(e) {

let feedbackMessageValue = e.target.value;

}

&nbsp;

&nbsp;

onChange(e) {

let feedbackMessageValue = e.target.value;

this.setState({

feedbackMessageValue: feedbackMessageValue

});

}

&nbsp;

&nbsp;

openModal() {

this.setState({

modalIsOpen: true

});

}

&nbsp;

&nbsp;

afterOpenModal() {

// references are now sync'd and can be accessed.

this.subtitle.style.color = '#f00';

}

&nbsp;

&nbsp;

closeModal() {

this.setState({

modalIsOpen: false

});

}

&nbsp;

&nbsp;

cancelModal() {

this.setState({

modalIsOpen: false,

showStars: true,

thankYou: false

})

}

&nbsp;

&nbsp;

render () {

const stars = [1,2,3,4,5];

const starRating = this.state.starRating;

const thankYou = this.state.thankYou;

const showStars = this.state.showStars;

&nbsp;

&nbsp;

return (

&nbsp;

&nbsp;

<div className="box">

<div className="answerFeedback">

{!thankYou ? <div className="title">Please rate this article:</div> : ""}

{showStars ? (  <div className="starsBox">

{

stars.map((star) => {

return(

<span

key={star}

className={`g72-star ${star<=starRating?'selectedStar':''}`}

onClick={(e) => this.handleStar(star)}>

</span>

)

})

}

</div>) : (<span></span>)

}

{thankYou ? <div className="thankYou">Thank you for your feedback!</div> : ""}

<div> {

//<button onClick={this.openModal}>Open Modal</button> }

<Modal

isOpen={this.state.modalIsOpen}

onAfterOpen={this.afterOpenModal}

onRequestClose={this.closeModal}

style={customStyles}

contentLabel="Example Modal">

&nbsp;

<h2 ref = { subtitle => this.subtitle = subtitle }>Provide Additional Information</h2>

<div className = "submittedMessage">Your rating has been submitted, please tell us how we can make this answer more useful.</div>

<div className = "faqQuestion">FAQ Feedback – How can we improve this answer? *</div>

<textarea

className = "feedbackMessage"

id = "feedbackMessage"

name = "feedbackMessage"

rows = "4"

cols = "50"

value = { this.state.feedbackMessageValue }

onKeyPress = { (e) => this.onKeyPress(e) }

onChange={(e) => this.onChange(e)}></textarea>

<div className="formButtons">

<button onClick = { this.submitAnswerFeedback } className="submitButton">Submit</button>

<button onClick = { this.cancelModal } className="cancelButton">Cancel</button>

</div>

&nbsp;

&nbsp;

</Modal>

</div>

</div>

<style jsx>{`

.answerFeedback .title {

font-weigth: bold;

}

.answerFeedback .g72-star {

font-size: 1.5em;

margin: 5px;

cursor: pointer;

color: #6d6b6b;

}

.answerFeedback .g72-star:hover, .selectedStar{

color: rgb(251, 224, 0) !important;

}

.starsBox {

background: #a09e9e;

border-radius: 10px;

padding: 0 10px;

width: 170px;

text-align: center;

}

.feedbackMessage {

border: 1px solid;

margin: 10px 10px 10px 0;

padding: 10px;

width: 100%;

}

.formButtons {

text-align: right;

}

.submitButton, .cancelButton {

width: 100%;

margin: 0;

padding: 10px;

font-weight: bold;

color: white;

text-transform: uppercase;

border-radius: 3px;

text-align: center;

text-decoration: none;

}

.submitButton {

background-color: rgba(250, 84, 0, 1);

}

.submitButton:hover {

background-color: #666;

}

.cancelButton {

background-color: rgb(153, 153, 153);

}

.cancelButton:hover {

background-color: #666;

}

.submitbutton:hover {

&nbsp;

&nbsp;

}

`}</style>

</div>

);

}

}
<pre>
Oracle AjaxCustom Service endpoint
function submitAnswerRating()
 {
 $answerID = $this-&amp;gt;input-&amp;gt;get('a_id');
 $rating = $this-&amp;gt;input-&amp;gt;get('rate');
 $scale = $this-&amp;gt;input-&amp;gt;get('options_count');
 if($answerID){
 if($this-&amp;gt;model('Answer')-&amp;gt;rate($answerID, $rating, $scale)){
 print "submitAnswerRating({'submitted':'true'})";
 }else{
 print "submitAnswerRating({'submitted':'false'})";
 }
 }
 }
 
 function getNewFormToken()
 {
 if($formToken = $this-&amp;gt;input-&amp;gt;get('formToken'))
 {
 $newToken = Framework::createTokenWithExpiration(0, false);
 print "getNewFormToken({'newToken':'" . $newToken . "'})";
 }
 }
 
 function submitAnswerFeedback()
 {
 AbuseDetection::check();
 $answerID = $this-&gt;input-&gt;get('a_id');
 if($answerID === 'null')
 $answerID = null;
 $rate = $this-&gt;input-&gt;get('rate');
 $message = $this-&gt;input-&gt;get('message');
 $givenEmail = '...@....com';
 $threshold = 3;
 $optionsCount = 5;
 $formToken = $this-&gt;input-&gt;get('f_tok');
 $incidentResult = $this-&gt;model('Incident')-&gt;submitFeedback($answerID, $rate, $threshold, null, $message, $givenEmail, $optionsCount);
 if($incidentResult-&gt;result){
 print "submitAnswerFeedback({'ID':'" . $incidentResult-&gt;result-&gt;ID . "'})";
 //$this-&gt;_renderJSON(array('ID' =&gt; $incidentResult-&gt;result-&gt;ID));
 }else{
 if($incidentResult-&gt;error){
 print "submitAnswerFeedback({'error 2':'" . $incidentResult-&gt;error-&gt;externalMessage . "'})";
 }
 }

trying out Gulp, node-modules for browerify, babel (to support/convert es6), & bootstrap

Monday, October 5th, 2015

gulpfile.js

var gulp = require('gulp'),
    babel = require('gulp-babel'),
    browserify = require('gulp-browserify'),
    jshint = require('gulp-jshint'),
    less = require('gulp-less'),
    path = require('path'),
    gp_concat = require('gulp-concat'),
    gp_rename = require('gulp-rename'),
    gp_uglify = require('gulp-uglify'),
    gp_sourcemaps = require('gulp-sourcemaps'),
    mainBowerFiles = require('main-bower-files'),
    minifyCSS = require('gulp-minify-css');

// Initial bootstrap setup
// Copy bootstrap from bower-components to public/lib
gulp.task('bower', function() {
    return gulp.src(mainBowerFiles(), {
            base: 'bower_components'
        })
        .pipe(gulp.dest('public/lib'));
});
// overwrite variables.less with our own edited version
gulp.task('bootstrap:prepareLess', ['bower'], function() {
    return gulp.src('public/lib/styles/less/variables.less')
        .pipe(gulp.dest('public/lib/bootstrap/less'));
});
// compile bootstrap less to css
gulp.task('bootstrap:compileLess', ['bootstrap:prepareLess'], function() {
    return gulp.src(['bower_components/bootstrap/less/bootstrap.less'])
    //return gulp.src('public/lib/bootstrap/less/bootstrap.less')
        .pipe(less())
        .pipe(gp_rename('bootstrap.css'))
        .pipe(gulp.dest('public/lib/styles/css'));
});
// End bootstrap setup

// concatenate css files altogether and minify
gulp.task('minifyCSS', function(){
    return gulp.src(['public/lib/styles/css/*.css'])
        .pipe(gp_concat('all.css'))
        .pipe(minifyCSS())
        .pipe(gp_rename('styles.min.css'))
        .pipe(gulp.dest('public/lib/styles/dist'));
});


// Lint/jshint JS
gulp.task('lint', function() {
    return gulp.src('public/lib/js/main.js')
        .pipe(jshint({'esnext': true}))
        .pipe(jshint.reporter('default'));
});


// Concatenate & Minify JS
gulp.task('scripts', function() {
    return gulp.src(['public/lib/js/main.js', 'pubilc/lib/bootstrap/dist/js/bootstrap.js'])
        .pipe(browserify({
            insertGlobals : true,
            debug : false
        }))
        .pipe(babel({compact: false}))
        .pipe(gp_concat('all.js'))
        .pipe(gp_rename('bundle.min.js'))
        .pipe(gp_uglify({ mangle: false }))
        .pipe(gulp.dest('public/lib/js/dist'));
});


// Just convert ES6
var paths = {
    es6: ['es6/myapp.js'],
    es5: 'es5',
    // Must be absolute or relative to source map
    sourceRoot: ('es6'),
};
gulp.task('babel', function () {
    return gulp.src(paths.es6)
        .pipe(gp_sourcemaps.init())
        .pipe(babel({compact: false}))
        .pipe(gp_sourcemaps.write('.', { sourceRoot: paths.sourceRoot }))
        .pipe(gp_rename('bundle.min.js'))
        .pipe(gulp.dest(paths.es5));
});


// start watch CSS & JS files for changes
gulp.task('watch', function() {
    gulp.watch(['public/lib/styles/**/*.*', 'public/lib/js/*.js'], ['lint', 'scripts', 'minifyCSS']);
});


// Default
gulp.task('default', ['lint', 'scripts', 'minifyCSS'], function(){});

Now let’s have a look at main.js using browerify’s require:

/*jshint strict:false */

let loadUnderscore = require('./loadunderscore');
loadUnderscore.logUnderscoreVersion();

let myUtils = require('./myutils');
myUtils.logDate();
myUtils.logMonth();

window.$ = window.jQuery = require('jquery');
require('jquery-ui');

// ES6 experiments, these ARE converted
var getName = () => "Hetal";

$(function(){
	$('#main').text('rewritten 10');
	console.log( $().jquery );
	/*alert('changed!');*/
	
	$( "#draggable" ).draggable();
});

// ES6 experiments, these are not converted/supported
/*
let developer = 'Alex';
console.log('Developer: ${developer}!');

let book = {
	author: 'John',
    title: 'Some Fancy Title'
};

$('#main').append('If you like ${author.name}, then read the new book, ${book.title}');
*/