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 /kvision-modules | |
parent | 6678eec9799681b09e5ac85de1a39596d56de22f (diff) | |
parent | 6b14906f0e35dc522bd1c1a44682d728315cf619 (diff) | |
download | kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.tar.gz kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.tar.bz2 kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.zip |
Merge branch 'bs4'
Diffstat (limited to 'kvision-modules')
248 files changed, 5638 insertions, 2111 deletions
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/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt new file mode 100644 index 00000000..4e20de81 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt @@ -0,0 +1,112 @@ +/* + * 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.dropdown + +import org.w3c.dom.events.MouseEvent +import pl.treksoft.kvision.core.Display +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.utils.px + +/** + * Context menu component. + * + * @constructor + * @param element an element to bind + * @param fixedPosition use fixed positioning + * @param classes a set of CSS class names + */ +open class ContextMenu( + element: Widget? = null, + protected val fixedPosition: Boolean = false, + classes: Set<String> = setOf(), init: (ContextMenu.() -> Unit)? = null +) : Div(classes = classes + "dropdown-menu") { + + init { + @Suppress("LeakingThis") + hide() + @Suppress("LeakingThis") + display = Display.BLOCK + val root = element?.getRoot() ?: Root.getLastRoot() + if (root != null) { + @Suppress("LeakingThis") + root.addContextMenu(this) + } else { + println("At least one Root object is required to create a context menu!") + } + @Suppress("LeakingThis") + init?.invoke(this) + } + + /** + * Positions and shows a context menu based on a mouse event. + * @param mouseEvent mouse event + * @return current context menu + */ + open fun positionMenu(mouseEvent: MouseEvent): ContextMenu { + if (fixedPosition) { + this.top = DEFAULT_FIXED_POS_Y.px + this.left = DEFAULT_FIXED_POS_X.px + } else { + this.top = mouseEvent.pageY.toInt().px + this.left = mouseEvent.pageX.toInt().px + } + this.show() + return this + } + + companion object { + + const val DEFAULT_FIXED_POS_X = 5 + 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. + */ + fun Widget.contextMenu( + fixedPosition: Boolean = false, + classes: Set<String> = setOf(), init: (ContextMenu.() -> Unit)? = null + ): ContextMenu { + val contextMenu = ContextMenu(this, fixedPosition, classes).apply { init?.invoke(this) } + this.setContextMenu(contextMenu) + return contextMenu + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt new file mode 100644 index 00000000..9862b322 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -0,0 +1,417 @@ +/* + * 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.dropdown + +import com.github.snabbdom.VNode +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.panel.SimplePanel +import pl.treksoft.kvision.utils.obj + +/** + * Useful options for use in DropDown's *elements* parameter. + */ +enum class DD(val option: String) { + HEADER("DD#HEADER"), + DISABLED("DD#DISABLED"), + SEPARATOR("DD#SEPARATOR") +} + +/** + * Dropdown directions. + */ +enum class Direction(internal val direction: String) { + DROPDOWN("dropdown"), + DROPUP("dropup"), + DROPLEFT("dropleft"), + DROPRIGHT("dropright") +} + +/** + * Bootstrap dropdown component. + * + * @constructor + * @param text the label of the dropdown button + * @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 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.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. + */ + var text + get() = button.text + set(value) { + button.text = value + } + private var elements by refreshOnUpdate(elements) { setChildrenFromElements() } + /** + * The icon of the dropdown button. + */ + var icon + get() = button.icon + set(value) { + button.icon = value + } + /** + * The style of the dropdown button. + */ + var style + get() = button.style + set(value) { + button.style = value + } + /** + * The size of the dropdown button. + */ + var size + get() = button.size + set(value) { + button.size = value + } + /** + * Determines if the dropdown button takes all the space horizontally. + */ + var block + get() = button.block + set(value) { + button.block = value + } + /** + * Determines if the dropdown is disabled. + */ + var disabled + get() = button.disabled + set(value) { + button.disabled = value + } + /** + * The image on the dropdown button. + */ + var image + get() = button.image + set(value) { + button.image = value + } + /** + * The direction of the dropdown. + */ + var direction by refreshOnUpdate(direction) + /** + * Width of the dropdown button. + */ + override var width: CssSize? + get() = super.width + set(value) { + super.width = value + button.width = value + } + + private val idc = "kv_dropdown_$counter" + internal val button: DropDownButton = DropDownButton( + idc, text, icon, style, disabled, forNavbar, forDropDown + ) + + fun buttonId() = button.id + + internal val list: DropDownDiv = DropDownDiv(idc) + + init { + if (forDropDown) { + this.style = ButtonStyle.LIGHT + this.direction = Direction.DROPRIGHT + } + setChildrenFromElements() + this.addInternal(button) + this.addInternal(list) + counter++ + } + + override fun render(): VNode { + return if (forNavbar) { + render("li", childrenVNodes()) + } else { + render("div", childrenVNodes()) + } + } + + override fun add(child: Component): SimplePanel { + list.add(child) + return this + } + + override fun addAll(children: List<Component>): SimplePanel { + list.addAll(children) + return this + } + + override fun remove(child: Component): SimplePanel { + list.remove(child) + return this + } + + override fun removeAll(): SimplePanel { + list.removeAll() + return this + } + + override fun getChildren(): List<Component> { + return list.getChildren() + } + + private fun setChildrenFromElements() { + list.removeAll() + elements?.let { elems -> + val c = elems.map { + when (it.second) { + DD.HEADER.option -> Header(it.first) + DD.SEPARATOR.option -> Separator() + DD.DISABLED.option -> { + Link(it.first, "javascript:void(0)", classes = setOf("dropdown-item", "disabled")).apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + } + } + else -> Link(it.first, it.second, classes = setOf("dropdown-item")) + } + } + list.addAll(c) + } + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + this.getElementJQuery()?.on("show.bs.dropdown") { e, _ -> + this.dispatchEvent("showBsDropdown", obj { detail = e }) + } + this.getElementJQuery()?.on("shown.bs.dropdown") { e, _ -> + this.dispatchEvent("shownBsDropdown", obj { detail = e }) + } + this.getElementJQuery()?.on("hide.bs.dropdown") { e, _ -> + this.dispatchEvent("hideBsDropdown", obj { detail = e }) + } + this.getElementJQuery()?.on("hidden.bs.dropdown") { e, _ -> + this.dispatchEvent("hiddenBsDropdown", obj { detail = e }) + } + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + if (forNavbar) cl.add("nav-item" to true) + cl.add(direction.direction to true) + return cl + } + + /** + * Toggles dropdown visibility. + */ + open fun toggle() { + this.button.getElementJQuery()?.click() + } + + companion object { + internal var counter = 0 + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.dropDown( + text: String, elements: List<StringPair>? = null, icon: String? = 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( + text, + elements, + icon, + style, + direction, + disabled, + forNavbar, + 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 + } + + } +} + +internal class DropDownButton( + id: String, + text: String, + icon: String? = null, + style: ButtonStyle = ButtonStyle.PRIMARY, + disabled: Boolean = false, + val forNavbar: Boolean = false, + val forDropDown: Boolean = false, + classes: Set<String> = setOf() +) : + Button(text, icon, style, ButtonType.BUTTON, disabled, classes) { + + init { + this.id = id + if (!forNavbar && !forDropDown) this.role = "button" + setInternalEventListener<DropDownButton> { + click = { e -> + 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 || forDropDown) { + render("a", text) + } else { + render("button", text) + } + } + + override fun getSnClass(): List<StringBoolPair> { + return if (forNavbar) { + 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() + ("dropdown-toggle" to true) + } + } + + override fun getSnAttrs(): List<StringPair> { + 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 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/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt new file mode 100644 index 00000000..13e0b2e4 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt @@ -0,0 +1,61 @@ +/* + * 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.dropdown + +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +/** + * Menu header component. + * + * @constructor + * @param content header content text + * @param classes a set of CSS class names + */ +open class Header(content: String? = null, classes: Set<String> = setOf()) : + Tag(TAG.H6, content, classes = classes + "dropdown-header") { + + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun ContextMenu.header(content: String? = null, classes: Set<String> = setOf()): Header { + val header = Header(content, classes) + this.add(header) + return header + } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun DropDown.header(content: String? = null, classes: Set<String> = setOf()): Header { + val header = Header(content, classes) + this.add(header) + return header + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt new file mode 100644 index 00000000..dd2344bd --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt @@ -0,0 +1,57 @@ +/* + * 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.dropdown + +import pl.treksoft.kvision.html.Div + +/** + * Menu separator component. + * + * @constructor + * @param classes a set of CSS class names + */ +open class Separator(classes: Set<String> = setOf()) : Div(classes = classes + "dropdown-divider") { + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun ContextMenu.separator(classes: Set<String> = setOf()): Separator { + val separator = Separator(classes) + this.add(separator) + return separator + } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun DropDown.separator(classes: Set<String> = setOf()): Separator { + val separator = Separator(classes) + this.add(separator) + return separator + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt new file mode 100644 index 00000000..4c5b222e --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt @@ -0,0 +1,121 @@ +/* + * 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.modal + +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.html.Align +import pl.treksoft.kvision.html.ButtonStyle +import pl.treksoft.kvision.html.Button +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.ENTER_KEY + +/** + * Alert window based on Bootstrap modal. + * + * @constructor + * @param caption window title + * @param text window content text. + * @param rich determines if [text] can contain HTML code + * @param align text align + * @param size modal window size + * @param animation determines if animations are used + * @param callback a function called after closing window with OK button + */ +open class Alert( + caption: String? = null, text: String? = null, rich: Boolean = false, + align: Align? = null, size: ModalSize? = null, animation: Boolean = true, + private val callback: (() -> Unit)? = null +) : Modal(caption, true, size, animation) { + + /** + * Window content text. + */ + var text + get() = contentTag.content + set(value) { + contentTag.content = value + } + /** + * Determines if [text] can contain HTML code. + */ + var rich + get() = contentTag.rich + set(value) { + contentTag.rich = value + } + /** + * Text align. + */ + var align + get() = contentTag.align + set(value) { + contentTag.align = value + } + + private val contentTag = Tag(TAG.DIV, text, rich, align) + + init { + body.add(contentTag) + val okButton = Button("OK", "fas fa-check", ButtonStyle.PRIMARY) + okButton.setEventListener { + click = { + hide() + } + } + this.addButton(okButton) + this.setEventListener { + keydown = { e -> + if (e.keyCode == ENTER_KEY) { + hide() + } + } + } + } + + override fun hide(): Widget { + super.hide() + this.callback?.invoke() + return this + } + + companion object { + /** + * Helper function for opening Alert window. + * @param caption window title + * @param text window content text. + * @param rich determines if [text] can contain HTML code + * @param align text align + * @param size modal window size + * @param animation determines if animations are used + * @param callback a function called after closing window with OK button + */ + @Suppress("LongParameterList") + fun show( + caption: String? = null, text: String? = null, rich: Boolean = false, + align: Align? = null, size: ModalSize? = null, animation: Boolean = true, + callback: (() -> Unit)? = null + ) { + Alert(caption, text, rich, align, size, animation, callback).show() + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt new file mode 100644 index 00000000..5f0440a6 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt @@ -0,0 +1,48 @@ +/* + * 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.modal + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.KVManager +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.core.Widget + +/** + * Helper class for close icon component. + */ +open class CloseIcon : Widget(setOf()) { + + override fun render(): VNode { + return render("button", arrayOf(KVManager.virtualize("<span aria-hidden='true'>×</span>"))) + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("close" to true) + return cl + } + + override fun getSnAttrs(): List<StringPair> { + return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Close") + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt new file mode 100644 index 00000000..058ca7bc --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt @@ -0,0 +1,176 @@ +/* + * 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.modal + +import pl.treksoft.kvision.html.Align +import pl.treksoft.kvision.html.Button +import pl.treksoft.kvision.html.ButtonStyle +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +/** + * Confirm window based on Bootstrap modal. + * + * @constructor + * @param caption window title + * @param text window content text. + * @param rich determines if [text] can contain HTML code + * @param align text align + * @param size modal window size + * @param animation determines if animations are used + * @param cancelVisible determines if Cancel button is visible + * @param yesTitle yes button text + * @param noTitle no button text + * @param cancelTitle cancel button text + * @param noCallback a function called after closing window with No button + * @param yesCallback a function called after closing window with Yes button + */ +open class Confirm( + caption: String? = null, text: String? = null, rich: Boolean = false, + align: Align? = null, size: ModalSize? = null, animation: Boolean = true, + cancelVisible: Boolean = false, yesTitle: String = "Yes", noTitle: String = "No", cancelTitle: String = "Cancel", + private val noCallback: (() -> Unit)? = null, + private val yesCallback: (() -> Unit)? = null +) : Modal(caption, false, size, animation, false) { + /** + * Window content text. + */ + var text + get() = contentTag.content + set(value) { + contentTag.content = value + } + /** + * Determines if [text] can contain HTML code. + */ + var rich + get() = contentTag.rich + set(value) { + contentTag.rich = value + } + /** + * Text align. + */ + var align + get() = contentTag.align + set(value) { + contentTag.align = value + } + /** + * Determines if Cancel button is visible. + */ + var cancelVisible by refreshOnUpdate(cancelVisible) { refreshCancelButton() } + + /** + * Yes button text. + */ + var yesTitle + get() = yesButton.text + set(value) { + yesButton.text = value + } + + /** + * No button text. + */ + var noTitle + get() = noButton.text + set(value) { + noButton.text = value + } + + /** + * Cancel button text. + */ + var cancelTitle + get() = cancelButton.text + set(value) { + cancelButton.text = value + } + + private val contentTag = Tag(TAG.DIV, text, rich, align) + 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) + cancelButton.setEventListener { + click = { + hide() + } + } + this.addButton(cancelButton) + noButton.setEventListener { + click = { + hide() + noCallback?.invoke() + } + } + this.addButton(noButton) + yesButton.setEventListener { + click = { + hide() + yesCallback?.invoke() + } + } + this.addButton(yesButton) + refreshCancelButton() + } + + private fun refreshCancelButton() { + if (cancelVisible) { + cancelButton.show() + closeIcon.show() + } else { + cancelButton.hide() + closeIcon.hide() + } + } + + companion object { + /** + * Helper function for opening Confirm window. + * @param caption window title + * @param text window content text. + * @param rich determines if [text] can contain HTML code + * @param align text align + * @param size modal window size + * @param animation determines if animations are used + * @param cancelVisible determines if Cancel button is visible + * @param noCallback a function called after closing window with No button + * @param yesCallback a function called after closing window with Yes button + */ + @Suppress("LongParameterList") + fun show( + caption: String? = null, text: String? = null, rich: Boolean = false, + align: Align? = null, size: ModalSize? = null, animation: Boolean = true, + cancelVisible: Boolean = false, yesTitle: String = "Yes", noTitle: String = "No", + cancelTitle: String = "Cancel", noCallback: (() -> Unit)? = null, yesCallback: (() -> Unit)? = null + ) { + Confirm( + caption, text, rich, align, size, animation, cancelVisible, yesTitle, noTitle, cancelTitle, + noCallback, yesCallback + ).show() + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt new file mode 100644 index 00000000..08fc7aa8 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt @@ -0,0 +1,292 @@ +/* + * 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.modal + +import com.github.snabbdom.VNode +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.core.Widget +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 + +/** + * Modal window sizes. + */ +enum class ModalSize(val className: String) { + XLARGE("modal-xl"), + LARGE("modal-lg"), + SMALL("modal-sm") +} + +/** + * Configurable modal window based on Bootstrap modal. + * + * @constructor + * @param caption window title + * @param closeButton determines if Close button is visible + * @param size modal window size + * @param animation determines if animations are used + * @param escape determines if dialog can be closed with Esc key + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +@Suppress("TooManyFunctions") +open class Modal( + caption: String? = null, closeButton: Boolean = true, + size: ModalSize? = null, animation: Boolean = true, private val escape: Boolean = true, + classes: Set<String> = setOf(), init: (Modal.() -> Unit)? = null +) : SimplePanel(classes) { + + override var parent: Container? = Root.getFirstRoot() + + /** + * Window caption text. + */ + var caption + get() = captionTag.content + set(value) { + captionTag.content = value + checkHeaderVisibility() + } + /** + * Determines if Close button is visible. + */ + var closeButton + get() = closeIcon.visible + set(value) { + closeIcon.visible = value + checkHeaderVisibility() + } + /** + * Window size. + */ + var size + get() = dialog.size + set(value) { + dialog.size = value + } + /** + * Determines if animations are used. + */ + var animation by refreshOnUpdate(animation) + + private val dialog = ModalDialog(size) + private val header = SimplePanel(setOf("modal-header")) + /** + * @suppress + * Internal property. + */ + protected val closeIcon = CloseIcon() + private val captionTag = Tag(TAG.H5, caption, classes = setOf("modal-title")) + /** + * @suppress + * Internal property. + */ + protected val body = SimplePanel(setOf("modal-body")) + private val footer = SimplePanel(setOf("modal-footer")) + + init { + this.hide() + this.role = "dialog" + this.tabindex = -1 + this.addInternal(dialog) + val content = SimplePanel(setOf("modal-content")) + dialog.role = "document" + dialog.add(content) + closeIcon.visible = closeButton + closeIcon.setEventListener { + click = { + hide() + } + } + header.add(captionTag) + header.add(closeIcon) + checkHeaderVisibility() + content.add(header) + content.add(body) + content.add(footer) + @Suppress("LeakingThis") + addModal(this) + @Suppress("LeakingThis") + init?.invoke(this) + } + + private fun checkHeaderVisibility() { + if (!closeButton && caption == null) { + header.hide() + } else { + header.show() + } + } + + override fun add(child: Component): SimplePanel { + body.add(child) + return this + } + + override fun addAll(children: List<Component>): SimplePanel { + body.addAll(children) + return this + } + + override fun remove(child: Component): SimplePanel { + body.remove(child) + return this + } + + override fun removeAll(): SimplePanel { + body.removeAll() + return this + } + + override fun getChildren(): List<Component> { + return body.getChildren() + } + + /** + * Adds given button to the bottom section of dialog window. + * @param button a [Button] component + * @return this modal + */ + open fun addButton(button: Button): Modal { + footer.add(button) + return this + } + + /** + * Removes given button from the bottom section of dialog window. + * @param button a [Button] component + * @return this modal + */ + open fun removeButton(button: Button): Modal { + footer.remove(button) + return this + } + + /** + * Removes all buttons from the bottom section of dialog window. + * @return this modal + */ + open fun removeAllButtons(): Modal { + footer.removeAll() + return this + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("modal" to true) + if (animation) { + cl.add("fade" to true) + } + return cl + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + getElementJQueryD()?.modal(obj { + keyboard = escape + backdrop = if (escape) "true" else "static" + }) + this.getElementJQuery()?.on("show.bs.modal") { e, _ -> + this.dispatchEvent("showBsModal", obj { detail = e }) + } + this.getElementJQuery()?.on("shown.bs.modal") { e, _ -> + this.dispatchEvent("shownBsModal", obj { detail = e }) + } + this.getElementJQuery()?.on("hide.bs.modal") { e, _ -> + this.dispatchEvent("hideBsModal", obj { detail = e }) + } + this.getElementJQuery()?.on("hidden.bs.modal") { e, _ -> + this.visible = false + hide() + this.dispatchEvent("hiddenBsModal", obj { detail = e }) + } + } + + override fun hide(): Widget { + if (visible) hideInternal() + return super.hide() + } + + /** + * Toggle modal window visibility. + */ + open fun toggle() { + if (visible) + hide() + else + show() + } + + @Suppress("UnsafeCastFromDynamic") + private fun showInternal() { + getElementJQueryD()?.modal("show") + } + + @Suppress("UnsafeCastFromDynamic") + private fun hideInternal() { + getElementJQueryD()?.modal("hide") + } + + override fun clearParent(): Widget { + this.parent = null + return this + } + + override fun getRoot(): Root? { + return this.parent?.getRoot() + } + + override fun dispose() { + removeModal(this) + } +} + +/** + * Internal helper class for modal content. + * + * @constructor + * @param size modal window size + */ +internal class ModalDialog(size: ModalSize?) : SimplePanel(setOf("modal-dialog")) { + + /** + * Modal window size. + */ + var size by refreshOnUpdate(size) + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + size?.let { + cl.add(it.className to true) + } + return cl + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt new file mode 100644 index 00000000..e0da480d --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt @@ -0,0 +1,110 @@ +/* + * 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.navbar + +import pl.treksoft.kvision.core.ResString +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.html.Link + +/** + * The Bootstrap Nav container. + * + * @constructor + * @param rightAlign determines if the nav is aligned to the right + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (Nav.() -> Unit)? = null) : + Div(classes = classes) { + + /** + * Determines if the nav is aligned to the right. + */ + var rightAlign by refreshOnUpdate(rightAlign) + + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("navbar-nav" to true) + if (rightAlign) { + cl.add("ml-auto" to true) + } + return cl + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Navbar.nav( + rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (Nav.() -> Unit)? = null + ): Nav { + val nav = Nav(rightAlign, classes).apply { init?.invoke(this) } + 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/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt new file mode 100644 index 00000000..45454cc8 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt @@ -0,0 +1,72 @@ +/* + * 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.navbar + +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +/** + * The Bootstrap Nav form container. + * + * @constructor + * @param rightAlign determines if the nav form is aligned to the right + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +open class NavForm(rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (NavForm.() -> Unit)? = null) : + Tag(TAG.FORM, classes = classes) { + + /** + * Determines if the nav form is aligned to the right. + */ + var rightAlign by refreshOnUpdate(rightAlign) + + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("form-inline" to true) + if (rightAlign) { + cl.add("ml-auto" to true) + } + return cl + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Navbar.navForm( + rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (NavForm.() -> Unit)? = null + ): NavForm { + val navForm = NavForm(rightAlign, classes).apply { init?.invoke(this) } + this.add(navForm) + return navForm + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt new file mode 100644 index 00000000..34a9dbe2 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt @@ -0,0 +1,229 @@ +/* + * 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.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.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("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"), +} + +/** + * The Bootstrap Navbar container. + * + * @constructor + * @param label the navbar label + * @param type the navbar type + * @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, + expand: NavbarExpand? = NavbarExpand.LG, + nColor: NavbarColor = NavbarColor.LIGHT, + bgColor: BsBgColor = BsBgColor.LIGHT, + classes: Set<String> = setOf(), init: (Navbar.() -> Unit)? = null +) : SimplePanel(classes) { + + /** + * The navbar header label. + */ + var label + get() = if (brandLink.visible) brandLink.label else null + set(value) { + if (value != null) { + brandLink.label = value + brandLink.show() + } else { + brandLink.hide() + } + } + + /** + * The navbar type. + */ + var type by refreshOnUpdate(type) + /** + * The navbar responsive behavior. + */ + 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" + + private val brandLink = Link(label ?: "", "#", classes = setOf("navbar-brand")) + internal val container = SimplePanel(setOf("collapse", "navbar-collapse")) { + id = idc + } + + init { + addInternal(brandLink) + addInternal(NavbarButton(idc)) + addInternal(container) + if (label == null) brandLink.hide() + counter++ + @Suppress("LeakingThis") + init?.invoke(this) + } + + override fun render(): VNode { + return render("nav", childrenVNodes()) + } + + override fun add(child: Component): Navbar { + container.add(child) + return this + } + + override fun addAll(children: List<Component>): Navbar { + container.addAll(children) + return this + } + + override fun remove(child: Component): Navbar { + container.remove(child) + return this + } + + override fun removeAll(): Navbar { + container.removeAll() + return this + } + + override fun getChildren(): List<Component> { + return container.getChildren() + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("navbar" to true) + type?.let { + cl.add(it.navbarType to true) + } + expand?.let { + cl.add(it.navbarExpand to true) + } + cl.add(nColor.navbarColor to true) + cl.add(bgColor.className to true) + return cl + } + + companion object { + internal var counter = 0 + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.navbar( + label: String? = null, + type: NavbarType? = null, + 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, 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 + } + } +} + +/** + * @suppress + * Internal component. + * The Bootstrap Navbar header button. + */ +internal class NavbarButton(private val idc: String, private val toggle: String = "Toggle navigation") : + SimplePanel(setOf("navbar-toggler")) { + + init { + span(classes = setOf("navbar-toggler-icon")) + } + + override fun render(): VNode { + return render("button", childrenVNodes()) + } + + override fun getSnAttrs(): List<StringPair> { + return super.getSnAttrs() + listOf( + "type" to "button", + "data-toggle" to "collapse", + "data-target" to "#$idc", + "aria-controls" to idc, + "aria-expanded" to "false", + "aria-label" to toggle + ) + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt new file mode 100644 index 00000000..2ff6fa19 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt @@ -0,0 +1,185 @@ +/* + * 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.panel + +import pl.treksoft.kvision.core.Component +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.core.WidgetWrapper +import pl.treksoft.kvision.html.Align +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +/** + * Bootstrap grid sizes. + */ +enum class GridSize(internal val size: String) { + SM("sm"), + MD("md"), + LG("lg"), + XL("xs") +} + +internal const val MAX_COLUMNS = 12 + +internal data class WidgetParam(val widget: Component, val size: Int, val offset: Int) + +/** + * The container with support for Bootstrap responsive grid layout. + * + * @constructor + * @param gridSize grid size + * @param rows number of rows + * @param cols number of columns + * @param align text align of grid cells + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +open class ResponsiveGridPanel( + private val gridSize: GridSize = GridSize.MD, + private var rows: Int = 0, private var cols: Int = 0, align: Align? = null, + classes: Set<String> = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null +) : SimplePanel(classes + "container-fluid") { + + /** + * Text align of grid cells. + */ + var align by refreshOnUpdate(align) { refreshRowContainers() } + + internal val map = mutableMapOf<Int, MutableMap<Int, WidgetParam>>() + private var auto: Boolean = true + + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + + /** + * Adds child component to the grid. + * @param child child component + * @param col column number + * @param row row number + * @param size cell size (colspan) + * @param offset cell offset + * @return this container + */ + open fun add(child: Component, col: Int, row: Int, size: Int = 0, offset: Int = 0): ResponsiveGridPanel { + 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() + return this + } + + override fun add(child: Component): ResponsiveGridPanel { + return this.add(child, this.cols, 0) + } + + override fun addAll(children: List<Component>): ResponsiveGridPanel { + children.forEach { this.add(it) } + return this + } + + @Suppress("NestedBlockDepth") + override fun remove(child: Component): ResponsiveGridPanel { + map.values.forEach { row -> + row.filterValues { it.widget == child } + .forEach { (i, _) -> row.remove(i) } + } + refreshRowContainers() + return this + } + + /** + * Removes child component at given location (column, row). + * @param col column number + * @param row row number + * @return this container + */ + open fun removeAt(col: Int, row: Int): ResponsiveGridPanel { + map[row]?.remove(col) + refreshRowContainers() + return this + } + + @Suppress("ComplexMethod", "NestedBlockDepth") + private fun refreshRowContainers() { + singleRender { + clearRowContainers() + val num = MAX_COLUMNS / cols + for (i in 1..rows) { + val rowContainer = SimplePanel(setOf("row")) + val row = map[i] + if (row != null) { + (1..cols).map { row[it] }.forEach { wp -> + if (auto) { + val widget = wp?.widget?.let { + WidgetWrapper(it, setOf("col-" + gridSize.size + "-" + num)) + } ?: Tag(TAG.DIV, classes = setOf("col-" + gridSize.size + "-" + num)) + align?.let { + widget.addCssClass(it.className) + } + rowContainer.add(widget) + } else { + if (wp != null) { + 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("offset-" + gridSize.size + "-" + wp.offset) + } + align?.let { + widget.addCssClass(it.className) + } + rowContainer.add(widget) + } + } + } + } + addInternal(rowContainer) + } + } + } + + private fun clearRowContainers() { + children.forEach { it.dispose() } + removeAll() + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.responsiveGridPanel( + gridSize: GridSize = GridSize.MD, + rows: Int = 0, cols: Int = 0, align: Align? = null, + classes: Set<String> = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null + ): ResponsiveGridPanel { + val responsiveGridPanel = ResponsiveGridPanel(gridSize, rows, cols, align, classes, init) + this.add(responsiveGridPanel) + return responsiveGridPanel + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt new file mode 100644 index 00000000..2009e4fc --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt @@ -0,0 +1,273 @@ +/* + * 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.panel + +import pl.treksoft.kvision.core.Component +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.core.ResString +import pl.treksoft.kvision.core.WidgetWrapper +import pl.treksoft.kvision.html.Icon +import pl.treksoft.kvision.html.Link.Companion.link +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.routing.routing +import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.html.Icon.Companion.icon as cicon + +/** + * Tab position. + */ +enum class TabPosition { + TOP, + LEFT, + RIGHT +} + +/** + * Left or right tab size. + */ +enum class SideTabSize { + SIZE_1, + SIZE_2, + SIZE_3, + SIZE_4, + SIZE_5, + SIZE_6 +} + +/** + * The container rendering it's children as tabs. + * + * It supports activating children by a JavaScript route. + * + * @constructor + * @param tabPosition tab position + * @param sideTabSize side tab size + * @param scrollableTabs determines if tabs are scrollable (default: false) + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +open class TabPanel( + private val tabPosition: TabPosition = TabPosition.TOP, + private val sideTabSize: SideTabSize = SideTabSize.SIZE_3, + scrollableTabs: Boolean = false, + classes: Set<String> = setOf(), + init: (TabPanel.() -> Unit)? = null +) : SimplePanel(classes) { + + /** + * The index of active (visible) tab. + */ + var activeIndex + get() = content.activeIndex + set(value) { + if (content.activeIndex != value) { + content.activeIndex = value + } + 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", "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) + + internal val childrenMap = mutableMapOf<Int, Component>() + + init { + when (tabPosition) { + TabPosition.TOP -> { + this.addInternal(nav) + this.addInternal(content) + } + TabPosition.LEFT -> { + this.addSurroundingCssClass("container-fluid") + this.addCssClass("row") + val sizes = calculateSideClasses() + 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.addSurroundingCssClass("container-fluid") + this.addCssClass("row") + val sizes = calculateSideClasses() + this.addInternal(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0"))) + this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0"))) + } + } + @Suppress("LeakingThis") + init?.invoke(this) + } + + private fun calculateSideClasses(): Pair<String, String> { + return when (sideTabSize) { + 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") + } + } + + /** + * Adds new tab and optionally bounds it's activation to a given route. + * @param title title of the tab + * @param panel child component + * @param icon icon of the tab + * @param image image of the tab + * @param closable determines if this tab is closable + * @param route JavaScript route to activate given child + * @return current container + */ + open fun addTab( + title: String, panel: Component, icon: String? = null, + image: ResString? = null, closable: Boolean = false, route: String? = null + ): TabPanel { + val currentIndex = counter++ + childrenMap[currentIndex] = panel + val tag = Tag(TAG.LI, classes = setOf("nav-item")) { + link(title, "#", icon, image, classes = setOf("nav-link")) { + if (closable) { + cicon("fas fa-times") { + addCssClass("kv-tab-close") + setEventListener<Icon> { + click = { e -> + val actIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) + e.asDynamic().data = actIndex + @Suppress("UnsafeCastFromDynamic") + if (this@TabPanel.dispatchEvent( + "tabClosing", + obj { detail = e; cancelable = true }) != false + ) { + this@TabPanel.removeTab(actIndex) + this@TabPanel.dispatchEvent("tabClosed", obj { detail = e }) + } + e.stopPropagation() + } + } + } + } + } + setEventListener { + click = { e -> + activeIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) + e.preventDefault() + if (route != null) { + routing.navigate(route) + } + } + } + } + nav.add(tag) + 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.getChildren().indexOf(childrenMap[currentIndex]) }) + .resolve() + } + return this + } + + /** + * Removes tab at given index. + */ + open fun removeTab(index: Int): TabPanel { + nav.remove(nav.getChildren()[index]) + childrenMap.filter { it.value == content.getChildren()[index] }.keys.firstOrNull()?.let { + childrenMap.remove(it) + } + content.remove(content.getChildren()[index]) + activeIndex = content.activeIndex + return this + } + + override fun add(child: Component): TabPanel { + return addTab("", child) + } + + override fun addAll(children: List<Component>): TabPanel { + children.forEach { add(it) } + return this + } + + override fun remove(child: Component): TabPanel { + val index = content.getChildren().indexOf(child) + return removeTab(index) + } + + /** + * Returns child component by tab index. + * @param index tab index + */ + open fun getChildComponent(index: Int): Component? { + return content.getChildren()[index] + } + + /** + * Returns tab header component by tab index. + * @param index tab index + */ + open fun getNavComponent(index: Int): Tag? { + return nav.getChildren()[index] as? Tag + } + + override fun removeAll(): TabPanel { + content.removeAll() + nav.removeAll() + childrenMap.clear() + refresh() + return this + } + + companion object { + internal var counter = 0 + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.tabPanel( + tabPosition: TabPosition = TabPosition.TOP, + sideTabSize: SideTabSize = SideTabSize.SIZE_3, + scrollableTabs: Boolean = false, + classes: Set<String> = setOf(), + init: (TabPanel.() -> Unit)? = null + ): TabPanel { + val tabPanel = TabPanel(tabPosition, sideTabSize, scrollableTabs, classes, init) + this.add(tabPanel) + return tabPanel + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt new file mode 100644 index 00000000..4d0f4b93 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt @@ -0,0 +1,162 @@ +/* + * 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.progress + +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.html.Align +import pl.treksoft.kvision.panel.SimplePanel + +/** + * The Bootstrap progress bar. + * + * @constructor + * @param progress the current progress + * @param min the minimal progress + * @param max the maximal progress + * @param style the style of the progress bar + * @param striped determines if the progress bar is striped + * @param animated determines if the progress bar is animated + * @param content element text + * @param rich determines if content can contain HTML code + * @param align content align + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +open class ProgressBar( + progress: Int, min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX, style: ProgressBarStyle? = null, + striped: Boolean = false, animated: Boolean = false, content: String? = null, + rich: Boolean = false, align: Align? = null, + classes: Set<String> = setOf(), init: (ProgressBar.() -> Unit)? = null +) : + SimplePanel(classes + "progress") { + + /** + * The current progress. + */ + var progress + get() = indicator.progress + set(value) { + indicator.progress = value + } + /** + * The minimal progress. + */ + var min + get() = indicator.min + set(value) { + indicator.min = value + } + /** + * The maximal progress. + */ + var max + get() = indicator.max + set(value) { + indicator.max = value + } + /** + * The style of the progress bar. + */ + var style + get() = indicator.style + set(value) { + indicator.style = value + } + /** + * Determines if the progress bar is striped. + */ + var striped + get() = indicator.striped + set(value) { + indicator.striped = value + } + /** + * Determines if the progress bar is animated. + */ + var animated + get() = indicator.animated + set(value) { + indicator.animated = value + } + /** + * Text content of the progress bar. + */ + var content + get() = indicator.content + set(value) { + indicator.content = value + } + /** + * Determines if [content] can contain HTML code. + */ + var rich + get() = indicator.rich + set(value) { + indicator.rich = value + } + /** + * Text align of the progress bar. + */ + var align + get() = indicator.align + set(value) { + indicator.align = value + } + + internal val indicator = ProgressIndicator(progress, min, max, style, striped, animated, content, rich, align) + + init { + addInternal(indicator) + + @Suppress("LeakingThis") + init?.invoke(this) + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.progressBar( + progress: Int, min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX, style: ProgressBarStyle? = null, + striped: Boolean = false, animated: Boolean = false, + content: String? = null, rich: Boolean = false, align: Align? = null, + classes: Set<String> = setOf(), init: (ProgressBar.() -> Unit)? = null + ): ProgressBar { + val progressBar = ProgressBar( + progress, + min, + max, + style, + striped, + animated, + content, + rich, + align, + classes + ).apply { init?.invoke(this) } + this.add(progressBar) + return progressBar + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt new file mode 100644 index 00000000..256d15d7 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt @@ -0,0 +1,125 @@ +/* + * 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.progress + +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.html.Align +import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.utils.perc + +/** + * Progress bar styles. + */ +enum class ProgressBarStyle(internal val className: String) { + SUCCESS("progress-bar-success"), + INFO("progress-bar-info"), + WARNING("progress-bar-warning"), + DANGER("progress-bar-danger") +} + +internal const val DEFAULT_MIN = 0 +internal const val DEFAULT_MAX = 100 + + +/** + * The Bootstrap progress bar indicator. + * + * @constructor + * @param progress the current progress + * @param min the minimal progress + * @param max the maximal progress + * @param style the style of the progress bar indicator + * @param striped determines if the progress bar indicator is striped + * @param animated determines if the progress bar indicator is animated + * @param content element text + * @param rich determines if [content] can contain HTML code + * @param align content align + * @param classes a set of CSS class names + */ +internal class ProgressIndicator( + progress: Int, min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX, style: ProgressBarStyle? = null, + striped: Boolean = false, animated: Boolean = false, + content: String? = null, rich: Boolean = false, align: Align? = null, + classes: Set<String> = setOf() +) : + Div(content, rich, align, classes) { + + /** + * The current progress. + */ + var progress by refreshOnUpdate(progress) { refreshWidth() } + /** + * The minimal progress. + */ + var min by refreshOnUpdate(min) { refreshWidth() } + /** + * The maximal progress. + */ + var max by refreshOnUpdate(max) { refreshWidth() } + /** + * The style of the progress indicator. + */ + var style by refreshOnUpdate(style) + /** + * Determines if the progress indicator is striped. + */ + var striped by refreshOnUpdate(striped) + /** + * Determines if the progress indicator is animated. + */ + var animated by refreshOnUpdate(animated) + + init { + role = "progressbar" + refreshWidth() + } + + private fun refreshWidth() { + val value = (if (max - min > 0) (progress - min) * DEFAULT_MAX.toFloat() / (max - min) else 0f).toInt() + val percent = if (value < 0) 0 else if (value > DEFAULT_MAX) DEFAULT_MAX else value + width = percent.perc + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("progress-bar" to true) + style?.let { + cl.add(it.className to true) + } + if (striped || animated) { + cl.add("progress-bar-striped" to true) + } + if (animated) { + cl.add("active" to true) + } + return cl + } + + override fun getSnAttrs(): List<StringPair> { + val sn = super.getSnAttrs().toMutableList() + sn.add("aria-valuenow" to "$progress") + sn.add("aria-valuemin" to "$min") + sn.add("aria-valuemax" to "$max") + return sn + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt new file mode 100644 index 00000000..2aef9e63 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt @@ -0,0 +1,109 @@ +/* + * 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.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") +} + +/** + * The Bootstrap button group. + * + * @constructor + * @param size button group size + * @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, vertical: Boolean = false, + classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null +) : SimplePanel(classes) { + + /** + * Button group size. + */ + var size by refreshOnUpdate(size) + /** + * Vertical alignment. + */ + var vertical by refreshOnUpdate(vertical) + + init { + role = "group" + @Suppress("LeakingThis") + init?.invoke(this) + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + if (vertical) { + cl.add("btn-group-vertical" to true) + } else { + cl.add("btn-group" to true) + } + size?.let { + cl.add(it.className to true) + } + return cl + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.buttonGroup( + 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(this.size, this.vertical, classes).apply { + marginRight = this@buttonGroup.spacing.px + init?.invoke(this) + } + this.add(group) + return group + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt new file mode 100644 index 00000000..13ed8972 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt @@ -0,0 +1,63 @@ +/* + * 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.toolbar + +import pl.treksoft.kvision.core.Container +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") { + + init { + role = "toolbar" + @Suppress("LeakingThis") + init?.invoke(this) + } + + companion object { + /** + * DSL builder extension function. + * + * 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(size, spacing, vertical, classes).apply { init?.invoke(this) } + this.add(toolbar) + return toolbar + } + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt new file mode 100644 index 00000000..a3ceaf61 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt @@ -0,0 +1,48 @@ +/* + * 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.window + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.KVManager +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.core.Widget + +/** + * Helper class for maximize icon component. + */ +open class MaximizeIcon : Widget(setOf()) { + + override fun render(): VNode { + return render("button", arrayOf(KVManager.virtualize("<span aria-hidden='true'>🗖</span>"))) + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("close" to true) + return cl + } + + override fun getSnAttrs(): List<StringPair> { + return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Maximize") + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt new file mode 100644 index 00000000..c8034d09 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt @@ -0,0 +1,48 @@ +/* + * 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.window + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.KVManager +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.core.Widget + +/** + * Helper class for minimize icon component. + */ +open class MinimizeIcon : Widget(setOf()) { + + override fun render(): VNode { + return render("button", arrayOf(KVManager.virtualize("<span aria-hidden='true'>🗕</span>"))) + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("close" to true) + return cl + } + + override fun getSnAttrs(): List<StringPair> { + return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Minimize") + } +} diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt new file mode 100644 index 00000000..83473858 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt @@ -0,0 +1,449 @@ +/* + * 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.window + +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 +import pl.treksoft.kvision.core.Overflow +import pl.treksoft.kvision.core.Position +import pl.treksoft.kvision.core.Resize +import pl.treksoft.kvision.core.UNIT +import pl.treksoft.kvision.html.Icon +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.modal.CloseIcon +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.px + +internal const val DEFAULT_Z_INDEX = 900 +internal const val WINDOW_HEADER_HEIGHT = 40 +internal const val WINDOW_CONTENT_MARGIN_BOTTOM = 11 + +/** + * Floating window container. + * + * @constructor + * @param caption window title + * @param contentWidth window content width + * @param contentHeight window content height + * @param isResizable determines if the window is resizable + * @param isDraggable determines if the window is draggable + * @param closeButton determines if Close button is visible + * @param maximizeButton determines if Maximize button is visible + * @param minimizeButton determines if Minimize button is visible + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +@Suppress("TooManyFunctions") +open class Window( + caption: String? = null, + contentWidth: CssSize? = CssSize(0, UNIT.auto), + contentHeight: CssSize? = CssSize(0, UNIT.auto), + isResizable: Boolean = true, + isDraggable: Boolean = true, + closeButton: Boolean = false, + maximizeButton: Boolean = false, + minimizeButton: Boolean = false, + icon: String? = null, + classes: Set<String> = setOf(), + init: (Window.() -> Unit)? = null +) : + SimplePanel(classes + setOf("modal-content", "kv-window")) { + + /** + * Window caption text. + */ + var caption + get() = captionTag.content + set(value) { + captionTag.content = value + checkHeaderVisibility() + } + /** + * Window content width. + */ + var contentWidth + get() = width + set(value) { + width = value + } + /** + * Window content height. + */ + var contentHeight + get() = content.height + set(value) { + content.height = value + } + /** + * Window content height. + */ + var contentOverflow + get() = content.overflow + set(value) { + content.overflow = value + } + /** + * Determines if the window is resizable. + */ + var isResizable by refreshOnUpdate(isResizable) { checkIsResizable() } + /** + * Determines if the window is draggable. + */ + var isDraggable by refreshOnUpdate(isDraggable) { checkIsDraggable(); checkHeaderVisibility() } + /** + * Determines if Close button is visible. + */ + var closeButton + get() = closeIcon.visible + set(value) { + closeIcon.visible = value + checkHeaderVisibility() + } + /** + * Determines if Maximize button is visible. + */ + var maximizeButton + get() = maximizeIcon.visible + set(value) { + maximizeIcon.visible = value + checkHeaderVisibility() + } + /** + * Determines if Maximize button is visible. + */ + var minimizeButton + get() = minimizeIcon.visible + set(value) { + minimizeIcon.visible = value + checkHeaderVisibility() + } + /** + * Window icon. + */ + var icon + get() = if (windowIcon.icon == "") null else windowIcon.icon + set(value) { + windowIcon.icon = value ?: "" + windowIcon.visible = (value != null && value != "") + } + + private val header = SimplePanel(setOf("modal-header")) + + /** + * @suppress + * Internal property. + */ + protected val content = SimplePanel().apply { + this.height = contentHeight + this.overflow = Overflow.AUTO + } + private val closeIcon = CloseIcon() + private val maximizeIcon = MaximizeIcon() + private val minimizeIcon = MinimizeIcon() + 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 != "") + } + + private var isResizeEvent = false + + init { + id = "kv_window_$counter" + @Suppress("LeakingThis") + position = Position.ABSOLUTE + @Suppress("LeakingThis") + overflow = Overflow.HIDDEN + @Suppress("LeakingThis") + width = contentWidth + @Suppress("LeakingThis") + zIndex = ++zIndexCounter + header.add(captionTag) + captionTag.add(windowIcon) + header.add(iconsContainer) + minimizeIcon.visible = minimizeButton + minimizeIcon.setEventListener { + click = { _ -> + @Suppress("UnsafeCastFromDynamic") + if (this@Window.dispatchEvent("minimizeWindow", obj {}) != false) { + toggleMinimize() + } + } + mousedown = { e -> + e.stopPropagation() + } + } + iconsContainer.add(minimizeIcon) + maximizeIcon.visible = maximizeButton + maximizeIcon.setEventListener { + click = { _ -> + @Suppress("UnsafeCastFromDynamic") + if (this@Window.dispatchEvent("maximizeWindow", obj {}) != false) { + toggleMaximize() + } + } + mousedown = { e -> + e.stopPropagation() + } + } + iconsContainer.add(maximizeIcon) + closeIcon.visible = closeButton + closeIcon.setEventListener { + click = { _ -> + @Suppress("UnsafeCastFromDynamic") + if (this@Window.dispatchEvent("closeWindow", obj {}) != false) { + close() + } + } + mousedown = { e -> + e.stopPropagation() + } + } + iconsContainer.add(closeIcon) + checkHeaderVisibility() + addInternal(header) + addInternal(content) + checkIsDraggable() + if (isResizable) { + @Suppress("LeakingThis") + resize = Resize.BOTH + content.marginBottom = WINDOW_CONTENT_MARGIN_BOTTOM.px + } + @Suppress("LeakingThis") + setEventListener<Window> { + click = { + toFront() + focus() + } + } + @Suppress("LeakingThis") + init?.invoke(this) + counter++ + } + + private fun checkHeaderVisibility() { + @Suppress("ComplexCondition") + if (!closeButton && !maximizeButton && !minimizeButton && caption == null && !isDraggable) { + header.hide() + } else { + header.show() + } + } + + private fun checkIsDraggable() { + var isDrag: Boolean + if (isDraggable) { + header.setEventListener<SimplePanel> { + mousedown = { e -> + if (e.button.toInt() == 0) { + isDrag = true + val dragStartX = this@Window.getElementJQuery()?.position()?.left?.toInt() ?: 0 + val dragStartY = this@Window.getElementJQuery()?.position()?.top?.toInt() ?: 0 + val dragMouseX = e.pageX + val dragMouseY = e.pageY + val moveCallback = { me: Event -> + if (isDrag) { + this@Window.left = (dragStartX + (me as MouseEvent).pageX - dragMouseX).toInt().px + this@Window.top = (dragStartY + (me).pageY - dragMouseY).toInt().px + } + } + kotlin.browser.window.addEventListener("mousemove", moveCallback) + var upCallback: ((Event) -> Unit)? = null + upCallback = { + isDrag = false + kotlin.browser.window.removeEventListener("mousemove", moveCallback) + kotlin.browser.window.removeEventListener("mouseup", upCallback) + } + kotlin.browser.window.addEventListener("mouseup", upCallback) + } + } + } + } else { + isDrag = false + header.removeEventListeners() + } + } + + private fun checkIsResizable() { + checkResizablEventHandler() + if (isResizable) { + resize = Resize.BOTH + val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0) + content.height = (intHeight - WINDOW_HEADER_HEIGHT - WINDOW_CONTENT_MARGIN_BOTTOM).px + content.marginBottom = WINDOW_CONTENT_MARGIN_BOTTOM.px + } else { + resize = Resize.NONE + val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0) + content.height = (intHeight - WINDOW_HEADER_HEIGHT).px + content.marginBottom = 0.px + } + } + + @Suppress("UnsafeCastFromDynamic") + private fun checkResizablEventHandler() { + if (isResizable) { + if (!isResizeEvent) { + isResizeEvent = true + KVManagerBootstrap.setResizeEvent(this) { + val eid = getElementJQuery()?.attr("id") + if (isResizable && eid == id) { + val outerWidth = (getElementJQuery()?.outerWidth()?.toInt() ?: 0) + val outerHeight = (getElementJQuery()?.outerHeight()?.toInt() ?: 0) + val intWidth = (getElementJQuery()?.width()?.toInt() ?: 0) + val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0) + content.width = intWidth.px + content.height = (intHeight - WINDOW_HEADER_HEIGHT - WINDOW_CONTENT_MARGIN_BOTTOM).px + width = outerWidth.px + height = outerHeight.px + this.dispatchEvent("resizeWindow", obj { + detail = obj { + this.width = outerWidth + this.height = outerHeight + } + }) + } + } + } + } else if (isResizeEvent) { + KVManagerBootstrap.clearResizeEvent(this) + isResizeEvent = false + } + } + + override fun add(child: Component): SimplePanel { + content.add(child) + return this + } + + override fun addAll(children: List<Component>): SimplePanel { + content.addAll(children) + return this + } + + override fun remove(child: Component): SimplePanel { + content.remove(child) + return this + } + + override fun removeAll(): SimplePanel { + content.removeAll() + return this + } + + override fun getChildren(): List<Component> { + return content.getChildren() + } + + override fun afterCreate(node: VNode) { + checkResizablEventHandler() + } + + override fun afterDestroy() { + if (isResizeEvent) { + KVManagerBootstrap.clearResizeEvent(this) + isResizeEvent = false + } + } + + /** + * Moves the current window to the front. + */ + open fun toFront() { + if ((zIndex ?: 0) < zIndexCounter) zIndex = ++zIndexCounter + } + + /** + * Makes the current window focused. + */ + open fun focus() { + getElementJQuery()?.focus() + } + + /** + * Close the window. + */ + open fun close() { + hide() + } + + /** + * Maximize or restore the window size. + */ + open fun toggleMaximize() { + } + + /** + * Minimize or restore the window size. + */ + open fun toggleMinimize() { + } + + companion object { + internal var counter = 0 + internal var zIndexCounter = DEFAULT_Z_INDEX + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.window( + caption: String? = null, + contentWidth: CssSize? = CssSize(0, UNIT.auto), + contentHeight: CssSize? = CssSize(0, UNIT.auto), + isResizable: Boolean = true, + isDraggable: Boolean = true, + closeButton: Boolean = false, + maximizeButton: Boolean = false, + minimizeButton: Boolean = false, + icon: String? = null, + classes: Set<String> = setOf(), + init: (Window.() -> Unit)? = null + ): Window { + val window = + Window( + caption, + contentWidth, + contentHeight, + isResizable, + isDraggable, + closeButton, + maximizeButton, + minimizeButton, + icon, + classes, + init + ) + this.add(window) + return window + } + } +} 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/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..b467f1ff --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt @@ -0,0 +1,76 @@ +/* + * 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 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 +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class ContextMenuSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val m = ContextMenu { + link("a", "b") + link("c", "d") + } + root.setContextMenu(m) + m.show() + val element = document.getElementById("test") + assertEqualsHtml( + "<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" + ) + } + } + + @Suppress("UnsafeCastFromDynamic") + @Test + fun positionMenu() { + run { + val root = Root("test", fixed = true) + val m = ContextMenu { + link("a", "b") + link("c", "d") + } + root.setContextMenu(m) + m.positionMenu(obj { + pageX = 40 + pageY = 50 + }) + val element = document.getElementById("test") + assertEqualsHtml( + "<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" + ) + } + } +}
\ No newline at end of file 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/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..25ca7a7d --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt @@ -0,0 +1,46 @@ +/* + * 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 test.pl.treksoft.kvision.dropdown + +import pl.treksoft.kvision.dropdown.Header +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class HeaderSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val h = Header("Test") + root.add(h) + val element = document.getElementById("test") + assertEqualsHtml( + "<h6 class=\"dropdown-header\">Test</h6>", + element?.innerHTML, + "Should render correct drop down header" + ) + } + } +}
\ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..36c22a74 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt @@ -0,0 +1,46 @@ +/* + * 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 test.pl.treksoft.kvision.dropdown + +import pl.treksoft.kvision.dropdown.Separator +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class SeparatorSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val s = Separator() + root.add(s) + val element = document.getElementById("test") + assertEqualsHtml( + "<div class=\"dropdown-divider\"></div>", + element?.innerHTML, + "Should render correct drop down separator" + ) + } + } +}
\ No newline at end of file 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/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..8eb7bd5b --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt @@ -0,0 +1,54 @@ +/* + * 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 test.pl.treksoft.kvision.navbar + +import pl.treksoft.kvision.navbar.NavForm +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class NavFormSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val navf = NavForm() + root.add(navf) + val element = document.getElementById("test") + assertEqualsHtml( + "<form class=\"form-inline\"></form>", + element?.innerHTML, + "Should render correct nav form" + ) + navf.rightAlign = true + assertEqualsHtml( + "<form class=\"form-inline ml-auto\"></form>", + element?.innerHTML, + "Should render correct right aligned nav form" + ) + + } + } + +} diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..2e52557f --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt @@ -0,0 +1,54 @@ +/* + * 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 test.pl.treksoft.kvision.navbar + +import pl.treksoft.kvision.navbar.Nav +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class NavSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val nav = Nav() + root.add(nav) + val element = document.getElementById("test") + assertEqualsHtml( + "<div class=\"navbar-nav\"></div>", + element?.innerHTML, + "Should render correct nav" + ) + nav.rightAlign = true + assertEqualsHtml( + "<div class=\"navbar-nav ml-auto\"></div>", + element?.innerHTML, + "Should render correct right aligned nav" + ) + + } + } + +} diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..1658e63c --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt @@ -0,0 +1,71 @@ +/* + * 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 test.pl.treksoft.kvision.navbar + +import pl.treksoft.kvision.html.Link.Companion.link +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 +import kotlin.browser.document +import kotlin.test.Test + +class NavbarSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val navbar = Navbar("TEST", NavbarType.FIXEDTOP) + root.add(navbar) + val element = document.getElementById("test") + val id = navbar.container.id + assertEqualsHtml( + "<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.nColor = NavbarColor.DARK + assertEqualsHtml( + "<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 dark navbar" + ) + navbar.add(Nav { + tag(TAG.LI) { + link("Test", "#!/test") + } + }) + assertEqualsHtml( + "<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/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..1ebac202 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt @@ -0,0 +1,50 @@ +/* + * 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 test.pl.treksoft.kvision.panel + +import pl.treksoft.kvision.html.Span +import pl.treksoft.kvision.panel.ResponsiveGridPanel +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class ResponsiveGridPanelSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val rgPanel = ResponsiveGridPanel() + root.add(rgPanel) + rgPanel.add(Span("abc"), 1, 1) + rgPanel.add(Span("def"), 2, 2) + rgPanel.add(Span("ghi"), 3, 3) + val element = document.getElementById("test") + assertEqualsHtml( + "<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" + ) + } + } +}
\ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..7a76cde9 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt @@ -0,0 +1,117 @@ +/* + * 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 test.pl.treksoft.kvision.panel + +import pl.treksoft.jquery.jQuery +import pl.treksoft.kvision.html.Span +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.panel.TabPanel +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class TabPanelSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val tabs = TabPanel() + root.add(tabs) + val label1 = Span("abc") + val label2 = Span("def") + tabs.addTab("ABC", label1) + tabs.addTab("DEF", label2) + val element = document.getElementById("test") + assertEqualsHtml( + "<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" + ) + } + } + + @Test + fun setActiveIndex() { + run { + val root = Root("test", fixed = true) + val tabs = TabPanel() + root.add(tabs) + val label1 = Span("abc") + val label2 = Span("def") + tabs.addTab("ABC", label1) + tabs.addTab("DEF", label2) + tabs.activeIndex = 1 + val element = document.getElementById("test") + assertEqualsHtml( + "<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" + ) + } + } + + @Test + fun removeTab() { + run { + val root = Root("test", fixed = true) + val tabs = TabPanel() + root.add(tabs) + val label1 = Span("abc") + val label2 = Span("def") + tabs.addTab("ABC", label1) + tabs.addTab("DEF", label2) + tabs.activeIndex = 1 + tabs.removeTab(1) + val element = document.getElementById("test") + assertEqualsHtml( + "<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" + ) + } + } + + + @Test + fun tabClick() { + run { + val root = Root("test", fixed = true) + val tabs = TabPanel() + root.add(tabs) + val label1 = Span("abc") + val label2 = Span("def") + tabs.addTab("ABC", label1) + tabs.addTab("DEF", label2) + tabs.removeTab(0) + val label3 = Span("ghi") + tabs.addTab("GHI", label3) + jQuery("#test a")[1]?.click() + val element = document.getElementById("test") + assertEqualsHtml( + "<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" + ) + } + } +}
\ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..2f044987 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt @@ -0,0 +1,56 @@ +/* + * 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 test.pl.treksoft.kvision.progress + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.progress.ProgressBar +import pl.treksoft.kvision.progress.ProgressBarStyle +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class ProgressBarSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val progressBar = + ProgressBar(50, style = ProgressBarStyle.SUCCESS, striped = true, content = "Processing ...") + root.add(progressBar) + val element = document.getElementById("test") + assertEqualsHtml( + "<div class=\"progress\"><div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 50%;\">Processing ...</div></div>", + element?.innerHTML, + "Should render correct progress bar" + ) + progressBar.max = 200 + assertEqualsHtml( + "<div class=\"progress\"><div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"200\" style=\"width: 25%;\">Processing ...</div></div>", + element?.innerHTML, + "Should render correct progress bar after max value change" + ) + + } + } + +} diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..4aa14230 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt @@ -0,0 +1,55 @@ +/* + * 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 test.pl.treksoft.kvision.progress + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.progress.ProgressBarStyle +import pl.treksoft.kvision.progress.ProgressIndicator +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class ProgressIndicatorSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val ind = ProgressIndicator(50, style = ProgressBarStyle.SUCCESS, striped = true) + root.add(ind) + val element = document.getElementById("test") + assertEqualsHtml( + "<div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 50%;\"></div>", + element?.innerHTML, + "Should render correct progress bar indicator" + ) + ind.max = 200 + assertEqualsHtml( + "<div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"200\" style=\"width: 25%;\"></div>", + element?.innerHTML, + "Should render correct progress bar indicator after max value change" + ) + + } + } + +} diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..b3ddbe40 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt @@ -0,0 +1,56 @@ +/* + * 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 test.pl.treksoft.kvision.toolbar + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.toolbar.ButtonGroup +import pl.treksoft.kvision.toolbar.ButtonGroupSize +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class ButtonGroupSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val group = ButtonGroup() + root.add(group) + val element = document.getElementById("test") + assertEqualsHtml( + "<div class=\"btn-group\" role=\"group\"></div>", + element?.innerHTML, + "Should render correct button group" + ) + group.size = ButtonGroupSize.LARGE + group.vertical = true + assertEqualsHtml( + "<div class=\"btn-group-lg btn-group-vertical\" role=\"group\"></div>", + element?.innerHTML, + "Should render correct button group with large and vertical buttons" + ) + + } + } + +} diff --git a/kvision-modules/kvision-bootstrap/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 new file mode 100644 index 00000000..d41ef05e --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt @@ -0,0 +1,47 @@ +/* + * 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 test.pl.treksoft.kvision.toolbar + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.toolbar.Toolbar +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class ToolbarSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val toolbar = Toolbar() + root.add(toolbar) + val element = document.getElementById("test") + assertEqualsHtml( + "<div class=\"btn-toolbar\" role=\"toolbar\"></div>", + element?.innerHTML, + "Should render correct toolbar" + ) + } + } + +} 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') |