aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle16
-rw-r--r--gradle.properties10
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin54329 -> 54329 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties3
-rw-r--r--kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/types/Date.kt (renamed from src/main/kotlin/pl/treksoft/kvision/types/KDate.kt)17
-rw-r--r--kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt2
-rw-r--r--kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt10
-rw-r--r--kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt43
-rw-r--r--kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt4
-rw-r--r--kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt4
-rw-r--r--kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt5
-rw-r--r--kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt5
-rw-r--r--kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt2
-rw-r--r--kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt11
-rw-r--r--kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt2
-rw-r--r--kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt42
-rw-r--r--kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt2
-rw-r--r--kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt7
-rw-r--r--kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/ServiceManager.kt40
-rw-r--r--kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Date.kt (renamed from kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt)24
-rw-r--r--kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt2
-rw-r--r--kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt28
-rw-r--r--kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt2
-rw-r--r--kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt56
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/core/Widget.kt2
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt2
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt19
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/Form.kt24
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt10
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt6
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt4
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt4
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt4
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/html/Template.kt2
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt2
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt1
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt16
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt4
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt4
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt6
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt12
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt307
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/remote/Security.kt1
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/table/Table.kt2
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/types/Date.kt65
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/utils/JSON.kt (renamed from kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt)32
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt24
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/window/Window.kt6
-rw-r--r--src/test/kotlin/test/pl/treksoft/kvision/panel/RootSpec.kt3
-rw-r--r--src/test/kotlin/test/pl/treksoft/kvision/utils/UtilsSpec.kt6
50 files changed, 544 insertions, 361 deletions
diff --git a/build.gradle b/build.gradle
index abb8f25d..35fa82c7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -34,6 +34,7 @@ configure(allprojects - project(':kvision-modules')) {
}
configure(allprojects - project(':kvision-modules') - project(":kvision-modules:kvision-base")) {
+ apply plugin: 'io.gitlab.arturbosch.detekt'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'maven'
apply plugin: 'maven-publish'
@@ -54,6 +55,11 @@ configure(allprojects - project(':kvision-modules') - project(":kvision-modules:
tasks.build.dependsOn(['sourceJar', 'emptyJar'])
+ detekt {
+ config = files(rootProject.projectDir.path + "/detekt.yml")
+ filters = ".*test.*,.*/resources/.*,.*/tmp/.*"
+ }
+
publishing {
publications {
mavenProject(MavenPublication) {
@@ -88,7 +94,6 @@ if (!project.gradle.startParameter.taskNames.contains("dokka")) {
apply plugin: 'kotlin'
}
apply plugin: 'org.jetbrains.kotlin.frontend'
-apply plugin: 'io.gitlab.arturbosch.detekt'
apply plugin: 'org.jetbrains.dokka'
apply plugin: 'kotlinx-serialization'
@@ -145,15 +150,6 @@ kotlinFrontend {
}
-detekt {
- version = "${detektVersion}"
- profile("main") {
- input = "$projectDir/src/main/kotlin"
- config = "$projectDir/detekt.yml"
- filters = ".*test.*,.*/resources/.*,.*/tmp/.*"
- }
-}
-
dokka {
includes = ['Module.md']
sourceDirs = files('kvision-modules/kvision-bootstrap/src/main/kotlin',
diff --git a/gradle.properties b/gradle.properties
index 8bbe74bd..a7d1cbf9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,14 +1,14 @@
group=pl.treksoft
version=0.0.18
-kotlinVersion=1.3.0-rc-116
+kotlinVersion=1.3.0-rc-146
javaVersion=1.8
-coroutinesVersion=0.26.1-eap13
+coroutinesVersion=0.30.0-eap13
serializationVersion=0.8.1-rc13
frontendPluginVersion=0.0.37
dokkaVersion=0.9.17
-detektVersion=1.0.0.RC8
+detektVersion=1.0.0.RC9.2
junitVersion=4.12
-joobyVersion=1.5.0
+joobyVersion=1.5.1
kweryVersion=0.17
dependencyManagementPluginVersion=1.0.4.RELEASE
-jacksonModuleKotlinVersion=2.9.6
+jacksonModuleKotlinVersion=2.9.7
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index a5fe1cb9..f6b961fd 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 79799daf..d76b502e 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Wed Mar 28 23:46:27 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
diff --git a/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt b/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
index c81ebde1..86a72b33 100644
--- a/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt
+++ b/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
@@ -21,19 +21,8 @@
*/
package pl.treksoft.kvision.types
-import pl.treksoft.kvision.utils.toDateF
-import pl.treksoft.kvision.utils.toStringF
-import kotlin.js.Date
+expect class Date
-@Suppress("MayBeConstant", "TopLevelPropertyNaming")
-actual val KDATE_FORMAT = "YYYY-MM-DD HH:mm:ss"
+expect fun String.toDateF(format: String = "YYYY-MM-DD HH:mm:ss"): Date
-actual fun nowDate(): KDate =
- KDate(Date().getTime().toLong())
-
-actual fun String.toKDateF(format: String): KDate =
- this.toDateF(format)?.getTime()?.toLong()?.let { KDate(it) } ?: KDate()
-
-actual fun KDate.toStringF(format: String) = this.toJS().toStringF(format)
-
-fun KDate.toJS(): kotlin.js.Date = kotlin.js.Date(this.time)
+expect fun Date.toStringF(format: String = "YYYY-MM-DD HH:mm:ss"): String
diff --git a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt b/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt
index cde55b1e..4cc71c8b 100644
--- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt
+++ b/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt
@@ -21,7 +21,7 @@
*/
package pl.treksoft.kvision
-internal val KVManagerDatetimeInit = KVManagerDatetime.init()
+internal val kVManagerDatetimeInit = KVManagerDatetime.init()
/**
* Internal singleton object which initializes and configures KVision datetime module.
diff --git a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt b/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt
index 9cdd0369..3d32fd8c 100644
--- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt
+++ b/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt
@@ -24,12 +24,12 @@ package pl.treksoft.kvision.form.time
import pl.treksoft.kvision.core.Container
import pl.treksoft.kvision.core.StringBoolPair
import pl.treksoft.kvision.core.Widget
+import pl.treksoft.kvision.form.DateFormControl
import pl.treksoft.kvision.form.FieldLabel
import pl.treksoft.kvision.form.HelpBlock
-import pl.treksoft.kvision.form.KDateFormControl
import pl.treksoft.kvision.panel.SimplePanel
-import pl.treksoft.kvision.types.KDate
import pl.treksoft.kvision.utils.SnOn
+import kotlin.js.Date
/**
* Form field date/time chooser component.
@@ -42,9 +42,9 @@ import pl.treksoft.kvision.utils.SnOn
* @param rich determines if [label] can contain HTML code
*/
open class DateTime(
- value: KDate? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null,
+ value: Date? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null,
rich: Boolean = false
-) : SimplePanel(setOf("form-group")), KDateFormControl {
+) : SimplePanel(setOf("form-group")), DateFormControl {
/**
* Date/time input value.
@@ -235,7 +235,7 @@ open class DateTime(
* It takes the same parameters as the constructor of the built component.
*/
fun Container.dateTime(
- value: KDate? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null,
+ value: Date? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null,
rich: Boolean = false, init: (DateTime.() -> Unit)? = null
): DateTime {
val dateTime = DateTime(value, name, format, label, rich).apply { init?.invoke(this) }
diff --git a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt b/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt
index 1df8a082..69b84c87 100644
--- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt
+++ b/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt
@@ -29,11 +29,10 @@ import pl.treksoft.kvision.core.Widget
import pl.treksoft.kvision.form.FormInput
import pl.treksoft.kvision.form.InputSize
import pl.treksoft.kvision.i18n.I18n
-import pl.treksoft.kvision.types.KDate
-import pl.treksoft.kvision.types.toJS
-import pl.treksoft.kvision.types.toKDateF
+import pl.treksoft.kvision.types.toDateF
import pl.treksoft.kvision.types.toStringF
import pl.treksoft.kvision.utils.obj
+import kotlin.js.Date
internal const val DEFAULT_MINUTE_STEP = 5
internal const val MAX_VIEW = 4
@@ -48,7 +47,7 @@ internal const val MAX_VIEW = 4
*/
@Suppress("TooManyFunctions")
open class DateTimeInput(
- value: KDate? = null, format: String = "YYYY-MM-DD HH:mm",
+ value: Date? = null, format: String = "YYYY-MM-DD HH:mm",
classes: Set<String> = setOf()
) : Widget(classes + "form-control"), FormInput {
@@ -63,11 +62,11 @@ open class DateTimeInput(
/**
* Date/time input value.
*/
- var value by refreshOnUpdate(value, { refreshState() })
+ var value by refreshOnUpdate(value) { refreshState() }
/**
* Date/time format.
*/
- var format by refreshOnUpdate(format, { refreshDatePicker() })
+ var format by refreshOnUpdate(format) { refreshDatePicker() }
/**
* The placeholder for the date/time input.
*/
@@ -95,31 +94,31 @@ open class DateTimeInput(
/**
* Day of the week start. 0 (Sunday) to 6 (Saturday).
*/
- var weekStart by refreshOnUpdate(0, { refreshDatePicker() })
+ var weekStart by refreshOnUpdate(0) { refreshDatePicker() }
/**
* Days of the week that should be disabled. Multiple values should be comma separated.
*/
- var daysOfWeekDisabled by refreshOnUpdate(arrayOf<Int>(), { refreshDatePicker() })
+ var daysOfWeekDisabled by refreshOnUpdate(arrayOf<Int>()) { refreshDatePicker() }
/**
* Determines if *Clear* button should be visible.
*/
- var clearBtn by refreshOnUpdate(true, { refreshDatePicker() })
+ var clearBtn by refreshOnUpdate(true) { refreshDatePicker() }
/**
* Determines if *Today* button should be visible.
*/
- var todayBtn by refreshOnUpdate(false, { refreshDatePicker() })
+ var todayBtn by refreshOnUpdate(false) { refreshDatePicker() }
/**
* Determines if the current day should be highlighted.
*/
- var todayHighlight by refreshOnUpdate(false, { refreshDatePicker() })
+ var todayHighlight by refreshOnUpdate(false) { refreshDatePicker() }
/**
* The increment used to build the hour view.
*/
- var minuteStep by refreshOnUpdate(DEFAULT_MINUTE_STEP, { refreshDatePicker() })
+ var minuteStep by refreshOnUpdate(DEFAULT_MINUTE_STEP) { refreshDatePicker() }
/**
* Determines if meridian views are visible in day and hour views.
*/
- var showMeridian by refreshOnUpdate(false, { refreshDatePicker() })
+ var showMeridian by refreshOnUpdate(false) { refreshDatePicker() }
override fun render(): VNode {
return render("input")
@@ -164,7 +163,7 @@ open class DateTimeInput(
@Suppress("UnsafeCastFromDynamic")
protected open fun refreshState() {
value?.let {
- getElementJQueryD()?.datetimepicker("update", it.toJS())
+ getElementJQueryD()?.datetimepicker("update", it)
} ?: run {
getElementJQueryD()?.`val`(null)
getElementJQueryD()?.datetimepicker("update", null)
@@ -181,7 +180,7 @@ open class DateTimeInput(
protected open fun changeValue() {
val v = getElementJQuery()?.`val`() as String?
if (v != null && v.isNotEmpty()) {
- this.value = v.toKDateF(format)
+ this.value = v.toDateF(format)
} else {
this.value = null
}
@@ -205,15 +204,15 @@ open class DateTimeInput(
override fun afterInsert(node: VNode) {
if (!this.disabled) {
this.initDateTimePicker()
- this.getElementJQuery()?.on("changeDate", { e, _ ->
+ this.getElementJQuery()?.on("changeDate") { e, _ ->
this.dispatchEvent("change", obj { detail = e })
- })
- this.getElementJQuery()?.on("show", { e, _ ->
+ }
+ this.getElementJQuery()?.on("show") { e, _ ->
this.dispatchEvent("showBsDateTime", obj { detail = e })
- })
- this.getElementJQuery()?.on("hide", { e, _ ->
+ }
+ this.getElementJQuery()?.on("hide") { e, _ ->
this.dispatchEvent("hideBsDateTime", obj { detail = e })
- })
+ }
refreshState()
}
}
@@ -280,7 +279,7 @@ open class DateTimeInput(
* It takes the same parameters as the constructor of the built component.
*/
fun Container.dateTimeInput(
- value: KDate? = null, format: String = "YYYY-MM-DD HH:mm", classes: Set<String> = setOf(),
+ value: Date? = null, format: String = "YYYY-MM-DD HH:mm", classes: Set<String> = setOf(),
init: (DateTimeInput.() -> Unit)? = null
): DateTimeInput {
val dateTimeInput = DateTimeInput(value, format, classes).apply { init?.invoke(this) }
diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt b/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt
index d824125b..69ab46ec 100644
--- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt
+++ b/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt
@@ -23,9 +23,9 @@ package test.pl.treksoft.kvision.form.time
import pl.treksoft.kvision.form.time.DateTimeInput
import pl.treksoft.kvision.panel.Root
-import pl.treksoft.kvision.types.KDate
import pl.treksoft.kvision.types.toStringF
import test.pl.treksoft.kvision.DomSpec
+import kotlin.js.Date
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -35,7 +35,7 @@ class DateTimeInputSpec : DomSpec {
fun render() {
run {
val root = Root("test", true)
- val data = KDate()
+ val data = Date()
val dti = DateTimeInput(value = data).apply {
placeholder = "place"
id = "idti"
diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt b/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt
index 482a7b7a..19cefd86 100644
--- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt
+++ b/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt
@@ -23,10 +23,10 @@ package test.pl.treksoft.kvision.form.time
import pl.treksoft.kvision.form.time.DateTime
import pl.treksoft.kvision.panel.Root
-import pl.treksoft.kvision.types.KDate
import pl.treksoft.kvision.types.toStringF
import test.pl.treksoft.kvision.DomSpec
import kotlin.browser.document
+import kotlin.js.Date
import kotlin.test.Test
class DateTimeSpec : DomSpec {
@@ -35,7 +35,7 @@ class DateTimeSpec : DomSpec {
fun render() {
run {
val root = Root("test", true)
- val data = KDate()
+ val data = Date()
val ti = DateTime(value = data, label = "Label").apply {
placeholder = "place"
name = "name"
diff --git a/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt b/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt
index b7f5fbc6..b2e52bf7 100644
--- a/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt
+++ b/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt
@@ -21,10 +21,7 @@
*/
package pl.treksoft.kvision
-import org.w3c.dom.asList
-import kotlin.browser.document
-
-internal val KVManagerHandlebarsInit = KVManagerHandlebars.init()
+internal val kVManagerHandlebarsInit = KVManagerHandlebars.init()
/**
* Internal singleton object which initializes and configures KVision handlebars module.
diff --git a/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt b/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt
index 66e3e72c..9e24327b 100644
--- a/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt
+++ b/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt
@@ -21,10 +21,7 @@
*/
package pl.treksoft.kvision
-import org.w3c.dom.asList
-import kotlin.browser.document
-
-internal val KVManagerI18nInit = KVManagerI18n.init()
+internal val kVManagerI18nInit = KVManagerI18n.init()
/**
* Internal singleton object which initializes and configures KVision i18n module.
diff --git a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt
index 1ccd7a85..c7cd444c 100644
--- a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt
+++ b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt
@@ -25,7 +25,7 @@ import pl.treksoft.kvision.i18n.I18n
import pl.treksoft.kvision.utils.obj
import kotlin.browser.window
-internal val KVManagerRichTextInit = KVManagerRichText.init()
+internal val kVManagerRichTextInit = KVManagerRichText.init()
/**
* Internal singleton object which initializes and configures KVision RichText module.
diff --git a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt
index 961c27cd..43b018f4 100644
--- a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt
+++ b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt
@@ -23,7 +23,6 @@ package pl.treksoft.kvision.form.text
import com.github.snabbdom.VNode
import pl.treksoft.jquery.jQuery
-import pl.treksoft.kvision.KVManagerRichText
import pl.treksoft.kvision.core.Container
import pl.treksoft.kvision.core.StringPair
import kotlin.browser.document
@@ -67,7 +66,7 @@ open class RichTextInput(value: String? = null, classes: Set<String> = setOf())
if (this.disabled || this.readonly == true) {
this.getElementJQuery()?.removeAttr("contenteditable")
} else {
- this.getElementJQuery()?.on("trix-change", { _, _ ->
+ this.getElementJQuery()?.on("trix-change") { _, _ ->
if (trixId != null) {
val v = document.getElementById("trix-input-$trixId")?.let { jQuery(it).`val`() as String? }
value = if (v != null && v.isNotEmpty()) {
@@ -78,9 +77,9 @@ open class RichTextInput(value: String? = null, classes: Set<String> = setOf())
val event = org.w3c.dom.events.Event("change")
this.getElement()?.dispatchEvent(event)
}
- })
+ }
}
- this.getElementJQuery()?.on("trix-initialize", { _, _ ->
+ this.getElementJQuery()?.on("trix-initialize") { _, _ ->
trixId = this.getElementJQuery()?.attr("trix-id")
if (trixId != null) {
value?.let {
@@ -89,8 +88,8 @@ open class RichTextInput(value: String? = null, classes: Set<String> = setOf())
}
}
}
- })
- this.getElementJQuery()?.on("trix-file-accept", { e, _ -> e.preventDefault() })
+ }
+ this.getElementJQuery()?.on("trix-file-accept") { e, _ -> e.preventDefault() }
}
override fun afterDestroy() {
diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt
index c7c3815a..e2c556c1 100644
--- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt
+++ b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt
@@ -21,7 +21,7 @@
*/
package pl.treksoft.kvision
-internal val KVManagerSelectInit = KVManagerSelect.init()
+internal val kVManagerSelectInit = KVManagerSelect.init()
/**
* Internal singleton object which initializes and configures KVision select module.
diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt
index 8f4569c7..30609907 100644
--- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt
+++ b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt
@@ -66,11 +66,11 @@ open class SelectInput(
/**
* A list of options (label to value pairs) for the select control.
*/
- internal var options by refreshOnUpdate(options, { setChildrenFromOptions() })
+ internal var options by refreshOnUpdate(options) { setChildrenFromOptions() }
/**
* A value of the selected option.
*/
- var value by refreshOnUpdate(value, { refreshState() })
+ var value by refreshOnUpdate(value) { refreshState() }
/**
* The name attribute of the generated HTML select element.
*/
@@ -82,12 +82,12 @@ open class SelectInput(
/**
* Additional options for remote (AJAX) data source.
*/
- var ajaxOptions by refreshOnUpdate(ajaxOptions, {
+ var ajaxOptions by refreshOnUpdate(ajaxOptions) {
if (it != null) {
liveSearch = true
}
refresh()
- })
+ }
/**
* Maximal number of selected options.
*/
@@ -115,7 +115,7 @@ open class SelectInput(
/**
* Determines if an empty option is automatically generated.
*/
- var emptyOption by refreshOnUpdate(false, { setChildrenFromOptions() })
+ var emptyOption by refreshOnUpdate(false) { setChildrenFromOptions() }
/**
* Determines if the field is disabled.
*/
@@ -291,31 +291,31 @@ open class SelectInput(
getElementJQueryD()?.selectpicker("render").ajaxSelectPicker(it.toJs(emptyOption))
} ?: getElementJQueryD()?.selectpicker("render")
- this.getElementJQuery()?.on("show.bs.select", { e, _ ->
+ this.getElementJQuery()?.on("show.bs.select") { e, _ ->
this.dispatchEvent("showBsSelect", obj { detail = e })
- })
- this.getElementJQuery()?.on("shown.bs.select", { e, _ ->
+ }
+ this.getElementJQuery()?.on("shown.bs.select") { e, _ ->
this.dispatchEvent("shownBsSelect", obj { detail = e })
- })
- this.getElementJQuery()?.on("hide.bs.select", { e, _ ->
+ }
+ this.getElementJQuery()?.on("hide.bs.select") { e, _ ->
this.dispatchEvent("hideBsSelect", obj { detail = e })
- })
- this.getElementJQuery()?.on("hidden.bs.select", { e, _ ->
+ }
+ this.getElementJQuery()?.on("hidden.bs.select") { e, _ ->
this.dispatchEvent("hiddenBsSelect", obj { detail = e })
- })
- this.getElementJQuery()?.on("loaded.bs.select", { e, _ ->
+ }
+ this.getElementJQuery()?.on("loaded.bs.select") { e, _ ->
this.dispatchEvent("loadedBsSelect", obj { detail = e })
- })
- this.getElementJQuery()?.on("rendered.bs.select", { e, _ ->
+ }
+ this.getElementJQuery()?.on("rendered.bs.select") { e, _ ->
this.dispatchEvent("renderedBsSelect", obj { detail = e })
- })
- this.getElementJQuery()?.on("refreshed.bs.select", { e, _ ->
+ }
+ this.getElementJQuery()?.on("refreshed.bs.select") { e, _ ->
this.dispatchEvent("refreshedBsSelect", obj { detail = e })
- })
- this.getElementJQueryD()?.on("changed.bs.select", { e, cIndex: Int ->
+ }
+ this.getElementJQueryD()?.on("changed.bs.select") { e, cIndex: Int ->
e["clickedIndex"] = cIndex
this.dispatchEvent("changedBsSelect", obj { detail = e })
- })
+ }
refreshState()
}
diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt
index e33b3457..d90f0e6d 100644
--- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt
+++ b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt
@@ -49,7 +49,7 @@ open class SelectOptGroup(
/**
* A list of options (label to value pairs) for the group.
*/
- var options by refreshOnUpdate(options, { setChildrenFromOptions() })
+ var options by refreshOnUpdate(options) { setChildrenFromOptions() }
/**
* Maximal number of selected options in the group.
*/
diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt
index 76f1ee30..38edc1b8 100644
--- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt
+++ b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt
@@ -19,8 +19,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-@file:Suppress("EXPERIMENTAL_FEATURE_WARNING")
-
package pl.treksoft.kvision.remote
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
@@ -31,6 +29,7 @@ import org.jooby.Kooby
import org.jooby.Session
import org.jooby.json.Jackson
import org.pac4j.core.profile.CommonProfile
+import java.text.SimpleDateFormat
import kotlinx.coroutines.async as coroutinesAsync
/**
@@ -42,7 +41,9 @@ actual open class KVServer(init: KVServer.() -> Unit) : Kooby() {
assets("/", "index.html")
@Suppress("LeakingThis")
assets("/**").onMissing(0)
- val mapper = jacksonObjectMapper()
+ val mapper = jacksonObjectMapper().apply {
+ dateFormat = SimpleDateFormat("YYYY-MM-DD HH:mm:ss")
+ }
@Suppress("LeakingThis")
use(Jackson(mapper))
@Suppress("LeakingThis")
diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/ServiceManager.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/ServiceManager.kt
index b37d7319..3091ce26 100644
--- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/ServiceManager.kt
+++ b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/ServiceManager.kt
@@ -28,11 +28,11 @@ import org.jooby.Response
import org.jooby.Status
import org.slf4j.Logger
import org.slf4j.LoggerFactory
+import java.text.SimpleDateFormat
/**
* Multiplatform service manager.
*/
-@Suppress("EXPERIMENTAL_FEATURE_WARNING")
actual open class ServiceManager<out T> actual constructor(val service: T) {
companion object {
@@ -40,7 +40,9 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
}
protected val routes: MutableList<KVServer.() -> Unit> = mutableListOf()
- val mapper = jacksonObjectMapper()
+ val mapper = jacksonObjectMapper().apply {
+ dateFormat = SimpleDateFormat("YYYY-MM-DD HH:mm:ss")
+ }
var counter: Int = 0
/**
@@ -50,12 +52,13 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
* @param method a HTTP method
* @param prefix an URL address prefix
*/
+ @Suppress("TooGenericExceptionCaught")
protected actual inline fun <reified RET> bind(
noinline function: T.(Request?) -> Deferred<RET>,
route: String?, method: RpcHttpMethod, prefix: String
) {
val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- routes.add({
+ routes.add {
call(method, "$prefix$routeDef") { req, res ->
if (service != null) {
val jsonRpcRequest = req.body(JsonRpcRequest::class.java)
@@ -75,7 +78,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
res.status(Status.SERVER_ERROR)
}
}.invoke(this)
- })
+ }
}
/**
@@ -85,12 +88,13 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
* @param method a HTTP method
* @param prefix an URL address prefix
*/
+ @Suppress("TooGenericExceptionCaught")
protected actual inline fun <reified PAR, reified RET> bind(
noinline function: T.(PAR, Request?) -> Deferred<RET>,
route: String?, method: RpcHttpMethod, prefix: String
) {
val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- routes.add({
+ routes.add {
call(method, "$prefix$routeDef") { req, res ->
if (service != null) {
val jsonRpcRequest = req.body(JsonRpcRequest::class.java)
@@ -115,7 +119,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
res.status(Status.SERVER_ERROR)
}
}.invoke(this)
- })
+ }
}
/**
@@ -125,12 +129,13 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
* @param method a HTTP method
* @param prefix an URL address prefix
*/
+ @Suppress("TooGenericExceptionCaught")
protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind(
noinline function: T.(PAR1, PAR2, Request?) -> Deferred<RET>,
route: String?, method: RpcHttpMethod, prefix: String
) {
val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- routes.add({
+ routes.add {
call(method, "$prefix$routeDef") { req, res ->
if (service != null) {
val jsonRpcRequest = req.body(JsonRpcRequest::class.java)
@@ -156,7 +161,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
res.status(Status.SERVER_ERROR)
}
}.invoke(this)
- })
+ }
}
/**
@@ -166,15 +171,17 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
* @param method a HTTP method
* @param prefix an URL address prefix
*/
+ @Suppress("TooGenericExceptionCaught")
protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind(
noinline function: T.(PAR1, PAR2, PAR3, Request?) -> Deferred<RET>,
route: String?, method: RpcHttpMethod, prefix: String
) {
val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- routes.add({
+ routes.add {
call(method, "$prefix$routeDef") { req, res ->
if (service != null) {
val jsonRpcRequest = req.body(JsonRpcRequest::class.java)
+ @Suppress("MagicNumber")
if (jsonRpcRequest.params.size == 3) {
val param1 = getParameter<PAR1>(jsonRpcRequest.params[0])
val param2 = getParameter<PAR2>(jsonRpcRequest.params[1])
@@ -198,7 +205,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
res.status(Status.SERVER_ERROR)
}
}.invoke(this)
- })
+ }
}
/**
@@ -208,15 +215,17 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
* @param method a HTTP method
* @param prefix an URL address prefix
*/
+ @Suppress("TooGenericExceptionCaught")
protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind(
noinline function: T.(PAR1, PAR2, PAR3, PAR4, Request?) -> Deferred<RET>,
route: String?, method: RpcHttpMethod, prefix: String
) {
val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- routes.add({
+ routes.add {
call(method, "$prefix$routeDef") { req, res ->
if (service != null) {
val jsonRpcRequest = req.body(JsonRpcRequest::class.java)
+ @Suppress("MagicNumber")
if (jsonRpcRequest.params.size == 4) {
val param1 = getParameter<PAR1>(jsonRpcRequest.params[0])
val param2 = getParameter<PAR2>(jsonRpcRequest.params[1])
@@ -242,7 +251,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
res.status(Status.SERVER_ERROR)
}
}.invoke(this)
- })
+ }
}
/**
@@ -252,6 +261,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
* @param method a HTTP method
* @param prefix an URL address prefix
*/
+ @Suppress("TooGenericExceptionCaught")
protected actual inline fun <reified PAR1, reified PAR2, reified PAR3,
reified PAR4, reified PAR5, reified RET> bind(
noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> Deferred<RET>,
@@ -260,10 +270,11 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
prefix: String
) {
val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- routes.add({
+ routes.add {
call(method, "$prefix$routeDef") { req, res ->
if (service != null) {
val jsonRpcRequest = req.body(JsonRpcRequest::class.java)
+ @Suppress("MagicNumber")
if (jsonRpcRequest.params.size == 5) {
val param1 = getParameter<PAR1>(jsonRpcRequest.params[0])
val param2 = getParameter<PAR2>(jsonRpcRequest.params[1])
@@ -292,7 +303,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
res.status(Status.SERVER_ERROR)
}
}.invoke(this)
- })
+ }
}
fun call(
@@ -310,6 +321,7 @@ actual open class ServiceManager<out T> actual constructor(val service: T) {
}
}
+ @Suppress("TooGenericExceptionCaught")
protected inline fun <reified T> getParameter(str: String?): T {
return str?.let {
if (T::class == String::class) {
diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
index 9fc534c4..32c8923e 100644
--- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt
+++ b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
@@ -28,31 +28,19 @@ import com.github.andrewoma.kwery.mapper.standardConverters
import com.github.andrewoma.kwery.mapper.util.camelToLowerUnderscore
import java.sql.Timestamp
import java.text.SimpleDateFormat
-import java.util.*
-/**
- * A serializable wrapper for a multiplatform Date type.
- */
-@Suppress("MayBeConstant")
-actual val KDATE_FORMAT = "yyyy-MM-dd HH:mm:ss"
-
-actual fun nowDate(): KDate =
- KDate(Date().time)
-
-actual fun String.toKDateF(format: String): KDate =
- KDate(SimpleDateFormat(format).parse(this).time)
+actual typealias Date = java.util.Date
-actual fun KDate.toStringF(format: String) =
- SimpleDateFormat(format).format(this.toJava())
+actual fun String.toDateF(format: String): Date = SimpleDateFormat(format).parse(this)
-fun KDate.toJava(): java.util.Date = java.util.Date(this.time)
+actual fun Date.toStringF(format: String): String = SimpleDateFormat(format).format(this)
-object KDateConverter : SimpleConverter<KDate>(
- { row, c -> KDate(row.timestamp(c).time) },
+object DateConverter : SimpleConverter<Date>(
+ { row, c -> Date(row.timestamp(c).time) },
{ Timestamp(it.time) }
)
val kvTableConfig = TableConfiguration(
- converters = standardConverters + reifiedConverter(KDateConverter),
+ converters = standardConverters + reifiedConverter(DateConverter),
namingConvention = camelToLowerUnderscore
)
diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt b/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt
index 0de06c8c..ca4d3764 100644
--- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt
+++ b/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt
@@ -21,7 +21,7 @@
*/
package pl.treksoft.kvision
-internal val KVManagerSpinnerInit = KVManagerSpinner.init()
+internal val kVManagerSpinnerInit = KVManagerSpinner.init()
/**
* Internal singleton object which initializes and configures KVision spinner module.
diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt b/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt
index 7d3af684..b4a8138a 100644
--- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt
+++ b/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt
@@ -98,38 +98,38 @@ open class SpinnerInput(
/**
* Spinner value.
*/
- var value by refreshOnUpdate(value, { refreshState() })
+ var value by refreshOnUpdate(value) { refreshState() }
/**
* The value attribute of the generated HTML input element.
*
* This value is placed directly in generated HTML code, while the [value] property is dynamically
* bound to the spinner input value.
*/
- var startValue by refreshOnUpdate(value, { this.value = it; refresh() })
+ var startValue by refreshOnUpdate(value) { this.value = it; refresh() }
/**
* Minimal value.
*/
- var min by refreshOnUpdate(min, { refreshSpinner() })
+ var min by refreshOnUpdate(min) { refreshSpinner() }
/**
* Maximal value.
*/
- var max by refreshOnUpdate(max, { refreshSpinner() })
+ var max by refreshOnUpdate(max) { refreshSpinner() }
/**
* Step value.
*/
- var step by refreshOnUpdate(step, { refreshSpinner() })
+ var step by refreshOnUpdate(step) { refreshSpinner() }
/**
* Number of decimal digits value.
*/
- var decimals by refreshOnUpdate(decimals, { refreshSpinner() })
+ var decimals by refreshOnUpdate(decimals) { refreshSpinner() }
/**
* Spinner buttons type.
*/
- var buttonsType by refreshOnUpdate(buttonsType, { refreshSpinner() })
+ var buttonsType by refreshOnUpdate(buttonsType) { refreshSpinner() }
/**
* Spinner force rounding type.
*/
- var forceType by refreshOnUpdate(forceType, { refreshSpinner() })
+ var forceType by refreshOnUpdate(forceType) { refreshSpinner() }
/**
* The placeholder for the spinner input.
*/
@@ -217,18 +217,18 @@ open class SpinnerInput(
size?.let {
siblings?.find("button")?.addClass(it.className)
}
- this.getElementJQuery()?.on("change", { e, _ ->
+ this.getElementJQuery()?.on("change") { e, _ ->
if (e.asDynamic().isTrigger != null) {
val event = org.w3c.dom.events.Event("change")
this.getElement()?.dispatchEvent(event)
}
- })
- this.getElementJQuery()?.on("touchspin.on.min", { e, _ ->
+ }
+ this.getElementJQuery()?.on("touchspin.on.min") { e, _ ->
this.dispatchEvent("onMinBsSpinner", obj { detail = e })
- })
- this.getElementJQuery()?.on("touchspin.on.max", { e, _ ->
+ }
+ this.getElementJQuery()?.on("touchspin.on.max") { e, _ ->
this.dispatchEvent("onMaxBsSpinner", obj { detail = e })
- })
+ }
refreshState()
}
diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt
index 64a25545..af0950eb 100644
--- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt
+++ b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt
@@ -21,7 +21,7 @@
*/
package pl.treksoft.kvision
-internal val KVManagerUploadInit = KVManagerUpload.init()
+internal val kVManagerUploadInit = KVManagerUpload.init()
/**
* Internal singleton object which initializes and configures KVision upload module.
diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt
index 51b73aa1..da35f9ef 100644
--- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt
+++ b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt
@@ -62,67 +62,67 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla
* The optional URL for the upload processing action.
* If not set the upload button action will default to form submission.
*/
- var uploadUrl: String? by refreshOnUpdate(uploadUrl, { refreshUploadInput() })
+ var uploadUrl: String? by refreshOnUpdate(uploadUrl) { refreshUploadInput() }
/**
* Determines if multiple file upload is supported.
*/
- var multiple: Boolean by refreshOnUpdate(multiple, { refresh(); refreshUploadInput() })
+ var multiple: Boolean by refreshOnUpdate(multiple) { refresh(); refreshUploadInput() }
/**
* The extra data that will be passed as data to the AJAX server call via POST.
*/
- var uploadExtraData: ((String, Int) -> dynamic)? by refreshOnUpdate({ refreshUploadInput() })
+ var uploadExtraData: ((String, Int) -> dynamic)? by refreshOnUpdate { refreshUploadInput() }
/**
* Determines if the explorer theme is used.
*/
- var explorerTheme: Boolean by refreshOnUpdate(false, { refreshUploadInput() })
+ var explorerTheme: Boolean by refreshOnUpdate(false) { refreshUploadInput() }
/**
* Determines if the input selection is required.
*/
- var required: Boolean by refreshOnUpdate(false, { refreshUploadInput() })
+ var required: Boolean by refreshOnUpdate(false) { refreshUploadInput() }
/**
* Determines if the caption is shown.
*/
- var showCaption: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var showCaption: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* Determines if the preview is shown.
*/
- var showPreview: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var showPreview: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* Determines if the remove button is shown.
*/
- var showRemove: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var showRemove: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* Determines if the upload button is shown.
*/
- var showUpload: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var showUpload: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* Determines if the cancel button is shown.
*/
- var showCancel: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var showCancel: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* Determines if the file browse button is shown.
*/
- var showBrowse: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var showBrowse: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* Determines if the click on the preview zone opens file browse window.
*/
- var browseOnZoneClick: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var browseOnZoneClick: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* Determines if the iconic preview is prefered.
*/
- var preferIconicPreview: Boolean by refreshOnUpdate(false, { refreshUploadInput() })
+ var preferIconicPreview: Boolean by refreshOnUpdate(false) { refreshUploadInput() }
/**
* Allowed file types.
*/
- var allowedFileTypes: Set<String>? by refreshOnUpdate({ refreshUploadInput() })
+ var allowedFileTypes: Set<String>? by refreshOnUpdate { refreshUploadInput() }
/**
* Allowed file extensions.
*/
- var allowedFileExtensions: Set<String>? by refreshOnUpdate({ refreshUploadInput() })
+ var allowedFileExtensions: Set<String>? by refreshOnUpdate { refreshUploadInput() }
/**
* Determines if Drag&Drop zone is enabled.
*/
- var dropZoneEnabled: Boolean by refreshOnUpdate(true, { refreshUploadInput() })
+ var dropZoneEnabled: Boolean by refreshOnUpdate(true) { refreshUploadInput() }
/**
* The name attribute of the generated HTML input element.
*/
@@ -130,7 +130,7 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla
/**
* Determines if the field is disabled.
*/
- override var disabled by refreshOnUpdate(false, { refresh(); refreshUploadInput() })
+ override var disabled by refreshOnUpdate(false) { refresh(); refreshUploadInput() }
/**
* The size of the input (currently not working)
*/
@@ -173,24 +173,24 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla
@Suppress("UnsafeCastFromDynamic")
override fun afterInsert(node: VNode) {
getElementJQueryD()?.fileinput(getSettingsObj())
- this.getElementJQuery()?.on("fileselect", { e, _ ->
+ this.getElementJQuery()?.on("fileselect") { e, _ ->
this.dispatchEvent("fileSelectUpload", obj { detail = e })
- })
- this.getElementJQuery()?.on("fileclear", { e, _ ->
+ }
+ this.getElementJQuery()?.on("fileclear") { e, _ ->
this.dispatchEvent("fileClearUpload", obj { detail = e })
- })
- this.getElementJQuery()?.on("filereset", { e, _ ->
+ }
+ this.getElementJQuery()?.on("filereset") { e, _ ->
this.dispatchEvent("fileResetUpload", obj { detail = e })
- })
- this.getElementJQuery()?.on("filebrowse", { e, _ ->
+ }
+ this.getElementJQuery()?.on("filebrowse") { e, _ ->
this.dispatchEvent("fileBrowseUpload", obj { detail = e })
- })
- this.getElementJQueryD()?.on("filepreupload", lambda@{ _, data, previewId, index ->
+ }
+ this.getElementJQueryD()?.on("filepreupload") lambda@{ _, data, previewId, index ->
data["previewId"] = previewId
data["index"] = index
this.dispatchEvent("filePreUpload", obj { detail = data })
return@lambda null
- })
+ }
}
override fun afterDestroy() {
@@ -334,7 +334,6 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla
* @param kFile object identifying the file
* @return KFile object
*/
- @Suppress("EXPERIMENTAL_FEATURE_WARNING")
suspend fun <K : Any> Form<K>.getContent(
key: KProperty1<K, List<KFile>?>,
kFile: KFile
@@ -351,7 +350,6 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla
* @param kFile object identifying the file
* @return KFile object
*/
- @Suppress("EXPERIMENTAL_FEATURE_WARNING")
suspend fun <K : Any> FormPanel<K>.getContent(
key: KProperty1<K, List<KFile>?>,
kFile: KFile
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
index 52f60813..9f28c52c 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
@@ -312,7 +312,7 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() {
afterPostpatch(v)
}
}
- destroy = { _ ->
+ destroy = {
afterDestroy()
vnode = null
vnode
diff --git a/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt b/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt
index 80a05ba7..d8b74c54 100644
--- a/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt
@@ -61,7 +61,7 @@ class DataContainer<M, C : Component>(
init {
container.parent = this
- model.onUpdate += { _ ->
+ model.onUpdate += {
update()
}
update()
diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt
index 4ae1e93b..a521fe95 100644
--- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt
@@ -61,6 +61,7 @@ enum class DD(val option: String) {
* @param withCaret determines if the dropdown button renders caret
* @param classes a set of CSS class names
*/
+@Suppress("TooManyFunctions")
open class DropDown(
text: String, elements: List<StringPair>? = null, icon: String? = null,
style: ButtonStyle = ButtonStyle.DEFAULT, disabled: Boolean = false, val forNavbar: Boolean = false,
@@ -74,7 +75,7 @@ open class DropDown(
set(value) {
button.text = value
}
- private var elements by refreshOnUpdate(elements, { setChildrenFromElements() })
+ private var elements by refreshOnUpdate(elements) { setChildrenFromElements() }
/**
* The icon of the dropdown button.
*/
@@ -207,18 +208,18 @@ open class DropDown(
@Suppress("UnsafeCastFromDynamic")
override fun afterInsert(node: VNode) {
- this.getElementJQuery()?.on("show.bs.dropdown", { e, _ ->
+ this.getElementJQuery()?.on("show.bs.dropdown") { e, _ ->
this.dispatchEvent("showBsDropdown", obj { detail = e })
- })
- this.getElementJQuery()?.on("shown.bs.dropdown", { e, _ ->
+ }
+ this.getElementJQuery()?.on("shown.bs.dropdown") { e, _ ->
this.dispatchEvent("shownBsDropdown", obj { detail = e })
- })
- this.getElementJQuery()?.on("hide.bs.dropdown", { e, _ ->
+ }
+ this.getElementJQuery()?.on("hide.bs.dropdown") { e, _ ->
this.dispatchEvent("hideBsDropdown", obj { detail = e })
- })
- this.getElementJQuery()?.on("hidden.bs.dropdown", { e, _ ->
+ }
+ this.getElementJQuery()?.on("hidden.bs.dropdown") { e, _ ->
this.dispatchEvent("hiddenBsDropdown", obj { detail = e })
- })
+ }
}
override fun getSnClass(): List<StringBoolPair> {
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt
index 19f7e68a..8f93c7ea 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt
@@ -23,12 +23,15 @@ package pl.treksoft.kvision.form
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Mapper
+import kotlinx.serialization.context.MutableSerialContextImpl
import kotlinx.serialization.decode
-import kotlinx.serialization.json.JSON
import kotlinx.serialization.serializer
import pl.treksoft.kvision.i18n.I18n.trans
-import pl.treksoft.kvision.types.KDate
+import pl.treksoft.kvision.types.DateSerializer
import pl.treksoft.kvision.types.KFile
+import pl.treksoft.kvision.types.toStringF
+import pl.treksoft.kvision.utils.JSON
+import kotlin.js.Date
import kotlin.js.Json
import kotlin.reflect.KProperty1
@@ -84,8 +87,8 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
modelFactory = {
val map = it.flatMap { entry ->
when (entry.value) {
- is KDate -> {
- listOf(entry.key to entry.value, "${entry.key}.time" to (entry.value as KDate).time)
+ is Date -> {
+ listOf(entry.key to (entry.value as? Date)?.toStringF())
}
is List<*> -> {
@Suppress("UNCHECKED_CAST")
@@ -93,9 +96,9 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
listOf(entry.key to entry.value, "${entry.key}.size" to list.size) +
list.mapIndexed { index, kFile ->
listOf(
- "${entry.key}.${index}.name" to kFile.name,
- "${entry.key}.${index}.size" to kFile.size,
- "${entry.key}.${index}.content" to kFile.content
+ "${entry.key}.$index.name" to kFile.name,
+ "${entry.key}.$index.size" to kFile.size,
+ "${entry.key}.$index.content" to kFile.content
)
}.flatten()
} ?: listOf()
@@ -104,6 +107,7 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
}
}.toMap()
val mapper = Mapper.InNullableMapper(FormMapWrapper(map))
+ mapper.context = MutableSerialContextImpl().apply { registerSerializer(Date::class, DateSerializer) }
mapper.decode(serializer)
}
}
@@ -182,8 +186,8 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
* @param validator optional validation function
* @return current form
*/
- fun <C : KDateFormControl> add(
- key: KProperty1<K, KDate?>, control: C, required: Boolean = false, requiredMessage: String? = null,
+ fun <C : DateFormControl> add(
+ key: KProperty1<K, Date?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): Form<K> {
@@ -278,7 +282,7 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
* @return data model as JSON
*/
fun getDataJson(): Json {
- return kotlin.js.JSON.parse(JSON.stringify(serializer, getData()))
+ return kotlin.js.JSON.parse(JSON.plain.stringify(serializer, getData()))
}
/**
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt
index 6aff842a..6759fef9 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt
@@ -22,8 +22,8 @@
package pl.treksoft.kvision.form
import pl.treksoft.kvision.core.Component
-import pl.treksoft.kvision.types.KDate
import pl.treksoft.kvision.types.KFile
+import kotlin.js.Date
/**
* Input controls sizes.
@@ -190,15 +190,15 @@ interface BoolFormControl : FormControl {
/**
* Base interface of a form control with a date value.
*/
-interface KDateFormControl : FormControl {
+interface DateFormControl : FormControl {
/**
* Date value.
*/
- var value: KDate?
+ var value: Date?
- override fun getValue(): KDate? = value
+ override fun getValue(): Date? = value
override fun setValue(v: Any?) {
- value = v as? KDate
+ value = v as? Date
}
override fun getValueAsString(): String? = value?.toString()
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt
index 3811ed82..3533dee5 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt
@@ -32,8 +32,8 @@ import pl.treksoft.kvision.form.check.Radio
import pl.treksoft.kvision.html.TAG
import pl.treksoft.kvision.html.Tag
import pl.treksoft.kvision.panel.SimplePanel
-import pl.treksoft.kvision.types.KDate
import pl.treksoft.kvision.types.KFile
+import kotlin.js.Date
import kotlin.js.Json
import kotlin.reflect.KProperty1
@@ -287,8 +287,8 @@ open class FormPanel<K : Any>(
* @param validator optional validation function
* @return current form panel
*/
- open fun <C : KDateFormControl> add(
- key: KProperty1<K, KDate?>, control: C, required: Boolean = false, requiredMessage: String? = null,
+ open fun <C : DateFormControl> add(
+ key: KProperty1<K, Date?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): FormPanel<K> {
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt
index f79c1b48..2df3a055 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt
@@ -67,14 +67,14 @@ open class CheckInput(
/**
* The selection state of the input.
*/
- var value by refreshOnUpdate(value, { refreshState() })
+ var value by refreshOnUpdate(value) { refreshState() }
/**
* The value attribute of the generated HTML input element.
*
* This value is placed directly in generated HTML code, while the [value] property is dynamically
* bound to the input selection state.
*/
- var startValue by refreshOnUpdate(value, { this.value = it; refresh() })
+ var startValue by refreshOnUpdate(value) { this.value = it; refresh() }
/**
* The type of the generated HTML input element.
*/
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt
index fdc1e3af..e2f27c36 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt
@@ -54,12 +54,12 @@ open class RadioGroup(
/**
* A list of options (label to value pairs) for the group.
*/
- var options by refreshOnUpdate(options, { setChildrenFromOptions() })
+ var options by refreshOnUpdate(options) { setChildrenFromOptions() }
/**
* A value of the selected option.
*/
- override var value by refreshOnUpdate(value, { setValueToChildren(it) })
+ override var value by refreshOnUpdate(value) { setValueToChildren(it) }
/**
* Determines if the options are rendered inline.
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt
index e41cfb8f..3a06f47b 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt
@@ -51,14 +51,14 @@ abstract class AbstractTextInput(
/**
* Text input value.
*/
- var value by refreshOnUpdate(value, { refreshState() })
+ var value by refreshOnUpdate(value) { refreshState() }
/**
* The value attribute of the generated HTML input element.
*
* This value is placed directly in generated HTML code, while the [value] property is dynamically
* bound to the text input value.
*/
- var startValue by refreshOnUpdate(value, { this.value = it; refresh() })
+ var startValue by refreshOnUpdate(value) { this.value = it; refresh() }
/**
* The placeholder for the text input.
*/
diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Template.kt b/src/main/kotlin/pl/treksoft/kvision/html/Template.kt
index 9a52eb5b..1f377406 100644
--- a/src/main/kotlin/pl/treksoft/kvision/html/Template.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/html/Template.kt
@@ -47,6 +47,6 @@ interface Template {
set(value) {
if (!rich) rich = true
templateDataObj = value
- content = template?.invoke(value) ?: templates.get(I18n.language)?.invoke(value)
+ content = template?.invoke(value) ?: templates[I18n.language]?.invoke(value)
}
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt
index 693ecbaa..e16ca87e 100644
--- a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt
@@ -78,7 +78,7 @@ open class Confirm(
/**
* Determines if Cancel button is visible.
*/
- var cancelVisible by refreshOnUpdate(cancelVisible, { refreshCancelButton() })
+ var cancelVisible by refreshOnUpdate(cancelVisible) { refreshCancelButton() }
/**
* Yes button text.
diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt
index d5695db3..e67a6f17 100644
--- a/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt
@@ -37,7 +37,6 @@ import kotlin.coroutines.resume
* @param classes a set of CSS class names
* @param init an initializer extension function
*/
-@Suppress("EXPERIMENTAL_FEATURE_WARNING")
open class Dialog<R>(
caption: String? = null, closeButton: Boolean = true,
size: ModalSize? = null, animation: Boolean = true, escape: Boolean = true,
diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt
index e09e9f7f..a0456e7e 100644
--- a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt
@@ -218,20 +218,20 @@ open class Modal(
keyboard = escape
backdrop = if (escape) "true" else "static"
})
- this.getElementJQuery()?.on("show.bs.modal", { e, _ ->
+ this.getElementJQuery()?.on("show.bs.modal") { e, _ ->
this.dispatchEvent("showBsModal", obj { detail = e })
- })
- this.getElementJQuery()?.on("shown.bs.modal", { e, _ ->
+ }
+ this.getElementJQuery()?.on("shown.bs.modal") { e, _ ->
this.dispatchEvent("shownBsModal", obj { detail = e })
- })
- this.getElementJQuery()?.on("hide.bs.modal", { e, _ ->
+ }
+ this.getElementJQuery()?.on("hide.bs.modal") { e, _ ->
this.dispatchEvent("hideBsModal", obj { detail = e })
- })
- this.getElementJQuery()?.on("hidden.bs.modal", { e, _ ->
+ }
+ this.getElementJQuery()?.on("hidden.bs.modal") { e, _ ->
this.visible = false
hide()
this.dispatchEvent("hiddenBsModal", obj { detail = e })
- })
+ }
}
override fun hide(): Widget {
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt
index d22a285b..310d4d49 100644
--- a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt
@@ -104,7 +104,7 @@ open class FlexPanel(
/**
* CSS flexbox direction.
*/
- var direction by refreshOnUpdate(direction, { refreshSpacing(); refresh() })
+ var direction by refreshOnUpdate(direction) { refreshSpacing(); refresh() }
/**
* CSS flexbox wrap mode.
*/
@@ -124,7 +124,7 @@ open class FlexPanel(
/**
* The spacing between columns/rows.
*/
- var spacing by refreshOnUpdate(spacing, { refreshSpacing(); refresh() })
+ var spacing by refreshOnUpdate(spacing) { refreshSpacing(); refresh() }
init {
@Suppress("LeakingThis")
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt
index edcf5789..7a5b07d6 100644
--- a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt
@@ -62,7 +62,7 @@ open class ResponsiveGridPanel(
/**
* Text align of grid cells.
*/
- var align by refreshOnUpdate(align, { refreshRowContainers() })
+ var align by refreshOnUpdate(align) { refreshRowContainers() }
internal val map = mutableMapOf<Int, MutableMap<Int, WidgetParam>>()
private var auto: Boolean = true
@@ -86,7 +86,7 @@ open class ResponsiveGridPanel(
val cCol = maxOf(col, 0)
if (row > rows - 1) rows = cRow + 1
if (col > cols - 1) cols = cCol + 1
- map.getOrPut(cRow, { mutableMapOf() })[cCol] = WidgetParam(child, size, offset)
+ map.getOrPut(cRow) { mutableMapOf() }[cCol] = WidgetParam(child, size, offset)
if (size > 0 || offset > 0) auto = false
refreshRowContainers()
return this
diff --git a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt b/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt
index 479ad62e..256d15d7 100644
--- a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt
@@ -67,15 +67,15 @@ internal class ProgressIndicator(
/**
* The current progress.
*/
- var progress by refreshOnUpdate(progress, { refreshWidth() })
+ var progress by refreshOnUpdate(progress) { refreshWidth() }
/**
* The minimal progress.
*/
- var min by refreshOnUpdate(min, { refreshWidth() })
+ var min by refreshOnUpdate(min) { refreshWidth() }
/**
* The maximal progress.
*/
- var max by refreshOnUpdate(max, { refreshWidth() })
+ var max by refreshOnUpdate(max) { refreshWidth() }
/**
* The style of the progress indicator.
*/
diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt b/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt
index 4247b0b7..a48a6b1f 100644
--- a/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/remote/CallAgent.kt
@@ -21,10 +21,10 @@
*/
package pl.treksoft.kvision.remote
-import kotlinx.serialization.json.JSON
import pl.treksoft.jquery.JQueryAjaxSettings
import pl.treksoft.jquery.JQueryXHR
import pl.treksoft.jquery.jQuery
+import pl.treksoft.kvision.utils.JSON
import pl.treksoft.kvision.utils.obj
import kotlin.js.Promise
import kotlin.js.undefined
@@ -56,8 +56,8 @@ open class CallAgent {
method: RpcHttpMethod = RpcHttpMethod.POST
): Promise<String> {
val jsonRpcRequest = JsonRpcRequest(counter++, url, data)
- val jsonData = JSON.stringify(jsonRpcRequest)
- return Promise({ resolve, reject ->
+ val jsonData = JSON.plain.stringify(jsonRpcRequest)
+ return Promise { resolve, reject ->
jQuery.ajax(url, obj {
this.contentType = "application/json"
this.data = jsonData
@@ -85,7 +85,7 @@ open class CallAgent {
}
}
})
- })
+ }
}
/**
@@ -103,7 +103,7 @@ open class CallAgent {
contentType: String = "application/json",
beforeSend: ((JQueryXHR, JQueryAjaxSettings) -> Boolean)? = null
): Promise<dynamic> {
- return Promise({ resolve, reject ->
+ return Promise { resolve, reject ->
jQuery.ajax(url, obj {
this.contentType = contentType
this.data = data
@@ -127,6 +127,6 @@ open class CallAgent {
}
this.beforeSend = beforeSend
})
- })
+ }
}
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt b/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt
index 25c20445..b4c8561e 100644
--- a/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/remote/RemoteAgent.kt
@@ -24,25 +24,24 @@ package pl.treksoft.kvision.remote
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.asDeferred
import kotlinx.serialization.KSerializer
-import kotlinx.serialization.internal.ArrayListSerializer
-import kotlinx.serialization.internal.BooleanSerializer
-import kotlinx.serialization.internal.CharSerializer
-import kotlinx.serialization.internal.DoubleSerializer
-import kotlinx.serialization.internal.LongSerializer
-import kotlinx.serialization.internal.StringSerializer
-import kotlinx.serialization.json.JSON
+import kotlinx.serialization.internal.*
import kotlinx.serialization.list
import kotlinx.serialization.serializer
-import kotlin.js.js
+import pl.treksoft.kvision.types.DateSerializer
+import pl.treksoft.kvision.types.toStringF
+import pl.treksoft.kvision.utils.JSON
+import kotlin.js.Date
import kotlin.reflect.KClass
import kotlin.js.JSON as NativeJSON
-internal class NonStandardTypeException(type: String) : Exception("Non standard type: $type!")
+internal class NotStandardTypeException(type: String) : Exception("Not a standard type: $type!")
+
+internal class NotEnumTypeException : Exception("Not the Enum type!")
/**
* Client side agent for JSON-RPC remote calls.
*/
-@Suppress("EXPERIMENTAL_FEATURE_WARNING", "LargeClass", "TooManyFunctions")
+@Suppress("LargeClass", "TooManyFunctions")
open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
val callAgent = CallAgent()
@@ -55,9 +54,15 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, method = method).then {
try {
+ @Suppress("UNCHECKED_CAST")
deserialize<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer(), it)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnum(RET::class as KClass<Any>, it) as RET
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer(), it)
+ }
}
}.asDeferred()
}
@@ -72,9 +77,14 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, method = method).then {
try {
- deserializeLists<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer().list, it)
+ deserializeList<RET>(it, RET::class.js.name)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnumList(RET::class as KClass<Any>, it) as List<RET>
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer().list, it)
+ }
}
}.asDeferred()
}
@@ -92,9 +102,14 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
return callAgent.jsonRpcCall(url, listOf(data), method).then {
try {
@Suppress("UNCHECKED_CAST")
- deserialize<RET>(it, (RET::class as KClass<Any>).js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer(), it)
+ deserialize<RET>(it, RET::class.js.name)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnum(RET::class as KClass<Any>, it) as RET
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer(), it)
+ }
}
}.asDeferred()
}
@@ -111,9 +126,14 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data), method).then {
try {
- deserializeLists<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer().list, it)
+ deserializeList<RET>(it, RET::class.js.name)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnumList(RET::class as KClass<Any>, it) as List<RET>
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer().list, it)
+ }
}
}.asDeferred()
}
@@ -131,9 +151,15 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2), method).then {
try {
+ @Suppress("UNCHECKED_CAST")
deserialize<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer(), it)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnum(RET::class as KClass<Any>, it) as RET
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer(), it)
+ }
}
}.asDeferred()
}
@@ -151,9 +177,14 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2), method).then {
try {
- deserializeLists<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer().list, it)
+ deserializeList<RET>(it, RET::class.js.name)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnumList(RET::class as KClass<Any>, it) as List<RET>
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer().list, it)
+ }
}
}.asDeferred()
}
@@ -173,9 +204,15 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2, data3), method).then {
try {
+ @Suppress("UNCHECKED_CAST")
deserialize<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer(), it)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnum(RET::class as KClass<Any>, it) as RET
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer(), it)
+ }
}
}.asDeferred()
}
@@ -195,9 +232,14 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2, data3), method).then {
try {
- deserializeLists<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer().list, it)
+ deserializeList<RET>(it, RET::class.js.name)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnumList(RET::class as KClass<Any>, it) as List<RET>
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer().list, it)
+ }
}
}.asDeferred()
}
@@ -224,9 +266,15 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2, data3, data4), method).then {
try {
+ @Suppress("UNCHECKED_CAST")
deserialize<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer(), it)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnum(RET::class as KClass<Any>, it) as RET
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer(), it)
+ }
}
}.asDeferred()
}
@@ -253,9 +301,14 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2, data3, data4), method).then {
try {
- deserializeLists<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer().list, it)
+ deserializeList<RET>(it, RET::class.js.name)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnumList(RET::class as KClass<Any>, it) as List<RET>
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer().list, it)
+ }
}
}.asDeferred()
}
@@ -287,9 +340,15 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2, data3, data4, data5), method).then {
try {
+ @Suppress("UNCHECKED_CAST")
deserialize<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer(), it)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnum(RET::class as KClass<Any>, it) as RET
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer(), it)
+ }
}
}.asDeferred()
}
@@ -321,9 +380,14 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!")
return callAgent.jsonRpcCall(url, listOf(data1, data2, data3, data4, data5), method).then {
try {
- deserializeLists<RET>(it, RET::class.js.name)
- } catch (t: NonStandardTypeException) {
- JSON.nonstrict.parse(RET::class.serializer().list, it)
+ deserializeList<RET>(it, RET::class.js.name)
+ } catch (t: NotStandardTypeException) {
+ try {
+ @Suppress("UNCHECKED_CAST")
+ tryDeserializeEnumList(RET::class as KClass<Any>, it) as List<RET>
+ } catch (t: NotEnumTypeException) {
+ JSON.nonstrict.parse(RET::class.serializer().list, it)
+ }
}
}.asDeferred()
}
@@ -337,18 +401,81 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
inline fun <reified PAR> serialize(value: PAR, serializer: KSerializer<PAR>?): String? {
return value?.let {
if (serializer != null) {
- JSON.stringify(serializer, it)
+ JSON.plain.stringify(serializer, it)
} else {
- if (it is Enum<*>) {
- "\"$it\""
- } else {
- try {
+ @Suppress("UNCHECKED_CAST")
+ trySerialize((PAR::class as KClass<Any>), it as Any)
+ }
+ }
+ }
+
+ /**
+ * @suppress
+ * Internal function
+ */
+ @Suppress("ComplexMethod", "TooGenericExceptionCaught", "NestedBlockDepth")
+ fun trySerialize(kClass: KClass<Any>, value: Any): String {
+ return if (value is List<*>) {
+ if (value.size > 0) {
+ when {
+ value[0] is String ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(StringSerializer) as KSerializer<Any>, value)
+ value[0] is Date ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(DateSerializer) as KSerializer<Any>, value)
+ value[0] is Int ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(IntSerializer) as KSerializer<Any>, value)
+ value[0] is Long ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(LongSerializer) as KSerializer<Any>, value)
+ value[0] is Boolean ->
@Suppress("UNCHECKED_CAST")
- JSON.stringify((PAR::class as KClass<Any>).serializer(), it as Any)
+ JSON.plain.stringify(ArrayListSerializer(BooleanSerializer) as KSerializer<Any>, value)
+ value[0] is Float ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(FloatSerializer) as KSerializer<Any>, value)
+ value[0] is Double ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(DoubleSerializer) as KSerializer<Any>, value)
+ value[0] is Char ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(CharSerializer) as KSerializer<Any>, value)
+ value[0] is Short ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(ShortSerializer) as KSerializer<Any>, value)
+ value[0] is Byte ->
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(ByteSerializer) as KSerializer<Any>, value)
+ value[0] is Enum<*> -> "[" + value.joinToString(",") { "\"$it\"" } + "]"
+ else -> try {
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(kClass.serializer()) as KSerializer<Any>, value)
} catch (e: Throwable) {
- it.toString()
+ try {
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(ArrayListSerializer(StringSerializer) as KSerializer<Any>, value)
+ } catch (e: Throwable) {
+ value.toString()
+ }
}
}
+ } else {
+ "[]"
+ }
+ } else {
+ when (value) {
+ is Enum<*> -> "\"$value\""
+ is String -> value
+ is Char -> "\"$value\""
+ is Date -> "\"${value.toStringF()}\""
+ else -> try {
+ @Suppress("UNCHECKED_CAST")
+ JSON.plain.stringify(kClass.serializer(), value)
+ } catch (e: Throwable) {
+ value.toString()
+ }
}
}
}
@@ -357,15 +484,37 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
* @suppress
* Internal function
*/
- @Suppress("UNCHECKED_CAST")
- fun <RET> deserialize(value: String, type: String): RET {
- return when (type) {
- "String" -> JSON.parse(StringSerializer, value) as RET
- "Number" -> JSON.parse(DoubleSerializer, value) as RET
- "Long" -> JSON.parse(LongSerializer, value) as RET
- "Boolean" -> JSON.parse(BooleanSerializer, value) as RET
- "Char" -> JSON.parse(CharSerializer, value) as RET
- else -> throw NonStandardTypeException(type)
+ @Suppress("UNCHECKED_CAST", "ComplexMethod")
+ fun <RET> deserialize(value: String, jsType: String): RET {
+ return when (jsType) {
+ "String" -> JSON.plain.parse(StringSerializer, value) as RET
+ "Number" -> JSON.plain.parse(DoubleSerializer, value) as RET
+ "Long" -> JSON.plain.parse(LongSerializer, value) as RET
+ "Boolean" -> JSON.plain.parse(BooleanSerializer, value) as RET
+ "BoxedChar" -> JSON.plain.parse(CharSerializer, value) as RET
+ "Short" -> JSON.plain.parse(ShortSerializer, value) as RET
+ "Date" -> JSON.plain.parse(DateSerializer, value) as RET
+ "Byte" -> JSON.plain.parse(ByteSerializer, value) as RET
+ else -> throw NotStandardTypeException(jsType)
+ }
+ }
+
+ /**
+ * @suppress
+ * Internal function
+ */
+ @Suppress("UNCHECKED_CAST", "ComplexMethod")
+ fun <RET> deserializeList(value: String, jsType: String): List<RET> {
+ return when (jsType) {
+ "String" -> JSON.plain.parse(ArrayListSerializer(StringSerializer), value) as List<RET>
+ "Number" -> JSON.plain.parse(ArrayListSerializer(DoubleSerializer), value) as List<RET>
+ "Long" -> JSON.plain.parse(ArrayListSerializer(LongSerializer), value) as List<RET>
+ "Boolean" -> JSON.plain.parse(ArrayListSerializer(BooleanSerializer), value) as List<RET>
+ "BoxedChar" -> JSON.plain.parse(ArrayListSerializer(CharSerializer), value) as List<RET>
+ "Short" -> JSON.plain.parse(ArrayListSerializer(ShortSerializer), value) as List<RET>
+ "Date" -> JSON.plain.parse(ArrayListSerializer(DateSerializer), value) as List<RET>
+ "Byte" -> JSON.plain.parse(ArrayListSerializer(ByteSerializer), value) as List<RET>
+ else -> throw NotStandardTypeException(jsType)
}
}
@@ -373,15 +522,41 @@ open class RemoteAgent<out T>(val serviceManager: ServiceManager<T>) {
* @suppress
* Internal function
*/
- @Suppress("UNCHECKED_CAST")
- fun <RET> deserializeLists(value: String, type: String): List<RET> {
- return when (type) {
- "String" -> JSON.parse(ArrayListSerializer(StringSerializer), value) as List<RET>
- "Number" -> JSON.parse(ArrayListSerializer(DoubleSerializer), value) as List<RET>
- "Long" -> JSON.parse(ArrayListSerializer(LongSerializer), value) as List<RET>
- "Boolean" -> JSON.parse(ArrayListSerializer(BooleanSerializer), value) as List<RET>
- "Char" -> JSON.parse(ArrayListSerializer(CharSerializer), value) as List<RET>
- else -> throw NonStandardTypeException(type)
+ @Suppress("TooGenericExceptionCaught", "ThrowsCount")
+ fun tryDeserializeEnum(kClass: KClass<Any>, value: String): Any {
+ return try {
+ if (kClass.asDynamic().jClass.`$metadata$`.interfaces[0].name == "Enum") {
+ findEnumValue(kClass, JSON.plain.parse(StringSerializer, value)) ?: throw NotEnumTypeException()
+ } else {
+ throw NotEnumTypeException()
+ }
+ } catch (e: Throwable) {
+ throw NotEnumTypeException()
+ }
+ }
+
+ /**
+ * @suppress
+ * Internal function
+ */
+ @Suppress("TooGenericExceptionCaught", "ThrowsCount")
+ fun tryDeserializeEnumList(kClass: KClass<Any>, value: String): List<Any> {
+ return try {
+ if (kClass.asDynamic().jClass.`$metadata$`.interfaces[0].name == "Enum") {
+ JSON.plain.parse(ArrayListSerializer(StringSerializer), value).map {
+ findEnumValue(kClass, JSON.plain.parse(StringSerializer, it)) ?: throw NotEnumTypeException()
+ }
+ } else {
+ throw NotEnumTypeException()
+ }
+ } catch (e: Throwable) {
+ throw NotEnumTypeException()
+ }
+ }
+
+ private fun findEnumValue(kClass: KClass<Any>, value: String): Any? {
+ return (kClass.asDynamic().jClass.values() as Array<Any>).find {
+ it.asDynamic().name == value
}
}
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt b/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt
index 56141f5e..bf77a06b 100644
--- a/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt
@@ -61,7 +61,6 @@ class LoginService {
/**
* Pac4j form login dispatcher.
*/
-@Suppress("EXPERIMENTAL_FEATURE_WARNING")
abstract class SecurityMgr {
private var isLoggedIn = false
diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt
index 1d44633d..f78d3f84 100644
--- a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt
@@ -63,7 +63,7 @@ open class Table(
/**
* Table headers names.
*/
- var headerNames by refreshOnUpdate(headerNames, { refreshHeaders() })
+ var headerNames by refreshOnUpdate(headerNames) { refreshHeaders() }
/**
* Table types.
*/
diff --git a/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
new file mode 100644
index 00000000..b6b60d5c
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.types
+
+import kotlinx.serialization.Decoder
+import kotlinx.serialization.Encoder
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.SerialDescriptor
+import kotlinx.serialization.internal.SerialClassDescImpl
+import pl.treksoft.kvision.KVManager
+import kotlin.js.Date
+
+actual typealias Date = kotlin.js.Date
+
+/**
+ * Extension function to convert String to Date with a given date format.
+ * @param format date/time format
+ * @return Date object
+ */
+@Suppress("UnsafeCastFromDynamic")
+actual fun String.toDateF(format: String): Date {
+ val result = KVManager.fecha.parse(this, format)
+ return if (result) result else Date()
+}
+
+/**
+ * Extension function to convert Date to String with a given date format.
+ * @param format date/time format
+ * @return String object
+ */
+@Suppress("UnsafeCastFromDynamic")
+actual fun Date.toStringF(format: String): String {
+ return KVManager.fecha.format(this, format)
+}
+
+object DateSerializer : KSerializer<Date> {
+ override val descriptor: SerialDescriptor = SerialClassDescImpl("kotlin.js.Date")
+
+ override fun deserialize(input: Decoder): Date {
+ return input.decodeString().toDateF()
+ }
+
+ override fun serialize(output: Encoder, obj: Date) {
+ output.encodeString(obj.toStringF())
+ }
+}
diff --git a/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt b/src/main/kotlin/pl/treksoft/kvision/utils/JSON.kt
index 0cb1a1f1..e47351ac 100644
--- a/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/types/KDate.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/utils/JSON.kt
@@ -19,31 +19,21 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-package pl.treksoft.kvision.types
+package pl.treksoft.kvision.utils
-import kotlinx.serialization.Serializable
+import kotlinx.serialization.context.SimpleModule
+import kotlinx.serialization.json.JSON
+import pl.treksoft.kvision.types.DateSerializer
+import kotlin.js.Date
-expect val KDATE_FORMAT: String
+object JSON {
-/**
- * A serializable wrapper for a multiplatform Date type.
- */
-@Serializable
-data class KDate(val time: Long) {
- constructor() : this(now().time)
- constructor(str: String) : this(str.toKDateF(KDATE_FORMAT).time)
-
- override fun toString(): String {
- return this.toStringF(KDATE_FORMAT)
+ val plain = JSON().apply {
+ install(SimpleModule(Date::class, DateSerializer))
}
- companion object {
- fun now() = nowDate()
+ val nonstrict = JSON(strictMode = false).apply {
+ install(SimpleModule(Date::class, DateSerializer))
}
-}
-expect fun nowDate(): KDate
-
-expect fun String.toKDateF(format: String): KDate
-
-expect fun KDate.toStringF(format: String): String
+}
diff --git a/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt b/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt
index e5f608c2..e252d672 100644
--- a/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt
@@ -27,13 +27,11 @@ import com.lightningkite.kotlin.observable.list.ObservableList
import kotlinx.coroutines.suspendCancellableCoroutine
import org.w3c.files.File
import org.w3c.files.FileReader
-import pl.treksoft.kvision.KVManager
import pl.treksoft.kvision.core.CssSize
import pl.treksoft.kvision.core.UNIT
import kotlin.browser.window
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
-import kotlin.js.Date
/**
* Extension property to convert Int to CSS px units.
@@ -186,27 +184,6 @@ fun Int.toHexString(): String {
}
/**
- * Extension function to convert String to Date with a given date format.
- * @param format date/time format
- * @return Date object
- */
-@Suppress("UnsafeCastFromDynamic")
-fun String.toDateF(format: String = "YYYY-MM-DD HH:mm:ss"): Date? {
- val result = KVManager.fecha.parse(this, format)
- return if (result) result else null
-}
-
-/**
- * Extension function to convert Date to String with a given date format.
- * @param format date/time format
- * @return String object
- */
-@Suppress("UnsafeCastFromDynamic")
-fun Date.toStringF(format: String = "YYYY-MM-DD HH:mm:ss"): String {
- return KVManager.fecha.format(this, format)
-}
-
-/**
* Utility function to detect Internet Explorer 11.
* @return true if the current browser is IE11
*/
@@ -216,7 +193,6 @@ fun isIE11(): Boolean = window.navigator.userAgent.matches("Trident\\/7\\.")
* Suspending extension function to get file content.
* @return file content
*/
-@Suppress("EXPERIMENTAL_FEATURE_WARNING")
suspend fun File.getContent(): String = suspendCancellableCoroutine { cont ->
val reader = FileReader()
reader.onload = {
diff --git a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/src/main/kotlin/pl/treksoft/kvision/window/Window.kt
index bdfb2c0f..ee20dc51 100644
--- a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/window/Window.kt
@@ -105,11 +105,11 @@ open class Window(
/**
* Determines if the window is resizable.
*/
- var isResizable by refreshOnUpdate(isResizable, { checkIsResizable() })
+ var isResizable by refreshOnUpdate(isResizable) { checkIsResizable() }
/**
* Determines if the window is draggable.
*/
- var isDraggable by refreshOnUpdate(isDraggable, { checkIsDraggable(); checkHeaderVisibility() })
+ var isDraggable by refreshOnUpdate(isDraggable) { checkIsDraggable(); checkHeaderVisibility() }
/**
* Determines if Close button is visible.
*/
@@ -201,7 +201,7 @@ open class Window(
}
kotlin.browser.window.addEventListener("mousemove", moveCallback)
var upCallback: ((Event) -> Unit)? = null
- upCallback = { _ ->
+ upCallback = {
isDrag = false
kotlin.browser.window.removeEventListener("mousemove", moveCallback)
kotlin.browser.window.removeEventListener("mouseup", upCallback)
diff --git a/src/test/kotlin/test/pl/treksoft/kvision/panel/RootSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/panel/RootSpec.kt
index 9e4342cc..659dac9a 100644
--- a/src/test/kotlin/test/pl/treksoft/kvision/panel/RootSpec.kt
+++ b/src/test/kotlin/test/pl/treksoft/kvision/panel/RootSpec.kt
@@ -21,7 +21,6 @@
*/
package test.pl.treksoft.kvision.panel
-import pl.treksoft.kvision.modal.Modal
import pl.treksoft.kvision.panel.Root
import test.pl.treksoft.kvision.DomSpec
import kotlin.browser.document
@@ -40,7 +39,7 @@ class RootSpec : DomSpec {
}
@Test
- fun getSnClass_Fluid() {
+ fun getSnClassFluid() {
run {
Root("test", fixed = true)
val rootElem = document.getElementById("test")
diff --git a/src/test/kotlin/test/pl/treksoft/kvision/utils/UtilsSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/utils/UtilsSpec.kt
index 97e157bd..36217dd7 100644
--- a/src/test/kotlin/test/pl/treksoft/kvision/utils/UtilsSpec.kt
+++ b/src/test/kotlin/test/pl/treksoft/kvision/utils/UtilsSpec.kt
@@ -21,9 +21,9 @@
*/
package test.pl.treksoft.kvision.utils
-import pl.treksoft.kvision.utils.toDateF
+import pl.treksoft.kvision.types.toDateF
+import pl.treksoft.kvision.types.toStringF
import pl.treksoft.kvision.utils.toHexString
-import pl.treksoft.kvision.utils.toStringF
import test.pl.treksoft.kvision.SimpleSpec
import kotlin.js.Date
import kotlin.test.Test
@@ -47,7 +47,7 @@ class UtilsSpec : SimpleSpec {
val res = "2017-03-14 14:50:35".toDateF()
assertEquals(
js("new Date(2017,2,14,14,50,35).getTime()"),
- res?.getTime(),
+ res.getTime(),
"Should convert String value to Date"
)
}