Adding dropdowns for Bank,Account,View to prepopulate URL

This commit is contained in:
Simon Redfern 2015-10-05 16:35:54 +02:00
parent 56eff62ae9
commit f120655350
3 changed files with 175 additions and 15 deletions

View File

@ -67,7 +67,7 @@ object ObpAPI extends Loggable {
ObpGet("/v1.2/banks/" + urlEncode(bankId) + "/accounts/" + urlEncode(accountId) + "/" + urlEncode(viewId) +
"/transactions", headers).flatMap(x => x.extractOpt[TransactionsJson])
}
def publicAccounts(bankId : String) : Box[BarebonesAccountsJson] = {
ObpGet("/v1.2/banks/" + urlEncode(bankId) + "/accounts/public").flatMap(_.extractOpt[BarebonesAccountsJson])
}
@ -84,6 +84,15 @@ object ObpAPI extends Loggable {
ObpGet("/v1.2.1/accounts/private").flatMap(_.extractOpt[BarebonesAccountsJson])
}
def allAccountsAtOneBank(bankId : String) : Box[BarebonesAccountsJson] = {
ObpGet("/v1.4.0/banks/" + urlEncode(bankId) + "/accounts").flatMap(_.extractOpt[BarebonesAccountsJson])
}
// Similar to getViews below
def getViewsForBankAccount(bankId: String, accountId: String) = {
ObpGet("/v1.2.1/banks/" + bankId + "/accounts/" + accountId + "/views").flatMap(_.extractOpt[ViewsJson])
}
def getAccount(bankId: String, accountId: String, viewId: String) : Box[AccountJson] = {
ObpGet("/v1.2/banks/" + urlEncode(bankId) + "/accounts/" + urlEncode(accountId) + "/" + urlEncode(viewId) + "/account").flatMap(x => x.extractOpt[AccountJson])
}
@ -156,6 +165,7 @@ object ObpAPI extends Loggable {
}
def getViews(bankId: String, accountId: String) : Box[List[ViewJson]] = {
// Note function of similar name above
for {
json <- ObpGet("/v1.2.1/banks/" + bankId + "/accounts/" + accountId + "/views")
viewsJson <- Box(json.extractOpt[ViewsJson])

View File

@ -1,8 +1,10 @@
package code.snippet
import _root_.net.liftweb._
import code.lib.ObpJson.ResourceDoc
import code.lib.{ObpPut, ObpDelete, ObpPost, ObpGet}
import code.lib.ObpJson.{BarebonesAccountJson, BarebonesAccountsJson, ResourceDoc}
import code.lib._
import net.liftweb.http.js.jquery.JqJsCmds.DisplayMessage
//import code.snippet.CallUrlForm._
import net.liftweb.http.{SHtml, S}
@ -19,26 +21,59 @@ import net.liftweb.json._
import common._
import net.liftweb.util.Helpers._
import net.liftweb.http.SHtml.{text,ajaxSubmit, textarea}
import net.liftweb.http.SHtml.{text,ajaxSubmit, textarea, select, ajaxSelect}
import net.liftweb.http.js.JsCmd
import net.liftweb.http.js.JsCmds.{Run, SetHtml}
import net.liftweb.json.Serialization.writePretty
import code.lib.ObpAPI.getResourceDocsJson
import code.lib.ObpAPI.{getResourceDocsJson, allBanks, allAccountsAtOneBank}
import net.liftweb.markdown._
/*
Present a list of OBP resource URLs
*/
class ApiExplorer extends Loggable {
val presetBankId = S.param("bank_id").getOrElse("")
logger.info(s"bank_id in url param is $presetBankId")
val presetAccountId = S.param("account_id").getOrElse("")
logger.info(s"account_id in url param is $presetAccountId")
val presetViewId = S.param("view_id").getOrElse("")
logger.info(s"account_id in url param is $presetViewId")
def stringToNodeSeq(html : String) : NodeSeq = {
scala.xml.XML.loadString("<div>" + html + "</div>")
}
def modifiedRequestUrl(url: String, presetBankId: String, presetAccountId: String) = {
// Potentially replace BANK_ID
val url2: String = presetBankId match {
case "" => url
case _ => url.replaceAll("BANK_ID", presetBankId)
}
// Potentially replace ACCOUNT_ID
val url3: String = presetAccountId match {
case "" => url2
case _ => url2.replaceAll("/ACCOUNT_ID", s"/$presetAccountId") // so we don't change OTHER_ACCOUNT_ID
}
// Potentially replace VIEW_ID
val url4: String = presetViewId match {
case "" => url3
case _ => url3.replaceAll("VIEW_ID", presetViewId)
}
url4
}
def showResources = {
// Get the requested version from the url parameter and default if none
@ -56,10 +91,7 @@ class ApiExplorer extends Loggable {
// The overview contains html. Just need to convert it to a NodeSeq so the template will render it as such
val resources = for {
r <- getResourceDocsJson.map(_.resource_docs).get
} yield ResourceDoc(id = r.operation_id, verb = r.request_verb, url = r.request_url, summary = r.summary, description = stringToNodeSeq(r.description), example_request_body = r.example_request_body)
} yield ResourceDoc(id = r.operation_id, verb = r.request_verb, url = modifiedRequestUrl(r.request_url, presetBankId, presetAccountId), summary = r.summary, description = stringToNodeSeq(r.description), example_request_body = r.example_request_body)
// Controls when we display the request body.
def displayRequestBody(resourceVerb : String) = {
@ -79,7 +111,7 @@ class ApiExplorer extends Loggable {
var requestVerb = ""
var requestUrl = ""
var requestBody = "{}"
var sOverView = "" // not used
//var sOverView = "" // not used
def process(): JsCmd = {
logger.info(s"requestUrl is $requestUrl")
@ -139,22 +171,118 @@ class ApiExplorer extends Loggable {
responseBody
}
val banks = allBanks
def onBankChange (v: Any) = {
logger.info("bank changed to " + v.toString)
S.redirectTo(s"api-explorer?bank_id=${v}&account_id=${presetAccountId}&view_id=${presetViewId}")
}
def onAccountChange (v: Any) = {
logger.info("account changed to " + v.toString)
S.redirectTo(s"api-explorer?bank_id=${presetBankId}&account_id=${v}&view_id=${presetViewId}")
}
def onViewChange (v: Any) = {
logger.info("view changed to " + v.toString)
S.redirectTo(s"api-explorer?bank_id=${presetBankId}&account_id=${presetAccountId}&view_id=${v}")
}
// Get a list of tuples List(("bank short name", "id"),("bank two", "id2")) to populate the drop down select list.
// Could we write this in a way such that if there are no banks the doBankSelect is not run?
val bankOptions = ("", "Select Bank") :: banks.map(b => b.bankJsons.map(bj => (bj.id.getOrElse(""), bj.short_name.getOrElse("")))).getOrElse(List(("", "No Banks")))
// TODO create BankId case class like in the API
type BankID = String
val privateAccountJsons : List[(String, String)] = for {
privateAccountsJson <- ObpAPI.allAccountsAtOneBank(presetBankId).toList
barebonesAccountJson <- privateAccountsJson.accounts.toList.flatten
//bankId <- barebonesAccountJson.bank_id
accountId <- barebonesAccountJson.id
label <- barebonesAccountJson.label
} yield (accountId, label)
def getAccountOptions : List[(String,String)] = {
val selectAccount = ("", "Select Account")
val noneFound = ("", "No Accounts Found")
val options: List[(String, String)] = presetBankId match {
case "" => List(noneFound)
case _ => for {
allAccountsJson <- ObpAPI.allAccountsAtOneBank(presetBankId).toList
barebonesAccountJson <- allAccountsJson.accounts.toList.flatten
accountId <- barebonesAccountJson.id
label <- barebonesAccountJson.label
} yield (accountId, label)
}
selectAccount :: options
}
def getViewOptions : List[(String,String)] = {
val selectOne = ("", "Select View")
val noneFound = ("", "No Views Found")
// TODO Should check for both presetBankId and presetAccountId
val options: List[(String, String)] = presetAccountId match {
case "" => List(noneFound)
case _ => for {
views <- ObpAPI.getViewsForBankAccount(presetBankId, presetAccountId).toList
view <- views.views.toList.flatten
viewId <- view.id
shortName <- view.short_name
} yield (viewId, shortName)
}
selectOne :: options
}
// Drop down box to select bank. Selected item taken from url param.
def doBankSelect(in: NodeSeq) = ajaxSelect(bankOptions,
Full(presetBankId),
v => onBankChange(v))
// Drop down box to select account. Selected item taken from url param.
def doAccountSelect(in: NodeSeq) = ajaxSelect(getAccountOptions,
Full(presetAccountId),
v => onAccountChange(v))
// Drop down box to select view for bank/account. Selected item taken from url param.
def doViewSelect(in: NodeSeq) = ajaxSelect(getViewOptions,
Full(presetViewId),
v => onViewChange(v))
// In case we use Extraction.decompose
implicit val formats = net.liftweb.json.DefaultFormats
"#bank_selector" #> doBankSelect _ &
"#account_selector" #> doAccountSelect _ &
"#view_selector" #> doViewSelect _ &
//
//
// Below we render the resources into a (nested) table.
// Notes on escaping strings:
// To have a $ in the resulting string use two: $$
// Can't escape " with \" or use triple quoted string in the string interpolation so may need to use the replace hack
//
// Note: This is the return of the function.
// All the replacements you want to do *must be chained here together at the end of the function*.
// Also, you can't use "replaceWith" (the alias for #>) to chain
//
// See the following for some examples.
// http://blog.knoldus.com/2013/03/08/lift-web-basics-of-using-snippets-for-a-beginner/
// http://simply.liftweb.net/index-7.10.html
//
// Show the version to the user.
// Append to the content child of id="version" e.g. the fixed text "Version:" is replacedWith "Version: 1.2.3"
"#version *+" #> apiVersion &
@ -170,7 +298,7 @@ class ApiExplorer extends Loggable {
".resource_url_td [id]" #> s"resource_url_td_${i.id}" & // Probably don't need this now
".resource_verb_td [id]" #> s"resource_verb_td_${i.id}" & // Probably don't need this now
".url_caller [id]" #> s"url_caller_${i.id}" &
// ".try_me_button [onclick]" #> s"$$(DOUBLE-QUOTE#url_caller_${i.id}DOUBLE-QUOTE).fadeToggle();".replaceAll("DOUBLE-QUOTE",""""""") &
// ".try_me_button [onclick]" #> s"$$(DOUBLE-QUOTE#url_caller_${i.id}DOUBLE-QUOTE).fadeToggle();".replaceAll("DOUBLE-QUOTE","""") &
".result [id]" #> s"result_${i.id}" &
"@example_request_body [id]" #> s"example_request_body_${i.id}" &
"@example_request_body [style]" #> s"display: ${displayRequestBody(i.verb)};" &

View File

@ -10,6 +10,28 @@
<div class="lift:Msgs"></div>
<div>
<select id="bank_selector">
<option value="bank_id1">Bank 1</option>
<option value="bank_id2">Bank 2</option>
</select>
<select id="account_selector">
<option value="account_id1">Account 1</option>
<option value="account_id2">Account 2</option>
</select>
<select id="view_selector">
<option value="view_id_1">Owner</option>
<option value="view_id_2">Accountant</option>
</select>
<!--
<select name="counterparty_selector">
<option value="other_account_id_1">Counterparty 1</option>
<option value="other_account_id_2">Counterparty 2</option>
</select>
-->
</div>
<table>
<!-- Each URL we document appears in a row, inside a table -->