diff options
author | Robert Jaros <rjaros@finn.pl> | 2019-10-07 09:58:14 +0200 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2019-10-07 09:58:14 +0200 |
commit | 04ac8542c218b7ce5199350f0880e8f7cb4252b6 (patch) | |
tree | 4f96d1c3bb8281289b96e2b11eecc404a3c98788 | |
parent | 6678eec9799681b09e5ac85de1a39596d56de22f (diff) | |
parent | 6b14906f0e35dc522bd1c1a44682d728315cf619 (diff) | |
download | kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.tar.gz kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.tar.bz2 kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.zip |
Merge branch 'bs4'
289 files changed, 3002 insertions, 2651 deletions
diff --git a/build.gradle b/build.gradle index 1a8952bb..da4ab01a 100644 --- a/build.gradle +++ b/build.gradle @@ -122,25 +122,24 @@ dependencies { if (!project.gradle.startParameter.taskNames.contains("dokka")) { kotlinFrontend { npm { - dependency("css-loader", "2.0.1") - dependency("style-loader", "0.23.1") - dependency("less", "3.9.0") - dependency("less-loader", "4.1.0") + dependency("css-loader", "3.2.0") + dependency("style-loader", "1.0.0") + dependency("less", "3.10.3") + dependency("less-loader", "5.0.0") dependency("imports-loader", "0.8.0") - dependency("uglifyjs-webpack-plugin", "2.0.1") - dependency("file-loader", "2.0.0") - dependency("url-loader", "1.1.2") - dependency("jquery", "3.2.1") - dependency("fecha", "2.3.2") + dependency("uglifyjs-webpack-plugin", "2.2.0") + dependency("file-loader", "4.2.0") + dependency("url-loader", "2.1.0") + dependency("jquery", "3.4.1") + dependency("fecha", "3.0.3") dependency("snabbdom", "0.7.3") dependency("snabbdom-virtualize", "0.7.0") dependency("jquery-resizable-dom", "0.32.0") - dependency("element-resize-event", "3.0.3") - dependency("navigo", "7.0.0") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") + dependency("navigo", "7.1.2") + devDependency("karma", "4.3.0") + devDependency("karma-chrome-launcher", "3.1.0") + devDependency("karma-webpack", "4.0.2") + devDependency("qunit", "2.9.2") } webpackBundle { @@ -160,23 +159,25 @@ if (!project.gradle.startParameter.taskNames.contains("dokka")) { dokka { includes = ['Module.md'] sourceDirs = files('kvision-modules/kvision-bootstrap/src/main/kotlin', - 'kvision-modules/kvision-select/src/main/kotlin', - 'kvision-modules/kvision-datetime/src/main/kotlin', - 'kvision-modules/kvision-spinner/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-css/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-select/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-datetime/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-spinner/src/main/kotlin', 'kvision-modules/kvision-richtext/src/main/kotlin', - 'kvision-modules/kvision-upload/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-upload/src/main/kotlin', 'kvision-modules/kvision-handlebars/src/main/kotlin', 'kvision-modules/kvision-i18n/src/main/kotlin', 'kvision-modules/kvision-chart/src/main/kotlin', 'kvision-modules/kvision-datacontainer/src/main/kotlin', - 'kvision-modules/kvision-dialog/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-dialog/src/main/kotlin', + 'kvision-modules/kvision-fontawesome/src/main/kotlin', 'kvision-modules/kvision-redux/src/main/kotlin', 'kvision-modules/kvision-redux-kotlin/src/main/kotlin', 'kvision-modules/kvision-moment/src/main/kotlin', 'kvision-modules/kvision-tabulator/src/main/kotlin', 'kvision-modules/kvision-pace/src/main/kotlin', 'kvision-modules/kvision-remote/src/main/kotlin', - 'kvision-modules/kvision-select-remote/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin', 'kvision-modules/kvision-tabulator-remote/src/main/kotlin', 'kvision-modules/kvision-common/src/main/kotlin', 'kvision-modules/kvision-common-types/src/main/kotlin', diff --git a/kvision-modules/kvision-bootstrap-css/build.gradle b/kvision-modules/kvision-bootstrap-css/build.gradle new file mode 100644 index 00000000..1aca3288 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/build.gradle @@ -0,0 +1,9 @@ +apply from: "../shared.gradle" + +kotlinFrontend { + + npm { + dependency("bootstrap", "4.3.1") + } + +} diff --git a/kvision-modules/kvision-bootstrap-css/package.json.d/project.info b/kvision-modules/kvision-bootstrap-css/package.json.d/project.info new file mode 100644 index 00000000..b990974a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Bootstrap CSS module" +} diff --git a/kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt b/kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt new file mode 100644 index 00000000..ec131d5d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt @@ -0,0 +1,35 @@ +/* + * 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 kVManagerBootstrapCssInit = KVManagerBootstrapCss.init() + +/** + * Internal singleton object which initializes and configures KVision Bootstrap CSS module. + */ +internal object KVManagerBootstrapCss { + init { + require("bootstrap/dist/css/bootstrap.min.css") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..32a7c4d0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js @@ -0,0 +1,4 @@ +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'}); +config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/kvision-modules/kvision-datetime/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-datetime/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/css.js diff --git a/kvision-modules/kvision-spinner/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js index bf5a1a20..bf5a1a20 100644 --- a/kvision-modules/kvision-spinner/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js diff --git a/kvision-modules/kvision-bootstrap-datetime/build.gradle b/kvision-modules/kvision-bootstrap-datetime/build.gradle new file mode 100644 index 00000000..8cb14799 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/build.gradle @@ -0,0 +1,13 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} + +kotlinFrontend { + + npm { + dependency("pc-bootstrap4-datetimepicker", "4.17.50") + } + +} diff --git a/kvision-modules/kvision-datetime/package.json.d/project.info b/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info index 3d332806..3d332806 100644 --- a/kvision-modules/kvision-datetime/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt new file mode 100644 index 00000000..c02a116d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt @@ -0,0 +1,36 @@ +/* + * 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 kVManagerDatetimeInit = KVManagerDatetime.init() + +/** + * Internal singleton object which initializes and configures KVision datetime module. + */ +internal object KVManagerDatetime { + init { + require("pc-bootstrap4-datetimepicker/build/css/bootstrap-datetimepicker.min.css") + require("pc-bootstrap4-datetimepicker/build/js/bootstrap-datetimepicker.min.js") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt index 3d32fd8c..b7cf18ec 100644 --- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt @@ -26,7 +26,7 @@ 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.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn import kotlin.js.Date @@ -87,14 +87,6 @@ open class DateTime( input.readonly = value } /** - * Day of the week start. 0 (Sunday) to 6 (Saturday). - */ - var weekStart - get() = input.weekStart - set(value) { - input.weekStart = value - } - /** * Days of the week that should be disabled. Multiple values should be comma separated. */ var daysOfWeekDisabled @@ -105,42 +97,82 @@ open class DateTime( /** * Determines if *Clear* button should be visible. */ - var clearBtn - get() = input.clearBtn + var showClear + get() = input.showClear set(value) { - input.clearBtn = value + input.showClear = value } /** - * Determines if *Today* button should be visible. + * Determines if *Close* button should be visible. */ - var todayBtn - get() = input.todayBtn + var showClose + get() = input.showClose set(value) { - input.todayBtn = value + input.showClose = value } /** - * Determines if the current day should be highlighted. + * Determines if *Today* button should be visible. */ - var todayHighlight - get() = input.todayHighlight + var showTodayButton + get() = input.showTodayButton set(value) { - input.todayHighlight = value + input.showTodayButton = value } /** * The increment used to build the hour view. */ - var minuteStep - get() = input.minuteStep + var stepping + get() = input.stepping + set(value) { + input.stepping = value + } + /** + * Prevents date selection before this date. + */ + var minDate + get() = input.minDate + set(value) { + input.minDate = value + } + /** + * Prevents date selection after this date. + */ + var maxDate + get() = input.maxDate + set(value) { + input.maxDate = value + } + /** + * Shows date and time pickers side by side. + */ + var sideBySide + get() = input.sideBySide + set(value) { + input.sideBySide = value + } + /** + * An array of enabled dates. + */ + var enabledDates + get() = input.enabledDates set(value) { - input.minuteStep = value + input.enabledDates = value } /** - * Determines if meridian views are visible in day and hour views. + * An array of disabled dates. */ - var showMeridian - get() = input.showMeridian + var disabledDates + get() = input.disabledDates set(value) { - input.showMeridian = value + input.disabledDates = value + } + /** + * Allow date picker for readonly component.. + */ + var ignoreReadonly + get() = input.ignoreReadonly + set(value) { + input.ignoreReadonly = value } /** * The label text bound to the input element. @@ -165,21 +197,21 @@ open class DateTime( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } @@ -214,6 +246,13 @@ open class DateTime( input.hidePopup() } + /** + * Toggle date/time chooser popup. + */ + open fun togglePopup() { + input.togglePopup() + } + override fun getValueAsString(): String? { return input.getValueAsString() } diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt new file mode 100644 index 00000000..626346b1 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt @@ -0,0 +1,377 @@ +/* + * 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.form.time + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.form.FormInput +import pl.treksoft.kvision.form.text.TextInput +import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.html.Icon +import pl.treksoft.kvision.html.Icon.Companion.icon +import pl.treksoft.kvision.html.Span.Companion.span +import pl.treksoft.kvision.i18n.I18n +import pl.treksoft.kvision.panel.SimplePanel +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_STEPPING = 5 + +/** + * Basic date/time chooser component. + * + * @constructor + * @param value date/time input value + * @param format date/time format (default YYYY-MM-DD HH:mm) + * @param classes a set of CSS class names + */ +@Suppress("TooManyFunctions") +open class DateTimeInput( + value: Date? = null, format: String = "YYYY-MM-DD HH:mm", + classes: Set<String> = setOf() +) : SimplePanel(classes + "input-group" + "date"), FormInput { + + private var initialized = false + + internal val input = TextInput(value = value?.toStringF(format)) + private lateinit var icon: Icon + private val addon = Div(classes = setOf("input-group-append")) { + span(classes = setOf("input-group-text", "datepickerbutton")) { + icon = icon(getIconClass(format)) + } + } + + init { + addInternal(input) + addInternal(addon) + } + + /** + * Date/time input value. + */ + var value + get() = input.value?.toDateF(format) + set(value) { + input.value = value?.toStringF(format) + refreshState() + } + /** + * Date/time format. + */ + var format by refreshOnUpdate(format) { refreshDatePicker() } + /** + * The placeholder for the date/time input. + */ + var placeholder + get() = input.placeholder + set(value) { + input.placeholder = value + } + /** + * The name attribute of the generated HTML input element. + */ + override var name + get() = input.name + set(value) { + input.name = value + } + /** + * Determines if the field is disabled. + */ + override var disabled + get() = input.disabled + set(value) { + input.disabled = value + } + /** + * Determines if the text input is automatically focused. + */ + var autofocus + get() = input.autofocus + set(value) { + input.autofocus = value + } + /** + * Determines if the date/time input is read-only. + */ + var readonly + get() = input.readonly + set(value) { + input.readonly = value + } + /** + * The size of the input. + */ + override var size + get() = input.size + set(value) { + input.size = value + } + /** + * The validation status of the input. + */ + override var validationStatus + get() = input.validationStatus + set(value) { + input.validationStatus = value + refresh() + } + /** + * Days of the week that should be disabled. Multiple values should be comma separated. + */ + var daysOfWeekDisabled by refreshOnUpdate(arrayOf<Int>()) { refreshDatePicker() } + /** + * Determines if *Clear* button should be visible. + */ + var showClear by refreshOnUpdate(true) { refreshDatePicker() } + /** + * Determines if *Close* button should be visible. + */ + var showClose by refreshOnUpdate(true) { refreshDatePicker() } + /** + * Determines if *Today* button should be visible. + */ + var showTodayButton by refreshOnUpdate(true) { refreshDatePicker() } + /** + * The increment used to build the hour view. + */ + var stepping by refreshOnUpdate(DEFAULT_STEPPING) { refreshDatePicker() } + /** + * Prevents date selection before this date. + */ + var minDate: Date? by refreshOnUpdate { refreshDatePicker() } + /** + * Prevents date selection after this date. + */ + var maxDate: Date? by refreshOnUpdate { refreshDatePicker() } + /** + * Shows date and time pickers side by side. + */ + var sideBySide by refreshOnUpdate(false) { refreshDatePicker() } + /** + * An array of enabled dates. + */ + var enabledDates by refreshOnUpdate(arrayOf<Date>()) { refreshDatePicker() } + /** + * An array of disabled dates. + */ + var disabledDates by refreshOnUpdate(arrayOf<Date>()) { refreshDatePicker() } + /** + * Allow date picker for readonly component. + */ + var ignoreReadonly by refreshOnUpdate(false) { refreshDatePicker() } + + private fun refreshState() { + if (initialized) getElementJQueryD().data("DateTimePicker").date(value) + } + + private fun getIconClass(format: String): String { + return if (format.contains("YYYY") || format.contains("MM") || format.contains("DD")) { + "fas fa-calendar-alt" + } else { + "fas fa-clock" + } + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } + return cl + } + + protected open fun refreshDatePicker() { + if (initialized) { + getElementJQueryD()?.data("DateTimePicker").destroy() + } + initDateTimePicker() + icon.icon = getIconClass(format) + } + + /** + * Open date/time chooser popup. + */ + open fun showPopup() { + if (initialized) getElementJQueryD()?.data("DateTimePicker").show() + } + + /** + * Hides date/time chooser popup. + */ + open fun hidePopup() { + if (initialized) getElementJQueryD()?.data("DateTimePicker").hide() + } + + /** + * Toggles date/time chooser popup. + */ + open fun togglePopup() { + if (initialized) getElementJQueryD()?.data("DateTimePicker").toggle() + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + this.initDateTimePicker() + this.initEventHandlers() + initialized = true + } + + override fun afterDestroy() { + if (initialized) { + val comp = getElementJQueryD()?.data("DateTimePicker") + if (comp != null) comp.destroy() + initialized = false + } + } + + private fun initDateTimePicker() { + val language = I18n.language + val self = this + getElementJQueryD()?.datetimepicker(obj { + this.useCurrent = false + this.format = format + this.stepping = stepping + this.showClear = showClear + this.showClose = showClose + this.showTodayButton = showTodayButton + this.sideBySide = sideBySide + this.ignoreReadonly = ignoreReadonly + if (minDate != null) this.minDate = minDate + if (maxDate != null) this.maxDate = maxDate + if (daysOfWeekDisabled.isNotEmpty()) this.daysOfWeekDisabled = daysOfWeekDisabled + if (enabledDates.isNotEmpty()) this.enabledDates = enabledDates + if (disabledDates.isNotEmpty()) this.disabledDates = disabledDates + this.locale = language + this.icons = obj { + this.time = "far fa-clock" + this.date = "far fa-calendar" + this.up = "fas fa-arrow-up" + this.down = "fas fa-arrow-down" + this.previous = "fas fa-chevron-left" + this.next = "fas fa-chevron-right" + this.today = "fas fa-calendar-check" + this.clear = "far fa-trash-alt" + this.close = "far fa-times-circle" + } + this.tooltips = obj { + this.today = "" + this.clear = "" + this.close = "" + this.selectMonth = "" + this.prevMonth = "" + this.nextMonth = "" + this.selectYear = "" + this.prevYear = "" + this.nextYear = "" + this.selectDecade = "" + this.prevDecade = "" + this.nextDecade = "" + this.prevCentury = "" + this.nextCentury = "" + this.pickHour = "" + this.incrementHour = "" + this.decrementHour = "" + this.pickMinute = "" + this.incrementMinute = "" + this.decrementMinute = "" + this.pickSecond = "" + this.incrementSecond = "" + this.decrementSecond = "" + this.togglePeriod = "" + this.selectTime = "" + } + this.keyBinds = obj { + enter = { + self.togglePopup() + } + } + }) + } + + private fun initEventHandlers() { + this.getElementJQuery()?.on("dp.change") { e, _ -> + val moment = e.asDynamic().date + if (moment) { + this.value = moment.toDate() + } else { + this.value = null + } + @Suppress("UnsafeCastFromDynamic") + this.dispatchEvent("change", obj { detail = e }) + } + this.getElementJQuery()?.on("dp.error") { e, _ -> + this.value = null + @Suppress("UnsafeCastFromDynamic") + this.dispatchEvent("change", obj { detail = e }) + } + this.getElementJQuery()?.on("dp.show") { e, _ -> + @Suppress("UnsafeCastFromDynamic") + this.dispatchEvent("showBsDateTime", obj { detail = e }) + } + this.getElementJQuery()?.on("dp.hide") { e, _ -> + @Suppress("UnsafeCastFromDynamic") + this.dispatchEvent("hideBsDateTime", obj { detail = e }) + } + } + + /** + * Get value of date/time input control as String + * @return value as a String + */ + fun getValueAsString(): String? { + return value?.toStringF(format) + } + + /** + * Makes the input element focused. + */ + override fun focus() { + input.focus() + } + + /** + * Makes the input element blur. + */ + override fun blur() { + input.blur() + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.dateTimeInput( + 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) } + this.add(dateTimeInput) + return dateTimeInput + } + } +} diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt index 877cf650..5cdb68c9 100644 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt @@ -25,6 +25,7 @@ import pl.treksoft.kvision.form.time.DateTimeInput import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.types.toStringF import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document import kotlin.js.Date import kotlin.test.Test import kotlin.test.assertEquals @@ -41,10 +42,11 @@ class DateTimeInputSpec : DomSpec { id = "idti" } root.add(dti) - val value = dti.getElementJQuery()?.`val`() + val element = document.getElementById("test") + val datastr = data.toStringF(dti.format) assertEquals( - data.toStringF(dti.format), - value, + "<div class=\"input-group date\" id=\"idti\"><input class=\"form-control\" placeholder=\"place\" type=\"text\" value=\"$datastr\"><div class=\"input-group-append\"><span class=\"input-group-text datepickerbutton\"><span class=\"fas fa-calendar-alt\"></span></span></div></div>", + element?.innerHTML, "Should render date time input with correctly formatted value" ) } diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt index b5e393bb..a6714f0c 100644 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt @@ -46,13 +46,13 @@ class DateTimeSpec : DomSpec { val id = ti.input.id val datastr = data.toStringF(ti.format) assertEqualsHtml( - "<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"text\" placeholder=\"place\" name=\"name\" disabled=\"disabled\" value=\"$datastr\"></div>", + "<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group date\" id=\"$id\"><input class=\"form-control\" placeholder=\"place\" name=\"name\" disabled=\"\" type=\"text\" value=\"$datastr\"><div class=\"input-group-append\"><span class=\"input-group-text datepickerbutton\"><span class=\"fas fa-calendar-alt\"></span></span></div></div></div>", element?.innerHTML, "Should render correct date time input form control" ) ti.validatorError = "Validation Error" assertEqualsHtml( - "<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"text\" placeholder=\"place\" name=\"name\" disabled=\"disabled\" value=\"$datastr\"><span class=\"help-block small\">Validation Error</span></div>", + "<div class=\"form-group text-danger\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group date is-invalid\" id=\"$id\"><input class=\"form-control is-invalid\" placeholder=\"place\" name=\"name\" disabled=\"\" type=\"text\" value=\"$datastr\"><div class=\"input-group-append\"><span class=\"input-group-text datepickerbutton\"><span class=\"fas fa-calendar-alt\"></span></span></div></div><div class=\"invalid-feedback\">Validation Error</div></div>", element?.innerHTML, "Should render correct date time input form control with validation error" ) diff --git a/kvision-modules/kvision-select/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-select/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js diff --git a/kvision-modules/kvision-bootstrap-dialog/build.gradle b/kvision-modules/kvision-bootstrap-dialog/build.gradle new file mode 100644 index 00000000..652d14d6 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-dialog/build.gradle @@ -0,0 +1,6 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap") + compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" +} diff --git a/kvision-modules/kvision-dialog/package.json.d/project.info b/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info index 416cd4a7..416cd4a7 100644 --- a/kvision-modules/kvision-dialog/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info diff --git a/kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt b/kvision-modules/kvision-bootstrap-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt index e67a6f17..e67a6f17 100644 --- a/kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt +++ b/kvision-modules/kvision-bootstrap-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt diff --git a/kvision-modules/kvision-spinner/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-spinner/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-dialog/webpack.config.d/css.js diff --git a/kvision-modules/kvision-select-remote/build.gradle b/kvision-modules/kvision-bootstrap-select-remote/build.gradle index 739c7a53..7a4dc8fa 100644 --- a/kvision-modules/kvision-select-remote/build.gradle +++ b/kvision-modules/kvision-bootstrap-select-remote/build.gradle @@ -1,6 +1,6 @@ apply from: "../shared.gradle" dependencies { - compile project(":kvision-modules:kvision-select") + compile project(":kvision-modules:kvision-bootstrap-select") compile project(":kvision-modules:kvision-remote") } diff --git a/kvision-modules/kvision-select-remote/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info index 5685d581..5685d581 100644 --- a/kvision-modules/kvision-select-remote/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info diff --git a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt index ea9d369b..de823280 100644 --- a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt @@ -26,7 +26,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.remote.KVServiceManager @@ -155,21 +155,21 @@ open class SelectRemote<T : Any>( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt index 4c891d30..4c891d30 100644 --- a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt diff --git a/kvision-modules/kvision-upload/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-upload/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-select-remote/webpack.config.d/css.js diff --git a/kvision-modules/kvision-bootstrap-select/build.gradle b/kvision-modules/kvision-bootstrap-select/build.gradle new file mode 100644 index 00000000..7c10515f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/build.gradle @@ -0,0 +1,14 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} + +kotlinFrontend { + + npm { + dependency("bootstrap-select", "1.13.11") + dependency("ajax-bootstrap-select", "1.4.5") + } + +} diff --git a/kvision-modules/kvision-select/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select/package.json.d/project.info index 80e675b0..80e675b0 100644 --- a/kvision-modules/kvision-select/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-select/package.json.d/project.info diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt index e2c556c1..09f92a0d 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt @@ -26,28 +26,17 @@ internal val kVManagerSelectInit = KVManagerSelect.init() /** * Internal singleton object which initializes and configures KVision select module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerSelect { internal const val AJAX_REQUEST_DELAY = 300 internal const val KVNULL = "#kvnull" - fun init() {} - - private val bootstrapSelectCss = try { + init { require("bootstrap-select/dist/css/bootstrap-select.min.css") - } catch (e: Throwable) { - } - private val bootstrapSelect = try { require("bootstrap-select/dist/js/bootstrap-select.min.js") require("./js/locales/bootstrap-select/bootstrap-select-i18n.min.js") - } catch (e: Throwable) { - } - private val bootstrapSelectAjaxCss = try { require("ajax-bootstrap-select/dist/css/ajax-bootstrap-select.min.css") - } catch (e: Throwable) { - } - private val bootstrapSelectAjax = try { require("ajax-bootstrap-select/dist/js/ajax-bootstrap-select.min.js") + require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.cs-CZ.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js") @@ -58,8 +47,12 @@ internal object KVManagerSelect { require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js") + require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.sr-SP.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js") - } catch (e: Throwable) { + js("$.fn.selectpicker.Constructor.BootstrapVersion = '4';") + js("$.fn.selectpicker.Constructor.DEFAULTS.styleBase = 'form-control';"); + js("$.fn.selectpicker.Constructor.DEFAULTS.style = '';") } + internal fun init() {} } diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt index c088f68d..c088f68d 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt index db8a5b3b..4b2505d2 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -176,21 +176,21 @@ open class Select( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt index e0a49326..84eccaf7 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt @@ -30,6 +30,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.asString @@ -128,6 +129,10 @@ open class SelectInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() init { setChildrenFromOptions() @@ -228,6 +233,9 @@ open class SelectInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() cl.add("selectpicker" to true) + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt index 3f07a9bf..3f07a9bf 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt index 3977776b..91c269a8 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt @@ -91,11 +91,7 @@ open class SelectOption( sn.add("data-subtext" to translate(it)) } icon?.let { - if (it.startsWith("fa-")) { - sn.add("data-icon" to "fa $it") - } else { - sn.add("data-icon" to "glyphicon-$it") - } + sn.add("data-icon" to it) } if (disabled) { sn.add("disabled" to "disabled") diff --git a/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.cs-CZ.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.cs-CZ.min.js new file mode 100644 index 00000000..994014a9 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.cs-CZ.min.js @@ -0,0 +1,23 @@ +/*! + * Ajax Bootstrap Select + * + * Extends existing [Bootstrap Select] implementations by adding the ability to search via AJAX requests as you type. Originally for CROSCON. + * + * @version 1.4.5 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2019 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2019-04-23 12:18:55 PM EDT + */ +!(function ($) { + +/*! + * Czech translation for the "cs-CZ" and "cs" language codes. + * Martin Brettschneider <martin.brettschneider@gmail.com> + */ +$.fn.ajaxSelectPicker.locale["cs-CZ"]={currentlySelected:"Aktuálně vybrané",emptyTitle:"Vyberte a začněte psát",errorText:"Výsledky nelze načíst",searchPlaceholder:"Vyhledat...",statusInitialized:"Začněte psát hledaný výraz",statusNoResults:"Žádné výsledky",statusSearching:"Vyhledávání...",statusTooShort:"Zadejte více znaků"},$.fn.ajaxSelectPicker.locale.cs=$.fn.ajaxSelectPicker.locale["cs-CZ"];})(jQuery); diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js index 08b38207..08b38207 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js index 8b130b97..8b130b97 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js index bbe3fe45..bbe3fe45 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js index 1d86582f..1d86582f 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js index b30deb3e..b30deb3e 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js index 23a9a348..23a9a348 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js index 2fd5299b..2fd5299b 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js index 6c6a16f2..6c6a16f2 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js index f104f491..f104f491 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js index 2a6e743d..2a6e743d 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js index aa6d4d06..aa6d4d06 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js diff --git a/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.sr-SP.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.sr-SP.min.js new file mode 100644 index 00000000..4536c620 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.sr-SP.min.js @@ -0,0 +1,23 @@ +/*! + * Ajax Bootstrap Select + * + * Extends existing [Bootstrap Select] implementations by adding the ability to search via AJAX requests as you type. Originally for CROSCON. + * + * @version 1.4.5 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2019 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2019-04-23 12:18:55 PM EDT + */ +!(function ($) { + +/*! + * Serbian translation for the "sr-SP" and "sr" language codes. + * Miroslav Maksimovic <miroslavmaksimovic95@gmail.com> + */ +$.fn.ajaxSelectPicker.locale["sr-SP"]={currentlySelected:"Trenutno izabrano",emptyTitle:"Izaberite i pocnite kucati",errorText:"Nemoguce dobiti rezultate",searchPlaceholder:"Pretrazi...",statusInitialized:"Pocnite kucati kljucnu rijec",statusNoResults:"Nema rezultata",statusSearching:"Trazim...",statusTooShort:"Molimo unesite vise znakova"},$.fn.ajaxSelectPicker.locale.ru=$.fn.ajaxSelectPicker.locale["sr-SP"];})(jQuery); diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js index 6af588f4..6af588f4 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js index 4428d3c0..877071ce 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js @@ -1 +1 @@ -!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){!function(a){a.fn.selectpicker.defaults={noneSelectedText:"",noneResultsText:"",countSelectedText:function(a,b){return 1==a?"... ({n})":"... ({n})"},maxOptionsText:function(a,b){return[1==a?"🛇":"🛇",1==b?"🛇":"🛇"]},selectAllText:"++",deselectAllText:"--",multipleSeparator:", "}}(a)});
\ No newline at end of file +!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){!function(a){a.fn.selectpicker.defaults={noneSelectedText:" ",noneResultsText:"",countSelectedText:function(a,b){return 1==a?"... ({n})":"... ({n})"},maxOptionsText:function(a,b){return[1==a?"🛇":"🛇",1==b?"🛇":"🛇"]},selectAllText:"++",deselectAllText:"--",multipleSeparator:", "}}(a)});
\ No newline at end of file diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt index bfd93900..0e759896 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt @@ -44,7 +44,7 @@ class SelectInputSpec : DomSpec { root.add(selectInput) val element = document.getElementById("test") assertTrue( - true == element?.innerHTML?.endsWith("<select class=\"selectpicker\" multiple=\"multiple\" data-live-search=\"true\" title=\"Choose ...\" data-style=\"btn-default\" data-width=\"fit\" tabindex=\"-98\"><option value=\"#kvnull\"></option><option value=\"test1\">Test 1</option><option value=\"test2\">Test 2</option></select></div>"), + true == element?.innerHTML?.startsWith("<div class=\"dropdown bootstrap-select show-tick fit-width\"><select class=\"selectpicker\" multiple=\"multiple\" data-live-search=\"true\" title=\"Choose ...\" data-style=\"btn-default\" data-width=\"fit\" tabindex=\"-98\"><option value=\"#kvnull\"></option><option value=\"test1\">Test 1</option><option value=\"test2\">Test 2</option></select>"), "Should render correct select input" ) } diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt index 33ccc843..33ccc843 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt index 33c36576..d711301a 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt @@ -41,9 +41,9 @@ class SelectOptionSpec : DomSpec { element?.innerHTML, "Should render correct select option" ) - selectOption.icon = "fa-flag" + selectOption.icon = "fas fa-flag" assertEqualsHtml( - "<option value=\"testValue\" data-icon=\"fa fa-flag\">testLabel</option>", + "<option value=\"testValue\" data-icon=\"fas fa-flag\">testLabel</option>", element?.innerHTML, "Should render correct select option with icon" ) diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt index 9eddff81..9ed44f82 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt @@ -45,11 +45,7 @@ class SelectSpec : DomSpec { val element = document.getElementById("test") val id = select.input.id assertTrue( - true == element?.innerHTML?.startsWith("<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label>"), - "Should render correct select form control" - ) - assertTrue( - true == element?.innerHTML?.endsWith("<select class=\"form-control selectpicker\" id=\"$id\" multiple=\"multiple\" data-live-search=\"true\" title=\"Choose ...\" data-style=\"btn-default\" data-width=\"fit\" tabindex=\"-98\"><option value=\"#kvnull\"></option><option value=\"test1\">Test 1</option><option value=\"test2\">Test 2</option></select></div></div>"), + true == element?.innerHTML?.startsWith("<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"dropdown bootstrap-select show-tick form-control fit-width\"><select class=\"form-control selectpicker\" id=\"$id\" multiple=\"multiple\" data-live-search=\"true\" title=\"Choose ...\" data-style=\"btn-default\" data-width=\"fit\" tabindex=\"-98\"><option value=\"#kvnull\"></option><option value=\"test1\">Test 1</option><option value=\"test2\">Test 2</option></select>"), "Should render correct select form control" ) } diff --git a/kvision-modules/kvision-bootstrap-select/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-select/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/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-bootstrap-select/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-select/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/webpack.config.d/jquery.js @@ -0,0 +1,5 @@ +config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" +})); diff --git a/kvision-modules/kvision-bootstrap-spinner/build.gradle b/kvision-modules/kvision-bootstrap-spinner/build.gradle new file mode 100644 index 00000000..02d4e9e5 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/build.gradle @@ -0,0 +1,13 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} + +kotlinFrontend { + + npm { + dependency("bootstrap-touchspin", "4.2.5") + } + +} diff --git a/kvision-modules/kvision-spinner/package.json.d/project.info b/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info index fb0c7956..fb0c7956 100644 --- a/kvision-modules/kvision-spinner/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt index ca4d3764..de406845 100644 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt @@ -26,17 +26,11 @@ internal val kVManagerSpinnerInit = KVManagerSpinner.init() /** * Internal singleton object which initializes and configures KVision spinner module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerSpinner { - fun init() {} - - private val bootstrapTouchspinCss = try { + init { require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css") - } catch (e: Throwable) { - } - private val bootstrapTouchspin = try { require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt index 31c6ceb8..7e3048d1 100644 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt @@ -25,8 +25,9 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.NumberFormControl +import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -47,8 +48,8 @@ import pl.treksoft.kvision.utils.SnOn */ open class Spinner( value: Number? = null, name: String? = null, min: Int? = null, max: Int? = null, step: Double = DEFAULT_STEP, - decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, label: String? = null, + decimals: Int = 0, val buttonsType: ButtonsType = ButtonsType.VERTICAL, + forceType: ForceType = ForceType.NONE, buttonStyle: ButtonStyle? = null, label: String? = null, rich: Boolean = false ) : SimplePanel(setOf("form-group")), NumberFormControl { @@ -104,14 +105,6 @@ open class Spinner( input.decimals = value } /** - * Spinner buttons type. - */ - var buttonsType - get() = input.buttonsType - set(value) { - input.buttonsType = value - } - /** * Spinner force rounding type. */ var forceType @@ -120,6 +113,14 @@ open class Spinner( input.forceType = value } /** + * The style of the up/down buttons. + */ + var buttonStyle + get() = input.buttonStyle + set(value) { + input.buttonStyle = value + } + /** * The placeholder for the spinner input. */ var placeholder @@ -160,28 +161,40 @@ open class Spinner( flabel.rich = value } - protected val idc = "kv_form_spinner_$counter" - final override val input: SpinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType) - .apply { - this.id = idc - this.name = name + override var validatorError: String? + get() = super.validatorError + set(value) { + super.validatorError = value + if (value != null) { + input.addSurroundingCssClass("is-invalid") + } else { + input.removeSurroundingCssClass("is-invalid") + } } + + protected val idc = "kv_form_spinner_$counter" + final override val input: SpinnerInput = + SpinnerInput(value, min, max, step, decimals, buttonsType, forceType, buttonStyle) + .apply { + this.id = idc + this.name = name + } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } @@ -230,6 +243,15 @@ open class Spinner( input.blur() } + override fun styleForHorizontalFormPanel() { + addCssClass("row") + flabel.addCssClass("col-sm-2") + flabel.addCssClass("col-form-label") + input.addSurroundingCssClass("col-sm-10") + invalidFeedback.addCssClass("offset-sm-2") + invalidFeedback.addCssClass("col-sm-10") + } + companion object { internal var counter = 0 @@ -247,15 +269,17 @@ open class Spinner( decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, forceType: ForceType = ForceType.NONE, + buttonStyle: ButtonStyle? = null, label: String? = null, rich: Boolean = false, init: (Spinner.() -> Unit)? = null ): Spinner { - val spinner = Spinner(value, name, min, max, step, decimals, buttonsType, forceType, label, rich).apply { - init?.invoke( - this - ) - } + val spinner = + Spinner(value, name, min, max, step, decimals, buttonsType, forceType, buttonStyle, label, rich).apply { + init?.invoke( + this + ) + } this.add(spinner) return spinner } diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt index 18df26fa..c75bbfc4 100644 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt @@ -29,6 +29,8 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus +import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.utils.obj /** @@ -63,37 +65,17 @@ internal const val DEFAULT_STEP = 1.0 * @param decimals number of decimal digits (default 0) * @param buttonsType spinner buttons type * @param forceType spinner force rounding type + * @param buttonStyle the style of the up/down buttons * @param classes a set of CSS class names */ @Suppress("TooManyFunctions") open class SpinnerInput( value: Number? = null, min: Int? = null, max: Int? = null, step: Double = DEFAULT_STEP, - decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, + decimals: Int = 0, val buttonsType: ButtonsType = ButtonsType.VERTICAL, + forceType: ForceType = ForceType.NONE, buttonStyle: ButtonStyle? = null, classes: Set<String> = setOf() ) : Widget(classes + "form-control"), FormInput { - init { - this.addSurroundingCssClass("input-group") - if (buttonsType == ButtonsType.NONE) { - this.addSurroundingCssClass("kv-spinner-btn-none") - } else { - this.removeSurroundingCssClass("kv-spinner-btn-none") - } - if (buttonsType == ButtonsType.VERTICAL) { - this.addSurroundingCssClass("kv-spinner-btn-vertical") - } else { - this.removeSurroundingCssClass("kv-spinner-btn-vertical") - } - this.surroundingSpan = true - this.refreshSpinner() - this.setInternalEventListener<SpinnerInput> { - change = { - self.changeValue() - } - } - } - /** * Spinner value. */ @@ -122,14 +104,14 @@ open class SpinnerInput( */ var decimals by refreshOnUpdate(decimals) { refreshSpinner() } /** - * Spinner buttons type. - */ - var buttonsType by refreshOnUpdate(buttonsType) { refreshSpinner() } - /** * Spinner force rounding type. */ var forceType by refreshOnUpdate(forceType) { refreshSpinner() } /** + * The style of the up/down buttons. + */ + var buttonStyle by refreshOnUpdate(buttonStyle) { refreshSpinner() } + /** * The placeholder for the spinner input. */ var placeholder: String? by refreshOnUpdate() @@ -153,15 +135,38 @@ open class SpinnerInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() private var siblings: JQuery? = null + init { + this.addSurroundingCssClass("input-group") + this.addSurroundingCssClass("kv-spinner") + when (buttonsType) { + ButtonsType.NONE -> this.addSurroundingCssClass("kv-spinner-btn-none") + ButtonsType.VERTICAL -> this.addSurroundingCssClass("kv-spinner-btn-vertical") + ButtonsType.HORIZONTAL -> this.addSurroundingCssClass("kv-spinner-btn-horizontal") + } + this.surroundingSpan = true + this.setInternalEventListener<SpinnerInput> { + change = { + self.changeValue() + } + } + } + override fun render(): VNode { return render("input") } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } @@ -273,6 +278,7 @@ open class SpinnerInput( private fun getSettingsObj(): dynamic { val verticalbuttons = buttonsType == ButtonsType.VERTICAL || buttonsType == ButtonsType.NONE + val style = buttonStyle return obj { this.min = min this.max = max @@ -280,12 +286,17 @@ open class SpinnerInput( this.decimals = decimals this.verticalbuttons = verticalbuttons this.forcestepdivisibility = forceType.value + if (style != null) { + this.buttonup_class = "btn ${style.className}" + this.buttondown_class = "btn ${style.className}" + } else { + this.buttonup_class = "btn btn-secondary" + this.buttondown_class = "btn btn-secondary" + } if (verticalbuttons) { - this.verticalup = "<i class=\"fa fa-caret-up\"></i>" - this.verticaldown = "<i class=\"fa fa-caret-down\"></i>" + this.verticalup = "<i class=\"fas fa-caret-up\"></i>" + this.verticaldown = "<i class=\"fas fa-caret-down\"></i>" } - this.buttondown_class = "btn btn-default" - this.buttonup_class = "btn btn-default" } } @@ -313,14 +324,15 @@ open class SpinnerInput( fun Container.spinnerInput( value: Number? = null, min: Int? = null, max: Int? = null, step: Double = DEFAULT_STEP, decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, classes: Set<String> = setOf(), + forceType: ForceType = ForceType.NONE, buttonStyle: ButtonStyle? = null, classes: Set<String> = setOf(), init: (SpinnerInput.() -> Unit)? = null ): SpinnerInput { - val spinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType, classes).apply { - init?.invoke( - this - ) - } + val spinnerInput = + SpinnerInput(value, min, max, step, decimals, buttonsType, forceType, buttonStyle, classes).apply { + init?.invoke( + this + ) + } this.add(spinnerInput) return spinnerInput } diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt index 467e48db..467e48db 100644 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt index 928fe0b1..bb090b61 100644 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt @@ -43,13 +43,13 @@ class SpinnerSpec : DomSpec { val element = document.getElementById("test") val id = ti.input.id assertEqualsHtml( - "<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner-btn-vertical\"><span><div class=\"input-group bootstrap-touchspin bootstrap-touchspin-injected\"><input class=\"form-control\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"disabled\"><span class=\"input-group-btn-vertical\"><button class=\"btn btn-default bootstrap-touchspin-up \" type=\"button\"><i class=\"fa fa-caret-up\"></i></button><button class=\"btn btn-default bootstrap-touchspin-down \" type=\"button\"><i class=\"fa fa-caret-down\"></i></button></span></div></span></div></div>", + "<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner kv-spinner-btn-vertical\"><span><div class=\"input-group bootstrap-touchspin bootstrap-touchspin-injected\"><input class=\"form-control\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"disabled\"><span class=\"input-group-btn-vertical\"><button class=\"btn btn-secondary bootstrap-touchspin-up \" type=\"button\"><i class=\"fas fa-caret-up\"></i></button><button class=\"btn btn-secondary bootstrap-touchspin-down \" type=\"button\"><i class=\"fas fa-caret-down\"></i></button></span></div></span></div></div>", element?.innerHTML, "Should render correct spinner input form control" ) ti.validatorError = "Validation Error" assertEqualsHtml( - "<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner-btn-vertical\"><span><div class=\"input-group bootstrap-touchspin bootstrap-touchspin-injected\"><input class=\"form-control\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"disabled\"><span class=\"input-group-btn-vertical\"><button class=\"btn btn-default bootstrap-touchspin-up \" type=\"button\"><i class=\"fa fa-caret-up\"></i></button><button class=\"btn btn-default bootstrap-touchspin-down \" type=\"button\"><i class=\"fa fa-caret-down\"></i></button></span></div></span></div><span class=\"help-block small\">Validation Error</span></div>", + "<div class=\"form-group text-danger\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner kv-spinner-btn-vertical is-invalid\"><span><div class=\"input-group bootstrap-touchspin bootstrap-touchspin-injected\"><input class=\"form-control is-invalid\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"disabled\"><span class=\"input-group-btn-vertical\"><button class=\"btn btn-secondary bootstrap-touchspin-up \" type=\"button\"><i class=\"fas fa-caret-up\"></i></button><button class=\"btn btn-secondary bootstrap-touchspin-down \" type=\"button\"><i class=\"fas fa-caret-down\"></i></button></span></div></span></div><div class=\"invalid-feedback\">Validation Error</div></div>", element?.innerHTML, "Should render correct spinner input form control with validation error" ) diff --git a/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/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-bootstrap-spinner/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js @@ -0,0 +1,5 @@ +config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" +})); diff --git a/kvision-modules/kvision-bootstrap-upload/build.gradle b/kvision-modules/kvision-bootstrap-upload/build.gradle new file mode 100644 index 00000000..a47a110a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/build.gradle @@ -0,0 +1,14 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap") + compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" +} + +kotlinFrontend { + + npm { + dependency("bootstrap-fileinput", "5.0.6") + } + +} diff --git a/kvision-modules/kvision-upload/package.json.d/project.info b/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info index d789d81b..d789d81b 100644 --- a/kvision-modules/kvision-upload/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt index af0950eb..1d8f05b0 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt @@ -26,19 +26,11 @@ internal val kVManagerUploadInit = KVManagerUpload.init() /** * Internal singleton object which initializes and configures KVision upload module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerUpload { - fun init() {} - private val bootstrapFileinputCss = try { + init { require("bootstrap-fileinput/css/fileinput.min.css") - } catch (e: Throwable) { - } - private val bootstrapFileinputCssFa = try { - require("bootstrap-fileinput/themes/explorer-fa/theme.min.css") - } catch (e: Throwable) { - } - private val bootstrapFileinput = try { + require("bootstrap-fileinput/themes/explorer-fas/theme.min.css") require("bootstrap-fileinput") require("./js/locales/bootstrap-fileinput/ar.js") require("./js/locales/bootstrap-fileinput/az.js") @@ -59,7 +51,7 @@ internal object KVManagerUpload { require("./js/locales/bootstrap-fileinput/it.js") require("./js/locales/bootstrap-fileinput/ja.js") require("./js/locales/bootstrap-fileinput/ka.js") - require("./js/locales/bootstrap-fileinput/ko.js") + require("./js/locales/bootstrap-fileinput/kr.js") require("./js/locales/bootstrap-fileinput/kz.js") require("./js/locales/bootstrap-fileinput/lt.js") require("./js/locales/bootstrap-fileinput/nl.js") @@ -76,11 +68,9 @@ internal object KVManagerUpload { require("./js/locales/bootstrap-fileinput/uk.js") require("./js/locales/bootstrap-fileinput/vi.js") require("./js/locales/bootstrap-fileinput/zh.js") - } catch (e: Throwable) { - } - private val bootstrapFileinputFa = try { - require("bootstrap-fileinput/themes/explorer-fa/theme.min.js") - } catch (e: Throwable) { + require("bootstrap-fileinput/themes/explorer-fas/theme.min.js") + require("bootstrap-fileinput/themes/fas/theme.min.js") } + internal fun init() {} } diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt index 971ce186..bd931127 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt @@ -26,7 +26,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.KFilesFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.types.KFile @@ -208,21 +208,21 @@ open class Upload( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt index 21073e61..faae5274 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt @@ -31,6 +31,7 @@ import pl.treksoft.kvision.form.Form import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.FormPanel import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.types.KFile import pl.treksoft.kvision.utils.getContent @@ -135,6 +136,10 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla * The size of the input (currently not working) */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() private val nativeFiles: MutableMap<KFile, File> = mutableMapOf() @@ -144,6 +149,9 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } @@ -290,7 +298,7 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla return obj { this.uploadUrl = uploadUrl this.uploadExtraData = uploadExtraData ?: undefined - this.theme = if (explorerTheme) "explorer-fa" else null + this.theme = if (explorerTheme) "explorer-fas" else "fas" this.required = required this.showCaption = showCaption this.showPreview = showPreview @@ -307,6 +315,8 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla this.showUpload = showUpload this.showRemove = showRemove } + this.autoOrientImage = false + this.purifyHtml = false this.language = language } } diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt index bdae5091..bdae5091 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js index 92d32d28..2245b633 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js @@ -20,10 +20,13 @@ removeTitle: 'إزالة الملفات المختارة', cancelLabel: 'إلغاء', cancelTitle: 'إنهاء الرفع الحالي', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'رفع', uploadTitle: 'رفع الملفات المختارة', msgNo: 'لا', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'ألغيت', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'معاينة تفصيلية', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'خطأ التحقق من صحة', msgLoading: 'تحميل ملف {index} من {files} …', msgProgress: 'تحميل ملف {index} من {files} - {name} - {percent}% منتهي.', @@ -69,6 +75,10 @@ msgImageResizeException: 'حدث خطأ أثناء تغيير أبعاد الصورة.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -87,7 +97,8 @@ indicatorNewTitle: 'لم يتم الرفع بعد', indicatorSuccessTitle: 'تم الرفع', indicatorErrorTitle: 'خطأ بالرفع', - indicatorLoadingTitle: 'جارٍ الرفع ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'جارٍ الرفع ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js index 5a9c6440..c3efafaa 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js @@ -20,10 +20,13 @@ removeTitle: 'Seçilmiş faylları təmizlə', cancelLabel: 'İmtina et', cancelTitle: 'Cari yükləməni dayandır', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Yüklə', uploadTitle: 'Seçilmiş faylları yüklə', msgNo: 'xeyir', msgNoFilesSelected: 'Heç bir fayl seçilməmişdir', + msgPaused: 'Paused', msgCancelled: 'İmtina edildi', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'İlkin baxış', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Yükləmə...', msgUploadBegin: 'Yoxlama...', msgUploadEnd: 'Fayl(lar) yükləndi', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Yükləmə üçün verilmiş məlumatlar yanlışdır', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Yoxlama nəticəsi səhvir', msgLoading: '{files} fayldan {index} yüklənir …', msgProgress: '{files} fayldan {index} - {name} - {percent}% yükləndi.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Faylın ölçülərini dəyişmək mümkün olmadı.<pre>{errors}</pre>', msgAjaxError: '{operation} əməliyyatı zamanı səhv baş verdi. Təkrar yoxlayın!', msgAjaxProgressError: '{operation} əməliyyatı yerinə yetirmək mümkün olmadı.', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'faylı sil', uploadThumb: 'faylı yüklə', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Davam edir', indicatorSuccessTitle: 'Tamamlandı', indicatorErrorTitle: 'Yükləmə xətası', - indicatorLoadingTitle: 'Yükləmə ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Yükləmə ...' }, previewZoomButtonTitles: { prev: 'Əvvəlki fayla bax', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js index cf75d1ab..537932d0 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js @@ -19,10 +19,13 @@ removeTitle: 'Изчисти избраните', cancelLabel: 'Откажи', cancelTitle: 'Откажи качването', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Качи', uploadTitle: 'Качи избраните файлове', msgNo: 'Не', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Отменен', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Детайлен преглед', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'утвърждаване грешка', msgLoading: 'Зареждане на файл {index} от общо {files} …', msgProgress: 'Зареждане на файл {index} от общо {files} - {name} - {percent}% завършени.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Грешка при промяна на размера на изображението.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Все още не е качил', indicatorSuccessTitle: 'Качено', indicatorErrorTitle: 'Качи Error', - indicatorLoadingTitle: 'Качва се ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Качва се ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js index 16514535..b8410975 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js @@ -19,10 +19,13 @@ removeTitle: 'Treure arxius seleccionats', cancelLabel: 'Cancel', cancelTitle: 'Avortar la pujada en curs', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Pujar arxiu', uploadTitle: 'Pujar arxius seleccionats', msgNo: 'No', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'cancel·lat', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Vista prèvia detallada', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Error de validació', msgLoading: 'Pujant fitxer {index} de {files} …', msgProgress: 'Pujant fitxer {index} de {files} - {name} - {percent}% completat.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Error en canviar la mida de la imatge.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -86,7 +96,8 @@ indicatorNewTitle: 'No pujat encara', indicatorSuccessTitle: 'Subido', indicatorErrorTitle: 'Pujar Error', - indicatorLoadingTitle: 'Pujant ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Pujant ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js index 685da85d..d6c9f420 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js @@ -20,10 +20,13 @@ removeTitle: 'Ukloni označene datoteke', cancelLabel: 'Odustani', cancelTitle: 'Prekini trenutno otpremanje', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Otpremi', uploadTitle: 'Otpremi označene datoteke', msgNo: 'Ne', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Otkazan', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Detaljni pregled', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Provjera pogrešaka', msgLoading: 'Učitavanje datoteke {index} od {files} …', msgProgress: 'Učitavanje datoteke {index} od {files} - {name} - {percent}% završeno.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Greška prilikom promjene veličine slike.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Još nije učitao', indicatorSuccessTitle: 'Preneseno', indicatorErrorTitle: 'Postavi Greška', - indicatorLoadingTitle: 'Prijenos ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Prijenos ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js index f5e8b723..e3989943 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js @@ -19,10 +19,13 @@ removeTitle: 'Vyčistit vybrané soubory', cancelLabel: 'Storno', cancelTitle: 'Přerušit nahrávání', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Nahrát', uploadTitle: 'Nahrát vybrané soubory', msgNo: 'Ne', msgNoFilesSelected: 'Nevybrány žádné soubory', + msgPaused: 'Paused', msgCancelled: 'Zrušeno', msgPlaceholder: 'Vybrat {files}...', msgZoomModalHeading: 'Detailní náhled', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Zpracovávám...', msgUploadBegin: 'Inicializujem...', msgUploadEnd: 'Hotovo', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Pro nahrávání nejsou k dispozici žádné platné údaje.', - msgUploadError: 'Chyba', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Chyba', msgValidationError: 'Chyba ověření', msgLoading: 'Nahrávání souboru {index} z {files} …', msgProgress: 'Nahrávání souboru {index} z {files} - {name} - {percent}% dokončeno.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Chyba při změně velikosti obrázku.<pre>{errors}</pre>', msgAjaxError: 'Došlo k chybě v {operation}. Prosím zkuste to znovu později!', msgAjaxProgressError: '{operation} - neúspěšné', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'odstranit soubor', uploadThumb: 'nahrát soubor', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Ještě nenahrál', indicatorSuccessTitle: 'Nahraný', indicatorErrorTitle: 'Chyba nahrávání', - indicatorLoadingTitle: 'Nahrávání ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Nahrávání ...' }, previewZoomButtonTitles: { prev: 'Zobrazit předchozí soubor', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js index 11a13892..27d57db5 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js @@ -19,10 +19,13 @@ removeTitle: 'Fjern valgte filer', cancelLabel: 'Fortryd', cancelTitle: 'Afbryd nuværende upload', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Upload', uploadTitle: 'Upload valgte filer', msgNo: 'Ingen', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'aflyst', msgPlaceholder: 'Vælg {files}...', msgZoomModalHeading: 'Detaljeret visning', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Arbejder...', msgUploadBegin: 'Initialiserer...', msgUploadEnd: 'Udført', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Ingen gyldig data tilgængelig til upload.', - msgUploadError: 'Fejl', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Fejl', msgValidationError: 'Valideringsfejl', msgLoading: 'Henter fil {index} af {files} …', msgProgress: 'Henter fil {index} af {files} - {name} - {percent}% færdiggjort.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Fejl ved at ændre størrelsen på billedet.<pre>{errors}</pre>', msgAjaxError: 'Noget gik galt med {operation} operationen. Forsøg venligst senere!', msgAjaxProgressError: '{operation} fejlede', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'fil slet', uploadThumb: 'fil upload', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Ikke uploadet endnu', indicatorSuccessTitle: 'Uploadet', indicatorErrorTitle: 'Upload fejl', - indicatorLoadingTitle: 'Uploader ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Uploader ...' }, previewZoomButtonTitles: { prev: 'Se forrige fil', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js index 56ee854b..c1bb4797 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js @@ -17,10 +17,13 @@ removeTitle: 'Ausgewählte löschen', cancelLabel: 'Abbrechen', cancelTitle: 'Hochladen abbrechen', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Hochladen', uploadTitle: 'Hochladen der ausgewählten Dateien', msgNo: 'Keine', msgNoFilesSelected: 'Keine Dateien ausgewählt', + msgPaused: 'Paused', msgCancelled: 'Abgebrochen', msgPlaceholder: '{files} auswählen...', msgZoomModalHeading: 'ausführliche Vorschau', @@ -51,8 +54,11 @@ msgUploadThreshold: 'Wird bearbeitet ...', msgUploadBegin: 'Wird initialisiert ...', msgUploadEnd: 'Erledigt', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Keine gültigen Daten zum Hochladen verfügbar.', - msgUploadError: 'Fehler', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Fehler', msgValidationError: 'Validierungsfehler', msgLoading: 'Lade Datei {index} von {files} hoch…', msgProgress: 'Datei {index} von {files} - {name} - zu {percent}% fertiggestellt.', @@ -66,6 +72,10 @@ msgImageResizeException: 'Fehler beim Ändern der Größe des Bildes.<pre>{errors}</pre>', msgAjaxError: 'Bei der Aktion {operation} ist ein Fehler aufgetreten. Bitte versuche es später noch einmal!', msgAjaxProgressError: '{operation} fehlgeschlagen', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'Datei löschen', uploadThumb: 'Datei hochladen', @@ -84,7 +94,8 @@ indicatorNewTitle: 'Noch nicht hochgeladen', indicatorSuccessTitle: 'Hochgeladen', indicatorErrorTitle: 'Upload Fehler', - indicatorLoadingTitle: 'Hochladen ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Hochladen ...' }, previewZoomButtonTitles: { prev: 'Vorherige Datei anzeigen', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js index 170eba1f..a0d888e4 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js @@ -19,10 +19,13 @@ removeTitle: 'Εκκαθάριση αρχείων', cancelLabel: 'Ακύρωση', cancelTitle: 'Ακύρωση μεταφόρτωσης', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Μεταφόρτωση', uploadTitle: 'Μεταφόρτωση επιλεγμένων αρχείων', msgNo: 'Όχι', msgNoFilesSelected: 'Δεν επιλέχθηκαν αρχεία', + msgPaused: 'Paused', msgCancelled: 'Ακυρώθηκε', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Λεπτομερής Προεπισκόπηση', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Μεταφόρτωση ...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Σφάλμα Επικύρωσης', msgLoading: 'Φόρτωση αρχείου {index} από {files} …', msgProgress: 'Φόρτωση αρχείου {index} απο {files} - {name} - {percent}% ολοκληρώθηκε.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Σφάλμα κατά την αλλαγή μεγέθους της εικόνας. <pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Δεν μεταφορτώθηκε ακόμα', indicatorSuccessTitle: 'Μεταφορτώθηκε', indicatorErrorTitle: 'Σφάλμα Μεταφόρτωσης', - indicatorLoadingTitle: 'Μεταφόρτωση ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Μεταφόρτωση ...' }, previewZoomButtonTitles: { prev: 'Προηγούμενο αρχείο', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js index 569e7ee5..b1c58e6f 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js @@ -19,10 +19,13 @@ removeTitle: 'Quitar archivos seleccionados', cancelLabel: 'Cancelar', cancelTitle: 'Abortar la subida en curso', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Subir archivo', uploadTitle: 'Subir archivos seleccionados', msgNo: 'No', msgNoFilesSelected: 'No hay archivos seleccionados', + msgPaused: 'Paused', msgCancelled: 'Cancelado', msgPlaceholder: 'Seleccionar {files}...', msgZoomModalHeading: 'Vista previa detallada', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Procesando...', msgUploadBegin: 'Inicializando...', msgUploadEnd: 'Hecho', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No existen datos válidos para el envío.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Error de validación', msgLoading: 'Subiendo archivo {index} de {files} …', msgProgress: 'Subiendo archivo {index} de {files} - {name} - {percent}% completado.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Error al cambiar el tamaño de la imagen.<pre>{errors}</pre>', msgAjaxError: 'Algo ha ido mal con la operación {operation}. Por favor, inténtelo de nuevo mas tarde.', msgAjaxProgressError: 'La operación {operation} ha fallado', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'Archivo borrado', uploadThumb: 'Archivo subido', @@ -86,7 +96,8 @@ indicatorNewTitle: 'No subido todavía', indicatorSuccessTitle: 'Subido', indicatorErrorTitle: 'Error al subir', - indicatorLoadingTitle: 'Subiendo...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Subiendo...' }, previewZoomButtonTitles: { prev: 'Anterior', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js index 50b15477..039980f1 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js @@ -19,10 +19,13 @@ removeTitle: 'Clear selected files', cancelLabel: 'Tühista', cancelTitle: 'Abort ongoing upload', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Salvesta', uploadTitle: 'Salvesta valitud failid', msgNo: 'No', msgNoFilesSelected: 'No files selected', + msgPaused: 'Paused', msgCancelled: 'Cancelled', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Detailed Preview', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Validation Error', msgLoading: 'Loading file {index} of {files} …', msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Error while resizing the image.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -85,7 +95,8 @@ indicatorNewTitle: 'Pole veel salvestatud', indicatorSuccessTitle: 'Uploaded', indicatorErrorTitle: 'Salvestamise viga', - indicatorLoadingTitle: 'Salvestan ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Salvestan ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js index 609099c4..11d1d291 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js @@ -20,10 +20,13 @@ removeTitle: 'پاکسازی فایلهای انتخاب شده', cancelLabel: 'لغو', cancelTitle: 'لغو بارگزاری جاری', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'بارگذاری', uploadTitle: 'بارگذاری فایلهای انتخاب شده', msgNo: 'نه', msgNoFilesSelected: 'هیچ فایلی انتخاب نشده است', + msgPaused: 'Paused', msgCancelled: 'لغو شد', msgPlaceholder: 'انتخاب {files}...', msgZoomModalHeading: 'نمایش با جزییات', @@ -54,8 +57,11 @@ msgUploadThreshold: 'در حال پردازش...', msgUploadBegin: 'در حال شروع...', msgUploadEnd: 'انجام شد', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'هیچ داده معتبری برای بارگذاری موجود نیست.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'خطای اعتبار سنجی', msgLoading: 'بارگیری فایل {index} از {files} …', msgProgress: 'بارگیری فایل {index} از {files} - {name} - {percent}% تمام شد.', @@ -69,6 +75,10 @@ msgImageResizeException: 'خطا در هنگام تغییر اندازه تصویر.<pre>{errors}</pre>', msgAjaxError: 'به نظر مشکلی در حین {operation} روی داده است. لطفا دوباره تلاش کنید!', msgAjaxProgressError: '{operation} لغو شد', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'حذف فایل', uploadThumb: 'بارگذاری فایل', @@ -87,7 +97,8 @@ indicatorNewTitle: 'آپلود نشده است', indicatorSuccessTitle: 'آپلود شده', indicatorErrorTitle: 'بارگذاری خطا', - indicatorLoadingTitle: 'آپلود ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'آپلود ...' }, previewZoomButtonTitles: { prev: 'مشاهده فایل قبلی', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js index 19317b54..85154eec 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js @@ -19,6 +19,8 @@ removeTitle: 'Tyhjännä valitut tiedostot', cancelLabel: 'Peruuta', cancelTitle: 'Peruuta lataus', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Lataa', uploadTitle: 'Lataa valitut tiedostot', msgNoFilesSelected: '', @@ -48,8 +50,11 @@ msgUploadThreshold: 'Käsitellään...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Ei ladattavaa dataa.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Tiedoston latausvirhe', msgLoading: 'Ladataan tiedostoa {index} / {files} …', msgProgress: 'Ladataan tiedostoa {index} / {files} - {name} - {percent}% valmistunut.', @@ -57,6 +62,10 @@ msgFoldersNotAllowed: 'Raahaa ja pudota ainoastaan tiedostoja! Ohitettu {n} raahattua kansiota.', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -75,7 +84,8 @@ indicatorNewTitle: 'Ei ladattu', indicatorSuccessTitle: 'Ladattu', indicatorErrorTitle: 'Lataus epäonnistui', - indicatorLoadingTitle: 'Ladataan ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Ladataan ...' }, previewZoomButtonTitles: { prev: 'Seuraava tiedosto', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js index 81a77042..0d9e1e97 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js @@ -19,10 +19,13 @@ removeTitle: 'Retirer les fichiers sélectionnés', cancelLabel: 'Annuler', cancelTitle: "Annuler l'envoi en cours", + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Transférer', uploadTitle: 'Transférer les fichiers sélectionnés', msgNo: 'Non', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Annulé', msgPlaceholder: 'Sélectionner le(s) {files}...', msgZoomModalHeading: 'Aperçu détaillé', @@ -53,8 +56,11 @@ msgUploadThreshold: 'En cours...', msgUploadBegin: 'Initialisation...', msgUploadEnd: 'Terminé', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Aucune donnée valide disponible pour transmission.', - msgUploadError: 'Erreur', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Erreur', msgValidationError: 'Erreur de validation', msgLoading: 'Transmission du fichier {index} sur {files}…', msgProgress: 'Transmission du fichier {index} sur {files} - {name} - {percent}%.', @@ -68,6 +74,10 @@ msgImageResizeException: "Erreur lors du redimensionnement de l'image.<pre>{errors}</pre>", msgAjaxError: "Une erreur s'est produite pendant l'opération de {operation}. Veuillez réessayer plus tard.", msgAjaxProgressError: 'L\'opération "{operation}" a échoué', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'suppression du fichier', uploadThumb: 'transfert du fichier', @@ -85,7 +95,8 @@ indicatorNewTitle: 'Pas encore transféré', indicatorSuccessTitle: 'Posté', indicatorErrorTitle: 'Ajouter erreur', - indicatorLoadingTitle: 'En cours...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'En cours...' }, previewZoomButtonTitles: { prev: 'Voir le fichier précédent', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js index a2ba90be..0b4992de 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js @@ -19,10 +19,13 @@ removeTitle: 'Quitar aquivos seleccionados', cancelLabel: 'Cancelar', cancelTitle: 'Abortar a subida en curso', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Subir arquivo', uploadTitle: 'Subir arquivos seleccionados', msgNo: 'Non', msgNoFilesSelected: 'Non hay arquivos seleccionados', + msgPaused: 'Paused', msgCancelled: 'Cancelado', msgPlaceholder: 'Seleccinar {files}...', msgZoomModalHeading: 'Vista previa detallada', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Procesando...', msgUploadBegin: 'Inicializando...', msgUploadEnd: 'Feito', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Non existen datos válidos para o envío.', - msgUploadError: 'Erro', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Erro', msgValidationError: 'Erro de validación', msgLoading: 'Subindo arquivo {index} de {files} …', msgProgress: 'Subindo arquivo {index} de {files} - {name} - {percent}% completado.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Erro ao cambiar o tamaño da imaxe. <pre>{errors}</pre>', msgAjaxError: 'Algo foi mal ca operación {operation}. Por favor, inténtao de novo máis tarde.', msgAjaxProgressError: 'A operación {operation} fallou', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'Arquivo borrado', uploadThumb: 'Arquivo subido', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Non subido aínda', indicatorSuccessTitle: 'Subido', indicatorErrorTitle: 'Erro ao subir', - indicatorLoadingTitle: 'Subindo...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Subindo...' }, previewZoomButtonTitles: { prev: 'Ver arquivo anterior', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js index cea7de35..49a73a13 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js @@ -20,10 +20,13 @@ removeTitle: 'נקה קבצים נבחרים', cancelLabel: 'ביטול', cancelTitle: 'ביטול העלאה מתמשכת', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'טעינה', uploadTitle: 'טעינת קבצים נבחרים', msgNo: 'לא', msgNoFilesSelected: 'לא נבחרו קבצים', + msgPaused: 'Paused', msgCancelled: 'מבוטל', msgPlaceholder: 'בחר {files}...', msgZoomModalHeading: 'תצוגה מקדימה מפורטת', @@ -53,6 +56,7 @@ msgUploadThreshold: 'מעבד...', msgUploadBegin: 'מאתחל ...', msgUploadEnd: 'בוצע', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'אין נתונים זמינים להעלאה.', msgValidationError: 'שגיאת אימות', msgLoading: 'טוען קובץ {index} של {files} …', @@ -67,6 +71,10 @@ msgImageResizeException: 'שגיאה בעת שינוי גודל התמונה.<pre>{errors}</pre>', msgAjaxError: 'משהו השתבש עם {operation} המערכת. יש לנסות מאוחר יותר!', msgAjaxProgressError: '{operation} נכשל', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'קובץ נמחק', uploadThumb: 'קובץ הועלה', @@ -83,7 +91,8 @@ indicatorNewTitle: 'עדיין לא הועלה', indicatorSuccessTitle: 'הועלה', indicatorErrorTitle: 'שגיאת העלאה', - indicatorLoadingTitle: 'מעלה...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'מעלה...' }, previewZoomButtonTitles: { prev: 'הצגת את הקובץ הקודם', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js index 534815fb..de210570 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js @@ -19,10 +19,13 @@ removeTitle: 'Kijelölt fájlok törlése', cancelLabel: 'Mégse', cancelTitle: 'Feltöltés megszakítása', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Feltöltés', uploadTitle: 'Kijelölt fájlok feltöltése', msgNo: 'Nem', msgNoFilesSelected: 'Nincs fájl kiválasztva', + msgPaused: 'Paused', msgCancelled: 'Megszakítva', msgPlaceholder: 'Válasz {files}...', msgZoomModalHeading: 'Részletes Előnézet', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Folyamatban...', msgUploadBegin: 'Inicializálás...', msgUploadEnd: 'Kész', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Nincs érvényes adat a feltöltéshez.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Érvényesítés hiba', msgLoading: '{index} / {files} töltése …', msgProgress: 'Feltöltés: {index} / {files} - {name} - {percent}% kész.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Hiba történt a méretezés közben.<pre>{errors}</pre>', msgAjaxError: 'Hiba történt a művelet közben ({operation}). Kérjük, próbálja később!', msgAjaxProgressError: 'Hiba! ({operation})', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'fájl törlés', uploadThumb: 'fájl feltöltés', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Nem feltöltött', indicatorSuccessTitle: 'Feltöltött', indicatorErrorTitle: 'Feltöltés hiba', - indicatorLoadingTitle: 'Feltöltés ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Feltöltés ...' }, previewZoomButtonTitles: { prev: 'Elöző fájl megnézése', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js index cc2bab23..936e46e8 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js @@ -20,10 +20,13 @@ removeTitle: 'Hapus berkas terpilih', cancelLabel: 'Batal', cancelTitle: 'Batalkan proses pengunggahan', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Unggah', uploadTitle: 'Unggah berkas terpilih', msgNo: 'Tidak', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Dibatalkan', msgPlaceholder: 'Pilih {files}...', msgZoomModalHeading: 'Pratinjau terperinci', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Memproses...', msgUploadBegin: 'Menyiapkan...', msgUploadEnd: 'Selesai', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Tidak ada data valid yang tersedia untuk diunggah.', - msgUploadError: 'Kesalahan', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Kesalahan', msgValidationError: 'Kesalahan saat memvalidasi', msgLoading: 'Memuat {index} dari {files} berkas …', msgProgress: 'Memuat {index} dari {files} berkas - {name} - {percent}% selesai.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Kesalahan saat mengubah ukuran gambar.<pre>{errors}</pre>', msgAjaxError: 'Terjadi kesalahan ketika melakukan operasi {operation}. Silahkan coba lagi nanti!', msgAjaxProgressError: '{operation} gagal', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'Hapus berkas', uploadThumb: 'Unggah berkas', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Belum diunggah', indicatorSuccessTitle: 'Sudah diunggah', indicatorErrorTitle: 'Kesalahan dalam mengungah', - indicatorLoadingTitle: 'Mengunggah ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Mengunggah ...' }, previewZoomButtonTitles: { prev: 'Lihat berkas sebelumnya', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js index 73ee7663..fd8e5c33 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js @@ -21,10 +21,13 @@ removeTitle: 'Rimuovi i file selezionati', cancelLabel: 'Annulla', cancelTitle: 'Annulla i caricamenti in corso', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Carica', uploadTitle: 'Carica i file selezionati', msgNo: 'No', msgNoFilesSelected: 'Nessun file selezionato', + msgPaused: 'Paused', msgCancelled: 'Annullato', msgPlaceholder: 'Seleziona {files}...', msgZoomModalHeading: 'Anteprima dettagliata', @@ -55,8 +58,11 @@ msgUploadThreshold: 'In lavorazione...', msgUploadBegin: 'Inizializzazione...', msgUploadEnd: 'Fatto', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Dati non disponibili', - msgUploadError: 'Errore', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Errore', msgValidationError: 'Errore di convalida', msgLoading: 'Caricamento file {index} di {files}…', msgProgress: 'Caricamento file {index} di {files} - {name} - {percent}% completato.', @@ -70,6 +76,10 @@ msgImageResizeException: 'Errore durante il ridimensionamento dell\'immagine.<pre>{errors}</pre>', msgAjaxError: 'Qualcosa non ha funzionato con l\'operazione {operation}. Per favore riprova più tardi!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'eliminazione file', uploadThumb: 'caricamento file', @@ -88,7 +98,8 @@ indicatorNewTitle: 'Non ancora caricato', indicatorSuccessTitle: 'Caricati', indicatorErrorTitle: 'Carica Errore', - indicatorLoadingTitle: 'Caricamento ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Caricamento ...' }, previewZoomButtonTitles: { prev: 'Vedi il file precedente', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js index 3decd7fa..912237de 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js @@ -26,10 +26,13 @@ removeTitle: '選択したファイルを削除', cancelLabel: 'キャンセル', cancelTitle: 'アップロードをキャンセル', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'アップロード', uploadTitle: '選択したファイルをアップロード', msgNo: 'いいえ', msgNoFilesSelected: 'ファイルが選択されていません', + msgPaused: 'Paused', msgCancelled: 'キャンセル', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'プレビュー', @@ -60,8 +63,11 @@ msgUploadThreshold: '処理中...', msgUploadBegin: '初期化中...', msgUploadEnd: '完了', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'アップロードに有効なデータがありません', - msgUploadError: 'エラー', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'エラー', msgValidationError: '検証エラー', msgLoading: '{files}個中{index}個目のファイルを読み込み中…', msgProgress: '{files}個中{index}個のファイルを読み込み中 - {name} - {percent}% 完了', @@ -75,6 +81,10 @@ msgImageResizeException: '画像のリサイズ時にエラーが発生しました。<pre>{errors}</pre>', msgAjaxError: '{operation}実行中にエラーが発生しました。時間をおいてもう一度お試しください。', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'ファイル削除', uploadThumb: 'ファイルアップロード', @@ -95,7 +105,8 @@ indicatorNewTitle: 'まだアップロードされていません', indicatorSuccessTitle: 'アップロード済み', indicatorErrorTitle: 'アップロード失敗', - indicatorLoadingTitle: 'アップロード中...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'アップロード中...' }, previewZoomButtonTitles: { prev: '前のファイルを表示', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js index c6c0a230..f5c552c3 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js @@ -20,10 +20,13 @@ removeTitle: 'არჩეული ფაილების წაშლა', cancelLabel: 'გაუქმება', cancelTitle: 'მიმდინარე ატვირთვის გაუქმება', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'ატვირთვა', uploadTitle: 'არჩეული ფაილების ატვირთვა', msgNo: 'არა', msgNoFilesSelected: 'ფაილები არ არის არჩეული', + msgPaused: 'Paused', msgCancelled: 'გაუქმებულია', msgPlaceholder: 'აირჩიეთ {files}...', msgZoomModalHeading: 'დეტალურად ნახვა', @@ -54,8 +57,11 @@ msgUploadThreshold: 'მუშავდება...', msgUploadBegin: 'ინიციალიზაცია...', msgUploadEnd: 'დასრულებულია', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'ატვირთვისთვის დაუშვებელი მონაცემები.', - msgUploadError: 'ატვირთვის შეცდომა', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'ატვირთვის შეცდომა', msgValidationError: 'ვალიდაციის შეცდომა', msgLoading: 'ატვირთვა {index} / {files} …', msgProgress: 'ფაილის ატვირთვა დასრულებულია {index} / {files} - {name} - {percent}%.', @@ -69,6 +75,10 @@ msgImageResizeException: 'შეცდომა სურათის ზომის შეცვლისას.<pre>{errors}</pre>', msgAjaxError: 'დაფიქსირდა შეცდომა ოპერაციის {operation} შესრულებისას. ცადეთ მოგვიანებით!', msgAjaxProgressError: 'ვერ მოხერხდა ოპერაციის {operation} შესრულება', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'ფაილის წაშლა', uploadThumb: 'ფაილის ატვირთვა', @@ -87,7 +97,8 @@ indicatorNewTitle: 'ჯერ არ ატვირთულა', indicatorSuccessTitle: 'ატვირთულია', indicatorErrorTitle: 'ატვირთვის შეცდომა', - indicatorLoadingTitle: 'ატვირთვა ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'ატვირთვა ...' }, previewZoomButtonTitles: { prev: 'წინა ფაილის ნახვა', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kr.js index 0190dd73..0cee688e 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kr.js @@ -19,10 +19,13 @@ removeTitle: '선택한 파일들 지우기', cancelLabel: '취소', cancelTitle: '진행중인 업로드 중단', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: '업로드', uploadTitle: '선택한 파일 업로드', msgNo: '아니요', msgNoFilesSelected: '선택한 파일이 없습니다', + msgPaused: 'Paused', msgCancelled: '취소되었습니다', msgPlaceholder: '{files} 선택...', msgZoomModalHeading: '세부 정보', @@ -53,8 +56,11 @@ msgUploadThreshold: '처리하는 중...', msgUploadBegin: '초기화 중...', msgUploadEnd: '완료', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: '업로드 가능한 데이터가 존재하지 않습니다.', - msgUploadError: '오류', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: '오류', msgValidationError: '유효성 오류', msgLoading: '{index}/{files}번째 파일을 불러오는 중입니다. …', msgProgress: '{index}/{files} - {name} - {percent}% 불러오기 완료.', @@ -68,6 +74,10 @@ msgImageResizeException: '이미지 사이즈 재조정이 다음 이유로 실패했습니다.<pre>{errors}</pre>', msgAjaxError: '{operation} 실행 도중 실패했습니다. 잠시 후 다시 시도해 주세요!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -86,7 +96,8 @@ indicatorNewTitle: '아직 업로드 되지 않았습니다', indicatorSuccessTitle: '업로드 성공', indicatorErrorTitle: '업로드 중 에러 발생', - indicatorLoadingTitle: '업로드 중 ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: '업로드 중 ...' }, previewZoomButtonTitles: { prev: '이전 파일', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js index 82c34cc4..8ec28c62 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js @@ -20,10 +20,13 @@ removeTitle: 'Таңдалған файлдарды жою', cancelLabel: 'Күшін жою', cancelTitle: 'Ағымдағы жүктеуді болдырмау', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Жүктеу', uploadTitle: 'Таңдалған файлдарды жүктеу', msgNo: 'жоқ', msgNoFilesSelected: 'Файл таңдалмады', + msgPaused: 'Paused', msgCancelled: 'Күші жойылған', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Алдын ала толық көру', @@ -41,8 +44,11 @@ msgUploadThreshold: 'Өңдеу...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Тексеру қатесі', msgLoading: '{index} файлды {files} … жүктеу', msgProgress: '{index} файлды {files} - {name} - {percent}% жүктеу аяқталды.', @@ -56,6 +62,10 @@ msgImageResizeException: 'Суреттің мөлшерлерін өзгерткен кезде қателік пайда болды.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -74,7 +84,8 @@ indicatorNewTitle: 'Жүктелген жоқ', indicatorSuccessTitle: 'Жүктелген', indicatorErrorTitle: 'Жүктелу қатесі ', - indicatorLoadingTitle: 'Жүктелу ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Жүктелу ...' }, previewZoomButtonTitles: { prev: 'Алдыңғы файлды қарау', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js index 91f36c94..f5c007a3 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js @@ -20,10 +20,13 @@ removeTitle: 'Pašalinti pasirinktus failus', cancelLabel: 'Atšaukti', cancelTitle: 'Atšaukti vykstantį įkėlimą', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Įkelti', uploadTitle: 'Įkelti pasirinktus failus', msgNo: 'Ne', msgNoFilesSelected: 'Nepasirinkta jokių failų', + msgPaused: 'Paused', msgCancelled: 'Atšaukta', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Detali Peržiūra', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Vykdoma...', msgUploadBegin: 'Inicijuojama...', msgUploadEnd: 'Baigta', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Nėra teisingų duomenų įkėlimui.', - msgUploadError: 'Klaida', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Klaida', msgValidationError: 'Validacijos Klaida', msgLoading: 'Keliamas failas {index} iš {files} …', msgProgress: 'Keliamas failas {index} iš {files} - {name} - {percent}% baigta.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Klaida keičiant paveikslėlio matmenis.<pre>{errors}</pre>', msgAjaxError: 'Kažkas nutiko vykdant {operation} operaciją. Prašome pabandyti vėliau!', msgAjaxProgressError: '{operation} operacija nesėkminga', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'failo trynimo', uploadThumb: 'failo įkėlimo', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Dar neįkelta', indicatorSuccessTitle: 'Įkelta', indicatorErrorTitle: 'Įkėlimo Klaida', - indicatorLoadingTitle: 'Įkeliama ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Įkeliama ...' }, previewZoomButtonTitles: { prev: 'Peržiūrėti ankstesnį failą', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js index df3f3dc4..cc462627 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js @@ -19,10 +19,13 @@ removeTitle: 'Verwijder geselecteerde bestanden', cancelLabel: 'Annuleren', cancelTitle: 'Annuleer upload', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Upload', uploadTitle: 'Upload geselecteerde bestanden', msgNo: 'Nee', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Geannuleerd', msgPlaceholder: 'Selecteer {files}...', msgZoomModalHeading: 'Gedetailleerd voorbeeld', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Verwerken...', msgUploadBegin: 'Initialiseren...', msgUploadEnd: 'Gedaan', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Geen geldige data beschikbaar voor upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Bevestiging fout', msgLoading: 'Bestanden laden {index} van de {files} …', msgProgress: 'Bestanden laden {index} van de {files} - {name} - {percent}% compleet.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Fout bij het verkleinen van de foto.<pre>{errors}</pre>', msgAjaxError: 'Er ging iets mis met de {operation} actie. Gelieve later opnieuw te proberen!', msgAjaxProgressError: '{operation} mislukt', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'bestand verwijderen', uploadThumb: 'bestand uploaden', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Nog niet geupload', indicatorSuccessTitle: 'geupload', indicatorErrorTitle: 'fout uploaden', - indicatorLoadingTitle: 'uploaden ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'uploaden ...' }, previewZoomButtonTitles: { prev: 'Toon vorig bestand', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js index 773bb1bd..f6b8ab33 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js @@ -19,10 +19,13 @@ removeTitle: 'Fjern valgte filer', cancelLabel: 'Avbryt', cancelTitle: 'Stopp pågående opplastninger', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Last opp', uploadTitle: 'Last opp valgte filer', msgNo: 'Nei', msgNoFilesSelected: 'Ingen filer er valgt', + msgPaused: 'Paused', msgCancelled: 'Avbrutt', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Detaljert visning', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Prosesserer...', msgUploadBegin: 'Initialiserer...', msgUploadEnd: 'Ferdig', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Ingen gyldige data tilgjengelig for opplastning.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Valideringsfeil', msgLoading: 'Laster fil {index} av {files} …', msgProgress: 'Laster fil {index} av {files} - {name} - {percent}% fullført.', @@ -68,6 +74,10 @@ msgImageResizeException: 'En feil oppstod under endring av størrelse .<pre>{errors}</pre>', msgAjaxError: 'Noe gikk galt med {operation} operasjonen. Vennligst prøv igjen senere!', msgAjaxProgressError: '{operation} feilet', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -85,7 +95,8 @@ indicatorNewTitle: 'Opplastning ikke fullført', indicatorSuccessTitle: 'Opplastet', indicatorErrorTitle: 'Opplastningsfeil', - indicatorLoadingTitle: 'Laster opp ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Laster opp ...' }, previewZoomButtonTitles: { prev: 'Vis forrige fil', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js index e19a0ed2..6de299fb 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js @@ -19,10 +19,13 @@ removeTitle: 'Usuń zaznaczone pliki', cancelLabel: 'Przerwij', cancelTitle: 'Anuluj wysyłanie', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Wgraj', uploadTitle: 'Wgraj zaznaczone pliki', msgNo: 'Nie', msgNoFilesSelected: 'Brak zaznaczonych plików', + msgPaused: 'Paused', msgCancelled: 'Odwołany', msgPlaceholder: 'Wybierz {files}...', msgZoomModalHeading: 'Szczegółowy podgląd', @@ -43,8 +46,11 @@ msgUploadThreshold: 'Przetwarzanie...', msgUploadBegin: 'Rozpoczynanie...', msgUploadEnd: 'Gotowe!', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Brak poprawnych danych do przesłania.', - msgUploadError: 'Błąd', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Błąd', msgValidationError: 'Błąd walidacji', msgLoading: 'Wczytywanie pliku {index} z {files} …', msgProgress: 'Wczytywanie pliku {index} z {files} - {name} - {percent}% zakończone.', @@ -58,6 +64,10 @@ msgImageResizeException: 'Błąd podczas zmiany rozmiaru obrazu.<pre>{errors}</pre>', msgAjaxError: 'Coś poczło nie tak podczas {operation}. Spróbuj ponownie!', msgAjaxProgressError: '{operation} nie powiodło się', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'usuwanie pliku', uploadThumb: 'przesyłanie pliku', @@ -76,7 +86,8 @@ indicatorNewTitle: 'Jeszcze nie przesłany', indicatorSuccessTitle: 'Dodane', indicatorErrorTitle: 'Błąd', - indicatorLoadingTitle: 'Przesyłanie ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Przesyłanie ...' }, previewZoomButtonTitles: { prev: 'Pokaż poprzedni plik', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js index 157ac84c..40c32cec 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js @@ -19,10 +19,13 @@ removeTitle: 'Remover arquivos selecionados', cancelLabel: 'Cancelar', cancelTitle: 'Interromper envio em andamento', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Enviar', uploadTitle: 'Enviar arquivos selecionados', msgNo: 'Não', msgNoFilesSelected: 'Nenhum arquivo selecionado', + msgPaused: 'Paused', msgCancelled: 'Cancelado', msgPlaceholder: 'Selecionar {files}...', msgZoomModalHeading: 'Pré-visualização detalhada', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Processando...', msgUploadBegin: 'Inicializando...', msgUploadEnd: 'Concluído', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Nenhuma informação válida para upload.', - msgUploadError: 'Erro de Upload', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Erro de Upload', msgValidationError: 'Erro de validação', msgLoading: 'Enviando arquivo {index} de {files}…', msgProgress: 'Enviando arquivo {index} de {files} - {name} - {percent}% completo.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Erro ao redimensionar a imagem.<pre>{errors}</pre>', msgAjaxError: 'Algo deu errado com a operação {operation}. Por favor tente novamente mais tarde!', msgAjaxProgressError: '{operation} falhou', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'Exclusão de arquivo', uploadThumb: 'Upload de arquivos', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Ainda não enviado', indicatorSuccessTitle: 'Enviado', indicatorErrorTitle: 'Erro', - indicatorLoadingTitle: 'Enviando...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Enviando...' }, previewZoomButtonTitles: { prev: 'Visualizar arquivo anterior', diff --git a/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js new file mode 100644 index 00000000..181ab198 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js @@ -0,0 +1,111 @@ +/*! + * FileInput Portuguese Translations + * + * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or + * any HTML markup tags in the messages must not be converted or translated. + * + * @see http://github.com/kartik-v/bootstrap-fileinput + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['pt'] = { + fileSingle: 'ficheiro', + filePlural: 'ficheiros', + browseLabel: 'Procurar …', + removeLabel: 'Remover', + removeTitle: 'Remover ficheiros selecionados', + cancelLabel: 'Cancelar', + cancelTitle: 'Abortar envio', + pauseLabel: 'Parar', + pauseTitle: 'Parar envio em curso', + uploadLabel: 'Enviar', + uploadTitle: 'Enviar ficheiros selecionados', + msgNo: 'Não', + msgNoFilesSelected: 'Nenhum ficheiro selecionado', + msgPaused: 'Parado', + msgCancelled: 'Cancelado', + msgPlaceholder: 'Selecionar {files}...', + msgZoomModalHeading: 'Pré-visualização detalhada', + msgFileRequired: 'É necessário selecionar um ficheiro a enviar.', + msgSizeTooSmall: 'Ficheiro "{name}" (<b>{size} KB</b>) é demasiado pequeno, tem ser ser maior que <b>{minSize} KB</b>.', + msgSizeTooLarge: 'Ficheiro "{name}" (<b>{size} KB</b>) excede o tamanho máximo permido de <b>{maxSize} KB</b>.', + msgFilesTooLess: 'Deve selecionar pelo menos <b>{n}</b> {files} para enviar.', + msgFilesTooMany: 'Número máximo de ficheiros selecionados <b>({n})</b> excede o limite máximo de <b>{m}</b>.', + msgFileNotFound: 'Ficheiro "{name}" não encontrado.', + msgFileSecured: 'Restrições de segurança impedem a leitura do ficheiro "{name}".', + msgFileNotReadable: 'Ficheiro "{name}" não pode ser lido.', + msgFilePreviewAborted: 'Pré-visualização abortado para o ficheiro "{name}".', + msgFilePreviewError: 'Ocorreu um erro ao ler o ficheiro "{name}".', + msgInvalidFileName: 'Caracteres inválidos ou não suportados no nome de ficheiro "{name}".', + msgInvalidFileType: 'Tipo inválido para o ficheiro "{name}". Apenas ficheiros "{types}" são suportados.', + msgInvalidFileExtension: 'Extensão inválida para o ficheiro "{name}". Apenas ficheiros "{extensions}" são suportados.', + msgFileTypes: { + 'image': 'imagem', + 'html': 'HTML', + 'text': 'texto', + 'video': 'vídeo', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'objeto' + }, + msgUploadAborted: 'O envio do ficheiro foi abortado', + msgUploadThreshold: 'A processar...', + msgUploadBegin: 'A inicializar...', + msgUploadEnd: 'Concluído', + msgUploadResume: 'A retomar o envio...', + msgUploadEmpty: 'Não existem dados válidos disponíveis para o envio.', + msgUploadError: 'Erro de Envio', + msgDeleteError: 'Erro de Eliminação', + msgProgressError: 'Erro', + msgValidationError: 'Erro de Validação', + msgLoading: 'A enviar ficheiro {index} de {files} …', + msgProgress: 'A enviar ficheiro {index} de {files} - {name} - {percent}% completo.', + msgSelected: '{n} {files} selecionados', + msgFoldersNotAllowed: 'Arrastar e largar ficheiros apenas. {n} pasta(s) ignoradas.', + msgImageWidthSmall: 'Largura da imagem "{name}" deve ser pelo menos {size} px.', + msgImageHeightSmall: 'Altura da imagem "{name}" deve ser pelo menos {size} px.', + msgImageWidthLarge: 'Largura da imagem "{name}" não pode exceder {size} px.', + msgImageHeightLarge: 'Altura da imagem "{name}" não pode exceder {size} px.', + msgImageResizeError: 'Nãofoi possível obter as dimensões da imagem para redimensionar.', + msgImageResizeException: 'Erro ao redimensionar a imagem.<pre>{errors}</pre>', + msgAjaxError: 'Ocorreu um erro durante a operação {operation}. Por favor tente de novo mais tarde.', + msgAjaxProgressError: '{operation} falhou', + msgDuplicateFile: 'O ficheiro "{name}" com o mesmo tamanho "{size} KB" já foi anteriormente selecionado. O ficheiro duplicado foi ignorado.', + msgResumableUploadRetriesExceeded: 'O envio foi abortado após <b>{max}</b> tentativas para o ficheiro <b>{file}</b>. Detalhes do erro: <pre>{error}</pre>', + msgPendingTime: '{time} restante', + msgCalculatingTime: 'a calcular o tempo restante', + ajaxOperations: { + deleteThumb: 'eliminar ficheiro', + uploadThumb: 'enviar ficheiro', + uploadBatch: 'envio de ficheiros em lote', + uploadExtra: 'envio de ficheiro em formulário' + }, + dropZoneTitle: 'Arrastar e largar ficheiros aqui …', + dropZoneClickTitle: '<br>(ou clique para selecionar {files})', + fileActionSettings: { + removeTitle: 'Remover ficheiro', + uploadTitle: 'Enviar ficheiro', + uploadRetryTitle: 'Voltar a tentar o envio', + downloadTitle: 'Transferir ficheiro', + zoomTitle: 'Ver detalhes', + dragTitle: 'Mover / Reorganizar', + indicatorNewTitle: 'Ainda Não Enviado', + indicatorSuccessTitle: 'Enviado', + indicatorErrorTitle: 'Erro de Envio', + indicatorPausedTitle: 'Envio Parado', + indicatorLoadingTitle: 'A enviar ...' + }, + previewZoomButtonTitles: { + prev: 'Ver ficheiro anterior', + next: 'Ver próximo ficheiro', + toggleheader: 'Mostrar/esconder cabeçalho', + fullscreen: 'Alternar entre ecrã completo', + borderless: 'Alternar entre modo sem bordas', + close: 'Fechar pré-visualização detalhada' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js index d31b85bd..b1930984 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js @@ -20,10 +20,13 @@ removeTitle: 'Curăță fișierele selectate', cancelLabel: 'Renunță', cancelTitle: 'Anulează încărcarea curentă', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Încarcă', uploadTitle: 'Încarcă fișierele selectate', msgNo: 'Nu', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Anulat', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Previzualizare detaliată', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Eroare de validare', msgLoading: 'Se încarcă fișierul {index} din {files} …', msgProgress: 'Se încarcă fișierul {index} din {files} - {name} - {percent}% încărcat.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Eroare la redimensionarea imaginii.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Nu a încărcat încă', indicatorSuccessTitle: 'încărcat', indicatorErrorTitle: 'Încărcați eroare', - indicatorLoadingTitle: 'Se încarcă ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Se încarcă ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js index 71c5ff7a..619744bc 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js @@ -20,10 +20,13 @@ removeTitle: 'Очистить выбранные файлы', cancelLabel: 'Отмена', cancelTitle: 'Отменить текущую загрузку', + pauseLabel: 'Пауза', + pauseTitle: 'Приостановить текущую загрузку', uploadLabel: 'Загрузить', uploadTitle: 'Загрузить выбранные файлы', msgNo: 'нет', msgNoFilesSelected: '', + msgPaused: 'Приостановлено', msgCancelled: 'Отменено', msgPlaceholder: 'Выбрать {files}...', msgZoomModalHeading: 'Подробное превью', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Обработка...', msgUploadBegin: 'Инициализация...', msgUploadEnd: 'Готово', + msgUploadResume: 'Возобновление загрузки...', msgUploadEmpty: 'Недопустимые данные для загрузки', msgUploadError: 'Ошибка загрузки', + msgDeleteError: 'Ошибка удаления', + msgProgressError: 'Ошибка загрузки', msgValidationError: 'Ошибка проверки', msgLoading: 'Загрузка файла {index} из {files} …', msgProgress: 'Загрузка файла {index} из {files} - {name} - {percent}% завершено.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Ошибка при изменении размера изображения.<pre>{errors}</pre>', msgAjaxError: 'Произошла ошибка при выполнении операции {operation}. Повторите попытку позже!', msgAjaxProgressError: 'Не удалось выполнить {operation}', + msgDuplicateFile: 'Файл "{name}" с размером "{size} KB" уже был выбран ранее. Пропуск повторяющегося выбора.', + msgResumableUploadRetriesExceeded: 'Загрузка прервана после <b>{max}</b> попыток для файла <b>{file}</b>! Информация об ошибке: <pre>{error}</pre>', + msgPendingTime: '{time} осталось', + msgCalculatingTime: 'расчет оставшегося времени', ajaxOperations: { deleteThumb: 'удалить файл', uploadThumb: 'загрузить файл', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Еще не загружен', indicatorSuccessTitle: 'Загружен', indicatorErrorTitle: 'Ошибка загрузки', - indicatorLoadingTitle: 'Загрузка ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Загрузка ...' }, previewZoomButtonTitles: { prev: 'Посмотреть предыдущий файл', @@ -98,4 +109,4 @@ close: 'Закрыть подробный предпросмотр' } }; -})(window.jQuery); +})(window.jQuery);
\ No newline at end of file diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js index 28d67e9a..706cb0e0 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js @@ -19,10 +19,13 @@ removeTitle: 'Vyčistiť vybraté súbory', cancelLabel: 'Storno', cancelTitle: 'Prerušiť nahrávanie', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Nahrať', uploadTitle: 'Nahrať vybraté súbory', msgNo: 'Nie', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Zrušené', msgPlaceholder: 'Vybrať {files}...', msgZoomModalHeading: 'Detailný náhľad', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Spracovávam...', msgUploadBegin: 'Inicializujem...', msgUploadEnd: 'Hotovo', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Na nahrávanie nie sú k dispozícii žiadne platné údaje.', - msgUploadError: 'Chyba', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Chyba', msgValidationError: 'Chyba overenia', msgLoading: 'Nahrávanie súboru {index} z {files} …', msgProgress: 'Nahrávanie súboru {index} z {files} - {name} - {percent}% dokončené.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Chyba pri zmene veľkosti obrázka.<pre>{errors}</pre>', msgAjaxError: 'Pri operácii {operation} sa vyskytla chyba. Skúste to prosím neskôr!', msgAjaxProgressError: '{operation} - neúspešné', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'odstrániť súbor', uploadThumb: 'nahrať súbor', @@ -86,7 +96,8 @@ indicatorNewTitle: 'Ešte nenahral', indicatorSuccessTitle: 'Nahraný', indicatorErrorTitle: 'Chyba pri nahrávaní', - indicatorLoadingTitle: 'Nahrávanie ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Nahrávanie ...' }, previewZoomButtonTitles: { prev: 'Zobraziť predchádzajúci súbor', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js index 490d7d61..b57d996d 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js @@ -20,10 +20,13 @@ removeTitle: 'Počisti izbrane datoteke', cancelLabel: 'Prekliči', cancelTitle: 'Prekliči nalaganje', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Naloži', uploadTitle: 'Naloži izbrane datoteke', msgNo: 'Ne', msgNoFilesSelected: 'Nobena datoteka ni izbrana', + msgPaused: 'Paused', msgCancelled: 'Preklicano', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Podroben predogled', @@ -51,8 +54,11 @@ msgUploadThreshold: 'Procesiram...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Napaki pri validiranju', msgLoading: 'Nalaganje datoteke {index} od {files} …', msgProgress: 'Nalaganje datoteke {index} od {files} - {name} - {percent}% dokončano.', @@ -66,6 +72,10 @@ msgImageResizeException: 'Napaka pri spreminjanju velikosti slike.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -84,7 +94,8 @@ indicatorNewTitle: 'Še ni naloženo', indicatorSuccessTitle: 'Naloženo', indicatorErrorTitle: 'Napaka pri nalaganju', - indicatorLoadingTitle: 'Nalagam ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Nalagam ...' }, previewZoomButtonTitles: { prev: 'Poglej prejšno datoteko', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js index 038b1d99..90abd31d 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js @@ -19,10 +19,13 @@ removeTitle: 'Rensa valda filer', cancelLabel: 'Avbryt', cancelTitle: 'Avbryt pågående uppladdning', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Ladda upp', uploadTitle: 'Ladda upp valda filer', msgNo: 'Nej', msgNoFilesSelected: 'Inga filer valda', + msgPaused: 'Paused', msgCancelled: 'Avbruten', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'detaljerad förhandsgranskning', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Bearbetar...', msgUploadBegin: 'Påbörjar...', msgUploadEnd: 'Färdig', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Ingen giltig data tillgänglig för uppladdning.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Valideringsfel', msgLoading: 'Laddar fil {index} av {files} …', msgProgress: 'Laddar fil {index} av {files} - {name} - {percent}% färdig.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Fel vid storleksändring av bilden.<pre>{errors}</pre>', msgAjaxError: 'Något gick fel med {operation} operationen. Försök igen senare!', msgAjaxProgressError: '{operation} misslyckades', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -85,7 +95,8 @@ indicatorNewTitle: 'Inte uppladdat ännu', indicatorSuccessTitle: 'Uppladdad', indicatorErrorTitle: 'Uppladdningsfel', - indicatorLoadingTitle: 'Laddar upp...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Laddar upp...' }, previewZoomButtonTitles: { prev: 'Visa föregående fil', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js index 7a2d0460..c00f82ea 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js @@ -19,10 +19,13 @@ removeTitle: 'ลบไฟล์ที่เลือกทิ้ง', cancelLabel: 'ยกเลิก', cancelTitle: 'ยกเลิกการอัพโหลด', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'อัพโหลด', uploadTitle: 'อัพโหลดไฟล์ที่เลือก', msgNo: 'ไม่', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'ยกเลิก', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'ตัวอย่างละเอียด', @@ -53,8 +56,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'ข้อผิดพลาดในการตรวจสอบ', msgLoading: 'กำลังโหลดไฟล์ {index} จาก {files} …', msgProgress: 'กำลังโหลดไฟล์ {index} จาก {files} - {name} - {percent}%', @@ -68,6 +74,10 @@ msgImageResizeException: 'ข้อผิดพลาดขณะปรับขนาดภาพ<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -86,7 +96,8 @@ indicatorNewTitle: 'ยังไม่ได้อัปโหลด', indicatorSuccessTitle: 'อัพโหลด', indicatorErrorTitle: 'อัปโหลดข้อผิดพลาด', - indicatorLoadingTitle: 'อัพโหลด ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'อัพโหลด ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js index 1fe6a383..a7efa29e 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js @@ -19,10 +19,13 @@ removeTitle: 'Seçilen dosyaları sil', cancelLabel: 'İptal', cancelTitle: 'Devam eden yüklemeyi iptal et', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Yükle', uploadTitle: 'Seçilen dosyaları yükle', msgNo: 'Hayır', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'İptal edildi', msgPlaceholder: 'Seçilen {files}...', msgZoomModalHeading: 'Detaylı Önizleme', @@ -53,8 +56,11 @@ msgUploadThreshold: 'İşlem yapılıyor...', msgUploadBegin: 'Başlıyor...', msgUploadEnd: 'Başarılı', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Yüklemek için geçerli veri mevcut değil.', - msgUploadError: 'Hata', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Hata', msgValidationError: 'Doğrulama Hatası', msgLoading: 'Dosya yükleniyor {index} / {files} …', msgProgress: 'Dosya yükleniyor {index} / {files} - {name} - %{percent} tamamlandı.', @@ -68,6 +74,10 @@ msgImageResizeException: 'Görüntü boyutlandırma sırasında hata.<pre>{errors}</pre>', msgAjaxError: '{operation} işlemi ile ilgili bir şeyler ters gitti. Lütfen daha sonra tekrar deneyiniz!', msgAjaxProgressError: '{operation} işlemi başarısız oldu.', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'dosya silme', uploadThumb: 'dosya yükleme', @@ -85,7 +95,8 @@ indicatorNewTitle: 'Henüz yüklenmedi', indicatorSuccessTitle: 'Yüklendi', indicatorErrorTitle: 'Yükleme Hatası', - indicatorLoadingTitle: 'Yükleniyor ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Yükleniyor ...' }, previewZoomButtonTitles: { prev: 'Önceki dosyayı göster', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js index d1b7f3a1..94928353 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js @@ -20,10 +20,13 @@ removeTitle: 'Видалити вибрані файли', cancelLabel: 'Скасувати', cancelTitle: 'Скасувати поточне відвантаження', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Відвантажити', uploadTitle: 'Відвантажити обрані файли', msgNo: 'Немає', msgNoFilesSelected: '', + msgPaused: 'Paused', msgCancelled: 'Cкасовано', msgPlaceholder: 'Оберіть {files}...', msgZoomModalHeading: 'Детальний превью', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Обробка...', msgUploadBegin: 'Ініціалізація...', msgUploadEnd: 'Готово', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'Немає доступних даних для відвантаження.', - msgUploadError: 'Помилка', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Помилка', msgValidationError: 'Помилка перевірки', msgLoading: 'Відвантаження файла {index} із {files} …', msgProgress: 'Відвантаження файла {index} із {files} - {name} - {percent}% завершено.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Помилка при зміні розміру зображення.<pre>{errors}</pre>', msgAjaxError: 'Щось не так із операцією {operation}. Будь ласка, спробуйте пізніше!', msgAjaxProgressError: 'помилка {operation}', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'видалити файл', uploadThumb: 'відвантажити файл', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Ще не відвантажено', indicatorSuccessTitle: 'Відвантажено', indicatorErrorTitle: 'Помилка при відвантаженні', - indicatorLoadingTitle: 'Завантаження ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Завантаження ...' }, previewZoomButtonTitles: { prev: 'Переглянути попередній файл', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js index c2c57168..7c43e166 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js @@ -20,10 +20,13 @@ removeTitle: 'Tanlangan fayllarni tozalash', cancelLabel: 'Bekor qilish', cancelTitle: 'Joriy yuklab olishni bekor qilish', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Yuklab olish', uploadTitle: 'Tanlangan fayllarni yuklash', msgNo: 'No', msgNoFilesSelected: 'No files selected', + msgPaused: 'Paused', msgCancelled: 'Cancelled', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Detailed Preview', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Processing...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Fayl yuklash xatosi', msgLoading: '{Files} dan {index} faylini yuklash …', msgProgress: '{Files} dan {index}{name} faylini yuklashi - {percent}% tugallandi.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Error while resizing the image.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Not uploaded yet', indicatorSuccessTitle: 'Uploaded', indicatorErrorTitle: 'Upload Error', - indicatorLoadingTitle: 'Uploading ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Uploading ...' }, previewZoomButtonTitles: { prev: 'View previous file', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js index 7d140b5e..7a51a4b9 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js @@ -20,10 +20,13 @@ removeTitle: 'Bỏ tập tin đã chọn', cancelLabel: 'Hủy', cancelTitle: 'Hủy upload', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: 'Upload', uploadTitle: 'Upload tập tin đã chọn', msgNo: 'Không', msgNoFilesSelected: 'Không tập tin nào được chọn', + msgPaused: 'Paused', msgCancelled: 'Đã hủy', msgPlaceholder: 'Select {files}...', msgZoomModalHeading: 'Chi tiết xem trước', @@ -54,8 +57,11 @@ msgUploadThreshold: 'Đang xử lý...', msgUploadBegin: 'Initializing...', msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', msgValidationError: 'Lỗi xác nhận', msgLoading: 'Đang nạp {index} tập tin trong số {files} …', msgProgress: 'Đang nạp {index} tập tin trong số {files} - {name} - {percent}% hoàn thành.', @@ -69,6 +75,10 @@ msgImageResizeException: 'Resize hình ảnh bị lỗi.<pre>{errors}</pre>', msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -87,7 +97,8 @@ indicatorNewTitle: 'Chưa được upload', indicatorSuccessTitle: 'Đã upload', indicatorErrorTitle: 'Upload bị lỗi', - indicatorLoadingTitle: 'Đang upload ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: 'Đang upload ...' }, previewZoomButtonTitles: { prev: 'Xem tập tin phía trước', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js index 49f7710f..a07eb079 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js @@ -20,10 +20,13 @@ removeTitle: '清除選取檔案', cancelLabel: '取消', cancelTitle: '取消上傳中檔案', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: '上傳', uploadTitle: '上傳選取檔案', msgNo: '沒有', msgNoFilesSelected: '未選擇檔案', + msgPaused: 'Paused', msgCancelled: '取消', zoomTitle: '詳細資料', msgPlaceholder: '選擇 {files}...', @@ -55,8 +58,11 @@ msgUploadThreshold: '處理中...', msgUploadBegin: '正在初始化...', msgUploadEnd: '完成', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: '無效的文件上傳.', - msgUploadError: '上傳錯誤', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: '上傳錯誤', msgValidationError: '驗證錯誤', msgLoading: '載入第 {index} 個檔案,共 {files} …', msgProgress: '載入第 {index} 個檔案,共 {files} - {name} - {percent}% 成功.', @@ -70,6 +76,10 @@ msgImageResizeException: '錯誤而調整圖像大小。<pre>{errors}</pre>', msgAjaxError: '{operation} 發生錯誤. 請重試!', msgAjaxProgressError: '{operation} 失敗', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: 'file delete', uploadThumb: 'file upload', @@ -88,7 +98,8 @@ indicatorNewTitle: '尚未上傳', indicatorSuccessTitle: '上傳成功', indicatorErrorTitle: '上傳失敗', - indicatorLoadingTitle: '上傳中 ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: '上傳中 ...' }, previewZoomButtonTitles: { prev: '預覽上壹個文件', diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js index 469fa380..2b000e2c 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js @@ -20,10 +20,13 @@ removeTitle: '清除选中文件', cancelLabel: '取消', cancelTitle: '取消进行中的上传', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', uploadLabel: '上传', uploadTitle: '上传选中文件', msgNo: '没有', msgNoFilesSelected: '未选择文件', + msgPaused: 'Paused', msgCancelled: '取消', msgPlaceholder: '选择 {files}...', msgZoomModalHeading: '详细预览', @@ -54,8 +57,11 @@ msgUploadThreshold: '处理中...', msgUploadBegin: '正在初始化...', msgUploadEnd: '完成', + msgUploadResume: 'Resuming upload...', msgUploadEmpty: '无效的文件上传.', - msgUploadError: '上传出错', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: '上传出错', msgValidationError: '验证错误', msgLoading: '加载第 {index} 文件 共 {files} …', msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', @@ -69,6 +75,10 @@ msgImageResizeException: '调整图像大小时发生错误。<pre>{errors}</pre>', msgAjaxError: '{operation} 发生错误. 请重试!', msgAjaxProgressError: '{operation} 失败', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond <b>{max}</b> retries for file <b>{file}</b>! Error Details: <pre>{error}</pre>', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', ajaxOperations: { deleteThumb: '删除文件', uploadThumb: '上传文件', @@ -87,7 +97,8 @@ indicatorNewTitle: '没有上传', indicatorSuccessTitle: '上传', indicatorErrorTitle: '上传错误', - indicatorLoadingTitle: '上传 ...' + indicatorPausedTitle: 'Upload Paused', + indicatorLoadingTitle: '上传 ...' }, previewZoomButtonTitles: { prev: '预览上一个文件', diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt index de7a9315..de7a9315 100644 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt index 92078153..92078153 100644 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt diff --git a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/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-upload/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js index a5c7b5da..a5c7b5da 100644 --- a/kvision-modules/kvision-upload/webpack.config.d/file.js +++ b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js diff --git a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/jquery.js @@ -0,0 +1,5 @@ +config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" +})); diff --git a/kvision-modules/kvision-bootstrap/build.gradle b/kvision-modules/kvision-bootstrap/build.gradle index 6c504c17..fe519014 100644 --- a/kvision-modules/kvision-bootstrap/build.gradle +++ b/kvision-modules/kvision-bootstrap/build.gradle @@ -3,16 +3,10 @@ apply from: "../shared.gradle" kotlinFrontend { npm { - dependency("bootstrap", "3.4.1") - dependency("bootstrap-webpack", "0.0.6") - dependency("font-awesome", "4.7.0") - dependency("font-awesome-webpack-4", "1.0.0") - dependency("awesome-bootstrap-checkbox", "0.3.7") - dependency("bootstrap-vertical-tabs", "1.2.2") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") + dependency("popper.js", "1.15.0") + dependency("bootstrap", "4.3.1") + dependency("awesome-bootstrap-checkbox", "1.0.1") + dependency("element-resize-event", "3.0.3") } } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt index 01e1f3c3..78365281 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt @@ -21,39 +21,41 @@ */ package pl.treksoft.kvision -import org.w3c.dom.asList -import kotlin.browser.document +import pl.treksoft.kvision.core.Component +import pl.treksoft.kvision.utils.isIE11 + +internal val kVManagerBootstrapInit = KVManagerBootstrap.init() /** * Internal singleton object which initializes and configures KVision Bootstrap module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerBootstrap { - private val links = document.getElementsByTagName("link") - private val bootstrapWebpack = try { - val bootswatch = links.asList().find { it.getAttribute("href")?.contains("bootstrap.min.css") ?: false } - if (bootswatch != null) { - require("bootstrap-webpack!./js/bootstrap.config.js") - if (bootswatch.getAttribute("href")?.contains("/paper/") == true) { - require("./css/paper.css") + init { + require("bootstrap/dist/js/bootstrap.bundle.min.js") + require("awesome-bootstrap-checkbox") + } + + private val elementResizeEvent = require("element-resize-event") + + @Suppress("UnsafeCastFromDynamic") + internal fun setResizeEvent(component: Component, callback: () -> Unit) { + if (!isIE11()) { + component.getElement()?.let { + elementResizeEvent(it, callback) } - require("./css/style.css") - } else { - require("bootstrap-webpack") - require("./css/style.css") } - } catch (e: Throwable) { - } - private val fontAwesomeWebpack = try { - require("font-awesome-webpack-4") - } catch (e: Throwable) { } - private val awesomeBootstrapCheckbox = try { - require("awesome-bootstrap-checkbox") - } catch (e: Throwable) { - } - private val bootstrapVerticalTabsCss = try { - require("bootstrap-vertical-tabs") - } catch (e: Throwable) { + + @Suppress("UnsafeCastFromDynamic") + internal fun clearResizeEvent(component: Component) { + if (!isIE11()) { + if (component.getElement()?.asDynamic()?.__resizeTrigger__?.contentDocument != null) { + component.getElement()?.let { + elementResizeEvent.unbind(it) + } + } + } } + + internal fun init() {} } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt new file mode 100644 index 00000000..c35ee9fb --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt @@ -0,0 +1,133 @@ +/* + * 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.core + +enum class BsBorder(internal val className: String) { + BORDER("border"), + BORDERTOP("border-top"), + BORDERBOTTOM("border-bottom"), + BORDERRIGHT("border-right"), + BORDERLEFT("border-left"), + BORDER_0("border-0"), + BORDERTOP_0("border-top-0"), + BORDERBOTTOM_0("border-bottom-0"), + BORDERRIGHT_0("border-right-0"), + BORDERLEFT_0("border-left-0"), + BORDERPRIMARY("border-primary"), + BORDERSECONDARY("border-secondary"), + BORDERSUCCESS("border-success"), + BORDERDANGER("border-danger"), + BORDERWARNING("border-warning"), + BORDERINFO("border-info"), + BORDERLIGHT("border-light"), + BORDERDARK("border-dark"), + BORDERWHITE("border-white") +} + +fun Component.addBsBorder(vararg bsBorder: BsBorder) { + bsBorder.forEach { + this.addCssClass(it.className) + } +} + +fun Component.removeBsBorder(vararg bsBorder: BsBorder) { + bsBorder.forEach { + this.removeCssClass(it.className) + } +} + +enum class BsRounded(internal val className: String) { + ROUNDED("rounded"), + ROUNDEDTOP("rounded-top"), + ROUNDEDBOTTOM("rounded-bottom"), + ROUNDEDLEFT("rounded-left"), + ROUNDEDRIGHT("rounded-right"), + ROUNDEDCIRCLE("rounded-circle"), + ROUNDEDPILL("rounded-pill"), + ROUNDEDLG("rounded-lg"), + ROUNDEDSM("rounded-sm") +} + +fun Component.addBsRounded(vararg bsRounded: BsRounded) { + bsRounded.forEach { + this.addCssClass(it.className) + } +} + +fun Component.removeBsRounded(vararg bsRounded: BsRounded) { + bsRounded.forEach { + this.removeCssClass(it.className) + } +} + +fun Component.addBsClearfix() { + this.addCssClass("clearfix") +} + +fun Component.removeBsClearfix() { + this.removeCssClass("clearfix") +} + +enum class BsColor(internal val className: String) { + PRIMARY("text-primary"), + SECONDARY("text-secondary"), + SUCCESS("text-success"), + DANGER("text-danger"), + WARNING("text-warning"), + INFO("text-info"), + LIGHT("text-light"), + DARK("text-dark"), + WHITE("text-white"), + BODY("text-body"), + MUTED("text-muted"), + BLACK50("text-black-50"), + WHITE50("text-white-50") +} + +fun Component.addBsColor(bsColor: BsColor) { + this.addCssClass(bsColor.className) +} + +fun Component.removeBsColor(bsColor: BsColor) { + this.removeCssClass(bsColor.className) +} + +enum class BsBgColor(internal val className: String) { + PRIMARY("bg-primary"), + SECONDARY("bg-secondary"), + SUCCESS("bg-success"), + DANGER("bg-danger"), + WARNING("bg-warning"), + INFO("bg-info"), + LIGHT("bg-light"), + DARK("bg-dark"), + WHITE("bg-white"), + TRANSPARENT("bg-transparent") +} + +fun Component.addBsBgColor(bsBgColor: BsBgColor) { + this.addCssClass(bsBgColor.className) +} + +fun Component.removeBsBgColor(bsBgColor: BsBgColor) { + this.removeCssClass(bsBgColor.className) +} diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt index 5fac0494..4e20de81 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt @@ -24,8 +24,7 @@ package pl.treksoft.kvision.dropdown import org.w3c.dom.events.MouseEvent import pl.treksoft.kvision.core.Display import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.ListType +import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.utils.px @@ -41,7 +40,7 @@ open class ContextMenu( element: Widget? = null, protected val fixedPosition: Boolean = false, classes: Set<String> = setOf(), init: (ContextMenu.() -> Unit)? = null -) : ListTag(ListType.UL, classes = classes + "dropdown-menu") { +) : Div(classes = classes + "dropdown-menu") { init { @Suppress("LeakingThis") @@ -82,6 +81,21 @@ open class ContextMenu( const val DEFAULT_FIXED_POS_Y = 5 /** + * Sets context menu for the current widget. + * @param contextMenu a context menu + * @return current widget + */ + fun Widget.setContextMenu(contextMenu: ContextMenu): Widget { + this.setEventListener<Widget> { + contextmenu = { e: MouseEvent -> + e.preventDefault() + contextMenu.positionMenu(e) + } + } + return this + } + + /** * DSL builder extension function. * * It takes the same parameters as the constructor of the built component. diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt index a521fe95..9862b322 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -22,20 +22,17 @@ package pl.treksoft.kvision.dropdown import com.github.snabbdom.VNode -import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.CssSize +import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.html.Button import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.html.ButtonType +import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.html.Link -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.ListType -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.obj @@ -49,6 +46,16 @@ enum class DD(val option: String) { } /** + * Dropdown directions. + */ +enum class Direction(internal val direction: String) { + DROPDOWN("dropdown"), + DROPUP("dropup"), + DROPLEFT("dropleft"), + DROPRIGHT("dropright") +} + +/** * Bootstrap dropdown component. * * @constructor @@ -56,16 +63,17 @@ enum class DD(val option: String) { * @param elements an optional list of link elements (special options from [DD] enum class can be used as values) * @param icon the icon of the dropdown button * @param style the style of the dropdown button + * @param direction the direction of the dropdown * @param disabled determines if the component is disabled on start * @param forNavbar determines if the component will be used in a navbar - * @param withCaret determines if the dropdown button renders caret + * @param forDropDown determines if the component will be used in a dropdown * @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, - withCaret: Boolean = true, classes: Set<String> = setOf() + style: ButtonStyle = ButtonStyle.PRIMARY, direction: Direction = Direction.DROPDOWN, disabled: Boolean = false, + val forNavbar: Boolean = false, val forDropDown: Boolean = false, classes: Set<String> = setOf() ) : SimplePanel(classes) { /** * Label of the dropdown button. @@ -125,9 +133,9 @@ open class DropDown( button.image = value } /** - * Determines if the dropdown is showing upwards. + * The direction of the dropdown. */ - var dropup by refreshOnUpdate(false) + var direction by refreshOnUpdate(direction) /** * Width of the dropdown button. */ @@ -140,15 +148,18 @@ open class DropDown( private val idc = "kv_dropdown_$counter" internal val button: DropDownButton = DropDownButton( - idc, text, icon, style, - disabled, forNavbar, withCaret, setOf("dropdown") + idc, text, icon, style, disabled, forNavbar, forDropDown ) fun buttonId() = button.id - internal val list: DropDownListTag = DropDownListTag(idc, setOf("dropdown-menu")) + internal val list: DropDownDiv = DropDownDiv(idc) init { + if (forDropDown) { + this.style = ButtonStyle.LIGHT + this.direction = Direction.DROPRIGHT + } setChildrenFromElements() this.addInternal(button) this.addInternal(list) @@ -195,11 +206,12 @@ open class DropDown( DD.HEADER.option -> Header(it.first) DD.SEPARATOR.option -> Separator() DD.DISABLED.option -> { - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(Link(it.first)) - tag + Link(it.first, "javascript:void(0)", classes = setOf("dropdown-item", "disabled")).apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + } } - else -> Link(it.first, it.second) + else -> Link(it.first, it.second, classes = setOf("dropdown-item")) } } list.addAll(c) @@ -224,10 +236,8 @@ open class DropDown( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - if (dropup) - cl.add("dropup" to true) - else - cl.add("dropdown" to true) + if (forNavbar) cl.add("nav-item" to true) + cl.add(direction.direction to true) return cl } @@ -235,7 +245,7 @@ open class DropDown( * Toggles dropdown visibility. */ open fun toggle() { - this.list.getElementJQueryD()?.dropdown("toggle") + this.button.getElementJQuery()?.click() } companion object { @@ -248,8 +258,9 @@ open class DropDown( */ fun Container.dropDown( text: String, elements: List<StringPair>? = null, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, disabled: Boolean = false, forNavbar: Boolean = false, - withCaret: Boolean = true, classes: Set<String> = setOf(), init: (DropDown.() -> Unit)? = null + style: ButtonStyle = ButtonStyle.PRIMARY, direction: Direction = Direction.DROPDOWN, + disabled: Boolean = false, forNavbar: Boolean = false, forDropDown: Boolean = false, + classes: Set<String> = setOf(), init: (DropDown.() -> Unit)? = null ): DropDown { val dropDown = DropDown( @@ -257,14 +268,84 @@ open class DropDown( elements, icon, style, + direction, disabled, forNavbar, - withCaret, + forDropDown, classes ).apply { init?.invoke(this) } this.add(dropDown) return dropDown } + + /** + * DSL builder extension function for a link in a dropdown list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun DropDown.ddLink( + label: String, url: String? = null, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, url, icon, image, classes + "dropdown-item").apply { + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a link in a context menu list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun ContextMenu.cmLink( + label: String, url: String? = null, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, url, icon, image, classes + "dropdown-item").apply { + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a disabled link in a dropdown list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun DropDown.ddLinkDisabled( + label: String, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, "javascript:void(0)", icon, image, classes + "dropdown-item" + "disabled").apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a disabled link in a context menu list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun ContextMenu.cmLinkDisabled( + label: String, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, "javascript:void(0)", icon, image, classes + "dropdown-item" + "disabled").apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + init?.invoke(this) + } + this.add(link) + return link + } + } } @@ -272,35 +353,33 @@ internal class DropDownButton( id: String, text: String, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, + style: ButtonStyle = ButtonStyle.PRIMARY, disabled: Boolean = false, val forNavbar: Boolean = false, - val withCaret: Boolean = true, + val forDropDown: Boolean = false, classes: Set<String> = setOf() ) : Button(text, icon, style, ButtonType.BUTTON, disabled, classes) { init { this.id = id - this.role = "button" + if (!forNavbar && !forDropDown) this.role = "button" setInternalEventListener<DropDownButton> { click = { e -> - if (parent?.parent is ContextMenu) e.asDynamic().dropDownCM = true + if (parent?.parent is ContextMenu) { + e.asDynamic().dropDownCM = true + } else if (forDropDown || forNavbar) { + (parent as DropDown).list.getElementJQuery()?.toggle() + e.stopPropagation() + } } } } override fun render(): VNode { val text = createLabelWithIcon(text, icon, image) - return if (forNavbar) { - if (withCaret) { - val textWithCarret = text.toMutableList() - textWithCarret.add(" ") - textWithCarret.add(KVManager.virtualize("<span class='caret'></span>")) - render("a", textWithCarret.toTypedArray()) - } else { - render("a", text) - } + return if (forNavbar || forDropDown) { + render("a", text) } else { render("button", text) } @@ -308,25 +387,30 @@ internal class DropDownButton( override fun getSnClass(): List<StringBoolPair> { return if (forNavbar) { - listOf("dropdown" to true) + listOf("nav-link" to true, "dropdown-toggle" to true) + } else if (forDropDown) { + super.getSnClass() + listOf("dropdown-item" to true, "dropdown-toggle" to true) } else { - super.getSnClass() + super.getSnClass() + ("dropdown-toggle" to true) } } override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + listOf( + val inherited = super.getSnAttrs() + return if (forDropDown || forNavbar) { + inherited.filter { it.first != "type" } + } else { + inherited + } + listOf( "data-toggle" to "dropdown", "aria-haspopup" to "true", "aria-expanded" to "false", "href" to "#" ) } } -internal class DropDownListTag(private val ariaId: String, classes: Set<String> = setOf()) : ListTag( - ListType.UL, null, - false, classes +internal class DropDownDiv(private val ariaId: String) : Div( + null, false, null, setOf("dropdown-menu") ) { - override fun getSnAttrs(): List<StringPair> { return super.getSnAttrs() + listOf("aria-labelledby" to ariaId) } diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt index 4cee7b7b..13e0b2e4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.dropdown -import pl.treksoft.kvision.html.ListTag import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag @@ -33,7 +32,7 @@ import pl.treksoft.kvision.html.Tag * @param classes a set of CSS class names */ open class Header(content: String? = null, classes: Set<String> = setOf()) : - Tag(TAG.LI, content, classes = classes + "dropdown-header") { + Tag(TAG.H6, content, classes = classes + "dropdown-header") { companion object { @@ -42,7 +41,7 @@ open class Header(content: String? = null, classes: Set<String> = setOf()) : * * It takes the same parameters as the constructor of the built component. */ - fun ListTag.header(content: String? = null, classes: Set<String> = setOf()): Header { + fun ContextMenu.header(content: String? = null, classes: Set<String> = setOf()): Header { val header = Header(content, classes) this.add(header) return header diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt index c682b0e9..dd2344bd 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt @@ -21,9 +21,7 @@ */ package pl.treksoft.kvision.dropdown -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.html.Div /** * Menu separator component. @@ -31,11 +29,7 @@ import pl.treksoft.kvision.html.Tag * @constructor * @param classes a set of CSS class names */ -open class Separator(classes: Set<String> = setOf()) : Tag(TAG.LI, classes = classes + "divider") { - - init { - role = "separator" - } +open class Separator(classes: Set<String> = setOf()) : Div(classes = classes + "dropdown-divider") { companion object { /** @@ -43,7 +37,7 @@ open class Separator(classes: Set<String> = setOf()) : Tag(TAG.LI, classes = cla * * It takes the same parameters as the constructor of the built component. */ - fun ListTag.separator(classes: Set<String> = setOf()): Separator { + fun ContextMenu.separator(classes: Set<String> = setOf()): Separator { val separator = Separator(classes) this.add(separator) return separator diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt index 5f5a1a80..4c5b222e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt @@ -76,7 +76,7 @@ open class Alert( init { body.add(contentTag) - val okButton = Button("OK", "ok", ButtonStyle.PRIMARY) + val okButton = Button("OK", "fas fa-check", ButtonStyle.PRIMARY) okButton.setEventListener { click = { hide() diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt index 5f0440a6..5f0440a6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt index e16ca87e..058ca7bc 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt @@ -108,9 +108,9 @@ open class Confirm( } private val contentTag = Tag(TAG.DIV, text, rich, align) - private val cancelButton = Button(cancelTitle, "remove") - private val noButton = Button(noTitle, "ban-circle") - private val yesButton = Button(yesTitle, "ok", ButtonStyle.PRIMARY) + private val cancelButton = Button(cancelTitle, "fas fa-times") + private val noButton = Button(noTitle, "fas fa-ban") + private val yesButton = Button(yesTitle, "fas fa-check", ButtonStyle.PRIMARY) init { body.add(contentTag) diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt index 7f120f73..08fc7aa8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt @@ -31,6 +31,8 @@ import pl.treksoft.kvision.html.Button import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.panel.Root.Companion.addModal +import pl.treksoft.kvision.panel.Root.Companion.removeModal import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.obj @@ -38,6 +40,7 @@ import pl.treksoft.kvision.utils.obj * Modal window sizes. */ enum class ModalSize(val className: String) { + XLARGE("modal-xl"), LARGE("modal-lg"), SMALL("modal-sm") } @@ -101,7 +104,7 @@ open class Modal( * Internal property. */ protected val closeIcon = CloseIcon() - private val captionTag = Tag(TAG.H4, caption, classes = setOf("modal-title")) + private val captionTag = Tag(TAG.H5, caption, classes = setOf("modal-title")) /** * @suppress * Internal property. @@ -112,6 +115,7 @@ open class Modal( init { this.hide() this.role = "dialog" + this.tabindex = -1 this.addInternal(dialog) val content = SimplePanel(setOf("modal-content")) dialog.role = "document" @@ -122,14 +126,14 @@ open class Modal( hide() } } - header.add(closeIcon) header.add(captionTag) + header.add(closeIcon) checkHeaderVisibility() content.add(header) content.add(body) content.add(footer) @Suppress("LeakingThis") - modals.add(this) + addModal(this) @Suppress("LeakingThis") init?.invoke(this) } @@ -195,12 +199,6 @@ open class Modal( return this } - override fun getSnAttrs(): List<StringPair> { - val pr = super.getSnAttrs().toMutableList() - pr.add("tabindex" to "-1") - return pr - } - override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() cl.add("modal" to true) @@ -267,11 +265,7 @@ open class Modal( } override fun dispose() { - modals.remove(this) - } - - companion object { - internal var modals = mutableListOf<Modal>() + removeModal(this) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt index 3bbb6eed..e0da480d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt @@ -21,9 +21,10 @@ */ package pl.treksoft.kvision.navbar +import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.html.Link /** * The Bootstrap Nav container. @@ -34,7 +35,7 @@ import pl.treksoft.kvision.html.Tag * @param init an initializer extension function */ open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (Nav.() -> Unit)? = null) : - Tag(TAG.UL, classes = classes) { + Div(classes = classes) { /** * Determines if the nav is aligned to the right. @@ -48,10 +49,9 @@ open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - cl.add("nav" to true) cl.add("navbar-nav" to true) if (rightAlign) { - cl.add("navbar-right" to true) + cl.add("ml-auto" to true) } return cl } @@ -69,5 +69,42 @@ open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init this.add(nav) return nav } + + + /** + * DSL builder extension function for a link in a nav list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Nav.navLink( + label: String, url: String? = null, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, url, icon, image, classes + "nav-item" + "nav-link").apply { + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a disabled link in a nav list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Nav.navLinkDisabled( + label: String, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = + Link(label, "javascript:void(0)", icon, image, classes + "nav-item" + "nav-link" + "disabled").apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + init?.invoke(this) + } + this.add(link) + return link + } + } } diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt index 725c298e..45454cc8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt @@ -48,11 +48,9 @@ open class NavForm(rightAlign: Boolean = false, classes: Set<String> = setOf(), override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - cl.add("navbar-form" to true) + cl.add("form-inline" to true) if (rightAlign) { - cl.add("navbar-right" to true) - } else { - cl.add("navbar-left" to true) + cl.add("ml-auto" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt index 2080bb8e..34a9dbe2 100644 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt @@ -22,22 +22,42 @@ package pl.treksoft.kvision.navbar import com.github.snabbdom.VNode +import pl.treksoft.kvision.core.BsBgColor import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.html.Link -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag.Companion.tag +import pl.treksoft.kvision.html.Span +import pl.treksoft.kvision.html.Span.Companion.span import pl.treksoft.kvision.panel.SimplePanel /** * Navbar types. */ enum class NavbarType(internal val navbarType: String) { - FIXEDTOP("navbar-fixed-top"), - FIXEDBOTTOM("navbar-fixed-bottom"), - STATICTOP("navbar-static-top") + FIXEDTOP("fixed-top"), + FIXEDBOTTOM("fixed-bottom"), + STICKYTOP("sticky-top") +} + +/** + * Navbar colors. + */ +enum class NavbarColor(internal val navbarColor: String) { + LIGHT("navbar-light"), + DARK("navbar-dark") +} + +/** + * Navbar responsive behavior. + */ +enum class NavbarExpand(internal val navbarExpand: String) { + ALWAYS("navbar-expand"), + XL("navbar-expand-xl"), + LG("navbar-expand-lg"), + MD("navbar-expand-md"), + SM("navbar-expand-sm"), } /** @@ -46,14 +66,18 @@ enum class NavbarType(internal val navbarType: String) { * @constructor * @param label the navbar label * @param type the navbar type - * @param inverted determines if the navbar is inverted + * @param expand the navbar responsive behavior + * @param nColor the navbar color + * @param bgColor the navbar background color * @param classes a set of CSS class names * @param init an initializer extension function */ open class Navbar( label: String? = null, type: NavbarType? = null, - inverted: Boolean = false, + expand: NavbarExpand? = NavbarExpand.LG, + nColor: NavbarColor = NavbarColor.LIGHT, + bgColor: BsBgColor = BsBgColor.LIGHT, classes: Set<String> = setOf(), init: (Navbar.() -> Unit)? = null ) : SimplePanel(classes) { @@ -76,9 +100,17 @@ open class Navbar( */ var type by refreshOnUpdate(type) /** - * Determines if the navbar is inverted. + * The navbar responsive behavior. */ - var inverted by refreshOnUpdate(inverted) + var expand by refreshOnUpdate(expand) + /** + * The navbar color. + */ + var nColor by refreshOnUpdate(nColor) + /** + * The navbar background color. + */ + var bgColor by refreshOnUpdate(bgColor) private val idc = "kv_navbar_$counter" @@ -88,14 +120,9 @@ open class Navbar( } init { - val c = SimplePanel(setOf("container-fluid")) { - simplePanel(setOf("navbar-header")) { - add(NavbarButton(idc)) - add(brandLink) - } - add(container) - } - addInternal(c) + addInternal(brandLink) + addInternal(NavbarButton(idc)) + addInternal(container) if (label == null) brandLink.hide() counter++ @Suppress("LeakingThis") @@ -136,11 +163,11 @@ open class Navbar( type?.let { cl.add(it.navbarType to true) } - if (inverted) { - cl.add("navbar-inverse" to true) - } else { - cl.add("navbar-default" to true) + expand?.let { + cl.add(it.navbarExpand to true) } + cl.add(nColor.navbarColor to true) + cl.add(bgColor.className to true) return cl } @@ -155,13 +182,21 @@ open class Navbar( fun Container.navbar( label: String? = null, type: NavbarType? = null, - inverted: Boolean = false, + expand: NavbarExpand? = NavbarExpand.LG, + nColor: NavbarColor = NavbarColor.LIGHT, + bgColor: BsBgColor = BsBgColor.LIGHT, classes: Set<String> = setOf(), init: (Navbar.() -> Unit)? = null ): Navbar { - val navbar = Navbar(label, type, inverted, classes, init) + val navbar = Navbar(label, type, expand, nColor, bgColor, classes, init) this.add(navbar) return navbar } + + fun Navbar.navText(label: String, classes: Set<String> = setOf()): Span { + val text = Span(label, classes = classes + "navbar-text") + this.add(text) + return text + } } } @@ -170,14 +205,11 @@ open class Navbar( * Internal component. * The Bootstrap Navbar header button. */ -internal class NavbarButton(private val idc: String, toggle: String = "Toggle navigation") : - SimplePanel(setOf("navbar-toggle", "collapsed")) { +internal class NavbarButton(private val idc: String, private val toggle: String = "Toggle navigation") : + SimplePanel(setOf("navbar-toggler")) { init { - tag(TAG.SPAN, toggle, classes = setOf("sr-only")) - tag(TAG.SPAN, classes = setOf("icon-bar")) - tag(TAG.SPAN, classes = setOf("icon-bar")) - tag(TAG.SPAN, classes = setOf("icon-bar")) + span(classes = setOf("navbar-toggler-icon")) } override fun render(): VNode { @@ -189,7 +221,9 @@ internal class NavbarButton(private val idc: String, toggle: String = "Toggle na "type" to "button", "data-toggle" to "collapse", "data-target" to "#$idc", - "aria-expanded" to "false" + "aria-controls" to idc, + "aria-expanded" to "false", + "aria-label" to toggle ) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt index 7a5b07d6..2ff6fa19 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt @@ -32,10 +32,10 @@ import pl.treksoft.kvision.html.Tag * Bootstrap grid sizes. */ enum class GridSize(internal val size: String) { - XS("xs"), SM("sm"), MD("md"), - LG("lg") + LG("lg"), + XL("xs") } internal const val MAX_COLUMNS = 12 @@ -82,10 +82,10 @@ open class ResponsiveGridPanel( * @return this container */ open fun add(child: Component, col: Int, row: Int, size: Int = 0, offset: Int = 0): ResponsiveGridPanel { - val cRow = maxOf(row, 0) - val cCol = maxOf(col, 0) - if (row > rows - 1) rows = cRow + 1 - if (col > cols - 1) cols = cCol + 1 + val cRow = maxOf(row, 1) + val cCol = maxOf(col, 1) + if (cRow > rows) rows = cRow + if (cCol > cols) cols = cCol map.getOrPut(cRow) { mutableMapOf() }[cCol] = WidgetParam(child, size, offset) if (size > 0 || offset > 0) auto = false refreshRowContainers() @@ -128,11 +128,11 @@ open class ResponsiveGridPanel( singleRender { clearRowContainers() val num = MAX_COLUMNS / cols - for (i in 0 until rows) { + for (i in 1..rows) { val rowContainer = SimplePanel(setOf("row")) val row = map[i] if (row != null) { - (0 until cols).map { row[it] }.forEach { wp -> + (1..cols).map { row[it] }.forEach { wp -> if (auto) { val widget = wp?.widget?.let { WidgetWrapper(it, setOf("col-" + gridSize.size + "-" + num)) @@ -146,7 +146,7 @@ open class ResponsiveGridPanel( val s = if (wp.size > 0) wp.size else num val widget = WidgetWrapper(wp.widget, setOf("col-" + gridSize.size + "-" + s)) if (wp.offset > 0) { - widget.addCssClass("col-" + gridSize.size + "-offset-" + wp.offset) + widget.addCssClass("offset-" + gridSize.size + "-" + wp.offset) } align?.let { widget.addCssClass(it.className) diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt index f620f2b0..2009e4fc 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt @@ -82,18 +82,18 @@ open class TabPanel( set(value) { if (content.activeIndex != value) { content.activeIndex = value - nav.children.forEach { - it.removeCssClass("active") - } - if (content.activeIndex in nav.children.indices) { - nav.children[content.activeIndex].addCssClass("active") - } + } + nav.getChildren().forEach { + (it as Tag).getChildren().firstOrNull()?.removeCssClass("active") + } + if (content.activeIndex in nav.getChildren().indices) { + (nav.getChildren()[content.activeIndex] as Tag).getChildren().firstOrNull()?.addCssClass("active") } } private val navClasses = when (tabPosition) { TabPosition.TOP -> if (scrollableTabs) setOf("nav", "nav-tabs", "tabs-top") else setOf("nav", "nav-tabs") - TabPosition.LEFT -> setOf("nav", "nav-tabs", "tabs-left") - TabPosition.RIGHT -> setOf("nav", "nav-tabs", "tabs-right") + TabPosition.LEFT -> setOf("nav", "nav-tabs", "tabs-left", "flex-column") + TabPosition.RIGHT -> setOf("nav", "nav-tabs", "tabs-right", "flex-column") } private var nav = Tag(TAG.UL, classes = navClasses) private var content = StackPanel(false) @@ -107,16 +107,18 @@ open class TabPanel( this.addInternal(content) } TabPosition.LEFT -> { - this.addCssClass("clearfix") + this.addSurroundingCssClass("container-fluid") + this.addCssClass("row") val sizes = calculateSideClasses() - this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding"))) - this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding"))) + this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0"))) + this.addInternal(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0"))) } TabPosition.RIGHT -> { - this.addCssClass("clearfix") + this.addSurroundingCssClass("container-fluid") + this.addCssClass("row") val sizes = calculateSideClasses() - this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding"))) - this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding"))) + this.addInternal(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0"))) + this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0"))) } } @Suppress("LeakingThis") @@ -125,12 +127,12 @@ open class TabPanel( private fun calculateSideClasses(): Pair<String, String> { return when (sideTabSize) { - SideTabSize.SIZE_1 -> Pair("col-xs-1", "col-xs-11") - SideTabSize.SIZE_2 -> Pair("col-xs-2", "col-xs-10") - SideTabSize.SIZE_3 -> Pair("col-xs-3", "col-xs-9") - SideTabSize.SIZE_4 -> Pair("col-xs-4", "col-xs-8") - SideTabSize.SIZE_5 -> Pair("col-xs-5", "col-xs-7") - SideTabSize.SIZE_6 -> Pair("col-xs-6", "col-xs-6") + SideTabSize.SIZE_1 -> Pair("col-sm-1", "col-sm-11") + SideTabSize.SIZE_2 -> Pair("col-sm-2", "col-sm-10") + SideTabSize.SIZE_3 -> Pair("col-sm-3", "col-sm-9") + SideTabSize.SIZE_4 -> Pair("col-sm-4", "col-sm-8") + SideTabSize.SIZE_5 -> Pair("col-sm-5", "col-sm-7") + SideTabSize.SIZE_6 -> Pair("col-sm-6", "col-sm-6") } } @@ -150,15 +152,14 @@ open class TabPanel( ): TabPanel { val currentIndex = counter++ childrenMap[currentIndex] = panel - val tag = Tag(TAG.LI) { - role = "presentation" - link(title, "#", icon, image) { + val tag = Tag(TAG.LI, classes = setOf("nav-item")) { + link(title, "#", icon, image, classes = setOf("nav-link")) { if (closable) { - cicon("remove") { + cicon("fas fa-times") { addCssClass("kv-tab-close") setEventListener<Icon> { click = { e -> - val actIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) + val actIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) e.asDynamic().data = actIndex @Suppress("UnsafeCastFromDynamic") if (this@TabPanel.dispatchEvent( @@ -176,7 +177,7 @@ open class TabPanel( } setEventListener { click = { e -> - activeIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) + activeIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) e.preventDefault() if (route != null) { routing.navigate(route) @@ -185,13 +186,15 @@ open class TabPanel( } } nav.add(tag) - if (nav.children.size == 1) { - tag.addCssClass("active") + if (nav.getChildren().size == 1) { + tag.getChildren().firstOrNull()?.addCssClass("active") activeIndex = 0 } content.add(panel) if (route != null) { - routing.on(route, { _ -> activeIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) }) + routing.on( + route, + { _ -> activeIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) }) .resolve() } return this @@ -201,11 +204,11 @@ open class TabPanel( * Removes tab at given index. */ open fun removeTab(index: Int): TabPanel { - nav.remove(nav.children[index]) - childrenMap.filter { it.value == content.children[index] }.keys.firstOrNull()?.let { + nav.remove(nav.getChildren()[index]) + childrenMap.filter { it.value == content.getChildren()[index] }.keys.firstOrNull()?.let { childrenMap.remove(it) } - content.remove(content.children[index]) + content.remove(content.getChildren()[index]) activeIndex = content.activeIndex return this } @@ -220,7 +223,7 @@ open class TabPanel( } override fun remove(child: Component): TabPanel { - val index = content.children.indexOf(child) + val index = content.getChildren().indexOf(child) return removeTab(index) } @@ -229,7 +232,7 @@ open class TabPanel( * @param index tab index */ open fun getChildComponent(index: Int): Component? { - return content.children[index] + return content.getChildren()[index] } /** @@ -237,7 +240,7 @@ open class TabPanel( * @param index tab index */ open fun getNavComponent(index: Int): Tag? { - return nav.children[index] as? Tag + return nav.getChildren()[index] as? Tag } override fun removeAll(): TabPanel { diff --git a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt index 4d0f4b93..4d0f4b93 100644 --- a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt index 256d15d7..256d15d7 100644 --- a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt index ae57fc90..2aef9e63 100644 --- a/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt @@ -24,22 +24,14 @@ package pl.treksoft.kvision.toolbar import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.px /** * Button group sizes. */ enum class ButtonGroupSize(internal val className: String) { LARGE("btn-group-lg"), - SMALL("btn-group-sm"), - XSMALL("btn-group-xs") -} - -/** - * Button group styles. - */ -enum class ButtonGroupStyle(internal val className: String) { - VERTICAL("btn-group-vertical"), - JUSTIFIED("btn-group-justified") + SMALL("btn-group-sm") } /** @@ -47,12 +39,12 @@ enum class ButtonGroupStyle(internal val className: String) { * * @constructor * @param size button group size - * @param style button group style + * @param vertical determines if button group is aligned vertically * @param classes a set of CSS class names * @param init an initializer extension function */ open class ButtonGroup( - size: ButtonGroupSize? = null, style: ButtonGroupStyle? = null, + size: ButtonGroupSize? = null, vertical: Boolean = false, classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null ) : SimplePanel(classes) { @@ -61,9 +53,9 @@ open class ButtonGroup( */ var size by refreshOnUpdate(size) /** - * Button group style. + * Vertical alignment. */ - var style by refreshOnUpdate(style) + var vertical by refreshOnUpdate(vertical) init { role = "group" @@ -73,12 +65,11 @@ open class ButtonGroup( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - if (style != ButtonGroupStyle.VERTICAL) { + if (vertical) { + cl.add("btn-group-vertical" to true) + } else { cl.add("btn-group" to true) } - style?.let { - cl.add(it.className to true) - } size?.let { cl.add(it.className to true) } @@ -92,10 +83,25 @@ open class ButtonGroup( * It takes the same parameters as the constructor of the built component. */ fun Container.buttonGroup( - size: ButtonGroupSize? = null, style: ButtonGroupStyle? = null, + size: ButtonGroupSize? = null, vertical: Boolean = false, + classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null + ): ButtonGroup { + val group = ButtonGroup(size, vertical, classes).apply { init?.invoke(this) } + this.add(group) + return group + } + /** + * DSL builder extension function for toolbar. + * + * It creates button groups with size and vertical parameters of the toolbar. + */ + fun Toolbar.buttonGroup( classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null ): ButtonGroup { - val group = ButtonGroup(size, style, classes).apply { init?.invoke(this) } + val group = ButtonGroup(this.size, this.vertical, classes).apply { + marginRight = this@buttonGroup.spacing.px + init?.invoke(this) + } this.add(group) return group } diff --git a/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt index f348f4cc..13ed8972 100644 --- a/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt @@ -28,10 +28,14 @@ import pl.treksoft.kvision.panel.SimplePanel * The Bootstrap toolbar. * * @constructor + * @param size button groups size + * @param spacing the spacing between button groups + * @param vertical determines if button groups are aligned vertically * @param classes a set of CSS class names * @param init an initializer extension function */ open class Toolbar( + val size: ButtonGroupSize? = null, val spacing: Int = 5, val vertical: Boolean = false, classes: Set<String> = setOf(), init: (Toolbar.() -> Unit)? = null ) : SimplePanel(classes + "btn-toolbar") { @@ -48,9 +52,10 @@ open class Toolbar( * It takes the same parameters as the constructor of the built component. */ fun Container.toolbar( + size: ButtonGroupSize? = null, spacing: Int = 2, vertical: Boolean = false, classes: Set<String> = setOf(), init: (Toolbar.() -> Unit)? = null ): Toolbar { - val toolbar = Toolbar(classes).apply { init?.invoke(this) } + val toolbar = Toolbar(size, spacing, vertical, classes).apply { init?.invoke(this) } this.add(toolbar) return toolbar } diff --git a/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt index a3ceaf61..a3ceaf61 100644 --- a/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt index c8034d09..c8034d09 100644 --- a/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt index 3816de3a..83473858 100644 --- a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt @@ -25,6 +25,7 @@ import com.github.snabbdom.VNode import org.w3c.dom.events.Event import org.w3c.dom.events.MouseEvent import pl.treksoft.kvision.KVManager +import pl.treksoft.kvision.KVManagerBootstrap import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.CssSize @@ -166,7 +167,8 @@ open class Window( private val closeIcon = CloseIcon() private val maximizeIcon = MaximizeIcon() private val minimizeIcon = MinimizeIcon() - private val captionTag = Tag(TAG.H4, caption, classes = setOf("modal-title")) + private val captionTag = Tag(TAG.H5, caption, classes = setOf("modal-title")) + private val iconsContainer = SimplePanel(setOf("kv-window-icons-container")) private val windowIcon = Icon(icon ?: "").apply { addCssClass("window-icon") visible = (icon != null && icon != "") @@ -184,19 +186,22 @@ open class Window( width = contentWidth @Suppress("LeakingThis") zIndex = ++zIndexCounter - closeIcon.visible = closeButton - closeIcon.setEventListener { + header.add(captionTag) + captionTag.add(windowIcon) + header.add(iconsContainer) + minimizeIcon.visible = minimizeButton + minimizeIcon.setEventListener { click = { _ -> @Suppress("UnsafeCastFromDynamic") - if (this@Window.dispatchEvent("closeWindow", obj {}) != false) { - close() + if (this@Window.dispatchEvent("minimizeWindow", obj {}) != false) { + toggleMinimize() } } mousedown = { e -> e.stopPropagation() } } - header.add(closeIcon) + iconsContainer.add(minimizeIcon) maximizeIcon.visible = maximizeButton maximizeIcon.setEventListener { click = { _ -> @@ -209,22 +214,20 @@ open class Window( e.stopPropagation() } } - header.add(maximizeIcon) - minimizeIcon.visible = minimizeButton - minimizeIcon.setEventListener { + iconsContainer.add(maximizeIcon) + closeIcon.visible = closeButton + closeIcon.setEventListener { click = { _ -> @Suppress("UnsafeCastFromDynamic") - if (this@Window.dispatchEvent("minimizeWindow", obj {}) != false) { - toggleMinimize() + if (this@Window.dispatchEvent("closeWindow", obj {}) != false) { + close() } } mousedown = { e -> e.stopPropagation() } } - header.add(minimizeIcon) - header.add(captionTag) - captionTag.add(windowIcon) + iconsContainer.add(closeIcon) checkHeaderVisibility() addInternal(header) addInternal(content) @@ -309,7 +312,7 @@ open class Window( if (isResizable) { if (!isResizeEvent) { isResizeEvent = true - KVManager.setResizeEvent(this) { + KVManagerBootstrap.setResizeEvent(this) { val eid = getElementJQuery()?.attr("id") if (isResizable && eid == id) { val outerWidth = (getElementJQuery()?.outerWidth()?.toInt() ?: 0) @@ -330,7 +333,7 @@ open class Window( } } } else if (isResizeEvent) { - KVManager.clearResizeEvent(this) + KVManagerBootstrap.clearResizeEvent(this) isResizeEvent = false } } @@ -365,7 +368,7 @@ open class Window( override fun afterDestroy() { if (isResizeEvent) { - KVManager.clearResizeEvent(this) + KVManagerBootstrap.clearResizeEvent(this) isResizeEvent = false } } diff --git a/kvision-modules/kvision-bootstrap/src/main/resources/css/paper.css b/kvision-modules/kvision-bootstrap/src/main/resources/css/paper.css deleted file mode 100644 index 1c783608..00000000 --- a/kvision-modules/kvision-bootstrap/src/main/resources/css/paper.css +++ /dev/null @@ -1,16 +0,0 @@ -body { - font-size: 14px; - line-height: 1.42857143; -} - -.kv-radio-checkbox { - padding-left: 20px !important; -} - -.radio label, .checkbox label { - white-space: nowrap; -} - -.modal-title { - font-size: 18px; -} diff --git a/kvision-modules/kvision-bootstrap/src/main/resources/css/style.css b/kvision-modules/kvision-bootstrap/src/main/resources/css/style.css deleted file mode 100644 index 475a0b85..00000000 --- a/kvision-modules/kvision-bootstrap/src/main/resources/css/style.css +++ /dev/null @@ -1,226 +0,0 @@ -.splitpanel-vertical { - display: flex; - flex-direction: row; - overflow: auto; -} - -.splitpanel-vertical > *:first-child { - max-width: calc(100% - 9px); -} - -.splitpanel-vertical > * { - flex: 0 0 auto; - overflow: auto; -} - -.splitpanel-vertical > *:last-child { - flex: 1 1 auto; - overflow: auto; -} - -.splitpanel-horizontal { - display: flex; - flex-direction: column; - overflow: auto; -} - -.splitpanel-horizontal > *:first-child { - max-height: calc(100% - 9px); -} - -.splitpanel-horizontal > * { - flex: 0 0 auto; - overflow: auto; -} - -.splitpanel-horizontal > *:last-child { - flex: 1 1 auto; - overflow: auto; -} - - -.splitter-vertical { - flex: 0 0 auto; - width: 9px; - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAhCAQAAABOpSL+AAAAIklEQVR4AWMwbb/PdR+JZDD9f1/oPhI5sgVGBSruc9xHIgGdSQqqQJGkRgAAAABJRU5ErkJggg==') center center no-repeat #cecece; - cursor: col-resize; -} - -.splitter-horizontal { - flex: 0 0 auto; - height: 9px; - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAICAQAAADdTl4aAAAAIElEQVQoz2MwrTD9TxFsZ7jPcV+IIsjFQAUw6hFqegQA+xzRHT2p7pEAAAAASUVORK5CYII=') center center no-repeat #cecece; - cursor: row-resize; -} - -.trix-control { - overflow-y: auto; -} - -trix-toolbar .trix-button-group { - margin-bottom: 3px; -} - -.form-inline .form-group { - margin-right:6px; -} - -.form-inline .checkbox, .form-inline .radio { - margin-right:6px; -} - -.form-inline .form-group .form-control, .navbar-form .form-group .form-control { - margin-left:6px; -} - -.form-horizontal .checkbox, .form-horizontal .radio { - padding-left: 25px; -} - -.form-inline .form-group trix-editor.form-control { - margin-left: 0px; - width: 100%; -} - -.form-inline .form-group, .form-inline .control-label { - vertical-align: top; -} - -.bootstrap-touchspin .input-group-btn-vertical> .input-sm { - padding: 7px 10px; - height: 6px; -} - -.bootstrap-touchspin .input-group-btn-vertical> .input-lg { - height: 24px; -} - -.kv-spinner-btn-none .input-group-btn-vertical { - display: none; -} - -.kv-spinner-btn-none .form-control { - border-radius: 4px !important; -} - -.kv-spinner-btn-vertical .form-control { - border-radius: 4px 0px 0px 4px !important; -} - -.kv-radiogroup .radio { - margin-top: -5px; -} - -.kv-radiogroup-inline label { - margin-right: 10px; -} - -.kv-radio-checkbox { - padding-left: 7px; -} - -.kv-window { - border-radius: 0px; -} - -.kv-window .modal-header { - height: 40px; - padding: 10px 15px 5px 15px; -} - -.kv-window .modal-header button.close { - width: 21px; -} - -.kv-window .modal-header .modal-title { - white-space: nowrap; -} - -.kv-window .modal-header .window-icon { - display: inline-block; - margin-right: 6px; -} - -ul.dropdown-menu li a { - cursor: pointer; -} - -.col-nopadding { - padding-left: 0; - padding-right: 0; -} - -.kv-preview-thumb .btn, .kv-zoom-actions .btn, .file-zoom-dialog .floating-buttons .btn { - padding: 5px 8px; -} - -.file-drop-zone.clickable:hover { - border: 1px dashed #999; -} - -.file-drop-zone.clickable:focus { - border: 1px solid #5acde2; -} - -ul.tabs-top { - overflow-x: auto; - overflow-y: hidden; - display: flex; -} - -ul.tabs-top > li { - float:none; - flex-shrink: 0; -} - -.kv-tab-close { - margin-left: 10px; - color: #000; - text-shadow: 0 1px 0 #fff; - filter: alpha(opacity=20); - opacity: 0.2; -} - -.kv-tab-close:hover, .kv-tab-close:focus { - cursor: pointer; - filter: alpha(opacity=50); - opacity: 0.5; -} - -select.form-control, .tabulator-row .tabulator-cell.tabulator-editing select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background: transparent none no-repeat; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAKCAYAAABblxXYAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wUKFyIn4IjqJgAAAENJREFUKM/l0LERACEQQlGsiTa2px1aokGugNNAx8wfMy8AeLoBALYjaTqoKkga2+gKPgF/2Q7JkEx359oftu+C7/UBCUIcVQz0PvcAAAAASUVORK5CYII='); - background-position: right center; - cursor: pointer; -} - -select.form-control:hover { - background-color: #e6e6e6; -} - -select.form-control option { - background-color: white; -} - -select.input-sm { - line-height: inherit; -} - -.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select { - border: 1px solid #ccc; - border-radius: 4px; -} - -.tabulator-row .tabulator-cell.tabulator-editing input:focus, .tabulator-row .tabulator-cell.tabulator-editing select:focus { - border-color: #66afe9; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); -} - -.tabulator-row .tabulator-cell.tabulator-editing { - border-right: 1px solid #1d68cd !important; - padding: 2px !important; -} diff --git a/kvision-modules/kvision-bootstrap/src/main/resources/js/bootstrap.config.js b/kvision-modules/kvision-bootstrap/src/main/resources/js/bootstrap.config.js deleted file mode 100644 index 906942d1..00000000 --- a/kvision-modules/kvision-bootstrap/src/main/resources/js/bootstrap.config.js +++ /dev/null @@ -1,64 +0,0 @@ -module.exports = { - - // Default for the style loading - styleLoader: 'style-loader!css-loader!less-loader', - - scripts: { - 'transition': true, - 'alert': true, - 'button': true, - 'carousel': true, - 'collapse': true, - 'dropdown': true, - 'modal': true, - 'tooltip': true, - 'popover': true, - 'scrollspy': true, - 'tab': true, - 'affix': true - }, - styles: { - "mixins": false, - - "normalize": false, - "print": false, - - "scaffolding": false, - "type": false, - "code": false, - "grid": false, - "tables": false, - "forms": false, - "buttons": false, - - "component-animations": false, - "glyphicons": false, - "dropdowns": false, - "button-groups": false, - "input-groups": false, - "navs": false, - "navbar": false, - "breadcrumbs": false, - "pagination": false, - "pager": false, - "labels": false, - "badges": false, - "jumbotron": false, - "thumbnails": false, - "alerts": false, - "progress-bars": false, - "media": false, - "list-group": false, - "panels": false, - "wells": false, - "close": false, - - "modals": false, - "tooltip": false, - "popovers": false, - "carousel": false, - - "utilities": false, - "responsive-utilities": false - } -}; diff --git a/kvision-modules/kvision-bootstrap/src/main/resources/js/bootstrap.config.less b/kvision-modules/kvision-bootstrap/src/main/resources/js/bootstrap.config.less deleted file mode 100644 index e69de29b..00000000 --- a/kvision-modules/kvision-bootstrap/src/main/resources/js/bootstrap.config.less +++ /dev/null diff --git a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 1ad97acc..fc3d5242 100644 --- a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt @@ -70,8 +70,8 @@ interface DomSpec : TestSpec { fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { if (expected != null && actual != null) { - val exp = jQuery(expected) - val act = jQuery(actual) + val exp = jQuery(expected.replace("position: ;","position: absolute;")) + val act = jQuery(actual.replace("position: ;","position: absolute;")) val result = exp[0]?.isEqualNode(act[0]) if (result == true) { assertTrue(result == true, message) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt index 35172267..b467f1ff 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt @@ -22,6 +22,7 @@ package test.pl.treksoft.kvision.dropdown import pl.treksoft.kvision.dropdown.ContextMenu +import pl.treksoft.kvision.dropdown.ContextMenu.Companion.setContextMenu import pl.treksoft.kvision.html.Link.Companion.link import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.utils.obj @@ -43,7 +44,7 @@ class ContextMenuSpec : DomSpec { m.show() val element = document.getElementById("test") assertEqualsHtml( - "<ul class=\"dropdown-menu\" style=\"display: block;\"><li><a href=\"b\">a</a></li><li><a href=\"d\">c</a></li></ul>", + "<div class=\"dropdown-menu\" style=\"display: block;\"><a href=\"b\">a</a><a href=\"d\">c</a></div>", element?.innerHTML, "Should render correct context menu" ) @@ -66,7 +67,7 @@ class ContextMenuSpec : DomSpec { }) val element = document.getElementById("test") assertEqualsHtml( - "<ul class=\"dropdown-menu\" style=\"display: block; top: 50px; left: 40px;\"><li><a href=\"b\">a</a></li><li><a href=\"d\">c</a></li></ul>", + "<div class=\"dropdown-menu\" style=\"display: block; top: 50px; left: 40px;\"><a href=\"b\">a</a><a href=\"d\">c</a></div>", element?.innerHTML, "Should place context menu in the correct position" ) diff --git a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/DropDownSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/DropDownSpec.kt index af35fa51..f75331f3 100644 --- a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/DropDownSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/DropDownSpec.kt @@ -22,6 +22,7 @@ package test.pl.treksoft.kvision.dropdown import pl.treksoft.kvision.dropdown.DD +import pl.treksoft.kvision.dropdown.Direction import pl.treksoft.kvision.dropdown.DropDown import pl.treksoft.kvision.panel.Root import test.pl.treksoft.kvision.DomSpec @@ -37,11 +38,11 @@ class DropDownSpec : DomSpec { val root = Root("test", fixed = true) val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag") root.add(dd) - dd.toggle() + dd.list.getElementJQueryD()?.dropdown("toggle") val element = document.getElementById("test") val id = dd.buttonId() assertEqualsHtml( - "<div class=\"dropdown open\"><button class=\"dropdown btn btn-default\" id=\"$id\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" role=\"button\" href=\"#\"><span class=\"glyphicon glyphicon-flag\"></span> Dropdown</button><ul class=\"dropdown-menu\" aria-labelledby=\"$id\" aria-expanded=\"true\"><li><a href=\"#!/x\">abc</a></li><li><a href=\"#!/y\">def</a></li></ul></div>", + "<div class=\"dropdown show\"><button class=\"btn btn-primary dropdown-toggle\" id=\"$id\" role=\"button\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" href=\"#\"><i class=\"flag\"></i> Dropdown</button><div class=\"dropdown-menu show\" aria-labelledby=\"$id\" x-placement=\"bottom-start\" aria-expanded=\"true\" style=\"position: ;\"><a class=\"dropdown-item\" href=\"#!/x\">abc</a><a class=\"dropdown-item\" href=\"#!/y\">def</a></div></div>", element?.innerHTML, "Should render correct drop down" ) @@ -52,13 +53,13 @@ class DropDownSpec : DomSpec { fun renderDropUp() { run { val root = Root("test", fixed = true) - val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag").apply { dropup = true } + val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag").apply { direction = Direction.DROPUP } root.add(dd) - dd.toggle() + dd.list.getElementJQueryD()?.dropdown("toggle") val element = document.getElementById("test") val id = dd.buttonId() assertEqualsHtml( - "<div class=\"dropup open\"><button class=\"dropdown btn btn-default\" id=\"$id\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" role=\"button\" href=\"#\"><span class=\"glyphicon glyphicon-flag\"></span> Dropdown</button><ul class=\"dropdown-menu\" aria-labelledby=\"$id\" aria-expanded=\"true\"><li><a href=\"#!/x\">abc</a></li><li><a href=\"#!/y\">def</a></li></ul></div>", + "<div class=\"dropup show\"><button class=\"btn btn-primary dropdown-toggle\" id=\"$id\" role=\"button\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" href=\"#\"><i class=\"flag\"></i> Dropdown</button><div class=\"dropdown-menu show\" aria-labelledby=\"$id\" x-placement=\"top-start\" aria-expanded=\"true\" style=\"position: ;\"><a class=\"dropdown-item\" href=\"#!/x\">abc</a><a class=\"dropdown-item\" href=\"#!/y\">def</a></div></div>", element?.innerHTML, "Should render correct drop down" ) @@ -71,11 +72,11 @@ class DropDownSpec : DomSpec { val root = Root("test", fixed = true) val dd = DropDown("Dropdown", listOf("abc" to DD.HEADER.option), "flag") root.add(dd) - dd.toggle() + dd.list.getElementJQueryD()?.dropdown("toggle") val element = document.getElementById("test") val id = dd.buttonId() assertEqualsHtml( - "<div class=\"dropdown open\"><button class=\"dropdown btn btn-default\" id=\"$id\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" role=\"button\" href=\"#\"><span class=\"glyphicon glyphicon-flag\"></span> Dropdown</button><ul class=\"dropdown-menu\" aria-labelledby=\"$id\" aria-expanded=\"true\"><li class=\"dropdown-header\">abc</li></ul></div>", + "<div class=\"dropdown show\"><button class=\"btn btn-primary dropdown-toggle\" id=\"$id\" role=\"button\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" href=\"#\"><i class=\"flag\"></i> Dropdown</button><div class=\"dropdown-menu show\" aria-labelledby=\"$id\" x-placement=\"bottom-start\" aria-expanded=\"true\" style=\"position: ;\"><h6 class=\"dropdown-header\">abc</h6></div></div>", element?.innerHTML, "Should render correct drop down" ) @@ -88,11 +89,11 @@ class DropDownSpec : DomSpec { val root = Root("test", fixed = true) val dd = DropDown("Dropdown", listOf("abc" to DD.SEPARATOR.option), "flag") root.add(dd) - dd.toggle() + dd.list.getElementJQueryD()?.dropdown("toggle") val element = document.getElementById("test") val id = dd.buttonId() assertEqualsHtml( - "<div class=\"dropdown open\"><button class=\"dropdown btn btn-default\" id=\"$id\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" role=\"button\" href=\"#\"><span class=\"glyphicon glyphicon-flag\"></span> Dropdown</button><ul class=\"dropdown-menu\" aria-labelledby=\"$id\" aria-expanded=\"true\"><li class=\"divider\" role=\"separator\"></li></ul></div>", + "<div class=\"dropdown show\"><button class=\"btn btn-primary dropdown-toggle\" id=\"$id\" role=\"button\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" href=\"#\"><i class=\"flag\"></i> Dropdown</button><div class=\"dropdown-menu show\" aria-labelledby=\"$id\" x-placement=\"bottom-start\" aria-expanded=\"true\" style=\"position: ;\"><div class=\"dropdown-divider\"></div></div></div>", element?.innerHTML, "Should render correct drop down" ) @@ -105,11 +106,11 @@ class DropDownSpec : DomSpec { val root = Root("test", fixed = true) val dd = DropDown("Dropdown", listOf("abc" to DD.DISABLED.option), "flag") root.add(dd) - dd.toggle() + dd.list.getElementJQueryD()?.dropdown("toggle") val element = document.getElementById("test") val id = dd.buttonId() assertEqualsHtml( - "<div class=\"dropdown open\"><button class=\"dropdown btn btn-default\" id=\"$id\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" role=\"button\" href=\"#\"><span class=\"glyphicon glyphicon-flag\"></span> Dropdown</button><ul class=\"dropdown-menu\" aria-labelledby=\"$id\" aria-expanded=\"true\"><li class=\"disabled\"><a>abc</a></li></ul></div>", + "<div class=\"dropdown show\"><button class=\"btn btn-primary dropdown-toggle\" id=\"$id\" role=\"button\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" href=\"#\"><i class=\"flag\"></i> Dropdown</button><div class=\"dropdown-menu show\" aria-labelledby=\"$id\" x-placement=\"bottom-start\" aria-expanded=\"true\" style=\"position: ;\"><a class=\"dropdown-item disabled\" tabindex=\"-1\" aria-disabled=\"true\" href=\"javascript:void(0)\">abc</a></div></div>", element?.innerHTML, "Should render correct drop down" ) @@ -122,10 +123,10 @@ class DropDownSpec : DomSpec { val root = Root("test", fixed = true) val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag") root.add(dd) - val visible = dd.getElementJQuery()?.hasClass("open") ?: false + val visible = dd.getElementJQuery()?.hasClass("show") ?: false assertTrue("Dropdown menu is not visible before toggle") { !visible } - dd.toggle() - val visible2 = dd.getElementJQuery()?.hasClass("open") ?: false + dd.list.getElementJQueryD()?.dropdown("toggle") + val visible2 = dd.getElementJQuery()?.hasClass("show") ?: false assertTrue("Dropdown menu is visible after toggle") { visible2 } } } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt index e75baf9e..25ca7a7d 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt @@ -37,7 +37,7 @@ class HeaderSpec : DomSpec { root.add(h) val element = document.getElementById("test") assertEqualsHtml( - "<li class=\"dropdown-header\">Test</li>", + "<h6 class=\"dropdown-header\">Test</h6>", element?.innerHTML, "Should render correct drop down header" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt index 86607ec7..36c22a74 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt @@ -37,7 +37,7 @@ class SeparatorSpec : DomSpec { root.add(s) val element = document.getElementById("test") assertEqualsHtml( - "<li class=\"divider\" role=\"separator\"></li>", + "<div class=\"dropdown-divider\"></div>", element?.innerHTML, "Should render correct drop down separator" ) diff --git a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/modal/AlertSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/modal/AlertSpec.kt index c3d17de9..48a8b5a0 100644 --- a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/modal/AlertSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/modal/AlertSpec.kt @@ -37,22 +37,22 @@ class AlertSpec : DomSpec { fun render() { run { Root("test", fixed = true) - Alert.show("Alert caption", "Alert content") - val alert = document.getElementById("test")?.let { jQuery(it).find(".modal")[0] } + Alert.show("Alert caption", "Alert content", animation = false) + val alert = document.getElementById("test")?.let { jQuery(it).parent().parent().find(".modal")[0] } assertNotNull(alert, "Should show alert window") - val title = document.getElementById("test")?.let { jQuery(it).find(".modal-title").html() } + val title = document.getElementById("test")?.let { jQuery(it).parent().parent().find(".modal-title").html() } assertEquals("Alert caption", title, "Should render alert window with correct caption") - val body = document.getElementById("test")?.let { jQuery(it).find(".modal-body").html() } + val body = document.getElementById("test")?.let { jQuery(it).parent().parent().find(".modal-body").html() } assertEquals("<div>Alert content</div>", body, "Should render alert window with correct content") - val footer = document.getElementById("test")?.let { jQuery(it).find(".modal-footer").html() } + val footer = document.getElementById("test")?.let { jQuery(it).parent().parent().find(".modal-footer").html() } assertEqualsHtml( - "<button class=\"btn btn-primary\" type=\"button\"><span class=\"glyphicon glyphicon-ok\"></span> OK</button>", + "<button class=\"btn btn-primary\" type=\"button\"><i class=\"fas fa-check\"></i> OK</button>", footer, "Should render alert window with correct footer" ) - val button = document.getElementById("test")?.let { jQuery(it).find(".modal-footer").find("button") } + val button = document.getElementById("test")?.let { jQuery(it).parent().parent().find(".modal-footer").find("button") } button?.click() - val alert2 = document.getElementById("test")?.let { jQuery(it).find(".modal")[0] } + val alert2 = document.getElementById("test")?.let { jQuery(it).parent().parent().find(".modal")[0] } assertNull(alert2, "Should hide alert window after clicking OK") } } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt index 40720bcb..8eb7bd5b 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt @@ -37,13 +37,13 @@ class NavFormSpec : DomSpec { root.add(navf) val element = document.getElementById("test") assertEqualsHtml( - "<form class=\"navbar-form navbar-left\"></form>", + "<form class=\"form-inline\"></form>", element?.innerHTML, "Should render correct nav form" ) navf.rightAlign = true assertEqualsHtml( - "<form class=\"navbar-form navbar-right\"></form>", + "<form class=\"form-inline ml-auto\"></form>", element?.innerHTML, "Should render correct right aligned nav form" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt index 988a706d..2e52557f 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt @@ -37,13 +37,13 @@ class NavSpec : DomSpec { root.add(nav) val element = document.getElementById("test") assertEqualsHtml( - "<ul class=\"nav navbar-nav\"></ul>", + "<div class=\"navbar-nav\"></div>", element?.innerHTML, "Should render correct nav" ) nav.rightAlign = true assertEqualsHtml( - "<ul class=\"nav navbar-nav navbar-right\"></ul>", + "<div class=\"navbar-nav ml-auto\"></div>", element?.innerHTML, "Should render correct right aligned nav" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt index f38a05f9..1658e63c 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt @@ -26,6 +26,7 @@ import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag.Companion.tag import pl.treksoft.kvision.navbar.Nav import pl.treksoft.kvision.navbar.Navbar +import pl.treksoft.kvision.navbar.NavbarColor import pl.treksoft.kvision.navbar.NavbarType import pl.treksoft.kvision.panel.Root import test.pl.treksoft.kvision.DomSpec @@ -43,15 +44,15 @@ class NavbarSpec : DomSpec { val element = document.getElementById("test") val id = navbar.container.id assertEqualsHtml( - "<nav class=\"navbar navbar-fixed-top navbar-default\"><div class=\"container-fluid\"><div class=\"navbar-header\"><button class=\"navbar-toggle collapsed\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-expanded=\"false\"><span class=\"sr-only\">Toggle navigation</span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span></button><a class=\"navbar-brand\" href=\"#\">TEST</a></div><div class=\"collapse navbar-collapse\" id=\"$id\"></div></div></nav>", + "<nav class=\"navbar fixed-top navbar-expand-lg navbar-light bg-light\"><a class=\"navbar-brand\" href=\"#\">TEST</a><button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-controls=\"$id\" aria-expanded=\"false\" aria-label=\"Toggle navigation\"><span class=\"navbar-toggler-icon\"></span></button><div class=\"collapse navbar-collapse\" id=\"$id\"></div></nav>", element?.innerHTML, "Should render correct navbar" ) - navbar.inverted = true + navbar.nColor = NavbarColor.DARK assertEqualsHtml( - "<nav class=\"navbar navbar-fixed-top navbar-inverse\"><div class=\"container-fluid\"><div class=\"navbar-header\"><button class=\"navbar-toggle collapsed\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-expanded=\"false\"><span class=\"sr-only\">Toggle navigation</span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span></button><a class=\"navbar-brand\" href=\"#\">TEST</a></div><div class=\"collapse navbar-collapse\" id=\"$id\"></div></div></nav>", + "<nav class=\"navbar fixed-top navbar-expand-lg bg-light navbar-dark\"><a class=\"navbar-brand\" href=\"#\">TEST</a><button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-controls=\"$id\" aria-expanded=\"false\" aria-label=\"Toggle navigation\"><span class=\"navbar-toggler-icon\"></span></button><div class=\"collapse navbar-collapse\" id=\"$id\"></div></nav>", element?.innerHTML, - "Should render correct inverted navbar" + "Should render correct dark navbar" ) navbar.add(Nav { tag(TAG.LI) { @@ -59,7 +60,7 @@ class NavbarSpec : DomSpec { } }) assertEqualsHtml( - "<nav class=\"navbar navbar-fixed-top navbar-inverse\"><div class=\"container-fluid\"><div class=\"navbar-header\"><button class=\"navbar-toggle collapsed\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-expanded=\"false\"><span class=\"sr-only\">Toggle navigation</span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span></button><a class=\"navbar-brand\" href=\"#\">TEST</a></div><div class=\"collapse navbar-collapse\" id=\"$id\"><ul class=\"nav navbar-nav\"><li><a href=\"#!/test\">Test</a></li></ul></div></div></nav>", + "<nav class=\"navbar fixed-top navbar-expand-lg bg-light navbar-dark\"><a class=\"navbar-brand\" href=\"#\">TEST</a><button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-controls=\"$id\" aria-expanded=\"false\" aria-label=\"Toggle navigation\"><span class=\"navbar-toggler-icon\"></span></button><div class=\"collapse navbar-collapse\" id=\"$id\"><div class=\"navbar-nav\"><li><a href=\"#!/test\">Test</a></li></div></div></nav>", element?.innerHTML, "Should render correct navbar with nav link" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt index fcdf9860..1ebac202 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt @@ -41,7 +41,7 @@ class ResponsiveGridPanelSpec : DomSpec { rgPanel.add(Span("ghi"), 3, 3) val element = document.getElementById("test") assertEqualsHtml( - "<div class=\"container-fluid\"><div class=\"row\"></div><div class=\"row\"><div class=\"col-md-3\"></div><div class=\"col-md-3\"><span>abc</span></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div></div><div class=\"row\"><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"><span>def</span></div><div class=\"col-md-3\"></div></div><div class=\"row\"><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"><span>ghi</span></div></div></div>", + "<div class=\"container-fluid\"><div class=\"row\"><div class=\"col-md-4\"><span>abc</span></div><div class=\"col-md-4\"></div><div class=\"col-md-4\"></div></div><div class=\"row\"><div class=\"col-md-4\"></div><div class=\"col-md-4\"><span>def</span></div><div class=\"col-md-4\"></div></div><div class=\"row\"><div class=\"col-md-4\"></div><div class=\"col-md-4\"></div><div class=\"col-md-4\"><span>ghi</span></div></div></div>", element?.innerHTML, "Should render correct responsive grid panel" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt index 9335562f..7a76cde9 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt @@ -43,7 +43,7 @@ class TabPanelSpec : DomSpec { tabs.addTab("DEF", label2) val element = document.getElementById("test") assertEqualsHtml( - "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\" class=\"active\"><a href=\"#\">ABC</a></li><li role=\"presentation\"><a href=\"#\">DEF</a></li></ul><div><span>abc</span></div></div>", + "<div><ul class=\"nav nav-tabs\"><li class=\"nav-item\"><a class=\"nav-link active\" href=\"#\">ABC</a></li><li class=\"nav-item\"><a class=\"nav-link\" href=\"#\">DEF</a></li></ul><div><span>abc</span></div></div>", element?.innerHTML, "Should render correct tabs" ) @@ -63,7 +63,7 @@ class TabPanelSpec : DomSpec { tabs.activeIndex = 1 val element = document.getElementById("test") assertEqualsHtml( - "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\" class=\"\"><a href=\"#\">ABC</a></li><li role=\"presentation\" class=\"active\"><a href=\"#\">DEF</a></li></ul><div><span>def</span></div></div>", + "<div><ul class=\"nav nav-tabs\"><li class=\"nav-item\"><a class=\"nav-link\" href=\"#\">ABC</a></li><li class=\"nav-item\"><a class=\"nav-link active\" href=\"#\">DEF</a></li></ul><div><span>def</span></div></div>", element?.innerHTML, "Should change selected tab" ) @@ -84,7 +84,7 @@ class TabPanelSpec : DomSpec { tabs.removeTab(1) val element = document.getElementById("test") assertEqualsHtml( - "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\" class=\"\"><a href=\"#\">ABC</a></li></ul><div><span>abc</span></div></div>", + "<div><ul class=\"nav nav-tabs\"><li class=\"nav-item\"><a class=\"nav-link active\" href=\"#\">ABC</a></li></ul><div><span>abc</span></div></div>", element?.innerHTML, "Should remove tab" ) @@ -105,10 +105,10 @@ class TabPanelSpec : DomSpec { tabs.removeTab(0) val label3 = Span("ghi") tabs.addTab("GHI", label3) - jQuery("#test a")[0]?.click() + jQuery("#test a")[1]?.click() val element = document.getElementById("test") assertEqualsHtml( - "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\"><a href=\"#\">DEF</a></li><li role=\"presentation\"><a href=\"#\">GHI</a></li></ul><div><span>def</span></div></div>", + "<div><ul class=\"nav nav-tabs\"><li class=\"nav-item\"><a class=\"nav-link\" href=\"#\">DEF</a></li><li class=\"nav-item\"><a class=\"nav-link active\" href=\"#\">GHI</a></li></ul><div><span>ghi</span></div></div>", element?.innerHTML, "Should select correct tab by clicking" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt index 2f044987..2f044987 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt index 4aa14230..4aa14230 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt index b324b8ab..b3ddbe40 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt @@ -24,7 +24,6 @@ package test.pl.treksoft.kvision.toolbar import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.toolbar.ButtonGroup import pl.treksoft.kvision.toolbar.ButtonGroupSize -import pl.treksoft.kvision.toolbar.ButtonGroupStyle import test.pl.treksoft.kvision.DomSpec import kotlin.browser.document import kotlin.test.Test @@ -44,11 +43,11 @@ class ButtonGroupSpec : DomSpec { "Should render correct button group" ) group.size = ButtonGroupSize.LARGE - group.style = ButtonGroupStyle.JUSTIFIED + group.vertical = true assertEqualsHtml( - "<div class=\"btn-group btn-group-lg btn-group-justified\" role=\"group\"></div>", + "<div class=\"btn-group-lg btn-group-vertical\" role=\"group\"></div>", element?.innerHTML, - "Should render correct button group with large and justified buttons" + "Should render correct button group with large and vertical buttons" ) } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt index d41ef05e..d41ef05e 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt diff --git a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/window/WindowSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/window/WindowSpec.kt index c79b9d32..a65ff7c3 100644 --- a/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/window/WindowSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/window/WindowSpec.kt @@ -35,18 +35,13 @@ class WindowSpec : DomSpec { val root = Root("test", fixed = true) val window = Window("Window title", isResizable = false) root.add(window) + window.show() val id = window.id val element = document.getElementById("test") assertEqualsHtml( - "<div class=\"modal-content kv-window\" id=\"$id\" style=\"width: auto; position: absolute; z-index: 901; overflow: hidden;\"><div class=\"modal-header\"><h4 class=\"modal-title\">Window title</h4></div><div style=\"height: auto; overflow: auto;\"></div></div>", + "<div class=\"modal-content kv-window\" id=\"$id\" style=\"width: auto; position: absolute; z-index: 901; overflow: hidden;\"><div class=\"modal-header\"><h5 class=\"modal-title\">Window title</h5><div class=\"kv-window-icons-container\"></div></div><div style=\"height: auto; overflow: auto;\"></div></div>", element?.innerHTML, - "Should render floating window without resizable handler" - ) - window.isResizable = true - assertEqualsHtml( - "<div class=\"modal-content kv-window\" id=\"$id\" style=\"width: auto; position: absolute; z-index: 901; overflow: hidden; resize: both;\"><div class=\"modal-header\"><h4 class=\"modal-title\">Window title</h4></div><div style=\"height: auto; overflow: auto; margin-bottom: 11px;\"></div><object style=\"position: absolute; top: 0; left: 0; height: 100%; width: 100%; pointer-events: none; z-index: -1; opacity: 0;\" class=\"resize-sensor\" tabindex=\"-1\" type=\"text/html\" data=\"about:blank\"></object></div>", - element?.innerHTML, - "Should render floating window with resizable handler" + "Should render floating window" ) } } diff --git a/kvision-modules/kvision-chart/build.gradle b/kvision-modules/kvision-chart/build.gradle index d90de6ce..6733a4ab 100644 --- a/kvision-modules/kvision-chart/build.gradle +++ b/kvision-modules/kvision-chart/build.gradle @@ -4,10 +4,6 @@ kotlinFrontend { npm { dependency("chart.js", "2.7.3") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") } } diff --git a/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt b/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt index 73a0f2b9..b572d896 100644 --- a/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt +++ b/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt @@ -26,13 +26,11 @@ internal val kVManagerChartInit = KVManagerChart.init() /** * Internal singleton object which initializes and configures KVision Chart module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerChart { - fun init() {} - private val chart = try { + init { require("chart.js/dist/Chart.bundle.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-chart/webpack.config.d/css.js b/kvision-modules/kvision-chart/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-chart/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-cordova/webpack.config.d/css.js b/kvision-modules/kvision-cordova/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-cordova/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-datacontainer/build.gradle b/kvision-modules/kvision-datacontainer/build.gradle index a10a048f..6779c309 100644 --- a/kvision-modules/kvision-datacontainer/build.gradle +++ b/kvision-modules/kvision-datacontainer/build.gradle @@ -1,12 +1 @@ apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") - } - -} diff --git a/kvision-modules/kvision-datacontainer/webpack.config.d/css.js b/kvision-modules/kvision-datacontainer/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-datacontainer/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-datetime/build.gradle b/kvision-modules/kvision-datetime/build.gradle deleted file mode 100644 index bbd4bb79..00000000 --- a/kvision-modules/kvision-datetime/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-datetime-picker", "2.4.4") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") - } - -} 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 deleted file mode 100644 index 4cc71c8b..00000000 --- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 kVManagerDatetimeInit = KVManagerDatetime.init() - -/** - * Internal singleton object which initializes and configures KVision datetime module. - */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") -internal object KVManagerDatetime { - fun init() {} - - private val bootstrapDateTimePickerCss = try { - require("bootstrap-datetime-picker/css/bootstrap-datetimepicker.min.css") - } catch (e: Throwable) { - } - private val bootstrapDateTimePicker = try { - require("bootstrap-datetime-picker/js/bootstrap-datetimepicker.min.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js") - require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js") - } catch (e: Throwable) { - } - -} 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 deleted file mode 100644 index a375ef35..00000000 --- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt +++ /dev/null @@ -1,320 +0,0 @@ -/* - * 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.form.time - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.StringPair -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.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 - -/** - * Basic date/time chooser component. - * - * @constructor - * @param value date/time input value - * @param format date/time format (default YYYY-MM-DD HH:mm) - * @param classes a set of CSS class names - */ -@Suppress("TooManyFunctions") -open class DateTimeInput( - value: Date? = null, format: String = "YYYY-MM-DD HH:mm", - classes: Set<String> = setOf() -) : Widget(classes + "form-control"), FormInput { - - private var initialized = false - - init { - this.setInternalEventListener<DateTimeInput> { - change = { - self.changeValue() - } - } - } - - /** - * Date/time input value. - */ - var value by refreshOnUpdate(value) { refreshState() } - /** - * Date/time format. - */ - var format by refreshOnUpdate(format) { refreshDatePicker() } - /** - * The placeholder for the date/time input. - */ - var placeholder: String? by refreshOnUpdate() - /** - * The name attribute of the generated HTML input element. - */ - override var name: String? by refreshOnUpdate() - /** - * Determines if the field is disabled. - */ - override var disabled by refreshOnUpdate(false) { refresh(); checkDisabled() } - /** - * Determines if the text input is automatically focused. - */ - var autofocus: Boolean? by refreshOnUpdate() - /** - * Determines if the date/time input is read-only. - */ - var readonly: Boolean? by refreshOnUpdate() - /** - * The size of the input. - */ - override var size: InputSize? by refreshOnUpdate() - /** - * Day of the week start. 0 (Sunday) to 6 (Saturday). - */ - 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() } - /** - * Determines if *Clear* button should be visible. - */ - var clearBtn by refreshOnUpdate(true) { refreshDatePicker() } - /** - * Determines if *Today* button should be visible. - */ - var todayBtn by refreshOnUpdate(false) { refreshDatePicker() } - /** - * Determines if the current day should be highlighted. - */ - var todayHighlight by refreshOnUpdate(false) { refreshDatePicker() } - /** - * The increment used to build the hour view. - */ - 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() } - - override fun render(): VNode { - return render("input") - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - size?.let { - cl.add(it.className to true) - } - return cl - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - sn.add("type" to "text") - placeholder?.let { - sn.add("placeholder" to translate(it)) - } - name?.let { - sn.add("name" to it) - } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - readonly?.let { - if (it) { - sn.add("readonly" to "readonly") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - value?.let { - sn.add("value" to it.toStringF(format)) - } - } - return sn - } - - private fun checkDisabled() { - if (disabled) { - if (initialized) { - getElementJQueryD()?.datetimepicker("remove") - initialized = false - } - } else { - if (!initialized) { - this.initDateTimePicker() - this.initEventHandlers() - this.refreshState() - initialized = true - } - } - } - - @Suppress("UnsafeCastFromDynamic") - protected open fun refreshState() { - value?.let { - getElementJQueryD()?.datetimepicker("update", it) - } ?: run { - getElementJQueryD()?.`val`(null) - getElementJQueryD()?.datetimepicker("update", null) - } - } - - protected open fun refreshDatePicker() { - getElementJQueryD()?.`val`(null) - getElementJQueryD()?.datetimepicker("remove") - initDateTimePicker() - refreshState() - } - - protected open fun changeValue() { - val v = getElementJQuery()?.`val`() as String? - if (v != null && v.isNotEmpty()) { - this.value = v.toDateF(format) - } else { - this.value = null - } - } - - /** - * Open date/time chooser popup. - */ - open fun showPopup() { - if (initialized) getElementJQueryD()?.datetimepicker("show") - } - - /** - * Hides date/time chooser popup. - */ - open fun hidePopup() { - if (initialized) getElementJQueryD()?.datetimepicker("hide") - } - - @Suppress("UnsafeCastFromDynamic") - override fun afterInsert(node: VNode) { - if (!this.disabled) { - this.initDateTimePicker() - this.initEventHandlers() - this.refreshState() - initialized = true - } - } - - override fun afterDestroy() { - if (initialized) { - getElementJQueryD()?.datetimepicker("remove") - initialized = false - } - } - - private fun initDateTimePicker() { - val datePickerFormat = format.toDatePickerFormat() - val minView = if (format.contains("HH") || format.contains("mm")) 0 else 2 - val maxView = if (format.contains("YY") || format.contains("M") || format.contains("D")) MAX_VIEW else 1 - val startView = if (maxView < 2) maxView else 2 - val language = I18n.language - getElementJQueryD()?.datetimepicker(obj { - this.format = datePickerFormat - this.startView = startView - this.minView = minView - this.maxView = maxView - this.minuteStep = minuteStep - this.todayHighlight = todayHighlight - this.clearBtn = clearBtn - this.todayBtn = todayBtn - this.weekStart = weekStart - this.showMeridian = showMeridian - this.daysOfWeekDisabled = daysOfWeekDisabled - this.autoclose = true - this.language = language - }) - } - - private fun initEventHandlers() { - this.getElementJQuery()?.on("changeDate") { e, _ -> - @Suppress("UnsafeCastFromDynamic") - this.dispatchEvent("change", obj { detail = e }) - } - this.getElementJQuery()?.on("show") { e, _ -> - @Suppress("UnsafeCastFromDynamic") - this.dispatchEvent("showBsDateTime", obj { detail = e }) - } - this.getElementJQuery()?.on("hide") { e, _ -> - @Suppress("UnsafeCastFromDynamic") - this.dispatchEvent("hideBsDateTime", obj { detail = e }) - } - } - - /** - * Get value of date/time input control as String - * @return value as a String - */ - fun getValueAsString(): String? { - return value?.toStringF(format) - } - - /** - * Makes the input element focused. - */ - override fun focus() { - getElementJQuery()?.focus() - } - - /** - * Makes the input element blur. - */ - override fun blur() { - getElementJQuery()?.blur() - } - - companion object { - - private fun String.toDatePickerFormat(): String { - return this.replace("YY", "yy").replace("m", "i").replace("MMMM", "{----}").replace("MMM", "{---}") - .replace("M", "m").replace("{----}", "MM").replace("{---}", "M").replace("H", "{-}") - .replace("h", "H").replace("{-}", "h").replace("D", "d").replace("a", "p").replace("A", "P") - } - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.dateTimeInput( - 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) } - this.add(dateTimeInput) - return dateTimeInput - } - } -} diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js deleted file mode 100644 index a43b4739..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js +++ /dev/null @@ -1,18 +0,0 @@ -/** -* Arabic translation for bootstrap-datetimepicker -* Ala' Mohammad <amohammad@birzeit.ecu> -*/ -;(function($){ - $.fn.datetimepicker.dates['ar'] = { - days: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"], - daysShort: ["أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت", "أحد"], - daysMin: ["أح", "إث", "ث", "أر", "خ", "ج", "س", "أح"], - months: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"], - monthsShort: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"], - today: "هذا اليوم", - clear: "x", - suffix: [], - meridiem: [], - rtl: true - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js deleted file mode 100644 index c840d6f0..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Azerbaijani translation for bootstrap-datetimepicker - * Konstantin Kaluzhnikov <k.kaluzhnikov@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['az'] = { - days: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə", "Bazar"], - daysShort: ["B", "Be", "Ça", "Ç", "Ca", "C", "Ş", "B"], - daysMin: ["B", "Be", "Ça", "Ç", "Ca", "C", "Ş", "B"], - months: ["Yanvar", "Fevral", "Mart", "Aprel", "May", "İyun", "İyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"], - monthsShort: ["Yan", "Fev", "Mar", "Apr", "May", "İyun", "İyul", "Avq", "Sen", "Okt", "Noy", "Dek"], - today: "Bugün", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js deleted file mode 100644 index 3bc7e273..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Bulgarian translation for bootstrap-datetimepicker - * Apostol Apostolov <apostol.s.apostolov@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['bg'] = { - days: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота", "Неделя"], - daysShort: ["Нед", "Пон", "Вто", "Сря", "Чет", "Пет", "Съб", "Нед"], - daysMin: ["Н", "П", "В", "С", "Ч", "П", "С", "Н"], - months: ["Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"], - monthsShort: ["Ян", "Фев", "Мар", "Апр", "Май", "Юни", "Юли", "Авг", "Сеп", "Окт", "Ное", "Дек"], - today: "днес", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js deleted file mode 100644 index b46bd54f..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Bangla(Bangladesh) translation for bootstrap-datetimepicker - * Mahbub Rabbani <mahbub [dot] rucse [at] gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['bn'] = { - days: ["রবিবার", "সোমবার", "মঙ্গলবার", "বুধবার", "বৃহষ্পতিবার", "শুক্রবার", "শনিবার", "রবিবার"], - daysShort: ["রবি", "সোম", "মঙ্গল", "বুধ", " বৃহঃ", "শুক্র", "শনি", "রবি"], - daysMin: ["রবি", "সোম", "মঙ্গ", "বুধ", "বৃহ", "শুক্র", "শনি", "রবি"], - months: ['জানুয়ারী', 'ফেব্রুয়ারী', 'মার্চ', 'এপ্রিল', 'মে', 'জুন', 'জুলাই', 'অগাস্ট', 'সেপ্টেম্বর', 'অক্টোবর', 'নভেম্বর', 'ডিসেম্বর' ], - monthsShort: ['জানু', 'ফেব্রু', 'মার্চ', 'এপ্রি', 'মে', 'জুন', 'জুলা', 'অগা', 'সেপ্টে', 'অক্টো', 'নভে', 'ডিসে' ], - today: "আজ", - clear: "x", - suffix: [], - meridiem: ['পূর্বাহ্ণ', 'অপরাহ্ন'] - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js deleted file mode 100644 index d3137a2d..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Catalan translation for bootstrap-datetimepicker - * J. Garcia <jogaco.en@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['ca'] = { - days: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte", "Diumenge"], - daysShort: ["Diu", "Dil", "Dmt", "Dmc", "Dij", "Div", "Dis", "Diu"], - daysMin: ["dg", "dl", "dt", "dc", "dj", "dv", "ds", "dg"], - months: ["Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"], - monthsShort: ["Gen", "Feb", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Oct", "Nov", "Des"], - today: "Avui", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js deleted file mode 100644 index 318cd5cf..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Czech translation for bootstrap-datetimepicker - * Matěj Koubík <matej@koubik.name> - * Fixes by Michal Remiš <michal.remis@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['cs'] = { - days: ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota", "Neděle"], - daysShort: ["Ned", "Pon", "Úte", "Stř", "Čtv", "Pát", "Sob", "Ned"], - daysMin: ["Ne", "Po", "Út", "St", "Čt", "Pá", "So", "Ne"], - months: ["Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"], - monthsShort: ["Led", "Úno", "Bře", "Dub", "Kvě", "Čer", "Čnc", "Srp", "Zář", "Říj", "Lis", "Pro"], - today: "Dnes", - suffix: [], - clear: "x", - meridiem: [], - weekStart: 1, - format: "dd.mm.yyyy" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js deleted file mode 100644 index 30d9a34a..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Danish translation for bootstrap-datetimepicker - * Christian Pedersen <http://github.com/chripede> - */ -;(function($){ - $.fn.datetimepicker.dates['da'] = { - days: ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"], - daysShort: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"], - daysMin: ["Sø", "Ma", "Ti", "On", "To", "Fr", "Lø", "Sø"], - months: ["Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"], - today: "I Dag", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js deleted file mode 100644 index 52a19060..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * German translation for bootstrap-datetimepicker - * Sam Zurcher <sam@orelias.ch> - */ -;(function($){ - $.fn.datetimepicker.dates['de'] = { - days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"], - daysShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam", "Son"], - daysMin: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"], - months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], - monthsShort: ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"], - today: "Heute", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1, - format: "dd.mm.yyyy" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js deleted file mode 100644 index 882378f3..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Estonian translation for bootstrap-datetimepicker - * Rene Korss <http://rene.korss.ee> - */ -;(function($){ - $.fn.datetimepicker.dates['ee'] = { - days: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev", "Pühapäev"], - daysShort: ["P", "E", "T", "K", "N", "R", "L", "P"], - daysMin: ["P", "E", "T", "K", "N", "R", "L", "P"], - months: ["Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"], - monthsShort: ["Jaan", "Veebr", "Märts", "Apr", "Mai", "Juuni", "Juuli", "Aug", "Sept", "Okt", "Nov", "Dets"], - today: "Täna", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1, - format: "dd.mm.yyyy hh:ii" - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js deleted file mode 100644 index cbbdc9a7..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js +++ /dev/null @@ -1,16 +0,0 @@ -/** -* Greek translation for bootstrap-datetimepicker -*/ -;(function($){ - $.fn.datetimepicker.dates['el'] = { - days: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο", "Κυριακή"], - daysShort: ["Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ", "Κυρ"], - daysMin: ["Κυ", "Δε", "Τρ", "Τε", "Πε", "Πα", "Σα", "Κυ"], - months: ["Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"], - monthsShort: ["Ιαν", "Φεβ", "Μαρ", "Απρ", "Μάι", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ"], - today: "Σήμερα", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js deleted file mode 100644 index bbf3c207..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Spanish translation for bootstrap-datetimepicker - * Bruno Bonamin <bruno.bonamin@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['es'] = { - days: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"], - daysShort: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"], - daysMin: ["Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"], - months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"], - monthsShort: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"], - today: "Hoy", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js deleted file mode 100644 index 95eb4a8d..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Finnish translation for bootstrap-datetimepicker - * Jaakko Salonen <https://github.com/jsalonen> - */ -;(function($){ - $.fn.datetimepicker.dates['fi'] = { - days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai", "sunnuntai"], - daysShort: ["sun", "maa", "tii", "kes", "tor", "per", "lau", "sun"], - daysMin: ["su", "ma", "ti", "ke", "to", "pe", "la", "su"], - months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"], - monthsShort: ["tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mar", "jou"], - today: "tänään", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js deleted file mode 100644 index f9194cbd..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * French translation for bootstrap-datetimepicker - * Nico Mollet <nico.mollet@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['fr'] = { - days: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"], - daysShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"], - daysMin: ["D", "L", "Ma", "Me", "J", "V", "S", "D"], - months: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"], - monthsShort: ["Jan", "Fev", "Mar", "Avr", "Mai", "Jui", "Jul", "Aou", "Sep", "Oct", "Nov", "Dec"], - today: "Aujourd'hui", - suffix: [], - clear: "x", - meridiem: ["am", "pm"], - weekStart: 1, - format: "dd/mm/yyyy hh:ii" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js deleted file mode 100644 index 1060a4a7..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Hebrew translation for bootstrap-datetimepicker - * Sagie Maoz <sagie@maoz.info> - */ -;(function($){ - $.fn.datetimepicker.dates['he'] = { - days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"], - daysShort: ["א", "ב", "ג", "ד", "ה", "ו", "ש", "א"], - daysMin: ["א", "ב", "ג", "ד", "ה", "ו", "ש", "א"], - months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"], - monthsShort: ["ינו", "פבר", "מרץ", "אפר", "מאי", "יונ", "יול", "אוג", "ספט", "אוק", "נוב", "דצמ"], - today: "היום", - clear: "x", - suffix: [], - meridiem: [], - rtl: true - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js deleted file mode 100644 index f85540fa..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Croatian localisation - */ -;(function($){ - $.fn.datetimepicker.dates['hr'] = { - days: ["Nedjelja", "Ponedjelja", "Utorak", "Srijeda", "Četrtak", "Petak", "Subota", "Nedjelja"], - daysShort: ["Ned", "Pon", "Uto", "Srr", "Čet", "Pet", "Sub", "Ned"], - daysMin: ["Ne", "Po", "Ut", "Sr", "Če", "Pe", "Su", "Ne"], - months: ["Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"], - monthsShort: ["Sije", "Velj", "Ožu", "Tra", "Svi", "Lip", "Jul", "Kol", "Ruj", "Lis", "Stu", "Pro"], - today: "Danas", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js deleted file mode 100644 index 5de9fe9e..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Hungarian translation for bootstrap-datetimepicker - * darevish <http://github.com/darevish> - */ -;(function($){ - $.fn.datetimepicker.dates['hu'] = { - days: ["Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat", "Vasárnap"], - daysShort: ["Vas", "Hét", "Ked", "Sze", "Csü", "Pén", "Szo", "Vas"], - daysMin: ["V", "H", "K", "Sze", "Cs", "P", "Szo", "V"], - months: ["Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"], - monthsShort: ["Jan", "Feb", "Már", "Ápr", "Máj", "Jún", "Júl", "Aug", "Sze", "Okt", "Nov", "Dec"], - today: "Ma", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1 - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js deleted file mode 100644 index cedee4db..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Armenian translation for bootstrap-datepicker - * Hayk Chamyan <hamshen@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['hy'] = { - days: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ", "Կիրակի"], - daysShort: ["Կիր", "Երկ", "Երք", "Չոր", "Հնգ", "Ուր", "Շաբ", "Կիր"], - daysMin: ["Կի", "Եկ", "Եք", "Չո", "Հի", "Ու", "Շա", "Կի"], - months: ["Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"], - monthsShort: ["Հնվ", "Փետ", "Մար", "Ապր", "Մայ", "Հուն", "Հուլ", "Օգս", "Սեպ", "Հոկ", "Նոյ", "Դեկ"], - today: "Այսօր", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js deleted file mode 100644 index feef4a3b..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Bahasa translation for bootstrap-datetimepicker - * Azwar Akbar <azwar.akbar@gmail.com> - * Addtional by Yulian Sutopo <yuliansutopo@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['id'] = { - days: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu"], - daysShort: ["Mng", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab", "Mng"], - daysMin: ["Mg", "Sn", "Sl", "Ra", "Ka", "Ju", "Sa", "Mg"], - months: ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Ags", "Sep", "Okt", "Nov", "Des"], - today: "Hari Ini", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1, - format: "dd/mm/yyyy hh:ii:ss" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js deleted file mode 100644 index 9944c6d7..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Icelandic translation for bootstrap-datetimepicker - * Hinrik Örn Sigurðsson <hinrik.sig@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['is'] = { - days: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur", "Sunnudagur"], - daysShort: ["Sun", "Mán", "Þri", "Mið", "Fim", "Fös", "Lau", "Sun"], - daysMin: ["Su", "Má", "Þr", "Mi", "Fi", "Fö", "La", "Su"], - months: ["Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maí", "Jún", "Júl", "Ágú", "Sep", "Okt", "Nóv", "Des"], - today: "Í Dag", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js deleted file mode 100644 index c00a0499..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Italian translation for bootstrap-datetimepicker - * Enrico Rubboli <rubboli@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['it'] = { - days: ["Domenica", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato", "Domenica"], - daysShort: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab", "Dom"], - daysMin: ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"], - months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"], - monthsShort: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"], - today: "Oggi", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1, - format: "dd/mm/yyyy hh:ii:ss" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js deleted file mode 100644 index 3a2d3b9b..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Japanese translation for bootstrap-datetimepicker - * Norio Suzuki <https://github.com/suzuki/> - */ -;(function($){ - $.fn.datetimepicker.dates['ja'] = { - days: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜", "日曜"], - daysShort: ["日", "月", "火", "水", "木", "金", "土", "日"], - daysMin: ["日", "月", "火", "水", "木", "金", "土", "日"], - months: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"], - monthsShort: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"], - today: "今日", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js deleted file mode 100644 index d4595eff..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Georgian translation for bootstrap-datetimepicker - * Zura Jijavadze <mailzura@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['ka'] = { - days: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი", "კვირა"], - daysShort: ["კვი", "ორშ", "სამ", "ოთხ", "ხუთ", "პარ", "შაბ", "კვი"], - daysMin: ["კვ", "ორ", "სა", "ოთ", "ხუ", "პა", "შა", "კვ"], - months: ["იანვარი", "თებერვალი", "მარტი", "აპრილი", "მაისი", "ივნისი", "ივლისი", "აგვისტო", "სექტემბერი", "ოქტომბერი", "ნოემბერი", "დეკემბერი"], - monthsShort: ["იან", "თებ", "მარ", "აპრ", "მაი", "ივნ", "ივლ", "აგვ", "სექ", "ოქტ", "ნოე", "დეკ"], - today: "დღეს", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js deleted file mode 100644 index adeb6cb6..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Korean translation for bootstrap-datetimepicker - * Gu Youn <http://github.com/guyoun> - * Baekjoon Choi <http://github.com/Baekjoon> - */ -;(function($){ - $.fn.datetimepicker.dates['ko'] = { - days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일", "일요일"], - daysShort: ["일", "월", "화", "수", "목", "금", "토", "일"], - daysMin: ["일", "월", "화", "수", "목", "금", "토", "일"], - months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], - monthsShort: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], - suffix: [], - meridiem: ["오전", "오후"], - today: "오늘", - clear: "x" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js deleted file mode 100644 index 917243c4..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Lithuanian translation for bootstrap-datetimepicker - * Šarūnas Gliebus <ssharunas@yahoo.co.uk> - */ - -;(function($){ - $.fn.datetimepicker.dates['lt'] = { - days: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis", "Sekmadienis"], - daysShort: ["S", "Pr", "A", "T", "K", "Pn", "Š", "S"], - daysMin: ["Sk", "Pr", "An", "Tr", "Ke", "Pn", "Št", "Sk"], - months: ["Sausis", "Vasaris", "Kovas", "Balandis", "Gegužė", "Birželis", "Liepa", "Rugpjūtis", "Rugsėjis", "Spalis", "Lapkritis", "Gruodis"], - monthsShort: ["Sau", "Vas", "Kov", "Bal", "Geg", "Bir", "Lie", "Rugp", "Rugs", "Spa", "Lap", "Gru"], - today: "Šiandien", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1 - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js deleted file mode 100644 index f9b3c774..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Latvian translation for bootstrap-datetimepicker - * Artis Avotins <artis@apit.lv> - */ - -;(function($){ - $.fn.datetimepicker.dates['lv'] = { - days: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena", "Svētdiena"], - daysShort: ["Sv", "P", "O", "T", "C", "Pk", "S", "Sv"], - daysMin: ["Sv", "Pr", "Ot", "Tr", "Ce", "Pk", "St", "Sv"], - months: ["Janvāris", "Februāris", "Marts", "Aprīlis", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jūn", "Jūl", "Aug", "Sep", "Okt", "Nov", "Dec."], - today: "Šodien", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1 - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js deleted file mode 100644 index 26a2cc0e..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Malay translation for bootstrap-datetimepicker - * Ateman Faiz <noorulfaiz@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['ms'] = { - days: ["Ahad", "Isnin", "Selasa", "Rabu", "Khamis", "Jumaat", "Sabtu", "Ahad"], - daysShort: ["Aha", "Isn", "Sel", "Rab", "Kha", "Jum", "Sab", "Aha"], - daysMin: ["Ah", "Is", "Se", "Ra", "Kh", "Ju", "Sa", "Ah"], - months: ["Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis"], - today: "Hari Ini", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js deleted file mode 100644 index a2fd01a6..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Norwegian (bokmål) translation for bootstrap-datetimepicker - * Fredrik Sundmyhr <http://github.com/fsundmyhr> - */ -;(function($){ - $.fn.datetimepicker.dates['nb'] = { - days: ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"], - daysShort: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"], - daysMin: ["Sø", "Ma", "Ti", "On", "To", "Fr", "Lø", "Sø"], - months: ["Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des"], - today: "I Dag", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js deleted file mode 100644 index a28fa031..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Dutch translation for bootstrap-datetimepicker - * Reinier Goltstein <mrgoltstein@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['nl'] = { - days: ["Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"], - daysShort: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"], - daysMin: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"], - months: ["Januari", "Februari", "Maart", "April", "Mei", "Juni", "Juli", "Augustus", "September", "Oktober", "November", "December"], - monthsShort: ["Jan", "Feb", "Mrt", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"], - today: "Vandaag", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js deleted file mode 100644 index 36e33a0b..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Norwegian translation for bootstrap-datetimepicker - * Rune Warhuus <rune@dinkdonkd.no> - */ -;(function($){ - $.fn.datetimepicker.dates['no'] = { - days: ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"], - daysShort: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"], - daysMin: ["Sø", "Ma", "Ti", "On", "To", "Fr", "Lø", "Sø"], - months: ["Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des"], - today: "I Dag", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js deleted file mode 100644 index 12fc7422..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Polish translation for bootstrap-datetimepicker - * Robert <rtpm@gazeta.pl> - */ -;(function($){ -$.fn.datetimepicker.dates['pl'] = { - days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota", "Niedziela"], - daysShort: ["Nie", "Pn", "Wt", "Śr", "Czw", "Pt", "So", "Nie"], - daysMin: ["N", "Pn", "Wt", "Śr", "Cz", "Pt", "So", "N"], - months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"], - monthsShort: ["Sty", "Lu", "Mar", "Kw", "Maj", "Cze", "Lip", "Sie", "Wrz", "Pa", "Lis", "Gru"], - today: "Dzisiaj", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1 -}; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js deleted file mode 100644 index 1d307416..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Brazilian translation for bootstrap-datetimepicker - * Cauan Cabral <cauan@radig.com.br> - */ -;(function($){ - $.fn.datetimepicker.dates['pt-BR'] = { - format: 'dd/mm/yyyy', - days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"], - daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"], - daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa", "Do"], - months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], - monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"], - today: "Hoje", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js deleted file mode 100644 index 166034ef..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Portuguese translation for bootstrap-datetimepicker - * Original code: Cauan Cabral <cauan@radig.com.br> - * Tiago Melo <tiago.blackcode@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['pt'] = { - days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"], - daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"], - daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa", "Do"], - months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], - monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"], - suffix: [], - meridiem: [], - today: "Hoje", - clear: "x" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js deleted file mode 100644 index a7569c6f..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Romanian translation for bootstrap-datetimepicker - * Cristian Vasile <cristi.mie@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['ro'] = { - days: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă", "Duminică"], - daysShort: ["Dum", "Lun", "Mar", "Mie", "Joi", "Vin", "Sâm", "Dum"], - daysMin: ["Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ", "Du"], - months: ["Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"], - monthsShort: ["Ian", "Feb", "Mar", "Apr", "Mai", "Iun", "Iul", "Aug", "Sep", "Oct", "Nov", "Dec"], - today: "Astăzi", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1 - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js deleted file mode 100644 index 57c819f9..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Serbian latin translation for bootstrap-datetimepicker - * Bojan Milosavlević <milboj@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['rs'] = { - days: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota", "Nedelja"], - daysShort: ["Ned", "Pon", "Uto", "Sre", "Čet", "Pet", "Sub", "Ned"], - daysMin: ["N", "Po", "U", "Sr", "Č", "Pe", "Su", "N"], - months: ["Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"], - today: "Danas", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js deleted file mode 100644 index 3e9db3e6..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Serbian cyrillic translation for bootstrap-datetimepicker - * Bojan Milosavlević <milboj@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['rs'] = { - days: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота", "Недеља"], - daysShort: ["Нед", "Пон", "Уто", "Сре", "Чет", "Пет", "Суб", "Нед"], - daysMin: ["Н", "По", "У", "Ср", "Ч", "Пе", "Су", "Н"], - months: ["Јануар", "Фебруар", "Март", "Април", "Мај", "Јун", "Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар"], - monthsShort: ["Јан", "Феб", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Нов", "Дец"], - today: "Данас", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js deleted file mode 100644 index 20caf251..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Russian translation for bootstrap-datetimepicker - * Victor Taranenko <darwin@snowdale.com> - */ -;(function($){ - $.fn.datetimepicker.dates['ru'] = { - days: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"], - daysShort: ["Вск", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Вск"], - daysMin: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"], - months: ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"], - monthsShort: ["Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"], - today: "Сегодня", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js deleted file mode 100644 index acf1495a..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Slovak translation for bootstrap-datetimepicker - * Marek Lichtner <marek@licht.sk> - * Fixes by Michal Remiš <michal.remis@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates["sk"] = { - days: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota", "Nedeľa"], - daysShort: ["Ned", "Pon", "Uto", "Str", "Štv", "Pia", "Sob", "Ned"], - daysMin: ["Ne", "Po", "Ut", "St", "Št", "Pi", "So", "Ne"], - months: ["Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Máj", "Jún", "Júl", "Aug", "Sep", "Okt", "Nov", "Dec"], - today: "Dnes", - clear: "x", - suffix: [], - meridiem: [], - weekStart: 1, - format: "dd.mm.yyyy" - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js deleted file mode 100644 index a7e58bdf..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Slovene translation for bootstrap-datetimepicker - * Gregor Rudolf <gregor.rudolf@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['sl'] = { - days: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota", "Nedelja"], - daysShort: ["Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob", "Ned"], - daysMin: ["Ne", "Po", "To", "Sr", "Če", "Pe", "So", "Ne"], - months: ["Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"], - today: "Danes", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js deleted file mode 100644 index 050125ad..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Swedish translation for bootstrap-datetimepicker - * Patrik Ragnarsson <patrik@starkast.net> - */ -;(function($){ - $.fn.datetimepicker.dates['sv'] = { - days: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag", "Söndag"], - daysShort: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör", "Sön"], - daysMin: ["Sö", "Må", "Ti", "On", "To", "Fr", "Lö", "Sö"], - months: ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"], - today: "I Dag", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js deleted file mode 100644 index 8cdb4df2..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Swahili translation for bootstrap-datetimepicker - * Edwin Mugendi <https://github.com/edwinmugendi> - * Source: http://scriptsource.org/cms/scripts/page.php?item_id=entry_detail&uid=xnfaqyzcku - */ -;(function($){ - $.fn.datetimepicker.dates['sw'] = { - days: ["Jumapili", "Jumatatu", "Jumanne", "Jumatano", "Alhamisi", "Ijumaa", "Jumamosi", "Jumapili"], - daysShort: ["J2", "J3", "J4", "J5", "Alh", "Ij", "J1", "J2"], - daysMin: ["2", "3", "4", "5", "A", "I", "1", "2"], - months: ["Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba"], - monthsShort: ["Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des"], - today: "Leo", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js deleted file mode 100644 index 8adc129a..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Thai translation for bootstrap-datetimepicker - * Suchau Jiraprapot <seroz24@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['th'] = { - days: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"], - daysShort: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"], - daysMin: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"], - months: ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"], - monthsShort: ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."], - today: "วันนี้", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js deleted file mode 100644 index 0130c94c..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Turkish translation for bootstrap-datetimepicker - * Serkan Algur <kaisercrazy_2@hotmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['tr'] = { - days: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi", "Pazar"], - daysShort: ["Pz", "Pzt", "Sal", "Çrş", "Prş", "Cu", "Cts", "Pz"], - daysMin: ["Pz", "Pzt", "Sa", "Çr", "Pr", "Cu", "Ct", "Pz"], - months: ["Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"], - monthsShort: ["Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara"], - today: "Bugün", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery)); - diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js deleted file mode 100644 index 1687a1dc..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Ukrainian translation for bootstrap-datepicker - * Igor Polynets - */ -;(function($){ - $.fn.datetimepicker.dates['ua'] = { - days: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четверг", "П'ятниця", "Субота", "Неділя"], - daysShort: ["Нед", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Нед"], - daysMin: ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Нд"], - months: ["Cічень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"], - monthsShort: ["Січ", "Лют", "Бер", "Квт", "Трв", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Грд"], - today: "Сьогодні", - clear: "x", - weekStart: 1 - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js deleted file mode 100644 index 4b3a9e0a..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Ukrainian translation for bootstrap-datetimepicker - * Andrey Vityuk <andrey [dot] vityuk [at] gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['uk'] = { - days: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота", "Неділя"], - daysShort: ["Нед", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Нед"], - daysMin: ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Нд"], - months: ["Січень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"], - monthsShort: ["Січ", "Лют", "Бер", "Кві", "Тра", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Гру"], - today: "Сьогодні", - clear: "x", - suffix: [], - meridiem: [] - }; -}(jQuery));
\ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js deleted file mode 100644 index f84ba548..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Traditional Chinese translation for bootstrap-datetimepicker - * Rung-Sheng Jang <daniel@i-trend.co.cc> - */ -;(function($){ - $.fn.datetimepicker.dates['zh-TW'] = { - days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], - daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], - daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], - months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], - monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], - today: "今天", - clear: "x", - suffix: [], - meridiem: ["上午", "下午"] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js b/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js deleted file mode 100644 index 66ac5a01..00000000 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Simplified Chinese translation for bootstrap-datetimepicker - * Yuan Cheung <advanimal@gmail.com> - */ -;(function($){ - $.fn.datetimepicker.dates['zh'] = { - days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], - daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], - daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], - months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], - monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], - today: "今天", - clear: "x", - suffix: [], - meridiem: ["上午", "下午"] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-dialog/build.gradle b/kvision-modules/kvision-dialog/build.gradle deleted file mode 100644 index 292a228f..00000000 --- a/kvision-modules/kvision-dialog/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" -} - -kotlinFrontend { - - npm { - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") - } - -} diff --git a/kvision-modules/kvision-fontawesome/build.gradle b/kvision-modules/kvision-fontawesome/build.gradle new file mode 100644 index 00000000..82dd1894 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/build.gradle @@ -0,0 +1,9 @@ +apply from: "../shared.gradle" + +kotlinFrontend { + + npm { + dependency("@fortawesome/fontawesome-free", "5.11.2") + } + +} diff --git a/kvision-modules/kvision-fontawesome/package.json.d/project.info b/kvision-modules/kvision-fontawesome/package.json.d/project.info new file mode 100644 index 00000000..0801ee7b --- /dev/null +++ b/kvision-modules/kvision-fontawesome/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Font Awesome module" +} diff --git a/kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt b/kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt new file mode 100644 index 00000000..f816fb0e --- /dev/null +++ b/kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt @@ -0,0 +1,35 @@ +/* + * 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 kVManagerFontAwesomeInit = KVManagerFontAwesome.init() + +/** + * Internal singleton object which initializes and configures KVision Font Awesome module. + */ +internal object KVManagerFontAwesome { + init { + require("@fortawesome/fontawesome-free/css/all.min.css") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js b/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..32a7c4d0 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js @@ -0,0 +1,4 @@ +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'}); +config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/kvision-modules/kvision-fontawesome/webpack.config.d/css.js b/kvision-modules/kvision-fontawesome/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/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-fontawesome/webpack.config.d/jquery.js b/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js @@ -0,0 +1,5 @@ +config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" +})); diff --git a/kvision-modules/kvision-handlebars/build.gradle b/kvision-modules/kvision-handlebars/build.gradle index a971427e..3864067c 100644 --- a/kvision-modules/kvision-handlebars/build.gradle +++ b/kvision-modules/kvision-handlebars/build.gradle @@ -3,12 +3,8 @@ apply from: "../shared.gradle" kotlinFrontend { npm { - dependency("handlebars", "4.1.0") + dependency("handlebars", "4.3.1") dependency("handlebars-loader", "1.7.1") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") } } 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 b2e52bf7..3bc021bc 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 @@ -26,13 +26,11 @@ internal val kVManagerHandlebarsInit = KVManagerHandlebars.init() /** * Internal singleton object which initializes and configures KVision handlebars module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerHandlebars { - fun init() {} - private val handlebars = try { + init { require("handlebars/dist/handlebars.runtime.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-i18n/build.gradle b/kvision-modules/kvision-i18n/build.gradle index 72870169..a2b6d3f8 100644 --- a/kvision-modules/kvision-i18n/build.gradle +++ b/kvision-modules/kvision-i18n/build.gradle @@ -4,10 +4,6 @@ kotlinFrontend { npm { dependency("jed", "1.1.1") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") } } 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 9e24327b..51f24fa4 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 @@ -26,13 +26,11 @@ internal val kVManagerI18nInit = KVManagerI18n.init() /** * Internal singleton object which initializes and configures KVision i18n module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerI18n { - fun init() {} - private val jed = try { + init { require("jed") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-i18n/webpack.config.d/css.js b/kvision-modules/kvision-i18n/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-i18n/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-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt b/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt index 330d818d..fe11288b 100644 --- a/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt +++ b/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt @@ -27,11 +27,11 @@ internal val kVManagerMomentInit = KVManagerMoment.init() /** * Internal singleton object which initializes and configures KVision Moment module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerMoment { - fun init() {} - private val moment = try { + init { require("moment/min/moment-with-locales.js") - } catch (e: Throwable) {} + } + + internal fun init() {} } diff --git a/kvision-modules/kvision-pace/build.gradle b/kvision-modules/kvision-pace/build.gradle index 238f9efa..d577df20 100644 --- a/kvision-modules/kvision-pace/build.gradle +++ b/kvision-modules/kvision-pace/build.gradle @@ -4,10 +4,6 @@ kotlinFrontend { npm { dependency("pace-progressbar", "1.0.8") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") } }
\ No newline at end of file diff --git a/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt b/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt index 9678d1fa..1a57f871 100644 --- a/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt +++ b/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt @@ -27,13 +27,11 @@ internal val kVManagerPaceInit = KVManagerPace.init() /** * Internal singleton object which initializes and configures KVision Moment module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerPace { - fun init() { - } - private val pace = try { + init { require("pace-progressbar").default - } catch (e: Throwable) { } + + internal fun init() {} } diff --git a/kvision-modules/kvision-redux-kotlin/build.gradle b/kvision-modules/kvision-redux-kotlin/build.gradle index 78bfda21..0b00ddd8 100644 --- a/kvision-modules/kvision-redux-kotlin/build.gradle +++ b/kvision-modules/kvision-redux-kotlin/build.gradle @@ -4,14 +4,3 @@ dependencies { compile ("org.reduxkotlin:redux-kotlin-js:$reduxKotlinVersion") compile ("org.reduxkotlin:redux-kotlin-thunk-js:$reduxKotlinThunkVersion") } - -kotlinFrontend { - - npm { - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") - } - -} diff --git a/kvision-modules/kvision-redux-kotlin/webpack.config.d/css.js b/kvision-modules/kvision-redux-kotlin/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-redux-kotlin/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-redux/build.gradle b/kvision-modules/kvision-redux/build.gradle index 3394095f..7acecd2f 100644 --- a/kvision-modules/kvision-redux/build.gradle +++ b/kvision-modules/kvision-redux/build.gradle @@ -9,13 +9,9 @@ dependencies { kotlinFrontend { npm { - dependency("redux", "4.0.0") + dependency("redux", "4.0.4") dependency("redux-thunk", "2.3.0") - dependency("core-js", "3.0.0") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") + dependency("core-js", "3.2.1") } } diff --git a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt index 346f623d..d86f3a67 100644 --- a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt +++ b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt @@ -33,18 +33,10 @@ internal val kVManagerReduxInit = KVManagerRedux.init() /** * Internal singleton object which initializes and configures KVision Redux module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerRedux { - fun init() {} - private val redux = try { - require("redux/dist/redux.min.js") - } catch (e: Throwable) { - } - internal val reduxThunk = try { - require("redux-thunk/dist/redux-thunk.min.js").default - } catch (e: Throwable) { - } + private val redux = require("redux/dist/redux.min.js") + internal val reduxThunk = require("redux-thunk/dist/redux-thunk.min.js").default @Suppress("UnsafeCastFromDynamic") internal fun <S, A, R> createStore( @@ -72,4 +64,6 @@ internal object KVManagerRedux { } return composeEnhancers(function1, function2) } + + internal fun init() {} } diff --git a/kvision-modules/kvision-redux/webpack.config.d/css.js b/kvision-modules/kvision-redux/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-redux/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-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt index d5745afe..47026f7f 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt @@ -22,7 +22,6 @@ package pl.treksoft.kvision.remote import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient /** * A user profile. @@ -38,7 +37,6 @@ actual data class Profile( val remembered: Boolean = false, val clientName: String? = null ) { - @Transient var username: String? get() = attributes["username"] set(value) { @@ -48,7 +46,6 @@ actual data class Profile( attributes.remove("username") } } - @Transient var firstName: String? get() = attributes["first_name"] set(value) { @@ -58,7 +55,6 @@ actual data class Profile( attributes.remove("first_name") } } - @Transient var familyName: String? get() = attributes["family_name"] set(value) { @@ -68,7 +64,6 @@ actual data class Profile( attributes.remove("family_name") } } - @Transient var displayName: String? get() = attributes["display_name"] set(value) { @@ -78,7 +73,6 @@ actual data class Profile( attributes.remove("display_name") } } - @Transient var email: String? get() = attributes["email"] set(value) { @@ -88,7 +82,6 @@ actual data class Profile( attributes.remove("email") } } - @Transient var pictureUrl: String? get() = attributes["picture_url"] set(value) { @@ -98,7 +91,6 @@ actual data class Profile( attributes.remove("picture_url") } } - @Transient var profileUrl: String? get() = attributes["profile_url"] set(value) { diff --git a/kvision-modules/kvision-richtext/build.gradle b/kvision-modules/kvision-richtext/build.gradle index fde9ff17..489113a7 100644 --- a/kvision-modules/kvision-richtext/build.gradle +++ b/kvision-modules/kvision-richtext/build.gradle @@ -3,11 +3,7 @@ apply from: "../shared.gradle" kotlinFrontend { npm { - dependency("trix", "1.1.0") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") + dependency("trix", "1.2.0") } } 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 c7cd444c..b1b624eb 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 @@ -30,15 +30,10 @@ internal val kVManagerRichTextInit = KVManagerRichText.init() /** * Internal singleton object which initializes and configures KVision RichText module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerRichText { - fun init() {} - private val trixCss = try { + init { require("trix/dist/trix.css") - } catch (e: Throwable) { - } - private val trix = try { val trix = require("trix") window.asDynamic().Trix = trix trix.config.languages = obj {} @@ -59,6 +54,7 @@ internal object KVManagerRichText { orig() } require("./js/locales/trix/trix.pl.js") - } catch (e: Throwable) { } + + internal fun init() {} } diff --git a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt index 22126797..04a02279 100644 --- a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt +++ b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt @@ -55,7 +55,7 @@ open class RichText( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/kvision-modules/kvision-richtext/webpack.config.d/jquery.js b/kvision-modules/kvision-richtext/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-richtext/webpack.config.d/jquery.js @@ -0,0 +1,5 @@ +config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" +})); diff --git a/kvision-modules/kvision-select/build.gradle b/kvision-modules/kvision-select/build.gradle deleted file mode 100644 index 7525f037..00000000 --- a/kvision-modules/kvision-select/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-select", "1.12.4") - dependency("ajax-bootstrap-select", "1.4.3") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") - } - -} diff --git a/kvision-modules/kvision-spinner/build.gradle b/kvision-modules/kvision-spinner/build.gradle deleted file mode 100644 index 4569b8bc..00000000 --- a/kvision-modules/kvision-spinner/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-touchspin", "4.2.5") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") - } - -} diff --git a/kvision-modules/kvision-tabulator-remote/webpack.config.d/css.js b/kvision-modules/kvision-tabulator-remote/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-tabulator-remote/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-tabulator/build.gradle b/kvision-modules/kvision-tabulator/build.gradle index 19da0553..0712c1e6 100644 --- a/kvision-modules/kvision-tabulator/build.gradle +++ b/kvision-modules/kvision-tabulator/build.gradle @@ -8,10 +8,6 @@ kotlinFrontend { npm { dependency("tabulator-tables", "4.4.1") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") } } diff --git a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt index ebd1b9f7..96c084e0 100644 --- a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt +++ b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt @@ -26,22 +26,18 @@ internal val kVManagerTabulatorInit = KVManagerTabulator.init() /** * Internal singleton object which initializes and configures KVision Tabulator module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerTabulator { - fun init() {} - private val tabulatorCss = try { - require("tabulator-tables/dist/css/bootstrap/tabulator_bootstrap.min.css") - } catch (e: Throwable) { + init { + require("tabulator-tables/dist/css/bootstrap/tabulator_bootstrap4.min.css") } - private val tabulator = try { - require("tabulator-tables/dist/js/tabulator.min.js") - } catch (e: Throwable) { - } + private val tabulator = require("tabulator-tables/dist/js/tabulator.min.js") @Suppress("UnsafeCastFromDynamic") fun getConstructor(): Any { return tabulator } + + internal fun init() {} } diff --git a/kvision-modules/kvision-upload/build.gradle b/kvision-modules/kvision-upload/build.gradle deleted file mode 100644 index 2ac20c32..00000000 --- a/kvision-modules/kvision-upload/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" -} - -kotlinFrontend { - - npm { - dependency("bootstrap-fileinput", "4.5.2") - devDependency("karma", "3.1.4") - devDependency("karma-chrome-launcher", "2.2.0") - devDependency("karma-webpack", "3.0.5") - devDependency("qunit", "2.8.0") - } - -} diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js deleted file mode 100644 index 419b1761..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Portuguese Translations - * - * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or - * any HTML markup tags in the messages must not be converted or translated. - * - * @see http://github.com/kartik-v/bootstrap-fileinput - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['pt'] = { - fileSingle: 'ficheiro', - filePlural: 'ficheiros', - browseLabel: 'Procurar …', - removeLabel: 'Remover', - removeTitle: 'Remover ficheiros seleccionados', - cancelLabel: 'Cancelar', - cancelTitle: 'Abortar carregamento ', - uploadLabel: 'Carregar', - uploadTitle: 'Carregar ficheiros seleccionados', - msgNo: 'Não', - msgNoFilesSelected: '', - msgCancelled: 'Cancelado', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Pré-visualização detalhada', - msgFileRequired: 'You must select a file to upload.', - msgSizeTooSmall: 'File "{name}" (<b>{size} KB</b>) is too small and must be larger than <b>{minSize} KB</b>.', - msgSizeTooLarge: 'Ficheiro "{name}" (<b>{size} KB</b>) excede o tamanho máximo permido de <b>{maxSize} KB</b>.', - msgFilesTooLess: 'Deve seleccionar pelo menos <b>{n}</b> {files} para fazer upload.', - msgFilesTooMany: 'Número máximo de ficheiros seleccionados <b>({n})</b> excede o limite máximo de <b>{m}</b>.', - msgFileNotFound: 'Ficheiro "{name}" não encontrado!', - msgFileSecured: 'Restrições de segurança preventem a leitura do ficheiro "{name}".', - msgFileNotReadable: 'Ficheiro "{name}" não pode ser lido.', - msgFilePreviewAborted: 'Pré-visualização abortado para o ficheiro "{name}".', - msgFilePreviewError: 'Ocorreu um erro ao ler o ficheiro "{name}".', - msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', - msgInvalidFileType: 'Tipo inválido para o ficheiro "{name}". Apenas ficheiros "{types}" são suportados.', - msgInvalidFileExtension: 'Extensão inválida para o ficheiro "{name}". Apenas ficheiros "{extensions}" são suportados.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'O upload do arquivo foi abortada', - msgUploadThreshold: 'Processing...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', - msgValidationError: 'Erro de validação', - msgLoading: 'A carregar ficheiro {index} de {files} …', - msgProgress: 'A carregar ficheiro {index} de {files} - {name} - {percent}% completo.', - msgSelected: '{n} {files} seleccionados', - msgFoldersNotAllowed: 'Arrastar e largar ficheiros apenas! {n} pasta(s) ignoradas.', - msgImageWidthSmall: 'Largura do arquivo de imagem "{name}" deve ser pelo menos {size} px.', - msgImageHeightSmall: 'Altura do arquivo de imagem "{name}" deve ser pelo menos {size} px.', - msgImageWidthLarge: 'Largura do arquivo de imagem "{name}" não pode exceder {size} px.', - msgImageHeightLarge: 'Altura do arquivo de imagem "{name}" não pode exceder {size} px.', - msgImageResizeError: 'Could not get the image dimensions to resize.', - msgImageResizeException: 'Erro ao redimensionar a imagem.<pre>{errors}</pre>', - msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', - msgAjaxProgressError: '{operation} failed', - ajaxOperations: { - deleteThumb: 'file delete', - uploadThumb: 'file upload', - uploadBatch: 'batch file upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: 'Arrastar e largar ficheiros aqui …', - dropZoneClickTitle: '<br>(or click to select {files})', - fileActionSettings: { - removeTitle: 'Remover arquivo', - uploadTitle: 'Carregar arquivo', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'Ver detalhes', - dragTitle: 'Move / Rearrange', - indicatorNewTitle: 'Ainda não carregou', - indicatorSuccessTitle: 'Carregado', - indicatorErrorTitle: 'Carregar Erro', - indicatorLoadingTitle: 'A carregar ...' - }, - previewZoomButtonTitles: { - prev: 'View previous file', - next: 'View next file', - toggleheader: 'Toggle header', - fullscreen: 'Toggle full screen', - borderless: 'Toggle borderless mode', - close: 'Close detailed preview' - } - }; -})(window.jQuery);
\ No newline at end of file diff --git a/kvision-modules/shared.gradle b/kvision-modules/shared.gradle index 2b45f630..640d8478 100644 --- a/kvision-modules/shared.gradle +++ b/kvision-modules/shared.gradle @@ -4,6 +4,13 @@ apply plugin: 'kotlinx-serialization' kotlinFrontend { + npm { + devDependency("karma", "4.3.0") + devDependency("karma-chrome-launcher", "3.1.0") + devDependency("karma-webpack", "4.0.2") + devDependency("qunit", "2.9.2") + } + webpackBundle { bundleName = "main" contentPath = file('src/main/web') diff --git a/settings.gradle b/settings.gradle index 39b26428..316306ce 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,23 +4,25 @@ include 'kvision-modules:kvision-base', 'kvision-modules:kvision-common-remote', 'kvision-modules:kvision-common-types', 'kvision-modules:kvision-bootstrap', - 'kvision-modules:kvision-select', - 'kvision-modules:kvision-datetime', - 'kvision-modules:kvision-spinner', + 'kvision-modules:kvision-bootstrap-css', + 'kvision-modules:kvision-bootstrap-datetime', + 'kvision-modules:kvision-bootstrap-spinner', + 'kvision-modules:kvision-bootstrap-upload', + 'kvision-modules:kvision-bootstrap-select', + 'kvision-modules:kvision-bootstrap-select-remote', + 'kvision-modules:kvision-bootstrap-dialog', 'kvision-modules:kvision-richtext', - 'kvision-modules:kvision-upload', 'kvision-modules:kvision-handlebars', 'kvision-modules:kvision-i18n', 'kvision-modules:kvision-chart', 'kvision-modules:kvision-datacontainer', - 'kvision-modules:kvision-dialog', + 'kvision-modules:kvision-fontawesome', 'kvision-modules:kvision-redux', 'kvision-modules:kvision-redux-kotlin', 'kvision-modules:kvision-tabulator', 'kvision-modules:kvision-moment', 'kvision-modules:kvision-pace', 'kvision-modules:kvision-remote', - 'kvision-modules:kvision-select-remote', 'kvision-modules:kvision-tabulator-remote', 'kvision-modules:kvision-server-jooby', 'kvision-modules:kvision-server-ktor', diff --git a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt index d1a4a8be..0ba694eb 100644 --- a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt @@ -30,8 +30,6 @@ import com.github.snabbdom.eventListenersModule import com.github.snabbdom.propsModule import com.github.snabbdom.styleModule import org.w3c.dom.HTMLElement -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.utils.isIE11 import kotlin.browser.document import kotlin.dom.clear @@ -44,21 +42,26 @@ external fun require(name: String): dynamic /** * Internal singleton object which initializes and configures KVision framework. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught", "LargeClass") -internal object KVManager { - private val kvisionBootstrap = try { - require("kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap - } catch (e: Throwable) { - } - private val elementResizeEvent = try { - require("element-resize-event") - } catch (e: Throwable) { - } - private val resizable = try { +@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") +object KVManager { + init { + try { + require("kvision-bootstrap-css").pl.treksoft.kvision.KVManagerBootstrapCss + } catch (e: Throwable) { + } + try { + require("kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap + } catch (e: Throwable) { + } + try { + require("kvision-fontawesome").pl.treksoft.kvision.KVManagerFontAwesome + } catch (e: Throwable) { + } + require("./css/style.css") require("jquery-resizable-dom") - } catch (e: Throwable) { } - internal val fecha = require("fecha") + + internal val fecha = require("fecha").default private val sdPatch = Snabbdom.init( arrayOf( classModule, attributesModule, propsModule, styleModule, @@ -81,28 +84,12 @@ internal object KVManager { return sdPatch(oldVNode, newVNode) } + /** + * @suppress + * Internal function. + */ @Suppress("UnsafeCastFromDynamic") - internal fun virtualize(html: String): VNode { + fun virtualize(html: String): VNode { return sdVirtualize(html) } - - @Suppress("UnsafeCastFromDynamic") - internal fun setResizeEvent(component: Component, callback: () -> Unit) { - if (!isIE11()) { - component.getElement()?.let { - elementResizeEvent(it, callback) - } - } - } - - @Suppress("UnsafeCastFromDynamic") - internal fun clearResizeEvent(component: Component) { - if (!isIE11()) { - if (component.getElement()?.asDynamic()?.__resizeTrigger__?.contentDocument != null) { - component.getElement()?.let { - elementResizeEvent.unbind(it) - } - } - } - } } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index e17d7ba9..24543b1f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -27,11 +27,9 @@ import com.github.snabbdom.h import org.w3c.dom.CustomEventInit import org.w3c.dom.DragEvent import org.w3c.dom.Node -import org.w3c.dom.events.MouseEvent import pl.treksoft.jquery.JQuery import pl.treksoft.jquery.jQuery import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.dropdown.ContextMenu import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.i18n.I18n.trans import pl.treksoft.kvision.panel.Root @@ -83,6 +81,10 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ var role: String? by refreshOnUpdate() /** + * A tabindex attribute of generated HTML element. + */ + var tabindex: Int? by refreshOnUpdate() + /** * Determines if the current widget is draggable. */ var draggable: Boolean? by refreshOnUpdate() @@ -241,6 +243,9 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component role?.let { snattrs.add("role" to it) } + tabindex?.let { + snattrs.add("tabindex" to it.toString()) + } if (draggable == true) { snattrs.add("draggable" to "true") } @@ -439,7 +444,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun enableTooltip(options: TooltipOptions = TooltipOptions()): Widget { this.tooltipOptions = options - getElementJQueryD()?.tooltip(options.copy(title = options.title?.let { translate(it) }).toJs()) + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip(options.copy(title = options.title?.let { translate(it) }).toJs()) return this } @@ -449,7 +455,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun showTooltip(): Widget { if (this.tooltipOptions != null) { - getElementJQueryD()?.tooltip("show") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("show") } return this } @@ -460,7 +467,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun hideTooltip(): Widget { if (this.tooltipOptions != null) { - getElementJQueryD()?.tooltip("hide") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("hide") } return this } @@ -471,7 +479,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun disableTooltip(): Widget { this.tooltipOptions = null - getElementJQueryD()?.tooltip("destroy") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("dispose") return this } @@ -482,7 +491,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun enablePopover(options: PopoverOptions = PopoverOptions()): Widget { this.popoverOptions = options - getElementJQueryD()?.popover( + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover( options.copy(title = options.title?.let { translate(it) }, content = options.content?.let { translate(it) }).toJs() ) @@ -495,7 +505,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun showPopover(): Widget { if (this.popoverOptions != null) { - getElementJQueryD()?.popover("show") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("show") } return this } @@ -506,7 +517,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun hidePopover(): Widget { if (this.popoverOptions != null) { - getElementJQueryD()?.popover("hide") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("hide") } return this } @@ -517,7 +529,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun disablePopover(): Widget { this.popoverOptions = null - getElementJQueryD()?.popover("destroy") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("dispose") return this } @@ -624,11 +637,13 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component internal open fun afterInsertInternal(node: VNode) { this.tooltipOptions?.let { @Suppress("UnsafeCastFromDynamic") - getElementJQueryD().tooltip(it.copy(title = it.title?.let { translate(it) }).toJs()) + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip(it.copy(title = it.title?.let { translate(it) }).toJs()) } this.popoverOptions?.let { @Suppress("UnsafeCastFromDynamic") - getElementJQueryD().popover( + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover( it.copy(title = it.title?.let { translate(it) }, content = it.content?.let { translate(it) }).toJs() ) @@ -647,10 +662,12 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component @Suppress("UnsafeCastFromDynamic") internal open fun afterDestroyInternal() { this.tooltipOptions?.let { - getElementJQueryD().tooltip("destroy") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("dispose") } this.popoverOptions?.let { - getElementJQueryD().popover("destroy") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("dispose") } } @@ -731,21 +748,6 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component } /** - * Sets context menu for the current widget. - * @param contextMenu a context menu - * @return current widget - */ - open fun setContextMenu(contextMenu: ContextMenu): Widget { - setEventListener<Widget> { - contextmenu = { e: MouseEvent -> - e.preventDefault() - contextMenu.positionMenu(e) - } - } - return this - } - - /** * @suppress * Internal function */ @@ -755,11 +757,7 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component ): Array<out Any> { val translatedLabel = translate(label) return if (icon != null) { - if (icon.startsWith("fa-")) { - arrayOf(KVManager.virtualize("<i class='fa $icon'></i>"), " $translatedLabel") - } else { - arrayOf(KVManager.virtualize("<span class='glyphicon glyphicon-$icon'></span>"), " $translatedLabel") - } + arrayOf(KVManager.virtualize("<i class='$icon'></i>"), " $translatedLabel") } else if (image != null) { arrayOf(KVManager.virtualize("<img src='$image' alt='' />"), " $translatedLabel") } else { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt index 3019fb6f..ece72189 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt @@ -30,8 +30,16 @@ import kotlin.js.Date * Input controls sizes. */ enum class InputSize(val className: String) { - LARGE("input-lg"), - SMALL("input-sm") + LARGE("form-control-lg"), + SMALL("form-control-sm") +} + +/** + * Input controls validation status. + */ +enum class ValidationStatus(val className: String) { + VALID("is-valid"), + INVALID("is-invalid") } interface FormInput : Component { @@ -47,6 +55,10 @@ interface FormInput : Component { * The name attribute of the generated HTML input element. */ var name: String? + /** + * Input control validation status. + */ + var validationStatus: ValidationStatus? /** * Makes the input element focused. @@ -78,6 +90,16 @@ interface FormControl : Component { get() = input.size set(value) { input.size = value + if (value == InputSize.SMALL) { + flabel.addCssClass("col-form-label-sm") + } else { + flabel.removeCssClass("col-form-label-sm") + } + if (value == InputSize.LARGE) { + flabel.addCssClass("col-form-label-lg") + } else { + flabel.removeCssClass("col-form-label-lg") + } } /** * The name attribute of the generated HTML input element. @@ -88,6 +110,14 @@ interface FormControl : Component { input.name = value } /** + * Input control validation status. + */ + var validationStatus: ValidationStatus? + get() = input.validationStatus + set(value) { + input.validationStatus = value + } + /** * The actual input component. */ val input: FormInput @@ -96,9 +126,9 @@ interface FormControl : Component { */ val flabel: FieldLabel /** - * Validation info component. + * Invalid feedback component. */ - val validationInfo: HelpBlock + val invalidFeedback: InvalidFeedback /** * Returns the value of the control. @@ -129,10 +159,11 @@ interface FormControl : Component { * Validator error message. */ var validatorError: String? - get() = validationInfo.content + get() = invalidFeedback.content set(value) { - validationInfo.content = value - validationInfo.visible = value != null + invalidFeedback.content = value + invalidFeedback.visible = value != null + input.validationStatus = if (value != null) ValidationStatus.INVALID else null refresh() } @@ -145,6 +176,30 @@ interface FormControl : Component { * Makes the input element blur. */ fun blur() + + /** + * Style form control element for vertical form panel. + */ + fun styleForVerticalFormPanel() { + } + + /** + * Style form control element for horizontal form panel. + */ + fun styleForHorizontalFormPanel() { + addCssClass("row") + flabel.addCssClass("col-sm-2") + flabel.addCssClass("col-form-label") + input.addCssClass("col-sm-10") + invalidFeedback.addCssClass("offset-sm-2") + invalidFeedback.addCssClass("col-sm-10") + } + + /** + * Style form control element for inline form panel. + */ + fun styleForInlineFormPanel() { + } } /** diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt index 21281556..e8fa0a42 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt @@ -28,10 +28,7 @@ import kotlinx.serialization.serializer import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.form.check.CheckBox -import pl.treksoft.kvision.form.check.Radio -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.types.KFile import kotlin.js.Date @@ -82,13 +79,14 @@ enum class FormTarget(internal val target: String) { * @param action the URL address to send data * @param enctype form encoding type * @param type form layout + * @param condensed determines if the form is condensed. * @param classes set of CSS class names * @param serializer a serializer for model type */ @Suppress("TooManyFunctions") open class FormPanel<K : Any>( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - private val type: FormType? = null, classes: Set<String> = setOf(), + private val type: FormType? = null, condensed: Boolean = false, classes: Set<String> = setOf(), serializer: KSerializer<K> ) : SimplePanel(classes) { @@ -120,6 +118,10 @@ open class FormPanel<K : Any>( * Determines if the form should have autocomplete. */ var autocomplete: Boolean? by refreshOnUpdate() + /** + * Determines if the form is condensed. + */ + var condensed by refreshOnUpdate(condensed) /** * Function returning validation message. @@ -156,7 +158,7 @@ open class FormPanel<K : Any>( * @suppress * Internal property. */ - protected val validationAlert = Tag(TAG.H5, classes = setOf("alert", "alert-danger")).apply { + protected val validationAlert = Div(classes = setOf("alert", "alert-danger")).apply { role = "alert" visible = false } @@ -173,7 +175,9 @@ open class FormPanel<K : Any>( val cl = super.getSnClass().toMutableList() if (type != null) { cl.add(type.formType to true) + if (type == FormType.HORIZONTAL) cl.add("container-fluid" to true) } + if (condensed) cl.add("kv-form-condensed" to true) return cl } @@ -208,16 +212,10 @@ open class FormPanel<K : Any>( validatorMessage: ((C) -> String?)? = null, validator: ((C) -> Boolean?)? = null ): FormPanel<K> { - if (type == FormType.HORIZONTAL) { - if (control is CheckBox || control is Radio) { - control.addCssClass("col-sm-offset-2") - control.addCssClass("col-sm-10") - } else { - control.flabel.addCssClass("col-sm-2") - control.input.addSurroundingCssClass("col-sm-10") - control.validationInfo.addCssClass("col-sm-offset-2") - control.validationInfo.addCssClass("col-sm-10") - } + when (type) { + FormType.INLINE -> control.styleForInlineFormPanel() + FormType.HORIZONTAL -> control.styleForHorizontalFormPanel() + else -> control.styleForVerticalFormPanel() } super.add(control) form.addInternal(key, control, required, requiredMessage, validatorMessage, validator) @@ -399,10 +397,10 @@ open class FormPanel<K : Any>( */ inline fun <reified K : Any> Container.formPanel( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - type: FormType? = null, classes: Set<String> = setOf(), + type: FormType? = null, condensed: Boolean = false, classes: Set<String> = setOf(), noinline init: (FormPanel<K>.() -> Unit)? = null ): FormPanel<K> { - val formPanel = create<K>(method, action, enctype, type, classes) + val formPanel = create<K>(method, action, enctype, type, condensed, classes) init?.invoke(formPanel) this.add(formPanel) return formPanel @@ -411,10 +409,10 @@ open class FormPanel<K : Any>( @UseExperimental(ImplicitReflectionSerializer::class) inline fun <reified K : Any> create( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - type: FormType? = null, classes: Set<String> = setOf(), + type: FormType? = null, condensed: Boolean = false, classes: Set<String> = setOf(), noinline init: (FormPanel<K>.() -> Unit)? = null ): FormPanel<K> { - val formPanel = FormPanel(method, action, enctype, type, classes, K::class.serializer()) + val formPanel = FormPanel(method, action, enctype, type, condensed, classes, K::class.serializer()) init?.invoke(formPanel) return formPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt b/src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt index 9ec3d8ae..0362d03a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt @@ -25,13 +25,13 @@ import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag /** - * Helper class for Bootstrap help block element. + * Helper class for Bootstrap help text element. * * @constructor * @param content the text of the label * @param rich determines if [content] can contain HTML code */ -open class HelpBlock(content: String? = null, rich: Boolean = false) : Tag( - TAG.SPAN, content, rich, - classes = setOf("help-block", "small") +open class HelpText(content: String? = null, rich: Boolean = false) : Tag( + TAG.SMALL, content, rich, + classes = setOf("form-text", "text-muted") ) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt b/src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt index 827c90fd..dad68239 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt @@ -19,33 +19,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package pl.treksoft.kvision.html +package pl.treksoft.kvision.form -import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag /** - * Simple label component rendered as *span*. + * Helper class for Bootstrap invalid feedback element. * * @constructor - * @param content label text + * @param content the text of the label * @param rich determines if [content] can contain HTML code */ -@Deprecated("Use Span class instead.") -open class Label(content: String? = null, rich: Boolean = false) : Span(content, rich) { - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - @Deprecated("User Span.Companion.span function instead.") - @Suppress("DEPRECATION") - fun Container.label( - content: String? = null, rich: Boolean = false, init: (Label.() -> Unit)? = null - ): Label { - val label = Label(content, rich).apply { init?.invoke(this) } - this.add(label) - return label - } - } -} +open class InvalidFeedback(content: String? = null, rich: Boolean = false) : Tag( + TAG.DIV, content, rich, + classes = setOf("invalid-feedback") +) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt index 730488eb..cb962850 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.BoolFormControl import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -35,12 +35,11 @@ import pl.treksoft.kvision.utils.SnOn * Checkbox style options. */ enum class CheckBoxStyle(internal val className: String) { - DEFAULT("checkbox-default"), - PRIMARY("checkbox-primary"), - SUCCESS("checkbox-success"), - INFO("checkbox-info"), - WARNING("checkbox-warning"), - DANGER("checkbox-danger"), + PRIMARY("abc-checkbox-primary"), + SUCCESS("abc-checkbox-success"), + INFO("abc-checkbox-info"), + WARNING("abc-checkbox-warning"), + DANGER("abc-checkbox-danger"), } /** @@ -55,7 +54,7 @@ enum class CheckBoxStyle(internal val className: String) { open class CheckBox( value: Boolean = false, name: String? = null, label: String? = null, rich: Boolean = false -) : SimplePanel(setOf("checkbox")), BoolFormControl { +) : SimplePanel(setOf("form-check", "abc-checkbox")), BoolFormControl { /** * The selection state of the checkbox. @@ -106,22 +105,19 @@ open class CheckBox( var inline by refreshOnUpdate(false) private val idc = "kv_form_checkbox_$counter" - final override val input: CheckBoxInput = CheckBoxInput( - value, - setOf("styled") - ).apply { + final override val input: CheckBoxInput = CheckBoxInput(value, classes = setOf("form-check-input")).apply { this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf("form-check-label")) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) this.addInternal(flabel) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } @@ -147,13 +143,13 @@ open class CheckBox( cl.add(it.className to true) } if (circled) { - cl.add("checkbox-circle" to true) + cl.add("abc-checkbox-circle" to true) } if (inline) { - cl.add("checkbox-inline" to true) + cl.add("form-check-inline" to true) } if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } @@ -178,6 +174,21 @@ open class CheckBox( input.blur() } + override fun styleForHorizontalFormPanel() { + addCssClass("form-group") + addSurroundingCssClass("row") + addCssClass("offset-sm-2") + addCssClass("col-sm-10") + } + + override fun styleForInlineFormPanel() { + addCssClass("form-group") + } + + override fun styleForVerticalFormPanel() { + addCssClass("form-group") + } + companion object { internal var counter = 0 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 a486b82e..f93fd436 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt @@ -28,6 +28,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus /** * Type of the check input control (checkbox or radio). @@ -94,6 +95,10 @@ abstract class CheckInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() override fun render(): VNode { return render("input") @@ -101,6 +106,9 @@ abstract class CheckInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt index 29b3cb35..e9551196 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.BoolFormControl import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -35,12 +35,11 @@ import pl.treksoft.kvision.utils.SnOn * Radio style options. */ enum class RadioStyle(internal val className: String) { - DEFAULT("radio-default"), - PRIMARY("radio-primary"), - SUCCESS("radio-success"), - INFO("radio-info"), - WARNING("radio-warning"), - DANGER("radio-danger"), + PRIMARY("abc-radio-primary"), + SUCCESS("abc-radio-success"), + INFO("abc-radio-info"), + WARNING("abc-radio-warning"), + DANGER("abc-radio-danger"), } /** @@ -56,7 +55,7 @@ enum class RadioStyle(internal val className: String) { open class Radio( value: Boolean = false, extraValue: String? = null, name: String? = null, label: String? = null, rich: Boolean = false -) : SimplePanel(), BoolFormControl { +) : SimplePanel(classes = setOf("form-check")), BoolFormControl { /** * The selection state of the radio button. @@ -115,20 +114,20 @@ open class Radio( var inline by refreshOnUpdate(false) private val idc = "kv_form_radio_$counter" - final override val input: RadioInput = RadioInput(value).apply { + final override val input: RadioInput = RadioInput(value, classes = setOf("form-check-input")).apply { this.id = idc this.extraValue = extraValue this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf("form-check-label")) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this.eventTarget ?: this this.addInternal(input) this.addInternal(flabel) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } @@ -151,25 +150,21 @@ open class Radio( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (!squared) { - cl.add("radio" to true) + cl.add("abc-radio" to true) style?.let { cl.add(it.className to true) } - if (inline) { - cl.add("radio-inline" to true) - } } else { - cl.add("checkbox" to true) - cl.add("kv-radio-checkbox" to true) + cl.add("abc-checkbox" to true) style?.let { cl.add(it.className.replace("radio", "checkbox") to true) } - if (inline) { - cl.add("checkbox-inline" to true) - } + } + if (inline) { + cl.add("form-check-inline" to true) } if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } @@ -194,6 +189,21 @@ open class Radio( input.blur() } + override fun styleForHorizontalFormPanel() { + addCssClass("form-group") + addSurroundingCssClass("row") + addCssClass("offset-sm-2") + addCssClass("col-sm-10") + } + + override fun styleForInlineFormPanel() { + addCssClass("form-group") + } + + override fun styleForVerticalFormPanel() { + addCssClass("form-group") + } + companion object { internal var counter = 0 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 6ac58bb7..14b426a3 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt @@ -25,9 +25,10 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.panel.SimplePanel /** @@ -97,13 +98,33 @@ open class RadioGroup( set(value) { setSizeToChildren(value) } + override var validationStatus + get() = getValidationStatusFromChildren() + set(value) { + setValidationStatusToChildren(value) + } + override var validatorError: String? + get() = super.validatorError + set(value) { + super.validatorError = value + if (value != null) { + container.addCssClass("is-invalid") + } else { + container.removeCssClass("is-invalid") + } + } private val idc = "kv_form_radiogroup_$counter" final override val input = RadioInput() final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + internal val container = SimplePanel(setOf("kv-radiogroup-container")) init { + this.addInternal(flabel) + this.addInternal(container) + this.addInternal(invalidFeedback) setChildrenFromOptions() setValueToChildren(value) setNameToChildren(name) @@ -113,7 +134,7 @@ open class RadioGroup( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } if (inline) { cl.add("kv-radiogroup-inline" to true) @@ -124,7 +145,7 @@ open class RadioGroup( } private fun setValueToChildren(value: String?) { - val radios = getChildren().filterIsInstance<Radio>() + val radios = container.getChildren().filterIsInstance<Radio>() radios.forEach { it.value = false } radios.find { it.extraValue == value @@ -132,34 +153,42 @@ open class RadioGroup( } private fun getDisabledFromChildren(): Boolean { - return getChildren().filterIsInstance<Radio>().firstOrNull()?.disabled ?: false + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.disabled ?: false } private fun setDisabledToChildren(disabled: Boolean) { - getChildren().filterIsInstance<Radio>().forEach { it.disabled = disabled } + container.getChildren().filterIsInstance<Radio>().forEach { it.disabled = disabled } } private fun getNameFromChildren(): String? { - return getChildren().filterIsInstance<Radio>().firstOrNull()?.name ?: this.idc + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.name ?: this.idc } private fun setNameToChildren(name: String?) { val tname = name ?: this.idc - getChildren().filterIsInstance<Radio>().forEach { it.name = tname } + container.getChildren().filterIsInstance<Radio>().forEach { it.name = tname } } private fun getSizeFromChildren(): InputSize? { - return getChildren().filterIsInstance<Radio>().firstOrNull()?.size + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.size } private fun setSizeToChildren(size: InputSize?) { - getChildren().filterIsInstance<Radio>().forEach { it.size = size } + container.getChildren().filterIsInstance<Radio>().forEach { it.size = size } + super.size = size + } + + private fun getValidationStatusFromChildren(): ValidationStatus? { + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.validationStatus + } + + private fun setValidationStatusToChildren(validationStatus: ValidationStatus?) { + container.getChildren().filterIsInstance<Radio>().forEach { it.validationStatus = validationStatus } } private fun setChildrenFromOptions() { val currentName = this.name - super.removeAll() - this.addInternal(flabel) + container.removeAll() options?.let { val tname = currentName ?: this.idc val tinline = this.inline @@ -175,17 +204,25 @@ open class RadioGroup( } } } - super.addAll(c) + container.addAll(c) } - this.addInternal(validationInfo) } override fun focus() { - getChildren().filterIsInstance<Radio>().firstOrNull()?.focus() + container.getChildren().filterIsInstance<Radio>().firstOrNull()?.focus() } override fun blur() { - getChildren().filterIsInstance<Radio>().firstOrNull()?.blur() + container.getChildren().filterIsInstance<Radio>().firstOrNull()?.blur() + } + + override fun styleForHorizontalFormPanel() { + addCssClass("row") + flabel.addCssClass("col-sm-2") + flabel.addCssClass("col-form-label") + container.addCssClass("col-sm-10") + invalidFeedback.addCssClass("offset-sm-2") + invalidFeedback.addCssClass("col-sm-10") } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt index fca681f6..d4301709 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt @@ -26,6 +26,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.panel.SimplePanel /** @@ -75,6 +76,11 @@ open class RadioGroupInput( set(value) { setSizeToChildren(value) } + override var validationStatus + get() = getValidationStatusFromChildren() + set(value) { + setValidationStatusToChildren(value) + } private val idc = "kv_form_radiogroup_$counter" @@ -128,6 +134,14 @@ open class RadioGroupInput( getChildren().filterIsInstance<Radio>().forEach { it.size = size } } + private fun getValidationStatusFromChildren(): ValidationStatus? { + return getChildren().filterIsInstance<Radio>().firstOrNull()?.validationStatus + } + + private fun setValidationStatusToChildren(validationStatus: ValidationStatus?) { + getChildren().filterIsInstance<Radio>().forEach { it.validationStatus = validationStatus } + } + private fun setChildrenFromOptions() { val currentName = this.name super.removeAll() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt index 4d278ad2..bef14bfa 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -117,21 +117,21 @@ open class SimpleSelect( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt index b2ba1d43..31d32052 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.SimplePanel @@ -83,6 +84,10 @@ open class SimpleSelectInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() init { setChildrenFromOptions() @@ -129,6 +134,9 @@ open class SimpleSelectInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt index 7c23615a..091278fc 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt @@ -24,7 +24,7 @@ package pl.treksoft.kvision.form.text import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -114,7 +114,7 @@ abstract class AbstractText(label: String? = null, rich: Boolean = false) : protected val idc = "kv_form_text_$counter" abstract override val input: AbstractTextInput final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { this.addInternal(flabel) @@ -128,7 +128,7 @@ abstract class AbstractText(label: String? = null, rich: Boolean = false) : override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } 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 e7ecba8a..192b33c8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus /** * Base class for basic text components. @@ -87,9 +88,16 @@ abstract class AbstractTextInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt index 7e4127f5..f493b06e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt @@ -64,7 +64,7 @@ open class Text( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt index d5058583..ccf17892 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt @@ -73,7 +73,7 @@ open class TextArea( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt index 0b6b43e5..aaa0f735 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt @@ -33,13 +33,23 @@ import pl.treksoft.kvision.core.Widget * Button styles. */ enum class ButtonStyle(val className: String) { - DEFAULT("btn-default"), PRIMARY("btn-primary"), + SECONDARY("btn-secondary"), SUCCESS("btn-success"), - INFO("btn-info"), - WARNING("btn-warning"), DANGER("btn-danger"), - LINK("btn-link") + WARNING("btn-warning"), + INFO("btn-info"), + LIGHT("btn-light"), + DARK("btn-dark"), + LINK("btn-link"), + OUTLINEPRIMARY("btn-outline-primary"), + OUTLINESECONDARY("btn-outline-secondary"), + OUTLINESUCCESS("btn-outline-success"), + OUTLINEDANGER("btn-outline-danger"), + OUTLINEWARNING("btn-outline-warning"), + OUTLINEINFO("btn-outline-info"), + OUTLINELIGHT("btn-outline-light"), + OUTLINEDARK("btn-outline-dark") } /** @@ -47,8 +57,7 @@ enum class ButtonStyle(val className: String) { */ enum class ButtonSize(internal val className: String) { LARGE("btn-lg"), - SMALL("btn-sm"), - XSMALL("btn-xs") + SMALL("btn-sm") } /** @@ -71,7 +80,7 @@ enum class ButtonType(internal val buttonType: String) { * @param classes a set of CSS class names */ open class Button( - text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.DEFAULT, type: ButtonType = ButtonType.BUTTON, + text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.PRIMARY, type: ButtonType = ButtonType.BUTTON, disabled: Boolean = false, classes: Set<String> = setOf() ) : Widget(classes) { @@ -123,14 +132,16 @@ open class Button( if (block) { cl.add("btn-block" to true) } - if (disabled) { - cl.add("disabled" to true) - } return cl } override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + ("type" to type.buttonType) + val snattrs = super.getSnAttrs().toMutableList() + snattrs.add("type" to type.buttonType) + if (disabled) { + snattrs.add("disabled" to "disabled") + } + return snattrs } /** @@ -154,7 +165,7 @@ open class Button( fun Container.button( text: String, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, + style: ButtonStyle = ButtonStyle.PRIMARY, type: ButtonType = ButtonType.BUTTON, disabled: Boolean = false, classes: Set<String> = setOf(), diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt b/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt index 7e10c10f..a9fb03db 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt @@ -39,13 +39,7 @@ open class Icon(icon: String) : Tag(TAG.SPAN) { override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - if (icon.startsWith("fa-")) { - cl.add("fa" to true) - cl.add(icon to true) - } else { - cl.add("glyphicon" to true) - cl.add("glyphicon-$icon" to true) - } + icon.split(" ").forEach { cl.add(it to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt index 4d373270..81873088 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt @@ -32,8 +32,8 @@ import pl.treksoft.kvision.core.Widget * Image shapes. */ enum class ImageShape(internal val className: String) { - ROUNDED("img-rounded"), - CIRCLE("img-circle"), + ROUNDED("rounded"), + CIRCLE("rounded-circle"), THUMBNAIL("img-thumbnail") } @@ -89,7 +89,7 @@ open class Image( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (responsive) { - cl.add("img-responsive" to true) + cl.add("img-fluid" to true) } if (centered) { cl.add("center-block" to true) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt index 5fc613e2..63104248 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt @@ -26,7 +26,6 @@ import org.w3c.dom.events.MouseEvent import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.dropdown.DropDown import pl.treksoft.kvision.panel.SimplePanel /** @@ -99,37 +98,5 @@ open class Link( this.add(link) return link } - - /** - * DSL builder extension function for a disabled link in a dropdown list. - * - * It takes the same parameters as the constructor of the built component. - */ - fun ListTag.linkDisabled( - label: String, icon: String? = null, image: ResString? = null, - classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null - ): Link { - val link = Link(label, null, icon, image, classes).apply { init?.invoke(this) } - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(link) - this.add(tag) - return link - } - - /** - * DSL builder extension function for a disabled link in a dropdown list. - * - * It takes the same parameters as the constructor of the built component. - */ - fun DropDown.linkDisabled( - label: String, icon: String? = null, image: ResString? = null, - classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null - ): Link { - val link = Link(label, "javascript:void(0)", icon, image, classes).apply { init?.invoke(this) } - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(link) - this.add(tag) - return link - } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/List.kt b/src/main/kotlin/pl/treksoft/kvision/html/List.kt index 5fb489da..cf3f8be6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/List.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/List.kt @@ -27,7 +27,6 @@ import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.dropdown.DropDown import pl.treksoft.kvision.panel.SimplePanel /** @@ -98,14 +97,14 @@ open class ListTag( val childrenElements = children.filter { it.visible } val res = when (type) { ListType.UL, ListType.OL, ListType.UNSTYLED, ListType.INLINE -> childrenElements.map { v -> - if (v is Tag && v.type == TAG.LI || v is DropDown && v.forNavbar) { + if (v is Tag && v.type == TAG.LI /*|| v is DropDown && v.forNavbar*/) { v.renderVNode() } else { h("li", arrayOf(v.renderVNode())) } } ListType.DL, ListType.DL_HORIZ -> childrenElements.mapIndexed { index, v -> - if (v is Tag && v.type == TAG.LI || v is DropDown && v.forNavbar) { + if (v is Tag && v.type == TAG.LI /*|| v is DropDown && v.forNavbar*/) { v.renderVNode() } else { h(if (index % 2 == 0) "dt" else "dd", arrayOf(v.renderVNode())) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt index 512ca8b8..a5e855ae 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt @@ -73,6 +73,12 @@ enum class TAG(internal val tagName: String) { BR("br"), CAPTION("caption"), + FIGURE("figure"), + FIGCAPTION("figcaption"), + PICTURE("figcaption"), + SOURCE("figcaption"), + + TABLE("table"), THEAD("thead"), TH("th"), TBODY("tbody"), diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt index 2d9dcc46..e0c70ac4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt @@ -27,8 +27,7 @@ import org.w3c.dom.HTMLElement import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Style -import pl.treksoft.kvision.dropdown.ContextMenu -import pl.treksoft.kvision.modal.Modal +import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.utils.snClasses import pl.treksoft.kvision.utils.snOpt @@ -52,7 +51,7 @@ class Root( private val fixed: Boolean = false, init: (Root.() -> Unit)? = null ) : SimplePanel() { - private val contextMenus: MutableList<ContextMenu> = mutableListOf() + private val contextMenus: MutableList<Widget> = mutableListOf() private var rootVnode: VNode = renderVNode() internal var renderDisabled = false @@ -71,7 +70,7 @@ class Root( } roots.add(this) if (isFirstRoot) { - Modal.modals.forEach { it.parent = this } + modals.forEach { it.parent = this } } @Suppress("LeakingThis") init?.invoke(this) @@ -87,7 +86,7 @@ class Root( } } - internal fun addContextMenu(contextMenu: ContextMenu) { + fun addContextMenu(contextMenu: Widget) { contextMenus.add(contextMenu) contextMenu.parent = this this.setInternalEventListener<Root> { @@ -114,7 +113,7 @@ class Root( private fun modalsVNodes(): Array<VNode> { return if (isFirstRoot) { - Modal.modals.filter { it.visible }.map { it.renderVNode() }.toTypedArray() + modals.filter { it.visible }.map { it.renderVNode() }.toTypedArray() } else { arrayOf() } @@ -150,12 +149,13 @@ class Root( roots.remove(this) if (isFirstRoot) { Style.styles.clear() - Modal.modals.clear() + modals.clear() } } companion object { internal var counter = 0 + private val modals: MutableList<Widget> = mutableListOf() /** * @suppress internal function @@ -167,18 +167,26 @@ class Root( internal val roots: MutableList<Root> = mutableListOf() - internal fun getFirstRoot(): Root? { + fun getFirstRoot(): Root? { return if (roots.isNotEmpty()) roots[0] else null } - internal fun getLastRoot(): Root? { + fun getLastRoot(): Root? { return if (roots.isNotEmpty()) roots[roots.size - 1] else null } + + fun addModal(modal: Widget) { + modals.add(modal) + } + + fun removeModal(modal: Widget) { + modals.remove(modal) + } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt index 2f702fad..91eeda80 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt @@ -35,7 +35,7 @@ import pl.treksoft.kvision.core.Widget */ open class SimplePanel(classes: Set<String> = setOf(), init: (SimplePanel.() -> Unit)? = null) : Widget(classes), Container { - internal val children: MutableList<Component> = mutableListOf() + protected val children: MutableList<Component> = mutableListOf() init { @Suppress("LeakingThis") @@ -94,7 +94,7 @@ open class SimplePanel(classes: Set<String> = setOf(), init: (SimplePanel.() -> } override fun getChildren(): List<Component> { - return ArrayList(children) + return children } override fun dispose() { diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt index 0a79c9f9..44646897 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt @@ -64,6 +64,22 @@ open class Cell( this.add(cell) return cell } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Row.thcell( + content: String? = null, + rich: Boolean = false, + align: Align? = null, + classes: Set<String> = setOf(), init: (HeaderCell.() -> Unit)? = null + ): HeaderCell { + val headerCell = HeaderCell(content, rich, align, Scope.ROW, classes, init) + this.add(headerCell) + return headerCell + } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt index b70845d6..14527f0f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt @@ -25,6 +25,11 @@ import pl.treksoft.kvision.html.Align import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +enum class Scope(internal val scope: String) { + ROW("row"), + COL("col") +} + /** * HTML table header cell component. * @@ -39,11 +44,16 @@ open class HeaderCell( content: String? = null, rich: Boolean = false, align: Align? = null, + scope: Scope? = null, classes: Set<String> = setOf(), init: (HeaderCell.() -> Unit)? = null ) : Tag(TAG.TH, content, rich, align, classes) { init { + scope?.let { + @Suppress("LeakingThis") + setAttribute("scope", it.scope) + } @Suppress("LeakingThis") init?.invoke(this) } @@ -58,9 +68,10 @@ open class HeaderCell( content: String? = null, rich: Boolean = false, align: Align? = null, + scope: Scope? = null, classes: Set<String> = setOf(), init: (HeaderCell.() -> Unit)? = null ): HeaderCell { - val cell = HeaderCell(content, rich, align, classes, init) + val cell = HeaderCell(content, rich, align, scope, classes, init) this.add(cell) return cell } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt index 11ed52fc..6d7c9b6e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt @@ -38,8 +38,29 @@ import pl.treksoft.kvision.utils.snOpt enum class TableType(val type: String) { STRIPED("table-striped"), BORDERED("table-bordered"), + BORDERLESS("table-borderless"), HOVER("table-hover"), - CONDENSED("table-condensed") + SMALL("table-sm"), + DARK("table-dark") +} + +/** + * HTML table responsive types. + */ +enum class ResponsiveType(val type: String) { + RESPONSIVE("table-responsive"), + RESPONSIVESM("table-responsive-sm"), + RESPONSIVEMD("table-responsive-md"), + RESPONSIVELG("table-responsive-lg"), + RESPONSIVEXL("table-responsive-xl") +} + +/** + * HTML table header types. + */ +enum class TheadType(internal val type: String) { + DARK("thead-dark"), + LIGHT("thead-light") } /** @@ -56,8 +77,8 @@ enum class TableType(val type: String) { @Suppress("TooManyFunctions") open class Table( headerNames: List<String>? = null, - types: Set<TableType> = setOf(), caption: String? = null, responsive: Boolean = false, - classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null + types: Set<TableType> = setOf(), caption: String? = null, responsiveType: ResponsiveType? = null, + theadType: TheadType? = null, classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null ) : SimplePanel(classes + "table") { /** @@ -75,10 +96,13 @@ open class Table( /** * Determines if the table is responsive. */ - var responsive by refreshOnUpdate(responsive) + var responsiveType by refreshOnUpdate(responsiveType) private val theadRow = Tag(TAG.TR) - private val thead = Tag(TAG.THEAD).add(theadRow) + private val thead = Tag(TAG.THEAD).apply { + if (theadType != null) addCssClass(theadType.type) + add(theadRow) + } private val tbody = Tag(TAG.TBODY) init { @@ -94,7 +118,7 @@ open class Table( private fun refreshHeaders() { theadRow.removeAll() headerNames?.forEach { - theadRow.add(HeaderCell(it)) + theadRow.add(HeaderCell(it, scope = Scope.COL)) } } @@ -128,9 +152,9 @@ open class Table( } override fun render(): VNode { - return if (responsive) { + return if (responsiveType != null) { val opt = snOpt { - `class` = snClasses(listOf("table-responsive" to true)) + `class` = snClasses(listOf(responsiveType!!.type to true)) } h("div", opt, arrayOf(render("table", childrenVNodes()))) } else { @@ -185,11 +209,11 @@ open class Table( */ fun Container.table( headerNames: List<String>? = null, - types: Set<TableType> = setOf(), caption: String? = null, responsive: Boolean = false, - classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null + types: Set<TableType> = setOf(), caption: String? = null, responsiveType: ResponsiveType? = null, + theadType: TheadType? = null, classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null ): Table { val table = - Table(headerNames, types, caption, responsive, classes, init) + Table(headerNames, types, caption, responsiveType, theadType, classes, init) this.add(table) return table } diff --git a/src/main/resources/css/style.css b/src/main/resources/css/style.css new file mode 100644 index 00000000..fccaeb2c --- /dev/null +++ b/src/main/resources/css/style.css @@ -0,0 +1,377 @@ +.splitpanel-vertical { + display: flex; + flex-direction: row; + overflow: auto; +} + +.splitpanel-vertical > *:first-child { + max-width: calc(100% - 9px); +} + +.splitpanel-vertical > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-vertical > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + +.splitpanel-horizontal { + display: flex; + flex-direction: column; + overflow: auto; +} + +.splitpanel-horizontal > *:first-child { + max-height: calc(100% - 9px); +} + +.splitpanel-horizontal > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-horizontal > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + +.splitter-vertical { + flex: 0 0 auto; + width: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAhCAQAAABOpSL+AAAAIklEQVR4AWMwbb/PdR+JZDD9f1/oPhI5sgVGBSruc9xHIgGdSQqqQJGkRgAAAABJRU5ErkJggg==') center center no-repeat #cecece; + cursor: col-resize; +} + +.splitter-horizontal { + flex: 0 0 auto; + height: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAICAQAAADdTl4aAAAAIElEQVQoz2MwrTD9TxFsZ7jPcV+IIsjFQAUw6hFqegQA+xzRHT2p7pEAAAAASUVORK5CYII=') center center no-repeat #cecece; + cursor: row-resize; +} + +.trix-control { + overflow-y: auto; +} + +trix-toolbar .trix-button-group { + margin-bottom: 3px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select { + border: 1px solid #ccc; + border-radius: 4px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input:focus, .tabulator-row .tabulator-cell.tabulator-editing select:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.tabulator-row .tabulator-cell.tabulator-editing { + border-right: 1px solid #1d68cd !important; + padding: 2px !important; +} + +.input-group.date.is-invalid~.invalid-feedback { + display: block; +} + +.input-group.date { + padding-left: 0px; + padding-right: 0px; +} + +.bootstrap-select .dropdown-toggle.btn-default:focus { + outline: none !important; +} + +.bootstrap-select .dropdown-toggle::after { + margin-left: -1em !important; +} + +.form-inline .bootstrap-select .form-control { + min-width: 200px; +} + +.kv-spinner-btn-none .input-group-btn-vertical { + display: none; +} + +.kv-spinner-btn-none .form-control { + border-radius: 4px !important; +} + +.kv-spinner > span { + display: inline-block; + width: 100%; +} + +.input-group.kv-spinner { + padding-left: 0px; + padding-right: 0px; +} + +.kv-spinner.is-invalid~.invalid-feedback { + display: block; +} + +.kv-radiogroup-inline label.control-label { + vertical-align: top; + margin-right: .75rem; + margin-bottom: 0px; +} +.row.kv-radiogroup-inline label.control-label { + margin-right: 0px; +} + +.row.kv-radiogroup-inline .kv-radiogroup-container, .row.kv-radiogroup .kv-radiogroup-container { + margin-left: -15px; +} + +.kv-radiogroup-inline .kv-radiogroup-container { + display: inline-flex; +} + +.kv-radiogroup-container.is-invalid~.invalid-feedback { + display: block; +} + +.form-check { + padding-left: 0.5rem; +} + +.form-check-input.form-control-sm, .form-check-input.form-control-lg { + height: inherit; +} + +.form-check-inline { + margin-left: 3px; +} + +.form-check-inline.form-check { + padding-left: 0px; +} + +.form-horizontal.container-fluid { + width: inherit; +} + +.form-inline .form-group { + margin-right: 6px; +} + +.form-inline .form-group .control-label { + margin-right: 6px; +} + +.form-inline .form-check.form-group { + margin-left: 6px; +} + +.kv-form-condensed .form-group { + margin-bottom: 0.5rem; +} + +.kv-window.modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0,0,0,.5); + box-shadow: 0 5px 15px rgba(0,0,0,.5); + border-radius: 0px; +} + +.kv-window .modal-header { + height: 40px; + padding: 5px 15px 5px 15px; + align-items: center; +} + +.kv-window .modal-header button.close { + width: 24px; + height: 24px; + margin: 0px; + padding: 0px; +} + +.kv-window .modal-header .modal-title { + white-space: nowrap; +} + +.kv-window .modal-header .window-icon { + margin-right: 6px; +} + +.kv-window .kv-window-icons-container { + display: flex; +} + +.kv-preview-thumb .btn, .kv-zoom-actions .btn, .file-zoom-dialog .floating-buttons .btn { + padding: 5px 8px; +} + +.file-drop-zone.clickable:hover { + border: 1px dashed #999; +} + +.file-drop-zone.clickable:focus { + border: 1px solid #5acde2; +} + +.nav.tabs-top { + flex-wrap: nowrap; +} + +ul.tabs-top { + overflow-x: auto; + overflow-y: hidden; + display: flex; +} + +ul.tabs-top > li { + float:none; + flex-shrink: 0; +} + +.kv-tab-close { + margin-left: 10px; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: 0.2; +} + +.kv-tab-close:hover, .kv-tab-close:focus { + cursor: pointer; + filter: alpha(opacity=50); + opacity: 0.5; +} + +select.form-control, .tabulator-row .tabulator-cell.tabulator-editing select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent none no-repeat; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAKCAYAAABblxXYAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wUKFyIn4IjqJgAAAENJREFUKM/l0LERACEQQlGsiTa2px1aokGugNNAx8wfMy8AeLoBALYjaTqoKkga2+gKPgF/2Q7JkEx359oftu+C7/UBCUIcVQz0PvcAAAAASUVORK5CYII='); + background-position: right center; + cursor: pointer; +} + +.abc-checkbox input[type="checkbox"]:checked+label::after, +.abc-checkbox input[type="radio"]:checked+label::after { + font-family: "Font Awesome 5 Pro", "Font Awesome 5 Free"; + content: "\f00c"; + font-weight: 900; +} + +.abc-checkbox label::before { + top: 0px; +} +.abc-checkbox label::after { + top: 0px; +} + +.abc-radio label::before { + top: 0px; +} + +.abc-radio label::after { + top: 3px; +} + +.abc-checkbox.form-check-inline label::before { + top: 2px; +} + +.abc-checkbox.form-check-inline label::after { + top: 2px; +} + +.abc-radio.form-check-inline label::before { + top: 2px; +} + +.abc-radio.form-check-inline label::after { + top: 5px; +} + +.abc-checkbox label.col-form-label-lg::before { + top: 10px; +} +.abc-checkbox label.col-form-label-lg::after { + top: 10px; +} + +.abc-radio label.col-form-label-lg::before { + top: 10px; +} + +.abc-radio label.col-form-label-lg::after { + top: 13px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::after { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::after { + top: 18px; +} + +/*! + * bootstrap-vertical-tabs - v1.2.2 + * https://dbtek.github.io/bootstrap-vertical-tabs + * 2016-12-02 + * Copyright (c) 2016 İsmail Demirbilek + * License: MIT + */ +.nav-tabs.tabs-left, .nav-tabs.tabs-right { + border-bottom: none; + padding-top: 2px; +} +.nav-tabs.tabs-left { + border-right: 1px solid #dee2e6; +} +.nav-tabs.tabs-right { + border-left: 1px solid #dee2e6; +} +.nav-tabs.tabs-left>li.nav-item, .nav-tabs.tabs-right>li.nav-item { + float: none; + margin-bottom: 2px; +} +.nav-tabs.tabs-left>li.nav-item { + margin-right: -1px; +} +.nav-tabs.tabs-right>li.nav-item { + margin-left: -1px; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:focus { + border-bottom-color: #dee2e6; + border-right-color: transparent; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:focus { + border-bottom: 1px solid #dee2e6; + border-left-color: transparent; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link { + border-radius: 4px 0 0 4px; + margin-right: 0; + display:block; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link { + border-radius: 0 4px 4px 0; + margin-right: 0; +} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.kt index c7c4ede5..785f9a2c 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.kt @@ -21,23 +21,23 @@ */ package test.pl.treksoft.kvision.form -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.HelpText import pl.treksoft.kvision.panel.Root import test.pl.treksoft.kvision.DomSpec import kotlin.browser.document import kotlin.test.Test -class HelpBlockSpec : DomSpec { +class HelpTextSpec : DomSpec { @Test fun render() { run { val root = Root("test", fixed = true) - val fl = HelpBlock("Form Error") + val fl = HelpText("Form Error") root.add(fl) val element = document.getElementById("test") assertEqualsHtml( - "<span class=\"help-block small\">Form Error</span>", + "<small class=\"form-text text-muted\">Form Error</small>", element?.innerHTML, "Should render correct help block" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/check/CheckBoxSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/check/CheckBoxSpec.kt index 16da0c70..2c329ffa 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/check/CheckBoxSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/check/CheckBoxSpec.kt @@ -45,7 +45,7 @@ class CheckBoxSpec : DomSpec { val element = document.getElementById("test") val id = ci.input.id assertEqualsHtml( - "<div class=\"checkbox checkbox-danger checkbox-circle checkbox-inline\"><input class=\"styled\" id=\"$id\" type=\"checkbox\" checked=\"checked\" name=\"name\" disabled=\"disabled\"><label for=\"$id\">Label</label></div>", + "<div class=\"form-check abc-checkbox abc-checkbox-danger abc-checkbox-circle form-check-inline\"><input class=\"form-check-input\" id=\"$id\" type=\"checkbox\" checked=\"checked\" name=\"name\" disabled=\"disabled\"><label class=\"form-check-label\" for=\"$id\">Label</label></div>", element?.innerHTML, "Should render correct checkbox form control" ) @@ -53,7 +53,7 @@ class CheckBoxSpec : DomSpec { ci.circled = false ci.inline = false assertEqualsHtml( - "<div class=\"checkbox checkbox-info\"><input class=\"styled\" id=\"$id\" type=\"checkbox\" checked=\"checked\" name=\"name\" disabled=\"disabled\"><label for=\"$id\">Label</label></div>", + "<div class=\"form-check abc-checkbox abc-checkbox-info\"><input class=\"form-check-input\" id=\"$id\" type=\"checkbox\" checked=\"checked\" name=\"name\" disabled=\"disabled\"><label class=\"form-check-label\" for=\"$id\">Label</label></div>", element?.innerHTML, "Should render correct checkbox form control" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupInputSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupInputSpec.kt index 55788c84..020ad529 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupInputSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupInputSpec.kt @@ -44,7 +44,7 @@ class RadioGroupInputSpec : DomSpec { val rid1 = ci.getChildren().filterIsInstance<Radio>().first().input.id val rid2 = ci.getChildren().filterIsInstance<Radio>().last().input.id assertEqualsHtml( - "<div class=\"form-group kv-radiogroup-inline\"><div class=\"radio\"><input id=\"$rid1\" type=\"radio\" name=\"$name\" disabled=\"disabled\" value=\"a\"><label for=\"$rid1\">A</label></div><div class=\"radio\"><input id=\"$rid2\" type=\"radio\" name=\"$name\" disabled=\"disabled\" value=\"b\"><label for=\"$rid2\">B</label></div></div>", + "<div class=\"form-group kv-radiogroup-inline\"><div class=\"form-check abc-radio\"><input class=\"form-check-input\" id=\"$rid1\" type=\"radio\" name=\"$name\" disabled=\"disabled\" value=\"a\"><label class=\"form-check-label\" for=\"$rid1\">A</label></div><div class=\"form-check abc-radio\"><input class=\"form-check-input\" id=\"$rid2\" type=\"radio\" name=\"$name\" disabled=\"disabled\" value=\"b\"><label class=\"form-check-label\" for=\"$rid2\">B</label></div></div>", element?.innerHTML, "Should render correct radio button group form control" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupSpec.kt index 2ed52b67..77547977 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioGroupSpec.kt @@ -41,10 +41,10 @@ class RadioGroupSpec : DomSpec { root.add(ci) val element = document.getElementById("test") val id = ci.flabel.forId - val rid1 = ci.getChildren().filterIsInstance<Radio>().first().input.id - val rid2 = ci.getChildren().filterIsInstance<Radio>().last().input.id + val rid1 = ci.container.getChildren().filterIsInstance<Radio>().first().input.id + val rid2 = ci.container.getChildren().filterIsInstance<Radio>().last().input.id assertEqualsHtml( - "<div class=\"form-group kv-radiogroup-inline\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"radio\"><input id=\"$rid1\" type=\"radio\" name=\"$id\" disabled=\"disabled\" value=\"a\"><label for=\"$rid1\">A</label></div><div class=\"radio\"><input id=\"$rid2\" type=\"radio\" name=\"$id\" disabled=\"disabled\" value=\"b\"><label for=\"$rid2\">B</label></div></div>", + "<div class=\"form-group kv-radiogroup-inline\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"kv-radiogroup-container\"><div class=\"form-check abc-radio\"><input class=\"form-check-input\" id=\"$rid1\" type=\"radio\" name=\"$id\" disabled=\"disabled\" value=\"a\"><label class=\"form-check-label\" for=\"$rid1\">A</label></div><div class=\"form-check abc-radio\"><input class=\"form-check-input\" id=\"$rid2\" type=\"radio\" name=\"$id\" disabled=\"disabled\" value=\"b\"><label class=\"form-check-label\" for=\"$rid2\">B</label></div></div></div>", element?.innerHTML, "Should render correct radio button group form control" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt index a8fbbcc5..c709b548 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt @@ -44,7 +44,7 @@ class RadioSpec : DomSpec { val element = document.getElementById("test") val id = ci.input.id assertEqualsHtml( - "<div class=\"radio radio-danger radio-inline\"><input id=\"$id\" type=\"radio\" checked=\"checked\" name=\"name\" disabled=\"disabled\" value=\"abc\"><label for=\"$id\">Label</label></div>", + "<div class=\"form-check abc-radio abc-radio-danger form-check-inline\"><input class=\"form-check-input\" id=\"$id\" type=\"radio\" checked=\"checked\" name=\"name\" disabled=\"disabled\" value=\"abc\"><label class=\"form-check-label\" for=\"$id\">Label</label></div>", element?.innerHTML, "Should render correct radio button form control" ) @@ -52,7 +52,7 @@ class RadioSpec : DomSpec { ci.squared = true ci.inline = false assertEqualsHtml( - "<div class=\"checkbox kv-radio-checkbox checkbox-info\"><input id=\"$id\" type=\"radio\" checked=\"checked\" name=\"name\" disabled=\"disabled\" value=\"abc\"><label for=\"$id\">Label</label></div>", + "<div class=\"form-check abc-checkbox abc-checkbox-info\"><input class=\"form-check-input\" id=\"$id\" type=\"radio\" checked=\"checked\" name=\"name\" disabled=\"disabled\" value=\"abc\"><label class=\"form-check-label\" for=\"$id\">Label</label></div>", element?.innerHTML, "Should render correct radio button form control" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt index 7ce811fa..02ba7643 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt @@ -49,7 +49,7 @@ class TextSpec : DomSpec { ) ti.validatorError = "Validation Error" assertEqualsHtml( - "<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"disabled\" type=\"text\" value=\"abc\"><span class=\"help-block small\">Validation Error</span></div>", + "<div class=\"form-group text-danger\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control is-invalid\" id=\"$id\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"disabled\" type=\"text\" value=\"abc\"><div class=\"invalid-feedback\">Validation Error</div></div>", element?.innerHTML, "Should render correct input form control with validation error" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/html/ButtonSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/html/ButtonSpec.kt index 512c3bc2..e807bfd5 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/html/ButtonSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/html/ButtonSpec.kt @@ -35,13 +35,13 @@ class ButtonSpec : DomSpec { fun render() { run { val root = Root("test", fixed = true) - val button = Button("Cancel", "fa-bars", ButtonStyle.PRIMARY) + val button = Button("Cancel", "fas fa-bars", ButtonStyle.PRIMARY) button.size = ButtonSize.LARGE button.block = true root.add(button) val element = document.getElementById("test") assertEqualsHtml( - "<button class=\"btn btn-primary btn-lg btn-block\" type=\"button\"><i class=\"fa fa-bars\"></i> Cancel</button>", + "<button class=\"btn btn-primary btn-lg btn-block\" type=\"button\"><i class=\"fas fa-bars\"></i> Cancel</button>", element?.innerHTML, "Should render correct html button" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/html/IconSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/html/IconSpec.kt index ea3425c5..9a63c68e 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/html/IconSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/html/IconSpec.kt @@ -33,10 +33,10 @@ class IconSpec : DomSpec { fun render() { run { val root = Root("test", fixed = true) - val icon = Icon("fa-check") + val icon = Icon("fas fa-check") root.add(icon) val element = document.getElementById("test") - assertEqualsHtml("<span class=\"fa fa-check\"></span>", element?.innerHTML, "Should render correct icon") + assertEqualsHtml("<span class=\"fas fa-check\"></span>", element?.innerHTML, "Should render correct icon") } } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt index 169575fc..ed3a5347 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt @@ -41,7 +41,7 @@ class ImageSpec : DomSpec { root.add(image) val element = document.getElementById("test") assertEqualsHtml( - "<img class=\"img-responsive center-block img-rounded\" src=\"$res\" alt=\"Image\">", + "<img class=\"img-fluid center-block rounded\" src=\"$res\" alt=\"Image\">", element?.innerHTML, "Should render correct html image" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt index 997da597..69dc05d3 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt @@ -23,6 +23,7 @@ package test.pl.treksoft.kvision.table import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.table.Cell.Companion.cell +import pl.treksoft.kvision.table.ResponsiveType import pl.treksoft.kvision.table.Row.Companion.row import pl.treksoft.kvision.table.Table import pl.treksoft.kvision.table.TableType @@ -45,16 +46,16 @@ class TableSpec : DomSpec { root.add(table) val element = document.getElementById("test") assertEqualsHtml( - "<table class=\"table\"><thead><tr><th>a</th><th>b</th></tr></thead><tbody><tr><td>A</td><td>B</td></tr></tbody></table>", + "<table class=\"table\"><thead><tr><th scope=\"col\">a</th><th scope=\"col\">b</th></tr></thead><tbody><tr><td>A</td><td>B</td></tr></tbody></table>", element?.innerHTML, "Should render correct table" ) table.caption = "Caption" - table.responsive = true + table.responsiveType = ResponsiveType.RESPONSIVE table.types = setOf(TableType.BORDERED) val element2 = document.getElementById("test") assertEqualsHtml( - "<div class=\"table-responsive\"><table class=\"table table-bordered\"><caption>Caption</caption><thead><tr><th>a</th><th>b</th></tr></thead><tbody><tr><td>A</td><td>B</td></tr></tbody></table></div>", + "<div class=\"table-responsive\"><table class=\"table table-bordered\"><caption>Caption</caption><thead><tr><th scope=\"col\">a</th><th scope=\"col\">b</th></tr></thead><tbody><tr><td>A</td><td>B</td></tr></tbody></table></div>", element2?.innerHTML, "Should render correct responsive table" ) |