From 0d3e7c87bf74948f83ce006a1d340b0f3f5e68b0 Mon Sep 17 00:00:00 2001 From: Robert Jaros Date: Mon, 8 Oct 2018 13:40:04 +0200 Subject: Refactoring to modules --- .../kotlin/pl/treksoft/kvision/KVManagerUpload.kt | 86 +++++ .../pl/treksoft/kvision/form/upload/Upload.kt | 333 +++++++++++++++++++ .../pl/treksoft/kvision/form/upload/UploadInput.kt | 364 +++++++++++++++++++++ .../resources/js/locales/bootstrap-fileinput/ar.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/az.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/bg.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/ca.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/cr.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/cs.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/da.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/de.js | 98 ++++++ .../resources/js/locales/bootstrap-fileinput/el.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/es.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/et.js | 99 ++++++ .../resources/js/locales/bootstrap-fileinput/fa.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/fi.js | 91 ++++++ .../resources/js/locales/bootstrap-fileinput/fr.js | 99 ++++++ .../resources/js/locales/bootstrap-fileinput/gl.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/hu.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/id.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/it.js | 102 ++++++ .../resources/js/locales/bootstrap-fileinput/ja.js | 109 ++++++ .../resources/js/locales/bootstrap-fileinput/ka.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/ko.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/kz.js | 88 +++++ .../resources/js/locales/bootstrap-fileinput/lt.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/nl.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/no.js | 99 ++++++ .../resources/js/locales/bootstrap-fileinput/pl.js | 90 +++++ .../js/locales/bootstrap-fileinput/pt-BR.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/pt.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/ro.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/ru.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/sk.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/sl.js | 98 ++++++ .../resources/js/locales/bootstrap-fileinput/sv.js | 99 ++++++ .../resources/js/locales/bootstrap-fileinput/th.js | 100 ++++++ .../resources/js/locales/bootstrap-fileinput/tr.js | 99 ++++++ .../resources/js/locales/bootstrap-fileinput/uk.js | 101 ++++++ .../resources/js/locales/bootstrap-fileinput/vi.js | 101 ++++++ .../js/locales/bootstrap-fileinput/zh-TW.js | 102 ++++++ .../resources/js/locales/bootstrap-fileinput/zh.js | 100 ++++++ .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 99 ++++++ .../kvision/form/upload/UploadInputSpec.kt | 57 ++++ .../pl/treksoft/kvision/form/upload/UploadSpec.kt | 56 ++++ 45 files changed, 4878 insertions(+) create mode 100644 kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt create mode 100644 kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt create mode 100644 kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js create mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js create mode 100644 kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt create mode 100644 kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt create mode 100644 kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt (limited to 'kvision-modules/kvision-upload/src') diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt new file mode 100644 index 00000000..64a25545 --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt @@ -0,0 +1,86 @@ +/* + * 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 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 { + 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") + require("./js/locales/bootstrap-fileinput/ar.js") + require("./js/locales/bootstrap-fileinput/az.js") + require("./js/locales/bootstrap-fileinput/bg.js") + require("./js/locales/bootstrap-fileinput/ca.js") + require("./js/locales/bootstrap-fileinput/cr.js") + require("./js/locales/bootstrap-fileinput/cs.js") + require("./js/locales/bootstrap-fileinput/da.js") + require("./js/locales/bootstrap-fileinput/de.js") + require("./js/locales/bootstrap-fileinput/el.js") + require("./js/locales/bootstrap-fileinput/es.js") + require("./js/locales/bootstrap-fileinput/et.js") + require("./js/locales/bootstrap-fileinput/fa.js") + require("./js/locales/bootstrap-fileinput/fi.js") + require("./js/locales/bootstrap-fileinput/fr.js") + require("./js/locales/bootstrap-fileinput/gl.js") + require("./js/locales/bootstrap-fileinput/id.js") + 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/kz.js") + require("./js/locales/bootstrap-fileinput/lt.js") + require("./js/locales/bootstrap-fileinput/nl.js") + require("./js/locales/bootstrap-fileinput/no.js") + require("./js/locales/bootstrap-fileinput/pl.js") + require("./js/locales/bootstrap-fileinput/pt.js") + require("./js/locales/bootstrap-fileinput/ro.js") + require("./js/locales/bootstrap-fileinput/ru.js") + require("./js/locales/bootstrap-fileinput/sk.js") + require("./js/locales/bootstrap-fileinput/sl.js") + require("./js/locales/bootstrap-fileinput/sv.js") + require("./js/locales/bootstrap-fileinput/th.js") + require("./js/locales/bootstrap-fileinput/tr.js") + 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) { + } + +} diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt new file mode 100644 index 00000000..314c9904 --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt @@ -0,0 +1,333 @@ +/* + * 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.upload + +import org.w3c.files.File +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.KFilesFormControl +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.types.KFile +import pl.treksoft.kvision.utils.SnOn + +/** + * The form field file upload component. + * + * @constructor + * @param uploadUrl the optional URL for the upload processing action + * @param multiple determines if multiple file upload is supported + * @param label label text bound to the input element + * @param rich determines if [label] can contain HTML code + */ +@Suppress("TooManyFunctions") +open class Upload( + uploadUrl: String? = null, multiple: Boolean = false, label: String? = null, + rich: Boolean = false +) : SimplePanel(setOf("form-group")), KFilesFormControl { + + /** + * File input value. + */ + override var value + get() = input.value + set(value) { + input.value = value + } + /** + * The optional URL for the upload processing action. + * If not set the upload button action will default to form submission. + */ + var uploadUrl + get() = input.uploadUrl + set(value) { + input.uploadUrl = value + } + /** + * Determines if multiple file upload is supported. + */ + var multiple + get() = input.multiple + set(value) { + input.multiple = value + } + /** + * The extra data that will be passed as data to the AJAX server call via POST. + */ + var uploadExtraData + get() = input.uploadExtraData + set(value) { + input.uploadExtraData = value + } + /** + * Determines if the explorer theme is used. + */ + var explorerTheme + get() = input.explorerTheme + set(value) { + input.explorerTheme = value + } + /** + * Determines if the input selection is required. + */ + var required + get() = input.required + set(value) { + input.required = value + } + /** + * Determines if the caption is shown. + */ + var showCaption + get() = input.showCaption + set(value) { + input.showCaption = value + } + /** + * Determines if the preview is shown. + */ + var showPreview + get() = input.showPreview + set(value) { + input.showPreview = value + } + /** + * Determines if the remove button is shown. + */ + var showRemove + get() = input.showRemove + set(value) { + input.showRemove = value + } + /** + * Determines if the upload button is shown. + */ + var showUpload + get() = input.showUpload + set(value) { + input.showUpload = value + } + /** + * Determines if the cancel button is shown. + */ + var showCancel + get() = input.showCancel + set(value) { + input.showCancel = value + } + /** + * Determines if the file browse button is shown. + */ + var showBrowse + get() = input.showBrowse + set(value) { + input.showBrowse = value + } + /** + * Determines if the click on the preview zone opens file browse window. + */ + var browseOnZoneClick + get() = input.browseOnZoneClick + set(value) { + input.browseOnZoneClick = value + } + /** + * Determines if the iconic preview is prefered. + */ + var preferIconicPreview + get() = input.preferIconicPreview + set(value) { + input.preferIconicPreview = value + } + /** + * Allowed file types. + */ + var allowedFileTypes + get() = input.allowedFileTypes + set(value) { + input.allowedFileTypes = value + } + /** + * Allowed file extensions. + */ + var allowedFileExtensions + get() = input.allowedFileExtensions + set(value) { + input.allowedFileExtensions = value + } + /** + * Determines if Drag&Drop zone is enabled. + */ + var dropZoneEnabled + get() = input.dropZoneEnabled + set(value) { + input.dropZoneEnabled = value + } + /** + * The label text bound to the spinner input element. + */ + var label + get() = flabel.content + set(value) { + flabel.content = value + } + /** + * Determines if [label] can contain HTML code. + */ + var rich + get() = flabel.rich + set(value) { + flabel.rich = value + } + + protected val idc = "kv_form_upload_$counter" + final override val input: UploadInput = UploadInput(uploadUrl, multiple) + .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 } + + init { + @Suppress("LeakingThis") + input.eventTarget = this + this.addInternal(flabel) + this.addInternal(input) + this.addInternal(validationInfo) + counter++ + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + if (validatorError != null) { + cl.add("has-error" to true) + } + return cl + } + + @Suppress("UNCHECKED_CAST") + override fun setEventListener(block: SnOn.() -> Unit): Widget { + input.setEventListener(block) + return this + } + + override fun setEventListener(block: SnOn.() -> Unit): Widget { + input.setEventListener(block) + return this + } + + override fun removeEventListeners(): Widget { + input.removeEventListeners() + return this + } + + override fun getValueAsString(): String? { + return input.getValueAsString() + } + + /** + * Returns the native JavaScript File object. + * @param kFile KFile object + * @return File object + */ + fun getNativeFile(kFile: KFile): File? { + return input.getNativeFile(kFile) + } + + /** + * Resets the file input control. + */ + open fun resetInput() { + input.resetInput() + } + + /** + * Clears the file input control (including the native input). + */ + open fun clearInput() { + input.clearInput() + } + + /** + * Trigger ajax upload (only for ajax mode). + */ + open fun upload() { + input.upload() + } + + /** + * Cancel an ongoing ajax upload (only for ajax mode). + */ + open fun cancel() { + input.cancel() + } + + /** + * Locks the file input (disabling all buttons except a cancel button). + */ + open fun lock() { + input.lock() + } + + /** + * Unlocks the file input. + */ + open fun unlock() { + input.unlock() + } + + override fun focus() { + input.focus() + } + + override fun blur() { + input.blur() + } + + companion object { + internal var counter = 0 + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.upload( + uploadUrl: String? = null, + multiple: Boolean = false, + label: String? = null, + rich: Boolean = false, + init: (Upload.() -> Unit)? = null + ): Upload { + val upload = Upload(uploadUrl, multiple, label, rich).apply { + init?.invoke( + this + ) + } + this.add(upload) + return upload + } + } +} diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt new file mode 100644 index 00000000..51b73aa1 --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt @@ -0,0 +1,364 @@ +/* + * 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.upload + +import com.github.snabbdom.VNode +import org.w3c.files.File +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.Form +import pl.treksoft.kvision.form.FormInput +import pl.treksoft.kvision.form.FormPanel +import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.i18n.I18n +import pl.treksoft.kvision.types.KFile +import pl.treksoft.kvision.utils.getContent +import pl.treksoft.kvision.utils.obj +import kotlin.reflect.KProperty1 + +/** + * The file upload component. + * + * @constructor + * @param uploadUrl the optional URL for the upload processing action + * @param multiple determines if multiple file upload is supported + * @param classes a set of CSS class names + */ +@Suppress("TooManyFunctions") +open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, classes: Set = setOf()) : + Widget(classes + "form-control"), FormInput { + + /** + * File input value. + */ + var value: List? + get() = getValue() + set(value) { + if (value == null) resetInput() + } + + /** + * The optional URL for the upload processing action. + * If not set the upload button action will default to form submission. + */ + var uploadUrl: String? by refreshOnUpdate(uploadUrl, { refreshUploadInput() }) + /** + * Determines if multiple file upload is supported. + */ + var multiple: Boolean by refreshOnUpdate(multiple, { refresh(); refreshUploadInput() }) + /** + * The extra data that will be passed as data to the AJAX server call via POST. + */ + var uploadExtraData: ((String, Int) -> dynamic)? by refreshOnUpdate({ refreshUploadInput() }) + /** + * Determines if the explorer theme is used. + */ + var explorerTheme: Boolean by refreshOnUpdate(false, { refreshUploadInput() }) + /** + * Determines if the input selection is required. + */ + var required: Boolean by refreshOnUpdate(false, { refreshUploadInput() }) + /** + * Determines if the caption is shown. + */ + var showCaption: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * Determines if the preview is shown. + */ + var showPreview: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * Determines if the remove button is shown. + */ + var showRemove: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * Determines if the upload button is shown. + */ + var showUpload: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * Determines if the cancel button is shown. + */ + var showCancel: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * Determines if the file browse button is shown. + */ + var showBrowse: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * Determines if the click on the preview zone opens file browse window. + */ + var browseOnZoneClick: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * Determines if the iconic preview is prefered. + */ + var preferIconicPreview: Boolean by refreshOnUpdate(false, { refreshUploadInput() }) + /** + * Allowed file types. + */ + var allowedFileTypes: Set? by refreshOnUpdate({ refreshUploadInput() }) + /** + * Allowed file extensions. + */ + var allowedFileExtensions: Set? by refreshOnUpdate({ refreshUploadInput() }) + /** + * Determines if Drag&Drop zone is enabled. + */ + var dropZoneEnabled: Boolean by refreshOnUpdate(true, { refreshUploadInput() }) + /** + * 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(); refreshUploadInput() }) + /** + * The size of the input (currently not working) + */ + override var size: InputSize? by refreshOnUpdate() + + private val nativeFiles: MutableMap = mutableMapOf() + + override fun render(): VNode { + return render("input") + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + size?.let { + cl.add(it.className to true) + } + return cl + } + + override fun getSnAttrs(): List { + val sn = super.getSnAttrs().toMutableList() + sn.add("type" to "file") + name?.let { + sn.add("name" to it) + } + if (multiple) { + sn.add("multiple" to "true") + } + if (disabled) { + sn.add("disabled" to "disabled") + } + return sn + } + + private fun getValue(): List? { + val v = getFiles() + return if (v.isNotEmpty()) v else null + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + getElementJQueryD()?.fileinput(getSettingsObj()) + this.getElementJQuery()?.on("fileselect", { e, _ -> + this.dispatchEvent("fileSelectUpload", obj { detail = e }) + }) + this.getElementJQuery()?.on("fileclear", { e, _ -> + this.dispatchEvent("fileClearUpload", obj { detail = e }) + }) + this.getElementJQuery()?.on("filereset", { e, _ -> + this.dispatchEvent("fileResetUpload", obj { detail = e }) + }) + this.getElementJQuery()?.on("filebrowse", { e, _ -> + this.dispatchEvent("fileBrowseUpload", obj { detail = e }) + }) + this.getElementJQueryD()?.on("filepreupload", lambda@{ _, data, previewId, index -> + data["previewId"] = previewId + data["index"] = index + this.dispatchEvent("filePreUpload", obj { detail = data }) + return@lambda null + }) + } + + override fun afterDestroy() { + getElementJQueryD()?.fileinput("destroy") + } + + private fun refreshUploadInput() { + getElementJQueryD()?.fileinput("refresh", getSettingsObj()) + } + + /** + * Resets the file input control. + */ + open fun resetInput() { + getElementJQueryD()?.fileinput("reset") + } + + /** + * Clears the file input control (including the native input). + */ + open fun clearInput() { + getElementJQueryD()?.fileinput("clear") + } + + /** + * Trigger ajax upload (only for ajax mode). + */ + open fun upload() { + getElementJQueryD()?.fileinput("upload") + } + + /** + * Cancel an ongoing ajax upload (only for ajax mode). + */ + open fun cancel() { + getElementJQueryD()?.fileinput("cancel") + } + + /** + * Locks the file input (disabling all buttons except a cancel button). + */ + open fun lock() { + getElementJQueryD()?.fileinput("lock") + } + + /** + * Unlocks the file input. + */ + open fun unlock() { + getElementJQueryD()?.fileinput("unlock") + } + + /** + * Returns the native JavaScript File object. + * @param kFile KFile object + * @return File object + */ + fun getNativeFile(kFile: KFile): File? { + return nativeFiles[kFile] + } + + private fun getFiles(): List { + nativeFiles.clear() + return (getElementJQueryD()?.fileinput("getFileStack") as Array).toList().map { + val kFile = KFile(it.name, it.size, null) + nativeFiles[kFile] = it + kFile + } + } + + /** + * Returns the value of the file input control as a String. + * @return value as a String + */ + fun getValueAsString(): String? { + return value?.joinToString { it.name } + } + + /** + * Makes the input element focused. + */ + open fun focus() { + getElementJQuery()?.focus() + } + + /** + * Makes the input element blur. + */ + open fun blur() { + getElementJQuery()?.blur() + } + + private fun getSettingsObj(): dynamic { + val language = I18n.language + return obj { + this.uploadUrl = uploadUrl + this.uploadExtraData = uploadExtraData ?: undefined + this.theme = if (explorerTheme) "explorer-fa" else null + this.required = required + this.showCaption = showCaption + this.showPreview = showPreview + this.showRemove = showRemove + this.showUpload = showUpload + this.showCancel = showCancel + this.showBrowse = showBrowse + this.browseOnZoneClick = browseOnZoneClick + this.preferIconicPreview = preferIconicPreview + this.allowedFileTypes = allowedFileTypes?.toTypedArray() + this.allowedFileExtensions = allowedFileExtensions?.toTypedArray() + this.dropZoneEnabled = dropZoneEnabled + this.language = language + } + } + + companion object { + internal var counter = 0 + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.uploadInput( + uploadUrl: String? = null, + multiple: Boolean = false, + classes: Set = setOf(), + init: (UploadInput.() -> Unit)? = null + ): UploadInput { + val uploadInput = UploadInput(uploadUrl, multiple, classes).apply { + init?.invoke( + this + ) + } + this.add(uploadInput) + return uploadInput + } + + /** + * Returns file with the content read. + * @param key key identifier of the control + * @param kFile object identifying the file + * @return KFile object + */ + @Suppress("EXPERIMENTAL_FEATURE_WARNING") + suspend fun Form.getContent( + key: KProperty1?>, + kFile: KFile + ): KFile { + val control = getControl(key) as Upload + val content = control.getNativeFile(kFile)?.getContent() + return kFile.copy(content = content) + } + + + /** + * Returns file with the content read. + * @param key key identifier of the control + * @param kFile object identifying the file + * @return KFile object + */ + @Suppress("EXPERIMENTAL_FEATURE_WARNING") + suspend fun FormPanel.getContent( + key: KProperty1?>, + kFile: KFile + ): KFile { + val control = getControl(key) as Upload + val content = control.getNativeFile(kFile)?.getContent() + return kFile.copy(content = content) + } + } +} diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js new file mode 100644 index 00000000..92d32d28 --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js @@ -0,0 +1,101 @@ +/*! + * FileInput Arabic 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 + * @author Yasser Lotfy + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['ar'] = { + fileSingle: 'ملف', + filePlural: 'ملفات', + browseLabel: 'تصفح …', + removeLabel: 'إزالة', + removeTitle: 'إزالة الملفات المختارة', + cancelLabel: 'إلغاء', + cancelTitle: 'إنهاء الرفع الحالي', + uploadLabel: 'رفع', + uploadTitle: 'رفع الملفات المختارة', + msgNo: 'لا', + msgNoFilesSelected: '', + msgCancelled: 'ألغيت', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'معاينة تفصيلية', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'الملف "{name}" ({size} ك.ب) تعدى الحد الأقصى المسموح للرفع {maxSize} ك.ب.', + msgFilesTooLess: 'يجب عليك اختيار {n} {files} على الأقل للرفع.', + msgFilesTooMany: 'عدد الملفات المختارة للرفع ({n}) تعدت الحد الأقصى المسموح به لعدد {m}.', + msgFileNotFound: 'الملف "{name}" غير موجود!', + msgFileSecured: 'قيود أمنية تمنع قراءة الملف "{name}".', + msgFileNotReadable: 'الملف "{name}" غير قابل للقراءة.', + msgFilePreviewAborted: 'تم إلغاء معاينة الملف "{name}".', + msgFilePreviewError: 'حدث خطأ أثناء قراءة الملف "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'نوعية غير صالحة للملف "{name}". فقط هذه النوعيات مدعومة "{types}".', + msgInvalidFileExtension: 'امتداد غير صالح للملف "{name}". فقط هذه الملفات مدعومة "{extensions}".', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'تم إلغاء رفع الملف', + msgUploadThreshold: 'Processing...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'خطأ التحقق من صحة', + msgLoading: 'تحميل ملف {index} من {files} …', + msgProgress: 'تحميل ملف {index} من {files} - {name} - {percent}% منتهي.', + msgSelected: '{n} {files} مختار(ة)', + msgFoldersNotAllowed: 'اسحب وأفلت الملفات فقط! تم تخطي {n} مجلد(ات).', + msgImageWidthSmall: 'عرض ملف الصورة "{name}" يجب أن يكون على الأقل {size} px.', + msgImageHeightSmall: 'طول ملف الصورة "{name}" يجب أن يكون على الأقل {size} px.', + msgImageWidthLarge: 'عرض ملف الصورة "{name}" لا يمكن أن يتعدى {size} px.', + msgImageHeightLarge: 'طول ملف الصورة "{name}" لا يمكن أن يتعدى {size} px.', + msgImageResizeError: 'لم يتمكن من معرفة أبعاد الصورة لتغييرها.', + msgImageResizeException: 'حدث خطأ أثناء تغيير أبعاد الصورة.
{errors}
', + 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: 'اسحب وأفلت الملفات هنا …', + dropZoneClickTitle: '
(or click to select {files})', + fileActionSettings: { + removeTitle: 'إزالة الملف', + uploadTitle: 'رفع الملف', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'مشاهدة التفاصيل', + dragTitle: 'Move / Rearrange', + indicatorNewTitle: 'لم يتم الرفع بعد', + indicatorSuccessTitle: 'تم الرفع', + indicatorErrorTitle: 'خطأ بالرفع', + indicatorLoadingTitle: 'جارٍ الرفع ...' + }, + 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); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js new file mode 100644 index 00000000..5a9c6440 --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js @@ -0,0 +1,101 @@ +/*! + * FileInput Azerbaijan 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 + * @author Elbrus + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['az'] = { + fileSingle: 'fayl', + filePlural: 'fayl', + browseLabel: 'Seç …', + removeLabel: 'Sil', + removeTitle: 'Seçilmiş faylları təmizlə', + cancelLabel: 'İmtina et', + cancelTitle: 'Cari yükləməni dayandır', + uploadLabel: 'Yüklə', + uploadTitle: 'Seçilmiş faylları yüklə', + msgNo: 'xeyir', + msgNoFilesSelected: 'Heç bir fayl seçilməmişdir', + msgCancelled: 'İmtina edildi', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'İlkin baxış', + msgFileRequired: 'Yükləmə üçün fayl seçməlisiniz.', + msgSizeTooSmall: 'Seçdiyiniz "{name}" faylının həcmi ({size} KB)-dır, minimum {minSize} KB olmalıdır.', + msgSizeTooLarge: 'Seçdiyiniz "{name}" faylının həcmi ({size} KB)-dır, maksimum {maxSize} KB olmalıdır.', + msgFilesTooLess: 'Yükləmə üçün minimum {n} {files} seçməlisiniz.', + msgFilesTooMany: 'Seçilmiş fayl sayı ({n}). Maksimum {m} fayl seçmək mümkündür.', + msgFileNotFound: 'Fayl "{name}" tapılmadı!', + msgFileSecured: '"{name}" faylının istifadəsinə yetginiz yoxdur.', + msgFileNotReadable: '"{name}" faylının istifadəsi mümkün deyil.', + msgFilePreviewAborted: '"{name}" faylı üçün ilkin baxış ləğv olunub.', + msgFilePreviewError: '"{name}" faylının oxunması mümkün olmadı.', + msgInvalidFileName: '"{name}" faylının adında qadağan olunmuş simvollardan istifadə olunmuşdur.', + msgInvalidFileType: '"{name}" faylının tipi dəstəklənmir. Yalnız "{types}" tipli faylları yükləmək mümkündür.', + msgInvalidFileExtension: '"{name}" faylının genişlənməsi yanlışdır. Yalnız "{extensions}" fayl genişlənmə(si / ləri) qəbul olunur.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Yükləmə dayandırılmışdır', + msgUploadThreshold: 'Yükləmə...', + msgUploadBegin: 'Yoxlama...', + msgUploadEnd: 'Fayl(lar) yükləndi', + msgUploadEmpty: 'Yükləmə üçün verilmiş məlumatlar yanlışdır', + msgUploadError: 'Error', + msgValidationError: 'Yoxlama nəticəsi səhvir', + msgLoading: '{files} fayldan {index} yüklənir …', + msgProgress: '{files} fayldan {index} - {name} - {percent}% yükləndi.', + msgSelected: 'Faylların sayı: {n}', + msgFoldersNotAllowed: 'Ancaq faylların daşınmasına icazə verilir! {n} qovluq yüklənmədi.', + msgImageWidthSmall: '{name} faylının eni {size} px -dən kiçik olmamalıdır.', + msgImageHeightSmall: '{name} faylının hündürlüyü {size} px -dən kiçik olmamalıdır.', + msgImageWidthLarge: '"{name}" faylının eni {size} px -dən böyük olmamalıdır.', + msgImageHeightLarge: '"{name}" faylının hündürlüyü {size} px -dən böyük olmamalıdır.', + msgImageResizeError: 'Faylın ölçülərini dəyişmək üçün ölçüləri hesablamaq mümkün olmadı.', + msgImageResizeException: 'Faylın ölçülərini dəyişmək mümkün olmadı.
{errors}
', + msgAjaxError: '{operation} əməliyyatı zamanı səhv baş verdi. Təkrar yoxlayın!', + msgAjaxProgressError: '{operation} əməliyyatı yerinə yetirmək mümkün olmadı.', + ajaxOperations: { + deleteThumb: 'faylı sil', + uploadThumb: 'faylı yüklə', + uploadBatch: 'bir neçə faylı yüklə', + uploadExtra: 'məlumatların yüklənməsi' + }, + dropZoneTitle: 'Faylları bura daşıyın …', + dropZoneClickTitle: '
(Və ya seçin {files})', + fileActionSettings: { + removeTitle: 'Faylı sil', + uploadTitle: 'Faylı yüklə', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'məlumatlara bax', + dragTitle: 'Yerini dəyiş və ya sırala', + indicatorNewTitle: 'Davam edir', + indicatorSuccessTitle: 'Tamamlandı', + indicatorErrorTitle: 'Yükləmə xətası', + indicatorLoadingTitle: 'Yükləmə ...' + }, + previewZoomButtonTitles: { + prev: 'Əvvəlki fayla bax', + next: 'Növbəti fayla bax', + toggleheader: 'Başlığı dəyiş', + fullscreen: 'Tam ekranı dəyiş', + borderless: 'Bölmələrsiz rejimi dəyiş', + close: 'Ətraflı baxışı bağla' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js new file mode 100644 index 00000000..cf75d1ab --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js @@ -0,0 +1,100 @@ +/*! + * FileInput Bulgarian 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['bg'] = { + fileSingle: 'файл', + filePlural: 'файла', + browseLabel: 'Избери …', + removeLabel: 'Премахни', + removeTitle: 'Изчисти избраните', + cancelLabel: 'Откажи', + cancelTitle: 'Откажи качването', + uploadLabel: 'Качи', + uploadTitle: 'Качи избраните файлове', + msgNo: 'Не', + msgNoFilesSelected: '', + msgCancelled: 'Отменен', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Детайлен преглед', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Файла "{name}" ({size} KB) надвишава максималните разрешени {maxSize} KB.', + msgFilesTooLess: 'Трябва да изберете поне {n} {files} файла.', + msgFilesTooMany: 'Броя файлове избрани за качване ({n}) надвишава ограниченито от максимум {m}.', + msgFileNotFound: 'Файлът "{name}" не може да бъде намерен!', + msgFileSecured: 'От съображения за сигурност не може да прочетем файла "{name}".', + msgFileNotReadable: 'Файлът "{name}" не е четим.', + msgFilePreviewAborted: 'Прегледа на файла е прекратен за "{name}".', + msgFilePreviewError: 'Грешка при опит за четене на файла "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Невалиден тип на файла "{name}". Разрешени са само "{types}".', + msgInvalidFileExtension: 'Невалидно разрешение на "{name}". Разрешени са само "{extensions}".', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Качите файла, бе прекратена', + msgUploadThreshold: 'Processing...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'утвърждаване грешка', + msgLoading: 'Зареждане на файл {index} от общо {files} …', + msgProgress: 'Зареждане на файл {index} от общо {files} - {name} - {percent}% завършени.', + msgSelected: '{n} {files} избрани', + msgFoldersNotAllowed: 'Само пуснати файлове! Пропуснати {n} пуснати папки.', + msgImageWidthSmall: 'Широчината на изображението "{name}" трябва да е поне {size} px.', + msgImageHeightSmall: 'Височината на изображението "{name}" трябва да е поне {size} px.', + msgImageWidthLarge: 'Широчината на изображението "{name}" не може да е по-голяма от {size} px.', + msgImageHeightLarge: 'Височината на изображението "{name}" нее може да е по-голяма от {size} px.', + msgImageResizeError: 'Не може да размерите на изображението, за да промените размера.', + msgImageResizeException: 'Грешка при промяна на размера на изображението.
{errors}
', + 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: 'Пуснете файловете тук …', + dropZoneClickTitle: '
(or click to select {files})', + fileActionSettings: { + removeTitle: 'Махни файл', + uploadTitle: 'Качване на файл', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Вижте детайли', + dragTitle: 'Move / Rearrange', + indicatorNewTitle: 'Все още не е качил', + indicatorSuccessTitle: 'Качено', + indicatorErrorTitle: 'Качи Error', + indicatorLoadingTitle: 'Качва се ...' + }, + 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); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js new file mode 100644 index 00000000..16514535 --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js @@ -0,0 +1,100 @@ +/*! + * FileInput Català 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['ca'] = { + fileSingle: 'arxiu', + filePlural: 'arxius', + browseLabel: 'Examinar …', + removeLabel: 'Treure', + removeTitle: 'Treure arxius seleccionats', + cancelLabel: 'Cancel', + cancelTitle: 'Avortar la pujada en curs', + uploadLabel: 'Pujar arxiu', + uploadTitle: 'Pujar arxius seleccionats', + msgNo: 'No', + msgNoFilesSelected: '', + msgCancelled: 'cancel·lat', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Vista prèvia detallada', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Arxiu "{name}" ({size} KB) excedeix la mida màxima permès de {maxSize} KB.', + msgFilesTooLess: 'Heu de seleccionar almenys {n} {files} a carregar.', + msgFilesTooMany: 'El nombre d\'arxius seleccionats a carregar ({n}) excedeix el límit màxim permès de {m}.', + msgFileNotFound: 'Arxiu "{name}" no trobat.', + msgFileSecured: 'No es pot accedir a l\'arxiu "{name}" perquè estarà sent usat per una altra aplicació o no tinguem permisos de lectura.', + msgFileNotReadable: 'No es pot accedir a l\'arxiu "{name}".', + msgFilePreviewAborted: 'Previsualització de l\'arxiu "{name}" cancel·lada.', + msgFilePreviewError: 'S\'ha produït un error mentre es llegia el fitxer "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Tipus de fitxer no vàlid per a "{name}". Només arxius "{types}" són permesos.', + msgInvalidFileExtension: 'Extensió de fitxer no vàlid per a "{name}". Només arxius "{extensions}" són permesos.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'La càrrega d\'arxius s\'ha cancel·lat', + msgUploadThreshold: 'Processing...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'Error de validació', + msgLoading: 'Pujant fitxer {index} de {files} …', + msgProgress: 'Pujant fitxer {index} de {files} - {name} - {percent}% completat.', + msgSelected: '{n} {files} seleccionat(s)', + msgFoldersNotAllowed: 'Arrossegueu i deixeu anar únicament arxius. Omesa(es) {n} carpeta(es).', + msgImageWidthSmall: 'L\'ample de la imatge "{name}" ha de ser almenys {size} px.', + msgImageHeightSmall: 'L\'alçada de la imatge "{name}" ha de ser almenys {size} px.', + msgImageWidthLarge: 'L\'ample de la imatge "{name}" no pot excedir de {size} px.', + msgImageHeightLarge: 'L\'alçada de la imatge "{name}" no pot excedir de {size} px.', + msgImageResizeError: 'No s\'ha pogut obtenir les dimensions d\'imatge per canviar la mida.', + msgImageResizeException: 'Error en canviar la mida de la imatge.
{errors}
', + 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: 'Arrossegueu i deixeu anar aquí els arxius …', + dropZoneClickTitle: '
(or click to select {files})', + fileActionSettings: { + removeTitle: 'Eliminar arxiu', + uploadTitle: 'Pujar arxiu', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Veure detalls', + dragTitle: 'Move / Rearrange', + indicatorNewTitle: 'No pujat encara', + indicatorSuccessTitle: 'Subido', + indicatorErrorTitle: 'Pujar Error', + indicatorLoadingTitle: 'Pujant ...' + }, + 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); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js new file mode 100644 index 00000000..685da85d --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js @@ -0,0 +1,101 @@ +/*! + * FileInput Croatian 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 + * @author Milos Stojanovic + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['cr'] = { + fileSingle: 'datoteka', + filePlural: 'datoteke', + browseLabel: 'Izaberi …', + removeLabel: 'Ukloni', + removeTitle: 'Ukloni označene datoteke', + cancelLabel: 'Odustani', + cancelTitle: 'Prekini trenutno otpremanje', + uploadLabel: 'Otpremi', + uploadTitle: 'Otpremi označene datoteke', + msgNo: 'Ne', + msgNoFilesSelected: '', + msgCancelled: 'Otkazan', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Detaljni pregled', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Datoteka "{name}" ({size} KB) prekoračuje maksimalnu dozvoljenu veličinu datoteke od {maxSize} KB.', + msgFilesTooLess: 'Morate odabrati najmanje {n} {files} za otpremanje.', + msgFilesTooMany: 'Broj datoteka označenih za otpremanje ({n}) prekoračuje maksimalni dozvoljeni limit od {m}.', + msgFileNotFound: 'Datoteka "{name}" nije pronađena!', + msgFileSecured: 'Datoteku "{name}" nije moguće pročitati zbog bezbednosnih ograničenja.', + msgFileNotReadable: 'Datoteku "{name}" nije moguće pročitati.', + msgFilePreviewAborted: 'Generisanje prikaza nije moguće za "{name}".', + msgFilePreviewError: 'Došlo je do greške prilikom čitanja datoteke "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Datoteka "{name}" je pogrešnog formata. Dozvoljeni formati su "{types}".', + msgInvalidFileExtension: 'Ekstenzija datoteke "{name}" nije dozvoljena. Dozvoljene ekstenzije su "{extensions}".', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Prijenos datoteka je prekinut', + msgUploadThreshold: 'Processing...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'Provjera pogrešaka', + msgLoading: 'Učitavanje datoteke {index} od {files} …', + msgProgress: 'Učitavanje datoteke {index} od {files} - {name} - {percent}% završeno.', + msgSelected: '{n} {files} je označeno', + msgFoldersNotAllowed: 'Moguće je prevlačiti samo datoteke! Preskočeno je {n} fascikla.', + msgImageWidthSmall: 'Širina slikovnu datoteku "{name}" moraju biti najmanje {size} px.', + msgImageHeightSmall: 'Visina slikovnu datoteku "{name}" moraju biti najmanje {size} px.', + msgImageWidthLarge: 'Širina slikovnu datoteku "{name}" ne može prelaziti {size} px.', + msgImageHeightLarge: 'Visina slikovnu datoteku "{name}" ne može prelaziti {size} px.', + msgImageResizeError: 'Nije mogao dobiti dimenzije slike na veličinu.', + msgImageResizeException: 'Greška prilikom promjene veličine slike.
{errors}
', + 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: 'Prevucite datoteke ovde …', + dropZoneClickTitle: '
(or click to select {files})', + fileActionSettings: { + removeTitle: 'Uklonite datoteku', + uploadTitle: 'Postavi datoteku', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Pregledavati pojedinosti', + dragTitle: 'Move / Rearrange', + indicatorNewTitle: 'Još nije učitao', + indicatorSuccessTitle: 'Preneseno', + indicatorErrorTitle: 'Postavi Greška', + indicatorLoadingTitle: 'Prijenos ...' + }, + 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); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js new file mode 100644 index 00000000..f5e8b723 --- /dev/null +++ b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js @@ -0,0 +1,100 @@ +/*! + * FileInput Czech 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['cs'] = { + fileSingle: 'soubor', + filePlural: 'soubory', + browseLabel: 'Vybrat …', + removeLabel: 'Odstranit', + removeTitle: 'Vyčistit vybrané soubory', + cancelLabel: 'Storno', + cancelTitle: 'Přerušit nahrávání', + uploadLabel: 'Nahrát', + uploadTitle: 'Nahrát vybrané soubory', + msgNo: 'Ne', + msgNoFilesSelected: 'Nevybrány žádné soubory', + msgCancelled: 'Zrušeno', + msgPlaceholder: 'Vybrat {files}...', + msgZoomModalHeading: 'Detailní náhled', + msgFileRequired: 'Musíte vybrat soubor, který chcete nahrát.', + msgSizeTooSmall: 'Soubor "{name}" ({size} KB) je pří