aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle.kts3
-rw-r--r--kvision-modules/kvision-toast/build.gradle.kts48
-rw-r--r--kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt38
-rw-r--r--kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt178
-rw-r--r--kvision-modules/kvision-toast/webpack.config.d/bootstrap.js3
-rw-r--r--kvision-modules/kvision-toast/webpack.config.d/css.js2
-rw-r--r--kvision-modules/kvision-toast/webpack.config.d/file.js9
-rw-r--r--settings.gradle.kts1
-rw-r--r--src/main/resources/css/style.css25
9 files changed, 306 insertions, 1 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 4f83c4b7..4a8e6607 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -130,7 +130,8 @@ tasks {
"kvision-tabulator",
"kvision-tabulator-remote",
"kvision-server-javalin",
- "kvision-server-vertx"
+ "kvision-server-vertx",
+ "kvision-toast"
)
multiplatform {
val js by creating {
diff --git a/kvision-modules/kvision-toast/build.gradle.kts b/kvision-modules/kvision-toast/build.gradle.kts
new file mode 100644
index 00000000..36ea4949
--- /dev/null
+++ b/kvision-modules/kvision-toast/build.gradle.kts
@@ -0,0 +1,48 @@
+buildscript {
+ extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true")
+}
+
+plugins {
+ kotlin("js")
+ id("maven-publish")
+}
+
+repositories()
+
+kotlin {
+ kotlinJsTargets()
+}
+
+dependencies {
+ implementation(kotlin("stdlib-js"))
+ api(rootProject)
+ implementation(npm("toastr", "2.1.4"))
+ testImplementation(kotlin("test-js"))
+}
+
+val sourcesJar by tasks.registering(Jar::class) {
+ archiveClassifier.set("sources")
+ from(kotlin.sourceSets.main.get().kotlin)
+}
+
+publishing {
+ publications {
+ create<MavenPublication>("kotlin") {
+ from(components["kotlin"])
+ artifact(tasks["sourcesJar"])
+ pom {
+ defaultPom()
+ }
+ }
+ }
+}
+
+setupPublication()
+
+tasks {
+ getByName("JsJar", Jar::class) {
+ from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") {
+ filter { it.replace("\"main\": \"kotlin/kvision-kvision", "\"main\": \"kvision-kvision") }
+ }
+ }
+}
diff --git a/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt
new file mode 100644
index 00000000..5c6e1441
--- /dev/null
+++ b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017-present Robert Jaros
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package pl.treksoft.kvision
+
+internal val kVManagerToastInit = KVManagerToast.init()
+
+/**
+ * Internal singleton object which initializes and configures KVision Toast module.
+ */
+internal object KVManagerToast {
+
+ init {
+ require("toastr/build/toastr.min.css")
+ }
+
+ internal val toastr = require("toastr/build/toastr.min.js")
+
+ internal fun init() {}
+}
diff --git a/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt
new file mode 100644
index 00000000..99201dc5
--- /dev/null
+++ b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2017-present Robert Jaros
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package pl.treksoft.kvision.toast
+
+import pl.treksoft.kvision.KVManagerToast
+import pl.treksoft.kvision.utils.obj
+
+/**
+ * Toast message types.
+ */
+internal enum class ToastType(internal val type: String) {
+ INFO("info"),
+ SUCCESS("success"),
+ WARNING("warning"),
+ ERROR("error")
+}
+
+/**
+ * Toast positions.
+ */
+enum class ToastPosition(internal val position: String) {
+ TOPRIGHT("toast-top-right"),
+ BOTTOMRIGHT("toast-bottom-right"),
+ BOTTOMLEFT("toast-bottom-left"),
+ TOPLEFT("toast-top-left"),
+ TOPFULLWIDTH("toast-top-full-width"),
+ BOTTOMFULLWIDTH("toast-bottom-full-width"),
+ TOPCENTER("toast-top-center"),
+ BOTTOMCENTER("toast-bottom-center")
+}
+
+/**
+ * Toast easings.
+ */
+enum class ToastEasing(internal val easing: String) {
+ SWING("swing"),
+ LINEAR("linear")
+}
+
+/**
+ * Toast animation methods.
+ */
+enum class ToastMethod(internal val method: String) {
+ FADEIN("fadeIn"),
+ FADEOUT("fadeOut"),
+ SLIDEUP("slideUp"),
+ SLIDEDOWN("slideDown"),
+ SHOW("show"),
+ HIDE("hide")
+}
+
+/**
+ * Toast options.
+ */
+data class ToastOptions(
+ val positionClass: ToastPosition? = null,
+ val escapeHtml: Boolean? = null,
+ val closeButton: Boolean? = null,
+ val closeHtml: String? = null,
+ val closeDuration: Int? = null,
+ val newestOnTop: Boolean? = null,
+ val showEasing: ToastEasing? = null,
+ val hideEasing: ToastEasing? = null,
+ val closeEasing: ToastEasing? = null,
+ val showMethod: ToastMethod? = null,
+ val hideMethod: ToastMethod? = null,
+ val closeMethod: ToastMethod? = null,
+ val preventDuplicates: Boolean? = null,
+ val timeOut: Int? = null,
+ val extendedTimeOut: Int? = null,
+ val progressBar: Boolean? = null,
+ val rtl: Boolean? = null,
+ val onShown: (() -> Unit)? = null,
+ val onHidden: (() -> Unit)? = null,
+ val onClick: (() -> Unit)? = null,
+ val onCloseClick: (() -> Unit)? = null
+)
+
+internal fun ToastOptions.toJs(): dynamic {
+ return obj {
+ if (positionClass != null) this.positionClass = positionClass.position
+ if (escapeHtml != null) this.escapeHtml = escapeHtml
+ if (closeButton != null) this.closeButton = closeButton
+ if (closeHtml != null) this.closeHtml = closeHtml
+ if (closeDuration != null) this.closeDuration = closeDuration
+ if (newestOnTop != null) this.newestOnTop = newestOnTop
+ if (showEasing != null) this.showEasing = showEasing.easing
+ if (hideEasing != null) this.hideEasing = hideEasing.easing
+ if (closeEasing != null) this.closeEasing = closeEasing.easing
+ if (showMethod != null) this.showMethod = showMethod.method
+ if (hideMethod != null) this.hideMethod = hideMethod.method
+ if (closeMethod != null) this.closeMethod = closeMethod.method
+ if (preventDuplicates != null) this.preventDuplicates = preventDuplicates
+ if (timeOut != null) this.timeOut = timeOut
+ if (extendedTimeOut != null) this.extendedTimeOut = extendedTimeOut
+ if (progressBar != null) this.progressBar = progressBar
+ if (rtl != null) this.rtl = rtl
+ if (onShown != null) this.onShown = onShown
+ if (onHidden != null) this.onHidden = onHidden
+ if (onClick != null) this.onClick = onClick
+ if (onCloseClick != null) this.onCloseClick = onCloseClick
+ }
+}
+
+/**
+ * Toast component object.
+ */
+object Toast {
+
+ /**
+ * Shows a success toast.
+ * @param message a toast message
+ * @param title a toast title
+ * @param options toast options
+ */
+ fun success(message: String, title: String? = null, options: ToastOptions? = null) {
+ show(ToastType.SUCCESS, message, title, options)
+ }
+
+ /**
+ * Shows an info toast.
+ * @param message a toast message
+ * @param title a toast title
+ * @param options toast options
+ */
+ fun info(message: String, title: String? = null, options: ToastOptions? = null) {
+ show(ToastType.INFO, message, title, options)
+ }
+
+ /**
+ * Shows a warning toast.
+ * @param message a toast message
+ * @param title a toast title
+ * @param options toast options
+ */
+ fun warning(message: String, title: String? = null, options: ToastOptions? = null) {
+ show(ToastType.WARNING, message, title, options)
+ }
+
+ /**
+ * Shows an error toast.
+ * @param message a toast message
+ * @param title a toast title
+ * @param options toast options
+ */
+ fun error(message: String, title: String? = null, options: ToastOptions? = null) {
+ show(ToastType.ERROR, message, title, options)
+ }
+
+ private fun show(type: ToastType, message: String, title: String? = null, options: ToastOptions? = null) {
+ if (options != null) {
+ KVManagerToast.toastr[type.type](message, title, options.toJs())
+ } else {
+ KVManagerToast.toastr[type.type](message, title)
+ }
+ }
+
+}
diff --git a/kvision-modules/kvision-toast/webpack.config.d/bootstrap.js b/kvision-modules/kvision-toast/webpack.config.d/bootstrap.js
new file mode 100644
index 00000000..35b28e6a
--- /dev/null
+++ b/kvision-modules/kvision-toast/webpack.config.d/bootstrap.js
@@ -0,0 +1,3 @@
+config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'});
+config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'});
+config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'});
diff --git a/kvision-modules/kvision-toast/webpack.config.d/css.js b/kvision-modules/kvision-toast/webpack.config.d/css.js
new file mode 100644
index 00000000..5d710d35
--- /dev/null
+++ b/kvision-modules/kvision-toast/webpack.config.d/css.js
@@ -0,0 +1,2 @@
+config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" });
+
diff --git a/kvision-modules/kvision-toast/webpack.config.d/file.js b/kvision-modules/kvision-toast/webpack.config.d/file.js
new file mode 100644
index 00000000..653ca21f
--- /dev/null
+++ b/kvision-modules/kvision-toast/webpack.config.d/file.js
@@ -0,0 +1,9 @@
+config.module.rules.push(
+ {
+ test: /\.(jpe?g|png|gif|svg)$/i,
+ loader: 'file-loader',
+ options: {
+ esModule: false,
+ },
+ }
+);
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 40c12aba..6860d1f8 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -48,6 +48,7 @@ include(
"kvision-modules:kvision-richtext",
"kvision-modules:kvision-tabulator",
"kvision-modules:kvision-tabulator-remote",
+ "kvision-modules:kvision-toast",
"kvision-modules:kvision-server-javalin",
"kvision-modules:kvision-server-jooby",
"kvision-modules:kvision-server-ktor",
diff --git a/src/main/resources/css/style.css b/src/main/resources/css/style.css
index cae50162..69f4b218 100644
--- a/src/main/resources/css/style.css
+++ b/src/main/resources/css/style.css
@@ -443,3 +443,28 @@ ul.typeahead > li.active > a {
text-decoration: none;
background-color: #f8f9fa;
}
+
+#toast-container .toast {
+ background-color: #030303;
+ max-width: inherit;
+}
+
+#toast-container .toast-success {
+ background-color: #51A351;
+}
+
+#toast-container .toast-error {
+ background-color: #BD362F;
+}
+
+#toast-container .toast-info {
+ background-color: #2F96B4;
+}
+
+#toast-container .toast-warning {
+ background-color: #F89406;
+}
+
+#toast-container .toast-progress {
+ background-color: #000000;
+}