Skip to content

Commit

Permalink
Merge pull request #7 from kostaskougios/0.30d
Browse files Browse the repository at this point in the history
0.30d
  • Loading branch information
kostaskougios authored Mar 8, 2024
2 parents 14f756f + 6ef7e4e commit 5330a39
Show file tree
Hide file tree
Showing 119 changed files with 4,328 additions and 2,129 deletions.
44 changes: 32 additions & 12 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,28 @@ Let's create a simple hello world script in scala-cli that uses terminal21 serve
```scala
import org.terminal21.client.*
import org.terminal21.client.components.*
// std components like Paragraph, https://github.com/kostaskougios/terminal21-restapi/blob/main/terminal21-ui-std/src/main/scala/org/terminal21/client/components/StdElement.scala
import org.terminal21.client.components.std.*

Sessions.withNewSession("hello-world", "Hello World Example"): session =>
Sessions
.withNewSession("hello-world", "Hello World Example")
.connect: session =>
given ConnectedSession = session
Seq(
Paragraph(text = "Hello World!")
).render()
session.waitTillUserClosesSession()

Controller.noModel(Paragraph(text = "Hello World!")).render()
// since this is a read-only UI, we can exit the app but leave the session open on the UI for the user to examine the data.
session.leaveSessionOpenAfterExiting()
```

If we run this, then we can point our browser to the server, and we will see this UI:

![hello world ui](docs/images/hello-world.png)

The script will wait until the user clicks the close button, which then will invalidate the
session it has with the server and terminate the app.

![hello world ui](docs/images/hello-world-terminated.png)
The script will wait until the user clicks the close button and then the script will terminate.

# Usecases

Due to it's client-server architecture, terminal21 gives a UI to scripts running i.e. on servers without a desktop environment and
Due to its client-server architecture, terminal21 gives a UI to scripts running i.e. on servers without a desktop environment and
can be used for things like:
- creating text file editors which run on desktop-less servers but still allows us to edit the text file on our browser, see [textedit.sc](example-scripts/textedit.sc)

Expand All @@ -122,7 +123,7 @@ can be used for things like:

# Available UI Components

Standard html elements
Standard html elements like paragraphs, headers, cookies etc
[Std](docs/std.md)

Generic components for buttons, menus, forms, text, grids, tables:
Expand All @@ -139,6 +140,14 @@ Maths:

Spark:
[Spark](docs/spark.md)

# Apps running on server

User applications can run on the terminal21 server so that they are always available. The api is the same but a bit of extra wiring is required
for the terminal21 server to be able to use them.

See [running apps on the server][docs/run-on-server.md]

# Architecture

Terminal21 consist of :
Expand All @@ -156,14 +165,25 @@ the state in the client scripts.
terminal21 ui components are immutable from v0.20. Use `component.withX(...).renderChanges()` to modify a component
and render it. Note that the original `component` is not changed.

Also when getting a value of i.e. an Input, use `myInput.current.value`. `current` makes sure we read the component with
Also, when getting a value of i.e. an Input, use `myInput.current.value`. `current` makes sure we read the component with
all changes that may have occurred at the browser and all the changes we did on our script.

# Need help?

Please use the [discussions](https://github.com/kostaskougios/terminal21-restapi/discussions) of the project to post any questions, comments or ideas.

# Changelog

## Version 0.30

- apps can now run on the server + server management bundled apps
- Cookie setter and reader.
- session builders refactoring for more flexible creation of sessions
- QuickTabs, QuickFormControl
- bug fix for old react state re-rendering on new session
- event iterators allows idiomatic handling of events and overhaul of the event handling for easier testing and easier development of larger apps
- MVC

## Version 0.21

- more std and chakra components like Alert, Progress, Tooltip, Tabs.
Expand Down
35 changes: 25 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import sbt.librarymanagement.ModuleFilter

/** This build has different sections for each integration. I.e. an http4s section and a kafka section. These sections are not related to each other, please
* examine the section you're interested in.
*/
val scala3Version = "3.3.1"
val scala3Version = "3.3.3"

ThisBuild / version := "0.21"
ThisBuild / version := "0.30"
ThisBuild / organization := "io.github.kostaskougios"
name := "rest-api"
ThisBuild / scalaVersion := scala3Version
Expand All @@ -27,8 +25,9 @@ val FunctionsHelidonClient = "io.github.kostaskougios" %% "helidon-client"
val FunctionsHelidonWsClient = "io.github.kostaskougios" %% "helidon-ws-client" % FunctionsVersion
val FunctionsFibers = "io.github.kostaskougios" %% "fibers" % FunctionsVersion

val ScalaTest = "org.scalatest" %% "scalatest" % "3.2.15" % Test
val ScalaTest = "org.scalatest" %% "scalatest" % "3.2.18" % Test
val Mockito = "org.mockito" % "mockito-all" % "2.0.2-beta" % Test
val Mockito510 = "org.scalatestplus" %% "mockito-5-10" % "3.2.18.0" % Test
val Scala3Tasty = "org.scala-lang" %% "scala3-tasty-inspector" % scala3Version
val CommonsText = "org.apache.commons" % "commons-text" % "1.10.0"
val CommonsIO = "commons-io" % "commons-io" % "2.11.0"
Expand All @@ -51,10 +50,10 @@ val HelidonServerLogging = "io.helidon.logging" % "helidon-logging-jul"
val LogBack = "ch.qos.logback" % "logback-classic" % "1.4.14"
val Slf4jApi = "org.slf4j" % "slf4j-api" % "2.0.9"

val SparkSql = ("org.apache.spark" %% "spark-sql" % "3.5.0" % "provided").cross(CrossVersion.for3Use2_13).exclude("org.scala-lang.modules", "scala-xml_2.13")
val SparkSql = ("org.apache.spark" %% "spark-sql" % "3.5.1" % "provided").cross(CrossVersion.for3Use2_13).exclude("org.scala-lang.modules", "scala-xml_2.13")
val SparkScala3Fix = Seq(
"io.github.vincenzobaz" %% "spark-scala3-encoders" % "0.2.5",
"io.github.vincenzobaz" %% "spark-scala3-udf" % "0.2.5"
"io.github.vincenzobaz" %% "spark-scala3-encoders" % "0.2.6",
"io.github.vincenzobaz" %% "spark-scala3-udf" % "0.2.6"
).map(_.exclude("org.scala-lang.modules", "scala-xml_2.13"))

// -----------------------------------------------------------------------------------------------
Expand All @@ -68,7 +67,7 @@ val commonSettings = Seq(
lazy val `terminal21-server-client-common` = project
.settings(
commonSettings,
libraryDependencies ++= Seq(
libraryDependencies ++= Circe ++ Seq(
ScalaTest,
Slf4jApi,
HelidonClientWebSocket,
Expand Down Expand Up @@ -102,6 +101,19 @@ lazy val `terminal21-server` = project
.dependsOn(`terminal21-ui-std-exports` % "compile->compile;test->test", `terminal21-server-client-common`)
.enablePlugins(FunctionsRemotePlugin)

lazy val `terminal21-server-app` = project
.settings(
commonSettings,
libraryDependencies ++= Seq(
Mockito510
)
)
.dependsOn(
`terminal21-server` % "compile->compile;test->test",
`terminal21-ui-std` % "compile->compile;test->test",
`terminal21-server-client-common` % "compile->compile;test->test"
)

lazy val `terminal21-ui-std-exports` = project
.settings(
commonSettings,
Expand Down Expand Up @@ -129,6 +141,7 @@ lazy val `terminal21-ui-std` = project
libraryDependencies ++= Seq(
ScalaTest,
Mockito,
Mockito510,
Slf4jApi,
HelidonClient,
FunctionsCaller,
Expand All @@ -147,9 +160,10 @@ lazy val `terminal21-ui-std` = project
lazy val `end-to-end-tests` = project
.settings(
commonSettings,
publish := {},
libraryDependencies ++= Seq(ScalaTest, LogBack)
)
.dependsOn(`terminal21-ui-std`, `terminal21-nivo`, `terminal21-mathjax`)
.dependsOn(`terminal21-ui-std` % "compile->compile;test->test", `terminal21-nivo`, `terminal21-mathjax`)

lazy val `terminal21-nivo` = project
.settings(
Expand Down Expand Up @@ -185,6 +199,7 @@ lazy val `terminal21-mathjax` = project
lazy val `terminal21-code-generation`: Project = project
.settings(
commonSettings,
publish := {},
libraryDependencies ++= Seq(
ScalaTest,
Scala3Tasty,
Expand Down
32 changes: 32 additions & 0 deletions docs/quick.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ simplify creation of this components.

## QuickTable

This class helps creating tables quickly.

```scala
val conversionTable = QuickTable().headers("To convert", "into", "multiply by")
.caption("Imperial to metric conversion factors")
Expand All @@ -14,3 +16,33 @@ val tableRows:Seq[Seq[String]] = Seq(
)
conversionTable.rows(tableRows)
```

## QuickTabs

This class simplifies the creation of tabs.

```scala

QuickTabs()
.withTabs("Tab 1", "Tab 2")
.withTabPanels(
Paragraph(text="Tab 1 content"),
Paragraph(text="Tab 2 content")
)

```

## QuickFormControl

Simplifies creating forms.

```scala
QuickFormControl()
.withLabel("Email address")
.withHelperText("We'll never share your email.")
.withInputGroup(
InputLeftAddon().withChildren(EmailIcon()),
emailInput,
InputRightAddon().withChildren(CheckCircleIcon())
)
```
32 changes: 32 additions & 0 deletions docs/run-on-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Running applications on the server

To create an app that runs on the server, implement the `ServerSideApp` trait and then pass your implementation to the `start()` method of the server:

```scala
class MyServerApp extends ServerSideApp:
override def name = "My Server App"

override def description = "Some app that I want to be available when I start the server"

override def createSession(serverSideSessions: ServerSideSessions, dependencies: Dependencies): Unit =
serverSideSessions
.withNewSession("my-server-app-session", name)
.connect: session =>
given ConnectedSession = session
... your app code ...
```

See for example the [default terminal21 apps](../terminal21-server-app/src/main/scala/org/terminal21/serverapp/bundled).

Now make sure your app is included in the server's classpath and then pass it as an argument to `start()`, i.e. with this `scala-cli` script:

```scala
//> ...
//> using dep MY_APP_DEP

import org.terminal21.server.Terminal21Server

Terminal21Server.start(apps = Seq(new MyServerApp))
```

Now start the server and the app should be available in the app list of terminal21.
15 changes: 15 additions & 0 deletions docs/std.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,19 @@ Header1(text = "Welcome to the std components demo/test")
val output = Paragraph(text = "This will reflect what you type in the input")
input.onChange: newValue =>
output.withText(newValue).renderChanges()
```

### Cookies

Set a cookie:

```scala
Cookie(name = "cookie-name", value = "cookie value")
```

Read a cookie:

```scala
val cookieReader = CookieReader(key = "cookie-reader", name = "cookie-name")
val cookieValue = events.changedValue(cookieReader)
```
Loading

0 comments on commit 5330a39

Please sign in to comment.