Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class MapControlStandaloneExpanded(params:MapControlsParams, title:String, selec
if (geometry.nonEmpty) controlButton(Icons.move, SharedLabels.map.move, Control.MOVE,nested) else frag(),
if (geometry.size > 1) controlButton(Icons.trash, SharedLabels.map.delete, Control.DELETE,nested) else frag(),
if (geometry.size == 1) {
val (el,tt) = WidgetUtils.addTooltip(Some(SharedLabels.map.delete))(button(ClientConf.style.mapButton)(
val (el,tt) = WidgetUtils.addTooltip(Some(Labels(SharedLabels.map.delete)))(button(ClientConf.style.mapButton)(
onclick :+= { (e: Event) =>
if(dom.window.confirm(SharedLabels.form.removeMap)) {
sourceMap(_.clear())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.scalajs.dom.{File, FormData, XMLHttpRequest}
import scribe.Logging

import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.scalajs.js

/**
* Created by andre on 4/26/2017.
Expand All @@ -25,6 +26,7 @@ trait HttpClient{
def maybeGet[T](url: String)(implicit decoder: io.circe.Decoder[T], ex:ExecutionContext): Future[Option[T]]
def delete[T](url: String)(implicit decoder: io.circe.Decoder[T], ex:ExecutionContext): Future[T]
def sendFile[T](url: String, file: File)(implicit decoder: io.circe.Decoder[T], ex:ExecutionContext):Future[T]
def sendRaw[T](url: String, data: js.Any)(implicit decoder: io.circe.Decoder[T], ex:ExecutionContext):Future[T]
def setHandleAuthFailure(f:() => Unit)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ object Labels {
def confirmRevert = get(SharedLabels.entity.confirmRevert)
def csv = get(SharedLabels.entity.csv)
def xls = get(SharedLabels.entity.xls)
def importxls = get(SharedLabels.entity.importxls)
def shp = get(SharedLabels.entity.shp)
def geoPackage = get(SharedLabels.entity.geopackage)
}
Expand Down
2 changes: 2 additions & 0 deletions client/src/main/scala/ch/wsl/box/client/services/REST.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ trait REST{
//files
def sendFile(file:File, id:JSONID, entity:String)(implicit ec:ExecutionContext): Future[Int]

def importXLS(kind:String, lang:String, entity:String,data:File)(implicit ec:ExecutionContext):Future[Int]

//other utilsString
def login(request:LoginRequest)(implicit ec:ExecutionContext):Future[UserInfo]
def authenticate(code:String,provider_id:String)(implicit ec:ExecutionContext):Future[UserInfo]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.scalajs.dom.{File, FormData, XMLHttpRequest}
import scribe.Logging

import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future, Promise}
import scala.scalajs.js

class HttpClientImpl extends HttpClient with Logging {

Expand Down Expand Up @@ -183,6 +184,13 @@ class HttpClientImpl extends HttpClient with Logging {

}.map(handle404)

override def sendRaw[T](url: String, data: js.Any)(implicit decoder: Decoder[T], ex: ExecutionContext): Future[T] = {
httpCallWithNoticeInterceptor[T]("POST", url, file = true) { xhr =>
xhr.send(data)
}

}.map(handle404)

private var handleAuthFailure: () => Unit = () => {}
override def setHandleAuthFailure(f: () => Unit): Unit = {
handleAuthFailure = f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ class RestImpl(httpClient:HttpClient) extends REST with Logging {
//files
def sendFile(file:File, id:JSONID, entity:String)(implicit ec:ExecutionContext): Future[Int] = httpClient.sendFile[Int](Routes.apiV1(s"/file/$entity/${id.asString}"),file)

override def importXLS(kind: String, lang: String, entity: String, data: File)(implicit ec:ExecutionContext): Future[Int] = {
for{
bytea <- data.arrayBuffer().toFuture
count <- httpClient.sendRaw[Int](Routes.apiV1(s"/$kind/$lang/$entity/xlsx/import"),bytea)
} yield count
}

//other utilsString
def login(request:LoginRequest)(implicit ec:ExecutionContext) = httpClient.post[LoginRequest,UserInfo](Routes.apiV1("/login"),request)
def authenticate(code:String,provider_id:String)(implicit ec:ExecutionContext) = httpClient.get[UserInfo](Routes.apiV1(s"/sso/$provider_id?code=$code"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,29 @@ case class EntityTablePresenter(model:ModelProperty[EntityTableModel], onSelect:
e.preventDefault()
}

val importXLS = (e:Event) => {

val kind = EntityKind(model.subProp(_.kind).get).entityOrForm
val modelName = model.subProp(_.name).get
val lang = services.clientSession.lang()

import scalatags.JsDom.all._
val el = input(`type` := "file", accept := ".xlsx").render
el.onchange = (ev: Event) => {
ev.preventDefault()
el.files.headOption match {
case Some(file) => services.rest.importXLS(kind,lang,modelName,file).map{ i =>
Notification.add(Labels(s"Imported $i rows"))
println("reload rows AAAAA")
reloadRows(model.get.pages)
}
case None => Notification.add(Labels("No files found"))
}
}
el.click()
e.preventDefault()
}

private def download(format:String) = {

val kind = EntityKind(model.subProp(_.kind).get).entityOrForm
Expand Down Expand Up @@ -1124,6 +1147,7 @@ case class EntityTableView(model:ModelProperty[EntityTableModel], presenter:Enti
tableContent(metadata),
button(`type` := "button", onclick :+= presenter.downloadCSV, ClientConf.style.boxButton, Labels.entity.csv),
button(`type` := "button", onclick :+= presenter.downloadXLS, ClientConf.style.boxButton, Labels.entity.xls),
button(`type` := "button", onclick :+= presenter.importXLS, ClientConf.style.boxButton, Labels.entity.importxls),
if (presenter.hasGeometry()) {
Seq(
//button(`type` := "button", onclick :+= presenter.downloadSHP, ClientConf.style.boxButton, Labels.entity.shp),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import io.circe.{Decoder, Encoder}
import org.scalajs.dom.File

import scala.concurrent.{ExecutionContext, Future}
import scala.scalajs.js

class HttpClientMock extends HttpClient {
override def post[D, R](url: String, obj: D)(implicit decoder: Decoder[R], encoder: Encoder[D], ec:ExecutionContext): Future[R] = throw new Exception("post not implemented")
Expand All @@ -21,5 +22,7 @@ class HttpClientMock extends HttpClient {

override def sendFile[T](url: String, file: File)(implicit decoder: Decoder[T], ec:ExecutionContext): Future[T] = throw new Exception("sendFile not implemented")

override def sendRaw[T](url: String, data: js.Any)(implicit decoder: Decoder[T], ex: ExecutionContext): Future[T] = ???

override def setHandleAuthFailure(f: () => Unit): Unit = {}
}
2 changes: 2 additions & 0 deletions client/src/test/scala/ch/wsl/box/client/mocks/RestMock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ class RestMock(values:Values) extends REST with Logging {
???
}

override def importXLS(kind: String, lang: String, entity: String, data: File)(implicit ec:ExecutionContext): Future[Int] = ???

val userInfo = UserInfo("t","t",None,Seq(),Json.Null)
override def login(request: LoginRequest)(implicit ec:ExecutionContext): Future[UserInfo] = Future.successful{
userInfo
Expand Down
2 changes: 2 additions & 0 deletions project/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ object Settings {
"com.github.spullara.mustache.java" % "compiler" % "0.9.6",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.10.3",
"com.norbitltd" %% "spoiwo" % "2.2.1",
"org.apache.poi" % "poi" % "5.2.5",
"org.apache.poi" % "poi-ooxml" % "5.2.5",
"io.github.cquiroz" %% "scala-java-time" % "2.0.0",
"com.nrinaudo" %% "kantan.csv" % versions.kantan,
"org.wvlet.airframe" %%% "airframe" % versions.airframe,
Expand Down
32 changes: 28 additions & 4 deletions server/src/main/scala/ch/wsl/box/rest/io/xls/XLS.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package ch.wsl.box.rest.io.xls

import java.io.ByteArrayOutputStream

import akka.http.scaladsl.model.{HttpEntity, HttpResponse, MediaTypes}
import akka.http.scaladsl.model.{ContentType, HttpEntity, HttpResponse, MediaTypes, StatusCodes}
import akka.http.scaladsl.model.headers.{ContentDispositionTypes, `Content-Disposition`}
import akka.http.scaladsl.server.Directives.{complete, get, parameters, path, respondWithHeader}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.directives.AuthenticationDirective
import ch.wsl.box.jdbc.UserDatabase
import ch.wsl.box.model.shared.{JSONMetadata, XLSTable}
import ch.wsl.box.rest.logic.{JSONTableActions, TableActions}
import ch.wsl.box.services.Services
import io.circe.Json
import slick.dbio.DBIO

import ch.wsl.box.model.shared.{XLSTable}
import scala.concurrent.ExecutionContext
import scala.util.{Failure, Success}


object XLS {
Expand All @@ -22,4 +29,21 @@ object XLS {
}
}
}

def importXls(metadata:JSONMetadata,actions:TableActions[Json],db:UserDatabase)(implicit ec:ExecutionContext, services:Services):Route = post{
entity(as[Array[Byte]]) { data =>

val insertData = for {
data <- new XLSImport(db).xlsToJson(data, metadata)
insert <- db.run {
DBIO.sequence {
data.map(row => actions.insert(row))
}
}
} yield HttpResponse(entity = HttpEntity(MediaTypes.`application/json`, insert.length.toString))

completeOrRecoverWith(insertData) { ex => complete(StatusCodes.BadRequest, ex.toString) }

}
}
}
Loading
Loading