web without framework
TRANSCRIPT
TEAM
• Software developper started with Java and then evolve to Scala
• Currently working on reactive solution using Akka.
• Some Knowledge of HTML, CSS and JavaScript
Well 2 guys !
PROJECT
• Perform data cleansing on csv file received by customers.
• Not technical user
• Get all the rules from the users to eventually process automatically
the files.
• Development time boxed to 20 days
USER INTERFACE ?
• Input is CSV
• Data manipulation evolving constantly
• Output is CSV
WHAT DO WE REALLY NEED ?
• Use Excel as UI
Never fits the needs
Learning curve / Dev time
HTML TableDSL / AceHTML Table
How to industrialise
• Existing mapping tool
• Framework (goJS, jointJS )
UI WEB FRAMEWORK ?
Evaluate, Read forums Do some tests
Got it !Learning curve
6 month later…StackOverflow Infinite Loop
DEV, NOT DESIGNER
• How to get it responsive !!
• Use a nice template (SmartAdmin)
• How to integrate with web framework
WHAT I WOULD LIKE
• Take the template and code the functionalities
• Use only one language for back and front
• User actions are events, just use the Actor Model.
• Need a state at the UI level, the Finite State Machine (FSM)
ARCHITECTURE
SmartAdmin
Browser
Ace Akka.js
uPickle
Scala.js
Akka
uPickle
Scala.js
Web Server
Akka
Files Processing
Apache Commons CSV
Asynchronous
Blocking
JSON
Akka messages
CALL SCALA FROM JS$(document).ready(function () { pageSetUp(); io.xtech.ui.client.FichierIntl().init();})
@JSExport("io.xtech.ui.client.FichierIntl") object FichierIntl { val webSocket = new WebSocket(getWebsocketUri(dom.document)) val system = ActorSystem("fichierIntl-ui") val fsm = system.actorOf(UIManagerActor.props(new ModalComponent()))
@JSExport def init(): Unit = { val socket = getWebSocket fsm ! UIInitialize(socket) } def getWebSocket: WebSocket = { webSocket.onmessage = { (event: MessageEvent) => val msg = read[userEvent](event.data.toString) msg match { case Stats(data) => fsm ! UIStats(data) case DSLStatement(ast) => fsm ! UINewDSL(ast) case Customers(cust) => fsm ! UICustomerList(cust) } webSocket.onclose = { (event: CloseEvent) ⇒ fsm ! UIResetToPageNotInitialized jQuery("#closedConnectionModal").modal("show") } webSocket }
class UIManagerActor(modal: ModalComponent) extends Actor with FSM[UIState, UIData] { def common: StateFunction = { // common code for all states case Event(msg@UICustomerList(cust), data) => logReceived(msg) modal.buildModalCustomerSelection(cust, data.socket.get) modal.buildModalFilesSelection(List.empty, data.socket.get) stay() }
CALL JS FROM SCALAfunction myFunction() { console.log(“Hello from Javascript”); }
@js.nativeobject MyCode extends js.Object { def myFunction(): Unit = js.native}
def foo { MyCode.myFunction() }
PRO / CONS
• Code Isomorphe
• Same paradigm
• Type Safe
• Team Building
• Setup (No pattern)
• Create UI components
• Debug Actor on client
• Understand JS signature