From 22a8d5c35db97d65a90b21d97e6835380191845d Mon Sep 17 00:00:00 2001 From: Robert Jaros Date: Wed, 25 Sep 2019 22:14:22 +0200 Subject: Upgrade Bootstrap to version 4 --- kvision-modules/kvision-handlebars/build.gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'kvision-modules/kvision-handlebars') 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") } } -- cgit From 6b53324c97bfc80ed14dfca6a5dbc879950715b9 Mon Sep 17 00:00:00 2001 From: Robert Jaros Date: Thu, 3 Oct 2019 19:03:21 +0200 Subject: Upgrade to Bootstrap 4. Upgrade to Font Awesome 5. Restructure modules. --- build.gradle | 15 +- kvision-modules/kvision-bootstrap-css/build.gradle | 5 + .../package.json.d/project.info | 3 + .../pl/treksoft/kvision/KVManagerBootstrapCss.kt | 35 ++ .../src/main/resources/css/paper.css | 16 + .../webpack.config.d/bootstrap.js | 4 + .../kvision-bootstrap-css/webpack.config.d/css.js | 2 + .../webpack.config.d/jquery.js | 5 + .../kvision-bootstrap-datetime/build.gradle | 13 + .../package.json.d/project.info | 3 + .../pl/treksoft/kvision/KVManagerDatetime.kt | 75 ++++ .../pl/treksoft/kvision/form/time/DateTime.kt | 246 +++++++++++ .../pl/treksoft/kvision/form/time/DateTimeInput.kt | 328 +++++++++++++++ .../bootstrap-datetimepicker.ar.js | 18 + .../bootstrap-datetimepicker.az.js | 17 + .../bootstrap-datetimepicker.bg.js | 17 + .../bootstrap-datetimepicker.bn.js | 17 + .../bootstrap-datetimepicker.ca.js | 17 + .../bootstrap-datetimepicker.cs.js | 20 + .../bootstrap-datetimepicker.da.js | 17 + .../bootstrap-datetimepicker.de.js | 19 + .../bootstrap-datetimepicker.ee.js | 19 + .../bootstrap-datetimepicker.el.js | 16 + .../bootstrap-datetimepicker.es.js | 17 + .../bootstrap-datetimepicker.fi.js | 17 + .../bootstrap-datetimepicker.fr.js | 19 + .../bootstrap-datetimepicker.he.js | 18 + .../bootstrap-datetimepicker.hr.js | 16 + .../bootstrap-datetimepicker.hu.js | 18 + .../bootstrap-datetimepicker.hy.js | 17 + .../bootstrap-datetimepicker.id.js | 20 + .../bootstrap-datetimepicker.is.js | 17 + .../bootstrap-datetimepicker.it.js | 19 + .../bootstrap-datetimepicker.ja.js | 17 + .../bootstrap-datetimepicker.ka.js | 17 + .../bootstrap-datetimepicker.ko.js | 18 + .../bootstrap-datetimepicker.lt.js | 19 + .../bootstrap-datetimepicker.lv.js | 19 + .../bootstrap-datetimepicker.ms.js | 17 + .../bootstrap-datetimepicker.nb.js | 17 + .../bootstrap-datetimepicker.nl.js | 17 + .../bootstrap-datetimepicker.no.js | 17 + .../bootstrap-datetimepicker.pl.js | 18 + .../bootstrap-datetimepicker.pt-BR.js | 18 + .../bootstrap-datetimepicker.pt.js | 18 + .../bootstrap-datetimepicker.ro.js | 18 + .../bootstrap-datetimepicker.rs-latin.js | 17 + .../bootstrap-datetimepicker.rs.js | 17 + .../bootstrap-datetimepicker.ru.js | 17 + .../bootstrap-datetimepicker.sk.js | 20 + .../bootstrap-datetimepicker.sl.js | 17 + .../bootstrap-datetimepicker.sv.js | 17 + .../bootstrap-datetimepicker.sw.js | 18 + .../bootstrap-datetimepicker.th.js | 17 + .../bootstrap-datetimepicker.tr.js | 18 + .../bootstrap-datetimepicker.ua.js | 16 + .../bootstrap-datetimepicker.uk.js | 17 + .../bootstrap-datetimepicker.zh-TW.js | 17 + .../bootstrap-datetimepicker.zh.js | 17 + .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 +++++ .../kvision/form/time/DateTimeInputSpec.kt | 53 +++ .../pl/treksoft/kvision/form/time/DateTimeSpec.kt | 62 +++ .../webpack.config.d/css.js | 2 + .../kvision-bootstrap-dialog/build.gradle | 6 + .../package.json.d/project.info | 3 + .../kotlin/pl/treksoft/kvision/modal/Dialog.kt | 76 ++++ .../kvision-bootstrap-select-remote/build.gradle | 6 + .../package.json.d/project.info | 3 + .../treksoft/kvision/form/select/SelectRemote.kt | 276 +++++++++++++ .../kvision/form/select/SelectRemoteInput.kt | 140 +++++++ .../kvision-bootstrap-select/build.gradle | 14 + .../package.json.d/project.info | 3 + .../kotlin/pl/treksoft/kvision/KVManagerSelect.kt | 53 +++ .../pl/treksoft/kvision/form/select/AjaxOptions.kt | 140 +++++++ .../pl/treksoft/kvision/form/select/Select.kt | 285 +++++++++++++ .../pl/treksoft/kvision/form/select/SelectInput.kt | 375 +++++++++++++++++ .../treksoft/kvision/form/select/SelectOptGroup.kt | 123 ++++++ .../treksoft/kvision/form/select/SelectOption.kt | 170 ++++++++ .../ajax-bootstrap-select.de-DE.min.js | 22 + .../ajax-bootstrap-select.en-US.min.js | 22 + .../ajax-bootstrap-select.es-ES.min.js | 22 + .../ajax-bootstrap-select.fr-FR.min.js | 22 + .../ajax-bootstrap-select.it-IT.min.js | 22 + .../ajax-bootstrap-select.ja-JP.min.js | 22 + .../ajax-bootstrap-select.ko-KR.min.js | 22 + .../ajax-bootstrap-select.nl-NL.min.js | 22 + .../ajax-bootstrap-select.pl-PL.min.js | 22 + .../ajax-bootstrap-select.pt-BR.min.js | 22 + .../ajax-bootstrap-select.ru-RU.min.js | 22 + .../ajax-bootstrap-select.tr-TR.min.js | 22 + .../bootstrap-select/bootstrap-select-i18n.min.js | 1 + .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 +++++ .../kvision/form/select/SelectInputSpec.kt | 53 +++ .../kvision/form/select/SelectOptGroupSpec.kt | 54 +++ .../kvision/form/select/SelectOptionSpec.kt | 59 +++ .../pl/treksoft/kvision/form/select/SelectSpec.kt | 58 +++ .../webpack.config.d/css.js | 2 + .../kvision-bootstrap-spinner/build.gradle | 13 + .../package.json.d/project.info | 3 + .../kotlin/pl/treksoft/kvision/KVManagerSpinner.kt | 36 ++ .../pl/treksoft/kvision/form/spinner/Spinner.kt | 263 ++++++++++++ .../treksoft/kvision/form/spinner/SpinnerInput.kt | 336 +++++++++++++++ .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 +++++ .../kvision/form/spinner/SpinnerInputSpec.kt | 75 ++++ .../treksoft/kvision/form/spinner/SpinnerSpec.kt | 82 ++++ .../webpack.config.d/css.js | 2 + .../webpack.config.d/jquery.js | 5 + .../kvision-bootstrap-upload/build.gradle | 14 + .../package.json.d/project.info | 3 + .../kotlin/pl/treksoft/kvision/KVManagerUpload.kt | 75 ++++ .../pl/treksoft/kvision/form/upload/Upload.kt | 333 +++++++++++++++ .../pl/treksoft/kvision/form/upload/UploadInput.kt | 375 +++++++++++++++++ .../main/kotlin/pl/treksoft/kvision/utils/Utils.kt | 73 ++++ .../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/he.js | 97 +++++ .../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/uz.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 | 101 +++++ .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 +++++ .../kvision/form/upload/UploadInputSpec.kt | 57 +++ .../pl/treksoft/kvision/form/upload/UploadSpec.kt | 56 +++ .../webpack.config.d/css.js | 2 + .../webpack.config.d/file.js | 6 + kvision-modules/kvision-bootstrap/build.gradle | 5 +- .../pl/treksoft/kvision/KVManagerBootstrap.kt | 55 +-- .../kotlin/pl/treksoft/kvision/core/Component.kt | 133 ++++++ .../pl/treksoft/kvision/dropdown/ContextMenu.kt | 112 +++++ .../pl/treksoft/kvision/dropdown/DropDown.kt | 417 +++++++++++++++++++ .../kotlin/pl/treksoft/kvision/dropdown/Header.kt | 61 +++ .../pl/treksoft/kvision/dropdown/Separator.kt | 57 +++ .../main/kotlin/pl/treksoft/kvision/modal/Alert.kt | 121 ++++++ .../kotlin/pl/treksoft/kvision/modal/CloseIcon.kt | 48 +++ .../kotlin/pl/treksoft/kvision/modal/Confirm.kt | 176 ++++++++ .../main/kotlin/pl/treksoft/kvision/modal/Modal.kt | 292 ++++++++++++++ .../main/kotlin/pl/treksoft/kvision/navbar/Nav.kt | 110 +++++ .../kotlin/pl/treksoft/kvision/navbar/NavForm.kt | 72 ++++ .../kotlin/pl/treksoft/kvision/navbar/Navbar.kt | 229 +++++++++++ .../treksoft/kvision/panel/ResponsiveGridPanel.kt | 185 +++++++++ .../kotlin/pl/treksoft/kvision/panel/TabPanel.kt | 273 +++++++++++++ .../pl/treksoft/kvision/progress/ProgressBar.kt | 162 ++++++++ .../treksoft/kvision/progress/ProgressIndicator.kt | 125 ++++++ .../pl/treksoft/kvision/toolbar/ButtonGroup.kt | 109 +++++ .../kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt | 63 +++ .../pl/treksoft/kvision/window/MaximizeIcon.kt | 48 +++ .../pl/treksoft/kvision/window/MinimizeIcon.kt | 48 +++ .../kotlin/pl/treksoft/kvision/window/Window.kt | 449 +++++++++++++++++++++ .../src/main/resources/css/kvbootstrap.css | 291 +++++++++++++ .../src/main/resources/css/paper.css | 16 - .../src/main/resources/css/style.css | 226 ----------- .../treksoft/kvision/dropdown/ContextMenuSpec.kt | 75 ++++ .../pl/treksoft/kvision/dropdown/HeaderSpec.kt | 46 +++ .../pl/treksoft/kvision/dropdown/SeparatorSpec.kt | 46 +++ .../test/pl/treksoft/kvision/navbar/NavFormSpec.kt | 54 +++ .../test/pl/treksoft/kvision/navbar/NavSpec.kt | 54 +++ .../test/pl/treksoft/kvision/navbar/NavbarSpec.kt | 70 ++++ .../kvision/panel/ResponsiveGridPanelSpec.kt | 50 +++ .../test/pl/treksoft/kvision/panel/TabPanelSpec.kt | 117 ++++++ .../treksoft/kvision/progress/ProgressBarSpec.kt | 56 +++ .../kvision/progress/ProgressIndicatorSpec.kt | 55 +++ .../pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt | 57 +++ .../pl/treksoft/kvision/toolbar/ToolbarSpec.kt | 47 +++ .../kotlin/pl/treksoft/kvision/KVManagerChart.kt | 6 +- kvision-modules/kvision-datetime/build.gradle | 9 - .../kvision-datetime/package.json.d/project.info | 3 - .../pl/treksoft/kvision/KVManagerDatetime.kt | 81 ---- .../pl/treksoft/kvision/form/time/DateTime.kt | 246 ----------- .../pl/treksoft/kvision/form/time/DateTimeInput.kt | 320 --------------- .../bootstrap-datetimepicker.ar.js | 18 - .../bootstrap-datetimepicker.az.js | 17 - .../bootstrap-datetimepicker.bg.js | 17 - .../bootstrap-datetimepicker.bn.js | 17 - .../bootstrap-datetimepicker.ca.js | 17 - .../bootstrap-datetimepicker.cs.js | 20 - .../bootstrap-datetimepicker.da.js | 17 - .../bootstrap-datetimepicker.de.js | 19 - .../bootstrap-datetimepicker.ee.js | 19 - .../bootstrap-datetimepicker.el.js | 16 - .../bootstrap-datetimepicker.es.js | 17 - .../bootstrap-datetimepicker.fi.js | 17 - .../bootstrap-datetimepicker.fr.js | 19 - .../bootstrap-datetimepicker.he.js | 18 - .../bootstrap-datetimepicker.hr.js | 16 - .../bootstrap-datetimepicker.hu.js | 18 - .../bootstrap-datetimepicker.hy.js | 17 - .../bootstrap-datetimepicker.id.js | 20 - .../bootstrap-datetimepicker.is.js | 17 - .../bootstrap-datetimepicker.it.js | 19 - .../bootstrap-datetimepicker.ja.js | 17 - .../bootstrap-datetimepicker.ka.js | 17 - .../bootstrap-datetimepicker.ko.js | 18 - .../bootstrap-datetimepicker.lt.js | 19 - .../bootstrap-datetimepicker.lv.js | 19 - .../bootstrap-datetimepicker.ms.js | 17 - .../bootstrap-datetimepicker.nb.js | 17 - .../bootstrap-datetimepicker.nl.js | 17 - .../bootstrap-datetimepicker.no.js | 17 - .../bootstrap-datetimepicker.pl.js | 18 - .../bootstrap-datetimepicker.pt-BR.js | 18 - .../bootstrap-datetimepicker.pt.js | 18 - .../bootstrap-datetimepicker.ro.js | 18 - .../bootstrap-datetimepicker.rs-latin.js | 17 - .../bootstrap-datetimepicker.rs.js | 17 - .../bootstrap-datetimepicker.ru.js | 17 - .../bootstrap-datetimepicker.sk.js | 20 - .../bootstrap-datetimepicker.sl.js | 17 - .../bootstrap-datetimepicker.sv.js | 17 - .../bootstrap-datetimepicker.sw.js | 18 - .../bootstrap-datetimepicker.th.js | 17 - .../bootstrap-datetimepicker.tr.js | 18 - .../bootstrap-datetimepicker.ua.js | 16 - .../bootstrap-datetimepicker.uk.js | 17 - .../bootstrap-datetimepicker.zh-TW.js | 17 - .../bootstrap-datetimepicker.zh.js | 17 - .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 ----- .../kvision/form/time/DateTimeInputSpec.kt | 53 --- .../pl/treksoft/kvision/form/time/DateTimeSpec.kt | 62 --- .../kvision-datetime/webpack.config.d/css.js | 2 - kvision-modules/kvision-dialog/build.gradle | 5 - .../kvision-dialog/package.json.d/project.info | 3 - .../kotlin/pl/treksoft/kvision/modal/Dialog.kt | 76 ---- kvision-modules/kvision-fontawesome/build.gradle | 9 + .../package.json.d/project.info | 3 + .../pl/treksoft/kvision/KVManagerFontAwesome.kt | 35 ++ .../webpack.config.d/bootstrap.js | 4 + .../kvision-fontawesome/webpack.config.d/css.js | 2 + .../kvision-fontawesome/webpack.config.d/jquery.js | 5 + .../pl/treksoft/kvision/KVManagerHandlebars.kt | 6 +- .../kotlin/pl/treksoft/kvision/KVManagerI18n.kt | 6 +- .../kotlin/pl/treksoft/kvision/KVManagerMoment.kt | 8 +- .../kotlin/pl/treksoft/kvision/KVManagerPace.kt | 8 +- .../kotlin/pl/treksoft/kvision/KVManagerRedux.kt | 14 +- .../kotlin/pl/treksoft/kvision/remote/Profile.kt | 8 - .../pl/treksoft/kvision/KVManagerRichText.kt | 10 +- .../pl/treksoft/kvision/form/text/RichText.kt | 2 +- kvision-modules/kvision-select-remote/build.gradle | 6 - .../package.json.d/project.info | 3 - .../treksoft/kvision/form/select/SelectRemote.kt | 276 ------------- .../kvision/form/select/SelectRemoteInput.kt | 140 ------- kvision-modules/kvision-select/build.gradle | 10 - .../kvision-select/package.json.d/project.info | 3 - .../kotlin/pl/treksoft/kvision/KVManagerSelect.kt | 65 --- .../pl/treksoft/kvision/form/select/AjaxOptions.kt | 140 ------- .../pl/treksoft/kvision/form/select/Select.kt | 285 ------------- .../pl/treksoft/kvision/form/select/SelectInput.kt | 367 ----------------- .../treksoft/kvision/form/select/SelectOptGroup.kt | 123 ------ .../treksoft/kvision/form/select/SelectOption.kt | 174 -------- .../ajax-bootstrap-select.de-DE.min.js | 22 - .../ajax-bootstrap-select.en-US.min.js | 22 - .../ajax-bootstrap-select.es-ES.min.js | 22 - .../ajax-bootstrap-select.fr-FR.min.js | 22 - .../ajax-bootstrap-select.it-IT.min.js | 22 - .../ajax-bootstrap-select.ja-JP.min.js | 22 - .../ajax-bootstrap-select.ko-KR.min.js | 22 - .../ajax-bootstrap-select.nl-NL.min.js | 22 - .../ajax-bootstrap-select.pl-PL.min.js | 22 - .../ajax-bootstrap-select.pt-BR.min.js | 22 - .../ajax-bootstrap-select.ru-RU.min.js | 22 - .../ajax-bootstrap-select.tr-TR.min.js | 22 - .../bootstrap-select/bootstrap-select-i18n.min.js | 1 - .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 ----- .../kvision/form/select/SelectInputSpec.kt | 53 --- .../kvision/form/select/SelectOptGroupSpec.kt | 54 --- .../kvision/form/select/SelectOptionSpec.kt | 59 --- .../pl/treksoft/kvision/form/select/SelectSpec.kt | 58 --- .../kvision-select/webpack.config.d/css.js | 2 - kvision-modules/kvision-spinner/build.gradle | 9 - .../kvision-spinner/package.json.d/project.info | 3 - .../kotlin/pl/treksoft/kvision/KVManagerSpinner.kt | 42 -- .../pl/treksoft/kvision/form/spinner/Spinner.kt | 263 ------------ .../treksoft/kvision/form/spinner/SpinnerInput.kt | 328 --------------- .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 ----- .../kvision/form/spinner/SpinnerInputSpec.kt | 75 ---- .../treksoft/kvision/form/spinner/SpinnerSpec.kt | 82 ---- .../kvision-spinner/webpack.config.d/css.js | 2 - .../kvision-spinner/webpack.config.d/jquery.js | 5 - .../pl/treksoft/kvision/KVManagerTabulator.kt | 14 +- kvision-modules/kvision-upload/build.gradle | 13 - .../kvision-upload/package.json.d/project.info | 3 - .../kotlin/pl/treksoft/kvision/KVManagerUpload.kt | 86 ---- .../pl/treksoft/kvision/form/upload/Upload.kt | 333 --------------- .../pl/treksoft/kvision/form/upload/UploadInput.kt | 367 ----------------- .../main/kotlin/pl/treksoft/kvision/utils/Utils.kt | 73 ---- .../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/he.js | 97 ----- .../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/uz.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 | 101 ----- .../kotlin/test/pl/treksoft/kvision/TestUtil.kt | 100 ----- .../kvision/form/upload/UploadInputSpec.kt | 57 --- .../pl/treksoft/kvision/form/upload/UploadSpec.kt | 56 --- .../kvision-upload/webpack.config.d/css.js | 2 - .../kvision-upload/webpack.config.d/file.js | 6 - settings.gradle | 48 +-- src/main/kotlin/pl/treksoft/kvision/KVManager.kt | 57 +-- src/main/kotlin/pl/treksoft/kvision/core/Widget.kt | 66 ++- .../pl/treksoft/kvision/dropdown/ContextMenu.kt | 98 ----- .../pl/treksoft/kvision/dropdown/DropDown.kt | 333 --------------- .../kotlin/pl/treksoft/kvision/dropdown/Header.kt | 62 --- .../pl/treksoft/kvision/dropdown/Separator.kt | 63 --- .../kotlin/pl/treksoft/kvision/form/FormControl.kt | 45 ++- .../kotlin/pl/treksoft/kvision/form/FormPanel.kt | 46 ++- .../kotlin/pl/treksoft/kvision/form/HelpBlock.kt | 37 -- .../kotlin/pl/treksoft/kvision/form/HelpText.kt | 37 ++ .../pl/treksoft/kvision/form/InvalidFeedback.kt | 37 ++ .../pl/treksoft/kvision/form/check/CheckBox.kt | 32 +- .../pl/treksoft/kvision/form/check/CheckInput.kt | 8 + .../kotlin/pl/treksoft/kvision/form/check/Radio.kt | 40 +- .../pl/treksoft/kvision/form/check/RadioGroup.kt | 60 ++- .../treksoft/kvision/form/check/RadioGroupInput.kt | 14 + .../treksoft/kvision/form/select/SimpleSelect.kt | 8 +- .../kvision/form/select/SimpleSelectInput.kt | 8 + .../pl/treksoft/kvision/form/text/AbstractText.kt | 6 +- .../kvision/form/text/AbstractTextInput.kt | 8 + .../kotlin/pl/treksoft/kvision/form/text/Text.kt | 2 +- .../pl/treksoft/kvision/form/text/TextArea.kt | 2 +- src/main/kotlin/pl/treksoft/kvision/html/Button.kt | 35 +- src/main/kotlin/pl/treksoft/kvision/html/Icon.kt | 8 +- src/main/kotlin/pl/treksoft/kvision/html/Image.kt | 6 +- src/main/kotlin/pl/treksoft/kvision/html/Label.kt | 51 --- src/main/kotlin/pl/treksoft/kvision/html/Link.kt | 33 -- src/main/kotlin/pl/treksoft/kvision/html/List.kt | 5 +- src/main/kotlin/pl/treksoft/kvision/html/Tag.kt | 6 + src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt | 121 ------ .../kotlin/pl/treksoft/kvision/modal/CloseIcon.kt | 48 --- .../kotlin/pl/treksoft/kvision/modal/Confirm.kt | 176 -------- src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt | 298 -------------- src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt | 73 ---- .../kotlin/pl/treksoft/kvision/navbar/NavForm.kt | 74 ---- .../kotlin/pl/treksoft/kvision/navbar/Navbar.kt | 195 --------- .../treksoft/kvision/panel/ResponsiveGridPanel.kt | 185 --------- src/main/kotlin/pl/treksoft/kvision/panel/Root.kt | 26 +- .../pl/treksoft/kvision/panel/SimplePanel.kt | 4 +- .../kotlin/pl/treksoft/kvision/panel/TabPanel.kt | 270 ------------- .../pl/treksoft/kvision/progress/ProgressBar.kt | 162 -------- .../treksoft/kvision/progress/ProgressIndicator.kt | 125 ------ src/main/kotlin/pl/treksoft/kvision/table/Cell.kt | 16 + .../kotlin/pl/treksoft/kvision/table/HeaderCell.kt | 13 +- src/main/kotlin/pl/treksoft/kvision/table/Table.kt | 46 ++- .../pl/treksoft/kvision/toolbar/ButtonGroup.kt | 103 ----- .../kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt | 58 --- .../pl/treksoft/kvision/window/MaximizeIcon.kt | 48 --- .../pl/treksoft/kvision/window/MinimizeIcon.kt | 48 --- .../kotlin/pl/treksoft/kvision/window/Window.kt | 446 -------------------- src/main/resources/css/style.css | 78 ++++ .../treksoft/kvision/dropdown/ContextMenuSpec.kt | 75 ---- .../pl/treksoft/kvision/dropdown/HeaderSpec.kt | 46 --- .../pl/treksoft/kvision/dropdown/SeparatorSpec.kt | 46 --- .../test/pl/treksoft/kvision/form/HelpBlockSpec.kt | 47 --- .../test/pl/treksoft/kvision/form/HelpTextSpec.kt | 47 +++ .../pl/treksoft/kvision/form/check/RadioSpec.kt | 2 +- .../test/pl/treksoft/kvision/form/text/TextSpec.kt | 2 +- .../test/pl/treksoft/kvision/navbar/NavFormSpec.kt | 54 --- .../test/pl/treksoft/kvision/navbar/NavSpec.kt | 54 --- .../test/pl/treksoft/kvision/navbar/NavbarSpec.kt | 70 ---- .../kvision/panel/ResponsiveGridPanelSpec.kt | 50 --- .../test/pl/treksoft/kvision/panel/TabPanelSpec.kt | 117 ------ .../treksoft/kvision/progress/ProgressBarSpec.kt | 56 --- .../kvision/progress/ProgressIndicatorSpec.kt | 55 --- .../test/pl/treksoft/kvision/table/TableSpec.kt | 3 +- .../pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt | 57 --- .../pl/treksoft/kvision/toolbar/ToolbarSpec.kt | 47 --- 433 files changed, 15142 insertions(+), 14482 deletions(-) create mode 100644 kvision-modules/kvision-bootstrap-css/build.gradle create mode 100644 kvision-modules/kvision-bootstrap-css/package.json.d/project.info create mode 100644 kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt create mode 100644 kvision-modules/kvision-bootstrap-css/src/main/resources/css/paper.css create mode 100644 kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js create mode 100644 kvision-modules/kvision-bootstrap-css/webpack.config.d/css.js create mode 100644 kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/build.gradle create mode 100644 kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js create mode 100644 kvision-modules/kvision-bootstrap-dialog/build.gradle create mode 100644 kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info create mode 100644 kvision-modules/kvision-bootstrap-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt create mode 100644 kvision-modules/kvision-bootstrap-select-remote/build.gradle create mode 100644 kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info create mode 100644 kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt create mode 100644 kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt create mode 100644 kvision-modules/kvision-bootstrap-select/build.gradle create mode 100644 kvision-modules/kvision-bootstrap-select/package.json.d/project.info create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js create mode 100644 kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-select/webpack.config.d/css.js create mode 100644 kvision-modules/kvision-bootstrap-spinner/build.gradle create mode 100644 kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info create mode 100644 kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt create mode 100644 kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt create mode 100644 kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt create mode 100644 kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt create mode 100644 kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-spinner/webpack.config.d/css.js create mode 100644 kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js create mode 100644 kvision-modules/kvision-bootstrap-upload/build.gradle create mode 100644 kvision-modules/kvision-bootstrap-upload/package.json.d/project.info create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js create mode 100644 kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt create mode 100644 kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt create mode 100644 kvision-modules/kvision-bootstrap-upload/webpack.config.d/css.js create mode 100644 kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt create mode 100644 kvision-modules/kvision-bootstrap/src/main/resources/css/kvbootstrap.css delete mode 100644 kvision-modules/kvision-bootstrap/src/main/resources/css/paper.css delete mode 100644 kvision-modules/kvision-bootstrap/src/main/resources/css/style.css create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt create mode 100644 kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt delete mode 100644 kvision-modules/kvision-datetime/build.gradle delete mode 100644 kvision-modules/kvision-datetime/package.json.d/project.info delete mode 100644 kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt delete mode 100644 kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt delete mode 100644 kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js delete mode 100644 kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js delete mode 100644 kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt delete mode 100644 kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt delete mode 100644 kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt delete mode 100644 kvision-modules/kvision-datetime/webpack.config.d/css.js delete mode 100644 kvision-modules/kvision-dialog/build.gradle delete mode 100644 kvision-modules/kvision-dialog/package.json.d/project.info delete mode 100644 kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt create mode 100644 kvision-modules/kvision-fontawesome/build.gradle create mode 100644 kvision-modules/kvision-fontawesome/package.json.d/project.info create mode 100644 kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt create mode 100644 kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js create mode 100644 kvision-modules/kvision-fontawesome/webpack.config.d/css.js create mode 100644 kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js delete mode 100644 kvision-modules/kvision-select-remote/build.gradle delete mode 100644 kvision-modules/kvision-select-remote/package.json.d/project.info delete mode 100644 kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt delete mode 100644 kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt delete mode 100644 kvision-modules/kvision-select/build.gradle delete mode 100644 kvision-modules/kvision-select/package.json.d/project.info delete mode 100644 kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt delete mode 100644 kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt delete mode 100644 kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt delete mode 100644 kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt delete mode 100644 kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt delete mode 100644 kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js delete mode 100644 kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js delete mode 100644 kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt delete mode 100644 kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt delete mode 100644 kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt delete mode 100644 kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt delete mode 100644 kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt delete mode 100644 kvision-modules/kvision-select/webpack.config.d/css.js delete mode 100644 kvision-modules/kvision-spinner/build.gradle delete mode 100644 kvision-modules/kvision-spinner/package.json.d/project.info delete mode 100644 kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt delete mode 100644 kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt delete mode 100644 kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt delete mode 100644 kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt delete mode 100644 kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt delete mode 100644 kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt delete mode 100644 kvision-modules/kvision-spinner/webpack.config.d/css.js delete mode 100644 kvision-modules/kvision-spinner/webpack.config.d/jquery.js delete mode 100644 kvision-modules/kvision-upload/build.gradle delete mode 100644 kvision-modules/kvision-upload/package.json.d/project.info delete mode 100644 kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt delete mode 100644 kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt delete mode 100644 kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt delete mode 100644 kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js delete mode 100644 kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js delete mode 100644 kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt delete mode 100644 kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt delete mode 100644 kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt delete mode 100644 kvision-modules/kvision-upload/webpack.config.d/css.js delete mode 100644 kvision-modules/kvision-upload/webpack.config.d/file.js delete mode 100644 src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt create mode 100644 src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt create mode 100644 src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/html/Label.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt delete mode 100644 src/main/kotlin/pl/treksoft/kvision/window/Window.kt create mode 100644 src/main/resources/css/style.css delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt create mode 100644 src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt delete mode 100644 src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt (limited to 'kvision-modules/kvision-handlebars') diff --git a/build.gradle b/build.gradle index af9c8ac6..da4ab01a 100644 --- a/build.gradle +++ b/build.gradle @@ -135,7 +135,6 @@ if (!project.gradle.startParameter.taskNames.contains("dokka")) { dependency("snabbdom", "0.7.3") dependency("snabbdom-virtualize", "0.7.0") dependency("jquery-resizable-dom", "0.32.0") - dependency("element-resize-event", "3.0.3") dependency("navigo", "7.1.2") devDependency("karma", "4.3.0") devDependency("karma-chrome-launcher", "3.1.0") @@ -160,23 +159,25 @@ if (!project.gradle.startParameter.taskNames.contains("dokka")) { dokka { includes = ['Module.md'] sourceDirs = files('kvision-modules/kvision-bootstrap/src/main/kotlin', - 'kvision-modules/kvision-select/src/main/kotlin', - 'kvision-modules/kvision-datetime/src/main/kotlin', - 'kvision-modules/kvision-spinner/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-css/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-select/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-datetime/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-spinner/src/main/kotlin', 'kvision-modules/kvision-richtext/src/main/kotlin', - 'kvision-modules/kvision-upload/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-upload/src/main/kotlin', 'kvision-modules/kvision-handlebars/src/main/kotlin', 'kvision-modules/kvision-i18n/src/main/kotlin', 'kvision-modules/kvision-chart/src/main/kotlin', 'kvision-modules/kvision-datacontainer/src/main/kotlin', - 'kvision-modules/kvision-dialog/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-dialog/src/main/kotlin', + 'kvision-modules/kvision-fontawesome/src/main/kotlin', 'kvision-modules/kvision-redux/src/main/kotlin', 'kvision-modules/kvision-redux-kotlin/src/main/kotlin', 'kvision-modules/kvision-moment/src/main/kotlin', 'kvision-modules/kvision-tabulator/src/main/kotlin', 'kvision-modules/kvision-pace/src/main/kotlin', 'kvision-modules/kvision-remote/src/main/kotlin', - 'kvision-modules/kvision-select-remote/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin', 'kvision-modules/kvision-tabulator-remote/src/main/kotlin', 'kvision-modules/kvision-common/src/main/kotlin', 'kvision-modules/kvision-common-types/src/main/kotlin', diff --git a/kvision-modules/kvision-bootstrap-css/build.gradle b/kvision-modules/kvision-bootstrap-css/build.gradle new file mode 100644 index 00000000..0d47049b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/build.gradle @@ -0,0 +1,5 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} 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/src/main/resources/css/paper.css b/kvision-modules/kvision-bootstrap-css/src/main/resources/css/paper.css new file mode 100644 index 00000000..1c783608 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/src/main/resources/css/paper.css @@ -0,0 +1,16 @@ +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-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-bootstrap-css/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/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-css/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/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-datetime/build.gradle b/kvision-modules/kvision-bootstrap-datetime/build.gradle new file mode 100644 index 00000000..fb440934 --- /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("bootstrap-datetime-picker", "2.4.4") + } + +} diff --git a/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info b/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info new file mode 100644 index 00000000..3d332806 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Datetime module" +} 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..41f8620f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt @@ -0,0 +1,75 @@ +/* + * 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("bootstrap-datetime-picker/css/bootstrap-datetimepicker.min.css") + 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") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..7fb35057 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt @@ -0,0 +1,246 @@ +/* + * 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 pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.core.StringBoolPair +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.form.DateFormControl +import pl.treksoft.kvision.form.FieldLabel +import pl.treksoft.kvision.form.InvalidFeedback +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.SnOn +import kotlin.js.Date + +/** + * Form field date/time chooser component. + * + * @constructor + * @param value date/time input value + * @param name the name attribute of the generated HTML input element + * @param format date/time format (default YYYY-MM-DD HH:mm) + * @param label label text bound to the input element + * @param rich determines if [label] can contain HTML code + */ +open class DateTime( + value: Date? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null, + rich: Boolean = false +) : SimplePanel(setOf("form-group")), DateFormControl { + + /** + * Date/time input value. + */ + override var value + get() = input.value + set(value) { + input.value = value + } + /** + * Date/time format. + */ + var format + get() = input.format + set(value) { + input.format = value + } + /** + * The placeholder for the date/time input. + */ + var placeholder + get() = input.placeholder + set(value) { + input.placeholder = value + } + /** + * Determines if the date/time 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 + } + /** + * 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 + get() = input.daysOfWeekDisabled + set(value) { + input.daysOfWeekDisabled = value + } + /** + * Determines if *Clear* button should be visible. + */ + var clearBtn + get() = input.clearBtn + set(value) { + input.clearBtn = value + } + /** + * Determines if *Today* button should be visible. + */ + var todayBtn + get() = input.todayBtn + set(value) { + input.todayBtn = value + } + /** + * Determines if the current day should be highlighted. + */ + var todayHighlight + get() = input.todayHighlight + set(value) { + input.todayHighlight = value + } + /** + * The increment used to build the hour view. + */ + var minuteStep + get() = input.minuteStep + set(value) { + input.minuteStep = value + } + /** + * Determines if meridian views are visible in day and hour views. + */ + var showMeridian + get() = input.showMeridian + set(value) { + input.showMeridian = value + } + /** + * The label text bound to the 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 + } + + private val idc = "kv_form_time_$counter" + final override val input: DateTimeInput = DateTimeInput(value, format).apply { + this.id = idc + this.name = name + } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + init { + @Suppress("LeakingThis") + input.eventTarget = this + this.addInternal(flabel) + this.addInternal(input) + this.addInternal(invalidFeedback) + counter++ + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + if (validatorError != null) { + cl.add("text-danger" 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 + } + + /** + * Open date/time chooser popup. + */ + open fun showPopup() { + input.showPopup() + } + + /** + * Hides date/time chooser popup. + */ + open fun hidePopup() { + input.hidePopup() + } + + override fun getValueAsString(): String? { + return input.getValueAsString() + } + + 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.dateTime( + value: Date? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null, + rich: Boolean = false, init: (DateTime.() -> Unit)? = null + ): DateTime { + val dateTime = DateTime(value, name, format, label, rich).apply { init?.invoke(this) } + this.add(dateTime) + return dateTime + } + } +} 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..66cb6cc0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt @@ -0,0 +1,328 @@ +/* + * 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.form.ValidationStatus +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 = setOf() +) : Widget(classes + "form-control"), FormInput { + + private var initialized = false + + init { + this.setInternalEventListener { + 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() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? 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()) { 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 { + val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } + size?.let { + cl.add(it.className to true) + } + return cl + } + + override fun getSnAttrs(): List { + 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 = 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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js new file mode 100644 index 00000000..a43b4739 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js @@ -0,0 +1,18 @@ +/** +* Arabic translation for bootstrap-datetimepicker +* Ala' Mohammad +*/ +;(function($){ + $.fn.datetimepicker.dates['ar'] = { + days: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"], + daysShort: ["أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت", "أحد"], + daysMin: ["أح", "إث", "ث", "أر", "خ", "ج", "س", "أح"], + months: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"], + monthsShort: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"], + today: "هذا اليوم", + clear: "x", + suffix: [], + meridiem: [], + rtl: true + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js new file mode 100644 index 00000000..c840d6f0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js @@ -0,0 +1,17 @@ +/** + * Azerbaijani translation for bootstrap-datetimepicker + * Konstantin Kaluzhnikov + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js new file mode 100644 index 00000000..3bc7e273 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js @@ -0,0 +1,17 @@ +/** + * Bulgarian translation for bootstrap-datetimepicker + * Apostol Apostolov + */ +;(function($){ + $.fn.datetimepicker.dates['bg'] = { + days: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота", "Неделя"], + daysShort: ["Нед", "Пон", "Вто", "Сря", "Чет", "Пет", "Съб", "Нед"], + daysMin: ["Н", "П", "В", "С", "Ч", "П", "С", "Н"], + months: ["Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"], + monthsShort: ["Ян", "Фев", "Мар", "Апр", "Май", "Юни", "Юли", "Авг", "Сеп", "Окт", "Ное", "Дек"], + today: "днес", + clear: "x", + suffix: [], + meridiem: [] + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js new file mode 100644 index 00000000..b46bd54f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js @@ -0,0 +1,17 @@ +/** + * Bangla(Bangladesh) translation for bootstrap-datetimepicker + * Mahbub Rabbani + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js new file mode 100644 index 00000000..d3137a2d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js @@ -0,0 +1,17 @@ +/** + * Catalan translation for bootstrap-datetimepicker + * J. Garcia + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js new file mode 100644 index 00000000..318cd5cf --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js @@ -0,0 +1,20 @@ +/** + * Czech translation for bootstrap-datetimepicker + * Matěj Koubík + * Fixes by Michal Remiš + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js new file mode 100644 index 00000000..30d9a34a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js @@ -0,0 +1,17 @@ +/** + * Danish translation for bootstrap-datetimepicker + * Christian Pedersen + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js new file mode 100644 index 00000000..52a19060 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js @@ -0,0 +1,19 @@ +/** + * German translation for bootstrap-datetimepicker + * Sam Zurcher + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js new file mode 100644 index 00000000..882378f3 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js @@ -0,0 +1,19 @@ +/** + * Estonian translation for bootstrap-datetimepicker + * Rene Korss + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js new file mode 100644 index 00000000..cbbdc9a7 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js @@ -0,0 +1,16 @@ +/** +* 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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js new file mode 100644 index 00000000..bbf3c207 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js @@ -0,0 +1,17 @@ +/** + * Spanish translation for bootstrap-datetimepicker + * Bruno Bonamin + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js new file mode 100644 index 00000000..95eb4a8d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js @@ -0,0 +1,17 @@ +/** + * Finnish translation for bootstrap-datetimepicker + * Jaakko Salonen + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js new file mode 100644 index 00000000..f9194cbd --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js @@ -0,0 +1,19 @@ +/** + * French translation for bootstrap-datetimepicker + * Nico Mollet + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js new file mode 100644 index 00000000..1060a4a7 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js @@ -0,0 +1,18 @@ +/** + * Hebrew translation for bootstrap-datetimepicker + * Sagie Maoz + */ +;(function($){ + $.fn.datetimepicker.dates['he'] = { + days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"], + daysShort: ["א", "ב", "ג", "ד", "ה", "ו", "ש", "א"], + daysMin: ["א", "ב", "ג", "ד", "ה", "ו", "ש", "א"], + months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"], + monthsShort: ["ינו", "פבר", "מרץ", "אפר", "מאי", "יונ", "יול", "אוג", "ספט", "אוק", "נוב", "דצמ"], + today: "היום", + clear: "x", + suffix: [], + meridiem: [], + rtl: true + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js new file mode 100644 index 00000000..f85540fa --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js @@ -0,0 +1,16 @@ +/** + * 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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js new file mode 100644 index 00000000..5de9fe9e --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js @@ -0,0 +1,18 @@ +/** + * Hungarian translation for bootstrap-datetimepicker + * 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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js new file mode 100644 index 00000000..cedee4db --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js @@ -0,0 +1,17 @@ +/** + * Armenian translation for bootstrap-datepicker + * Hayk Chamyan + */ +;(function($){ + $.fn.datetimepicker.dates['hy'] = { + days: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ", "Կիրակի"], + daysShort: ["Կիր", "Երկ", "Երք", "Չոր", "Հնգ", "Ուր", "Շաբ", "Կիր"], + daysMin: ["Կի", "Եկ", "Եք", "Չո", "Հի", "Ու", "Շա", "Կի"], + months: ["Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"], + monthsShort: ["Հնվ", "Փետ", "Մար", "Ապր", "Մայ", "Հուն", "Հուլ", "Օգս", "Սեպ", "Հոկ", "Նոյ", "Դեկ"], + today: "Այսօր", + clear: "x", + suffix: [], + meridiem: [] + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js new file mode 100644 index 00000000..feef4a3b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js @@ -0,0 +1,20 @@ +/** + * Bahasa translation for bootstrap-datetimepicker + * Azwar Akbar + * Addtional by Yulian Sutopo + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js new file mode 100644 index 00000000..9944c6d7 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js @@ -0,0 +1,17 @@ +/** + * Icelandic translation for bootstrap-datetimepicker + * Hinrik Örn Sigurðsson + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js new file mode 100644 index 00000000..c00a0499 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js @@ -0,0 +1,19 @@ +/** + * Italian translation for bootstrap-datetimepicker + * Enrico Rubboli + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js new file mode 100644 index 00000000..3a2d3b9b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js @@ -0,0 +1,17 @@ +/** + * Japanese translation for bootstrap-datetimepicker + * Norio 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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js new file mode 100644 index 00000000..d4595eff --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js @@ -0,0 +1,17 @@ +/** + * Georgian translation for bootstrap-datetimepicker + * Zura Jijavadze + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js new file mode 100644 index 00000000..adeb6cb6 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js @@ -0,0 +1,18 @@ +/** + * Korean translation for bootstrap-datetimepicker + * Gu Youn + * Baekjoon Choi + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js new file mode 100644 index 00000000..917243c4 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js @@ -0,0 +1,19 @@ +/** + * Lithuanian translation for bootstrap-datetimepicker + * Šarūnas Gliebus + */ + +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js new file mode 100644 index 00000000..f9b3c774 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js @@ -0,0 +1,19 @@ +/** + * Latvian translation for bootstrap-datetimepicker + * Artis Avotins + */ + +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js new file mode 100644 index 00000000..26a2cc0e --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js @@ -0,0 +1,17 @@ +/** + * Malay translation for bootstrap-datetimepicker + * Ateman Faiz + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js new file mode 100644 index 00000000..a2fd01a6 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js @@ -0,0 +1,17 @@ +/** + * Norwegian (bokmål) translation for bootstrap-datetimepicker + * Fredrik Sundmyhr + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js new file mode 100644 index 00000000..a28fa031 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js @@ -0,0 +1,17 @@ +/** + * Dutch translation for bootstrap-datetimepicker + * Reinier Goltstein + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js new file mode 100644 index 00000000..36e33a0b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js @@ -0,0 +1,17 @@ +/** + * Norwegian translation for bootstrap-datetimepicker + * Rune Warhuus + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js new file mode 100644 index 00000000..12fc7422 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js @@ -0,0 +1,18 @@ +/** + * Polish translation for bootstrap-datetimepicker + * Robert + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js new file mode 100644 index 00000000..1d307416 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js @@ -0,0 +1,18 @@ +/** + * Brazilian translation for bootstrap-datetimepicker + * Cauan Cabral + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js new file mode 100644 index 00000000..166034ef --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js @@ -0,0 +1,18 @@ +/** + * Portuguese translation for bootstrap-datetimepicker + * Original code: Cauan Cabral + * Tiago Melo + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js new file mode 100644 index 00000000..a7569c6f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js @@ -0,0 +1,18 @@ +/** + * Romanian translation for bootstrap-datetimepicker + * Cristian Vasile + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js new file mode 100644 index 00000000..57c819f9 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js @@ -0,0 +1,17 @@ +/** + * Serbian latin translation for bootstrap-datetimepicker + * Bojan Milosavlević + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js new file mode 100644 index 00000000..3e9db3e6 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js @@ -0,0 +1,17 @@ +/** + * Serbian cyrillic translation for bootstrap-datetimepicker + * Bojan Milosavlević + */ +;(function($){ + $.fn.datetimepicker.dates['rs'] = { + days: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота", "Недеља"], + daysShort: ["Нед", "Пон", "Уто", "Сре", "Чет", "Пет", "Суб", "Нед"], + daysMin: ["Н", "По", "У", "Ср", "Ч", "Пе", "Су", "Н"], + months: ["Јануар", "Фебруар", "Март", "Април", "Мај", "Јун", "Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар"], + monthsShort: ["Јан", "Феб", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Нов", "Дец"], + today: "Данас", + clear: "x", + suffix: [], + meridiem: [] + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js new file mode 100644 index 00000000..20caf251 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js @@ -0,0 +1,17 @@ +/** + * Russian translation for bootstrap-datetimepicker + * Victor Taranenko + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js new file mode 100644 index 00000000..acf1495a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js @@ -0,0 +1,20 @@ +/** + * Slovak translation for bootstrap-datetimepicker + * Marek Lichtner + * Fixes by Michal Remiš + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js new file mode 100644 index 00000000..a7e58bdf --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js @@ -0,0 +1,17 @@ +/** + * Slovene translation for bootstrap-datetimepicker + * Gregor Rudolf + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js new file mode 100644 index 00000000..050125ad --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js @@ -0,0 +1,17 @@ +/** + * Swedish translation for bootstrap-datetimepicker + * Patrik Ragnarsson + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js new file mode 100644 index 00000000..8cdb4df2 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js @@ -0,0 +1,18 @@ +/** + * Swahili translation for bootstrap-datetimepicker + * Edwin Mugendi + * 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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js new file mode 100644 index 00000000..8adc129a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js @@ -0,0 +1,17 @@ +/** + * Thai translation for bootstrap-datetimepicker + * Suchau Jiraprapot + */ +;(function($){ + $.fn.datetimepicker.dates['th'] = { + days: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"], + daysShort: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"], + daysMin: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"], + months: ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"], + monthsShort: ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."], + today: "วันนี้", + clear: "x", + suffix: [], + meridiem: [] + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js new file mode 100644 index 00000000..0130c94c --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js @@ -0,0 +1,18 @@ +/** + * Turkish translation for bootstrap-datetimepicker + * Serkan Algur + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js new file mode 100644 index 00000000..1687a1dc --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js @@ -0,0 +1,16 @@ +/** + * 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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js new file mode 100644 index 00000000..4b3a9e0a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js @@ -0,0 +1,17 @@ +/** + * Ukrainian translation for bootstrap-datetimepicker + * Andrey Vityuk + */ +;(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-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js new file mode 100644 index 00000000..f84ba548 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js @@ -0,0 +1,17 @@ +/** + * Traditional Chinese translation for bootstrap-datetimepicker + * Rung-Sheng Jang + */ +;(function($){ + $.fn.datetimepicker.dates['zh-TW'] = { + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], + daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], + daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + today: "今天", + clear: "x", + suffix: [], + meridiem: ["上午", "下午"] + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js new file mode 100644 index 00000000..66ac5a01 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js @@ -0,0 +1,17 @@ +/** + * Simplified Chinese translation for bootstrap-datetimepicker + * Yuan Cheung + */ +;(function($){ + $.fn.datetimepicker.dates['zh'] = { + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], + daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], + daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + today: "今天", + clear: "x", + suffix: [], + meridiem: ["上午", "下午"] + }; +}(jQuery)); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..13c8531b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt @@ -0,0 +1,100 @@ +/* + * 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 + +import org.w3c.dom.Element +import pl.treksoft.jquery.jQuery +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.panel.Root +import kotlin.browser.document +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +interface TestSpec { + fun beforeTest() + + fun afterTest() + + fun run(code: () -> Unit) { + beforeTest() + code() + afterTest() + } +} + +interface SimpleSpec : TestSpec { + + override fun beforeTest() { + } + + override fun afterTest() { + } + +} + +interface DomSpec : TestSpec { + + override fun beforeTest() { + val fixture = "
" + + "
" + document.body?.insertAdjacentHTML("afterbegin", fixture) + } + + override fun afterTest() { + val div = document.getElementById("pretest") + div?.let { jQuery(it).remove() } + jQuery(".modal-backdrop").remove() + Root.shutdown() + } + + fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { + if (expected != null && actual != null) { + val exp = jQuery(expected) + val act = jQuery(actual) + val result = exp[0]?.isEqualNode(act[0]) + if (result == true) { + assertTrue(result == true, message) + } else { + assertEquals(expected, actual, message) + } + } else { + assertEquals(expected, actual, message) + } + } +} + +interface WSpec : DomSpec { + + fun runW(code: (widget: Widget, element: Element?) -> Unit) { + run { + val root = Root("test", fixed = true) + val widget = Widget() + widget.id = "test_id" + root.add(widget) + val element = document.getElementById("test_id") + code(widget, element) + } + } + +} + +external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..877cf650 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt @@ -0,0 +1,53 @@ +/* + * 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.form.time + +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.js.Date +import kotlin.test.Test +import kotlin.test.assertEquals + +class DateTimeInputSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val data = Date() + val dti = DateTimeInput(value = data).apply { + placeholder = "place" + id = "idti" + } + root.add(dti) + val value = dti.getElementJQuery()?.`val`() + assertEquals( + data.toStringF(dti.format), + value, + "Should render date time input with correctly formatted value" + ) + } + } + +} \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..eba3ef74 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt @@ -0,0 +1,62 @@ +/* + * 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.form.time + +import pl.treksoft.kvision.form.time.DateTime +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 + +class DateTimeSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val data = Date() + val ti = DateTime(value = data, label = "Label").apply { + placeholder = "place" + name = "name" + disabled = true + } + root.add(ti) + val element = document.getElementById("test") + val id = ti.input.id + val datastr = data.toStringF(ti.format) + assertEqualsHtml( + "
", + element?.innerHTML, + "Should render correct date time input form control" + ) + ti.validatorError = "Validation Error" + assertEqualsHtml( + "
Validation Error
", + element?.innerHTML, + "Should render correct date time input form control with validation error" + ) + } + } + +} \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-datetime/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-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-bootstrap-dialog/package.json.d/project.info b/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info new file mode 100644 index 00000000..416cd4a7 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Dialog module" +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..e67a6f17 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.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 pl.treksoft.kvision.modal + +import kotlinx.coroutines.suspendCancellableCoroutine +import pl.treksoft.kvision.core.Widget +import kotlin.coroutines.resume + +/** + * Modal window with a result. + * + * @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 + */ +open class Dialog( + caption: String? = null, closeButton: Boolean = true, + size: ModalSize? = null, animation: Boolean = true, escape: Boolean = true, + classes: Set = setOf(), init: (Dialog.() -> Unit)? = null +) : Modal(caption, closeButton, size, animation, escape, classes) { + + internal var resultCallback: ((R?) -> Unit)? = null + + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + + /** + * A suspending function returning result value. + */ + suspend fun getResult(): R? = suspendCancellableCoroutine { cont -> + resultCallback = { result -> + resultCallback = null + hide() + cont.resume(result) + } + show() + } + + /** + * A function to be called with a result value. + */ + open fun setResult(result: R?) { + resultCallback?.invoke(result) + } + + override fun hide(): Widget { + resultCallback?.invoke(null) + return super.hide() + } +} diff --git a/kvision-modules/kvision-bootstrap-select-remote/build.gradle b/kvision-modules/kvision-bootstrap-select-remote/build.gradle new file mode 100644 index 00000000..7a4dc8fa --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select-remote/build.gradle @@ -0,0 +1,6 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap-select") + compile project(":kvision-modules:kvision-remote") +} diff --git a/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info new file mode 100644 index 00000000..5685d581 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Select remote addon module" +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..de823280 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt @@ -0,0 +1,276 @@ +/* + * 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.select + +import pl.treksoft.kvision.core.Component +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.InvalidFeedback +import pl.treksoft.kvision.form.StringFormControl +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.remote.KVServiceManager +import pl.treksoft.kvision.remote.RemoteOption +import pl.treksoft.kvision.utils.SnOn + +/** + * The form field component for SelectRemote control. + * + * @constructor + * @param value selected value + * @param serviceManager multiplatform service manager + * @param function multiplatform service method returning the list of options + * @param name the name attribute of the generated HTML input element + * @param multiple allows multiple value selection (multiple values are comma delimited) + * @param ajaxOptions additional options for remote data source + * @param label label text bound to the input element + * @param rich determines if [label] can contain HTML code + */ +@Suppress("TooManyFunctions") +open class SelectRemote( + value: String? = null, + serviceManager: KVServiceManager, + function: T.(String?, String?) -> List, + name: String? = null, + multiple: Boolean = false, + ajaxOptions: AjaxOptions? = null, + label: String? = null, + rich: Boolean = false +) : SimplePanel(setOf("form-group")), StringFormControl { + /** + * A value of the selected option. + */ + override var value + get() = input.value + set(value) { + input.value = value + } + /** + * Determines if multiple value selection is allowed. + */ + var multiple + get() = input.multiple + set(value) { + input.multiple = value + } + /** + * Maximal number of selected options. + */ + var maxOptions + get() = input.maxOptions + set(value) { + input.maxOptions = value + } + /** + * The placeholder for the select control. + */ + var placeholder + get() = input.placeholder + set(value) { + input.placeholder = value + } + /** + * The style of the select control. + */ + var style + get() = input.style + set(value) { + input.style = value + } + /** + * The width of the select control. + */ + var selectWidth + get() = input.selectWidth + set(value) { + input.selectWidth = value + } + /** + * The width type of the select control. + */ + var selectWidthType + get() = input.selectWidthType + set(value) { + input.selectWidthType = value + } + /** + * Determines if an empty option is automatically generated. + */ + var emptyOption + get() = input.emptyOption + set(value) { + input.emptyOption = value + } + /** + * Determines if the select is automatically focused. + */ + var autofocus + get() = input.autofocus + set(value) { + input.autofocus = value + } + /** + * The label text bound to the select 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 + } + + private val idc = "kv_form_SelectRemote_$counter" + final override val input: SelectRemoteInput = SelectRemoteInput( + value, serviceManager, function, multiple, ajaxOptions, + setOf("form-control") + ).apply { + this.id = idc + this.name = name + } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + init { + @Suppress("LeakingThis") + input.eventTarget = this + this.addInternal(flabel) + this.addInternal(input) + this.addInternal(invalidFeedback) + counter++ + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + if (validatorError != null) { + cl.add("text-danger" 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 add(child: Component): SimplePanel { + input.add(child) + return this + } + + override fun addAll(children: List): SimplePanel { + input.addAll(children) + return this + } + + override fun remove(child: Component): SimplePanel { + input.remove(child) + return this + } + + override fun removeAll(): SimplePanel { + input.removeAll() + return this + } + + override fun getChildren(): List { + return input.getChildren() + } + + /** + * Opens dropdown with options. + */ + open fun showOptions() { + input.showOptions() + } + + /** + * Hides dropdown with options. + */ + open fun hideOptions() { + input.hideOptions() + } + + /** + * Toggles visibility of dropdown with options. + */ + open fun toggleOptions() { + input.toggleOptions() + } + + 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.selectRemote( + value: String? = null, + serviceManager: KVServiceManager, + function: T.(String?, String?) -> List, name: String? = null, + multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, + rich: Boolean = false, init: (SelectRemote.() -> Unit)? = null + ): SelectRemote { + val selectRemote = + SelectRemote( + value, + serviceManager, + function, + name, + multiple, + ajaxOptions, + label, + rich + ).apply { init?.invoke(this) } + this.add(selectRemote) + return selectRemote + } + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..4c891d30 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt @@ -0,0 +1,140 @@ +/* + * 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.select + +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.asDeferred +import kotlinx.coroutines.launch +import kotlinx.serialization.ImplicitReflectionSerializer +import kotlinx.serialization.list +import kotlinx.serialization.stringify +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.remote.CallAgent +import pl.treksoft.kvision.remote.HttpMethod +import pl.treksoft.kvision.remote.JsonRpcRequest +import pl.treksoft.kvision.remote.KVServiceManager +import pl.treksoft.kvision.remote.RemoteOption +import pl.treksoft.kvision.utils.JSON +import pl.treksoft.kvision.utils.obj + +external fun decodeURIComponent(encodedURI: String): String + +/** + * The Select control connected to the multiplatform service. + * + * @constructor + * @param value selected value + * @param serviceManager multiplatform service manager + * @param function multiplatform service method returning the list of options + * @param multiple allows multiple value selection (multiple values are comma delimited) + * @param ajaxOptions additional options for remote data source + * @param classes a set of CSS class names + */ +@UseExperimental(ImplicitReflectionSerializer::class) +open class SelectRemoteInput( + value: String? = null, + serviceManager: KVServiceManager, + function: T.(String?, String?) -> List, + multiple: Boolean = false, + ajaxOptions: AjaxOptions? = null, + classes: Set = setOf() +) : SelectInput(null, value, multiple, null, classes) { + init { + val (url, method) = + serviceManager.getCalls()[function.toString().replace("\\s".toRegex(), "")] + ?: throw IllegalStateException("Function not specified!") + val data = obj { + q = "{{{q}}}" + } + val tempAjaxOptions = ajaxOptions ?: AjaxOptions() + this.ajaxOptions = tempAjaxOptions.copy(url = url, preprocessData = { + @Suppress("UnsafeCastFromDynamic") + JSON.plain.parse(RemoteOption.serializer().list, it.result as String).map { + obj { + this.value = it.value + if (it.text != null) this.text = it.text + if (it.className != null) this.`class` = it.className + if (it.disabled) this.disabled = true + if (it.divider) this.divider = true + this.data = obj { + if (it.subtext != null) this.subtext = it.subtext + if (it.icon != null) this.icon = it.icon + if (it.content != null) this.content = it.content + } + } + }.toTypedArray() + }, data = data, beforeSend = { _, b -> + @Suppress("UnsafeCastFromDynamic") + val q = decodeURIComponent(b.data.substring(2)) + b.data = JSON.plain.stringify(JsonRpcRequest(0, url, listOf(q, this.value))) + true + }, httpType = HttpType.valueOf(method.name), cache = false, preserveSelected = true) + if (value != null) { + GlobalScope.launch { + val callAgent = CallAgent() + val initials = callAgent.remoteCall( + url, + JSON.plain.stringify(JsonRpcRequest(0, url, listOf(null, value))), + HttpMethod.POST + ).asDeferred().await() + JSON.plain.parse(RemoteOption.serializer().list, initials.result as String).map { + add(SelectOption(it.value, it.text, selected = true)) + } + this@SelectRemoteInput.refreshSelectInput() + } + } + if (this.ajaxOptions?.emptyRequest == true) { + this.setInternalEventListener> { + shownBsSelect = { + val input = self.getElementJQuery()?.parent()?.find("input") + input?.trigger("keyup", null) + input?.hide(0) + } + } + + } + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.selectRemoteInput( + value: String? = null, + serviceManager: KVServiceManager, + function: T.(String?, String?) -> List, + multiple: Boolean = false, + ajaxOptions: AjaxOptions? = null, + classes: Set = setOf(), init: (SelectRemoteInput.() -> Unit)? = null + ): SelectRemoteInput { + val selectRemoteInput = + SelectRemoteInput(value, serviceManager, function, multiple, ajaxOptions, classes).apply { + init?.invoke(this) + } + this.add(selectRemoteInput) + return selectRemoteInput + } + } + +} diff --git a/kvision-modules/kvision-bootstrap-select/build.gradle b/kvision-modules/kvision-bootstrap-select/build.gradle new file mode 100644 index 00000000..83bcd627 --- /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.12.4") + dependency("ajax-bootstrap-select", "1.4.3") + } + +} diff --git a/kvision-modules/kvision-bootstrap-select/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select/package.json.d/project.info new file mode 100644 index 00000000..80e675b0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Select module" +} diff --git a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt new file mode 100644 index 00000000..3617c417 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt @@ -0,0 +1,53 @@ +/* + * 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 kVManagerSelectInit = KVManagerSelect.init() + +/** + * Internal singleton object which initializes and configures KVision select module. + */ +internal object KVManagerSelect { + internal const val AJAX_REQUEST_DELAY = 300 + internal const val KVNULL = "#kvnull" + + init { + require("bootstrap-select/dist/css/bootstrap-select.min.css") + require("bootstrap-select/dist/js/bootstrap-select.min.js") + require("./js/locales/bootstrap-select/bootstrap-select-i18n.min.js") + require("ajax-bootstrap-select/dist/css/ajax-bootstrap-select.min.css") + require("ajax-bootstrap-select/dist/js/ajax-bootstrap-select.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") + require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js") + require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js") + require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js") + require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js") + 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.tr-TR.min.js") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..c088f68d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt @@ -0,0 +1,140 @@ +/* + * 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.select + +import pl.treksoft.jquery.JQueryXHR +import pl.treksoft.kvision.KVManagerSelect.AJAX_REQUEST_DELAY +import pl.treksoft.kvision.KVManagerSelect.KVNULL +import pl.treksoft.kvision.i18n.I18n +import pl.treksoft.kvision.utils.obj + +/** + * HTTP protocol type for the AJAX call. + */ +enum class HttpType(internal val type: String) { + GET("GET"), + POST("POST") +} + +/** + * Data type for the AJAX call. + */ +enum class DataType(internal val type: String) { + JSON("json"), + JSONP("jsonp"), + XML("xml"), + TEXT("text"), + SCRIPT("script") +} + +/** + * Data class for AJAX options. + * + * @constructor + * @param url the url address + * @param preprocessData + * [AjaxBootstrapSelect preprocessOption](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionspreprocessdata) + * option + * @param beforeSend + * [JQuery ajax.beforeSend](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option + * @param data + * [JQuery ajax.data](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option + * @param httpType + * [JQuery ajax.type](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option + * @param minLength + * [AjaxBootstrapSelect minLength](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsminlength) option + * @param cache + * [AjaxBootstrapSelect cache](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionscache) option + * @param clearOnEmpty + * [AjaxBootstrapSelect clearOnEmpty](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsclearonempty) option + * @param clearOnError + * [AjaxBootstrapSelect clearOnError](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsclearonerror) option + * @param emptyRequest + * [AjaxBootstrapSelect emptyRequest](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsemptyrequest) option + * @param requestDelay + * [AjaxBootstrapSelect requestDelay](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsrequestdelay) option + * @param restoreOnError + * [AjaxBootstrapSelect restoreOnError](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsrestoreonerror) + * option + */ +data class AjaxOptions( + val url: String? = null, + val preprocessData: ((dynamic) -> dynamic)? = null, + val beforeSend: ((JQueryXHR, dynamic) -> dynamic)? = null, + val data: dynamic = null, + val httpType: HttpType = HttpType.GET, + val dataType: DataType = DataType.JSON, + val minLength: Int = 0, + val cache: Boolean = true, + val clearOnEmpty: Boolean = true, + val clearOnError: Boolean = true, + val emptyRequest: Boolean = false, + val requestDelay: Int = AJAX_REQUEST_DELAY, + val restoreOnError: Boolean = false, + val preserveSelected: Boolean = false, + val processData: Boolean = false +) + +/** + * Convert AjaxOptions to JavaScript JSON object. + * @param emptyOption add an empty position as the first select option + * @return JSON object + */ +fun AjaxOptions.toJs(emptyOption: Boolean): dynamic { + val procData = { data: dynamic -> + val processedData = this.preprocessData?.invoke(data) ?: data + if (emptyOption) { + val ret = mutableListOf(obj { + this.value = KVNULL + this.text = "" + }) + @Suppress("UnsafeCastFromDynamic") + ret.addAll((processedData as Array).asList()) + ret.toTypedArray() + } else { + processedData + } + } + val language = I18n.language + return obj { + this.ajax = obj { + this.url = url ?: "/" + this.method = httpType.type + this.dataType = dataType.type + this.data = data + this.beforeSend = beforeSend + this.contentType = "application/json" + } + this.preprocessData = procData + this.minLength = minLength + this.cache = cache + this.clearOnEmpty = clearOnEmpty + this.clearOnError = clearOnError + this.emptyRequest = emptyRequest + this.preserveSelected = preserveSelected + this.requestDelay = requestDelay + this.restoreOnError = restoreOnError + this.langCode = language + this.processData = processData + this.preserveSelectedOrder = true + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..4b2505d2 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt @@ -0,0 +1,285 @@ +/* + * 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.select + +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.form.FieldLabel +import pl.treksoft.kvision.form.InvalidFeedback +import pl.treksoft.kvision.form.StringFormControl +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.SnOn + +/** + * The form field component for Select control. + * + * The select control can be populated directly from *options* parameter or manually by adding + * [SelectOption] or [SelectOptGroup] components to the container. + * + * @constructor + * @param options an optional list of options (value to label pairs) for the select control + * @param value selected value + * @param name the name attribute of the generated HTML input element + * @param multiple allows multiple value selection (multiple values are comma delimited) + * @param ajaxOptions additional options for remote (AJAX) data source + * @param label label text bound to the input element + * @param rich determines if [label] can contain HTML code + */ +@Suppress("TooManyFunctions") +open class Select( + options: List? = null, value: String? = null, name: String? = null, + multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, + rich: Boolean = false +) : SimplePanel(setOf("form-group")), StringFormControl { + + /** + * A list of options (value to label pairs) for the select control. + */ + var options + get() = input.options + set(value) { + input.options = value + } + /** + * A value of the selected option. + */ + override var value + get() = input.value + set(value) { + input.value = value + } + /** + * Determines if multiple value selection is allowed. + */ + var multiple + get() = input.multiple + set(value) { + input.multiple = value + } + /** + * Additional options for remote (AJAX) data source. + */ + var ajaxOptions + get() = input.ajaxOptions + set(value) { + input.ajaxOptions = value + } + /** + * Maximal number of selected options. + */ + var maxOptions + get() = input.maxOptions + set(value) { + input.maxOptions = value + } + /** + * Determines if live search is available. + */ + var liveSearch + get() = input.liveSearch + set(value) { + input.liveSearch = value + } + /** + * The placeholder for the select control. + */ + var placeholder + get() = input.placeholder + set(value) { + input.placeholder = value + } + /** + * The style of the select control. + */ + var style + get() = input.style + set(value) { + input.style = value + } + /** + * The width of the select control. + */ + var selectWidth + get() = input.selectWidth + set(value) { + input.selectWidth = value + } + /** + * The width type of the select control. + */ + var selectWidthType + get() = input.selectWidthType + set(value) { + input.selectWidthType = value + } + /** + * Determines if an empty option is automatically generated. + */ + var emptyOption + get() = input.emptyOption + set(value) { + input.emptyOption = value + } + /** + * Determines if the select is automatically focused. + */ + var autofocus + get() = input.autofocus + set(value) { + input.autofocus = value + } + /** + * The label text bound to the select 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 + } + + private val idc = "kv_form_select_$counter" + final override val input: SelectInput = SelectInput( + options, value, multiple, ajaxOptions, + setOf("form-control") + ).apply { + this.id = idc + this.name = name + } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + init { + @Suppress("LeakingThis") + input.eventTarget = this + this.addInternal(flabel) + this.addInternal(input) + this.addInternal(invalidFeedback) + counter++ + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + if (validatorError != null) { + cl.add("text-danger" 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 add(child: Component): SimplePanel { + input.add(child) + return this + } + + override fun addAll(children: List): SimplePanel { + input.addAll(children) + return this + } + + override fun remove(child: Component): SimplePanel { + input.remove(child) + return this + } + + override fun removeAll(): SimplePanel { + input.removeAll() + return this + } + + override fun getChildren(): List { + return input.getChildren() + } + + /** + * Opens dropdown with options. + */ + open fun showOptions() { + input.showOptions() + } + + /** + * Hides dropdown with options. + */ + open fun hideOptions() { + input.hideOptions() + } + + /** + * Toggles visibility of dropdown with options. + */ + open fun toggleOptions() { + input.toggleOptions() + } + + 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.select( + options: List? = null, value: String? = null, name: String? = null, + multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, + rich: Boolean = false, init: (Select.() -> Unit)? = null + ): Select { + val select = Select(options, value, name, multiple, ajaxOptions, label, rich).apply { init?.invoke(this) } + this.add(select) + return select + } + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..84eccaf7 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt @@ -0,0 +1,375 @@ +/* + * 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.select + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.KVManagerSelect.KVNULL +import pl.treksoft.kvision.core.Component +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.core.CssSize +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 +import pl.treksoft.kvision.utils.obj + +/** + * Select width types. See [Bootstrap Select width](http://silviomoreto.github.io/bootstrap-select/examples/#width). + */ +enum class SelectWidthType(internal val value: String) { + AUTO("auto"), + FIT("fit") +} + +/** + * The basic component for Select control. + * + * The select control can be populated directly from *options* parameter or manually by adding + * [SelectOption] or [SelectOptGroup] components to the container. + * + * @constructor + * @param options an optional list of options (value to label pairs) for the select control + * @param value selected value + * @param multiple allows multiple value selection (multiple values are comma delimited) + * @param ajaxOptions additional options for remote (AJAX) data source + * @param classes a set of CSS class names + */ +@Suppress("TooManyFunctions") +open class SelectInput( + options: List? = null, value: String? = null, + multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, + classes: Set = setOf() +) : SimplePanel(classes), FormInput { + + /** + * A list of options (value to label pairs) for the select control. + */ + var options by refreshOnUpdate(options) { setChildrenFromOptions() } + /** + * A value of the selected option. + */ + var value by refreshOnUpdate(value) { refreshState() } + /** + * The name attribute of the generated HTML select element. + */ + override var name: String? by refreshOnUpdate() + /** + * Determines if multiple value selection is allowed. + */ + var multiple by refreshOnUpdate(multiple) + /** + * Additional options for remote (AJAX) data source. + */ + var ajaxOptions by refreshOnUpdate(ajaxOptions) { + if (it != null) { + liveSearch = true + } + refresh() + } + /** + * Maximal number of selected options. + */ + var maxOptions: Int? by refreshOnUpdate() + /** + * Determines if live search is available. + */ + var liveSearch by refreshOnUpdate(false) + /** + * The placeholder for the select control. + */ + var placeholder: String? by refreshOnUpdate() + /** + * The style of the select control. + */ + var style: ButtonStyle? by refreshOnUpdate() + /** + * The width of the select control. + */ + var selectWidth: CssSize? by refreshOnUpdate() + /** + * The width type of the select control. + */ + var selectWidthType: SelectWidthType? by refreshOnUpdate() + /** + * Determines if an empty option is automatically generated. + */ + var emptyOption by refreshOnUpdate(false) { setChildrenFromOptions() } + /** + * Determines if the field is disabled. + */ + override var disabled by refreshOnUpdate(false) + /** + * Determines if the select is automatically focused. + */ + var autofocus: Boolean? by refreshOnUpdate() + /** + * 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() + this.setInternalEventListener { + change = { + val v = getElementJQuery()?.`val`() + self.value = v?.let { + calculateValue(it) + } + } + } + } + + private fun calculateValue(v: Any): String? { + return if (this.multiple) { + @Suppress("UNCHECKED_CAST") + val arr = v as? Array + if (arr != null && arr.isNotEmpty()) { + arr.filter { it.isNotEmpty() }.joinToString(",") + } else { + null + } + } else { + val vs = v as String + if (KVNULL == vs || vs.isEmpty()) { + null + } else { + vs + } + } + } + + override fun render(): VNode { + return render("select", childrenVNodes()) + } + + override fun add(child: Component): SimplePanel { + super.add(child) + refreshSelectInput() + return this + } + + override fun addAll(children: List): SimplePanel { + super.addAll(children) + refreshSelectInput() + return this + } + + override fun remove(child: Component): SimplePanel { + super.remove(child) + refreshSelectInput() + return this + } + + override fun removeAll(): SimplePanel { + super.removeAll() + refreshSelectInput() + return this + } + + private fun setChildrenFromOptions() { + if (ajaxOptions == null) { + super.removeAll() + if (emptyOption) { + super.add(SelectOption(KVNULL, "")) + } + options?.let { + val c = it.map { + SelectOption(it.first, it.second) + } + super.addAll(c) + } + } + this.refreshSelectInput() + } + + /** + * Opens dropdown with options. + */ + open fun showOptions() { + getElementJQueryD()?.selectpicker("show") + } + + /** + * Hides dropdown with options. + */ + open fun hideOptions() { + getElementJQueryD()?.selectpicker("hide") + } + + /** + * Toggles visibility of dropdown with options. + */ + open fun toggleOptions() { + getElementJQueryD()?.selectpicker("toggle") + } + + override fun getSnClass(): List { + 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) + } + return cl + } + + protected fun refreshSelectInput() { + getElementJQueryD()?.selectpicker("refresh") + refreshState() + getElementJQueryD()?.trigger("change")?.data("AjaxBootstrapSelect")?.list?.cache = {} + } + + @Suppress("ComplexMethod") + override fun getSnAttrs(): List { + val sn = super.getSnAttrs().toMutableList() + name?.let { + sn.add("name" to it) + } + if (multiple) { + sn.add("multiple" to "multiple") + } + maxOptions?.let { + sn.add("data-max-options" to "" + it) + } + if (liveSearch) { + sn.add("data-live-search" to "true") + } + placeholder?.let { + sn.add("title" to translate(it)) + } + autofocus?.let { + if (it) { + sn.add("autofocus" to "autofocus") + } + } + if (disabled) { + sn.add("disabled" to "disabled") + } + val btnStyle = style?.className ?: "btn-default" + when (size) { + InputSize.LARGE -> { + sn.add("data-style" to "$btnStyle btn-lg") + } + InputSize.SMALL -> { + sn.add("data-style" to "$btnStyle btn-sm") + } + else -> { + sn.add("data-style" to btnStyle) + } + } + selectWidthType?.let { + sn.add("data-width" to it.value) + } ?: selectWidth?.let { + sn.add("data-width" to it.asString()) + } + return sn + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + ajaxOptions?.let { + getElementJQueryD()?.selectpicker("render").ajaxSelectPicker(it.toJs(emptyOption)) + } ?: getElementJQueryD()?.selectpicker("render") + + this.getElementJQuery()?.on("show.bs.select") { e, _ -> + this.dispatchEvent("showBsSelect", obj { detail = e }) + } + this.getElementJQuery()?.on("shown.bs.select") { e, _ -> + this.dispatchEvent("shownBsSelect", obj { detail = e }) + } + this.getElementJQuery()?.on("hide.bs.select") { e, _ -> + this.dispatchEvent("hideBsSelect", obj { detail = e }) + } + this.getElementJQuery()?.on("hidden.bs.select") { e, _ -> + this.dispatchEvent("hiddenBsSelect", obj { detail = e }) + } + this.getElementJQuery()?.on("loaded.bs.select") { e, _ -> + this.dispatchEvent("loadedBsSelect", obj { detail = e }) + } + this.getElementJQuery()?.on("rendered.bs.select") { e, _ -> + this.dispatchEvent("renderedBsSelect", obj { detail = e }) + } + this.getElementJQuery()?.on("refreshed.bs.select") { e, _ -> + this.dispatchEvent("refreshedBsSelect", obj { detail = e }) + } + this.getElementJQueryD()?.on("changed.bs.select") { e, cIndex: Int -> + e["clickedIndex"] = cIndex + this.dispatchEvent("changedBsSelect", obj { detail = e }) + } + refreshState() + } + + @Suppress("UnsafeCastFromDynamic") + private fun refreshState() { + if (ajaxOptions == null) { + value?.let { + if (multiple) { + getElementJQueryD()?.selectpicker("val", it.split(",").toTypedArray()) + } else { + getElementJQueryD()?.selectpicker("val", it) + } + } ?: getElementJQueryD()?.selectpicker("val", null) + } + } + + /** + * Makes the input element focused. + */ + override fun focus() { + getElementJQuery()?.focus() + } + + /** + * Makes the input element blur. + */ + override fun blur() { + getElementJQuery()?.blur() + } + + companion object { + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Container.selectInput( + options: List? = null, value: String? = null, + multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, + classes: Set = setOf(), init: (SelectInput.() -> Unit)? = null + ): SelectInput { + val selectInput = SelectInput(options, value, multiple, ajaxOptions, classes).apply { init?.invoke(this) } + this.add(selectInput) + return selectInput + } + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..3f07a9bf --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt @@ -0,0 +1,123 @@ +/* + * 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.select + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.panel.SimplePanel + +/** + * The helper container for adding option groups to [Select]. + * + * The option group can be populated directly from *options* parameter or manually by adding + * [SelectOption] components to the container. + * + * @constructor + * @param label the label of the group + * @param options an optional list of options (label to value pairs) for the group + * @param maxOptions maximal number of selected options in the group + * @param disabled renders a disabled group + * @param classes a set of CSS class names + */ +open class SelectOptGroup( + label: String, options: List? = null, maxOptions: Int? = null, + disabled: Boolean = false, classes: Set = setOf() +) : SimplePanel(classes) { + /** + * A label for the group. + */ + var label by refreshOnUpdate(label) + /** + * A list of options (label to value pairs) for the group. + */ + var options by refreshOnUpdate(options) { setChildrenFromOptions() } + /** + * Maximal number of selected options in the group. + */ + var maxOptions by refreshOnUpdate(maxOptions) + /** + * Determines if the group is disabled. + */ + var disabled by refreshOnUpdate(disabled) + + init { + setChildrenFromOptions() + } + + override fun render(): VNode { + return render("optgroup", childrenVNodes()) + } + + private fun setChildrenFromOptions() { + this.removeAll() + options?.let { + val c = it.map { + SelectOption(it.first, it.second) + } + this.addAll(c) + } + } + + override fun getSnAttrs(): List { + val sn = super.getSnAttrs().toMutableList() + sn.add("label" to translate(label)) + maxOptions?.let { + sn.add("data-max-options" to "" + it) + } + if (disabled) { + sn.add("disabled" to "disabled") + } + return sn + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Select.selectOptGroup( + label: String, options: List? = null, maxOptions: Int? = null, + disabled: Boolean = false, classes: Set = setOf(), init: (SelectOptGroup.() -> Unit)? = null + ): SelectOptGroup { + val selectOptGroup = + SelectOptGroup(label, options, maxOptions, disabled, classes).apply { init?.invoke(this) } + this.add(selectOptGroup) + return selectOptGroup + } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun SelectInput.selectOptGroup( + label: String, options: List? = null, maxOptions: Int? = null, + disabled: Boolean = false, classes: Set = setOf(), init: (SelectOptGroup.() -> Unit)? = null + ): SelectOptGroup { + val selectOptGroup = + SelectOptGroup(label, options, maxOptions, disabled, classes).apply { init?.invoke(this) } + this.add(selectOptGroup) + return selectOptGroup + } + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..91c269a8 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt @@ -0,0 +1,170 @@ +/* + * 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.select + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.core.Widget + +/** + * The helper component for adding options to [Select] or [SelectOptGroup]. + * + * @constructor + * @param value the value of the option + * @param label the label of the option + * @param subtext the small subtext after the label of the option + * @param icon the icon before the label of the option + * @param divider renders this option as a divider + * @param disabled renders a disabled option + * @param classes a set of CSS class names + */ +open class SelectOption( + value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, + divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, + classes: Set = setOf() +) : Widget(classes) { + + /** + * The value of the option. + */ + var value by refreshOnUpdate(value) + /** + * The label of the option. + */ + var label by refreshOnUpdate(label) + /** + * The subtext after the label of the option. + */ + var subtext by refreshOnUpdate(subtext) + /** + * The icon before the label of the option. + */ + var icon by refreshOnUpdate(icon) + /** + * Determines if the option should be rendered as divider. + */ + var divider by refreshOnUpdate(divider) + /** + * Determines if the option should be disabled. + */ + var disabled by refreshOnUpdate(disabled) + /** + * Determines if the option is selected. + */ + var selected by refreshOnUpdate(selected) + + override fun render(): VNode { + return if (!divider) { + render("option", arrayOf(translate(label) ?: value)) + } else { + render("option") + } + } + + @Suppress("ComplexMethod") + override fun getSnAttrs(): List { + val sn = super.getSnAttrs().toMutableList() + if (!divider) { + value?.let { + sn.add("value" to it) + } + subtext?.let { + sn.add("data-subtext" to translate(it)) + } + icon?.let { + sn.add("data-icon" to it) + } + if (disabled) { + sn.add("disabled" to "disabled") + } + if (selected) { + sn.add("selected" to "selected") + } + } else { + sn.add("data-divider" to "true") + } + return sn + } + + companion object { + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Select.selectOption( + value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, + divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, + classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null + ): SelectOption { + val selectOption = + SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { + init?.invoke( + this + ) + } + this.add(selectOption) + return selectOption + } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun SelectInput.selectOption( + value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, + divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, + classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null + ): SelectOption { + val selectOption = + SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { + init?.invoke( + this + ) + } + this.add(selectOption) + return selectOption + } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun SelectOptGroup.selectOption( + value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, + divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, + classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null + ): SelectOption { + val selectOption = + SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { + init?.invoke( + this + ) + } + this.add(selectOption) + return selectOption + } + + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..08b38207 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * English translation for the "en-US" and "en" language codes. + * Tobias Weichart + */ +$.fn.ajaxSelectPicker.locale["de-DE"]={currentlySelected:"Momentan ausgewählt",emptyTitle:"Hier klicken und eingeben",errorText:"Ergebnisse konnten nicht abgerufen wurden",searchPlaceholder:"Suche...",statusInitialized:"Suchbegriff eingeben",statusNoResults:"Keine Ergebnisse",statusSearching:"Suche...",statusTooShort:"Der Suchbegriff ist nicht lang genug"},$.fn.ajaxSelectPicker.locale.de=$.fn.ajaxSelectPicker.locale["de-DE"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..8b130b97 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * English translation for the "en-US" and "en" language codes. + * Mark Carver + */ +$.fn.ajaxSelectPicker.locale["en-US"]={currentlySelected:"Currently Selected",emptyTitle:"Select and begin typing",errorText:"Unable to retrieve results",searchPlaceholder:"Search...",statusInitialized:"Start typing a search query",statusNoResults:"No Results",statusSearching:"Searching...",statusTooShort:"Please enter more characters"},$.fn.ajaxSelectPicker.locale.en=$.fn.ajaxSelectPicker.locale["en-US"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..bbe3fe45 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Spanish translation for the "es-ES" and "es" language codes. + * Diomedes Domínguez + */ +$.fn.ajaxSelectPicker.locale["es-ES"]={currentlySelected:"Seleccionado",emptyTitle:"Seleccione y comience a escribir",errorText:"No se puede recuperar resultados",searchPlaceholder:"Buscar...",statusInitialized:"Empieza a escribir una consulta de búsqueda",statusNoResults:"Sin Resultados",statusSearching:"Buscando...",statusTooShort:"Introduzca más caracteres"},$.fn.ajaxSelectPicker.locale.es=$.fn.ajaxSelectPicker.locale["es-ES"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..1d86582f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * French translation for the "fr-FR" and "fr" language codes. + * Bastien (https://github.com/lisurc) + */ +$.fn.ajaxSelectPicker.locale["fr-FR"]={currentlySelected:"Actuellement sélectionné",emptyTitle:"Sélectionner et commencer à taper",errorText:"Impossible de récupérer les résultats",searchPlaceholder:"Rechercher...",statusInitialized:"Commencer à taper une recherche",statusNoResults:"Aucun résultat",statusSearching:"Recherche en cours...",statusTooShort:"Entrez plus de caractères"},$.fn.ajaxSelectPicker.locale.fr=$.fn.ajaxSelectPicker.locale["fr-FR"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..b30deb3e --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Italian translation for the "it-IT" and "it" language codes. + * Luca Longo + */ +$.fn.ajaxSelectPicker.locale["it-IT"]={currentlySelected:"Selezionati",emptyTitle:"Clicca qui e scrivi...",errorText:"Impossibile recuperare dei risultati",searchPlaceholder:"Cerca...",statusInitialized:"Inizia a digitare...",statusNoResults:"Non ci sono risultati",statusSearching:"Ricerca in corso...",statusTooShort:"Inserisci altri caratteri"},$.fn.ajaxSelectPicker.locale.it=$.fn.ajaxSelectPicker.locale["it-IT"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..23a9a348 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Japanese translation for the "ja-JP" and "ja" language codes. + * Haginaga + */ +$.fn.ajaxSelectPicker.locale["ja-JP"]={currentlySelected:"現在の値",emptyTitle:"未選択",errorText:"検索できません",searchPlaceholder:"検索する",statusInitialized:"選択肢を入力",statusNoResults:"見つかりません",statusSearching:"検索中...",statusTooShort:"入力文字数不足"},$.fn.ajaxSelectPicker.locale.ja=$.fn.ajaxSelectPicker.locale["ja-JP"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..2fd5299b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Korean translation for the "ko-KR" and "ko" language codes. + * Jo JungLae + */ +$.fn.ajaxSelectPicker.locale["ko-KR"]={currentlySelected:"현재 선택된 항목",emptyTitle:"클릭하고 입력 시작",errorText:"결과를 검색할 수 없습니다",searchPlaceholder:"검색",statusInitialized:"검색어를 입력",statusNoResults:"검색결과가 없습니다",statusSearching:"검색중",statusTooShort:"추가 문자를 입력하십시오."},$.fn.ajaxSelectPicker.locale.ko=$.fn.ajaxSelectPicker.locale["ko-KR"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..6c6a16f2 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Dutch translation for the "nl-NL" and "nl" language codes. + * Arjen Ruiterkamp + */ +$.fn.ajaxSelectPicker.locale["nl-NL"]={currentlySelected:"Momenteel geselecteerd",emptyTitle:"Selecteer en begin met typen",errorText:"Kon geen resultaten ophalen",searchPlaceholder:"Zoeken...",statusInitialized:"Begin met typen om te zoeken",statusNoResults:"Geen resultaten",statusSearching:"Zoeken...",statusTooShort:"U dient meer karakters in te voeren"},$.fn.ajaxSelectPicker.locale.nl=$.fn.ajaxSelectPicker.locale["nl-NL"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..f104f491 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Polish translation for the "pl-PL" and "pl" language codes. + * Robert Jaros + */ +$.fn.ajaxSelectPicker.locale["pl-PL"]={currentlySelected:"Aktualny wybór",emptyTitle:"Wybierz i zacznij pisać",errorText:"Nie można pobrać wyników",searchPlaceholder:"Szukaj...",statusInitialized:"Zacznij pisać warunek wyszukiwania",statusNoResults:"Brak wyników",statusSearching:"Szukam...",statusTooShort:"Wprowadź więcej znaków"},$.fn.ajaxSelectPicker.locale.pl=$.fn.ajaxSelectPicker.locale["pl-PL"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..2a6e743d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Brazilian portuguese translation for the "pt-BR" and "pt" language codes. + * Luan Fonseca + */ +$.fn.ajaxSelectPicker.locale["pt-BR"]={currentlySelected:"Selecionado Atualmente",emptyTitle:"Clique e comece a digitar",errorText:"Incapaz de encontrar resultados",searchPlaceholder:"Buscar...",statusInitialized:"Comece a digitar",statusNoResults:"Sem Resultados",statusSearching:"Buscando...",statusTooShort:"Digite mais caracteres"},$.fn.ajaxSelectPicker.locale.pt=$.fn.ajaxSelectPicker.locale["pt-BR"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..aa6d4d06 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Russian translation for the "ru-RU" and "ru" language codes. + * Bercut Stray + */ +$.fn.ajaxSelectPicker.locale["ru-RU"]={currentlySelected:"Выбрано",emptyTitle:"Выделите и начните печатать",errorText:"Невозможно получить результат",searchPlaceholder:"Искать...",statusInitialized:"Начните печатать запрос для поиска",statusNoResults:"Нет результатов",statusSearching:"Поиск...",statusTooShort:"Введите еще несколько символов"},$.fn.ajaxSelectPicker.locale.ru=$.fn.ajaxSelectPicker.locale["ru-RU"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..6af588f4 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js @@ -0,0 +1,22 @@ +/*! + * 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.3 + * @author Adam Heim - https://github.com/truckingsim + * @link https://github.com/truckingsim/Ajax-Bootstrap-Select + * @copyright 2017 Adam Heim + * @license Released under the MIT license. + * + * Contributors: + * Mark Carver - https://github.com/markcarver + * + * Last build: 2017-11-15 1:19:45 PM EST + */ +!(function ($) { +/*! + * Turkish translation for the "tr-TR" and "tr" language codes. + * Burak Çakırel + */ +$.fn.ajaxSelectPicker.locale["tr-TR"]={currentlySelected:"Seçili olanlar",emptyTitle:"Seç ve yazmaya başla",errorText:"Sonuçlar alınamadı",searchPlaceholder:"Ara...",statusInitialized:"Arama için yazmaya başla",statusNoResults:"Sonuç yok",statusSearching:"Aranıyor...",statusTooShort:"Lütfen daha fazla karakter girin"},$.fn.ajaxSelectPicker.locale.tr=$.fn.ajaxSelectPicker.locale["tr-TR"];})(jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..4428d3c0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js @@ -0,0 +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 diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..13c8531b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt @@ -0,0 +1,100 @@ +/* + * 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 + +import org.w3c.dom.Element +import pl.treksoft.jquery.jQuery +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.panel.Root +import kotlin.browser.document +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +interface TestSpec { + fun beforeTest() + + fun afterTest() + + fun run(code: () -> Unit) { + beforeTest() + code() + afterTest() + } +} + +interface SimpleSpec : TestSpec { + + override fun beforeTest() { + } + + override fun afterTest() { + } + +} + +interface DomSpec : TestSpec { + + override fun beforeTest() { + val fixture = "
" + + "
" + document.body?.insertAdjacentHTML("afterbegin", fixture) + } + + override fun afterTest() { + val div = document.getElementById("pretest") + div?.let { jQuery(it).remove() } + jQuery(".modal-backdrop").remove() + Root.shutdown() + } + + fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { + if (expected != null && actual != null) { + val exp = jQuery(expected) + val act = jQuery(actual) + val result = exp[0]?.isEqualNode(act[0]) + if (result == true) { + assertTrue(result == true, message) + } else { + assertEquals(expected, actual, message) + } + } else { + assertEquals(expected, actual, message) + } + } +} + +interface WSpec : DomSpec { + + fun runW(code: (widget: Widget, element: Element?) -> Unit) { + run { + val root = Root("test", fixed = true) + val widget = Widget() + widget.id = "test_id" + root.add(widget) + val element = document.getElementById("test_id") + code(widget, element) + } + } + +} + +external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..bfd93900 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt @@ -0,0 +1,53 @@ +/* + * 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.form.select + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.form.select.SelectWidthType +import pl.treksoft.kvision.form.select.SelectInput +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test +import kotlin.test.assertTrue + +class SelectInputSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val selectInput = SelectInput(listOf("test1" to "Test 1", "test2" to "Test 2"), "test1", true).apply { + liveSearch = true + placeholder = "Choose ..." + selectWidthType = SelectWidthType.FIT + emptyOption = true + } + root.add(selectInput) + val element = document.getElementById("test") + assertTrue( + true == element?.innerHTML?.endsWith(""), + "Should render correct select input" + ) + } + } + +} \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..33ccc843 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.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.form.select + +import pl.treksoft.kvision.form.select.SelectOptGroup +import pl.treksoft.kvision.form.select.SelectOption +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class SelectOptGroupSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val selectOptGroup = SelectOptGroup("Group", listOf("test1" to "Test 1", "test2" to "Test 2"), 2) + root.add(selectOptGroup) + val element = document.getElementById("test") + assertEqualsHtml( + "", + element?.innerHTML, + "Should render correct select option group" + ) + selectOptGroup.add(SelectOption("test3", "Test 3")) + assertEqualsHtml( + "", + element?.innerHTML, + "Should render correct select option group with added option" + ) + } + } + +} \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..33c36576 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt @@ -0,0 +1,59 @@ +/* + * 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.form.select + +import pl.treksoft.kvision.form.select.SelectOption +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class SelectOptionSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val selectOption = SelectOption("testValue", "testLabel") + root.add(selectOption) + val element = document.getElementById("test") + assertEqualsHtml( + "", + element?.innerHTML, + "Should render correct select option" + ) + selectOption.icon = "fa-flag" + assertEqualsHtml( + "", + element?.innerHTML, + "Should render correct select option with icon" + ) + selectOption.divider = true + assertEqualsHtml( + "", + element?.innerHTML, + "Should render correct divider option" + ) + } + } + +} \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..9eddff81 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt @@ -0,0 +1,58 @@ +/* + * 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.form.select + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.form.select.SelectWidthType +import pl.treksoft.kvision.form.select.Select +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test +import kotlin.test.assertTrue + +class SelectSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val select = Select(listOf("test1" to "Test 1", "test2" to "Test 2"), "test1", null, true, null, "Label").apply { + liveSearch = true + placeholder = "Choose ..." + selectWidthType = SelectWidthType.FIT + emptyOption = true + } + root.add(select) + val element = document.getElementById("test") + val id = select.input.id + assertTrue( + true == element?.innerHTML?.startsWith("
"), + "Should render correct select form control" + ) + assertTrue( + true == element?.innerHTML?.endsWith("
"), + "Should render correct select form control" + ) + } + } + +} \ No newline at end of file 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-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-bootstrap-spinner/package.json.d/project.info b/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info new file mode 100644 index 00000000..fb0c7956 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Spinner module" +} diff --git a/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt new file mode 100644 index 00000000..de406845 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.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 kVManagerSpinnerInit = KVManagerSpinner.init() + +/** + * Internal singleton object which initializes and configures KVision spinner module. + */ +internal object KVManagerSpinner { + init { + require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css") + require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..afe085d0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt @@ -0,0 +1,263 @@ +/* + * 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.spinner + +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.InvalidFeedback +import pl.treksoft.kvision.form.NumberFormControl +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.SnOn + +/** + * The form field component for spinner control. + * + * @constructor + * @param value spinner value + * @param name the name attribute of the generated HTML input element + * @param min minimal value + * @param max maximal value + * @param step step value (default 1) + * @param decimals number of decimal digits (default 0) + * @param buttonsType spinner buttons type + * @param forceType spinner force rounding type + * @param label label text bound to the input element + * @param rich determines if [label] can contain HTML code + */ +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, + rich: Boolean = false +) : SimplePanel(setOf("form-group")), NumberFormControl { + + /** + * Spinner value. + */ + override var value + get() = input.value + set(value) { + input.value = value + } + /** + * The value attribute of the generated HTML input element. + * + * This value is placed directly in generated HTML code, while the [value] property is dynamically + * bound to the spinner input value. + */ + var startValue + get() = input.startValue + set(value) { + input.startValue = value + } + /** + * Minimal value. + */ + var min + get() = input.min + set(value) { + input.min = value + } + /** + * Maximal value. + */ + var max + get() = input.max + set(value) { + input.max = value + } + /** + * Step value. + */ + var step + get() = input.step + set(value) { + input.step = value + } + /** + * Number of decimal digits value. + */ + var decimals + get() = input.decimals + set(value) { + input.decimals = value + } + /** + * Spinner buttons type. + */ + var buttonsType + get() = input.buttonsType + set(value) { + input.buttonsType = value + } + /** + * Spinner force rounding type. + */ + var forceType + get() = input.forceType + set(value) { + input.forceType = value + } + /** + * The placeholder for the spinner input. + */ + var placeholder + get() = input.placeholder + set(value) { + input.placeholder = value + } + /** + * Determines if the spinner is automatically focused. + */ + var autofocus + get() = input.autofocus + set(value) { + input.autofocus = value + } + /** + * Determines if the spinner is read-only. + */ + var readonly + get() = input.readonly + set(value) { + input.readonly = 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_spinner_$counter" + final override val input: SpinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType) + .apply { + this.id = idc + this.name = name + } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + init { + @Suppress("LeakingThis") + input.eventTarget = this + this.addInternal(flabel) + this.addInternal(input) + this.addInternal(invalidFeedback) + counter++ + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + if (validatorError != null) { + cl.add("text-danger" 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() + } + + /** + * Change value in plus. + */ + open fun spinUp(): Spinner { + input.spinUp() + return this + } + + /** + * Change value in minus. + */ + open fun spinDown(): Spinner { + input.spinDown() + return this + } + + 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.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, + 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 + ) + } + this.add(spinner) + return spinner + } + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..d760f34b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt @@ -0,0 +1,336 @@ +/* + * 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.spinner + +import com.github.snabbdom.VNode +import pl.treksoft.jquery.JQuery +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.form.ValidationStatus +import pl.treksoft.kvision.utils.obj + +/** + * Spinner buttons layout types. + */ +enum class ButtonsType { + NONE, + HORIZONTAL, + VERTICAL +} + +/** + * Spinner force rounding types. + */ +enum class ForceType(internal val value: String) { + NONE("none"), + ROUND("round"), + FLOOR("floor"), + CEIL("ceil") +} + +internal const val DEFAULT_STEP = 1.0 + +/** + * The basic component for spinner control. + * + * @constructor + * @param value spinner value + * @param min minimal value + * @param max maximal value + * @param step step value (default 1) + * @param decimals number of decimal digits (default 0) + * @param buttonsType spinner buttons type + * @param forceType spinner force rounding type + * @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, + classes: Set = 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 { + change = { + self.changeValue() + } + } + } + + /** + * Spinner value. + */ + var value by refreshOnUpdate(value) { refreshState() } + /** + * The value attribute of the generated HTML input element. + * + * This value is placed directly in generated HTML code, while the [value] property is dynamically + * bound to the spinner input value. + */ + var startValue by refreshOnUpdate(value) { this.value = it; refresh() } + /** + * Minimal value. + */ + var min by refreshOnUpdate(min) { refreshSpinner() } + /** + * Maximal value. + */ + var max by refreshOnUpdate(max) { refreshSpinner() } + /** + * Step value. + */ + var step by refreshOnUpdate(step) { refreshSpinner() } + /** + * Number of decimal digits value. + */ + 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 placeholder for the spinner 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) + /** + * Determines if the spinner is automatically focused. + */ + var autofocus: Boolean? by refreshOnUpdate() + /** + * Determines if the spinner is read-only. + */ + var readonly: Boolean? by refreshOnUpdate() + /** + * 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 + + override fun render(): VNode { + return render("input") + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } + size?.let { + cl.add(it.className to true) + } + return cl + } + + @Suppress("ComplexMethod") + override fun getSnAttrs(): List { + val sn = super.getSnAttrs().toMutableList() + sn.add("type" to "text") + startValue?.let { + sn.add("value" to it.toString()) + } + 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.toString()) + } + } + return sn + } + + protected open fun changeValue() { + val v = getElementJQuery()?.`val`() as String? + if (v != null && v.isNotEmpty()) { + this.value = v.toDoubleOrNull() + this.value?.let { + if (min != null && it.toInt() < min ?: 0) this.value = min + if (max != null && it.toInt() > max ?: 0) this.value = max + } + } else { + this.value = null + } + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + getElementJQueryD()?.TouchSpin(getSettingsObj()) + siblings = getElementJQuery()?.parent(".bootstrap-touchspin")?.children("span") + this.getElementJQuery()?.on("change") { e, _ -> + if (e.asDynamic().isTrigger != null) { + val event = org.w3c.dom.events.Event("change") + this.getElement()?.dispatchEvent(event) + } + } + this.getElementJQuery()?.on("touchspin.on.min") { e, _ -> + this.dispatchEvent("onMinBsSpinner", obj { detail = e }) + } + this.getElementJQuery()?.on("touchspin.on.max") { e, _ -> + this.dispatchEvent("onMaxBsSpinner", obj { detail = e }) + } + refreshState() + } + + override fun afterDestroy() { + siblings?.remove() + siblings = null + } + + /** + * Returns the value of the spinner as a String. + * @return value as a String + */ + fun getValueAsString(): String? { + return value?.toString() + } + + /** + * Change value in plus. + */ + fun spinUp(): SpinnerInput { + getElementJQueryD()?.trigger("touchspin.uponce") + return this + } + + /** + * Change value in minus. + */ + fun spinDown(): SpinnerInput { + getElementJQueryD()?.trigger("touchspin.downonce") + return this + } + + private fun refreshState() { + value?.let { + getElementJQuery()?.`val`(it.toString()) + } ?: getElementJQueryD()?.`val`(null) + } + + private fun refreshSpinner() { + getElementJQueryD()?.trigger("touchspin.updatesettings", getSettingsObj()) + } + + private fun getSettingsObj(): dynamic { + val verticalbuttons = buttonsType == ButtonsType.VERTICAL || buttonsType == ButtonsType.NONE + return obj { + this.min = min + this.max = max + this.step = step + this.decimals = decimals + this.verticalbuttons = verticalbuttons + this.forcestepdivisibility = forceType.value + if (verticalbuttons) { + this.verticalup = "" + this.verticaldown = "" + } + this.buttondown_class = "btn btn-default" + this.buttonup_class = "btn btn-default" + } + } + + /** + * Makes the input element focused. + */ + override fun focus() { + getElementJQuery()?.focus() + } + + /** + * Makes the input element blur. + */ + override fun blur() { + getElementJQuery()?.blur() + } + + companion object { + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + 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 = setOf(), + init: (SpinnerInput.() -> Unit)? = null + ): SpinnerInput { + val spinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType, classes).apply { + init?.invoke( + this + ) + } + this.add(spinnerInput) + return spinnerInput + } + } +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..13c8531b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt @@ -0,0 +1,100 @@ +/* + * 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 + +import org.w3c.dom.Element +import pl.treksoft.jquery.jQuery +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.panel.Root +import kotlin.browser.document +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +interface TestSpec { + fun beforeTest() + + fun afterTest() + + fun run(code: () -> Unit) { + beforeTest() + code() + afterTest() + } +} + +interface SimpleSpec : TestSpec { + + override fun beforeTest() { + } + + override fun afterTest() { + } + +} + +interface DomSpec : TestSpec { + + override fun beforeTest() { + val fixture = "
" + + "
" + document.body?.insertAdjacentHTML("afterbegin", fixture) + } + + override fun afterTest() { + val div = document.getElementById("pretest") + div?.let { jQuery(it).remove() } + jQuery(".modal-backdrop").remove() + Root.shutdown() + } + + fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { + if (expected != null && actual != null) { + val exp = jQuery(expected) + val act = jQuery(actual) + val result = exp[0]?.isEqualNode(act[0]) + if (result == true) { + assertTrue(result == true, message) + } else { + assertEquals(expected, actual, message) + } + } else { + assertEquals(expected, actual, message) + } + } +} + +interface WSpec : DomSpec { + + fun runW(code: (widget: Widget, element: Element?) -> Unit) { + run { + val root = Root("test", fixed = true) + val widget = Widget() + widget.id = "test_id" + root.add(widget) + val element = document.getElementById("test_id") + code(widget, element) + } + } + +} + +external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..467e48db --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt @@ -0,0 +1,75 @@ +/* + * 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.form.spinner + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.form.spinner.SpinnerInput +import test.pl.treksoft.kvision.DomSpec +import kotlin.test.Test +import kotlin.test.assertEquals + +class SpinnerInputSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val si = SpinnerInput(value = 13).apply { + placeholder = "place" + id = "idti" + } + root.add(si) + val value = si.getElementJQuery()?.`val`() + assertEquals("13", value, "Should render spinner input with correct value") + } + } + + @Test + fun spinUp() { + run { + val root = Root("test", fixed = true) + val si = SpinnerInput(value = 13).apply { + placeholder = "place" + id = "idti" + } + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinUp") + si.spinUp() + assertEquals(14, si.value, "Should return changed value after spinUp") + } + } + + @Test + fun spinDown() { + run { + val root = Root("test", fixed = true) + val si = SpinnerInput(value = 13).apply { + placeholder = "place" + id = "idti" + } + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinDown") + si.spinDown() + assertEquals(12, si.value, "Should return changed value after spinDown") + } + } +} \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..ead19d86 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt @@ -0,0 +1,82 @@ +/* + * 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.form.spinner + +import pl.treksoft.kvision.form.spinner.Spinner +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test +import kotlin.test.assertEquals + +class SpinnerSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val ti = Spinner(value = 13, label = "Label").apply { + placeholder = "place" + name = "name" + disabled = true + } + root.add(ti) + val element = document.getElementById("test") + val id = ti.input.id + assertEqualsHtml( + "
", + element?.innerHTML, + "Should render correct spinner input form control" + ) + ti.validatorError = "Validation Error" + assertEqualsHtml( + "
Validation Error
", + element?.innerHTML, + "Should render correct spinner input form control with validation error" + ) + } + } + + @Test + fun spinUp() { + run { + val root = Root("test", fixed = true) + val si = Spinner(value = 13) + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinUp") + si.spinUp() + assertEquals(14, si.value, "Should return changed value after spinUp") + } + } + + @Test + fun spinDown() { + run { + val root = Root("test", fixed = true) + val si = Spinner(value = 13) + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinDown") + si.spinDown() + assertEquals(12, si.value, "Should return changed value after spinDown") + } + } +} \ No newline at end of file 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..a0dfa950 --- /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", "4.5.2") + } + +} diff --git a/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info b/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info new file mode 100644 index 00000000..d789d81b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Upload module" +} diff --git a/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt new file mode 100644 index 00000000..f3370743 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt @@ -0,0 +1,75 @@ +/* + * 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. + */ +internal object KVManagerUpload { + + init { + require("bootstrap-fileinput/css/fileinput.min.css") + require("bootstrap-fileinput/themes/explorer-fa/theme.min.css") + 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") + require("bootstrap-fileinput/themes/explorer-fa/theme.min.js") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..bd931127 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-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.InvalidFeedback +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 invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + init { + @Suppress("LeakingThis") + input.eventTarget = this + this.addInternal(flabel) + this.addInternal(input) + this.addInternal(invalidFeedback) + counter++ + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + if (validatorError != null) { + cl.add("text-danger" 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 + */ + override 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-bootstrap-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 new file mode 100644 index 00000000..71e00ede --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt @@ -0,0 +1,375 @@ +/* + * 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.form.ValidationStatus +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() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() + + private val nativeFiles: MutableMap = mutableMapOf() + + override fun render(): VNode { + return render("input") + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } + 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()) + if (uploadUrl != null) { + 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 + } ?: listOf() + } + + /** + * 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. + */ + override fun focus() { + getElementJQuery()?.focus() + } + + /** + * Makes the input element blur. + */ + override 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.fileActionSettings = obj { + this.showUpload = showUpload + this.showRemove = showRemove + } + this.language = language + } + } + + companion object { + + /** + * 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 + */ + 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 + */ + 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-bootstrap-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 new file mode 100644 index 00000000..bdae5091 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt @@ -0,0 +1,73 @@ +/* + * 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.utils + +import kotlinx.coroutines.suspendCancellableCoroutine +import org.w3c.files.File +import org.w3c.files.FileReader +import pl.treksoft.kvision.form.Form +import pl.treksoft.kvision.form.FormPanel +import pl.treksoft.kvision.form.KFilesFormControl +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException + +/** + * Suspending extension function to get file content. + * @return file content + */ +suspend fun File.getContent(): String = suspendCancellableCoroutine { cont -> + val reader = FileReader() + reader.onload = { + @Suppress("UnsafeCastFromDynamic") + cont.resume(reader.result) + } + reader.onerror = { e -> + cont.resumeWithException(Exception(e.type)) + } + reader.readAsDataURL(this@getContent) +} + +/** + * Returns current data model with file content read for all KFiles controls. + * @return data model + */ +suspend fun Form.getDataWithFileContent(): K { + val map = this.fields.entries.associateBy({ it.key }, { + val value = it.value + if (value is KFilesFormControl) { + value.getValue()?.map { + it.copy(content = value.getNativeFile(it)?.getContent()) + } + } else { + value.getValue() + } + }) + return this.modelFactory(map.withDefault { null }) +} + +/** + * Returns current data model with file content read for all KFiles controls. + * @return data model + */ +suspend fun FormPanel.getDataWithFileContent(): K { + return this.form.getDataWithFileContent() +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..92d32d28 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-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-bootstrap-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 new file mode 100644 index 00000000..5a9c6440 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-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-bootstrap-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 new file mode 100644 index 00000000..cf75d1ab --- /dev/null +++ b/kvision-modules/kvision-bootstrap-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-bootstrap-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 new file mode 100644 index 00000000..16514535 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-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-bootstrap-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 new file mode 100644 index 00000000..685da85d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-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-bootstrap-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 new file mode 100644 index 00000000..f5e8b723 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-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říliš malý, musí mít velikost nejméně {minSize} KB.', + msgSizeTooLarge: 'Soubor "{name}" ({size} KB) je příliš velký, maximální povolená velikost {maxSize} KB.', + msgFilesTooLess: 'Musíte vybrat nejméně {n} {files} souborů.', + msgFilesTooMany: 'Počet vybraných souborů ({n}) překročil maximální povolený limit {m}.', + msgFileNotFound: 'Soubor "{name}" nebyl nalezen!', + msgFileSecured: 'Zabezpečení souboru znemožnilo číst soubor "{name}".', + msgFileNotReadable: 'Soubor "{name}" není čitelný.', + msgFilePreviewAborted: 'Náhled souboru byl přerušen pro "{name}".', + msgFilePreviewError: 'Nastala chyba při načtení souboru "{name}".', + msgInvalidFileName: 'Neplatné nebo nepovolené znaky ve jménu souboru "{name}".', + msgInvalidFileType: 'Neplatný typ souboru "{name}". Pouze "{types}" souborů jsou podporovány.', + msgInvalidFileExtension: 'Neplatná extenze souboru "{name}". Pouze "{extensions}" souborů jsou podporovány.', + msgFileTypes: { + 'image': 'obrázek', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Nahrávání souboru bylo přerušeno', + msgUploadThreshold: 'Zpracovávám...', + msgUploadBegin: 'Inicializujem...', + msgUploadEnd: 'Hotovo', + msgUploadEmpty: 'Pro nahrávání nejsou k dispozici žádné platné údaje.', + msgUploadError: '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.', + msgSelected: '{n} {files} vybráno', + msgFoldersNotAllowed: 'Táhni a pusť pouze soubory! Vynechané {n} pustěné složk(y).', + msgImageWidthSmall: 'Šířka obrázku "{name}", musí být alespoň {size} px.', + msgImageHeightSmall: 'Výška obrázku "{name}", musí být alespoň {size} px.', + msgImageWidthLarge: 'Šířka obrázku "{name}" nesmí být větší než {size} px.', + msgImageHeightLarge: 'Výška obrázku "{name}" nesmí být větší než {size} px.', + msgImageResizeError: 'Nelze získat rozměry obrázku pro změnu velikosti.', + msgImageResizeException: 'Chyba při změně velikosti obrázku.
{errors}
', + msgAjaxError: 'Došlo k chybě v {operation}. Prosím zkuste to znovu později!', + msgAjaxProgressError: '{operation} - neúspěšné', + ajaxOperations: { + deleteThumb: 'odstranit soubor', + uploadThumb: 'nahrát soubor', + uploadBatch: 'nahrát várku souborů', + uploadExtra: 'odesílání dat formuláře' + }, + dropZoneTitle: 'Přetáhni soubory sem …', + dropZoneClickTitle: '
(nebo klikni sem a vyber je)', + fileActionSettings: { + removeTitle: 'Odstranit soubor', + uploadTitle: 'Nahrát soubor', + uploadRetryTitle: 'Opakovat nahrávání', + downloadTitle: 'Stáhnout soubor', + zoomTitle: 'Zobrazit podrobnosti', + dragTitle: 'Posunout / Přeskládat', + indicatorNewTitle: 'Ještě nenahrál', + indicatorSuccessTitle: 'Nahraný', + indicatorErrorTitle: 'Chyba nahrávání', + indicatorLoadingTitle: 'Nahrávání ...' + }, + previewZoomButtonTitles: { + prev: 'Zobrazit předchozí soubor', + next: 'Zobrazit následující soubor', + toggleheader: 'Přepnout záhlaví', + fullscreen: 'Přepnout celoobrazovkové zobrazení', + borderless: 'Přepnout bezrámečkové zobrazení', + close: 'Zavřít detailní náhled' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..11a13892 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js @@ -0,0 +1,100 @@ +/*! + * FileInput Danish 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['da'] = { + fileSingle: 'fil', + filePlural: 'filer', + browseLabel: 'Browse …', + removeLabel: 'Fjern', + removeTitle: 'Fjern valgte filer', + cancelLabel: 'Fortryd', + cancelTitle: 'Afbryd nuværende upload', + uploadLabel: 'Upload', + uploadTitle: 'Upload valgte filer', + msgNo: 'Ingen', + msgNoFilesSelected: '', + msgCancelled: 'aflyst', + msgPlaceholder: 'Vælg {files}...', + msgZoomModalHeading: 'Detaljeret visning', + msgFileRequired: 'Du skal vælge en fil at uploade.', + msgSizeTooSmall: 'Fil "{name}" ({size} KB) er for lille og skal være større end {minSize} KB.', + msgSizeTooLarge: 'Fil "{name}" ({size} KB) er større end de tilladte {maxSize} KB.', + msgFilesTooLess: 'Du skal mindst vælge {n} {files} til upload.', + msgFilesTooMany: '({n}) filer valgt til upload, men maks. {m} er tilladt.', + msgFileNotFound: 'Filen "{name}" blev ikke fundet!', + msgFileSecured: 'Sikkerhedsrestriktioner forhindrer læsning af "{name}".', + msgFileNotReadable: 'Filen "{name}" kan ikke indlæses.', + msgFilePreviewAborted: 'Filgennemsyn annulleret for "{name}".', + msgFilePreviewError: 'Der skete en fejl under læsningen af filen "{name}".', + msgInvalidFileName: 'Ugyldige eller ikke-understøttede tegn i filnavn "{name}".', + msgInvalidFileType: 'Ukendt type for filen "{name}". Kun "{types}" kan bruges.', + msgInvalidFileExtension: 'Ukendt filtype for filen "{name}". Kun "{extensions}" filer kan bruges.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Filupload annulleret', + msgUploadThreshold: 'Arbejder...', + msgUploadBegin: 'Initialiserer...', + msgUploadEnd: 'Udført', + msgUploadEmpty: 'Ingen gyldig data tilgængelig til upload.', + msgUploadError: 'Fejl', + msgValidationError: 'Valideringsfejl', + msgLoading: 'Henter fil {index} af {files} …', + msgProgress: 'Henter fil {index} af {files} - {name} - {percent}% færdiggjort.', + msgSelected: '{n} {files} valgt', + msgFoldersNotAllowed: 'Drag & drop kun filer! {n} mappe(r) sprunget over.', + msgImageWidthSmall: 'Bredden af billedet "{name}" skal være på mindst {size} px.', + msgImageHeightSmall: 'Højden af billedet "{name}" skal være på mindst {size} px.', + msgImageWidthLarge: 'Bredden af billedet "{name}" må ikke være over {size} px.', + msgImageHeightLarge: 'Højden af billedet "{name}" må ikke være over {size} px.', + msgImageResizeError: 'Kunne ikke få billedets dimensioner for at ændre størrelsen.', + msgImageResizeException: 'Fejl ved at ændre størrelsen på billedet.
{errors}
', + msgAjaxError: 'Noget gik galt med {operation} operationen. Forsøg venligst senere!', + msgAjaxProgressError: '{operation} fejlede', + ajaxOperations: { + deleteThumb: 'fil slet', + uploadThumb: 'fil upload', + uploadBatch: 'batchfil upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Drag & drop filer her …', + dropZoneClickTitle: '
(eller klik for at vælge {files})', + fileActionSettings: { + removeTitle: 'Fjern fil', + uploadTitle: 'Upload fil', + uploadRetryTitle: 'Forsåg upload igen', + downloadTitle: 'Download fil', + zoomTitle: 'Se detaljer', + dragTitle: 'Flyt / Omarranger', + indicatorNewTitle: 'Ikke uploadet endnu', + indicatorSuccessTitle: 'Uploadet', + indicatorErrorTitle: 'Upload fejl', + indicatorLoadingTitle: 'Uploader ...' + }, + previewZoomButtonTitles: { + prev: 'Se forrige fil', + next: 'Se næste fil', + toggleheader: 'Skift header', + fullscreen: 'Skift fuld skærm', + borderless: 'Skift grænseløs mode', + close: 'Luk detaljeret visning' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..56ee854b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js @@ -0,0 +1,98 @@ +/*! + * FileInput German 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 + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['de'] = { + fileSingle: 'Datei', + filePlural: 'Dateien', + browseLabel: 'Auswählen …', + removeLabel: 'Löschen', + removeTitle: 'Ausgewählte löschen', + cancelLabel: 'Abbrechen', + cancelTitle: 'Hochladen abbrechen', + uploadLabel: 'Hochladen', + uploadTitle: 'Hochladen der ausgewählten Dateien', + msgNo: 'Keine', + msgNoFilesSelected: 'Keine Dateien ausgewählt', + msgCancelled: 'Abgebrochen', + msgPlaceholder: '{files} auswählen...', + msgZoomModalHeading: 'ausführliche Vorschau', + msgFileRequired: 'Sie müssen eine Datei zum Hochladen auswählen.', + msgSizeTooSmall: 'Datei "{name}" ({size} KB) unterschreitet mindestens notwendige Upload-Größe von {minSize} KB.', + msgSizeTooLarge: 'Datei "{name}" ({size} KB) überschreitet maximal zulässige Upload-Größe von {maxSize} KB.', + msgFilesTooLess: 'Sie müssen mindestens {n} {files} zum Hochladen auswählen.', + msgFilesTooMany: 'Anzahl der zum Hochladen ausgewählten Dateien ({n}), überschreitet maximal zulässige Grenze von {m} Stück.', + msgFileNotFound: 'Datei "{name}" wurde nicht gefunden!', + msgFileSecured: 'Sicherheitseinstellungen verhindern das Lesen der Datei "{name}".', + msgFileNotReadable: 'Die Datei "{name}" ist nicht lesbar.', + msgFilePreviewAborted: 'Dateivorschau abgebrochen für "{name}".', + msgFilePreviewError: 'Beim Lesen der Datei "{name}" ein Fehler aufgetreten.', + msgInvalidFileName: 'Ungültige oder nicht unterstützte Zeichen im Dateinamen "{name}".', + msgInvalidFileType: 'Ungültiger Typ für Datei "{name}". Nur Dateien der Typen "{types}" werden unterstützt.', + msgInvalidFileExtension: 'Ungültige Erweiterung für Datei "{name}". Nur Dateien mit der Endung "{extensions}" werden unterstützt.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Der Datei-Upload wurde abgebrochen', + msgUploadThreshold: 'Wird bearbeitet ...', + msgUploadBegin: 'Wird initialisiert ...', + msgUploadEnd: 'Erledigt', + msgUploadEmpty: 'Keine gültigen Daten zum Hochladen verfügbar.', + msgUploadError: 'Fehler', + msgValidationError: 'Validierungsfehler', + msgLoading: 'Lade Datei {index} von {files} hoch…', + msgProgress: 'Datei {index} von {files} - {name} - zu {percent}% fertiggestellt.', + msgSelected: '{n} {files} ausgewählt', + msgFoldersNotAllowed: 'Drag & Drop funktioniert nur bei Dateien! {n} Ordner übersprungen.', + msgImageWidthSmall: 'Breite der Bilddatei "{name}" muss mindestens {size} px betragen.', + msgImageHeightSmall: 'Höhe der Bilddatei "{name}" muss mindestens {size} px betragen.', + msgImageWidthLarge: 'Breite der Bilddatei "{name}" nicht überschreiten {size} px.', + msgImageHeightLarge: 'Höhe der Bilddatei "{name}" nicht überschreiten {size} px.', + msgImageResizeError: 'Konnte nicht die Bildabmessungen zu ändern.', + msgImageResizeException: 'Fehler beim Ändern der Größe des Bildes.
{errors}
', + msgAjaxError: 'Bei der Aktion {operation} ist ein Fehler aufgetreten. Bitte versuche es später noch einmal!', + msgAjaxProgressError: '{operation} fehlgeschlagen', + ajaxOperations: { + deleteThumb: 'Datei löschen', + uploadThumb: 'Datei hochladen', + uploadBatch: 'Batch-Datei-Upload', + uploadExtra: 'Formular-Datei-Upload' + }, + dropZoneTitle: 'Dateien hierher ziehen …', + dropZoneClickTitle: '
(oder klicken um {files} auszuwählen)', + fileActionSettings: { + removeTitle: 'Datei entfernen', + uploadTitle: 'Datei hochladen', + uploadRetryTitle: 'Upload erneut versuchen', + downloadTitle: 'Datei herunterladen', + zoomTitle: 'Details anzeigen', + dragTitle: 'Verschieben / Neuordnen', + indicatorNewTitle: 'Noch nicht hochgeladen', + indicatorSuccessTitle: 'Hochgeladen', + indicatorErrorTitle: 'Upload Fehler', + indicatorLoadingTitle: 'Hochladen ...' + }, + previewZoomButtonTitles: { + prev: 'Vorherige Datei anzeigen', + next: 'Nächste Datei anzeigen', + toggleheader: 'Header umschalten', + fullscreen: 'Vollbildmodus umschalten', + borderless: 'Randlosen Modus umschalten', + close: 'Detailansicht schließen' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..170eba1f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js @@ -0,0 +1,100 @@ +/*! + * FileInput Greek 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['el'] = { + 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: 'Το "{name}" ({size} KB) είναι πολύ μικρό, πρέπει να είναι μεγαλύτερο από {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: 'Μη έγκυροι χαρακτήρες στο όνομα του αρχείου "{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: 'Μεταφόρτωση ...', + 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: '
(ή πατήστε για επιλογή {files})', + fileActionSettings: { + removeTitle: 'Αφαιρέστε το αρχείο', + uploadTitle: 'Μεταφορτώστε το αρχείο', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Δείτε λεπτομέρειες', + dragTitle: 'Μετακίνηση/Προσπαρμογή', + indicatorNewTitle: 'Δεν μεταφορτώθηκε ακόμα', + indicatorSuccessTitle: 'Μεταφορτώθηκε', + indicatorErrorTitle: 'Σφάλμα Μεταφόρτωσης', + indicatorLoadingTitle: 'Μεταφόρτωση ...' + }, + previewZoomButtonTitles: { + prev: 'Προηγούμενο αρχείο', + next: 'Επόμενο αρχείο', + toggleheader: 'Εμφάνιση/Απόκρυψη τίτλου', + fullscreen: 'Εναλλαγή πλήρους οθόνης', + borderless: 'Με ή χωρίς πλαίσιο', + close: 'Κλείσιμο προβολής' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..569e7ee5 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js @@ -0,0 +1,100 @@ +/*! + * FileInput Spanish 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['es'] = { + fileSingle: 'archivo', + filePlural: 'archivos', + browseLabel: 'Examinar …', + removeLabel: 'Quitar', + removeTitle: 'Quitar archivos seleccionados', + cancelLabel: 'Cancelar', + cancelTitle: 'Abortar la subida en curso', + uploadLabel: 'Subir archivo', + uploadTitle: 'Subir archivos seleccionados', + msgNo: 'No', + msgNoFilesSelected: 'No hay archivos seleccionados', + msgCancelled: 'Cancelado', + msgPlaceholder: 'Seleccionar {files}...', + msgZoomModalHeading: 'Vista previa detallada', + msgFileRequired: 'Debes seleccionar un archivo para subir.', + msgSizeTooSmall: 'El archivo "{name}" ({size} KB) es demasiado pequeño y debe ser mayor de {minSize} KB.', + msgSizeTooLarge: 'El archivo "{name}" ({size} KB) excede el tamaño máximo permitido de {maxSize} KB.', + msgFilesTooLess: 'Debe seleccionar al menos {n} {files} a cargar.', + msgFilesTooMany: 'El número de archivos seleccionados a cargar ({n}) excede el límite máximo permitido de {m}.', + msgFileNotFound: 'Archivo "{name}" no encontrado.', + msgFileSecured: 'No es posible acceder al archivo "{name}" porque está siendo usado por otra aplicación o no tiene permisos de lectura.', + msgFileNotReadable: 'No es posible acceder al archivo "{name}".', + msgFilePreviewAborted: 'Previsualización del archivo "{name}" cancelada.', + msgFilePreviewError: 'Ocurrió un error mientras se leía el archivo "{name}".', + msgInvalidFileName: 'Caracteres no válidos o no soportados en el nombre del archivo "{name}".', + msgInvalidFileType: 'Tipo de archivo no válido para "{name}". Sólo se permiten archivos de tipo "{types}".', + msgInvalidFileExtension: 'Extensión de archivo no válida para "{name}". Sólo se permiten archivos "{extensions}".', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'La carga de archivos se ha cancelado', + msgUploadThreshold: 'Procesando...', + msgUploadBegin: 'Inicializando...', + msgUploadEnd: 'Hecho', + msgUploadEmpty: 'No existen datos válidos para el envío.', + msgUploadError: 'Error', + msgValidationError: 'Error de validación', + msgLoading: 'Subiendo archivo {index} de {files} …', + msgProgress: 'Subiendo archivo {index} de {files} - {name} - {percent}% completado.', + msgSelected: '{n} {files} seleccionado(s)', + msgFoldersNotAllowed: 'Arrastre y suelte únicamente archivos. Omitida(s) {n} carpeta(s).', + msgImageWidthSmall: 'El ancho de la imagen "{name}" debe ser de al menos {size} px.', + msgImageHeightSmall: 'La altura de la imagen "{name}" debe ser de al menos {size} px.', + msgImageWidthLarge: 'El ancho de la imagen "{name}" no puede exceder de {size} px.', + msgImageHeightLarge: 'La altura de la imagen "{name}" no puede exceder de {size} px.', + msgImageResizeError: 'No se pudieron obtener las dimensiones de la imagen para cambiar el tamaño.', + msgImageResizeException: 'Error al cambiar el tamaño de la imagen.
{errors}
', + 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', + ajaxOperations: { + deleteThumb: 'Archivo borrado', + uploadThumb: 'Archivo subido', + uploadBatch: 'Datos subidos en lote', + uploadExtra: 'Datos del formulario subidos ' + }, + dropZoneTitle: 'Arrastre y suelte aquí los archivos …', + dropZoneClickTitle: '
(o haga clic para seleccionar {files})', + fileActionSettings: { + removeTitle: 'Eliminar archivo', + uploadTitle: 'Subir archivo', + uploadRetryTitle: 'Reintentar subir', + downloadTitle: 'Descargar archivo', + zoomTitle: 'Ver detalles', + dragTitle: 'Mover / Reordenar', + indicatorNewTitle: 'No subido todavía', + indicatorSuccessTitle: 'Subido', + indicatorErrorTitle: 'Error al subir', + indicatorLoadingTitle: 'Subiendo...' + }, + previewZoomButtonTitles: { + prev: 'Anterior', + next: 'Siguiente', + toggleheader: 'Mostrar encabezado', + fullscreen: 'Pantalla completa', + borderless: 'Modo sin bordes', + close: 'Cerrar vista detallada' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..50b15477 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js @@ -0,0 +1,99 @@ +/*! + * FileInput Estonian 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['et'] = { + fileSingle: 'fail', + filePlural: 'failid', + browseLabel: 'Sirvi …', + removeLabel: 'Eemalda', + removeTitle: 'Clear selected files', + cancelLabel: 'Tühista', + cancelTitle: 'Abort ongoing upload', + uploadLabel: 'Salvesta', + uploadTitle: 'Salvesta valitud failid', + msgNo: 'No', + msgNoFilesSelected: 'No files selected', + msgCancelled: 'Cancelled', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Detailed Preview', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Fail "{name}" ({size} KB) ületab lubatu suuruse {maxSize} KB.', + msgFilesTooLess: 'You must select at least {n} {files} to upload.', + msgFilesTooMany: 'Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.', + msgFileNotFound: 'File "{name}" not found!', + msgFileSecured: 'Security restrictions prevent reading the file "{name}".', + msgFileNotReadable: 'File "{name}" is not readable.', + msgFilePreviewAborted: 'File preview aborted for "{name}".', + msgFilePreviewError: 'An error occurred while reading the file "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: '"{name}" on vale tüüpi. Ainult "{types}" on lubatud.', + msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'The file upload was aborted', + msgUploadThreshold: 'Processing...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'Validation Error', + msgLoading: 'Loading file {index} of {files} …', + msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.', + msgSelected: '{n} {files} selected', + msgFoldersNotAllowed: 'Drag & drop files only! Skipped {n} dropped folder(s).', + msgImageWidthSmall: 'Pildi laius peab olema vähemalt {size} px.', + msgImageHeightSmall: 'Pildi kõrgus peab olema vähemalt {size} px.', + msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', + msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', + msgImageResizeError: 'Could not get the image dimensions to resize.', + msgImageResizeException: 'Error while resizing the image.
{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: 'Lohista failid siia …', + dropZoneClickTitle: '
(or click to select {files})', + fileActionSettings: { + removeTitle: 'Eemalda fail', + uploadTitle: 'Salvesta fail', + uploadRetryTitle: 'Retry upload', + zoomTitle: 'Vaata detaile', + dragTitle: 'Liiguta / Korralda', + indicatorNewTitle: 'Pole veel salvestatud', + indicatorSuccessTitle: 'Uploaded', + indicatorErrorTitle: 'Salvestamise viga', + indicatorLoadingTitle: 'Salvestan ...' + }, + 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/kvision-bootstrap-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 new file mode 100644 index 00000000..609099c4 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js @@ -0,0 +1,101 @@ +/*! + * FileInput Persian 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 Milad Nekofar + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['fa'] = { + fileSingle: 'فایل', + filePlural: 'فایل‌ها', + browseLabel: 'مرور …', + removeLabel: 'حذف', + removeTitle: 'پاکسازی فایل‌های انتخاب شده', + cancelLabel: 'لغو', + cancelTitle: 'لغو بارگزاری جاری', + uploadLabel: 'بارگذاری', + uploadTitle: 'بارگذاری فایل‌های انتخاب شده', + msgNo: 'نه', + msgNoFilesSelected: 'هیچ فایلی انتخاب نشده است', + msgCancelled: 'لغو شد', + msgPlaceholder: 'انتخاب {files}...', + msgZoomModalHeading: 'نمایش با جزییات', + msgFileRequired: 'شما باید یک فایل برای بارگذاری انتخاب نمایید.', + msgSizeTooSmall: 'فایل "{name}" ({size} کیلوبایت) خیلی کوچک است و باید از {minSize} کیلوبایت بزرگتر باشد.', + msgSizeTooLarge: 'فایل "{name}" ({size} کیلوبایت) از حداکثر مجاز {maxSize} کیلوبایت بزرگتر است.', + msgFilesTooLess: 'شما باید حداقل {n} {files} فایل برای بارگذاری انتخاب کنید.', + msgFilesTooMany: 'تعداد فایل‌های انتخاب شده برای بارگذاری ({n}) از حداکثر مجاز عبور کرده است {m}.', + msgFileNotFound: 'فایل "{name}" یافت نشد!', + msgFileSecured: 'محدودیت های امنیتی مانع خواندن فایل "{name}" است.', + msgFileNotReadable: 'فایل "{name}" قابل نوشتن نیست.', + msgFilePreviewAborted: 'پیش نمایش فایل "{name}". به مشکل خورد', + msgFilePreviewError: 'در هنگام خواندن فایل "{name}" خطایی رخ داد.', + msgInvalidFileName: 'کاراکترهای غیرمجاز و یا ناشناخته در نام فایل "{name}".', + msgInvalidFileType: 'نوع فایل "{name}" معتبر نیست. فقط "{types}" پشیبانی می‌شوند.', + msgInvalidFileExtension: 'پسوند فایل "{name}" معتبر نیست. فقط "{extensions}" پشتیبانی می‌شوند.', + msgFileTypes: { + 'image': 'عکس', + 'html': 'اچ تا ام ال', + 'text': 'متن', + 'video': 'ویدئو', + 'audio': 'صدا', + 'flash': 'فلش', + 'pdf': 'پی دی اف', + 'object': 'دیگر' + }, + msgUploadAborted: 'بارگذاری فایل به مشکل خورد.', + msgUploadThreshold: 'در حال پردازش...', + msgUploadBegin: 'در حال شروع...', + msgUploadEnd: 'انجام شد', + msgUploadEmpty: 'هیچ داده معتبری برای بارگذاری موجود نیست.', + msgUploadError: 'Error', + msgValidationError: 'خطای اعتبار سنجی', + msgLoading: 'بارگیری فایل {index} از {files} …', + msgProgress: 'بارگیری فایل {index} از {files} - {name} - {percent}% تمام شد.', + msgSelected: '{n} {files} انتخاب شده', + msgFoldersNotAllowed: 'فقط فایل‌ها را بکشید و رها کنید! {n} پوشه نادیده گرفته شد.', + msgImageWidthSmall: 'عرض فایل تصویر "{name}" باید حداقل {size} پیکسل باشد.', + msgImageHeightSmall: 'ارتفاع فایل تصویر "{name}" باید حداقل {size} پیکسل باشد.', + msgImageWidthLarge: 'عرض فایل تصویر "{name}" نمیتواند از {size} پیکسل بیشتر باشد.', + msgImageHeightLarge: 'ارتفاع فایل تصویر "{name}" نمی‌تواند از {size} پیکسل بیشتر باشد.', + msgImageResizeError: 'یافت نشد ابعاد تصویر را برای تغییر اندازه.', + msgImageResizeException: 'خطا در هنگام تغییر اندازه تصویر.
{errors}
', + msgAjaxError: 'به نظر مشکلی در حین {operation} روی داده است. لطفا دوباره تلاش کنید!', + msgAjaxProgressError: '{operation} لغو شد', + ajaxOperations: { + deleteThumb: 'حذف فایل', + uploadThumb: 'بارگذاری فایل', + uploadBatch: 'بارگذاری جمعی فایلها', + uploadExtra: 'بارگذاری با کمک فُرم' + }, + dropZoneTitle: 'فایل‌ها را بکشید و در اینجا رها کنید …', + dropZoneClickTitle: '
(یا برای انتخاب {files} کلیک کنید)', + fileActionSettings: { + removeTitle: 'حذف فایل', + uploadTitle: 'آپلود فایل', + uploadRetryTitle: 'بارگیری مجدد', + downloadTitle: 'دریافت فایل', + zoomTitle: 'دیدن جزئیات', + dragTitle: 'جابجایی / چیدمان', + indicatorNewTitle: 'آپلود نشده است', + indicatorSuccessTitle: 'آپلود شده', + indicatorErrorTitle: 'بارگذاری خطا', + indicatorLoadingTitle: 'آپلود ...' + }, + previewZoomButtonTitles: { + prev: 'مشاهده فایل قبلی', + next: 'مشاهده فایل بعدی', + toggleheader: 'نمایش عنوان', + fullscreen: 'نمایش تمام صفحه', + borderless: 'نمایش حاشیه', + close: 'بستن نمایش با جزییات' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..19317b54 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js @@ -0,0 +1,91 @@ +/*! + * FileInput Finnish 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.fi = { + fileSingle: 'tiedosto', + filePlural: 'tiedostot', + browseLabel: 'Selaa …', + removeLabel: 'Poista', + removeTitle: 'Tyhjännä valitut tiedostot', + cancelLabel: 'Peruuta', + cancelTitle: 'Peruuta lataus', + uploadLabel: 'Lataa', + uploadTitle: 'Lataa valitut tiedostot', + msgNoFilesSelected: '', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Tiedosto "{name}" ({size} Kt) ylittää suurimman sallitun tiedoston koon, joka on {maxSize} Kt. Yritä uudelleen!', + msgFilesTooLess: 'Vähintään {n} {files} tiedostoa on valittava ladattavaksi. Ole hyvä ja yritä uudelleen!', + msgFilesTooMany: 'Valittujen tiedostojen lukumäärä ({n}) ylittää suurimman sallitun määrän {m}. Ole hyvä ja yritä uudelleen!', + msgFileNotFound: 'Tiedostoa "{name}" ei löydy!', + msgFileSecured: 'Tietoturvarajoitukset estävät tiedoston "{name}" lukemisen.', + msgFileNotReadable: 'Tiedosto "{name}" ei ole luettavissa.', + msgFilePreviewAborted: 'Tiedoston "{name}" esikatselu keskeytetty.', + msgFilePreviewError: 'Virhe on tapahtunut luettaessa tiedostoa "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Tiedosto "{name}" on väärän tyyppinen. Ainoastaan tiedostot tyyppiä "{types}" ovat tuettuja.', + msgInvalidFileExtension: 'Tiedoston "{name}" tarkenne on epäkelpo. Ainoastaan tarkenteet "{extensions}" ovat tuettuja.', + msgFileTypes: { + 'image': 'Kuva', + 'html': 'HTML', + 'text': 'Teksti', + 'video': 'Video', + 'audio': 'Ääni', + 'flash': 'Flash', + 'pdf': 'PDF', + 'object': 'Olio' + }, + msgUploadThreshold: 'Käsitellään...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'Ei ladattavaa dataa.', + msgUploadError: 'Error', + msgValidationError: 'Tiedoston latausvirhe', + msgLoading: 'Ladataan tiedostoa {index} / {files} …', + msgProgress: 'Ladataan tiedostoa {index} / {files} - {name} - {percent}% valmistunut.', + msgSelected: '{n} tiedostoa valittu', + 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', + ajaxOperations: { + deleteThumb: 'file delete', + uploadThumb: 'file upload', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Raahaa ja pudota tiedostot tähän …', + dropZoneClickTitle: '
(tai valitse hiirellä {files})', + fileActionSettings: { + removeTitle: 'Poista tiedosto', + uploadTitle: 'Upload file', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Yksityiskohdat', + dragTitle: 'Siirrä / Järjestele', + indicatorNewTitle: 'Ei ladattu', + indicatorSuccessTitle: 'Ladattu', + indicatorErrorTitle: 'Lataus epäonnistui', + indicatorLoadingTitle: 'Ladataan ...' + }, + previewZoomButtonTitles: { + prev: 'Seuraava tiedosto', + next: 'Edellinen tiedosto', + toggleheader: 'Näytä otsikko', + fullscreen: 'Kokonäytön tila', + borderless: 'Rajaton tila', + close: 'Sulje esikatselu' + } + }; + + $.extend($.fn.fileinput.defaults, $.fn.fileinputLocales.fi); +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..81a77042 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js @@ -0,0 +1,99 @@ +/*! + * FileInput French 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['fr'] = { + fileSingle: 'fichier', + filePlural: 'fichiers', + browseLabel: 'Parcourir…', + removeLabel: 'Retirer', + removeTitle: 'Retirer les fichiers sélectionnés', + cancelLabel: 'Annuler', + cancelTitle: "Annuler l'envoi en cours", + uploadLabel: 'Transférer', + uploadTitle: 'Transférer les fichiers sélectionnés', + msgNo: 'Non', + msgNoFilesSelected: '', + msgCancelled: 'Annulé', + msgPlaceholder: 'Sélectionner le(s) {files}...', + msgZoomModalHeading: 'Aperçu détaillé', + msgFileRequired: 'Vous devez sélectionner un fichier à uploader.', + msgSizeTooSmall: 'Le fichier "{name}" ({size} KB) est inférieur à la taille minimale de {minSize} KB.', + msgSizeTooLarge: 'Le fichier "{name}" ({size} Ko) dépasse la taille maximale autorisée qui est de {maxSize} Ko.', + msgFilesTooLess: 'Vous devez sélectionner au moins {n} {files} à transmettre.', + msgFilesTooMany: 'Le nombre de fichier sélectionné ({n}) dépasse la quantité maximale autorisée qui est de {m}.', + msgFileNotFound: 'Le fichier "{name}" est introuvable !', + msgFileSecured: "Des restrictions de sécurité vous empêchent d'accéder au fichier \"{name}\".", + msgFileNotReadable: 'Le fichier "{name}" est illisible.', + msgFilePreviewAborted: 'Prévisualisation du fichier "{name}" annulée.', + msgFilePreviewError: 'Une erreur est survenue lors de la lecture du fichier "{name}".', + msgInvalidFileName: 'Caractères invalides ou non supportés dans le nom de fichier "{name}".', + msgInvalidFileType: 'Type de document invalide pour "{name}". Seulement les documents de type "{types}" sont autorisés.', + msgInvalidFileExtension: 'Extension invalide pour le fichier "{name}". Seules les extensions "{extensions}" sont autorisées.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Le transfert du fichier a été interrompu', + msgUploadThreshold: 'En cours...', + msgUploadBegin: 'Initialisation...', + msgUploadEnd: 'Terminé', + msgUploadEmpty: 'Aucune donnée valide disponible pour transmission.', + msgUploadError: 'Erreur', + msgValidationError: 'Erreur de validation', + msgLoading: 'Transmission du fichier {index} sur {files}…', + msgProgress: 'Transmission du fichier {index} sur {files} - {name} - {percent}%.', + msgSelected: '{n} {files} sélectionné(s)', + msgFoldersNotAllowed: 'Glissez et déposez uniquement des fichiers ! {n} répertoire(s) exclu(s).', + msgImageWidthSmall: 'La largeur de l\'image "{name}" doit être d\'au moins {size} px.', + msgImageHeightSmall: 'La hauteur de l\'image "{name}" doit être d\'au moins {size} px.', + msgImageWidthLarge: 'La largeur de l\'image "{name}" ne peut pas dépasser {size} px.', + msgImageHeightLarge: 'La hauteur de l\'image "{name}" ne peut pas dépasser {size} px.', + msgImageResizeError: "Impossible d'obtenir les dimensions de l'image à redimensionner.", + msgImageResizeException: "Erreur lors du redimensionnement de l'image.
{errors}
", + msgAjaxError: "Une erreur s'est produite pendant l'opération de {operation}. Veuillez réessayer plus tard.", + msgAjaxProgressError: 'L\'opération "{operation}" a échoué', + ajaxOperations: { + deleteThumb: 'suppression du fichier', + uploadThumb: 'transfert du fichier', + uploadBatch: 'transfert des fichiers', + uploadExtra: 'soumission des données de formulaire' + }, + dropZoneTitle: 'Glissez et déposez les fichiers ici…', + dropZoneClickTitle: '
(ou cliquez pour sélectionner manuellement)', + fileActionSettings: { + removeTitle: 'Supprimer le fichier', + uploadTitle: 'Transférer le fichier', + uploadRetryTitle: 'Relancer le transfert', + zoomTitle: 'Voir les détails', + dragTitle: 'Déplacer / Réarranger', + indicatorNewTitle: 'Pas encore transféré', + indicatorSuccessTitle: 'Posté', + indicatorErrorTitle: 'Ajouter erreur', + indicatorLoadingTitle: 'En cours...' + }, + previewZoomButtonTitles: { + prev: 'Voir le fichier précédent', + next: 'Voir le fichier suivant', + toggleheader: 'Masquer le titre', + fullscreen: 'Mode plein écran', + borderless: 'Mode cinéma', + close: "Fermer l'aperçu" + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..a2ba90be --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js @@ -0,0 +1,100 @@ +/*! + * FileInput Galician 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['gl'] = { + fileSingle: 'arquivo', + filePlural: 'arquivos', + browseLabel: 'Examinar …', + removeLabel: 'Quitar', + removeTitle: 'Quitar aquivos seleccionados', + cancelLabel: 'Cancelar', + cancelTitle: 'Abortar a subida en curso', + uploadLabel: 'Subir arquivo', + uploadTitle: 'Subir arquivos seleccionados', + msgNo: 'Non', + msgNoFilesSelected: 'Non hay arquivos seleccionados', + msgCancelled: 'Cancelado', + msgPlaceholder: 'Seleccinar {files}...', + msgZoomModalHeading: 'Vista previa detallada', + msgFileRequired: 'Debes seleccionar un arquivo para subir.', + msgSizeTooSmall: 'O arquivo "{name}" ({size} KB) é demasiado pequeno e debe ser maior de {minSize} KB.', + msgSizeTooLarge: 'O arquivo "{name}" ({size} KB) excede o tamaño máximo permitido de {maxSize} KB.', + msgFilesTooLess: 'Debe seleccionar ao menos {n} {files} a cargar.', + msgFilesTooMany: 'O número de arquivos seleccionados a cargar ({n}) excede do límite máximo permitido de {m}.', + msgFileNotFound: 'Arquivo "{name}" non encontrado.', + msgFileSecured: 'Non é posible acceder ao arquivo "{name}" porque estará sendo usado por outra aplicación ou non teñamos permisos de lectura.', + msgFileNotReadable: 'Non é posible acceder ao arquivo "{name}".', + msgFilePreviewAborted: 'Previsualización do arquivo "{name}" cancelada.', + msgFilePreviewError: 'Ocurriu un erro mentras se lía o arquivo "{name}".', + msgInvalidFileName: 'Caracteres non válidos ou non soportados no nome do arquivo "{name}".', + msgInvalidFileType: 'Tipo de arquivo non válido para "{name}". Só se permiten arquivos do tipo "{types}".', + msgInvalidFileExtension: 'Extensión de arquivo non válida para "{name}". Só se permiten arquivos "{extensions}".', + msgFileTypes: { + 'image': 'imaxe', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'A carga de arquivos cancelouse', + msgUploadThreshold: 'Procesando...', + msgUploadBegin: 'Inicializando...', + msgUploadEnd: 'Feito', + msgUploadEmpty: 'Non existen datos válidos para o envío.', + msgUploadError: 'Erro', + msgValidationError: 'Erro de validación', + msgLoading: 'Subindo arquivo {index} de {files} …', + msgProgress: 'Subindo arquivo {index} de {files} - {name} - {percent}% completado.', + msgSelected: '{n} {files} seleccionado(s)', + msgFoldersNotAllowed: 'Arrastra e solta unicamente arquivos. Omitida(s) {n} carpeta(s).', + msgImageWidthSmall: 'O ancho da imaxe "{name}" debe ser de ao menos {size} px.', + msgImageHeightSmall: 'A altura da imaxe "{name}" debe ser de ao menos {size} px.', + msgImageWidthLarge: 'O ancho da imaxe "{name}" non pode exceder de {size} px.', + msgImageHeightLarge: 'A altura da imaxe "{name}" non pode exceder de {size} px.', + msgImageResizeError: 'Non se puideron obter as dimensións da imaxe para cambiar o tamaño.', + msgImageResizeException: 'Erro ao cambiar o tamaño da imaxe.
{errors}
', + msgAjaxError: 'Algo foi mal ca operación {operation}. Por favor, inténtao de novo máis tarde.', + msgAjaxProgressError: 'A operación {operation} fallou', + ajaxOperations: { + deleteThumb: 'Arquivo borrado', + uploadThumb: 'Arquivo subido', + uploadBatch: 'Datos subidos en lote', + uploadExtra: 'Datos do formulario subidos' + }, + dropZoneTitle: 'Arrasta e solta aquí os arquivos …', + dropZoneClickTitle: '
(ou fai clic para seleccionar {files})', + fileActionSettings: { + removeTitle: 'Eliminar arquivo', + uploadTitle: 'Subir arquivo', + uploadRetryTitle: 'Reintentar a subida', + downloadTitle: 'Descargar arquivo', + zoomTitle: 'Ver detalles', + dragTitle: 'Mover / Reordenar', + indicatorNewTitle: 'Non subido aínda', + indicatorSuccessTitle: 'Subido', + indicatorErrorTitle: 'Erro ao subir', + indicatorLoadingTitle: 'Subindo...' + }, + previewZoomButtonTitles: { + prev: 'Ver arquivo anterior', + next: 'Ver arquivo seguinte', + toggleheader: 'Mostrar encabezado', + fullscreen: 'Mostrar a pantalla completa', + borderless: 'Activar o modo sen bordes', + close: 'Cerrar vista detallada' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..cea7de35 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js @@ -0,0 +1,97 @@ +/*! + * FileInput Hebrew 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 Daniel Coryat + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['he'] = { + fileSingle: 'קובץ', + filePlural: 'קבצים', + browseLabel: 'העלאה …', + removeLabel: 'הסרה', + removeTitle: 'נקה קבצים נבחרים', + cancelLabel: 'ביטול', + cancelTitle: 'ביטול העלאה מתמשכת', + uploadLabel: 'טעינה', + uploadTitle: 'טעינת קבצים נבחרים', + msgNo: 'לא', + msgNoFilesSelected: 'לא נבחרו קבצים', + msgCancelled: 'מבוטל', + msgPlaceholder: 'בחר {files}...', + msgZoomModalHeading: 'תצוגה מקדימה מפורטת', + msgSizeTooSmall: 'קובץ "{name}" ({size} KB) קטן מדי וחייב להיות גדול מ {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: 'תווים לא חוקיים או לא נתמכים בשם הקובץ "{name}".', + msgInvalidFileType: 'סוג קובץ לא חוקי "{name}". רק "{types}" קבצים נתמכים.', + msgInvalidFileExtension: 'תוסף לא חוקי עבור הקובץ "{name}". רק "{extensions}" קבצים נתמכים.', + msgFileTypes: { + 'image': 'תמונה', + 'html': 'HTML', + 'text': 'טקסט', + 'video': 'וידאו', + 'audio': 'שמע', + 'flash': 'פלאש', + 'pdf': 'PDF', + 'object': 'אובייקט' + }, + msgUploadAborted: 'העלאת הקובץ בוטלה', + msgUploadThreshold: 'מעבד...', + msgUploadBegin: 'מאתחל ...', + msgUploadEnd: 'בוצע', + msgUploadEmpty: 'אין נתונים זמינים להעלאה.', + msgValidationError: 'שגיאת אימות', + msgLoading: 'טוען קובץ {index} של {files} …', + msgProgress: 'טוען קובץ {index} של {files} - {name} - {percent}% הושלמה.', + msgSelected: '{n} {files} נבחרו', + msgFoldersNotAllowed: 'גרירת קבצים ושחרורם בלבד! דילוג {n} גרירת תיקיה(s).', + msgImageWidthSmall: 'רוחב קובץ התמונה "{name}" חייב להיות לפחות {size} px.', + msgImageHeightSmall: 'גובה קובץ התמונה "{name}" חייב להיות לפחות {size} px.', + msgImageWidthLarge: 'רוחב קובץ התמונה "{name}" לא יעלה על {size} px.', + msgImageHeightLarge: 'גובה קובץ התמונה "{name}" לא יעלה על {size} px.', + msgImageResizeError: 'לא ניתן לשנות את גודל מידות התמונה.', + msgImageResizeException: 'שגיאה בעת שינוי גודל התמונה.
{errors}
', + msgAjaxError: 'משהו השתבש עם {operation} המערכת. יש לנסות מאוחר יותר!', + msgAjaxProgressError: '{operation} נכשל', + ajaxOperations: { + deleteThumb: 'קובץ נמחק', + uploadThumb: 'קובץ הועלה', + uploadBatch: 'קובץ אצווה הועלה', + uploadExtra: 'העלאת נתונים בטופס' + }, + dropZoneTitle: 'גרירת קבצים ושחרורם כאן …', + dropZoneClickTitle: '
(או לחץ /י כדי לבחור {files})', + fileActionSettings: { + removeTitle: 'הסרת קובץ', + uploadTitle: 'טעינת קובץ', + zoomTitle: 'הצגת פרטים', + dragTitle: 'העברה / סידור מחדש', + indicatorNewTitle: 'עדיין לא הועלה', + indicatorSuccessTitle: 'הועלה', + indicatorErrorTitle: 'שגיאת העלאה', + indicatorLoadingTitle: 'מעלה...' + }, + previewZoomButtonTitles: { + prev: 'הצגת את הקובץ הקודם', + next: 'הצגת את הקובץ הבא', + toggleheader: 'שינוי כותרת', + fullscreen: 'מעבר למסך מלא', + borderless: 'שינוי המודל ללא שוליים', + close: 'סגירת תצוגה מקדימה מפורטת' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..534815fb --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js @@ -0,0 +1,100 @@ +/*! + * FileInput Hungarian 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['hu'] = { + fileSingle: 'fájl', + filePlural: 'fájlok', + browseLabel: 'Tallóz …', + removeLabel: 'Eltávolít', + removeTitle: 'Kijelölt fájlok törlése', + cancelLabel: 'Mégse', + cancelTitle: 'Feltöltés megszakítása', + uploadLabel: 'Feltöltés', + uploadTitle: 'Kijelölt fájlok feltöltése', + msgNo: 'Nem', + msgNoFilesSelected: 'Nincs fájl kiválasztva', + msgCancelled: 'Megszakítva', + msgPlaceholder: 'Válasz {files}...', + msgZoomModalHeading: 'Részletes Előnézet', + msgFileRequired: 'Kötelező fájlt kiválasztani a feltöltéshez.', + msgSizeTooSmall: 'A fájl: "{name}" ({size} KB) mérete túl kicsi, nagyobbnak kell lennie, mint {minSize} KB.', + msgSizeTooLarge: '"{name}" fájl ({size} KB) mérete nagyobb a megengedettnél {maxSize} KB.', + msgFilesTooLess: 'Legalább {n} {files} ki kell választania a feltöltéshez.', + msgFilesTooMany: 'A feltölteni kívánt fájlok száma ({n}) elérte a megengedett maximumot {m}.', + msgFileNotFound: '"{name}" fájl nem található!', + msgFileSecured: 'Biztonsági beállítások nem engedik olvasni a fájlt "{name}".', + msgFileNotReadable: '"{name}" fájl nem olvasható.', + msgFilePreviewAborted: '"{name}" fájl feltöltése megszakítva.', + msgFilePreviewError: 'Hiba lépett fel a "{name}" fájl olvasása közben.', + msgInvalidFileName: 'Hibás vagy nem támogatott karakterek a fájl nevében "{name}".', + msgInvalidFileType: 'Nem megengedett fájl "{name}". Csak a "{types}" fájl típusok támogatottak.', + msgInvalidFileExtension: 'Nem megengedett kiterjesztés / fájltípus "{name}". Csak a "{extensions}" kiterjesztés(ek) / fájltípus(ok) támogatottak.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'A fájl feltöltés megszakítva', + msgUploadThreshold: 'Folyamatban...', + msgUploadBegin: 'Inicializálás...', + msgUploadEnd: 'Kész', + msgUploadEmpty: 'Nincs érvényes adat a feltöltéshez.', + msgUploadError: 'Error', + msgValidationError: 'Érvényesítés hiba', + msgLoading: '{index} / {files} töltése …', + msgProgress: 'Feltöltés: {index} / {files} - {name} - {percent}% kész.', + msgSelected: '{n} {files} kiválasztva.', + msgFoldersNotAllowed: 'Csak fájlokat húzzon ide! Kihagyva {n} könyvtár.', + msgImageWidthSmall: 'A kép szélességének "{name}" legalább {size} pixelnek kell lennie.', + msgImageHeightSmall: 'A kép magasságának "{name}" legalább {size} pixelnek kell lennie.', + msgImageWidthLarge: 'A kép szélessége "{name}" nem haladhatja meg a {size} pixelt.', + msgImageHeightLarge: 'A kép magassága "{name}" nem haladhatja meg a {size} pixelt.', + msgImageResizeError: 'Nem lehet megállapítani a kép méreteit az átméretezéshez.', + msgImageResizeException: 'Hiba történt a méretezés közben.
{errors}
', + msgAjaxError: 'Hiba történt a művelet közben ({operation}). Kérjük, próbálja később!', + msgAjaxProgressError: 'Hiba! ({operation})', + ajaxOperations: { + deleteThumb: 'fájl törlés', + uploadThumb: 'fájl feltöltés', + uploadBatch: 'csoportos fájl feltöltés', + uploadExtra: 'űrlap adat feltöltés' + }, + dropZoneTitle: 'Húzzon ide fájlokat …', + dropZoneClickTitle: '
(vagy kattintson ide a {files} tallózásához...)', + fileActionSettings: { + removeTitle: 'A fájl eltávolítása', + uploadTitle: 'fájl feltöltése', + uploadRetryTitle: 'Feltöltés újból', + downloadTitle: 'Fájl letöltése', + zoomTitle: 'Részletek megtekintése', + dragTitle: 'Mozgatás / Átrendezés', + indicatorNewTitle: 'Nem feltöltött', + indicatorSuccessTitle: 'Feltöltött', + indicatorErrorTitle: 'Feltöltés hiba', + indicatorLoadingTitle: 'Feltöltés ...' + }, + previewZoomButtonTitles: { + prev: 'Elöző fájl megnézése', + next: 'Következő fájl megnézése', + toggleheader: 'Fejléc mutatása', + fullscreen: 'Teljes képernyős mód bekapcsolása', + borderless: 'Keret nélküli ablak mód bekapcsolása', + close: 'Részletes előnézet bezárása' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..cc2bab23 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js @@ -0,0 +1,101 @@ +/*! + * FileInput Indonesian 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 Bambang Riswanto + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['id'] = { + fileSingle: 'berkas', + filePlural: 'berkas', + browseLabel: 'Pilih berkas …', + removeLabel: 'Hapus', + removeTitle: 'Hapus berkas terpilih', + cancelLabel: 'Batal', + cancelTitle: 'Batalkan proses pengunggahan', + uploadLabel: 'Unggah', + uploadTitle: 'Unggah berkas terpilih', + msgNo: 'Tidak', + msgNoFilesSelected: '', + msgCancelled: 'Dibatalkan', + msgPlaceholder: 'Pilih {files}...', + msgZoomModalHeading: 'Pratinjau terperinci', + msgFileRequired: 'Anda harus memilih berkas untuk diunggah.', + msgSizeTooSmall: 'Berkas "{name}" ({size} KB) terlalu kecil dan harus lebih besar dari {minSize} KB.', + msgSizeTooLarge: 'Berkas "{name}" ({size} KB) melebihi ukuran unggah maksimal yaitu {maxSize} KB.', + msgFilesTooLess: 'Anda harus memilih setidaknya {n} {files} untuk diunggah.', + msgFilesTooMany: '({n}) berkas yang dipilih untuk diunggah melebihi ukuran unggah maksimal yaitu {m}.', + msgFileNotFound: 'Berkas "{name}" tak ditemukan!', + msgFileSecured: 'Sistem keamanan mencegah untuk membaca berkas "{name}".', + msgFileNotReadable: 'Berkas "{name}" tak dapat dibaca.', + msgFilePreviewAborted: 'Pratinjau untuk berkas "{name}" dibatalkan.', + msgFilePreviewError: 'Kesalahan saat membaca berkas "{name}".', + msgInvalidFileName: 'Karakter tidak dikenali atau tidak didukung untuk nama berkas "{name}".', + msgInvalidFileType: 'Jenis berkas "{name}" tidak sah. Hanya berkas "{types}" yang didukung.', + msgInvalidFileExtension: 'Ekstensi berkas "{name}" tidak sah. Hanya ekstensi "{extensions}" yang didukung.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Proses Unggah berkas dibatalkan', + msgUploadThreshold: 'Memproses...', + msgUploadBegin: 'Menyiapkan...', + msgUploadEnd: 'Selesai', + msgUploadEmpty: 'Tidak ada data valid yang tersedia untuk diunggah.', + msgUploadError: 'Kesalahan', + msgValidationError: 'Kesalahan saat memvalidasi', + msgLoading: 'Memuat {index} dari {files} berkas …', + msgProgress: 'Memuat {index} dari {files} berkas - {name} - {percent}% selesai.', + msgSelected: '{n} {files} dipilih', + msgFoldersNotAllowed: 'Hanya tahan dan lepas file saja! {n} folder diabaikan.', + msgImageWidthSmall: 'Lebar dari gambar "{name}" harus sekurangnya {size} px.', + msgImageHeightSmall: 'Tinggi dari gambar "{name}" harus sekurangnya {size} px.', + msgImageWidthLarge: 'Lebar dari gambar "{name}" tak boleh melebihi {size} px.', + msgImageHeightLarge: 'Tinggi dari gambar "{name}" tak boleh melebihi {size} px.', + msgImageResizeError: 'Tidak dapat menentukan dimensi gambar untuk mengubah ukuran.', + msgImageResizeException: 'Kesalahan saat mengubah ukuran gambar.
{errors}
', + msgAjaxError: 'Terjadi kesalahan ketika melakukan operasi {operation}. Silahkan coba lagi nanti!', + msgAjaxProgressError: '{operation} gagal', + ajaxOperations: { + deleteThumb: 'Hapus berkas', + uploadThumb: 'Unggah berkas', + uploadBatch: 'Unggah banyak berkas', + uploadExtra: 'Unggah form ekstra' + }, + dropZoneTitle: 'Tarik dan lepaskan berkas disini …', + dropZoneClickTitle: '
(atau klik untuk memilih {files})', + fileActionSettings: { + removeTitle: 'Hapus Berkas', + uploadTitle: 'Unggah Berkas', + uploadRetryTitle: 'Unggah Ulang', + downloadTitle: 'Unduh Berkas', + zoomTitle: 'Tampilkan Rincian', + dragTitle: 'Pindah atau Atur Ulang', + indicatorNewTitle: 'Belum diunggah', + indicatorSuccessTitle: 'Sudah diunggah', + indicatorErrorTitle: 'Kesalahan dalam mengungah', + indicatorLoadingTitle: 'Mengunggah ...' + }, + previewZoomButtonTitles: { + prev: 'Lihat berkas sebelumnya', + next: 'Lihat berkas selanjutnya', + toggleheader: 'Beralih ke tajuk', + fullscreen: 'Beralih ke mode penuh', + borderless: 'Beralih ke mode tanpa tepi', + close: 'Tutup pratinjau terperinci' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..73ee7663 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js @@ -0,0 +1,102 @@ +/*! + * FileInput Italian Translation + * + * Author: Lorenzo Milesi + * + * 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['it'] = { + fileSingle: 'file', + filePlural: 'file', + browseLabel: 'Sfoglia…', + removeLabel: 'Rimuovi', + removeTitle: 'Rimuovi i file selezionati', + cancelLabel: 'Annulla', + cancelTitle: 'Annulla i caricamenti in corso', + uploadLabel: 'Carica', + uploadTitle: 'Carica i file selezionati', + msgNo: 'No', + msgNoFilesSelected: 'Nessun file selezionato', + msgCancelled: 'Annullato', + msgPlaceholder: 'Seleziona {files}...', + msgZoomModalHeading: 'Anteprima dettagliata', + msgFileRequired: 'Devi selezionare un file da caricare.', + msgSizeTooSmall: 'Il file "{name}" ({size} KB) è troppo piccolo, deve essere almeno di {minSize} KB.', + msgSizeTooLarge: 'Il file "{name}" ({size} KB) eccede la dimensione massima di caricamento di {maxSize} KB.', + msgFilesTooLess: 'Devi selezionare almeno {n} {files} da caricare.', + msgFilesTooMany: 'Il numero di file selezionati per il caricamento ({n}) eccede il numero massimo di file accettati {m}.', + msgFileNotFound: 'File "{name}" non trovato!', + msgFileSecured: 'Restrizioni di sicurezza impediscono la lettura del file "{name}".', + msgFileNotReadable: 'Il file "{name}" non è leggibile.', + msgFilePreviewAborted: 'Generazione anteprima per "{name}" annullata.', + msgFilePreviewError: 'Errore durante la lettura del file "{name}".', + msgInvalidFileName: 'Carattere non valido o non supportato nel file "{name}".', + msgInvalidFileType: 'Tipo non valido per il file "{name}". Sono ammessi solo file di tipo "{types}".', + msgInvalidFileExtension: 'Estensione non valida per il file "{name}". Sono ammessi solo file con estensione "{extensions}".', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Il caricamento del file è stato interrotto', + msgUploadThreshold: 'In lavorazione...', + msgUploadBegin: 'Inizializzazione...', + msgUploadEnd: 'Fatto', + msgUploadEmpty: 'Dati non disponibili', + msgUploadError: 'Errore', + msgValidationError: 'Errore di convalida', + msgLoading: 'Caricamento file {index} di {files}…', + msgProgress: 'Caricamento file {index} di {files} - {name} - {percent}% completato.', + msgSelected: '{n} {files} selezionati', + msgFoldersNotAllowed: 'Trascina solo file! Ignorata/e {n} cartella/e.', + msgImageWidthSmall: 'La larghezza dell\'immagine "{name}" deve essere di almeno {size} px.', + msgImageHeightSmall: 'L\'altezza dell\'immagine "{name}" deve essere di almeno {size} px.', + msgImageWidthLarge: 'La larghezza dell\'immagine "{name}" non può superare {size} px.', + msgImageHeightLarge: 'L\'altezza dell\'immagine "{name}" non può superare {size} px.', + msgImageResizeError: 'Impossibile ottenere le dimensioni dell\'immagine per ridimensionare.', + msgImageResizeException: 'Errore durante il ridimensionamento dell\'immagine.
{errors}
', + msgAjaxError: 'Qualcosa non ha funzionato con l\'operazione {operation}. Per favore riprova più tardi!', + msgAjaxProgressError: '{operation} failed', + ajaxOperations: { + deleteThumb: 'eliminazione file', + uploadThumb: 'caricamento file', + uploadBatch: 'caricamento file in batch', + uploadExtra: 'upload dati del form' + }, + dropZoneTitle: 'Trascina i file qui…', + dropZoneClickTitle: '
(o clicca per selezionare {files})', + fileActionSettings: { + removeTitle: 'Rimuovere il file', + uploadTitle: 'Caricare un file', + uploadRetryTitle: 'Riprova il caricamento', + downloadTitle: 'Scarica file', + zoomTitle: 'Guarda i dettagli', + dragTitle: 'Muovi / Riordina', + indicatorNewTitle: 'Non ancora caricato', + indicatorSuccessTitle: 'Caricati', + indicatorErrorTitle: 'Carica Errore', + indicatorLoadingTitle: 'Caricamento ...' + }, + previewZoomButtonTitles: { + prev: 'Vedi il file precedente', + next: 'Vedi il file seguente', + toggleheader: 'Attiva header', + fullscreen: 'Attiva full screen', + borderless: 'Abilita modalità senza bordi', + close: 'Chiudi' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..3decd7fa --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js @@ -0,0 +1,109 @@ +/*! + * FileInput Japanese 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 Yuta Hoshina + * + * NOTE: this file must be saved in UTF-8 encoding. + * slugCallback + * \u4e00-\u9fa5 : Kanji (Chinese characters) + * \u3040-\u309f : Hiragana (Japanese syllabary) + * \u30a0-\u30ff\u31f0-\u31ff : Katakana (including phonetic extension) + * \u3200-\u32ff : Enclosed CJK Letters and Months + * \uff00-\uffef : Halfwidth and Fullwidth Forms + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['ja'] = { + fileSingle: 'ファイル', + filePlural: 'ファイル', + browseLabel: 'ファイルを選択…', + removeLabel: '削除', + removeTitle: '選択したファイルを削除', + cancelLabel: 'キャンセル', + cancelTitle: 'アップロードをキャンセル', + uploadLabel: 'アップロード', + uploadTitle: '選択したファイルをアップロード', + msgNo: 'いいえ', + msgNoFilesSelected: 'ファイルが選択されていません', + msgCancelled: 'キャンセル', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'プレビュー', + msgFileRequired: 'ファイルを選択してください', + msgSizeTooSmall: 'ファイル"{name}" ({size} KB)はアップロード可能な下限容量{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: 'ファイル名に無効な文字が含まれています "{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: '処理中...', + msgUploadBegin: '初期化中...', + msgUploadEnd: '完了', + msgUploadEmpty: 'アップロードに有効なデータがありません', + msgUploadError: 'エラー', + msgValidationError: '検証エラー', + msgLoading: '{files}個中{index}個目のファイルを読み込み中…', + msgProgress: '{files}個中{index}個のファイルを読み込み中 - {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: '{operation}実行中にエラーが発生しました。時間をおいてもう一度お試しください。', + msgAjaxProgressError: '{operation} failed', + ajaxOperations: { + deleteThumb: 'ファイル削除', + uploadThumb: 'ファイルアップロード', + uploadBatch: '一括ファイルアップロード', + uploadExtra: 'フォームデータアップロード' + }, + dropZoneTitle: 'ファイルをドラッグ&ドロップ…', + dropZoneClickTitle: '
(または クリックして{files}を選択 )', + slugCallback: function(text) { + return text ? text.split(/(\\|\/)/g).pop().replace(/[^\w\u4e00-\u9fa5\u3040-\u309f\u30a0-\u30ff\u31f0-\u31ff\u3200-\u32ff\uff00-\uffef\-.\\\/ ]+/g, '') : ''; + }, + fileActionSettings: { + removeTitle: 'ファイルを削除', + uploadTitle: 'ファイルをアップロード', + uploadRetryTitle: '再アップロード', + zoomTitle: 'プレビュー', + dragTitle: '移動 / 再配置', + indicatorNewTitle: 'まだアップロードされていません', + indicatorSuccessTitle: 'アップロード済み', + indicatorErrorTitle: 'アップロード失敗', + indicatorLoadingTitle: 'アップロード中...' + }, + previewZoomButtonTitles: { + prev: '前のファイルを表示', + next: '次のファイルを表示', + toggleheader: 'ファイル情報の表示/非表示', + fullscreen: 'フルスクリーン表示の開始/終了', + borderless: 'フルウィンドウ表示の開始/終了', + close: 'プレビューを閉じる' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..c6c0a230 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js @@ -0,0 +1,101 @@ +/*! + * FileInput Georgian 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 Avtandil Kikabidze aka LONGMAN + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['ka'] = { + fileSingle: 'ფაილი', + filePlural: 'ფაილები', + browseLabel: 'არჩევა …', + removeLabel: 'წაშლა', + removeTitle: 'არჩეული ფაილების წაშლა', + cancelLabel: 'გაუქმება', + cancelTitle: 'მიმდინარე ატვირთვის გაუქმება', + uploadLabel: 'ატვირთვა', + uploadTitle: 'არჩეული ფაილების ატვირთვა', + msgNo: 'არა', + msgNoFilesSelected: 'ფაილები არ არის არჩეული', + msgCancelled: 'გაუქმებულია', + msgPlaceholder: 'აირჩიეთ {files}...', + msgZoomModalHeading: 'დეტალურად ნახვა', + msgFileRequired: 'ატვირთვისთვის აუცილებელია ფაილის არჩევა.', + msgSizeTooSmall: 'ფაილი "{name}" ({size} KB) არის ძალიან პატარა. მისი ზომა უნდა იყოს არანაკლებ {minSize} KB.', + msgSizeTooLarge: 'ფაილი "{name}" ({size} KB) აჭარბებს მაქსიმალურ დასაშვებ ზომას {maxSize} KB.', + msgFilesTooLess: 'უნდა აირჩიოთ მინიმუმ {n} {file} ატვირთვისთვის.', + msgFilesTooMany: 'არჩეული ფაილების რაოდენობა ({n}) აჭარბებს დასაშვებ ლიმიტს {m}.', + msgFileNotFound: 'ფაილი "{name}" არ მოიძებნა!', + msgFileSecured: 'უსაფრთხოებით გამოწვეული შეზღუდვები კრძალავს ფაილის "{name}" წაკითხვას.', + msgFileNotReadable: 'ფაილის "{name}" წაკითხვა შეუძლებელია.', + msgFilePreviewAborted: 'პრევიუ გაუქმებულია ფაილისათვის "{name}".', + msgFilePreviewError: 'დაფიქსირდა შეცდომა ფაილის "{name}" კითხვისას.', + msgInvalidFileName: 'ნაპოვნია დაუშვებელი სიმბოლოები ფაილის "{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: 'მუშავდება...', + msgUploadBegin: 'ინიციალიზაცია...', + msgUploadEnd: 'დასრულებულია', + msgUploadEmpty: 'ატვირთვისთვის დაუშვებელი მონაცემები.', + msgUploadError: 'ატვირთვის შეცდომა', + msgValidationError: 'ვალიდაციის შეცდომა', + msgLoading: 'ატვირთვა {index} / {files} …', + msgProgress: 'ფაილის ატვირთვა დასრულებულია {index} / {files} - {name} - {percent}%.', + msgSelected: 'არჩეულია {n} {file}', + msgFoldersNotAllowed: 'დაშვებულია მხოლოდ ფაილების გადმოთრევა! გამოტოვებულია {n} გადმოთრეული ფოლდერი.', + msgImageWidthSmall: 'სურათის "{name}" სიგანე უნდა იყოს არანაკლებ {size} px.', + msgImageHeightSmall: 'სურათის "{name}" სიმაღლე უნდა იყოს არანაკლებ {size} px.', + msgImageWidthLarge: 'სურათის "{name}" სიგანე არ უნდა აღემატებოდეს {size} px-ს.', + msgImageHeightLarge: 'სურათის "{name}" სიმაღლე არ უნდა აღემატებოდეს {size} px-ს.', + msgImageResizeError: 'ვერ მოხერხდა სურათის ზომის შეცვლისთვის საჭირო მონაცემების გარკვევა.', + msgImageResizeException: 'შეცდომა სურათის ზომის შეცვლისას.
{errors}
', + msgAjaxError: 'დაფიქსირდა შეცდომა ოპერაციის {operation} შესრულებისას. ცადეთ მოგვიანებით!', + msgAjaxProgressError: 'ვერ მოხერხდა ოპერაციის {operation} შესრულება', + ajaxOperations: { + deleteThumb: 'ფაილის წაშლა', + uploadThumb: 'ფაილის ატვირთვა', + uploadBatch: 'ფაილების ატვირთვა', + uploadExtra: 'მონაცემების გაგზავნა ფორმიდან' + }, + dropZoneTitle: 'გადმოათრიეთ ფაილები აქ …', + dropZoneClickTitle: '
(ან დააჭირეთ რათა აირჩიოთ {files})', + fileActionSettings: { + removeTitle: 'ფაილის წაშლა', + uploadTitle: 'ფაილის ატვირთვა', + uploadRetryTitle: 'ატვირთვის გამეორება', + downloadTitle: 'ფაილის ჩამოტვირთვა', + zoomTitle: 'დეტალურად ნახვა', + dragTitle: 'გადაადგილება / მიმდევრობის შეცვლა', + indicatorNewTitle: 'ჯერ არ ატვირთულა', + indicatorSuccessTitle: 'ატვირთულია', + indicatorErrorTitle: 'ატვირთვის შეცდომა', + indicatorLoadingTitle: 'ატვირთვა ...' + }, + previewZoomButtonTitles: { + prev: 'წინა ფაილის ნახვა', + next: 'შემდეგი ფაილის ნახვა', + toggleheader: 'სათაურის დამალვა', + fullscreen: 'მთელ ეკრანზე გაშლა', + borderless: 'მთელ გვერდზე გაშლა', + close: 'დახურვა' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js new file mode 100644 index 00000000..0190dd73 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js @@ -0,0 +1,100 @@ +/*! + * FileInput Korean 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['kr'] = { + fileSingle: '파일', + filePlural: '파일들', + browseLabel: '찾아보기 …', + removeLabel: '지우기', + removeTitle: '선택한 파일들 지우기', + cancelLabel: '취소', + cancelTitle: '진행중인 업로드 중단', + uploadLabel: '업로드', + uploadTitle: '선택한 파일 업로드', + msgNo: '아니요', + msgNoFilesSelected: '선택한 파일이 없습니다', + msgCancelled: '취소되었습니다', + msgPlaceholder: '{files} 선택...', + msgZoomModalHeading: '세부 정보', + msgFileRequired: '업로드를 위해 반드시 파일을 선택해야 합니다.', + msgSizeTooSmall: '파일 "{name}" ({size} KB)이 너무 작습니다. {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: '파일 이름 "{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: '처리하는 중...', + msgUploadBegin: '초기화 중...', + msgUploadEnd: '완료', + msgUploadEmpty: '업로드 가능한 데이터가 존재하지 않습니다.', + msgUploadError: '오류', + msgValidationError: '유효성 오류', + msgLoading: '{index}/{files}번째 파일을 불러오는 중입니다. …', + msgProgress: '{index}/{files} - {name} - {percent}% 불러오기 완료.', + msgSelected: '{n} {files}이 선택 되었습니다.', + msgFoldersNotAllowed: '파일만 마우스로 끌어올 수 있습니다! 끌어온 폴더는 건너뜁니다.', + msgImageWidthSmall: '"{name}"의 가로는 {size} px 보다 넓어야 합니다.', + msgImageHeightSmall: '"{name}"의 세로는 {size} px 보다 높아야 합니다.', + msgImageWidthLarge: '"{name}"의 가로는 {size} px를 넘을 수 없습니다.', + msgImageHeightLarge: '"{name}"의 세로는 {size} px를 넘을 수 없습니다.', + msgImageResizeError: '이미지의 치수를 가져올 수 없습니다', + msgImageResizeException: '이미지 사이즈 재조정이 다음 이유로 실패했습니다.
{errors}
', + msgAjaxError: '{operation} 실행 도중 실패했습니다. 잠시 후 다시 시도해 주세요!', + msgAjaxProgressError: '{operation} failed', + ajaxOperations: { + deleteThumb: 'file delete', + uploadThumb: 'file upload', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: '마우스로 파일을 끌어오세요 …', + dropZoneClickTitle: '
(또는 {files} 선택을 위해 클릭하십시요)', + fileActionSettings: { + removeTitle: '파일 지우기', + uploadTitle: '파일 업로드', + uploadRetryTitle: '업로드 재시도', + downloadTitle: '파일 다운로드', + zoomTitle: '세부 정보 보기', + dragTitle: '옮기기 / 재배열하기', + indicatorNewTitle: '아직 업로드 되지 않았습니다', + indicatorSuccessTitle: '업로드 성공', + indicatorErrorTitle: '업로드 중 에러 발생', + indicatorLoadingTitle: '업로드 중 ...' + }, + previewZoomButtonTitles: { + prev: '이전 파일', + next: '다음 파일', + toggleheader: '머릿글 토글', + fullscreen: '전체화면 토글', + borderless: '창 테두리 토글', + close: '세부 정보 닫기' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..82c34cc4 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js @@ -0,0 +1,88 @@ +/*! + * FileInput Kazakh 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 Kali Toleugazy + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['kz'] = { + fileSingle: 'файл', + filePlural: 'файлдар', + browseLabel: 'Таңдау …', + removeLabel: 'Жою', + removeTitle: 'Таңдалған файлдарды жою', + cancelLabel: 'Күшін жою', + cancelTitle: 'Ағымдағы жүктеуді болдырмау', + uploadLabel: 'Жүктеу', + uploadTitle: 'Таңдалған файлдарды жүктеу', + msgNo: 'жоқ', + msgNoFilesSelected: 'Файл таңдалмады', + msgCancelled: 'Күші жойылған', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Алдын ала толық көру', + msgSizeTooLarge: 'Файл "{name}" ({size} KB) ең үлкен {maxSize} KB өлшемінен асады.', + msgFilesTooLess: 'Жүктеу үшіy кемінде {n} {files} таңдау керек.', + msgFilesTooMany: 'Таңдалған ({n}) файлдардың саны берілген {m} саннан асып кетті.', + msgFileNotFound: 'Файл "{name}" табылмады!', + msgFileSecured: 'Шектеу қауіпсіздігі "{name}" файлын оқуға тыйым салады.', + msgFileNotReadable: '"{name}" файлды оқу мүмкін емес.', + msgFilePreviewAborted: '"{name}" файл үшін алдын ала қарап көру тыйым салынған.', + msgFilePreviewError: '"{name}" файлды оқығанда қате пайда болды.', + msgInvalidFileType: '"{name}" тыйым салынған файл түрі. Тек мынаналарға рұқсат етілген: "{types}"', + msgInvalidFileExtension: '"{name}" тыйым салынған файл кеңейтімі. Тек "{extensions}" рұқсат.', + msgUploadAborted: 'Файлды жүктеу доғарылды', + msgUploadThreshold: 'Өңдеу...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'Тексеру қатесі', + msgLoading: '{index} файлды {files} … жүктеу', + msgProgress: '{index} файлды {files} - {name} - {percent}% жүктеу аяқталды.', + msgSelected: 'Таңдалған файлдар саны: {n}', + 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: 'Орнын ауыстыру', + indicatorNewTitle: 'Жүктелген жоқ', + indicatorSuccessTitle: 'Жүктелген', + indicatorErrorTitle: 'Жүктелу қатесі ', + indicatorLoadingTitle: 'Жүктелу ...' + }, + previewZoomButtonTitles: { + prev: 'Алдыңғы файлды қарау', + next: 'Келесі файлды қарау', + toggleheader: 'Тақырыпты ауыстыру', + fullscreen: 'Толық экран режимін қосу', + borderless: 'Жиексіз режиміне ауысу', + close: 'Толық көрінісін жабу' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..91f36c94 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js @@ -0,0 +1,100 @@ +/*! + * FileInput <_LANG_> 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 Mindaugas Varkalys + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['lt'] = { + fileSingle: 'failas', + filePlural: 'failai', + browseLabel: 'Naršyti …', + removeLabel: 'Šalinti', + removeTitle: 'Pašalinti pasirinktus failus', + cancelLabel: 'Atšaukti', + cancelTitle: 'Atšaukti vykstantį įkėlimą', + uploadLabel: 'Įkelti', + uploadTitle: 'Įkelti pasirinktus failus', + msgNo: 'Ne', + msgNoFilesSelected: 'Nepasirinkta jokių failų', + msgCancelled: 'Atšaukta', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Detali Peržiūra', + msgFileRequired: 'Pasirinkite failą įkėlimui.', + msgSizeTooSmall: 'Failas "{name}" ({size} KB) yra per mažas ir turi būti didesnis nei {minSize} KB.', + msgSizeTooLarge: 'Failas "{name}" ({size} KB) viršija maksimalų leidžiamą įkeliamo failo dydį {maxSize} KB.', + msgFilesTooLess: 'Turite pasirinkti bent {n} failus įkėlimui.', + msgFilesTooMany: 'Įkėlimui pasirinktų failų skaičius ({n}) viršija maksimalų leidžiamą limitą {m}.', + msgFileNotFound: 'Failas "{name}" nerastas!', + msgFileSecured: 'Saugumo apribojimai neleidžia perskaityti failo "{name}".', + msgFileNotReadable: 'Failas "{name}" neperskaitomas.', + msgFilePreviewAborted: 'Failo peržiūra nutraukta "{name}".', + msgFilePreviewError: 'Įvyko klaida skaitant failą "{name}".', + msgInvalidFileName: 'Klaidingi arba nepalaikomi simboliai failo pavadinime "{name}".', + msgInvalidFileType: 'Klaidingas failo "{name}" tipas. Tik "{types}" tipai yra palaikomi.', + msgInvalidFileExtension: 'Klaidingas failo "{name}" plėtinys. Tik "{extensions}" plėtiniai yra palaikomi.', + msgFileTypes: { + 'image': 'paveikslėlis', + 'html': 'HTML', + 'text': 'tekstas', + 'video': 'vaizdo įrašas', + 'audio': 'garso įrašas', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'objektas' + }, + msgUploadAborted: 'Failo įkėlimas buvo nutrauktas', + msgUploadThreshold: 'Vykdoma...', + msgUploadBegin: 'Inicijuojama...', + msgUploadEnd: 'Baigta', + msgUploadEmpty: 'Nėra teisingų duomenų įkėlimui.', + msgUploadError: 'Klaida', + msgValidationError: 'Validacijos Klaida', + msgLoading: 'Keliamas failas {index} iš {files} …', + msgProgress: 'Keliamas failas {index} iš {files} - {name} - {percent}% baigta.', + msgSelected: 'Pasirinkti {n} {files}', + msgFoldersNotAllowed: 'Tempkite tik failus! Praleisti {n} nutempti aplankalas(-i).', + msgImageWidthSmall: 'Paveikslėlio "{name}" plotis turi būti bent {size} px.', + msgImageHeightSmall: 'Paveikslėlio "{name}" aukštis turi būti bent {size} px.', + msgImageWidthLarge: 'Paveikslėlio "{name}" plotis negali viršyti {size} px.', + msgImageHeightLarge: 'Paveikslėlio "{name}" aukštis negali viršyti {size} px.', + msgImageResizeError: 'Nepavyksta gauti paveikslėlio matmetų, kad pakeisti jo matmemis.', + msgImageResizeException: 'Klaida keičiant paveikslėlio matmenis.
{errors}
', + msgAjaxError: 'Kažkas nutiko vykdant {operation} operaciją. Prašome pabandyti vėliau!', + msgAjaxProgressError: '{operation} operacija nesėkminga', + ajaxOperations: { + deleteThumb: 'failo trynimo', + uploadThumb: 'failo įkėlimo', + uploadBatch: 'failų rinkinio įkėlimo', + uploadExtra: 'formos duomenų įkėlimo' + }, + dropZoneTitle: 'Tempkite failus čia …', + dropZoneClickTitle: '
(arba paspauskite, kad pasirinktumėte failus)', + fileActionSettings: { + removeTitle: 'Šalinti failą', + uploadTitle: 'Įkelti failą', + uploadRetryTitle: 'Bandyti įkelti vėl', + zoomTitle: 'Peržiūrėti detales', + dragTitle: 'Perstumti', + indicatorNewTitle: 'Dar neįkelta', + indicatorSuccessTitle: 'Įkelta', + indicatorErrorTitle: 'Įkėlimo Klaida', + indicatorLoadingTitle: 'Įkeliama ...' + }, + previewZoomButtonTitles: { + prev: 'Peržiūrėti ankstesnį failą', + next: 'Peržiūrėti kitą failą', + toggleheader: 'Perjungti viršutinę juostą', + fullscreen: 'Perjungti pilno ekrano rėžimą', + borderless: 'Perjungti berėmį režimą', + close: 'Uždaryti detalią peržiūrą' + } + }; +})(window.jQuery); \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..df3f3dc4 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js @@ -0,0 +1,100 @@ +/*! + * FileInput Dutch 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['nl'] = { + fileSingle: 'bestand', + filePlural: 'bestanden', + browseLabel: 'Zoek …', + removeLabel: 'Verwijder', + removeTitle: 'Verwijder geselecteerde bestanden', + cancelLabel: 'Annuleren', + cancelTitle: 'Annuleer upload', + uploadLabel: 'Upload', + uploadTitle: 'Upload geselecteerde bestanden', + msgNo: 'Nee', + msgNoFilesSelected: '', + msgCancelled: 'Geannuleerd', + msgPlaceholder: 'Selecteer {files}...', + msgZoomModalHeading: 'Gedetailleerd voorbeeld', + msgFileRequired: 'U moet een bestand kiezen om te uploaden.', + msgSizeTooSmall: 'Bestand "{name}" ({size} KB) is te klein en moet groter zijn dan {minSize} KB.', + msgSizeTooLarge: 'Bestand "{name}" ({size} KB) is groter dan de toegestane {maxSize} KB.', + msgFilesTooLess: 'U moet minstens {n} {files} selecteren om te uploaden.', + msgFilesTooMany: 'Aantal geselecteerde bestanden ({n}) is meer dan de toegestane {m}.', + msgFileNotFound: 'Bestand "{name}" niet gevonden!', + msgFileSecured: 'Bestand kan niet gelezen worden in verband met beveiligings redenen "{name}".', + msgFileNotReadable: 'Bestand "{name}" is niet leesbaar.', + msgFilePreviewAborted: 'Bestand weergaven geannuleerd voor "{name}".', + msgFilePreviewError: 'Er is een fout opgetreden met het lezen van "{name}".', + msgInvalidFileName: 'Ongeldige of niet ondersteunde karakters in bestandsnaam "{name}".', + msgInvalidFileType: 'Geen geldig bestand "{name}". Alleen "{types}" zijn toegestaan.', + msgInvalidFileExtension: 'Geen geldige extensie "{name}". Alleen "{extensions}" zijn toegestaan.', + msgFileTypes: { + 'image': 'afbeelding', + 'html': 'HTML', + 'text': 'tekst', + 'video': 'video', + 'audio': 'geluid', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Het uploaden van bestanden is afgebroken', + msgUploadThreshold: 'Verwerken...', + msgUploadBegin: 'Initialiseren...', + msgUploadEnd: 'Gedaan', + msgUploadEmpty: 'Geen geldige data beschikbaar voor upload.', + msgUploadError: 'Error', + msgValidationError: 'Bevestiging fout', + msgLoading: 'Bestanden laden {index} van de {files} …', + msgProgress: 'Bestanden laden {index} van de {files} - {name} - {percent}% compleet.', + msgSelected: '{n} {files} geselecteerd', + msgFoldersNotAllowed: 'Drag & drop alleen bestanden! {n} overgeslagen map(pen).', + msgImageWidthSmall: 'Breedte van het foto-bestand "{name}" moet minstens {size} px zijn.', + msgImageHeightSmall: 'Hoogte van het foto-bestand "{name}" moet minstens {size} px zijn.', + msgImageWidthLarge: 'Breedte van het foto-bestand "{name}" kan niet hoger zijn dan {size} px.', + msgImageHeightLarge: 'Hoogte van het foto bestand "{name}" kan niet hoger zijn dan {size} px.', + msgImageResizeError: 'Kon de foto afmetingen niet lezen om te verkleinen.', + msgImageResizeException: 'Fout bij het verkleinen van de foto.
{errors}
', + msgAjaxError: 'Er ging iets mis met de {operation} actie. Gelieve later opnieuw te proberen!', + msgAjaxProgressError: '{operation} mislukt', + ajaxOperations: { + deleteThumb: 'bestand verwijderen', + uploadThumb: 'bestand uploaden', + uploadBatch: 'alle bestanden uploaden', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Drag & drop bestanden hier …', + dropZoneClickTitle: '
(of klik hier om {files} te selecteren)', + fileActionSettings: { + removeTitle: 'Verwijder bestand', + uploadTitle: 'bestand uploaden', + uploadRetryTitle: 'Opnieuw uploaden', + downloadTitle: 'Download file', + zoomTitle: 'Bekijk details', + dragTitle: 'Verplaatsen / herindelen', + indicatorNewTitle: 'Nog niet geupload', + indicatorSuccessTitle: 'geupload', + indicatorErrorTitle: 'fout uploaden', + indicatorLoadingTitle: 'uploaden ...' + }, + previewZoomButtonTitles: { + prev: 'Toon vorig bestand', + next: 'Toon volgend bestand', + toggleheader: 'Toggle header', + fullscreen: 'Toggle volledig scherm', + borderless: 'Toggle randloze modus', + close: 'Sluit gedetailleerde weergave' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..773bb1bd --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js @@ -0,0 +1,99 @@ +/*! + * FileInput Norwegian 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['no'] = { + fileSingle: 'fil', + filePlural: 'filer', + browseLabel: 'Bla gjennom …', + removeLabel: 'Fjern', + removeTitle: 'Fjern valgte filer', + cancelLabel: 'Avbryt', + cancelTitle: 'Stopp pågående opplastninger', + uploadLabel: 'Last opp', + uploadTitle: 'Last opp valgte filer', + msgNo: 'Nei', + msgNoFilesSelected: 'Ingen filer er valgt', + msgCancelled: 'Avbrutt', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Detaljert visning', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'Filen "{name}" ({size} KB) er for liten og må være større enn {minSize} KB.', + msgSizeTooLarge: 'Filen "{name}" ({size} KB) er for stor, maksimal filstørrelse er {maxSize} KB.', + msgFilesTooLess: 'Du må velge minst {n} {files} for opplastning.', + msgFilesTooMany: 'For mange filer til opplastning, ({n}) overstiger maksantallet som er {m}.', + msgFileNotFound: 'Fant ikke filen "{name}"!', + msgFileSecured: 'Sikkerhetsrestriksjoner hindrer lesing av filen "{name}".', + msgFileNotReadable: 'Filen "{name}" er ikke lesbar.', + msgFilePreviewAborted: 'Filvisning avbrutt for "{name}".', + msgFilePreviewError: 'En feil oppstod under lesing av filen "{name}".', + msgInvalidFileName: 'Ugyldige tegn i filen "{name}".', + msgInvalidFileType: 'Ugyldig type for filen "{name}". Kun "{types}" filer er tillatt.', + msgInvalidFileExtension: 'Ugyldig endelse for filen "{name}". Kun "{extensions}" filer støttes.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Filopplastningen ble avbrutt', + msgUploadThreshold: 'Prosesserer...', + msgUploadBegin: 'Initialiserer...', + msgUploadEnd: 'Ferdig', + msgUploadEmpty: 'Ingen gyldige data tilgjengelig for opplastning.', + msgUploadError: 'Error', + msgValidationError: 'Valideringsfeil', + msgLoading: 'Laster fil {index} av {files} …', + msgProgress: 'Laster fil {index} av {files} - {name} - {percent}% fullført.', + msgSelected: '{n} {files} valgt', + msgFoldersNotAllowed: 'Kun Dra & slipp filer! Hoppet over {n} mappe(r).', + msgImageWidthSmall: 'Bredde på bildefilen "{name}" må være minst {size} px.', + msgImageHeightSmall: 'Høyde på bildefilen "{name}" må være minst {size} px.', + msgImageWidthLarge: 'Bredde på bildefilen "{name}" kan ikke overstige {size} px.', + msgImageHeightLarge: 'Høyde på bildefilen "{name}" kan ikke overstige {size} px.', + msgImageResizeError: 'Fant ikke dimensjonene som skulle resizes.', + msgImageResizeException: 'En feil oppstod under endring av størrelse .
{errors}
', + msgAjaxError: 'Noe gikk galt med {operation} operasjonen. Vennligst prøv igjen senere!', + msgAjaxProgressError: '{operation} feilet', + ajaxOperations: { + deleteThumb: 'file delete', + uploadThumb: 'file upload', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Dra & slipp filer her …', + dropZoneClickTitle: '
(eller klikk for å velge {files})', + fileActionSettings: { + removeTitle: 'Fjern fil', + uploadTitle: 'Last opp fil', + uploadRetryTitle: 'Retry upload', + zoomTitle: 'Vis detaljer', + dragTitle: 'Flytt / endre rekkefølge', + indicatorNewTitle: 'Opplastning ikke fullført', + indicatorSuccessTitle: 'Opplastet', + indicatorErrorTitle: 'Opplastningsfeil', + indicatorLoadingTitle: 'Laster opp ...' + }, + previewZoomButtonTitles: { + prev: 'Vis forrige fil', + next: 'Vis neste fil', + toggleheader: 'Vis header', + fullscreen: 'Åpne fullskjerm', + borderless: 'Åpne uten kanter', + close: 'Lukk detaljer' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..e19a0ed2 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js @@ -0,0 +1,90 @@ +/*! + * FileInput Polish 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['pl'] = { + fileSingle: 'plik', + filePlural: 'pliki', + browseLabel: 'Przeglądaj …', + removeLabel: 'Usuń', + removeTitle: 'Usuń zaznaczone pliki', + cancelLabel: 'Przerwij', + cancelTitle: 'Anuluj wysyłanie', + uploadLabel: 'Wgraj', + uploadTitle: 'Wgraj zaznaczone pliki', + msgNo: 'Nie', + msgNoFilesSelected: 'Brak zaznaczonych plików', + msgCancelled: 'Odwołany', + msgPlaceholder: 'Wybierz {files}...', + msgZoomModalHeading: 'Szczegółowy podgląd', + msgFileRequired: 'Musisz wybrać plik do wgrania.', + msgSizeTooSmall: 'Plik "{name}" ({size} KB) jest zbyt mały i musi być większy niż {minSize} KB.', + msgSizeTooLarge: 'Plik o nazwie "{name}" ({size} KB) przekroczył maksymalną dopuszczalną wielkość pliku wynoszącą {maxSize} KB.', + msgFilesTooLess: 'Minimalna liczba plików do wgrania: {n}.', + msgFilesTooMany: 'Liczba plików wybranych do wgrania w liczbie ({n}), przekracza maksymalny dozwolony limit wynoszący {m}.', + msgFileNotFound: 'Plik "{name}" nie istnieje!', + msgFileSecured: 'Ustawienia zabezpieczeń uniemożliwiają odczyt pliku "{name}".', + msgFileNotReadable: 'Plik "{name}" nie jest plikiem do odczytu.', + msgFilePreviewAborted: 'Podgląd pliku "{name}" został przerwany.', + msgFilePreviewError: 'Wystąpił błąd w czasie odczytu pliku "{name}".', + msgInvalidFileName: 'Nieprawidłowe lub nieobsługiwane znaki w nazwie pliku "{name}".', + msgInvalidFileType: 'Nieznany typ pliku "{name}". Tylko następujące rodzaje plików są dozwolone: "{types}".', + msgInvalidFileExtension: 'Złe rozszerzenie dla pliku "{name}". Tylko następujące rozszerzenia plików są dozwolone: "{extensions}".', + msgUploadAborted: 'Przesyłanie pliku zostało przerwane', + msgUploadThreshold: 'Przetwarzanie...', + msgUploadBegin: 'Rozpoczynanie...', + msgUploadEnd: 'Gotowe!', + msgUploadEmpty: 'Brak poprawnych danych do przesłania.', + msgUploadError: 'Błąd', + msgValidationError: 'Błąd walidacji', + msgLoading: 'Wczytywanie pliku {index} z {files} …', + msgProgress: 'Wczytywanie pliku {index} z {files} - {name} - {percent}% zakończone.', + msgSelected: '{n} Plików zaznaczonych', + msgFoldersNotAllowed: 'Metodą przeciągnij i upuść, można przenosić tylko pliki. Pominięto {n} katalogów.', + msgImageWidthSmall: 'Szerokość pliku obrazu "{name}" musi być co najmniej {size} px.', + msgImageHeightSmall: 'Wysokość pliku obrazu "{name}" musi być co najmniej {size} px.', + msgImageWidthLarge: 'Szerokość pliku obrazu "{name}" nie może przekraczać {size} px.', + msgImageHeightLarge: 'Wysokość pliku obrazu "{name}" nie może przekraczać {size} px.', + msgImageResizeError: 'Nie udało się uzyskać wymiaru obrazu, aby zmienić rozmiar.', + msgImageResizeException: 'Błąd podczas zmiany rozmiaru obrazu.
{errors}
', + msgAjaxError: 'Coś poczło nie tak podczas {operation}. Spróbuj ponownie!', + msgAjaxProgressError: '{operation} nie powiodło się', + ajaxOperations: { + deleteThumb: 'usuwanie pliku', + uploadThumb: 'przesyłanie pliku', + uploadBatch: 'masowe przesyłanie plików', + uploadExtra: 'przesyłanie danych formularza' + }, + dropZoneTitle: 'Przeciągnij i upuść pliki tutaj …', + dropZoneClickTitle: '
(lub kliknij tutaj i wybierz {files} z komputera)', + fileActionSettings: { + removeTitle: 'Usuń plik', + uploadTitle: 'Przesyłanie pliku', + uploadRetryTitle: 'Ponów', + downloadTitle: 'Pobierz plik', + zoomTitle: 'Pokaż szczegóły', + dragTitle: 'Przenies / Ponownie zaaranżuj', + indicatorNewTitle: 'Jeszcze nie przesłany', + indicatorSuccessTitle: 'Dodane', + indicatorErrorTitle: 'Błąd', + indicatorLoadingTitle: 'Przesyłanie ...' + }, + previewZoomButtonTitles: { + prev: 'Pokaż poprzedni plik', + next: 'Pokaż następny plik', + toggleheader: 'Włącz / wyłącz nagłówek', + fullscreen: 'Włącz / wyłącz pełny ekran', + borderless: 'Włącz / wyłącz tryb bez ramek', + close: 'Zamknij szczegółowy widok' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..157ac84c --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js @@ -0,0 +1,100 @@ +/*! + * FileInput Brazillian 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-BR'] = { + fileSingle: 'arquivo', + filePlural: 'arquivos', + browseLabel: 'Procurar…', + removeLabel: 'Remover', + removeTitle: 'Remover arquivos selecionados', + cancelLabel: 'Cancelar', + cancelTitle: 'Interromper envio em andamento', + uploadLabel: 'Enviar', + uploadTitle: 'Enviar arquivos selecionados', + msgNo: 'Não', + msgNoFilesSelected: 'Nenhum arquivo selecionado', + msgCancelled: 'Cancelado', + msgPlaceholder: 'Selecionar {files}...', + msgZoomModalHeading: 'Pré-visualização detalhada', + msgFileRequired: 'Você deve selecionar um arquivo para enviar.', + msgSizeTooSmall: 'O arquivo "{name}" ({size} KB) é muito pequeno e deve ser maior que {minSize} KB.', + msgSizeTooLarge: 'O arquivo "{name}" ({size} KB) excede o tamanho máximo permitido de {maxSize} KB.', + msgFilesTooLess: 'Você deve selecionar pelo menos {n} {files} para enviar.', + msgFilesTooMany: 'O número de arquivos selecionados para o envio ({n}) excede o limite máximo permitido de {m}.', + msgFileNotFound: 'O arquivo "{name}" não foi encontrado!', + msgFileSecured: 'Restrições de segurança impedem a leitura do arquivo "{name}".', + msgFileNotReadable: 'O arquivo "{name}" não pode ser lido.', + msgFilePreviewAborted: 'A pré-visualização do arquivo "{name}" foi interrompida.', + msgFilePreviewError: 'Ocorreu um erro ao ler o arquivo "{name}".', + msgInvalidFileName: 'Caracteres inválidos ou não suportados no arquivo "{name}".', + msgInvalidFileType: 'Tipo inválido para o arquivo "{name}". Apenas arquivos "{types}" são permitidos.', + msgInvalidFileExtension: 'Extensão inválida para o arquivo "{name}". Apenas arquivos "{extensions}" são permitidos.', + msgFileTypes: { + 'image': 'imagem', + 'html': 'HTML', + 'text': 'texto', + 'video': 'vídeo', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'objeto' + }, + msgUploadAborted: 'O envio do arquivo foi abortado', + msgUploadThreshold: 'Processando...', + msgUploadBegin: 'Inicializando...', + msgUploadEnd: 'Concluído', + msgUploadEmpty: 'Nenhuma informação válida para upload.', + msgUploadError: 'Erro de Upload', + msgValidationError: 'Erro de validação', + msgLoading: 'Enviando arquivo {index} de {files}…', + msgProgress: 'Enviando arquivo {index} de {files} - {name} - {percent}% completo.', + msgSelected: '{n} {files} selecionado(s)', + msgFoldersNotAllowed: 'Arraste e solte apenas arquivos! {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: 'Não foi possível obter as dimensões da imagem para redimensionar.', + msgImageResizeException: 'Erro ao redimensionar a imagem.
{errors}
', + msgAjaxError: 'Algo deu errado com a operação {operation}. Por favor tente novamente mais tarde!', + msgAjaxProgressError: '{operation} falhou', + ajaxOperations: { + deleteThumb: 'Exclusão de arquivo', + uploadThumb: 'Upload de arquivos', + uploadBatch: 'Carregamento de arquivos em lote', + uploadExtra: 'Carregamento de dados do formulário' + }, + dropZoneTitle: 'Arraste e solte os arquivos aqui…', + dropZoneClickTitle: '
(ou clique para selecionar o(s) arquivo(s))', + fileActionSettings: { + removeTitle: 'Remover arquivo', + uploadTitle: 'Enviar arquivo', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Ver detalhes', + dragTitle: 'Mover / Reordenar', + indicatorNewTitle: 'Ainda não enviado', + indicatorSuccessTitle: 'Enviado', + indicatorErrorTitle: 'Erro', + indicatorLoadingTitle: 'Enviando...' + }, + previewZoomButtonTitles: { + prev: 'Visualizar arquivo anterior', + next: 'Visualizar próximo arquivo', + toggleheader: 'Mostrar cabeçalho', + fullscreen: 'Ativar tela cheia', + borderless: 'Ativar modo sem borda', + close: 'Fechar pré-visualização detalhada' + } + }; +})(window.jQuery); 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..419b1761 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js @@ -0,0 +1,100 @@ +/*! + * 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}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Ficheiro "{name}" ({size} KB) excede o tamanho máximo permido de {maxSize} KB.', + msgFilesTooLess: 'Deve seleccionar pelo menos {n} {files} para fazer upload.', + msgFilesTooMany: 'Número máximo de ficheiros seleccionados ({n}) excede o limite máximo de {m}.', + 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.
{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: 'Arrastar e largar ficheiros aqui …', + dropZoneClickTitle: '
(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/kvision-bootstrap-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 new file mode 100644 index 00000000..d31b85bd --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js @@ -0,0 +1,101 @@ +/*! + * FileInput Romanian 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 Ciprian Voicu + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['ro'] = { + fileSingle: 'fișier', + filePlural: 'fișiere', + browseLabel: 'Răsfoiește …', + removeLabel: 'Șterge', + removeTitle: 'Curăță fișierele selectate', + cancelLabel: 'Renunță', + cancelTitle: 'Anulează încărcarea curentă', + uploadLabel: 'Încarcă', + uploadTitle: 'Încarcă fișierele selectate', + msgNo: 'Nu', + msgNoFilesSelected: '', + msgCancelled: 'Anulat', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Previzualizare detaliată', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Fișierul "{name}" ({size} KB) depășește limita maximă de încărcare de {maxSize} KB.', + msgFilesTooLess: 'Trebuie să selectezi cel puțin {n} {files} pentru a încărca.', + msgFilesTooMany: 'Numărul fișierelor pentru încărcare ({n}) depășește limita maximă de {m}.', + msgFileNotFound: 'Fișierul "{name}" nu a fost găsit!', + msgFileSecured: 'Restricții de securitate previn citirea fișierului "{name}".', + msgFileNotReadable: 'Fișierul "{name}" nu se poate citi.', + msgFilePreviewAborted: 'Fișierului "{name}" nu poate fi previzualizat.', + msgFilePreviewError: 'A intervenit o eroare în încercarea de citire a fișierului "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Tip de fișier incorect pentru "{name}". Sunt suportate doar fișiere de tipurile "{types}".', + msgInvalidFileExtension: 'Extensie incorectă pentru "{name}". Sunt suportate doar extensiile "{extensions}".', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Fișierul Încărcarea a fost întrerupt', + msgUploadThreshold: 'Processing...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: '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.', + msgSelected: '{n} {files} încărcate', + msgFoldersNotAllowed: 'Se poate doar trăgând fișierele! Se renunță la {n} dosar(e).', + msgImageWidthSmall: 'Lățimea de fișier de imagine "{name}" trebuie să fie de cel puțin {size} px.', + msgImageHeightSmall: 'Înălțimea fișier imagine "{name}" trebuie să fie de cel puțin {size} px.', + msgImageWidthLarge: 'Lățimea de fișier de imagine "{name}" nu poate depăși {size} px.', + msgImageHeightLarge: 'Înălțimea fișier imagine "{name}" nu poate depăși {size} px.', + msgImageResizeError: 'Nu a putut obține dimensiunile imaginii pentru a redimensiona.', + msgImageResizeException: 'Eroare la redimensionarea imaginii.
{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: 'Trage fișierele aici …', + dropZoneClickTitle: '
(or click to select {files})', + fileActionSettings: { + removeTitle: 'Scoateți fișier', + uploadTitle: 'Incarca fisier', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Vezi detalii', + dragTitle: 'Move / Rearrange', + indicatorNewTitle: 'Nu a încărcat încă', + indicatorSuccessTitle: 'încărcat', + indicatorErrorTitle: 'Încărcați eroare', + indicatorLoadingTitle: 'Se încarcă ...' + }, + 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-bootstrap-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 new file mode 100644 index 00000000..71c5ff7a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js @@ -0,0 +1,101 @@ +/*! + * FileInput Russian 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 CyanoFresh + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['ru'] = { + fileSingle: 'файл', + filePlural: 'файлы', + browseLabel: 'Выбрать …', + removeLabel: 'Удалить', + removeTitle: 'Очистить выбранные файлы', + cancelLabel: 'Отмена', + cancelTitle: 'Отменить текущую загрузку', + uploadLabel: 'Загрузить', + uploadTitle: 'Загрузить выбранные файлы', + msgNo: 'нет', + msgNoFilesSelected: '', + msgCancelled: 'Отменено', + msgPlaceholder: 'Выбрать {files}...', + msgZoomModalHeading: 'Подробное превью', + msgFileRequired: 'Необходимо выбрать файл для загрузки.', + msgSizeTooSmall: 'Файл "{name}" ({size} KB) имеет слишком маленький размер и должен быть больше {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: 'Неверные или неподдерживаемые символы в названии файла "{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: 'Обработка...', + msgUploadBegin: 'Инициализация...', + msgUploadEnd: 'Готово', + msgUploadEmpty: 'Недопустимые данные для загрузки', + msgUploadError: 'Ошибка загрузки', + msgValidationError: 'Ошибка проверки', + msgLoading: 'Загрузка файла {index} из {files} …', + msgProgress: 'Загрузка файла {index} из {files} - {name} - {percent}% завершено.', + msgSelected: 'Выбрано файлов: {n}', + msgFoldersNotAllowed: 'Разрешено перетаскивание только файлов! Пропущено {n} папок.', + msgImageWidthSmall: 'Ширина изображения {name} должна быть не меньше {size} px.', + msgImageHeightSmall: 'Высота изображения {name} должна быть не меньше {size} px.', + msgImageWidthLarge: 'Ширина изображения "{name}" не может превышать {size} px.', + msgImageHeightLarge: 'Высота изображения "{name}" не может превышать {size} px.', + msgImageResizeError: 'Не удалось получить размеры изображения, чтобы изменить размер.', + msgImageResizeException: 'Ошибка при изменении размера изображения.
{errors}
', + msgAjaxError: 'Произошла ошибка при выполнении операции {operation}. Повторите попытку позже!', + msgAjaxProgressError: 'Не удалось выполнить {operation}', + ajaxOperations: { + deleteThumb: 'удалить файл', + uploadThumb: 'загрузить файл', + uploadBatch: 'загрузить пакет файлов', + uploadExtra: 'загрузка данных с формы' + }, + dropZoneTitle: 'Перетащите файлы сюда …', + dropZoneClickTitle: '
(Или щёлкните, чтобы выбрать {files})', + fileActionSettings: { + removeTitle: 'Удалить файл', + uploadTitle: 'Загрузить файл', + uploadRetryTitle: 'Повторить загрузку', + downloadTitle: 'Загрузить файл', + zoomTitle: 'Посмотреть детали', + dragTitle: 'Переместить / Изменить порядок', + indicatorNewTitle: 'Еще не загружен', + indicatorSuccessTitle: 'Загружен', + indicatorErrorTitle: 'Ошибка загрузки', + indicatorLoadingTitle: 'Загрузка ...' + }, + previewZoomButtonTitles: { + prev: 'Посмотреть предыдущий файл', + next: 'Посмотреть следующий файл', + toggleheader: 'Переключить заголовок', + fullscreen: 'Переключить полноэкранный режим', + borderless: 'Переключить режим без полей', + close: 'Закрыть подробный предпросмотр' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..28d67e9a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js @@ -0,0 +1,100 @@ +/*! + * FileInput Slovakian 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['sk'] = { + fileSingle: 'súbor', + filePlural: 'súbory', + browseLabel: 'Vybrať …', + removeLabel: 'Odstrániť', + removeTitle: 'Vyčistiť vybraté súbory', + cancelLabel: 'Storno', + cancelTitle: 'Prerušiť nahrávanie', + uploadLabel: 'Nahrať', + uploadTitle: 'Nahrať vybraté súbory', + msgNo: 'Nie', + msgNoFilesSelected: '', + msgCancelled: 'Zrušené', + msgPlaceholder: 'Vybrať {files}...', + msgZoomModalHeading: 'Detailný náhľad', + msgFileRequired: 'Musíte vybrať súbor, ktorý chcete nahrať.', + msgSizeTooSmall: 'Súbor "{name}" ({size} KB) je príliš malý, musí mať veľkosť najmenej {minSize} KB.', + msgSizeTooLarge: 'Súbor "{name}" ({size} KB) je príliš veľký, maximálna povolená veľkosť {maxSize} KB.', + msgFilesTooLess: 'Musíte vybrať najmenej {n} {files} pre nahranie.', + msgFilesTooMany: 'Počet vybratých súborov ({n}) prekročil maximálny povolený limit {m}.', + msgFileNotFound: 'Súbor "{name}" nebol nájdený!', + msgFileSecured: 'Zabezpečenie súboru znemožnilo čítať súbor "{name}".', + msgFileNotReadable: 'Súbor "{name}" nie je čitateľný.', + msgFilePreviewAborted: 'Náhľad súboru bol prerušený pre "{name}".', + msgFilePreviewError: 'Nastala chyba pri načítaní súboru "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Neplatný typ súboru "{name}". Iba "{types}" súborov sú podporované.', + msgInvalidFileExtension: 'Neplatná extenzia súboru "{name}". Iba "{extensions}" súborov sú podporované.', + msgFileTypes: { + 'image': 'obrázok', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Nahrávanie súboru bolo prerušené', + msgUploadThreshold: 'Spracovávam...', + msgUploadBegin: 'Inicializujem...', + msgUploadEnd: 'Hotovo', + msgUploadEmpty: 'Na nahrávanie nie sú k dispozícii žiadne platné údaje.', + msgUploadError: 'Chyba', + msgValidationError: 'Chyba overenia', + msgLoading: 'Nahrávanie súboru {index} z {files} …', + msgProgress: 'Nahrávanie súboru {index} z {files} - {name} - {percent}% dokončené.', + msgSelected: '{n} {files} vybraté', + msgFoldersNotAllowed: 'Tiahni a pusť iba súbory! Vynechané {n} pustené prečinok(y).', + msgImageWidthSmall: 'Šírka obrázku "{name}", musí byť minimálne {size} px.', + msgImageHeightSmall: 'Výška obrázku "{name}", musí byť minimálne {size} px.', + msgImageWidthLarge: 'Šírka obrázku "{name}" nemôže presiahnuť {size} px.', + msgImageHeightLarge: 'Výška obrázku "{name}" nesmie presiahnuť {size} px.', + msgImageResizeError: 'Nepodarilo sa získať veľkosť obrázka pre zmenu veľkosti.', + msgImageResizeException: 'Chyba pri zmene veľkosti obrázka.
{errors}
', + msgAjaxError: 'Pri operácii {operation} sa vyskytla chyba. Skúste to prosím neskôr!', + msgAjaxProgressError: '{operation} - neúspešné', + ajaxOperations: { + deleteThumb: 'odstrániť súbor', + uploadThumb: 'nahrať súbor', + uploadBatch: 'nahrať várku súborov', + uploadExtra: 'odosielanie údajov z formulára' + }, + dropZoneTitle: 'Tiahni a pusť súbory tu …', + dropZoneClickTitle: '
(alebo kliknite sem a vyberte {files})', + fileActionSettings: { + removeTitle: 'Odstrániť súbor', + uploadTitle: 'Nahrať súbor', + uploadRetryTitle: 'Znova nahrať', + downloadTitle: 'Stiahnuť súbor', + zoomTitle: 'Zobraziť podrobnosti', + dragTitle: 'Posunúť / Preskládať', + indicatorNewTitle: 'Ešte nenahral', + indicatorSuccessTitle: 'Nahraný', + indicatorErrorTitle: 'Chyba pri nahrávaní', + indicatorLoadingTitle: 'Nahrávanie ...' + }, + previewZoomButtonTitles: { + prev: 'Zobraziť predchádzajúci súbor', + next: 'Zobraziť následujúci súbor', + toggleheader: 'Prepnúť záhlavie', + fullscreen: 'Prepnúť zobrazenie na celú obrazovku', + borderless: 'Prepnúť na bezrámikové zobrazenie', + close: 'Zatvoriť detailný náhľad' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..490d7d61 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js @@ -0,0 +1,98 @@ +/*! + * FileInput Slovenian 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 kv1dr + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['sl'] = { + fileSingle: 'datoteka', + filePlural: 'datotek', + browseLabel: 'Prebrskaj …', + removeLabel: 'Odstrani', + removeTitle: 'Počisti izbrane datoteke', + cancelLabel: 'Prekliči', + cancelTitle: 'Prekliči nalaganje', + uploadLabel: 'Naloži', + uploadTitle: 'Naloži izbrane datoteke', + msgNo: 'Ne', + msgNoFilesSelected: 'Nobena datoteka ni izbrana', + msgCancelled: 'Preklicano', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Podroben predogled', + msgSizeTooLarge: 'Datoteka "{name}" ({size} KB) presega največjo dovoljeno velikost za nalaganje {maxSize} KB.', + msgFilesTooLess: 'Za nalaganje morate izbrati vsaj {n} {files}.', + msgFilesTooMany: 'Število datotek, izbranih za nalaganje ({n}) je prekoračilo največjo dovoljeno število {m}.', + msgFileNotFound: 'Datoteka "{name}" ni bila najdena!', + msgFileSecured: 'Zaradi varnostnih omejitev nisem mogel prebrati datoteko "{name}".', + msgFileNotReadable: 'Datoteka "{name}" ni berljiva.', + msgFilePreviewAborted: 'Predogled datoteke "{name}" preklican.', + msgFilePreviewError: 'Pri branju datoteke "{name}" je prišlo do napake.', + msgInvalidFileType: 'Napačen tip datoteke "{name}". Samo "{types}" datoteke so podprte.', + msgInvalidFileExtension: 'Napačna končnica datoteke "{name}". Samo "{extensions}" datoteke so podprte.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Nalaganje datoteke je bilo preklicano', + msgUploadThreshold: 'Procesiram...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'Napaki pri validiranju', + msgLoading: 'Nalaganje datoteke {index} od {files} …', + msgProgress: 'Nalaganje datoteke {index} od {files} - {name} - {percent}% dokončano.', + msgSelected: '{n} {files} izbrano', + msgFoldersNotAllowed: 'Povlecite in spustite samo datoteke! Izpuščenih je bilo {n} map.', + msgImageWidthSmall: 'Širina slike "{name}" mora biti vsaj {size} px.', + msgImageHeightSmall: 'Višina slike "{name}" mora biti vsaj {size} px.', + msgImageWidthLarge: 'Širina slike "{name}" ne sme preseči {size} px.', + msgImageHeightLarge: 'Višina slike "{name}" ne sme preseči {size} px.', + msgImageResizeError: 'Nisem mogel pridobiti dimenzij slike za spreminjanje velikosti.', + msgImageResizeException: 'Napaka pri spreminjanju velikosti 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: 'Povlecite in spustite datoteke sem …', + dropZoneClickTitle: '
(ali kliknite sem za izbiro {files})', + fileActionSettings: { + removeTitle: 'Odstrani datoteko', + uploadTitle: 'Naloži datoteko', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Poglej podrobnosti', + dragTitle: 'Premaki / Razporedi', + indicatorNewTitle: 'Še ni naloženo', + indicatorSuccessTitle: 'Naloženo', + indicatorErrorTitle: 'Napaka pri nalaganju', + indicatorLoadingTitle: 'Nalagam ...' + }, + previewZoomButtonTitles: { + prev: 'Poglej prejšno datoteko', + next: 'Poglej naslednjo datoteko', + toggleheader: 'Preklopi glavo', + fullscreen: 'Preklopi celozaslonski način', + borderless: 'Preklopi način brez robov', + close: 'Zapri predogled podrobnosti' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..038b1d99 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js @@ -0,0 +1,99 @@ +/*! + * FileInput <_LANG_> 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['sv'] = { + fileSingle: 'fil', + filePlural: 'filer', + browseLabel: 'Bläddra …', + removeLabel: 'Ta bort', + removeTitle: 'Rensa valda filer', + cancelLabel: 'Avbryt', + cancelTitle: 'Avbryt pågående uppladdning', + uploadLabel: 'Ladda upp', + uploadTitle: 'Ladda upp valda filer', + msgNo: 'Nej', + msgNoFilesSelected: 'Inga filer valda', + msgCancelled: 'Avbruten', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'detaljerad förhandsgranskning', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'Filen "{name}" ({size} KB) är för liten och måste vara större än {minSize} KB.', + msgSizeTooLarge: 'File "{name}" ({size} KB) överstiger högsta tillåtna uppladdningsstorlek {maxSize} KB.', + msgFilesTooLess: 'Du måste välja minst {n} {files} för att ladda upp.', + msgFilesTooMany: 'Antal filer valda för uppladdning ({n}) överstiger högsta tillåtna gränsen {m}.', + msgFileNotFound: 'Filen "{name}" kunde inte hittas!', + msgFileSecured: 'Säkerhetsbegränsningar förhindrar att läsa filen "{name}".', + msgFileNotReadable: 'Filen "{name}" är inte läsbar.', + msgFilePreviewAborted: 'Filförhandsvisning avbröts för "{name}".', + msgFilePreviewError: 'Ett fel uppstod vid inläsning av filen "{name}".', + msgInvalidFileName: 'Ogiltiga eller tecken som inte stöds i filnamnet "{name}".', + msgInvalidFileType: 'Ogiltig typ för filen "{name}". Endast "{types}" filtyper stöds.', + msgInvalidFileExtension: 'Ogiltigt filtillägg för filen "{name}". Endast "{extensions}" filer stöds.', + msgFileTypes: { + 'image': 'bild', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'ljud', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'objekt' + }, + msgUploadAborted: 'Filöverföringen avbröts', + msgUploadThreshold: 'Bearbetar...', + msgUploadBegin: 'Påbörjar...', + msgUploadEnd: 'Färdig', + msgUploadEmpty: 'Ingen giltig data tillgänglig för uppladdning.', + msgUploadError: 'Error', + msgValidationError: 'Valideringsfel', + msgLoading: 'Laddar fil {index} av {files} …', + msgProgress: 'Laddar fil {index} av {files} - {name} - {percent}% färdig.', + msgSelected: '{n} {files} valda', + msgFoldersNotAllowed: 'Endast drag & släppfiler! Skippade {n} släpta mappar.', + msgImageWidthSmall: 'Bredd på bildfilen "{name}" måste minst vara {size} pixlar.', + msgImageHeightSmall: 'Höjden på bildfilen "{name}" måste minst vara {size} pixlar.', + msgImageWidthLarge: 'Bredd på bildfil "{name}" kan inte överstiga {size} pixlar.', + msgImageHeightLarge: 'Höjden på bildfilen "{name}" kan inte överstiga {size} pixlar.', + msgImageResizeError: 'Det gick inte att hämta bildens dimensioner för att ändra storlek.', + msgImageResizeException: 'Fel vid storleksändring av bilden.
{errors}
', + msgAjaxError: 'Något gick fel med {operation} operationen. Försök igen senare!', + msgAjaxProgressError: '{operation} misslyckades', + ajaxOperations: { + deleteThumb: 'file delete', + uploadThumb: 'file upload', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Drag & släpp filer här …', + dropZoneClickTitle: '
(eller klicka för att markera {files})', + fileActionSettings: { + removeTitle: 'Ta bort fil', + uploadTitle: 'Ladda upp fil', + uploadRetryTitle: 'Retry upload', + zoomTitle: 'Visa detaljer', + dragTitle: 'Flytta / Ändra ordning', + indicatorNewTitle: 'Inte uppladdat ännu', + indicatorSuccessTitle: 'Uppladdad', + indicatorErrorTitle: 'Uppladdningsfel', + indicatorLoadingTitle: 'Laddar upp...' + }, + previewZoomButtonTitles: { + prev: 'Visa föregående fil', + next: 'Visa nästa fil', + toggleheader: 'Rubrik', + fullscreen: 'Fullskärm', + borderless: 'Gränslös', + close: 'Stäng detaljerad förhandsgranskning' + } + }; +})(window.jQuery); \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..7a2d0460 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js @@ -0,0 +1,100 @@ +/*! + * FileInput Thai 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['th'] = { + 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}" เป็น extension ที่ไมถูกต้อง, อนุญาตเฉพาะไฟล์ extension "{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: 'Drag & drop เฉพาะไฟล์เท่านั้น! ข้าม dropped folder จำนวน {n}', + msgImageWidthSmall: 'ความกว้างของภาพไฟล์ "{name}" ต้องมีอย่างน้อย {size} px.', + msgImageHeightSmall: 'ความสูงของภาพไฟล์ "{name}" ต้องมีอย่างน้อย {size} px.', + msgImageWidthLarge: 'ความกว้างของภาพไฟล์ "{name}" ไม่เกิน {size} พิกเซล.', + msgImageHeightLarge: 'ความสูงของไฟล์ภาพ "{name}" ไม่เกิน {size} พิกเซล.', + 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: 'Drag & drop ไฟล์ตรงนี้ …', + 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); \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..1fe6a383 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js @@ -0,0 +1,99 @@ +/*! + * FileInput Turkish 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['tr'] = { + fileSingle: 'dosya', + filePlural: 'dosyalar', + browseLabel: 'Gözat …', + removeLabel: 'Sil', + removeTitle: 'Seçilen dosyaları sil', + cancelLabel: 'İptal', + cancelTitle: 'Devam eden yüklemeyi iptal et', + uploadLabel: 'Yükle', + uploadTitle: 'Seçilen dosyaları yükle', + msgNo: 'Hayır', + msgNoFilesSelected: '', + msgCancelled: 'İptal edildi', + msgPlaceholder: 'Seçilen {files}...', + msgZoomModalHeading: 'Detaylı Önizleme', + msgFileRequired: 'Yüklemek için bir dosya seçmelisiniz.', + msgSizeTooSmall: '"{name}"({size} KB) dosyası çok küçük ve {minSize} KB boyutundan büyük olmalıdır.', + msgSizeTooLarge: '"{name}" dosyasının boyutu ({size} KB) izin verilen azami dosya boyutu olan {maxSize} KB\'tan büyük.', + msgFilesTooLess: 'Yüklemek için en az {n} {files} dosya seçmelisiniz.', + msgFilesTooMany: 'Yüklemek için seçtiğiniz dosya sayısı ({n}) azami limitin ({m}) altında olmalıdır.', + msgFileNotFound: '"{name}" dosyası bulunamadı!', + msgFileSecured: 'Güvenlik kısıtlamaları "{name}" dosyasının okunmasını engelliyor.', + msgFileNotReadable: '"{name}" dosyası okunabilir değil.', + msgFilePreviewAborted: '"{name}" dosyası için önizleme iptal edildi.', + msgFilePreviewError: '"{name}" dosyası okunurken bir hata oluştu.', + msgInvalidFileName: '"{name}" dosya adında geçersiz veya desteklenmeyen karakterler var.', + msgInvalidFileType: '"{name}" dosyasının türü geçerli değil. Yalnızca "{types}" türünde dosyalara izin veriliyor.', + msgInvalidFileExtension: '"{name}" dosyasının uzantısı geçersiz. Yalnızca "{extensions}" uzantılı dosyalara izin veriliyor.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Dosya yükleme iptal edildi', + msgUploadThreshold: 'İşlem yapılıyor...', + msgUploadBegin: 'Başlıyor...', + msgUploadEnd: 'Başarılı', + msgUploadEmpty: 'Yüklemek için geçerli veri mevcut değil.', + msgUploadError: 'Hata', + msgValidationError: 'Doğrulama Hatası', + msgLoading: 'Dosya yükleniyor {index} / {files} …', + msgProgress: 'Dosya yükleniyor {index} / {files} - {name} - %{percent} tamamlandı.', + msgSelected: '{n} {files} seçildi', + msgFoldersNotAllowed: 'Yalnızca dosyaları sürükleyip bırakabilirsiniz! {n} dizin(ler) göz ardı edildi.', + msgImageWidthSmall: '"{name}" adlı görüntü dosyasının genişliği en az {size} piksel olmalıdır.', + msgImageHeightSmall: '"{name}" adlı görüntü dosyasının yüksekliği en az {size} piksel olmalıdır.', + msgImageWidthLarge: '"{name}" adlı görüntü dosyasının genişliği {size} pikseli geçemez.', + msgImageHeightLarge: '"{name}" adlı görüntü dosyasının yüksekliği {size} pikseli geçemez.', + msgImageResizeError: 'Görüntü boyutlarını yeniden boyutlandıramadı.', + msgImageResizeException: 'Görüntü boyutlandırma sırasında hata.
{errors}
', + 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.', + ajaxOperations: { + deleteThumb: 'dosya silme', + uploadThumb: 'dosya yükleme', + uploadBatch: 'toplu dosya yükleme', + uploadExtra: 'form verisi yükleme' + }, + dropZoneTitle: 'Dosyaları buraya sürükleyip bırakın', + dropZoneClickTitle: '
(ya da {files} seçmek için tıklayınız)', + fileActionSettings: { + removeTitle: 'Dosyayı kaldır', + uploadTitle: 'Dosyayı yükle', + uploadRetryTitle: 'Retry upload', + zoomTitle: 'Ayrıntıları görüntüle', + dragTitle: 'Taşı / Yeniden düzenle', + indicatorNewTitle: 'Henüz yüklenmedi', + indicatorSuccessTitle: 'Yüklendi', + indicatorErrorTitle: 'Yükleme Hatası', + indicatorLoadingTitle: 'Yükleniyor ...' + }, + previewZoomButtonTitles: { + prev: 'Önceki dosyayı göster', + next: 'Sonraki dosyayı göster', + toggleheader: 'Üst bilgi geçiş', + fullscreen: 'Tam ekran geçiş', + borderless: 'Çerçevesiz moda geçiş', + close: 'Detaylı önizlemeyi kapat' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..d1b7f3a1 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js @@ -0,0 +1,101 @@ +/*! + * FileInput Ukrainian 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 CyanoFresh + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['uk'] = { + fileSingle: 'файл', + filePlural: 'файли', + browseLabel: 'Вибрати …', + removeLabel: 'Видалити', + removeTitle: 'Видалити вибрані файли', + cancelLabel: 'Скасувати', + cancelTitle: 'Скасувати поточне відвантаження', + uploadLabel: 'Відвантажити', + uploadTitle: 'Відвантажити обрані файли', + msgNo: 'Немає', + msgNoFilesSelected: '', + msgCancelled: 'Cкасовано', + msgPlaceholder: 'Оберіть {files}...', + msgZoomModalHeading: 'Детальний превью', + msgFileRequired: 'Ви повинні обрати файл для завантаження.', + msgSizeTooSmall: 'Файл "{name}" ({size} KB) занадто малий і повинен бути більший, ніж {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: 'Недійсні чи непідтримувані символи в імені файлу "{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: 'Обробка...', + msgUploadBegin: 'Ініціалізація...', + msgUploadEnd: 'Готово', + msgUploadEmpty: 'Немає доступних даних для відвантаження.', + msgUploadError: 'Помилка', + 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: 'Щось не так із операцією {operation}. Будь ласка, спробуйте пізніше!', + msgAjaxProgressError: 'помилка {operation}', + ajaxOperations: { + deleteThumb: 'видалити файл', + uploadThumb: 'відвантажити файл', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Перетягніть файли сюди …', + dropZoneClickTitle: '
(або клацність та оберіть {files})', + fileActionSettings: { + removeTitle: 'Видалити файл', + uploadTitle: 'Відвантажити файл', + uploadRetryTitle: 'Повторити відвантаження', + downloadTitle: 'Завантажити файл', + zoomTitle: 'Подивитися деталі', + dragTitle: 'Перенести / Переставити', + indicatorNewTitle: 'Ще не відвантажено', + indicatorSuccessTitle: 'Відвантажено', + indicatorErrorTitle: 'Помилка при відвантаженні', + indicatorLoadingTitle: 'Завантаження ...' + }, + previewZoomButtonTitles: { + prev: 'Переглянути попередній файл', + next: 'Переглянути наступний файл', + toggleheader: 'Перемкнути заголовок', + fullscreen: 'Перемкнути повноекранний режим', + borderless: 'Перемкнути режим без полів', + close: 'Закрити детальний перегляд' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..c2c57168 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js @@ -0,0 +1,101 @@ +/*! + * FileInput Uzbek 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 CyanoFresh + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales.uz = { + fileSingle: 'fayl', + filePlural: 'fayllar', + browseLabel: 'Tanlash …', + removeLabel: 'O\'chirish', + removeTitle: 'Tanlangan fayllarni tozalash', + cancelLabel: 'Bekor qilish', + cancelTitle: 'Joriy yuklab olishni bekor qilish', + uploadLabel: 'Yuklab olish', + uploadTitle: 'Tanlangan fayllarni yuklash', + msgNo: 'No', + msgNoFilesSelected: 'No files selected', + msgCancelled: 'Cancelled', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Detailed Preview', + 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}" fayl ({size} KB) ruxsat etilgan maksimal yuklash hajmidan {maxSize} KB ortiq. Yuklashni qayta urinib ko\'ring!', + msgFilesTooLess: 'Yuklash uchun kamida {n} {files} tanlashingiz kerak. Yuklashni qayta urinib ko\'ring!', + msgFilesTooMany: 'Tanlangan fayllar ({n}) ruxsat etilgan maksimal yuklash hajmidan {m} ortiq. Yuklashni qayta urinib ko\'ring!', + msgFileNotFound: '"{name}" fayl topilmaydi!', + msgFileSecured: 'Security restrictions prevent reading the file "{name}".', + msgFileNotReadable: '"{name}" fayl o\'qilmaydi.', + msgFilePreviewAborted: '"{name}" Ffylni oldindan ko\'rish jarayoni to\'xtatildi.', + msgFilePreviewError: '"{name}" faylni o\'qish paytida xatolik yuz berdi.', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: '"{name}" fayl uchun yaroqsiz tur. Faqat "{types}" fayllari qo\'llab-quvvatlanadi.', + msgInvalidFileExtension: '"{name}" fayl uchun noto\'g\'ri kengaytma. Faqat "{extensions}" fayllari qo\'llab-quvvatlanadi.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'The file upload was aborted', + msgUploadThreshold: 'Processing...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Error', + msgValidationError: 'Fayl yuklash xatosi', + msgLoading: '{Files} dan {index} faylini yuklash …', + msgProgress: '{Files} dan {index}{name} faylini yuklashi - {percent}% tugallandi.', + msgSelected: '{n} {files} tanlangan', + msgFoldersNotAllowed: 'Faqat tortib qo\'yiladon fayllar! {n} o\'tirilgan tashlangan papka(lar).', + msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.', + msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.', + msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', + msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', + msgImageResizeError: 'Could not get the image dimensions to resize.', + msgImageResizeException: 'Error while resizing the image.
{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: 'Fayllarni bu yerga tortib qo\'ying …', + dropZoneClickTitle: '
(or click to select {files})', + fileActionSettings: { + removeTitle: 'Remove file', + uploadTitle: 'Upload file', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'View details', + dragTitle: 'Move / Rearrange', + indicatorNewTitle: 'Not uploaded yet', + indicatorSuccessTitle: 'Uploaded', + indicatorErrorTitle: 'Upload Error', + indicatorLoadingTitle: 'Uploading ...' + }, + 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-bootstrap-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 new file mode 100644 index 00000000..7d140b5e --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js @@ -0,0 +1,101 @@ +/*! + * FileInput Vietnamese 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['vi'] = { + fileSingle: 'tập tin', + filePlural: 'các tập tin', + browseLabel: 'Duyệt …', + removeLabel: 'Gỡ bỏ', + removeTitle: 'Bỏ tập tin đã chọn', + cancelLabel: 'Hủy', + cancelTitle: 'Hủy upload', + uploadLabel: 'Upload', + uploadTitle: 'Upload tập tin đã chọn', + msgNo: 'Không', + msgNoFilesSelected: 'Không tập tin nào được chọn', + msgCancelled: 'Đã hủy', + msgPlaceholder: 'Select {files}...', + msgZoomModalHeading: 'Chi tiết xem trước', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'Tập tin "{name}" ({size} KB) vượt quá kích thước giới hạn cho phép {maxSize} KB.', + msgFilesTooLess: 'Bạn phải chọn ít nhất {n} {files} để upload.', + msgFilesTooMany: 'Số lượng tập tin upload ({n}) vượt quá giới hạn cho phép là {m}.', + msgFileNotFound: 'Không tìm thấy tập tin "{name}"!', + msgFileSecured: 'Các hạn chế về bảo mật không cho phép đọc tập tin "{name}".', + msgFileNotReadable: 'Không đọc được tập tin "{name}".', + msgFilePreviewAborted: 'Đã dừng xem trước tập tin "{name}".', + msgFilePreviewError: 'Đã xảy ra lỗi khi đọc tập tin "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Tập tin "{name}" không hợp lệ. Chỉ hỗ trợ loại tập tin "{types}".', + msgInvalidFileExtension: 'Phần mở rộng của tập tin "{name}" không hợp lệ. Chỉ hỗ trợ phần mở rộng "{extensions}".', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'Đã dừng upload', + msgUploadThreshold: 'Đang xử lý...', + msgUploadBegin: 'Initializing...', + msgUploadEnd: 'Done', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: '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.', + msgSelected: '{n} {files} được chọn', + msgFoldersNotAllowed: 'Chỉ kéo thả tập tin! Đã bỏ qua {n} thư mục.', + msgImageWidthSmall: 'Chiều rộng của hình ảnh "{name}" phải tối thiểu là {size} px.', + msgImageHeightSmall: 'Chiều cao của hình ảnh "{name}" phải tối thiểu là {size} px.', + msgImageWidthLarge: 'Chiều rộng của hình ảnh "{name}" không được quá {size} px.', + msgImageHeightLarge: 'Chiều cao của hình ảnh "{name}" không được quá {size} px.', + msgImageResizeError: 'Không lấy được kích thước của hình ảnh để resize.', + msgImageResizeException: 'Resize hình ảnh bị lỗi.
{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: 'Kéo thả tập tin vào đây …', + dropZoneClickTitle: '
(hoặc click để chọn {files})', + fileActionSettings: { + removeTitle: 'Gỡ bỏ', + uploadTitle: 'Upload tập tin', + uploadRetryTitle: 'Retry upload', + downloadTitle: 'Download file', + zoomTitle: 'Phóng lớn', + dragTitle: 'Di chuyển / Sắp xếp lại', + indicatorNewTitle: 'Chưa được upload', + indicatorSuccessTitle: 'Đã upload', + indicatorErrorTitle: 'Upload bị lỗi', + indicatorLoadingTitle: 'Đang upload ...' + }, + previewZoomButtonTitles: { + prev: 'Xem tập tin phía trước', + next: 'Xem tập tin tiếp theo', + toggleheader: 'Ẩn/hiện tiêu đề', + fullscreen: 'Bật/tắt toàn màn hình', + borderless: 'Bật/tắt chế độ không viền', + close: 'Đóng' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..49f7710f --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js @@ -0,0 +1,102 @@ +/*! + * FileInput Chinese Traditional 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 kangqf + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['zh-TW'] = { + fileSingle: '單一檔案', + filePlural: '複選檔案', + browseLabel: '瀏覽 …', + removeLabel: '移除', + removeTitle: '清除選取檔案', + cancelLabel: '取消', + cancelTitle: '取消上傳中檔案', + uploadLabel: '上傳', + uploadTitle: '上傳選取檔案', + msgNo: '沒有', + msgNoFilesSelected: '未選擇檔案', + msgCancelled: '取消', + zoomTitle: '詳細資料', + msgPlaceholder: '選擇 {files}...', + msgZoomModalHeading: '內容預覽', + msgFileRequired: '必須選擇壹個文件上傳.', + msgSizeTooSmall: '檔案 "{name}" ({size} KB) 必須大於限定大小 {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: '附檔名 "{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: '處理中...', + msgUploadBegin: '正在初始化...', + msgUploadEnd: '完成', + msgUploadEmpty: '無效的文件上傳.', + msgUploadError: '上傳錯誤', + 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: '{operation} 發生錯誤. 請重試!', + msgAjaxProgressError: '{operation} 失敗', + ajaxOperations: { + deleteThumb: 'file delete', + uploadThumb: 'file upload', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: '拖曳檔案至此 …', + dropZoneClickTitle: '
(或點擊{files}按鈕選擇文件)', + fileActionSettings: { + removeTitle: '刪除檔案', + uploadTitle: '上傳檔案', + uploadRetryTitle: '重試', + downloadTitle: '下載檔案', + zoomTitle: '詳細資料', + dragTitle: '移動 / 重置', + indicatorNewTitle: '尚未上傳', + indicatorSuccessTitle: '上傳成功', + indicatorErrorTitle: '上傳失敗', + indicatorLoadingTitle: '上傳中 ...' + }, + previewZoomButtonTitles: { + prev: '預覽上壹個文件', + next: '預覽下壹個文件', + toggleheader: '縮放', + fullscreen: '全屏', + borderless: '無邊界模式', + close: '關閉當前預覽' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..469fa380 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js @@ -0,0 +1,101 @@ +/*! + * FileInput Chinese 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 kangqf + * + * NOTE: this file must be saved in UTF-8 encoding. + */ +(function ($) { + "use strict"; + + $.fn.fileinputLocales['zh'] = { + fileSingle: '文件', + filePlural: '个文件', + browseLabel: '选择 …', + removeLabel: '移除', + removeTitle: '清除选中文件', + cancelLabel: '取消', + cancelTitle: '取消进行中的上传', + uploadLabel: '上传', + uploadTitle: '上传选中文件', + msgNo: '没有', + msgNoFilesSelected: '未选择文件', + msgCancelled: '取消', + msgPlaceholder: '选择 {files}...', + msgZoomModalHeading: '详细预览', + msgFileRequired: '必须选择一个文件上传.', + msgSizeTooSmall: '文件 "{name}" ({size} KB) 必须大于限定大小 {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: '文件名 "{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: '处理中...', + msgUploadBegin: '正在初始化...', + msgUploadEnd: '完成', + msgUploadEmpty: '无效的文件上传.', + msgUploadError: '上传出错', + msgValidationError: '验证错误', + msgLoading: '加载第 {index} 文件 共 {files} …', + msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', + msgSelected: '{n} {files} 选中', + msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', + msgImageWidthSmall: '图像文件的"{name}"的宽度必须是至少{size}像素.', + msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', + msgImageWidthLarge: '图像文件"{name}"的宽度不能超过{size}像素.', + msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', + msgImageResizeError: '无法获取的图像尺寸调整。', + msgImageResizeException: '调整图像大小时发生错误。
{errors}
', + msgAjaxError: '{operation} 发生错误. 请重试!', + msgAjaxProgressError: '{operation} 失败', + ajaxOperations: { + deleteThumb: '删除文件', + uploadThumb: '上传文件', + uploadBatch: '批量上传', + uploadExtra: '表单数据上传' + }, + dropZoneTitle: '拖拽文件到这里 …
支持多文件同时上传', + dropZoneClickTitle: '
(或点击{files}按钮选择文件)', + fileActionSettings: { + removeTitle: '删除文件', + uploadTitle: '上传文件', + downloadTitle: '下载文件', + uploadRetryTitle: '重试', + zoomTitle: '查看详情', + dragTitle: '移动 / 重置', + indicatorNewTitle: '没有上传', + indicatorSuccessTitle: '上传', + indicatorErrorTitle: '上传错误', + indicatorLoadingTitle: '上传 ...' + }, + previewZoomButtonTitles: { + prev: '预览上一个文件', + next: '预览下一个文件', + toggleheader: '缩放', + fullscreen: '全屏', + borderless: '无边界模式', + close: '关闭当前预览' + } + }; +})(window.jQuery); diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..13c8531b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt @@ -0,0 +1,100 @@ +/* + * 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 + +import org.w3c.dom.Element +import pl.treksoft.jquery.jQuery +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.panel.Root +import kotlin.browser.document +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +interface TestSpec { + fun beforeTest() + + fun afterTest() + + fun run(code: () -> Unit) { + beforeTest() + code() + afterTest() + } +} + +interface SimpleSpec : TestSpec { + + override fun beforeTest() { + } + + override fun afterTest() { + } + +} + +interface DomSpec : TestSpec { + + override fun beforeTest() { + val fixture = "
" + + "
" + document.body?.insertAdjacentHTML("afterbegin", fixture) + } + + override fun afterTest() { + val div = document.getElementById("pretest") + div?.let { jQuery(it).remove() } + jQuery(".modal-backdrop").remove() + Root.shutdown() + } + + fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { + if (expected != null && actual != null) { + val exp = jQuery(expected) + val act = jQuery(actual) + val result = exp[0]?.isEqualNode(act[0]) + if (result == true) { + assertTrue(result == true, message) + } else { + assertEquals(expected, actual, message) + } + } else { + assertEquals(expected, actual, message) + } + } +} + +interface WSpec : DomSpec { + + fun runW(code: (widget: Widget, element: Element?) -> Unit) { + run { + val root = Root("test", fixed = true) + val widget = Widget() + widget.id = "test_id" + root.add(widget) + val element = document.getElementById("test_id") + code(widget, element) + } + } + +} + +external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..de7a9315 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.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 test.pl.treksoft.kvision.form.upload + +import pl.treksoft.jquery.jQuery +import pl.treksoft.kvision.form.upload.UploadInput +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class UploadInputSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val upi = UploadInput(multiple = true).apply { + id = "idti" + } + root.add(upi) + val content = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } + assertEqualsHtml( + "", + content, + "Should render correct file input control for multiple files" + ) + upi.multiple = false + val content2 = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } + assertEqualsHtml( + "", + content2, + "Should render correct file input control for single file" + ) + } + } + +} diff --git a/kvision-modules/kvision-bootstrap-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 new file mode 100644 index 00000000..92078153 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.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.form.upload + +import pl.treksoft.jquery.jQuery +import pl.treksoft.kvision.form.upload.Upload +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class UploadSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val upi = Upload(multiple = true) + val id = upi.input.id + root.add(upi) + val content = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } + assertEqualsHtml( + "", + content, + "Should render correct file input control for multiple files" + ) + upi.multiple = false + val content2 = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } + assertEqualsHtml( + "", + content2, + "Should render correct file input control for single file" + ) + } + } + +} 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-bootstrap-upload/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js new file mode 100644 index 00000000..a5c7b5da --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js @@ -0,0 +1,6 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif)$/i, + loader: 'file-loader' + } +); \ No newline at end of file diff --git a/kvision-modules/kvision-bootstrap/build.gradle b/kvision-modules/kvision-bootstrap/build.gradle index 2f8efeb8..34aa8bb0 100644 --- a/kvision-modules/kvision-bootstrap/build.gradle +++ b/kvision-modules/kvision-bootstrap/build.gradle @@ -3,12 +3,9 @@ apply from: "../shared.gradle" kotlinFrontend { npm { - dependency("popper.js", "1.15.0") dependency("bootstrap", "4.3.1") - dependency("font-awesome", "4.7.0") - dependency("font-awesome-webpack-4", "1.0.0") dependency("awesome-bootstrap-checkbox", "1.0.1") - dependency("bootstrap-vertical-tabs", "1.2.2") + 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 678ad33e..1a650117 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,38 +21,43 @@ */ 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 } - require("bootstrap") - if (bootswatch != null) { - if (bootswatch.getAttribute("href")?.contains("/paper/") == true) { - require("./css/paper.css") + init { + require("bootstrap/dist/js/bootstrap.bundle.min.js") + require("awesome-bootstrap-checkbox") + require("bootstrap-vertical-tabs") + require("./css/kvbootstrap.css") + } + + private val elementResizeEvent = require("element-resize-event") + + @Suppress("UnsafeCastFromDynamic") + internal fun setResizeEvent(component: Component, callback: () -> Unit) { + if (!isIE11()) { + component.getElement()?.let { + elementResizeEvent(it, callback) } - } else { - require("bootstrap/dist/css/bootstrap.min.css") } - 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 = 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 { + 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 = 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? = 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 = 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): 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 { + 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 { + 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? = null, icon: String? = null, + style: ButtonStyle = ButtonStyle.PRIMARY, direction: Direction = Direction.DROPDOWN, + disabled: Boolean = false, forNavbar: Boolean = false, forDropDown: Boolean = false, + classes: Set = 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 = 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 = 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 = 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 = 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 = setOf() +) : + Button(text, icon, style, ButtonType.BUTTON, disabled, classes) { + + init { + this.id = id + if (!forNavbar && !forDropDown) this.role = "button" + setInternalEventListener { + 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 { + 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 { + 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 { + 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 = 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 = 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 = 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 = 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 = 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 = 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..5f5a1a80 --- /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", "ok", 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(""))) + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + cl.add("close" to true) + return cl + } + + override fun getSnAttrs(): List { + 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..e16ca87e --- /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, "remove") + private val noButton = Button(noTitle, "ban-circle") + private val yesButton = Button(yesTitle, "ok", 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 = 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): 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 { + 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 { + 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 { + 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 = 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 { + 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 = 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 = 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 = 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 = 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 { + 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 = 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 = 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): 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 { + return container.getChildren() + } + + override fun getSnClass(): List { + 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 = 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 = 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 { + 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 = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null +) : SimplePanel(classes + "container-fluid") { + + /** + * Text align of grid cells. + */ + var align by refreshOnUpdate(align) { refreshRowContainers() } + + internal val map = mutableMapOf>() + 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): 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 = 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 = 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() + + 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 { + 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 { + 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): 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 = 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 = 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 = 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 = 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 { + 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 { + 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 = 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 { + 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 = 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 = 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 = 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 = 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(""))) + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + cl.add("close" to true) + return cl + } + + override fun getSnAttrs(): List { + 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(""))) + } + + override fun getSnClass(): List { + val cl = super.getSnClass().toMutableList() + cl.add("close" to true) + return cl + } + + override fun getSnAttrs(): List { + 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 = 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 { + 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 { + 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): 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 { + 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 = 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/kvbootstrap.css b/kvision-modules/kvision-bootstrap/src/main/resources/css/kvbootstrap.css new file mode 100644 index 00000000..1a16b41f --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/resources/css/kvbootstrap.css @@ -0,0 +1,291 @@ +/* + +.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; +}*/ + +.form-check { + padding-left: 0.5rem; +} + +.form-check-input.form-control-sm, .form-check-input.form-control-lg { + height: inherit; +} + +.kv-radiogroup-inline label.control-label { + vertical-align: top; + margin-right: .75rem; + margin-bottom: 0px; +} +.row.kv-radiogroup-inline label.control-label { + margin-right: 0px; +} + +.row.kv-radiogroup-inline .kv-radiogroup-container, .row.kv-radiogroup .kv-radiogroup-container { + margin-left: -15px; +} + +.kv-radiogroup-inline .kv-radiogroup-container { + display: inline-flex; +} + +.kv-radiogroup-container.is-invalid~.invalid-feedback { + display: block; +} + +.form-check-inline { + margin-left: 3px; +} + +.form-check-inline.form-check { + padding-left: 0px; +} + +.form-horizontal.container-fluid { + width: inherit; +} + +.form-inline .form-group { + margin-right: 6px; +} + +.form-inline .form-group .control-label { + margin-right: 6px; +} + +.form-inline .form-check.form-group { + margin-left: 6px; +} + +.kv-form-condensed .form-group { + margin-bottom: 0.5rem; +} + +.kv-window.modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0,0,0,.5); + box-shadow: 0 5px 15px rgba(0,0,0,.5); + border-radius: 0px; +} + +.kv-window .modal-header { + height: 40px; + padding: 5px 15px 5px 15px; + align-items: center; +} + +.kv-window .modal-header button.close { + width: 24px; + height: 24px; + margin: 0px; + padding: 0px; +} + +.kv-window .modal-header .modal-title { + white-space: nowrap; +} + +.kv-window .modal-header .window-icon { + margin-right: 6px; +} + +.kv-window .kv-window-icons-container { + display: flex; +} + +.kv-preview-thumb .btn, .kv-zoom-actions .btn, .file-zoom-dialog .floating-buttons .btn { + padding: 5px 8px; +} + +.file-drop-zone.clickable:hover { + border: 1px dashed #999; +} + +.file-drop-zone.clickable:focus { + border: 1px solid #5acde2; +} + +.nav.tabs-top { + flex-wrap: nowrap; +} + +ul.tabs-top { + overflow-x: auto; + overflow-y: hidden; + display: flex; +} + +ul.tabs-top > li { + float:none; + flex-shrink: 0; +} + +.kv-tab-close { + margin-left: 10px; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: 0.2; +} + +.kv-tab-close:hover, .kv-tab-close:focus { + cursor: pointer; + filter: alpha(opacity=50); + opacity: 0.5; +} + +/*select.form-control, .tabulator-row .tabulator-cell.tabulator-editing select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent none no-repeat; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAKCAYAAABblxXYAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wUKFyIn4IjqJgAAAENJREFUKM/l0LERACEQQlGsiTa2px1aokGugNNAx8wfMy8AeLoBALYjaTqoKkga2+gKPgF/2Q7JkEx359oftu+C7/UBCUIcVQz0PvcAAAAASUVORK5CYII='); + background-position: right center; + cursor: pointer; +} + +select.form-control:hover { + background-color: #e6e6e6; +} + +select.form-control option { + background-color: white; +} + +select.input-sm { + line-height: inherit; +}*/ + +.abc-checkbox input[type="checkbox"]:checked+label::after, +.abc-checkbox input[type="radio"]:checked+label::after { + font-family: "Font Awesome 5 Pro", "Font Awesome 5 Free"; + content: "\f00c"; + font-weight: 900; +} + +.abc-checkbox label::before { + top: 0px; +} +.abc-checkbox label::after { + top: 0px; +} + +.abc-radio label::before { + top: 0px; +} + +.abc-radio label::after { + top: 3px; +} + +.abc-checkbox.form-check-inline label::before { + top: 2px; +} + +.abc-checkbox.form-check-inline label::after { + top: 2px; +} + +.abc-radio.form-check-inline label::before { + top: 2px; +} + +.abc-radio.form-check-inline label::after { + top: 5px; +} + +.abc-checkbox label.col-form-label-lg::before { + top: 10px; +} +.abc-checkbox label.col-form-label-lg::after { + top: 10px; +} + +.abc-radio label.col-form-label-lg::before { + top: 10px; +} + +.abc-radio label.col-form-label-lg::after { + top: 13px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::after { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::after { + top: 18px; +} + +/*! + * bootstrap-vertical-tabs - v1.2.2 + * https://dbtek.github.io/bootstrap-vertical-tabs + * 2016-12-02 + * Copyright (c) 2016 İsmail Demirbilek + * License: MIT + */ +.nav-tabs.tabs-left, .nav-tabs.tabs-right { + border-bottom: none; + padding-top: 2px; +} +.nav-tabs.tabs-left { + border-right: 1px solid #dee2e6; +} +.nav-tabs.tabs-right { + border-left: 1px solid #dee2e6; +} +.nav-tabs.tabs-left>li.nav-item, .nav-tabs.tabs-right>li.nav-item { + float: none; + margin-bottom: 2px; +} +.nav-tabs.tabs-left>li.nav-item { + margin-right: -1px; +} +.nav-tabs.tabs-right>li.nav-item { + margin-left: -1px; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:focus { + border-bottom-color: #dee2e6; + border-right-color: transparent; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:focus { + border-bottom: 1px solid #dee2e6; + border-left-color: transparent; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link { + border-radius: 4px 0 0 4px; + margin-right: 0; + display:block; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link { + border-radius: 0 4px 4px 0; + margin-right: 0; +} diff --git a/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/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..35172267 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt @@ -0,0 +1,75 @@ +/* + * 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.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( + "", + 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( + "", + 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/HeaderSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt new file mode 100644 index 00000000..e75baf9e --- /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( + "
  • Test
  • ", + 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..86607ec7 --- /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( + "
  • ", + 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/navbar/NavFormSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt new file mode 100644 index 00000000..40720bcb --- /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( + "
    ", + element?.innerHTML, + "Should render correct nav form" + ) + navf.rightAlign = true + assertEqualsHtml( + "
    ", + 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..988a706d --- /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( + "
      ", + element?.innerHTML, + "Should render correct nav" + ) + nav.rightAlign = true + assertEqualsHtml( + "
        ", + 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..f38a05f9 --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt @@ -0,0 +1,70 @@ +/* + * 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.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( + "", + element?.innerHTML, + "Should render correct navbar" + ) + navbar.inverted = true + assertEqualsHtml( + "", + element?.innerHTML, + "Should render correct inverted navbar" + ) + navbar.add(Nav { + tag(TAG.LI) { + link("Test", "#!/test") + } + }) + assertEqualsHtml( + "", + 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..fcdf9860 --- /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( + "
        abc
        def
        ghi
        ", + 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..9335562f --- /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( + "", + 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( + "", + 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( + "
        abc
        ", + 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")[0]?.click() + val element = document.getElementById("test") + assertEqualsHtml( + "", + 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( + "
        Processing ...
        ", + element?.innerHTML, + "Should render correct progress bar" + ) + progressBar.max = 200 + assertEqualsHtml( + "
        Processing ...
        ", + 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( + "
        ", + element?.innerHTML, + "Should render correct progress bar indicator" + ) + ind.max = 200 + assertEqualsHtml( + "
        ", + 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..b324b8ab --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.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 test.pl.treksoft.kvision.toolbar + +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.toolbar.ButtonGroup +import pl.treksoft.kvision.toolbar.ButtonGroupSize +import pl.treksoft.kvision.toolbar.ButtonGroupStyle +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +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( + "
        ", + element?.innerHTML, + "Should render correct button group" + ) + group.size = ButtonGroupSize.LARGE + group.style = ButtonGroupStyle.JUSTIFIED + assertEqualsHtml( + "
        ", + element?.innerHTML, + "Should render correct button group with large and justified 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( + "
        ", + element?.innerHTML, + "Should render correct toolbar" + ) + } + } + +} 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-datetime/build.gradle b/kvision-modules/kvision-datetime/build.gradle deleted file mode 100644 index b853d2f4..00000000 --- a/kvision-modules/kvision-datetime/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-datetime-picker", "2.4.4") - } - -} diff --git a/kvision-modules/kvision-datetime/package.json.d/project.info b/kvision-modules/kvision-datetime/package.json.d/project.info deleted file mode 100644 index 3d332806..00000000 --- a/kvision-modules/kvision-datetime/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Datetime module" -} 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/DateTime.kt b/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt deleted file mode 100644 index 3d32fd8c..00000000 --- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt +++ /dev/null @@ -1,246 +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 pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.form.DateFormControl -import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn -import kotlin.js.Date - -/** - * Form field date/time chooser component. - * - * @constructor - * @param value date/time input value - * @param name the name attribute of the generated HTML input element - * @param format date/time format (default YYYY-MM-DD HH:mm) - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class DateTime( - value: Date? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), DateFormControl { - - /** - * Date/time input value. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * Date/time format. - */ - var format - get() = input.format - set(value) { - input.format = value - } - /** - * The placeholder for the date/time input. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * Determines if the date/time 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 - } - /** - * 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 - get() = input.daysOfWeekDisabled - set(value) { - input.daysOfWeekDisabled = value - } - /** - * Determines if *Clear* button should be visible. - */ - var clearBtn - get() = input.clearBtn - set(value) { - input.clearBtn = value - } - /** - * Determines if *Today* button should be visible. - */ - var todayBtn - get() = input.todayBtn - set(value) { - input.todayBtn = value - } - /** - * Determines if the current day should be highlighted. - */ - var todayHighlight - get() = input.todayHighlight - set(value) { - input.todayHighlight = value - } - /** - * The increment used to build the hour view. - */ - var minuteStep - get() = input.minuteStep - set(value) { - input.minuteStep = value - } - /** - * Determines if meridian views are visible in day and hour views. - */ - var showMeridian - get() = input.showMeridian - set(value) { - input.showMeridian = value - } - /** - * The label text bound to the 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 - } - - private val idc = "kv_form_time_$counter" - final override val input: DateTimeInput = DateTimeInput(value, format).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 - } - - /** - * Open date/time chooser popup. - */ - open fun showPopup() { - input.showPopup() - } - - /** - * Hides date/time chooser popup. - */ - open fun hidePopup() { - input.hidePopup() - } - - override fun getValueAsString(): String? { - return input.getValueAsString() - } - - 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.dateTime( - value: Date? = null, name: String? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null, - rich: Boolean = false, init: (DateTime.() -> Unit)? = null - ): DateTime { - val dateTime = DateTime(value, name, format, label, rich).apply { init?.invoke(this) } - this.add(dateTime) - return dateTime - } - } -} 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 = setOf() -) : Widget(classes + "form-control"), FormInput { - - private var initialized = false - - init { - this.setInternalEventListener { - 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()) { 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 { - 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 "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 = 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 -*/ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - * Fixes by Michal Remiš - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - * Addtional by Yulian Sutopo - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - * Baekjoon Choi - */ -;(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 - */ - -;(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 - */ - -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - * Tiago Melo - */ -;(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 - */ -;(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ć - */ -;(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ć - */ -;(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 - */ -;(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 - * Fixes by Michal Remiš - */ -;(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 - */ -;(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 - */ -;(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 - * 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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(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 - */ -;(function($){ - $.fn.datetimepicker.dates['zh'] = { - days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"], - daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"], - daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"], - months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], - monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], - today: "今天", - clear: "x", - suffix: [], - meridiem: ["上午", "下午"] - }; -}(jQuery)); diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt deleted file mode 100644 index 13c8531b..00000000 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ /dev/null @@ -1,100 +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 test.pl.treksoft.kvision - -import org.w3c.dom.Element -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.panel.Root -import kotlin.browser.document -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -interface TestSpec { - fun beforeTest() - - fun afterTest() - - fun run(code: () -> Unit) { - beforeTest() - code() - afterTest() - } -} - -interface SimpleSpec : TestSpec { - - override fun beforeTest() { - } - - override fun afterTest() { - } - -} - -interface DomSpec : TestSpec { - - override fun beforeTest() { - val fixture = "
        " + - "
        " - document.body?.insertAdjacentHTML("afterbegin", fixture) - } - - override fun afterTest() { - val div = document.getElementById("pretest") - div?.let { jQuery(it).remove() } - jQuery(".modal-backdrop").remove() - Root.shutdown() - } - - fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { - if (expected != null && actual != null) { - val exp = jQuery(expected) - val act = jQuery(actual) - val result = exp[0]?.isEqualNode(act[0]) - if (result == true) { - assertTrue(result == true, message) - } else { - assertEquals(expected, actual, message) - } - } else { - assertEquals(expected, actual, message) - } - } -} - -interface WSpec : DomSpec { - - fun runW(code: (widget: Widget, element: Element?) -> Unit) { - run { - val root = Root("test", fixed = true) - val widget = Widget() - widget.id = "test_id" - root.add(widget) - val element = document.getElementById("test_id") - code(widget, element) - } - } - -} - -external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt b/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt deleted file mode 100644 index 877cf650..00000000 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt +++ /dev/null @@ -1,53 +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 test.pl.treksoft.kvision.form.time - -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.js.Date -import kotlin.test.Test -import kotlin.test.assertEquals - -class DateTimeInputSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val data = Date() - val dti = DateTimeInput(value = data).apply { - placeholder = "place" - id = "idti" - } - root.add(dti) - val value = dti.getElementJQuery()?.`val`() - assertEquals( - data.toStringF(dti.format), - value, - "Should render date time input with correctly formatted value" - ) - } - } - -} \ No newline at end of file diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt b/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt deleted file mode 100644 index b5e393bb..00000000 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt +++ /dev/null @@ -1,62 +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 test.pl.treksoft.kvision.form.time - -import pl.treksoft.kvision.form.time.DateTime -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 - -class DateTimeSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val data = Date() - val ti = DateTime(value = data, label = "Label").apply { - placeholder = "place" - name = "name" - disabled = true - } - root.add(ti) - val element = document.getElementById("test") - val id = ti.input.id - val datastr = data.toStringF(ti.format) - assertEqualsHtml( - "
        ", - element?.innerHTML, - "Should render correct date time input form control" - ) - ti.validatorError = "Validation Error" - assertEqualsHtml( - "
        Validation Error
        ", - element?.innerHTML, - "Should render correct date time input form control with validation error" - ) - } - } - -} \ No newline at end of file diff --git a/kvision-modules/kvision-datetime/webpack.config.d/css.js b/kvision-modules/kvision-datetime/webpack.config.d/css.js deleted file mode 100644 index 5d710d35..00000000 --- a/kvision-modules/kvision-datetime/webpack.config.d/css.js +++ /dev/null @@ -1,2 +0,0 @@ -config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); - diff --git a/kvision-modules/kvision-dialog/build.gradle b/kvision-modules/kvision-dialog/build.gradle deleted file mode 100644 index 4aaef76d..00000000 --- a/kvision-modules/kvision-dialog/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - 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-dialog/package.json.d/project.info deleted file mode 100644 index 416cd4a7..00000000 --- a/kvision-modules/kvision-dialog/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Dialog module" -} diff --git a/kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt b/kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt deleted file mode 100644 index e67a6f17..00000000 --- a/kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt +++ /dev/null @@ -1,76 +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.modal - -import kotlinx.coroutines.suspendCancellableCoroutine -import pl.treksoft.kvision.core.Widget -import kotlin.coroutines.resume - -/** - * Modal window with a result. - * - * @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 - */ -open class Dialog( - caption: String? = null, closeButton: Boolean = true, - size: ModalSize? = null, animation: Boolean = true, escape: Boolean = true, - classes: Set = setOf(), init: (Dialog.() -> Unit)? = null -) : Modal(caption, closeButton, size, animation, escape, classes) { - - internal var resultCallback: ((R?) -> Unit)? = null - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - /** - * A suspending function returning result value. - */ - suspend fun getResult(): R? = suspendCancellableCoroutine { cont -> - resultCallback = { result -> - resultCallback = null - hide() - cont.resume(result) - } - show() - } - - /** - * A function to be called with a result value. - */ - open fun setResult(result: R?) { - resultCallback?.invoke(result) - } - - override fun hide(): Widget { - resultCallback?.invoke(null) - return super.hide() - } -} 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/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/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-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/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/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 createStore( @@ -72,4 +64,6 @@ internal object KVManagerRedux { } return composeEnhancers(function1, function2) } + + internal fun init() {} } 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/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-select-remote/build.gradle b/kvision-modules/kvision-select-remote/build.gradle deleted file mode 100644 index 739c7a53..00000000 --- a/kvision-modules/kvision-select-remote/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile project(":kvision-modules:kvision-select") - compile project(":kvision-modules:kvision-remote") -} diff --git a/kvision-modules/kvision-select-remote/package.json.d/project.info b/kvision-modules/kvision-select-remote/package.json.d/project.info deleted file mode 100644 index 5685d581..00000000 --- a/kvision-modules/kvision-select-remote/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Select remote addon module" -} diff --git a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt b/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt deleted file mode 100644 index ea9d369b..00000000 --- a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt +++ /dev/null @@ -1,276 +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.select - -import pl.treksoft.kvision.core.Component -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.StringFormControl -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.remote.KVServiceManager -import pl.treksoft.kvision.remote.RemoteOption -import pl.treksoft.kvision.utils.SnOn - -/** - * The form field component for SelectRemote control. - * - * @constructor - * @param value selected value - * @param serviceManager multiplatform service manager - * @param function multiplatform service method returning the list of options - * @param name the name attribute of the generated HTML input element - * @param multiple allows multiple value selection (multiple values are comma delimited) - * @param ajaxOptions additional options for remote data source - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -@Suppress("TooManyFunctions") -open class SelectRemote( - value: String? = null, - serviceManager: KVServiceManager, - function: T.(String?, String?) -> List, - name: String? = null, - multiple: Boolean = false, - ajaxOptions: AjaxOptions? = null, - label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), StringFormControl { - /** - * A value of the selected option. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * Determines if multiple value selection is allowed. - */ - var multiple - get() = input.multiple - set(value) { - input.multiple = value - } - /** - * Maximal number of selected options. - */ - var maxOptions - get() = input.maxOptions - set(value) { - input.maxOptions = value - } - /** - * The placeholder for the select control. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * The style of the select control. - */ - var style - get() = input.style - set(value) { - input.style = value - } - /** - * The width of the select control. - */ - var selectWidth - get() = input.selectWidth - set(value) { - input.selectWidth = value - } - /** - * The width type of the select control. - */ - var selectWidthType - get() = input.selectWidthType - set(value) { - input.selectWidthType = value - } - /** - * Determines if an empty option is automatically generated. - */ - var emptyOption - get() = input.emptyOption - set(value) { - input.emptyOption = value - } - /** - * Determines if the select is automatically focused. - */ - var autofocus - get() = input.autofocus - set(value) { - input.autofocus = value - } - /** - * The label text bound to the select 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 - } - - private val idc = "kv_form_SelectRemote_$counter" - final override val input: SelectRemoteInput = SelectRemoteInput( - value, serviceManager, function, multiple, ajaxOptions, - setOf("form-control") - ).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 add(child: Component): SimplePanel { - input.add(child) - return this - } - - override fun addAll(children: List): SimplePanel { - input.addAll(children) - return this - } - - override fun remove(child: Component): SimplePanel { - input.remove(child) - return this - } - - override fun removeAll(): SimplePanel { - input.removeAll() - return this - } - - override fun getChildren(): List { - return input.getChildren() - } - - /** - * Opens dropdown with options. - */ - open fun showOptions() { - input.showOptions() - } - - /** - * Hides dropdown with options. - */ - open fun hideOptions() { - input.hideOptions() - } - - /** - * Toggles visibility of dropdown with options. - */ - open fun toggleOptions() { - input.toggleOptions() - } - - 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.selectRemote( - value: String? = null, - serviceManager: KVServiceManager, - function: T.(String?, String?) -> List, name: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, - rich: Boolean = false, init: (SelectRemote.() -> Unit)? = null - ): SelectRemote { - val selectRemote = - SelectRemote( - value, - serviceManager, - function, - name, - multiple, - ajaxOptions, - label, - rich - ).apply { init?.invoke(this) } - this.add(selectRemote) - return selectRemote - } - } -} diff --git a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt b/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt deleted file mode 100644 index 4c891d30..00000000 --- a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt +++ /dev/null @@ -1,140 +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.select - -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.asDeferred -import kotlinx.coroutines.launch -import kotlinx.serialization.ImplicitReflectionSerializer -import kotlinx.serialization.list -import kotlinx.serialization.stringify -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.remote.CallAgent -import pl.treksoft.kvision.remote.HttpMethod -import pl.treksoft.kvision.remote.JsonRpcRequest -import pl.treksoft.kvision.remote.KVServiceManager -import pl.treksoft.kvision.remote.RemoteOption -import pl.treksoft.kvision.utils.JSON -import pl.treksoft.kvision.utils.obj - -external fun decodeURIComponent(encodedURI: String): String - -/** - * The Select control connected to the multiplatform service. - * - * @constructor - * @param value selected value - * @param serviceManager multiplatform service manager - * @param function multiplatform service method returning the list of options - * @param multiple allows multiple value selection (multiple values are comma delimited) - * @param ajaxOptions additional options for remote data source - * @param classes a set of CSS class names - */ -@UseExperimental(ImplicitReflectionSerializer::class) -open class SelectRemoteInput( - value: String? = null, - serviceManager: KVServiceManager, - function: T.(String?, String?) -> List, - multiple: Boolean = false, - ajaxOptions: AjaxOptions? = null, - classes: Set = setOf() -) : SelectInput(null, value, multiple, null, classes) { - init { - val (url, method) = - serviceManager.getCalls()[function.toString().replace("\\s".toRegex(), "")] - ?: throw IllegalStateException("Function not specified!") - val data = obj { - q = "{{{q}}}" - } - val tempAjaxOptions = ajaxOptions ?: AjaxOptions() - this.ajaxOptions = tempAjaxOptions.copy(url = url, preprocessData = { - @Suppress("UnsafeCastFromDynamic") - JSON.plain.parse(RemoteOption.serializer().list, it.result as String).map { - obj { - this.value = it.value - if (it.text != null) this.text = it.text - if (it.className != null) this.`class` = it.className - if (it.disabled) this.disabled = true - if (it.divider) this.divider = true - this.data = obj { - if (it.subtext != null) this.subtext = it.subtext - if (it.icon != null) this.icon = it.icon - if (it.content != null) this.content = it.content - } - } - }.toTypedArray() - }, data = data, beforeSend = { _, b -> - @Suppress("UnsafeCastFromDynamic") - val q = decodeURIComponent(b.data.substring(2)) - b.data = JSON.plain.stringify(JsonRpcRequest(0, url, listOf(q, this.value))) - true - }, httpType = HttpType.valueOf(method.name), cache = false, preserveSelected = true) - if (value != null) { - GlobalScope.launch { - val callAgent = CallAgent() - val initials = callAgent.remoteCall( - url, - JSON.plain.stringify(JsonRpcRequest(0, url, listOf(null, value))), - HttpMethod.POST - ).asDeferred().await() - JSON.plain.parse(RemoteOption.serializer().list, initials.result as String).map { - add(SelectOption(it.value, it.text, selected = true)) - } - this@SelectRemoteInput.refreshSelectInput() - } - } - if (this.ajaxOptions?.emptyRequest == true) { - this.setInternalEventListener> { - shownBsSelect = { - val input = self.getElementJQuery()?.parent()?.find("input") - input?.trigger("keyup", null) - input?.hide(0) - } - } - - } - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.selectRemoteInput( - value: String? = null, - serviceManager: KVServiceManager, - function: T.(String?, String?) -> List, - multiple: Boolean = false, - ajaxOptions: AjaxOptions? = null, - classes: Set = setOf(), init: (SelectRemoteInput.() -> Unit)? = null - ): SelectRemoteInput { - val selectRemoteInput = - SelectRemoteInput(value, serviceManager, function, multiple, ajaxOptions, classes).apply { - init?.invoke(this) - } - this.add(selectRemoteInput) - return selectRemoteInput - } - } - -} diff --git a/kvision-modules/kvision-select/build.gradle b/kvision-modules/kvision-select/build.gradle deleted file mode 100644 index f8fcbc8a..00000000 --- a/kvision-modules/kvision-select/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-select", "1.12.4") - dependency("ajax-bootstrap-select", "1.4.3") - } - -} diff --git a/kvision-modules/kvision-select/package.json.d/project.info b/kvision-modules/kvision-select/package.json.d/project.info deleted file mode 100644 index 80e675b0..00000000 --- a/kvision-modules/kvision-select/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Select module" -} diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt deleted file mode 100644 index e2c556c1..00000000 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt +++ /dev/null @@ -1,65 +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 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 { - 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.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") - require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js") - require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js") - require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js") - require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js") - 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.tr-TR.min.js") - } catch (e: Throwable) { - } - -} diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt deleted file mode 100644 index c088f68d..00000000 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt +++ /dev/null @@ -1,140 +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.select - -import pl.treksoft.jquery.JQueryXHR -import pl.treksoft.kvision.KVManagerSelect.AJAX_REQUEST_DELAY -import pl.treksoft.kvision.KVManagerSelect.KVNULL -import pl.treksoft.kvision.i18n.I18n -import pl.treksoft.kvision.utils.obj - -/** - * HTTP protocol type for the AJAX call. - */ -enum class HttpType(internal val type: String) { - GET("GET"), - POST("POST") -} - -/** - * Data type for the AJAX call. - */ -enum class DataType(internal val type: String) { - JSON("json"), - JSONP("jsonp"), - XML("xml"), - TEXT("text"), - SCRIPT("script") -} - -/** - * Data class for AJAX options. - * - * @constructor - * @param url the url address - * @param preprocessData - * [AjaxBootstrapSelect preprocessOption](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionspreprocessdata) - * option - * @param beforeSend - * [JQuery ajax.beforeSend](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option - * @param data - * [JQuery ajax.data](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option - * @param httpType - * [JQuery ajax.type](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option - * @param minLength - * [AjaxBootstrapSelect minLength](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsminlength) option - * @param cache - * [AjaxBootstrapSelect cache](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionscache) option - * @param clearOnEmpty - * [AjaxBootstrapSelect clearOnEmpty](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsclearonempty) option - * @param clearOnError - * [AjaxBootstrapSelect clearOnError](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsclearonerror) option - * @param emptyRequest - * [AjaxBootstrapSelect emptyRequest](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsemptyrequest) option - * @param requestDelay - * [AjaxBootstrapSelect requestDelay](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsrequestdelay) option - * @param restoreOnError - * [AjaxBootstrapSelect restoreOnError](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsrestoreonerror) - * option - */ -data class AjaxOptions( - val url: String? = null, - val preprocessData: ((dynamic) -> dynamic)? = null, - val beforeSend: ((JQueryXHR, dynamic) -> dynamic)? = null, - val data: dynamic = null, - val httpType: HttpType = HttpType.GET, - val dataType: DataType = DataType.JSON, - val minLength: Int = 0, - val cache: Boolean = true, - val clearOnEmpty: Boolean = true, - val clearOnError: Boolean = true, - val emptyRequest: Boolean = false, - val requestDelay: Int = AJAX_REQUEST_DELAY, - val restoreOnError: Boolean = false, - val preserveSelected: Boolean = false, - val processData: Boolean = false -) - -/** - * Convert AjaxOptions to JavaScript JSON object. - * @param emptyOption add an empty position as the first select option - * @return JSON object - */ -fun AjaxOptions.toJs(emptyOption: Boolean): dynamic { - val procData = { data: dynamic -> - val processedData = this.preprocessData?.invoke(data) ?: data - if (emptyOption) { - val ret = mutableListOf(obj { - this.value = KVNULL - this.text = "" - }) - @Suppress("UnsafeCastFromDynamic") - ret.addAll((processedData as Array).asList()) - ret.toTypedArray() - } else { - processedData - } - } - val language = I18n.language - return obj { - this.ajax = obj { - this.url = url ?: "/" - this.method = httpType.type - this.dataType = dataType.type - this.data = data - this.beforeSend = beforeSend - this.contentType = "application/json" - } - this.preprocessData = procData - this.minLength = minLength - this.cache = cache - this.clearOnEmpty = clearOnEmpty - this.clearOnError = clearOnError - this.emptyRequest = emptyRequest - this.preserveSelected = preserveSelected - this.requestDelay = requestDelay - this.restoreOnError = restoreOnError - this.langCode = language - this.processData = processData - this.preserveSelectedOrder = true - } -} diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt deleted file mode 100644 index db8a5b3b..00000000 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt +++ /dev/null @@ -1,285 +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.select - -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.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.form.StringFormControl -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn - -/** - * The form field component for Select control. - * - * The select control can be populated directly from *options* parameter or manually by adding - * [SelectOption] or [SelectOptGroup] components to the container. - * - * @constructor - * @param options an optional list of options (value to label pairs) for the select control - * @param value selected value - * @param name the name attribute of the generated HTML input element - * @param multiple allows multiple value selection (multiple values are comma delimited) - * @param ajaxOptions additional options for remote (AJAX) data source - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -@Suppress("TooManyFunctions") -open class Select( - options: List? = null, value: String? = null, name: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), StringFormControl { - - /** - * A list of options (value to label pairs) for the select control. - */ - var options - get() = input.options - set(value) { - input.options = value - } - /** - * A value of the selected option. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * Determines if multiple value selection is allowed. - */ - var multiple - get() = input.multiple - set(value) { - input.multiple = value - } - /** - * Additional options for remote (AJAX) data source. - */ - var ajaxOptions - get() = input.ajaxOptions - set(value) { - input.ajaxOptions = value - } - /** - * Maximal number of selected options. - */ - var maxOptions - get() = input.maxOptions - set(value) { - input.maxOptions = value - } - /** - * Determines if live search is available. - */ - var liveSearch - get() = input.liveSearch - set(value) { - input.liveSearch = value - } - /** - * The placeholder for the select control. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * The style of the select control. - */ - var style - get() = input.style - set(value) { - input.style = value - } - /** - * The width of the select control. - */ - var selectWidth - get() = input.selectWidth - set(value) { - input.selectWidth = value - } - /** - * The width type of the select control. - */ - var selectWidthType - get() = input.selectWidthType - set(value) { - input.selectWidthType = value - } - /** - * Determines if an empty option is automatically generated. - */ - var emptyOption - get() = input.emptyOption - set(value) { - input.emptyOption = value - } - /** - * Determines if the select is automatically focused. - */ - var autofocus - get() = input.autofocus - set(value) { - input.autofocus = value - } - /** - * The label text bound to the select 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 - } - - private val idc = "kv_form_select_$counter" - final override val input: SelectInput = SelectInput( - options, value, multiple, ajaxOptions, - setOf("form-control") - ).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 add(child: Component): SimplePanel { - input.add(child) - return this - } - - override fun addAll(children: List): SimplePanel { - input.addAll(children) - return this - } - - override fun remove(child: Component): SimplePanel { - input.remove(child) - return this - } - - override fun removeAll(): SimplePanel { - input.removeAll() - return this - } - - override fun getChildren(): List { - return input.getChildren() - } - - /** - * Opens dropdown with options. - */ - open fun showOptions() { - input.showOptions() - } - - /** - * Hides dropdown with options. - */ - open fun hideOptions() { - input.hideOptions() - } - - /** - * Toggles visibility of dropdown with options. - */ - open fun toggleOptions() { - input.toggleOptions() - } - - 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.select( - options: List? = null, value: String? = null, name: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, - rich: Boolean = false, init: (Select.() -> Unit)? = null - ): Select { - val select = Select(options, value, name, multiple, ajaxOptions, label, rich).apply { init?.invoke(this) } - this.add(select) - return select - } - } -} diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt deleted file mode 100644 index e0a49326..00000000 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt +++ /dev/null @@ -1,367 +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.select - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.KVManagerSelect.KVNULL -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.CssSize -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.html.ButtonStyle -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.asString -import pl.treksoft.kvision.utils.obj - -/** - * Select width types. See [Bootstrap Select width](http://silviomoreto.github.io/bootstrap-select/examples/#width). - */ -enum class SelectWidthType(internal val value: String) { - AUTO("auto"), - FIT("fit") -} - -/** - * The basic component for Select control. - * - * The select control can be populated directly from *options* parameter or manually by adding - * [SelectOption] or [SelectOptGroup] components to the container. - * - * @constructor - * @param options an optional list of options (value to label pairs) for the select control - * @param value selected value - * @param multiple allows multiple value selection (multiple values are comma delimited) - * @param ajaxOptions additional options for remote (AJAX) data source - * @param classes a set of CSS class names - */ -@Suppress("TooManyFunctions") -open class SelectInput( - options: List? = null, value: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, - classes: Set = setOf() -) : SimplePanel(classes), FormInput { - - /** - * A list of options (value to label pairs) for the select control. - */ - var options by refreshOnUpdate(options) { setChildrenFromOptions() } - /** - * A value of the selected option. - */ - var value by refreshOnUpdate(value) { refreshState() } - /** - * The name attribute of the generated HTML select element. - */ - override var name: String? by refreshOnUpdate() - /** - * Determines if multiple value selection is allowed. - */ - var multiple by refreshOnUpdate(multiple) - /** - * Additional options for remote (AJAX) data source. - */ - var ajaxOptions by refreshOnUpdate(ajaxOptions) { - if (it != null) { - liveSearch = true - } - refresh() - } - /** - * Maximal number of selected options. - */ - var maxOptions: Int? by refreshOnUpdate() - /** - * Determines if live search is available. - */ - var liveSearch by refreshOnUpdate(false) - /** - * The placeholder for the select control. - */ - var placeholder: String? by refreshOnUpdate() - /** - * The style of the select control. - */ - var style: ButtonStyle? by refreshOnUpdate() - /** - * The width of the select control. - */ - var selectWidth: CssSize? by refreshOnUpdate() - /** - * The width type of the select control. - */ - var selectWidthType: SelectWidthType? by refreshOnUpdate() - /** - * Determines if an empty option is automatically generated. - */ - var emptyOption by refreshOnUpdate(false) { setChildrenFromOptions() } - /** - * Determines if the field is disabled. - */ - override var disabled by refreshOnUpdate(false) - /** - * Determines if the select is automatically focused. - */ - var autofocus: Boolean? by refreshOnUpdate() - /** - * The size of the input. - */ - override var size: InputSize? by refreshOnUpdate() - - init { - setChildrenFromOptions() - this.setInternalEventListener { - change = { - val v = getElementJQuery()?.`val`() - self.value = v?.let { - calculateValue(it) - } - } - } - } - - private fun calculateValue(v: Any): String? { - return if (this.multiple) { - @Suppress("UNCHECKED_CAST") - val arr = v as? Array - if (arr != null && arr.isNotEmpty()) { - arr.filter { it.isNotEmpty() }.joinToString(",") - } else { - null - } - } else { - val vs = v as String - if (KVNULL == vs || vs.isEmpty()) { - null - } else { - vs - } - } - } - - override fun render(): VNode { - return render("select", childrenVNodes()) - } - - override fun add(child: Component): SimplePanel { - super.add(child) - refreshSelectInput() - return this - } - - override fun addAll(children: List): SimplePanel { - super.addAll(children) - refreshSelectInput() - return this - } - - override fun remove(child: Component): SimplePanel { - super.remove(child) - refreshSelectInput() - return this - } - - override fun removeAll(): SimplePanel { - super.removeAll() - refreshSelectInput() - return this - } - - private fun setChildrenFromOptions() { - if (ajaxOptions == null) { - super.removeAll() - if (emptyOption) { - super.add(SelectOption(KVNULL, "")) - } - options?.let { - val c = it.map { - SelectOption(it.first, it.second) - } - super.addAll(c) - } - } - this.refreshSelectInput() - } - - /** - * Opens dropdown with options. - */ - open fun showOptions() { - getElementJQueryD()?.selectpicker("show") - } - - /** - * Hides dropdown with options. - */ - open fun hideOptions() { - getElementJQueryD()?.selectpicker("hide") - } - - /** - * Toggles visibility of dropdown with options. - */ - open fun toggleOptions() { - getElementJQueryD()?.selectpicker("toggle") - } - - override fun getSnClass(): List { - val cl = super.getSnClass().toMutableList() - cl.add("selectpicker" to true) - size?.let { - cl.add(it.className to true) - } - return cl - } - - protected fun refreshSelectInput() { - getElementJQueryD()?.selectpicker("refresh") - refreshState() - getElementJQueryD()?.trigger("change")?.data("AjaxBootstrapSelect")?.list?.cache = {} - } - - @Suppress("ComplexMethod") - override fun getSnAttrs(): List { - val sn = super.getSnAttrs().toMutableList() - name?.let { - sn.add("name" to it) - } - if (multiple) { - sn.add("multiple" to "multiple") - } - maxOptions?.let { - sn.add("data-max-options" to "" + it) - } - if (liveSearch) { - sn.add("data-live-search" to "true") - } - placeholder?.let { - sn.add("title" to translate(it)) - } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - } - val btnStyle = style?.className ?: "btn-default" - when (size) { - InputSize.LARGE -> { - sn.add("data-style" to "$btnStyle btn-lg") - } - InputSize.SMALL -> { - sn.add("data-style" to "$btnStyle btn-sm") - } - else -> { - sn.add("data-style" to btnStyle) - } - } - selectWidthType?.let { - sn.add("data-width" to it.value) - } ?: selectWidth?.let { - sn.add("data-width" to it.asString()) - } - return sn - } - - @Suppress("UnsafeCastFromDynamic") - override fun afterInsert(node: VNode) { - ajaxOptions?.let { - getElementJQueryD()?.selectpicker("render").ajaxSelectPicker(it.toJs(emptyOption)) - } ?: getElementJQueryD()?.selectpicker("render") - - this.getElementJQuery()?.on("show.bs.select") { e, _ -> - this.dispatchEvent("showBsSelect", obj { detail = e }) - } - this.getElementJQuery()?.on("shown.bs.select") { e, _ -> - this.dispatchEvent("shownBsSelect", obj { detail = e }) - } - this.getElementJQuery()?.on("hide.bs.select") { e, _ -> - this.dispatchEvent("hideBsSelect", obj { detail = e }) - } - this.getElementJQuery()?.on("hidden.bs.select") { e, _ -> - this.dispatchEvent("hiddenBsSelect", obj { detail = e }) - } - this.getElementJQuery()?.on("loaded.bs.select") { e, _ -> - this.dispatchEvent("loadedBsSelect", obj { detail = e }) - } - this.getElementJQuery()?.on("rendered.bs.select") { e, _ -> - this.dispatchEvent("renderedBsSelect", obj { detail = e }) - } - this.getElementJQuery()?.on("refreshed.bs.select") { e, _ -> - this.dispatchEvent("refreshedBsSelect", obj { detail = e }) - } - this.getElementJQueryD()?.on("changed.bs.select") { e, cIndex: Int -> - e["clickedIndex"] = cIndex - this.dispatchEvent("changedBsSelect", obj { detail = e }) - } - refreshState() - } - - @Suppress("UnsafeCastFromDynamic") - private fun refreshState() { - if (ajaxOptions == null) { - value?.let { - if (multiple) { - getElementJQueryD()?.selectpicker("val", it.split(",").toTypedArray()) - } else { - getElementJQueryD()?.selectpicker("val", it) - } - } ?: getElementJQueryD()?.selectpicker("val", null) - } - } - - /** - * Makes the input element focused. - */ - override fun focus() { - getElementJQuery()?.focus() - } - - /** - * Makes the input element blur. - */ - override fun blur() { - getElementJQuery()?.blur() - } - - companion object { - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.selectInput( - options: List? = null, value: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, - classes: Set = setOf(), init: (SelectInput.() -> Unit)? = null - ): SelectInput { - val selectInput = SelectInput(options, value, multiple, ajaxOptions, classes).apply { init?.invoke(this) } - this.add(selectInput) - return selectInput - } - } -} diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt deleted file mode 100644 index 3f07a9bf..00000000 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt +++ /dev/null @@ -1,123 +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.select - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.panel.SimplePanel - -/** - * The helper container for adding option groups to [Select]. - * - * The option group can be populated directly from *options* parameter or manually by adding - * [SelectOption] components to the container. - * - * @constructor - * @param label the label of the group - * @param options an optional list of options (label to value pairs) for the group - * @param maxOptions maximal number of selected options in the group - * @param disabled renders a disabled group - * @param classes a set of CSS class names - */ -open class SelectOptGroup( - label: String, options: List? = null, maxOptions: Int? = null, - disabled: Boolean = false, classes: Set = setOf() -) : SimplePanel(classes) { - /** - * A label for the group. - */ - var label by refreshOnUpdate(label) - /** - * A list of options (label to value pairs) for the group. - */ - var options by refreshOnUpdate(options) { setChildrenFromOptions() } - /** - * Maximal number of selected options in the group. - */ - var maxOptions by refreshOnUpdate(maxOptions) - /** - * Determines if the group is disabled. - */ - var disabled by refreshOnUpdate(disabled) - - init { - setChildrenFromOptions() - } - - override fun render(): VNode { - return render("optgroup", childrenVNodes()) - } - - private fun setChildrenFromOptions() { - this.removeAll() - options?.let { - val c = it.map { - SelectOption(it.first, it.second) - } - this.addAll(c) - } - } - - override fun getSnAttrs(): List { - val sn = super.getSnAttrs().toMutableList() - sn.add("label" to translate(label)) - maxOptions?.let { - sn.add("data-max-options" to "" + it) - } - if (disabled) { - sn.add("disabled" to "disabled") - } - return sn - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Select.selectOptGroup( - label: String, options: List? = null, maxOptions: Int? = null, - disabled: Boolean = false, classes: Set = setOf(), init: (SelectOptGroup.() -> Unit)? = null - ): SelectOptGroup { - val selectOptGroup = - SelectOptGroup(label, options, maxOptions, disabled, classes).apply { init?.invoke(this) } - this.add(selectOptGroup) - return selectOptGroup - } - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun SelectInput.selectOptGroup( - label: String, options: List? = null, maxOptions: Int? = null, - disabled: Boolean = false, classes: Set = setOf(), init: (SelectOptGroup.() -> Unit)? = null - ): SelectOptGroup { - val selectOptGroup = - SelectOptGroup(label, options, maxOptions, disabled, classes).apply { init?.invoke(this) } - this.add(selectOptGroup) - return selectOptGroup - } - } -} diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt b/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt deleted file mode 100644 index 3977776b..00000000 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt +++ /dev/null @@ -1,174 +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.select - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.core.Widget - -/** - * The helper component for adding options to [Select] or [SelectOptGroup]. - * - * @constructor - * @param value the value of the option - * @param label the label of the option - * @param subtext the small subtext after the label of the option - * @param icon the icon before the label of the option - * @param divider renders this option as a divider - * @param disabled renders a disabled option - * @param classes a set of CSS class names - */ -open class SelectOption( - value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, - divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, - classes: Set = setOf() -) : Widget(classes) { - - /** - * The value of the option. - */ - var value by refreshOnUpdate(value) - /** - * The label of the option. - */ - var label by refreshOnUpdate(label) - /** - * The subtext after the label of the option. - */ - var subtext by refreshOnUpdate(subtext) - /** - * The icon before the label of the option. - */ - var icon by refreshOnUpdate(icon) - /** - * Determines if the option should be rendered as divider. - */ - var divider by refreshOnUpdate(divider) - /** - * Determines if the option should be disabled. - */ - var disabled by refreshOnUpdate(disabled) - /** - * Determines if the option is selected. - */ - var selected by refreshOnUpdate(selected) - - override fun render(): VNode { - return if (!divider) { - render("option", arrayOf(translate(label) ?: value)) - } else { - render("option") - } - } - - @Suppress("ComplexMethod") - override fun getSnAttrs(): List { - val sn = super.getSnAttrs().toMutableList() - if (!divider) { - value?.let { - sn.add("value" to it) - } - subtext?.let { - 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") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - } - if (selected) { - sn.add("selected" to "selected") - } - } else { - sn.add("data-divider" to "true") - } - return sn - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Select.selectOption( - value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, - divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, - classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null - ): SelectOption { - val selectOption = - SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { - init?.invoke( - this - ) - } - this.add(selectOption) - return selectOption - } - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun SelectInput.selectOption( - value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, - divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, - classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null - ): SelectOption { - val selectOption = - SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { - init?.invoke( - this - ) - } - this.add(selectOption) - return selectOption - } - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun SelectOptGroup.selectOption( - value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, - divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, - classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null - ): SelectOption { - val selectOption = - SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { - init?.invoke( - this - ) - } - this.add(selectOption) - return selectOption - } - - } -} 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js deleted file mode 100644 index 08b38207..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * English translation for the "en-US" and "en" language codes. - * Tobias Weichart - */ -$.fn.ajaxSelectPicker.locale["de-DE"]={currentlySelected:"Momentan ausgewählt",emptyTitle:"Hier klicken und eingeben",errorText:"Ergebnisse konnten nicht abgerufen wurden",searchPlaceholder:"Suche...",statusInitialized:"Suchbegriff eingeben",statusNoResults:"Keine Ergebnisse",statusSearching:"Suche...",statusTooShort:"Der Suchbegriff ist nicht lang genug"},$.fn.ajaxSelectPicker.locale.de=$.fn.ajaxSelectPicker.locale["de-DE"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js deleted file mode 100644 index 8b130b97..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * English translation for the "en-US" and "en" language codes. - * Mark Carver - */ -$.fn.ajaxSelectPicker.locale["en-US"]={currentlySelected:"Currently Selected",emptyTitle:"Select and begin typing",errorText:"Unable to retrieve results",searchPlaceholder:"Search...",statusInitialized:"Start typing a search query",statusNoResults:"No Results",statusSearching:"Searching...",statusTooShort:"Please enter more characters"},$.fn.ajaxSelectPicker.locale.en=$.fn.ajaxSelectPicker.locale["en-US"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js deleted file mode 100644 index bbe3fe45..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Spanish translation for the "es-ES" and "es" language codes. - * Diomedes Domínguez - */ -$.fn.ajaxSelectPicker.locale["es-ES"]={currentlySelected:"Seleccionado",emptyTitle:"Seleccione y comience a escribir",errorText:"No se puede recuperar resultados",searchPlaceholder:"Buscar...",statusInitialized:"Empieza a escribir una consulta de búsqueda",statusNoResults:"Sin Resultados",statusSearching:"Buscando...",statusTooShort:"Introduzca más caracteres"},$.fn.ajaxSelectPicker.locale.es=$.fn.ajaxSelectPicker.locale["es-ES"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js deleted file mode 100644 index 1d86582f..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * French translation for the "fr-FR" and "fr" language codes. - * Bastien (https://github.com/lisurc) - */ -$.fn.ajaxSelectPicker.locale["fr-FR"]={currentlySelected:"Actuellement sélectionné",emptyTitle:"Sélectionner et commencer à taper",errorText:"Impossible de récupérer les résultats",searchPlaceholder:"Rechercher...",statusInitialized:"Commencer à taper une recherche",statusNoResults:"Aucun résultat",statusSearching:"Recherche en cours...",statusTooShort:"Entrez plus de caractères"},$.fn.ajaxSelectPicker.locale.fr=$.fn.ajaxSelectPicker.locale["fr-FR"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js deleted file mode 100644 index b30deb3e..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Italian translation for the "it-IT" and "it" language codes. - * Luca Longo - */ -$.fn.ajaxSelectPicker.locale["it-IT"]={currentlySelected:"Selezionati",emptyTitle:"Clicca qui e scrivi...",errorText:"Impossibile recuperare dei risultati",searchPlaceholder:"Cerca...",statusInitialized:"Inizia a digitare...",statusNoResults:"Non ci sono risultati",statusSearching:"Ricerca in corso...",statusTooShort:"Inserisci altri caratteri"},$.fn.ajaxSelectPicker.locale.it=$.fn.ajaxSelectPicker.locale["it-IT"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js deleted file mode 100644 index 23a9a348..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Japanese translation for the "ja-JP" and "ja" language codes. - * Haginaga - */ -$.fn.ajaxSelectPicker.locale["ja-JP"]={currentlySelected:"現在の値",emptyTitle:"未選択",errorText:"検索できません",searchPlaceholder:"検索する",statusInitialized:"選択肢を入力",statusNoResults:"見つかりません",statusSearching:"検索中...",statusTooShort:"入力文字数不足"},$.fn.ajaxSelectPicker.locale.ja=$.fn.ajaxSelectPicker.locale["ja-JP"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js deleted file mode 100644 index 2fd5299b..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Korean translation for the "ko-KR" and "ko" language codes. - * Jo JungLae - */ -$.fn.ajaxSelectPicker.locale["ko-KR"]={currentlySelected:"현재 선택된 항목",emptyTitle:"클릭하고 입력 시작",errorText:"결과를 검색할 수 없습니다",searchPlaceholder:"검색",statusInitialized:"검색어를 입력",statusNoResults:"검색결과가 없습니다",statusSearching:"검색중",statusTooShort:"추가 문자를 입력하십시오."},$.fn.ajaxSelectPicker.locale.ko=$.fn.ajaxSelectPicker.locale["ko-KR"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js deleted file mode 100644 index 6c6a16f2..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Dutch translation for the "nl-NL" and "nl" language codes. - * Arjen Ruiterkamp - */ -$.fn.ajaxSelectPicker.locale["nl-NL"]={currentlySelected:"Momenteel geselecteerd",emptyTitle:"Selecteer en begin met typen",errorText:"Kon geen resultaten ophalen",searchPlaceholder:"Zoeken...",statusInitialized:"Begin met typen om te zoeken",statusNoResults:"Geen resultaten",statusSearching:"Zoeken...",statusTooShort:"U dient meer karakters in te voeren"},$.fn.ajaxSelectPicker.locale.nl=$.fn.ajaxSelectPicker.locale["nl-NL"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js deleted file mode 100644 index f104f491..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Polish translation for the "pl-PL" and "pl" language codes. - * Robert Jaros - */ -$.fn.ajaxSelectPicker.locale["pl-PL"]={currentlySelected:"Aktualny wybór",emptyTitle:"Wybierz i zacznij pisać",errorText:"Nie można pobrać wyników",searchPlaceholder:"Szukaj...",statusInitialized:"Zacznij pisać warunek wyszukiwania",statusNoResults:"Brak wyników",statusSearching:"Szukam...",statusTooShort:"Wprowadź więcej znaków"},$.fn.ajaxSelectPicker.locale.pl=$.fn.ajaxSelectPicker.locale["pl-PL"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js deleted file mode 100644 index 2a6e743d..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Brazilian portuguese translation for the "pt-BR" and "pt" language codes. - * Luan Fonseca - */ -$.fn.ajaxSelectPicker.locale["pt-BR"]={currentlySelected:"Selecionado Atualmente",emptyTitle:"Clique e comece a digitar",errorText:"Incapaz de encontrar resultados",searchPlaceholder:"Buscar...",statusInitialized:"Comece a digitar",statusNoResults:"Sem Resultados",statusSearching:"Buscando...",statusTooShort:"Digite mais caracteres"},$.fn.ajaxSelectPicker.locale.pt=$.fn.ajaxSelectPicker.locale["pt-BR"];})(jQuery); 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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js deleted file mode 100644 index aa6d4d06..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Russian translation for the "ru-RU" and "ru" language codes. - * Bercut Stray - */ -$.fn.ajaxSelectPicker.locale["ru-RU"]={currentlySelected:"Выбрано",emptyTitle:"Выделите и начните печатать",errorText:"Невозможно получить результат",searchPlaceholder:"Искать...",statusInitialized:"Начните печатать запрос для поиска",statusNoResults:"Нет результатов",statusSearching:"Поиск...",statusTooShort:"Введите еще несколько символов"},$.fn.ajaxSelectPicker.locale.ru=$.fn.ajaxSelectPicker.locale["ru-RU"];})(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-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js deleted file mode 100644 index 6af588f4..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * 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.3 - * @author Adam Heim - https://github.com/truckingsim - * @link https://github.com/truckingsim/Ajax-Bootstrap-Select - * @copyright 2017 Adam Heim - * @license Released under the MIT license. - * - * Contributors: - * Mark Carver - https://github.com/markcarver - * - * Last build: 2017-11-15 1:19:45 PM EST - */ -!(function ($) { -/*! - * Turkish translation for the "tr-TR" and "tr" language codes. - * Burak Çakırel - */ -$.fn.ajaxSelectPicker.locale["tr-TR"]={currentlySelected:"Seçili olanlar",emptyTitle:"Seç ve yazmaya başla",errorText:"Sonuçlar alınamadı",searchPlaceholder:"Ara...",statusInitialized:"Arama için yazmaya başla",statusNoResults:"Sonuç yok",statusSearching:"Aranıyor...",statusTooShort:"Lütfen daha fazla karakter girin"},$.fn.ajaxSelectPicker.locale.tr=$.fn.ajaxSelectPicker.locale["tr-TR"];})(jQuery); diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js b/kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js deleted file mode 100644 index 4428d3c0..00000000 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js +++ /dev/null @@ -1 +0,0 @@ -!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-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt deleted file mode 100644 index 13c8531b..00000000 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ /dev/null @@ -1,100 +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 test.pl.treksoft.kvision - -import org.w3c.dom.Element -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.panel.Root -import kotlin.browser.document -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -interface TestSpec { - fun beforeTest() - - fun afterTest() - - fun run(code: () -> Unit) { - beforeTest() - code() - afterTest() - } -} - -interface SimpleSpec : TestSpec { - - override fun beforeTest() { - } - - override fun afterTest() { - } - -} - -interface DomSpec : TestSpec { - - override fun beforeTest() { - val fixture = "
        " + - "
        " - document.body?.insertAdjacentHTML("afterbegin", fixture) - } - - override fun afterTest() { - val div = document.getElementById("pretest") - div?.let { jQuery(it).remove() } - jQuery(".modal-backdrop").remove() - Root.shutdown() - } - - fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { - if (expected != null && actual != null) { - val exp = jQuery(expected) - val act = jQuery(actual) - val result = exp[0]?.isEqualNode(act[0]) - if (result == true) { - assertTrue(result == true, message) - } else { - assertEquals(expected, actual, message) - } - } else { - assertEquals(expected, actual, message) - } - } -} - -interface WSpec : DomSpec { - - fun runW(code: (widget: Widget, element: Element?) -> Unit) { - run { - val root = Root("test", fixed = true) - val widget = Widget() - widget.id = "test_id" - root.add(widget) - val element = document.getElementById("test_id") - code(widget, element) - } - } - -} - -external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt b/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt deleted file mode 100644 index bfd93900..00000000 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt +++ /dev/null @@ -1,53 +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 test.pl.treksoft.kvision.form.select - -import pl.treksoft.kvision.panel.Root -import pl.treksoft.kvision.form.select.SelectWidthType -import pl.treksoft.kvision.form.select.SelectInput -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test -import kotlin.test.assertTrue - -class SelectInputSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val selectInput = SelectInput(listOf("test1" to "Test 1", "test2" to "Test 2"), "test1", true).apply { - liveSearch = true - placeholder = "Choose ..." - selectWidthType = SelectWidthType.FIT - emptyOption = true - } - root.add(selectInput) - val element = document.getElementById("test") - assertTrue( - true == element?.innerHTML?.endsWith(""), - "Should render correct select input" - ) - } - } - -} \ No newline at end of file diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt b/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt deleted file mode 100644 index 33ccc843..00000000 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt +++ /dev/null @@ -1,54 +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 test.pl.treksoft.kvision.form.select - -import pl.treksoft.kvision.form.select.SelectOptGroup -import pl.treksoft.kvision.form.select.SelectOption -import pl.treksoft.kvision.panel.Root -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test - -class SelectOptGroupSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val selectOptGroup = SelectOptGroup("Group", listOf("test1" to "Test 1", "test2" to "Test 2"), 2) - root.add(selectOptGroup) - val element = document.getElementById("test") - assertEqualsHtml( - "", - element?.innerHTML, - "Should render correct select option group" - ) - selectOptGroup.add(SelectOption("test3", "Test 3")) - assertEqualsHtml( - "", - element?.innerHTML, - "Should render correct select option group with added option" - ) - } - } - -} \ No newline at end of file diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt b/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt deleted file mode 100644 index 33c36576..00000000 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt +++ /dev/null @@ -1,59 +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 test.pl.treksoft.kvision.form.select - -import pl.treksoft.kvision.form.select.SelectOption -import pl.treksoft.kvision.panel.Root -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test - -class SelectOptionSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val selectOption = SelectOption("testValue", "testLabel") - root.add(selectOption) - val element = document.getElementById("test") - assertEqualsHtml( - "", - element?.innerHTML, - "Should render correct select option" - ) - selectOption.icon = "fa-flag" - assertEqualsHtml( - "", - element?.innerHTML, - "Should render correct select option with icon" - ) - selectOption.divider = true - assertEqualsHtml( - "", - element?.innerHTML, - "Should render correct divider option" - ) - } - } - -} \ No newline at end of file diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt b/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt deleted file mode 100644 index 9eddff81..00000000 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt +++ /dev/null @@ -1,58 +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 test.pl.treksoft.kvision.form.select - -import pl.treksoft.kvision.panel.Root -import pl.treksoft.kvision.form.select.SelectWidthType -import pl.treksoft.kvision.form.select.Select -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test -import kotlin.test.assertTrue - -class SelectSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val select = Select(listOf("test1" to "Test 1", "test2" to "Test 2"), "test1", null, true, null, "Label").apply { - liveSearch = true - placeholder = "Choose ..." - selectWidthType = SelectWidthType.FIT - emptyOption = true - } - root.add(select) - val element = document.getElementById("test") - val id = select.input.id - assertTrue( - true == element?.innerHTML?.startsWith("
        "), - "Should render correct select form control" - ) - assertTrue( - true == element?.innerHTML?.endsWith("
        "), - "Should render correct select form control" - ) - } - } - -} \ No newline at end of file diff --git a/kvision-modules/kvision-select/webpack.config.d/css.js b/kvision-modules/kvision-select/webpack.config.d/css.js deleted file mode 100644 index 5d710d35..00000000 --- a/kvision-modules/kvision-select/webpack.config.d/css.js +++ /dev/null @@ -1,2 +0,0 @@ -config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); - diff --git a/kvision-modules/kvision-spinner/build.gradle b/kvision-modules/kvision-spinner/build.gradle deleted file mode 100644 index 0c3a2940..00000000 --- a/kvision-modules/kvision-spinner/build.gradle +++ /dev/null @@ -1,9 +0,0 @@ -apply from: "../shared.gradle" - -kotlinFrontend { - - npm { - dependency("bootstrap-touchspin", "4.2.5") - } - -} diff --git a/kvision-modules/kvision-spinner/package.json.d/project.info b/kvision-modules/kvision-spinner/package.json.d/project.info deleted file mode 100644 index fb0c7956..00000000 --- a/kvision-modules/kvision-spinner/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Spinner module" -} diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt b/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt deleted file mode 100644 index ca4d3764..00000000 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt +++ /dev/null @@ -1,42 +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 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 { - 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) { - } - -} diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt b/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt deleted file mode 100644 index 31c6ceb8..00000000 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt +++ /dev/null @@ -1,263 +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.spinner - -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.NumberFormControl -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn - -/** - * The form field component for spinner control. - * - * @constructor - * @param value spinner value - * @param name the name attribute of the generated HTML input element - * @param min minimal value - * @param max maximal value - * @param step step value (default 1) - * @param decimals number of decimal digits (default 0) - * @param buttonsType spinner buttons type - * @param forceType spinner force rounding type - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -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, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), NumberFormControl { - - /** - * Spinner value. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the spinner input value. - */ - var startValue - get() = input.startValue - set(value) { - input.startValue = value - } - /** - * Minimal value. - */ - var min - get() = input.min - set(value) { - input.min = value - } - /** - * Maximal value. - */ - var max - get() = input.max - set(value) { - input.max = value - } - /** - * Step value. - */ - var step - get() = input.step - set(value) { - input.step = value - } - /** - * Number of decimal digits value. - */ - var decimals - get() = input.decimals - set(value) { - input.decimals = value - } - /** - * Spinner buttons type. - */ - var buttonsType - get() = input.buttonsType - set(value) { - input.buttonsType = value - } - /** - * Spinner force rounding type. - */ - var forceType - get() = input.forceType - set(value) { - input.forceType = value - } - /** - * The placeholder for the spinner input. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * Determines if the spinner is automatically focused. - */ - var autofocus - get() = input.autofocus - set(value) { - input.autofocus = value - } - /** - * Determines if the spinner is read-only. - */ - var readonly - get() = input.readonly - set(value) { - input.readonly = 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_spinner_$counter" - final override val input: SpinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType) - .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() - } - - /** - * Change value in plus. - */ - open fun spinUp(): Spinner { - input.spinUp() - return this - } - - /** - * Change value in minus. - */ - open fun spinDown(): Spinner { - input.spinDown() - return this - } - - 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.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, - 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 - ) - } - 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-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt deleted file mode 100644 index 18df26fa..00000000 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt +++ /dev/null @@ -1,328 +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.spinner - -import com.github.snabbdom.VNode -import pl.treksoft.jquery.JQuery -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.utils.obj - -/** - * Spinner buttons layout types. - */ -enum class ButtonsType { - NONE, - HORIZONTAL, - VERTICAL -} - -/** - * Spinner force rounding types. - */ -enum class ForceType(internal val value: String) { - NONE("none"), - ROUND("round"), - FLOOR("floor"), - CEIL("ceil") -} - -internal const val DEFAULT_STEP = 1.0 - -/** - * The basic component for spinner control. - * - * @constructor - * @param value spinner value - * @param min minimal value - * @param max maximal value - * @param step step value (default 1) - * @param decimals number of decimal digits (default 0) - * @param buttonsType spinner buttons type - * @param forceType spinner force rounding type - * @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, - classes: Set = 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 { - change = { - self.changeValue() - } - } - } - - /** - * Spinner value. - */ - var value by refreshOnUpdate(value) { refreshState() } - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the spinner input value. - */ - var startValue by refreshOnUpdate(value) { this.value = it; refresh() } - /** - * Minimal value. - */ - var min by refreshOnUpdate(min) { refreshSpinner() } - /** - * Maximal value. - */ - var max by refreshOnUpdate(max) { refreshSpinner() } - /** - * Step value. - */ - var step by refreshOnUpdate(step) { refreshSpinner() } - /** - * Number of decimal digits value. - */ - 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 placeholder for the spinner 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) - /** - * Determines if the spinner is automatically focused. - */ - var autofocus: Boolean? by refreshOnUpdate() - /** - * Determines if the spinner is read-only. - */ - var readonly: Boolean? by refreshOnUpdate() - /** - * The size of the input. - */ - override var size: InputSize? by refreshOnUpdate() - - private var siblings: JQuery? = null - - 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 - } - - @Suppress("ComplexMethod") - override fun getSnAttrs(): List { - val sn = super.getSnAttrs().toMutableList() - sn.add("type" to "text") - startValue?.let { - sn.add("value" to it.toString()) - } - 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.toString()) - } - } - return sn - } - - protected open fun changeValue() { - val v = getElementJQuery()?.`val`() as String? - if (v != null && v.isNotEmpty()) { - this.value = v.toDoubleOrNull() - this.value?.let { - if (min != null && it.toInt() < min ?: 0) this.value = min - if (max != null && it.toInt() > max ?: 0) this.value = max - } - } else { - this.value = null - } - } - - @Suppress("UnsafeCastFromDynamic") - override fun afterInsert(node: VNode) { - getElementJQueryD()?.TouchSpin(getSettingsObj()) - siblings = getElementJQuery()?.parent(".bootstrap-touchspin")?.children("span") - this.getElementJQuery()?.on("change") { e, _ -> - if (e.asDynamic().isTrigger != null) { - val event = org.w3c.dom.events.Event("change") - this.getElement()?.dispatchEvent(event) - } - } - this.getElementJQuery()?.on("touchspin.on.min") { e, _ -> - this.dispatchEvent("onMinBsSpinner", obj { detail = e }) - } - this.getElementJQuery()?.on("touchspin.on.max") { e, _ -> - this.dispatchEvent("onMaxBsSpinner", obj { detail = e }) - } - refreshState() - } - - override fun afterDestroy() { - siblings?.remove() - siblings = null - } - - /** - * Returns the value of the spinner as a String. - * @return value as a String - */ - fun getValueAsString(): String? { - return value?.toString() - } - - /** - * Change value in plus. - */ - fun spinUp(): SpinnerInput { - getElementJQueryD()?.trigger("touchspin.uponce") - return this - } - - /** - * Change value in minus. - */ - fun spinDown(): SpinnerInput { - getElementJQueryD()?.trigger("touchspin.downonce") - return this - } - - private fun refreshState() { - value?.let { - getElementJQuery()?.`val`(it.toString()) - } ?: getElementJQueryD()?.`val`(null) - } - - private fun refreshSpinner() { - getElementJQueryD()?.trigger("touchspin.updatesettings", getSettingsObj()) - } - - private fun getSettingsObj(): dynamic { - val verticalbuttons = buttonsType == ButtonsType.VERTICAL || buttonsType == ButtonsType.NONE - return obj { - this.min = min - this.max = max - this.step = step - this.decimals = decimals - this.verticalbuttons = verticalbuttons - this.forcestepdivisibility = forceType.value - if (verticalbuttons) { - this.verticalup = "" - this.verticaldown = "" - } - this.buttondown_class = "btn btn-default" - this.buttonup_class = "btn btn-default" - } - } - - /** - * Makes the input element focused. - */ - override fun focus() { - getElementJQuery()?.focus() - } - - /** - * Makes the input element blur. - */ - override fun blur() { - getElementJQuery()?.blur() - } - - companion object { - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - 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 = setOf(), - init: (SpinnerInput.() -> Unit)? = null - ): SpinnerInput { - val spinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType, 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-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt deleted file mode 100644 index 13c8531b..00000000 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ /dev/null @@ -1,100 +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 test.pl.treksoft.kvision - -import org.w3c.dom.Element -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.panel.Root -import kotlin.browser.document -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -interface TestSpec { - fun beforeTest() - - fun afterTest() - - fun run(code: () -> Unit) { - beforeTest() - code() - afterTest() - } -} - -interface SimpleSpec : TestSpec { - - override fun beforeTest() { - } - - override fun afterTest() { - } - -} - -interface DomSpec : TestSpec { - - override fun beforeTest() { - val fixture = "
        " + - "
        " - document.body?.insertAdjacentHTML("afterbegin", fixture) - } - - override fun afterTest() { - val div = document.getElementById("pretest") - div?.let { jQuery(it).remove() } - jQuery(".modal-backdrop").remove() - Root.shutdown() - } - - fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { - if (expected != null && actual != null) { - val exp = jQuery(expected) - val act = jQuery(actual) - val result = exp[0]?.isEqualNode(act[0]) - if (result == true) { - assertTrue(result == true, message) - } else { - assertEquals(expected, actual, message) - } - } else { - assertEquals(expected, actual, message) - } - } -} - -interface WSpec : DomSpec { - - fun runW(code: (widget: Widget, element: Element?) -> Unit) { - run { - val root = Root("test", fixed = true) - val widget = Widget() - widget.id = "test_id" - root.add(widget) - val element = document.getElementById("test_id") - code(widget, element) - } - } - -} - -external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt b/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt deleted file mode 100644 index 467e48db..00000000 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt +++ /dev/null @@ -1,75 +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 test.pl.treksoft.kvision.form.spinner - -import pl.treksoft.kvision.panel.Root -import pl.treksoft.kvision.form.spinner.SpinnerInput -import test.pl.treksoft.kvision.DomSpec -import kotlin.test.Test -import kotlin.test.assertEquals - -class SpinnerInputSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val si = SpinnerInput(value = 13).apply { - placeholder = "place" - id = "idti" - } - root.add(si) - val value = si.getElementJQuery()?.`val`() - assertEquals("13", value, "Should render spinner input with correct value") - } - } - - @Test - fun spinUp() { - run { - val root = Root("test", fixed = true) - val si = SpinnerInput(value = 13).apply { - placeholder = "place" - id = "idti" - } - root.add(si) - assertEquals(13, si.value, "Should return initial value before spinUp") - si.spinUp() - assertEquals(14, si.value, "Should return changed value after spinUp") - } - } - - @Test - fun spinDown() { - run { - val root = Root("test", fixed = true) - val si = SpinnerInput(value = 13).apply { - placeholder = "place" - id = "idti" - } - root.add(si) - assertEquals(13, si.value, "Should return initial value before spinDown") - si.spinDown() - assertEquals(12, si.value, "Should return changed value after spinDown") - } - } -} \ No newline at end of file diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt b/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt deleted file mode 100644 index 928fe0b1..00000000 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt +++ /dev/null @@ -1,82 +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 test.pl.treksoft.kvision.form.spinner - -import pl.treksoft.kvision.form.spinner.Spinner -import pl.treksoft.kvision.panel.Root -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test -import kotlin.test.assertEquals - -class SpinnerSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val ti = Spinner(value = 13, label = "Label").apply { - placeholder = "place" - name = "name" - disabled = true - } - root.add(ti) - val element = document.getElementById("test") - val id = ti.input.id - assertEqualsHtml( - "
        ", - element?.innerHTML, - "Should render correct spinner input form control" - ) - ti.validatorError = "Validation Error" - assertEqualsHtml( - "
        Validation Error
        ", - element?.innerHTML, - "Should render correct spinner input form control with validation error" - ) - } - } - - @Test - fun spinUp() { - run { - val root = Root("test", fixed = true) - val si = Spinner(value = 13) - root.add(si) - assertEquals(13, si.value, "Should return initial value before spinUp") - si.spinUp() - assertEquals(14, si.value, "Should return changed value after spinUp") - } - } - - @Test - fun spinDown() { - run { - val root = Root("test", fixed = true) - val si = Spinner(value = 13) - root.add(si) - assertEquals(13, si.value, "Should return initial value before spinDown") - si.spinDown() - assertEquals(12, si.value, "Should return changed value after spinDown") - } - } -} \ No newline at end of file diff --git a/kvision-modules/kvision-spinner/webpack.config.d/css.js b/kvision-modules/kvision-spinner/webpack.config.d/css.js deleted file mode 100644 index 5d710d35..00000000 --- a/kvision-modules/kvision-spinner/webpack.config.d/css.js +++ /dev/null @@ -1,2 +0,0 @@ -config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); - diff --git a/kvision-modules/kvision-spinner/webpack.config.d/jquery.js b/kvision-modules/kvision-spinner/webpack.config.d/jquery.js deleted file mode 100644 index bf5a1a20..00000000 --- a/kvision-modules/kvision-spinner/webpack.config.d/jquery.js +++ /dev/null @@ -1,5 +0,0 @@ -config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" -})); 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 2a843308..00000000 --- a/kvision-modules/kvision-upload/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -apply from: "../shared.gradle" - -dependencies { - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" -} - -kotlinFrontend { - - npm { - dependency("bootstrap-fileinput", "4.5.2") - } - -} diff --git a/kvision-modules/kvision-upload/package.json.d/project.info b/kvision-modules/kvision-upload/package.json.d/project.info deleted file mode 100644 index d789d81b..00000000 --- a/kvision-modules/kvision-upload/package.json.d/project.info +++ /dev/null @@ -1,3 +0,0 @@ -{ - "description": "KVision Upload module" -} 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 deleted file mode 100644 index af0950eb..00000000 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt +++ /dev/null @@ -1,86 +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 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 deleted file mode 100644 index 971ce186..00000000 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt +++ /dev/null @@ -1,333 +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.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 - */ - override 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 deleted file mode 100644 index 21073e61..00000000 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt +++ /dev/null @@ -1,367 +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.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()) - if (uploadUrl != null) { - 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 - } ?: listOf() - } - - /** - * 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. - */ - override fun focus() { - getElementJQuery()?.focus() - } - - /** - * Makes the input element blur. - */ - override 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.fileActionSettings = obj { - this.showUpload = showUpload - this.showRemove = showRemove - } - this.language = language - } - } - - companion object { - - /** - * 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 - */ - 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 - */ - 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/kotlin/pl/treksoft/kvision/utils/Utils.kt b/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt deleted file mode 100644 index bdae5091..00000000 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt +++ /dev/null @@ -1,73 +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.utils - -import kotlinx.coroutines.suspendCancellableCoroutine -import org.w3c.files.File -import org.w3c.files.FileReader -import pl.treksoft.kvision.form.Form -import pl.treksoft.kvision.form.FormPanel -import pl.treksoft.kvision.form.KFilesFormControl -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException - -/** - * Suspending extension function to get file content. - * @return file content - */ -suspend fun File.getContent(): String = suspendCancellableCoroutine { cont -> - val reader = FileReader() - reader.onload = { - @Suppress("UnsafeCastFromDynamic") - cont.resume(reader.result) - } - reader.onerror = { e -> - cont.resumeWithException(Exception(e.type)) - } - reader.readAsDataURL(this@getContent) -} - -/** - * Returns current data model with file content read for all KFiles controls. - * @return data model - */ -suspend fun Form.getDataWithFileContent(): K { - val map = this.fields.entries.associateBy({ it.key }, { - val value = it.value - if (value is KFilesFormControl) { - value.getValue()?.map { - it.copy(content = value.getNativeFile(it)?.getContent()) - } - } else { - value.getValue() - } - }) - return this.modelFactory(map.withDefault { null }) -} - -/** - * Returns current data model with file content read for all KFiles controls. - * @return data model - */ -suspend fun FormPanel.getDataWithFileContent(): K { - return this.form.getDataWithFileContent() -} 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 deleted file mode 100644 index 92d32d28..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * 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 deleted file mode 100644 index 5a9c6440..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * 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 deleted file mode 100644 index cf75d1ab..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * 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 deleted file mode 100644 index 16514535..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * 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 deleted file mode 100644 index 685da85d..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * 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 deleted file mode 100644 index f5e8b723..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * 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říliš malý, musí mít velikost nejméně {minSize} KB.', - msgSizeTooLarge: 'Soubor "{name}" ({size} KB) je příliš velký, maximální povolená velikost {maxSize} KB.', - msgFilesTooLess: 'Musíte vybrat nejméně {n} {files} souborů.', - msgFilesTooMany: 'Počet vybraných souborů ({n}) překročil maximální povolený limit {m}.', - msgFileNotFound: 'Soubor "{name}" nebyl nalezen!', - msgFileSecured: 'Zabezpečení souboru znemožnilo číst soubor "{name}".', - msgFileNotReadable: 'Soubor "{name}" není čitelný.', - msgFilePreviewAborted: 'Náhled souboru byl přerušen pro "{name}".', - msgFilePreviewError: 'Nastala chyba při načtení souboru "{name}".', - msgInvalidFileName: 'Neplatné nebo nepovolené znaky ve jménu souboru "{name}".', - msgInvalidFileType: 'Neplatný typ souboru "{name}". Pouze "{types}" souborů jsou podporovány.', - msgInvalidFileExtension: 'Neplatná extenze souboru "{name}". Pouze "{extensions}" souborů jsou podporovány.', - msgFileTypes: { - 'image': 'obrázek', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Nahrávání souboru bylo přerušeno', - msgUploadThreshold: 'Zpracovávám...', - msgUploadBegin: 'Inicializujem...', - msgUploadEnd: 'Hotovo', - msgUploadEmpty: 'Pro nahrávání nejsou k dispozici žádné platné údaje.', - msgUploadError: '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.', - msgSelected: '{n} {files} vybráno', - msgFoldersNotAllowed: 'Táhni a pusť pouze soubory! Vynechané {n} pustěné složk(y).', - msgImageWidthSmall: 'Šířka obrázku "{name}", musí být alespoň {size} px.', - msgImageHeightSmall: 'Výška obrázku "{name}", musí být alespoň {size} px.', - msgImageWidthLarge: 'Šířka obrázku "{name}" nesmí být větší než {size} px.', - msgImageHeightLarge: 'Výška obrázku "{name}" nesmí být větší než {size} px.', - msgImageResizeError: 'Nelze získat rozměry obrázku pro změnu velikosti.', - msgImageResizeException: 'Chyba při změně velikosti obrázku.
        {errors}
        ', - msgAjaxError: 'Došlo k chybě v {operation}. Prosím zkuste to znovu později!', - msgAjaxProgressError: '{operation} - neúspěšné', - ajaxOperations: { - deleteThumb: 'odstranit soubor', - uploadThumb: 'nahrát soubor', - uploadBatch: 'nahrát várku souborů', - uploadExtra: 'odesílání dat formuláře' - }, - dropZoneTitle: 'Přetáhni soubory sem …', - dropZoneClickTitle: '
        (nebo klikni sem a vyber je)', - fileActionSettings: { - removeTitle: 'Odstranit soubor', - uploadTitle: 'Nahrát soubor', - uploadRetryTitle: 'Opakovat nahrávání', - downloadTitle: 'Stáhnout soubor', - zoomTitle: 'Zobrazit podrobnosti', - dragTitle: 'Posunout / Přeskládat', - indicatorNewTitle: 'Ještě nenahrál', - indicatorSuccessTitle: 'Nahraný', - indicatorErrorTitle: 'Chyba nahrávání', - indicatorLoadingTitle: 'Nahrávání ...' - }, - previewZoomButtonTitles: { - prev: 'Zobrazit předchozí soubor', - next: 'Zobrazit následující soubor', - toggleheader: 'Přepnout záhlaví', - fullscreen: 'Přepnout celoobrazovkové zobrazení', - borderless: 'Přepnout bezrámečkové zobrazení', - close: 'Zavřít detailní náhled' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js deleted file mode 100644 index 11a13892..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Danish 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['da'] = { - fileSingle: 'fil', - filePlural: 'filer', - browseLabel: 'Browse …', - removeLabel: 'Fjern', - removeTitle: 'Fjern valgte filer', - cancelLabel: 'Fortryd', - cancelTitle: 'Afbryd nuværende upload', - uploadLabel: 'Upload', - uploadTitle: 'Upload valgte filer', - msgNo: 'Ingen', - msgNoFilesSelected: '', - msgCancelled: 'aflyst', - msgPlaceholder: 'Vælg {files}...', - msgZoomModalHeading: 'Detaljeret visning', - msgFileRequired: 'Du skal vælge en fil at uploade.', - msgSizeTooSmall: 'Fil "{name}" ({size} KB) er for lille og skal være større end {minSize} KB.', - msgSizeTooLarge: 'Fil "{name}" ({size} KB) er større end de tilladte {maxSize} KB.', - msgFilesTooLess: 'Du skal mindst vælge {n} {files} til upload.', - msgFilesTooMany: '({n}) filer valgt til upload, men maks. {m} er tilladt.', - msgFileNotFound: 'Filen "{name}" blev ikke fundet!', - msgFileSecured: 'Sikkerhedsrestriktioner forhindrer læsning af "{name}".', - msgFileNotReadable: 'Filen "{name}" kan ikke indlæses.', - msgFilePreviewAborted: 'Filgennemsyn annulleret for "{name}".', - msgFilePreviewError: 'Der skete en fejl under læsningen af filen "{name}".', - msgInvalidFileName: 'Ugyldige eller ikke-understøttede tegn i filnavn "{name}".', - msgInvalidFileType: 'Ukendt type for filen "{name}". Kun "{types}" kan bruges.', - msgInvalidFileExtension: 'Ukendt filtype for filen "{name}". Kun "{extensions}" filer kan bruges.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Filupload annulleret', - msgUploadThreshold: 'Arbejder...', - msgUploadBegin: 'Initialiserer...', - msgUploadEnd: 'Udført', - msgUploadEmpty: 'Ingen gyldig data tilgængelig til upload.', - msgUploadError: 'Fejl', - msgValidationError: 'Valideringsfejl', - msgLoading: 'Henter fil {index} af {files} …', - msgProgress: 'Henter fil {index} af {files} - {name} - {percent}% færdiggjort.', - msgSelected: '{n} {files} valgt', - msgFoldersNotAllowed: 'Drag & drop kun filer! {n} mappe(r) sprunget over.', - msgImageWidthSmall: 'Bredden af billedet "{name}" skal være på mindst {size} px.', - msgImageHeightSmall: 'Højden af billedet "{name}" skal være på mindst {size} px.', - msgImageWidthLarge: 'Bredden af billedet "{name}" må ikke være over {size} px.', - msgImageHeightLarge: 'Højden af billedet "{name}" må ikke være over {size} px.', - msgImageResizeError: 'Kunne ikke få billedets dimensioner for at ændre størrelsen.', - msgImageResizeException: 'Fejl ved at ændre størrelsen på billedet.
        {errors}
        ', - msgAjaxError: 'Noget gik galt med {operation} operationen. Forsøg venligst senere!', - msgAjaxProgressError: '{operation} fejlede', - ajaxOperations: { - deleteThumb: 'fil slet', - uploadThumb: 'fil upload', - uploadBatch: 'batchfil upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: 'Drag & drop filer her …', - dropZoneClickTitle: '
        (eller klik for at vælge {files})', - fileActionSettings: { - removeTitle: 'Fjern fil', - uploadTitle: 'Upload fil', - uploadRetryTitle: 'Forsåg upload igen', - downloadTitle: 'Download fil', - zoomTitle: 'Se detaljer', - dragTitle: 'Flyt / Omarranger', - indicatorNewTitle: 'Ikke uploadet endnu', - indicatorSuccessTitle: 'Uploadet', - indicatorErrorTitle: 'Upload fejl', - indicatorLoadingTitle: 'Uploader ...' - }, - previewZoomButtonTitles: { - prev: 'Se forrige fil', - next: 'Se næste fil', - toggleheader: 'Skift header', - fullscreen: 'Skift fuld skærm', - borderless: 'Skift grænseløs mode', - close: 'Luk detaljeret visning' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js deleted file mode 100644 index 56ee854b..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js +++ /dev/null @@ -1,98 +0,0 @@ -/*! - * FileInput German 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 - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['de'] = { - fileSingle: 'Datei', - filePlural: 'Dateien', - browseLabel: 'Auswählen …', - removeLabel: 'Löschen', - removeTitle: 'Ausgewählte löschen', - cancelLabel: 'Abbrechen', - cancelTitle: 'Hochladen abbrechen', - uploadLabel: 'Hochladen', - uploadTitle: 'Hochladen der ausgewählten Dateien', - msgNo: 'Keine', - msgNoFilesSelected: 'Keine Dateien ausgewählt', - msgCancelled: 'Abgebrochen', - msgPlaceholder: '{files} auswählen...', - msgZoomModalHeading: 'ausführliche Vorschau', - msgFileRequired: 'Sie müssen eine Datei zum Hochladen auswählen.', - msgSizeTooSmall: 'Datei "{name}" ({size} KB) unterschreitet mindestens notwendige Upload-Größe von {minSize} KB.', - msgSizeTooLarge: 'Datei "{name}" ({size} KB) überschreitet maximal zulässige Upload-Größe von {maxSize} KB.', - msgFilesTooLess: 'Sie müssen mindestens {n} {files} zum Hochladen auswählen.', - msgFilesTooMany: 'Anzahl der zum Hochladen ausgewählten Dateien ({n}), überschreitet maximal zulässige Grenze von {m} Stück.', - msgFileNotFound: 'Datei "{name}" wurde nicht gefunden!', - msgFileSecured: 'Sicherheitseinstellungen verhindern das Lesen der Datei "{name}".', - msgFileNotReadable: 'Die Datei "{name}" ist nicht lesbar.', - msgFilePreviewAborted: 'Dateivorschau abgebrochen für "{name}".', - msgFilePreviewError: 'Beim Lesen der Datei "{name}" ein Fehler aufgetreten.', - msgInvalidFileName: 'Ungültige oder nicht unterstützte Zeichen im Dateinamen "{name}".', - msgInvalidFileType: 'Ungültiger Typ für Datei "{name}". Nur Dateien der Typen "{types}" werden unterstützt.', - msgInvalidFileExtension: 'Ungültige Erweiterung für Datei "{name}". Nur Dateien mit der Endung "{extensions}" werden unterstützt.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Der Datei-Upload wurde abgebrochen', - msgUploadThreshold: 'Wird bearbeitet ...', - msgUploadBegin: 'Wird initialisiert ...', - msgUploadEnd: 'Erledigt', - msgUploadEmpty: 'Keine gültigen Daten zum Hochladen verfügbar.', - msgUploadError: 'Fehler', - msgValidationError: 'Validierungsfehler', - msgLoading: 'Lade Datei {index} von {files} hoch…', - msgProgress: 'Datei {index} von {files} - {name} - zu {percent}% fertiggestellt.', - msgSelected: '{n} {files} ausgewählt', - msgFoldersNotAllowed: 'Drag & Drop funktioniert nur bei Dateien! {n} Ordner übersprungen.', - msgImageWidthSmall: 'Breite der Bilddatei "{name}" muss mindestens {size} px betragen.', - msgImageHeightSmall: 'Höhe der Bilddatei "{name}" muss mindestens {size} px betragen.', - msgImageWidthLarge: 'Breite der Bilddatei "{name}" nicht überschreiten {size} px.', - msgImageHeightLarge: 'Höhe der Bilddatei "{name}" nicht überschreiten {size} px.', - msgImageResizeError: 'Konnte nicht die Bildabmessungen zu ändern.', - msgImageResizeException: 'Fehler beim Ändern der Größe des Bildes.
        {errors}
        ', - msgAjaxError: 'Bei der Aktion {operation} ist ein Fehler aufgetreten. Bitte versuche es später noch einmal!', - msgAjaxProgressError: '{operation} fehlgeschlagen', - ajaxOperations: { - deleteThumb: 'Datei löschen', - uploadThumb: 'Datei hochladen', - uploadBatch: 'Batch-Datei-Upload', - uploadExtra: 'Formular-Datei-Upload' - }, - dropZoneTitle: 'Dateien hierher ziehen …', - dropZoneClickTitle: '
        (oder klicken um {files} auszuwählen)', - fileActionSettings: { - removeTitle: 'Datei entfernen', - uploadTitle: 'Datei hochladen', - uploadRetryTitle: 'Upload erneut versuchen', - downloadTitle: 'Datei herunterladen', - zoomTitle: 'Details anzeigen', - dragTitle: 'Verschieben / Neuordnen', - indicatorNewTitle: 'Noch nicht hochgeladen', - indicatorSuccessTitle: 'Hochgeladen', - indicatorErrorTitle: 'Upload Fehler', - indicatorLoadingTitle: 'Hochladen ...' - }, - previewZoomButtonTitles: { - prev: 'Vorherige Datei anzeigen', - next: 'Nächste Datei anzeigen', - toggleheader: 'Header umschalten', - fullscreen: 'Vollbildmodus umschalten', - borderless: 'Randlosen Modus umschalten', - close: 'Detailansicht schließen' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js deleted file mode 100644 index 170eba1f..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Greek 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['el'] = { - 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: 'Το "{name}" ({size} KB) είναι πολύ μικρό, πρέπει να είναι μεγαλύτερο από {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: 'Μη έγκυροι χαρακτήρες στο όνομα του αρχείου "{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: 'Μεταφόρτωση ...', - 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: '
        (ή πατήστε για επιλογή {files})', - fileActionSettings: { - removeTitle: 'Αφαιρέστε το αρχείο', - uploadTitle: 'Μεταφορτώστε το αρχείο', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'Δείτε λεπτομέρειες', - dragTitle: 'Μετακίνηση/Προσπαρμογή', - indicatorNewTitle: 'Δεν μεταφορτώθηκε ακόμα', - indicatorSuccessTitle: 'Μεταφορτώθηκε', - indicatorErrorTitle: 'Σφάλμα Μεταφόρτωσης', - indicatorLoadingTitle: 'Μεταφόρτωση ...' - }, - previewZoomButtonTitles: { - prev: 'Προηγούμενο αρχείο', - next: 'Επόμενο αρχείο', - toggleheader: 'Εμφάνιση/Απόκρυψη τίτλου', - fullscreen: 'Εναλλαγή πλήρους οθόνης', - borderless: 'Με ή χωρίς πλαίσιο', - close: 'Κλείσιμο προβολής' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js deleted file mode 100644 index 569e7ee5..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Spanish 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['es'] = { - fileSingle: 'archivo', - filePlural: 'archivos', - browseLabel: 'Examinar …', - removeLabel: 'Quitar', - removeTitle: 'Quitar archivos seleccionados', - cancelLabel: 'Cancelar', - cancelTitle: 'Abortar la subida en curso', - uploadLabel: 'Subir archivo', - uploadTitle: 'Subir archivos seleccionados', - msgNo: 'No', - msgNoFilesSelected: 'No hay archivos seleccionados', - msgCancelled: 'Cancelado', - msgPlaceholder: 'Seleccionar {files}...', - msgZoomModalHeading: 'Vista previa detallada', - msgFileRequired: 'Debes seleccionar un archivo para subir.', - msgSizeTooSmall: 'El archivo "{name}" ({size} KB) es demasiado pequeño y debe ser mayor de {minSize} KB.', - msgSizeTooLarge: 'El archivo "{name}" ({size} KB) excede el tamaño máximo permitido de {maxSize} KB.', - msgFilesTooLess: 'Debe seleccionar al menos {n} {files} a cargar.', - msgFilesTooMany: 'El número de archivos seleccionados a cargar ({n}) excede el límite máximo permitido de {m}.', - msgFileNotFound: 'Archivo "{name}" no encontrado.', - msgFileSecured: 'No es posible acceder al archivo "{name}" porque está siendo usado por otra aplicación o no tiene permisos de lectura.', - msgFileNotReadable: 'No es posible acceder al archivo "{name}".', - msgFilePreviewAborted: 'Previsualización del archivo "{name}" cancelada.', - msgFilePreviewError: 'Ocurrió un error mientras se leía el archivo "{name}".', - msgInvalidFileName: 'Caracteres no válidos o no soportados en el nombre del archivo "{name}".', - msgInvalidFileType: 'Tipo de archivo no válido para "{name}". Sólo se permiten archivos de tipo "{types}".', - msgInvalidFileExtension: 'Extensión de archivo no válida para "{name}". Sólo se permiten archivos "{extensions}".', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'La carga de archivos se ha cancelado', - msgUploadThreshold: 'Procesando...', - msgUploadBegin: 'Inicializando...', - msgUploadEnd: 'Hecho', - msgUploadEmpty: 'No existen datos válidos para el envío.', - msgUploadError: 'Error', - msgValidationError: 'Error de validación', - msgLoading: 'Subiendo archivo {index} de {files} …', - msgProgress: 'Subiendo archivo {index} de {files} - {name} - {percent}% completado.', - msgSelected: '{n} {files} seleccionado(s)', - msgFoldersNotAllowed: 'Arrastre y suelte únicamente archivos. Omitida(s) {n} carpeta(s).', - msgImageWidthSmall: 'El ancho de la imagen "{name}" debe ser de al menos {size} px.', - msgImageHeightSmall: 'La altura de la imagen "{name}" debe ser de al menos {size} px.', - msgImageWidthLarge: 'El ancho de la imagen "{name}" no puede exceder de {size} px.', - msgImageHeightLarge: 'La altura de la imagen "{name}" no puede exceder de {size} px.', - msgImageResizeError: 'No se pudieron obtener las dimensiones de la imagen para cambiar el tamaño.', - msgImageResizeException: 'Error al cambiar el tamaño de la imagen.
        {errors}
        ', - 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', - ajaxOperations: { - deleteThumb: 'Archivo borrado', - uploadThumb: 'Archivo subido', - uploadBatch: 'Datos subidos en lote', - uploadExtra: 'Datos del formulario subidos ' - }, - dropZoneTitle: 'Arrastre y suelte aquí los archivos …', - dropZoneClickTitle: '
        (o haga clic para seleccionar {files})', - fileActionSettings: { - removeTitle: 'Eliminar archivo', - uploadTitle: 'Subir archivo', - uploadRetryTitle: 'Reintentar subir', - downloadTitle: 'Descargar archivo', - zoomTitle: 'Ver detalles', - dragTitle: 'Mover / Reordenar', - indicatorNewTitle: 'No subido todavía', - indicatorSuccessTitle: 'Subido', - indicatorErrorTitle: 'Error al subir', - indicatorLoadingTitle: 'Subiendo...' - }, - previewZoomButtonTitles: { - prev: 'Anterior', - next: 'Siguiente', - toggleheader: 'Mostrar encabezado', - fullscreen: 'Pantalla completa', - borderless: 'Modo sin bordes', - close: 'Cerrar vista detallada' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js deleted file mode 100644 index 50b15477..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js +++ /dev/null @@ -1,99 +0,0 @@ -/*! - * FileInput Estonian 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['et'] = { - fileSingle: 'fail', - filePlural: 'failid', - browseLabel: 'Sirvi …', - removeLabel: 'Eemalda', - removeTitle: 'Clear selected files', - cancelLabel: 'Tühista', - cancelTitle: 'Abort ongoing upload', - uploadLabel: 'Salvesta', - uploadTitle: 'Salvesta valitud failid', - msgNo: 'No', - msgNoFilesSelected: 'No files selected', - msgCancelled: 'Cancelled', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Detailed Preview', - msgFileRequired: 'You must select a file to upload.', - msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', - msgSizeTooLarge: 'Fail "{name}" ({size} KB) ületab lubatu suuruse {maxSize} KB.', - msgFilesTooLess: 'You must select at least {n} {files} to upload.', - msgFilesTooMany: 'Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.', - msgFileNotFound: 'File "{name}" not found!', - msgFileSecured: 'Security restrictions prevent reading the file "{name}".', - msgFileNotReadable: 'File "{name}" is not readable.', - msgFilePreviewAborted: 'File preview aborted for "{name}".', - msgFilePreviewError: 'An error occurred while reading the file "{name}".', - msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', - msgInvalidFileType: '"{name}" on vale tüüpi. Ainult "{types}" on lubatud.', - msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'The file upload was aborted', - msgUploadThreshold: 'Processing...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', - msgValidationError: 'Validation Error', - msgLoading: 'Loading file {index} of {files} …', - msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.', - msgSelected: '{n} {files} selected', - msgFoldersNotAllowed: 'Drag & drop files only! Skipped {n} dropped folder(s).', - msgImageWidthSmall: 'Pildi laius peab olema vähemalt {size} px.', - msgImageHeightSmall: 'Pildi kõrgus peab olema vähemalt {size} px.', - msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', - msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', - msgImageResizeError: 'Could not get the image dimensions to resize.', - msgImageResizeException: 'Error while resizing the image.
        {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: 'Lohista failid siia …', - dropZoneClickTitle: '
        (or click to select {files})', - fileActionSettings: { - removeTitle: 'Eemalda fail', - uploadTitle: 'Salvesta fail', - uploadRetryTitle: 'Retry upload', - zoomTitle: 'Vaata detaile', - dragTitle: 'Liiguta / Korralda', - indicatorNewTitle: 'Pole veel salvestatud', - indicatorSuccessTitle: 'Uploaded', - indicatorErrorTitle: 'Salvestamise viga', - indicatorLoadingTitle: 'Salvestan ...' - }, - 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/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js deleted file mode 100644 index 609099c4..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Persian 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 Milad Nekofar - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['fa'] = { - fileSingle: 'فایل', - filePlural: 'فایل‌ها', - browseLabel: 'مرور …', - removeLabel: 'حذف', - removeTitle: 'پاکسازی فایل‌های انتخاب شده', - cancelLabel: 'لغو', - cancelTitle: 'لغو بارگزاری جاری', - uploadLabel: 'بارگذاری', - uploadTitle: 'بارگذاری فایل‌های انتخاب شده', - msgNo: 'نه', - msgNoFilesSelected: 'هیچ فایلی انتخاب نشده است', - msgCancelled: 'لغو شد', - msgPlaceholder: 'انتخاب {files}...', - msgZoomModalHeading: 'نمایش با جزییات', - msgFileRequired: 'شما باید یک فایل برای بارگذاری انتخاب نمایید.', - msgSizeTooSmall: 'فایل "{name}" ({size} کیلوبایت) خیلی کوچک است و باید از {minSize} کیلوبایت بزرگتر باشد.', - msgSizeTooLarge: 'فایل "{name}" ({size} کیلوبایت) از حداکثر مجاز {maxSize} کیلوبایت بزرگتر است.', - msgFilesTooLess: 'شما باید حداقل {n} {files} فایل برای بارگذاری انتخاب کنید.', - msgFilesTooMany: 'تعداد فایل‌های انتخاب شده برای بارگذاری ({n}) از حداکثر مجاز عبور کرده است {m}.', - msgFileNotFound: 'فایل "{name}" یافت نشد!', - msgFileSecured: 'محدودیت های امنیتی مانع خواندن فایل "{name}" است.', - msgFileNotReadable: 'فایل "{name}" قابل نوشتن نیست.', - msgFilePreviewAborted: 'پیش نمایش فایل "{name}". به مشکل خورد', - msgFilePreviewError: 'در هنگام خواندن فایل "{name}" خطایی رخ داد.', - msgInvalidFileName: 'کاراکترهای غیرمجاز و یا ناشناخته در نام فایل "{name}".', - msgInvalidFileType: 'نوع فایل "{name}" معتبر نیست. فقط "{types}" پشیبانی می‌شوند.', - msgInvalidFileExtension: 'پسوند فایل "{name}" معتبر نیست. فقط "{extensions}" پشتیبانی می‌شوند.', - msgFileTypes: { - 'image': 'عکس', - 'html': 'اچ تا ام ال', - 'text': 'متن', - 'video': 'ویدئو', - 'audio': 'صدا', - 'flash': 'فلش', - 'pdf': 'پی دی اف', - 'object': 'دیگر' - }, - msgUploadAborted: 'بارگذاری فایل به مشکل خورد.', - msgUploadThreshold: 'در حال پردازش...', - msgUploadBegin: 'در حال شروع...', - msgUploadEnd: 'انجام شد', - msgUploadEmpty: 'هیچ داده معتبری برای بارگذاری موجود نیست.', - msgUploadError: 'Error', - msgValidationError: 'خطای اعتبار سنجی', - msgLoading: 'بارگیری فایل {index} از {files} …', - msgProgress: 'بارگیری فایل {index} از {files} - {name} - {percent}% تمام شد.', - msgSelected: '{n} {files} انتخاب شده', - msgFoldersNotAllowed: 'فقط فایل‌ها را بکشید و رها کنید! {n} پوشه نادیده گرفته شد.', - msgImageWidthSmall: 'عرض فایل تصویر "{name}" باید حداقل {size} پیکسل باشد.', - msgImageHeightSmall: 'ارتفاع فایل تصویر "{name}" باید حداقل {size} پیکسل باشد.', - msgImageWidthLarge: 'عرض فایل تصویر "{name}" نمیتواند از {size} پیکسل بیشتر باشد.', - msgImageHeightLarge: 'ارتفاع فایل تصویر "{name}" نمی‌تواند از {size} پیکسل بیشتر باشد.', - msgImageResizeError: 'یافت نشد ابعاد تصویر را برای تغییر اندازه.', - msgImageResizeException: 'خطا در هنگام تغییر اندازه تصویر.
        {errors}
        ', - msgAjaxError: 'به نظر مشکلی در حین {operation} روی داده است. لطفا دوباره تلاش کنید!', - msgAjaxProgressError: '{operation} لغو شد', - ajaxOperations: { - deleteThumb: 'حذف فایل', - uploadThumb: 'بارگذاری فایل', - uploadBatch: 'بارگذاری جمعی فایلها', - uploadExtra: 'بارگذاری با کمک فُرم' - }, - dropZoneTitle: 'فایل‌ها را بکشید و در اینجا رها کنید …', - dropZoneClickTitle: '
        (یا برای انتخاب {files} کلیک کنید)', - fileActionSettings: { - removeTitle: 'حذف فایل', - uploadTitle: 'آپلود فایل', - uploadRetryTitle: 'بارگیری مجدد', - downloadTitle: 'دریافت فایل', - zoomTitle: 'دیدن جزئیات', - dragTitle: 'جابجایی / چیدمان', - indicatorNewTitle: 'آپلود نشده است', - indicatorSuccessTitle: 'آپلود شده', - indicatorErrorTitle: 'بارگذاری خطا', - indicatorLoadingTitle: 'آپلود ...' - }, - previewZoomButtonTitles: { - prev: 'مشاهده فایل قبلی', - next: 'مشاهده فایل بعدی', - toggleheader: 'نمایش عنوان', - fullscreen: 'نمایش تمام صفحه', - borderless: 'نمایش حاشیه', - close: 'بستن نمایش با جزییات' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js deleted file mode 100644 index 19317b54..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js +++ /dev/null @@ -1,91 +0,0 @@ -/*! - * FileInput Finnish 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.fi = { - fileSingle: 'tiedosto', - filePlural: 'tiedostot', - browseLabel: 'Selaa …', - removeLabel: 'Poista', - removeTitle: 'Tyhjännä valitut tiedostot', - cancelLabel: 'Peruuta', - cancelTitle: 'Peruuta lataus', - uploadLabel: 'Lataa', - uploadTitle: 'Lataa valitut tiedostot', - msgNoFilesSelected: '', - msgFileRequired: 'You must select a file to upload.', - msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', - msgSizeTooLarge: 'Tiedosto "{name}" ({size} Kt) ylittää suurimman sallitun tiedoston koon, joka on {maxSize} Kt. Yritä uudelleen!', - msgFilesTooLess: 'Vähintään {n} {files} tiedostoa on valittava ladattavaksi. Ole hyvä ja yritä uudelleen!', - msgFilesTooMany: 'Valittujen tiedostojen lukumäärä ({n}) ylittää suurimman sallitun määrän {m}. Ole hyvä ja yritä uudelleen!', - msgFileNotFound: 'Tiedostoa "{name}" ei löydy!', - msgFileSecured: 'Tietoturvarajoitukset estävät tiedoston "{name}" lukemisen.', - msgFileNotReadable: 'Tiedosto "{name}" ei ole luettavissa.', - msgFilePreviewAborted: 'Tiedoston "{name}" esikatselu keskeytetty.', - msgFilePreviewError: 'Virhe on tapahtunut luettaessa tiedostoa "{name}".', - msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', - msgInvalidFileType: 'Tiedosto "{name}" on väärän tyyppinen. Ainoastaan tiedostot tyyppiä "{types}" ovat tuettuja.', - msgInvalidFileExtension: 'Tiedoston "{name}" tarkenne on epäkelpo. Ainoastaan tarkenteet "{extensions}" ovat tuettuja.', - msgFileTypes: { - 'image': 'Kuva', - 'html': 'HTML', - 'text': 'Teksti', - 'video': 'Video', - 'audio': 'Ääni', - 'flash': 'Flash', - 'pdf': 'PDF', - 'object': 'Olio' - }, - msgUploadThreshold: 'Käsitellään...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'Ei ladattavaa dataa.', - msgUploadError: 'Error', - msgValidationError: 'Tiedoston latausvirhe', - msgLoading: 'Ladataan tiedostoa {index} / {files} …', - msgProgress: 'Ladataan tiedostoa {index} / {files} - {name} - {percent}% valmistunut.', - msgSelected: '{n} tiedostoa valittu', - 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', - ajaxOperations: { - deleteThumb: 'file delete', - uploadThumb: 'file upload', - uploadBatch: 'batch file upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: 'Raahaa ja pudota tiedostot tähän …', - dropZoneClickTitle: '
        (tai valitse hiirellä {files})', - fileActionSettings: { - removeTitle: 'Poista tiedosto', - uploadTitle: 'Upload file', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'Yksityiskohdat', - dragTitle: 'Siirrä / Järjestele', - indicatorNewTitle: 'Ei ladattu', - indicatorSuccessTitle: 'Ladattu', - indicatorErrorTitle: 'Lataus epäonnistui', - indicatorLoadingTitle: 'Ladataan ...' - }, - previewZoomButtonTitles: { - prev: 'Seuraava tiedosto', - next: 'Edellinen tiedosto', - toggleheader: 'Näytä otsikko', - fullscreen: 'Kokonäytön tila', - borderless: 'Rajaton tila', - close: 'Sulje esikatselu' - } - }; - - $.extend($.fn.fileinput.defaults, $.fn.fileinputLocales.fi); -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js deleted file mode 100644 index 81a77042..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js +++ /dev/null @@ -1,99 +0,0 @@ -/*! - * FileInput French 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['fr'] = { - fileSingle: 'fichier', - filePlural: 'fichiers', - browseLabel: 'Parcourir…', - removeLabel: 'Retirer', - removeTitle: 'Retirer les fichiers sélectionnés', - cancelLabel: 'Annuler', - cancelTitle: "Annuler l'envoi en cours", - uploadLabel: 'Transférer', - uploadTitle: 'Transférer les fichiers sélectionnés', - msgNo: 'Non', - msgNoFilesSelected: '', - msgCancelled: 'Annulé', - msgPlaceholder: 'Sélectionner le(s) {files}...', - msgZoomModalHeading: 'Aperçu détaillé', - msgFileRequired: 'Vous devez sélectionner un fichier à uploader.', - msgSizeTooSmall: 'Le fichier "{name}" ({size} KB) est inférieur à la taille minimale de {minSize} KB.', - msgSizeTooLarge: 'Le fichier "{name}" ({size} Ko) dépasse la taille maximale autorisée qui est de {maxSize} Ko.', - msgFilesTooLess: 'Vous devez sélectionner au moins {n} {files} à transmettre.', - msgFilesTooMany: 'Le nombre de fichier sélectionné ({n}) dépasse la quantité maximale autorisée qui est de {m}.', - msgFileNotFound: 'Le fichier "{name}" est introuvable !', - msgFileSecured: "Des restrictions de sécurité vous empêchent d'accéder au fichier \"{name}\".", - msgFileNotReadable: 'Le fichier "{name}" est illisible.', - msgFilePreviewAborted: 'Prévisualisation du fichier "{name}" annulée.', - msgFilePreviewError: 'Une erreur est survenue lors de la lecture du fichier "{name}".', - msgInvalidFileName: 'Caractères invalides ou non supportés dans le nom de fichier "{name}".', - msgInvalidFileType: 'Type de document invalide pour "{name}". Seulement les documents de type "{types}" sont autorisés.', - msgInvalidFileExtension: 'Extension invalide pour le fichier "{name}". Seules les extensions "{extensions}" sont autorisées.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Le transfert du fichier a été interrompu', - msgUploadThreshold: 'En cours...', - msgUploadBegin: 'Initialisation...', - msgUploadEnd: 'Terminé', - msgUploadEmpty: 'Aucune donnée valide disponible pour transmission.', - msgUploadError: 'Erreur', - msgValidationError: 'Erreur de validation', - msgLoading: 'Transmission du fichier {index} sur {files}…', - msgProgress: 'Transmission du fichier {index} sur {files} - {name} - {percent}%.', - msgSelected: '{n} {files} sélectionné(s)', - msgFoldersNotAllowed: 'Glissez et déposez uniquement des fichiers ! {n} répertoire(s) exclu(s).', - msgImageWidthSmall: 'La largeur de l\'image "{name}" doit être d\'au moins {size} px.', - msgImageHeightSmall: 'La hauteur de l\'image "{name}" doit être d\'au moins {size} px.', - msgImageWidthLarge: 'La largeur de l\'image "{name}" ne peut pas dépasser {size} px.', - msgImageHeightLarge: 'La hauteur de l\'image "{name}" ne peut pas dépasser {size} px.', - msgImageResizeError: "Impossible d'obtenir les dimensions de l'image à redimensionner.", - msgImageResizeException: "Erreur lors du redimensionnement de l'image.
        {errors}
        ", - msgAjaxError: "Une erreur s'est produite pendant l'opération de {operation}. Veuillez réessayer plus tard.", - msgAjaxProgressError: 'L\'opération "{operation}" a échoué', - ajaxOperations: { - deleteThumb: 'suppression du fichier', - uploadThumb: 'transfert du fichier', - uploadBatch: 'transfert des fichiers', - uploadExtra: 'soumission des données de formulaire' - }, - dropZoneTitle: 'Glissez et déposez les fichiers ici…', - dropZoneClickTitle: '
        (ou cliquez pour sélectionner manuellement)', - fileActionSettings: { - removeTitle: 'Supprimer le fichier', - uploadTitle: 'Transférer le fichier', - uploadRetryTitle: 'Relancer le transfert', - zoomTitle: 'Voir les détails', - dragTitle: 'Déplacer / Réarranger', - indicatorNewTitle: 'Pas encore transféré', - indicatorSuccessTitle: 'Posté', - indicatorErrorTitle: 'Ajouter erreur', - indicatorLoadingTitle: 'En cours...' - }, - previewZoomButtonTitles: { - prev: 'Voir le fichier précédent', - next: 'Voir le fichier suivant', - toggleheader: 'Masquer le titre', - fullscreen: 'Mode plein écran', - borderless: 'Mode cinéma', - close: "Fermer l'aperçu" - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js deleted file mode 100644 index a2ba90be..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Galician 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['gl'] = { - fileSingle: 'arquivo', - filePlural: 'arquivos', - browseLabel: 'Examinar …', - removeLabel: 'Quitar', - removeTitle: 'Quitar aquivos seleccionados', - cancelLabel: 'Cancelar', - cancelTitle: 'Abortar a subida en curso', - uploadLabel: 'Subir arquivo', - uploadTitle: 'Subir arquivos seleccionados', - msgNo: 'Non', - msgNoFilesSelected: 'Non hay arquivos seleccionados', - msgCancelled: 'Cancelado', - msgPlaceholder: 'Seleccinar {files}...', - msgZoomModalHeading: 'Vista previa detallada', - msgFileRequired: 'Debes seleccionar un arquivo para subir.', - msgSizeTooSmall: 'O arquivo "{name}" ({size} KB) é demasiado pequeno e debe ser maior de {minSize} KB.', - msgSizeTooLarge: 'O arquivo "{name}" ({size} KB) excede o tamaño máximo permitido de {maxSize} KB.', - msgFilesTooLess: 'Debe seleccionar ao menos {n} {files} a cargar.', - msgFilesTooMany: 'O número de arquivos seleccionados a cargar ({n}) excede do límite máximo permitido de {m}.', - msgFileNotFound: 'Arquivo "{name}" non encontrado.', - msgFileSecured: 'Non é posible acceder ao arquivo "{name}" porque estará sendo usado por outra aplicación ou non teñamos permisos de lectura.', - msgFileNotReadable: 'Non é posible acceder ao arquivo "{name}".', - msgFilePreviewAborted: 'Previsualización do arquivo "{name}" cancelada.', - msgFilePreviewError: 'Ocurriu un erro mentras se lía o arquivo "{name}".', - msgInvalidFileName: 'Caracteres non válidos ou non soportados no nome do arquivo "{name}".', - msgInvalidFileType: 'Tipo de arquivo non válido para "{name}". Só se permiten arquivos do tipo "{types}".', - msgInvalidFileExtension: 'Extensión de arquivo non válida para "{name}". Só se permiten arquivos "{extensions}".', - msgFileTypes: { - 'image': 'imaxe', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'A carga de arquivos cancelouse', - msgUploadThreshold: 'Procesando...', - msgUploadBegin: 'Inicializando...', - msgUploadEnd: 'Feito', - msgUploadEmpty: 'Non existen datos válidos para o envío.', - msgUploadError: 'Erro', - msgValidationError: 'Erro de validación', - msgLoading: 'Subindo arquivo {index} de {files} …', - msgProgress: 'Subindo arquivo {index} de {files} - {name} - {percent}% completado.', - msgSelected: '{n} {files} seleccionado(s)', - msgFoldersNotAllowed: 'Arrastra e solta unicamente arquivos. Omitida(s) {n} carpeta(s).', - msgImageWidthSmall: 'O ancho da imaxe "{name}" debe ser de ao menos {size} px.', - msgImageHeightSmall: 'A altura da imaxe "{name}" debe ser de ao menos {size} px.', - msgImageWidthLarge: 'O ancho da imaxe "{name}" non pode exceder de {size} px.', - msgImageHeightLarge: 'A altura da imaxe "{name}" non pode exceder de {size} px.', - msgImageResizeError: 'Non se puideron obter as dimensións da imaxe para cambiar o tamaño.', - msgImageResizeException: 'Erro ao cambiar o tamaño da imaxe.
        {errors}
        ', - msgAjaxError: 'Algo foi mal ca operación {operation}. Por favor, inténtao de novo máis tarde.', - msgAjaxProgressError: 'A operación {operation} fallou', - ajaxOperations: { - deleteThumb: 'Arquivo borrado', - uploadThumb: 'Arquivo subido', - uploadBatch: 'Datos subidos en lote', - uploadExtra: 'Datos do formulario subidos' - }, - dropZoneTitle: 'Arrasta e solta aquí os arquivos …', - dropZoneClickTitle: '
        (ou fai clic para seleccionar {files})', - fileActionSettings: { - removeTitle: 'Eliminar arquivo', - uploadTitle: 'Subir arquivo', - uploadRetryTitle: 'Reintentar a subida', - downloadTitle: 'Descargar arquivo', - zoomTitle: 'Ver detalles', - dragTitle: 'Mover / Reordenar', - indicatorNewTitle: 'Non subido aínda', - indicatorSuccessTitle: 'Subido', - indicatorErrorTitle: 'Erro ao subir', - indicatorLoadingTitle: 'Subindo...' - }, - previewZoomButtonTitles: { - prev: 'Ver arquivo anterior', - next: 'Ver arquivo seguinte', - toggleheader: 'Mostrar encabezado', - fullscreen: 'Mostrar a pantalla completa', - borderless: 'Activar o modo sen bordes', - close: 'Cerrar vista detallada' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js deleted file mode 100644 index cea7de35..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js +++ /dev/null @@ -1,97 +0,0 @@ -/*! - * FileInput Hebrew 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 Daniel Coryat - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['he'] = { - fileSingle: 'קובץ', - filePlural: 'קבצים', - browseLabel: 'העלאה …', - removeLabel: 'הסרה', - removeTitle: 'נקה קבצים נבחרים', - cancelLabel: 'ביטול', - cancelTitle: 'ביטול העלאה מתמשכת', - uploadLabel: 'טעינה', - uploadTitle: 'טעינת קבצים נבחרים', - msgNo: 'לא', - msgNoFilesSelected: 'לא נבחרו קבצים', - msgCancelled: 'מבוטל', - msgPlaceholder: 'בחר {files}...', - msgZoomModalHeading: 'תצוגה מקדימה מפורטת', - msgSizeTooSmall: 'קובץ "{name}" ({size} KB) קטן מדי וחייב להיות גדול מ {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: 'תווים לא חוקיים או לא נתמכים בשם הקובץ "{name}".', - msgInvalidFileType: 'סוג קובץ לא חוקי "{name}". רק "{types}" קבצים נתמכים.', - msgInvalidFileExtension: 'תוסף לא חוקי עבור הקובץ "{name}". רק "{extensions}" קבצים נתמכים.', - msgFileTypes: { - 'image': 'תמונה', - 'html': 'HTML', - 'text': 'טקסט', - 'video': 'וידאו', - 'audio': 'שמע', - 'flash': 'פלאש', - 'pdf': 'PDF', - 'object': 'אובייקט' - }, - msgUploadAborted: 'העלאת הקובץ בוטלה', - msgUploadThreshold: 'מעבד...', - msgUploadBegin: 'מאתחל ...', - msgUploadEnd: 'בוצע', - msgUploadEmpty: 'אין נתונים זמינים להעלאה.', - msgValidationError: 'שגיאת אימות', - msgLoading: 'טוען קובץ {index} של {files} …', - msgProgress: 'טוען קובץ {index} של {files} - {name} - {percent}% הושלמה.', - msgSelected: '{n} {files} נבחרו', - msgFoldersNotAllowed: 'גרירת קבצים ושחרורם בלבד! דילוג {n} גרירת תיקיה(s).', - msgImageWidthSmall: 'רוחב קובץ התמונה "{name}" חייב להיות לפחות {size} px.', - msgImageHeightSmall: 'גובה קובץ התמונה "{name}" חייב להיות לפחות {size} px.', - msgImageWidthLarge: 'רוחב קובץ התמונה "{name}" לא יעלה על {size} px.', - msgImageHeightLarge: 'גובה קובץ התמונה "{name}" לא יעלה על {size} px.', - msgImageResizeError: 'לא ניתן לשנות את גודל מידות התמונה.', - msgImageResizeException: 'שגיאה בעת שינוי גודל התמונה.
        {errors}
        ', - msgAjaxError: 'משהו השתבש עם {operation} המערכת. יש לנסות מאוחר יותר!', - msgAjaxProgressError: '{operation} נכשל', - ajaxOperations: { - deleteThumb: 'קובץ נמחק', - uploadThumb: 'קובץ הועלה', - uploadBatch: 'קובץ אצווה הועלה', - uploadExtra: 'העלאת נתונים בטופס' - }, - dropZoneTitle: 'גרירת קבצים ושחרורם כאן …', - dropZoneClickTitle: '
        (או לחץ /י כדי לבחור {files})', - fileActionSettings: { - removeTitle: 'הסרת קובץ', - uploadTitle: 'טעינת קובץ', - zoomTitle: 'הצגת פרטים', - dragTitle: 'העברה / סידור מחדש', - indicatorNewTitle: 'עדיין לא הועלה', - indicatorSuccessTitle: 'הועלה', - indicatorErrorTitle: 'שגיאת העלאה', - indicatorLoadingTitle: 'מעלה...' - }, - previewZoomButtonTitles: { - prev: 'הצגת את הקובץ הקודם', - next: 'הצגת את הקובץ הבא', - toggleheader: 'שינוי כותרת', - fullscreen: 'מעבר למסך מלא', - borderless: 'שינוי המודל ללא שוליים', - close: 'סגירת תצוגה מקדימה מפורטת' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js deleted file mode 100644 index 534815fb..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Hungarian 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['hu'] = { - fileSingle: 'fájl', - filePlural: 'fájlok', - browseLabel: 'Tallóz …', - removeLabel: 'Eltávolít', - removeTitle: 'Kijelölt fájlok törlése', - cancelLabel: 'Mégse', - cancelTitle: 'Feltöltés megszakítása', - uploadLabel: 'Feltöltés', - uploadTitle: 'Kijelölt fájlok feltöltése', - msgNo: 'Nem', - msgNoFilesSelected: 'Nincs fájl kiválasztva', - msgCancelled: 'Megszakítva', - msgPlaceholder: 'Válasz {files}...', - msgZoomModalHeading: 'Részletes Előnézet', - msgFileRequired: 'Kötelező fájlt kiválasztani a feltöltéshez.', - msgSizeTooSmall: 'A fájl: "{name}" ({size} KB) mérete túl kicsi, nagyobbnak kell lennie, mint {minSize} KB.', - msgSizeTooLarge: '"{name}" fájl ({size} KB) mérete nagyobb a megengedettnél {maxSize} KB.', - msgFilesTooLess: 'Legalább {n} {files} ki kell választania a feltöltéshez.', - msgFilesTooMany: 'A feltölteni kívánt fájlok száma ({n}) elérte a megengedett maximumot {m}.', - msgFileNotFound: '"{name}" fájl nem található!', - msgFileSecured: 'Biztonsági beállítások nem engedik olvasni a fájlt "{name}".', - msgFileNotReadable: '"{name}" fájl nem olvasható.', - msgFilePreviewAborted: '"{name}" fájl feltöltése megszakítva.', - msgFilePreviewError: 'Hiba lépett fel a "{name}" fájl olvasása közben.', - msgInvalidFileName: 'Hibás vagy nem támogatott karakterek a fájl nevében "{name}".', - msgInvalidFileType: 'Nem megengedett fájl "{name}". Csak a "{types}" fájl típusok támogatottak.', - msgInvalidFileExtension: 'Nem megengedett kiterjesztés / fájltípus "{name}". Csak a "{extensions}" kiterjesztés(ek) / fájltípus(ok) támogatottak.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'A fájl feltöltés megszakítva', - msgUploadThreshold: 'Folyamatban...', - msgUploadBegin: 'Inicializálás...', - msgUploadEnd: 'Kész', - msgUploadEmpty: 'Nincs érvényes adat a feltöltéshez.', - msgUploadError: 'Error', - msgValidationError: 'Érvényesítés hiba', - msgLoading: '{index} / {files} töltése …', - msgProgress: 'Feltöltés: {index} / {files} - {name} - {percent}% kész.', - msgSelected: '{n} {files} kiválasztva.', - msgFoldersNotAllowed: 'Csak fájlokat húzzon ide! Kihagyva {n} könyvtár.', - msgImageWidthSmall: 'A kép szélességének "{name}" legalább {size} pixelnek kell lennie.', - msgImageHeightSmall: 'A kép magasságának "{name}" legalább {size} pixelnek kell lennie.', - msgImageWidthLarge: 'A kép szélessége "{name}" nem haladhatja meg a {size} pixelt.', - msgImageHeightLarge: 'A kép magassága "{name}" nem haladhatja meg a {size} pixelt.', - msgImageResizeError: 'Nem lehet megállapítani a kép méreteit az átméretezéshez.', - msgImageResizeException: 'Hiba történt a méretezés közben.
        {errors}
        ', - msgAjaxError: 'Hiba történt a művelet közben ({operation}). Kérjük, próbálja később!', - msgAjaxProgressError: 'Hiba! ({operation})', - ajaxOperations: { - deleteThumb: 'fájl törlés', - uploadThumb: 'fájl feltöltés', - uploadBatch: 'csoportos fájl feltöltés', - uploadExtra: 'űrlap adat feltöltés' - }, - dropZoneTitle: 'Húzzon ide fájlokat …', - dropZoneClickTitle: '
        (vagy kattintson ide a {files} tallózásához...)', - fileActionSettings: { - removeTitle: 'A fájl eltávolítása', - uploadTitle: 'fájl feltöltése', - uploadRetryTitle: 'Feltöltés újból', - downloadTitle: 'Fájl letöltése', - zoomTitle: 'Részletek megtekintése', - dragTitle: 'Mozgatás / Átrendezés', - indicatorNewTitle: 'Nem feltöltött', - indicatorSuccessTitle: 'Feltöltött', - indicatorErrorTitle: 'Feltöltés hiba', - indicatorLoadingTitle: 'Feltöltés ...' - }, - previewZoomButtonTitles: { - prev: 'Elöző fájl megnézése', - next: 'Következő fájl megnézése', - toggleheader: 'Fejléc mutatása', - fullscreen: 'Teljes képernyős mód bekapcsolása', - borderless: 'Keret nélküli ablak mód bekapcsolása', - close: 'Részletes előnézet bezárása' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js deleted file mode 100644 index cc2bab23..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Indonesian 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 Bambang Riswanto - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['id'] = { - fileSingle: 'berkas', - filePlural: 'berkas', - browseLabel: 'Pilih berkas …', - removeLabel: 'Hapus', - removeTitle: 'Hapus berkas terpilih', - cancelLabel: 'Batal', - cancelTitle: 'Batalkan proses pengunggahan', - uploadLabel: 'Unggah', - uploadTitle: 'Unggah berkas terpilih', - msgNo: 'Tidak', - msgNoFilesSelected: '', - msgCancelled: 'Dibatalkan', - msgPlaceholder: 'Pilih {files}...', - msgZoomModalHeading: 'Pratinjau terperinci', - msgFileRequired: 'Anda harus memilih berkas untuk diunggah.', - msgSizeTooSmall: 'Berkas "{name}" ({size} KB) terlalu kecil dan harus lebih besar dari {minSize} KB.', - msgSizeTooLarge: 'Berkas "{name}" ({size} KB) melebihi ukuran unggah maksimal yaitu {maxSize} KB.', - msgFilesTooLess: 'Anda harus memilih setidaknya {n} {files} untuk diunggah.', - msgFilesTooMany: '({n}) berkas yang dipilih untuk diunggah melebihi ukuran unggah maksimal yaitu {m}.', - msgFileNotFound: 'Berkas "{name}" tak ditemukan!', - msgFileSecured: 'Sistem keamanan mencegah untuk membaca berkas "{name}".', - msgFileNotReadable: 'Berkas "{name}" tak dapat dibaca.', - msgFilePreviewAborted: 'Pratinjau untuk berkas "{name}" dibatalkan.', - msgFilePreviewError: 'Kesalahan saat membaca berkas "{name}".', - msgInvalidFileName: 'Karakter tidak dikenali atau tidak didukung untuk nama berkas "{name}".', - msgInvalidFileType: 'Jenis berkas "{name}" tidak sah. Hanya berkas "{types}" yang didukung.', - msgInvalidFileExtension: 'Ekstensi berkas "{name}" tidak sah. Hanya ekstensi "{extensions}" yang didukung.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Proses Unggah berkas dibatalkan', - msgUploadThreshold: 'Memproses...', - msgUploadBegin: 'Menyiapkan...', - msgUploadEnd: 'Selesai', - msgUploadEmpty: 'Tidak ada data valid yang tersedia untuk diunggah.', - msgUploadError: 'Kesalahan', - msgValidationError: 'Kesalahan saat memvalidasi', - msgLoading: 'Memuat {index} dari {files} berkas …', - msgProgress: 'Memuat {index} dari {files} berkas - {name} - {percent}% selesai.', - msgSelected: '{n} {files} dipilih', - msgFoldersNotAllowed: 'Hanya tahan dan lepas file saja! {n} folder diabaikan.', - msgImageWidthSmall: 'Lebar dari gambar "{name}" harus sekurangnya {size} px.', - msgImageHeightSmall: 'Tinggi dari gambar "{name}" harus sekurangnya {size} px.', - msgImageWidthLarge: 'Lebar dari gambar "{name}" tak boleh melebihi {size} px.', - msgImageHeightLarge: 'Tinggi dari gambar "{name}" tak boleh melebihi {size} px.', - msgImageResizeError: 'Tidak dapat menentukan dimensi gambar untuk mengubah ukuran.', - msgImageResizeException: 'Kesalahan saat mengubah ukuran gambar.
        {errors}
        ', - msgAjaxError: 'Terjadi kesalahan ketika melakukan operasi {operation}. Silahkan coba lagi nanti!', - msgAjaxProgressError: '{operation} gagal', - ajaxOperations: { - deleteThumb: 'Hapus berkas', - uploadThumb: 'Unggah berkas', - uploadBatch: 'Unggah banyak berkas', - uploadExtra: 'Unggah form ekstra' - }, - dropZoneTitle: 'Tarik dan lepaskan berkas disini …', - dropZoneClickTitle: '
        (atau klik untuk memilih {files})', - fileActionSettings: { - removeTitle: 'Hapus Berkas', - uploadTitle: 'Unggah Berkas', - uploadRetryTitle: 'Unggah Ulang', - downloadTitle: 'Unduh Berkas', - zoomTitle: 'Tampilkan Rincian', - dragTitle: 'Pindah atau Atur Ulang', - indicatorNewTitle: 'Belum diunggah', - indicatorSuccessTitle: 'Sudah diunggah', - indicatorErrorTitle: 'Kesalahan dalam mengungah', - indicatorLoadingTitle: 'Mengunggah ...' - }, - previewZoomButtonTitles: { - prev: 'Lihat berkas sebelumnya', - next: 'Lihat berkas selanjutnya', - toggleheader: 'Beralih ke tajuk', - fullscreen: 'Beralih ke mode penuh', - borderless: 'Beralih ke mode tanpa tepi', - close: 'Tutup pratinjau terperinci' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js deleted file mode 100644 index 73ee7663..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js +++ /dev/null @@ -1,102 +0,0 @@ -/*! - * FileInput Italian Translation - * - * Author: Lorenzo Milesi - * - * 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['it'] = { - fileSingle: 'file', - filePlural: 'file', - browseLabel: 'Sfoglia…', - removeLabel: 'Rimuovi', - removeTitle: 'Rimuovi i file selezionati', - cancelLabel: 'Annulla', - cancelTitle: 'Annulla i caricamenti in corso', - uploadLabel: 'Carica', - uploadTitle: 'Carica i file selezionati', - msgNo: 'No', - msgNoFilesSelected: 'Nessun file selezionato', - msgCancelled: 'Annullato', - msgPlaceholder: 'Seleziona {files}...', - msgZoomModalHeading: 'Anteprima dettagliata', - msgFileRequired: 'Devi selezionare un file da caricare.', - msgSizeTooSmall: 'Il file "{name}" ({size} KB) è troppo piccolo, deve essere almeno di {minSize} KB.', - msgSizeTooLarge: 'Il file "{name}" ({size} KB) eccede la dimensione massima di caricamento di {maxSize} KB.', - msgFilesTooLess: 'Devi selezionare almeno {n} {files} da caricare.', - msgFilesTooMany: 'Il numero di file selezionati per il caricamento ({n}) eccede il numero massimo di file accettati {m}.', - msgFileNotFound: 'File "{name}" non trovato!', - msgFileSecured: 'Restrizioni di sicurezza impediscono la lettura del file "{name}".', - msgFileNotReadable: 'Il file "{name}" non è leggibile.', - msgFilePreviewAborted: 'Generazione anteprima per "{name}" annullata.', - msgFilePreviewError: 'Errore durante la lettura del file "{name}".', - msgInvalidFileName: 'Carattere non valido o non supportato nel file "{name}".', - msgInvalidFileType: 'Tipo non valido per il file "{name}". Sono ammessi solo file di tipo "{types}".', - msgInvalidFileExtension: 'Estensione non valida per il file "{name}". Sono ammessi solo file con estensione "{extensions}".', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Il caricamento del file è stato interrotto', - msgUploadThreshold: 'In lavorazione...', - msgUploadBegin: 'Inizializzazione...', - msgUploadEnd: 'Fatto', - msgUploadEmpty: 'Dati non disponibili', - msgUploadError: 'Errore', - msgValidationError: 'Errore di convalida', - msgLoading: 'Caricamento file {index} di {files}…', - msgProgress: 'Caricamento file {index} di {files} - {name} - {percent}% completato.', - msgSelected: '{n} {files} selezionati', - msgFoldersNotAllowed: 'Trascina solo file! Ignorata/e {n} cartella/e.', - msgImageWidthSmall: 'La larghezza dell\'immagine "{name}" deve essere di almeno {size} px.', - msgImageHeightSmall: 'L\'altezza dell\'immagine "{name}" deve essere di almeno {size} px.', - msgImageWidthLarge: 'La larghezza dell\'immagine "{name}" non può superare {size} px.', - msgImageHeightLarge: 'L\'altezza dell\'immagine "{name}" non può superare {size} px.', - msgImageResizeError: 'Impossibile ottenere le dimensioni dell\'immagine per ridimensionare.', - msgImageResizeException: 'Errore durante il ridimensionamento dell\'immagine.
        {errors}
        ', - msgAjaxError: 'Qualcosa non ha funzionato con l\'operazione {operation}. Per favore riprova più tardi!', - msgAjaxProgressError: '{operation} failed', - ajaxOperations: { - deleteThumb: 'eliminazione file', - uploadThumb: 'caricamento file', - uploadBatch: 'caricamento file in batch', - uploadExtra: 'upload dati del form' - }, - dropZoneTitle: 'Trascina i file qui…', - dropZoneClickTitle: '
        (o clicca per selezionare {files})', - fileActionSettings: { - removeTitle: 'Rimuovere il file', - uploadTitle: 'Caricare un file', - uploadRetryTitle: 'Riprova il caricamento', - downloadTitle: 'Scarica file', - zoomTitle: 'Guarda i dettagli', - dragTitle: 'Muovi / Riordina', - indicatorNewTitle: 'Non ancora caricato', - indicatorSuccessTitle: 'Caricati', - indicatorErrorTitle: 'Carica Errore', - indicatorLoadingTitle: 'Caricamento ...' - }, - previewZoomButtonTitles: { - prev: 'Vedi il file precedente', - next: 'Vedi il file seguente', - toggleheader: 'Attiva header', - fullscreen: 'Attiva full screen', - borderless: 'Abilita modalità senza bordi', - close: 'Chiudi' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js deleted file mode 100644 index 3decd7fa..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js +++ /dev/null @@ -1,109 +0,0 @@ -/*! - * FileInput Japanese 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 Yuta Hoshina - * - * NOTE: this file must be saved in UTF-8 encoding. - * slugCallback - * \u4e00-\u9fa5 : Kanji (Chinese characters) - * \u3040-\u309f : Hiragana (Japanese syllabary) - * \u30a0-\u30ff\u31f0-\u31ff : Katakana (including phonetic extension) - * \u3200-\u32ff : Enclosed CJK Letters and Months - * \uff00-\uffef : Halfwidth and Fullwidth Forms - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['ja'] = { - fileSingle: 'ファイル', - filePlural: 'ファイル', - browseLabel: 'ファイルを選択…', - removeLabel: '削除', - removeTitle: '選択したファイルを削除', - cancelLabel: 'キャンセル', - cancelTitle: 'アップロードをキャンセル', - uploadLabel: 'アップロード', - uploadTitle: '選択したファイルをアップロード', - msgNo: 'いいえ', - msgNoFilesSelected: 'ファイルが選択されていません', - msgCancelled: 'キャンセル', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'プレビュー', - msgFileRequired: 'ファイルを選択してください', - msgSizeTooSmall: 'ファイル"{name}" ({size} KB)はアップロード可能な下限容量{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: 'ファイル名に無効な文字が含まれています "{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: '処理中...', - msgUploadBegin: '初期化中...', - msgUploadEnd: '完了', - msgUploadEmpty: 'アップロードに有効なデータがありません', - msgUploadError: 'エラー', - msgValidationError: '検証エラー', - msgLoading: '{files}個中{index}個目のファイルを読み込み中…', - msgProgress: '{files}個中{index}個のファイルを読み込み中 - {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: '{operation}実行中にエラーが発生しました。時間をおいてもう一度お試しください。', - msgAjaxProgressError: '{operation} failed', - ajaxOperations: { - deleteThumb: 'ファイル削除', - uploadThumb: 'ファイルアップロード', - uploadBatch: '一括ファイルアップロード', - uploadExtra: 'フォームデータアップロード' - }, - dropZoneTitle: 'ファイルをドラッグ&ドロップ…', - dropZoneClickTitle: '
        (または クリックして{files}を選択 )', - slugCallback: function(text) { - return text ? text.split(/(\\|\/)/g).pop().replace(/[^\w\u4e00-\u9fa5\u3040-\u309f\u30a0-\u30ff\u31f0-\u31ff\u3200-\u32ff\uff00-\uffef\-.\\\/ ]+/g, '') : ''; - }, - fileActionSettings: { - removeTitle: 'ファイルを削除', - uploadTitle: 'ファイルをアップロード', - uploadRetryTitle: '再アップロード', - zoomTitle: 'プレビュー', - dragTitle: '移動 / 再配置', - indicatorNewTitle: 'まだアップロードされていません', - indicatorSuccessTitle: 'アップロード済み', - indicatorErrorTitle: 'アップロード失敗', - indicatorLoadingTitle: 'アップロード中...' - }, - previewZoomButtonTitles: { - prev: '前のファイルを表示', - next: '次のファイルを表示', - toggleheader: 'ファイル情報の表示/非表示', - fullscreen: 'フルスクリーン表示の開始/終了', - borderless: 'フルウィンドウ表示の開始/終了', - close: 'プレビューを閉じる' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js deleted file mode 100644 index c6c0a230..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Georgian 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 Avtandil Kikabidze aka LONGMAN - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['ka'] = { - fileSingle: 'ფაილი', - filePlural: 'ფაილები', - browseLabel: 'არჩევა …', - removeLabel: 'წაშლა', - removeTitle: 'არჩეული ფაილების წაშლა', - cancelLabel: 'გაუქმება', - cancelTitle: 'მიმდინარე ატვირთვის გაუქმება', - uploadLabel: 'ატვირთვა', - uploadTitle: 'არჩეული ფაილების ატვირთვა', - msgNo: 'არა', - msgNoFilesSelected: 'ფაილები არ არის არჩეული', - msgCancelled: 'გაუქმებულია', - msgPlaceholder: 'აირჩიეთ {files}...', - msgZoomModalHeading: 'დეტალურად ნახვა', - msgFileRequired: 'ატვირთვისთვის აუცილებელია ფაილის არჩევა.', - msgSizeTooSmall: 'ფაილი "{name}" ({size} KB) არის ძალიან პატარა. მისი ზომა უნდა იყოს არანაკლებ {minSize} KB.', - msgSizeTooLarge: 'ფაილი "{name}" ({size} KB) აჭარბებს მაქსიმალურ დასაშვებ ზომას {maxSize} KB.', - msgFilesTooLess: 'უნდა აირჩიოთ მინიმუმ {n} {file} ატვირთვისთვის.', - msgFilesTooMany: 'არჩეული ფაილების რაოდენობა ({n}) აჭარბებს დასაშვებ ლიმიტს {m}.', - msgFileNotFound: 'ფაილი "{name}" არ მოიძებნა!', - msgFileSecured: 'უსაფრთხოებით გამოწვეული შეზღუდვები კრძალავს ფაილის "{name}" წაკითხვას.', - msgFileNotReadable: 'ფაილის "{name}" წაკითხვა შეუძლებელია.', - msgFilePreviewAborted: 'პრევიუ გაუქმებულია ფაილისათვის "{name}".', - msgFilePreviewError: 'დაფიქსირდა შეცდომა ფაილის "{name}" კითხვისას.', - msgInvalidFileName: 'ნაპოვნია დაუშვებელი სიმბოლოები ფაილის "{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: 'მუშავდება...', - msgUploadBegin: 'ინიციალიზაცია...', - msgUploadEnd: 'დასრულებულია', - msgUploadEmpty: 'ატვირთვისთვის დაუშვებელი მონაცემები.', - msgUploadError: 'ატვირთვის შეცდომა', - msgValidationError: 'ვალიდაციის შეცდომა', - msgLoading: 'ატვირთვა {index} / {files} …', - msgProgress: 'ფაილის ატვირთვა დასრულებულია {index} / {files} - {name} - {percent}%.', - msgSelected: 'არჩეულია {n} {file}', - msgFoldersNotAllowed: 'დაშვებულია მხოლოდ ფაილების გადმოთრევა! გამოტოვებულია {n} გადმოთრეული ფოლდერი.', - msgImageWidthSmall: 'სურათის "{name}" სიგანე უნდა იყოს არანაკლებ {size} px.', - msgImageHeightSmall: 'სურათის "{name}" სიმაღლე უნდა იყოს არანაკლებ {size} px.', - msgImageWidthLarge: 'სურათის "{name}" სიგანე არ უნდა აღემატებოდეს {size} px-ს.', - msgImageHeightLarge: 'სურათის "{name}" სიმაღლე არ უნდა აღემატებოდეს {size} px-ს.', - msgImageResizeError: 'ვერ მოხერხდა სურათის ზომის შეცვლისთვის საჭირო მონაცემების გარკვევა.', - msgImageResizeException: 'შეცდომა სურათის ზომის შეცვლისას.
        {errors}
        ', - msgAjaxError: 'დაფიქსირდა შეცდომა ოპერაციის {operation} შესრულებისას. ცადეთ მოგვიანებით!', - msgAjaxProgressError: 'ვერ მოხერხდა ოპერაციის {operation} შესრულება', - ajaxOperations: { - deleteThumb: 'ფაილის წაშლა', - uploadThumb: 'ფაილის ატვირთვა', - uploadBatch: 'ფაილების ატვირთვა', - uploadExtra: 'მონაცემების გაგზავნა ფორმიდან' - }, - dropZoneTitle: 'გადმოათრიეთ ფაილები აქ …', - dropZoneClickTitle: '
        (ან დააჭირეთ რათა აირჩიოთ {files})', - fileActionSettings: { - removeTitle: 'ფაილის წაშლა', - uploadTitle: 'ფაილის ატვირთვა', - uploadRetryTitle: 'ატვირთვის გამეორება', - downloadTitle: 'ფაილის ჩამოტვირთვა', - zoomTitle: 'დეტალურად ნახვა', - dragTitle: 'გადაადგილება / მიმდევრობის შეცვლა', - indicatorNewTitle: 'ჯერ არ ატვირთულა', - indicatorSuccessTitle: 'ატვირთულია', - indicatorErrorTitle: 'ატვირთვის შეცდომა', - indicatorLoadingTitle: 'ატვირთვა ...' - }, - previewZoomButtonTitles: { - prev: 'წინა ფაილის ნახვა', - next: 'შემდეგი ფაილის ნახვა', - toggleheader: 'სათაურის დამალვა', - fullscreen: 'მთელ ეკრანზე გაშლა', - borderless: 'მთელ გვერდზე გაშლა', - close: 'დახურვა' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js deleted file mode 100644 index 0190dd73..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Korean 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['kr'] = { - fileSingle: '파일', - filePlural: '파일들', - browseLabel: '찾아보기 …', - removeLabel: '지우기', - removeTitle: '선택한 파일들 지우기', - cancelLabel: '취소', - cancelTitle: '진행중인 업로드 중단', - uploadLabel: '업로드', - uploadTitle: '선택한 파일 업로드', - msgNo: '아니요', - msgNoFilesSelected: '선택한 파일이 없습니다', - msgCancelled: '취소되었습니다', - msgPlaceholder: '{files} 선택...', - msgZoomModalHeading: '세부 정보', - msgFileRequired: '업로드를 위해 반드시 파일을 선택해야 합니다.', - msgSizeTooSmall: '파일 "{name}" ({size} KB)이 너무 작습니다. {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: '파일 이름 "{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: '처리하는 중...', - msgUploadBegin: '초기화 중...', - msgUploadEnd: '완료', - msgUploadEmpty: '업로드 가능한 데이터가 존재하지 않습니다.', - msgUploadError: '오류', - msgValidationError: '유효성 오류', - msgLoading: '{index}/{files}번째 파일을 불러오는 중입니다. …', - msgProgress: '{index}/{files} - {name} - {percent}% 불러오기 완료.', - msgSelected: '{n} {files}이 선택 되었습니다.', - msgFoldersNotAllowed: '파일만 마우스로 끌어올 수 있습니다! 끌어온 폴더는 건너뜁니다.', - msgImageWidthSmall: '"{name}"의 가로는 {size} px 보다 넓어야 합니다.', - msgImageHeightSmall: '"{name}"의 세로는 {size} px 보다 높아야 합니다.', - msgImageWidthLarge: '"{name}"의 가로는 {size} px를 넘을 수 없습니다.', - msgImageHeightLarge: '"{name}"의 세로는 {size} px를 넘을 수 없습니다.', - msgImageResizeError: '이미지의 치수를 가져올 수 없습니다', - msgImageResizeException: '이미지 사이즈 재조정이 다음 이유로 실패했습니다.
        {errors}
        ', - msgAjaxError: '{operation} 실행 도중 실패했습니다. 잠시 후 다시 시도해 주세요!', - msgAjaxProgressError: '{operation} failed', - ajaxOperations: { - deleteThumb: 'file delete', - uploadThumb: 'file upload', - uploadBatch: 'batch file upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: '마우스로 파일을 끌어오세요 …', - dropZoneClickTitle: '
        (또는 {files} 선택을 위해 클릭하십시요)', - fileActionSettings: { - removeTitle: '파일 지우기', - uploadTitle: '파일 업로드', - uploadRetryTitle: '업로드 재시도', - downloadTitle: '파일 다운로드', - zoomTitle: '세부 정보 보기', - dragTitle: '옮기기 / 재배열하기', - indicatorNewTitle: '아직 업로드 되지 않았습니다', - indicatorSuccessTitle: '업로드 성공', - indicatorErrorTitle: '업로드 중 에러 발생', - indicatorLoadingTitle: '업로드 중 ...' - }, - previewZoomButtonTitles: { - prev: '이전 파일', - next: '다음 파일', - toggleheader: '머릿글 토글', - fullscreen: '전체화면 토글', - borderless: '창 테두리 토글', - close: '세부 정보 닫기' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js deleted file mode 100644 index 82c34cc4..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js +++ /dev/null @@ -1,88 +0,0 @@ -/*! - * FileInput Kazakh 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 Kali Toleugazy - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['kz'] = { - fileSingle: 'файл', - filePlural: 'файлдар', - browseLabel: 'Таңдау …', - removeLabel: 'Жою', - removeTitle: 'Таңдалған файлдарды жою', - cancelLabel: 'Күшін жою', - cancelTitle: 'Ағымдағы жүктеуді болдырмау', - uploadLabel: 'Жүктеу', - uploadTitle: 'Таңдалған файлдарды жүктеу', - msgNo: 'жоқ', - msgNoFilesSelected: 'Файл таңдалмады', - msgCancelled: 'Күші жойылған', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Алдын ала толық көру', - msgSizeTooLarge: 'Файл "{name}" ({size} KB) ең үлкен {maxSize} KB өлшемінен асады.', - msgFilesTooLess: 'Жүктеу үшіy кемінде {n} {files} таңдау керек.', - msgFilesTooMany: 'Таңдалған ({n}) файлдардың саны берілген {m} саннан асып кетті.', - msgFileNotFound: 'Файл "{name}" табылмады!', - msgFileSecured: 'Шектеу қауіпсіздігі "{name}" файлын оқуға тыйым салады.', - msgFileNotReadable: '"{name}" файлды оқу мүмкін емес.', - msgFilePreviewAborted: '"{name}" файл үшін алдын ала қарап көру тыйым салынған.', - msgFilePreviewError: '"{name}" файлды оқығанда қате пайда болды.', - msgInvalidFileType: '"{name}" тыйым салынған файл түрі. Тек мынаналарға рұқсат етілген: "{types}"', - msgInvalidFileExtension: '"{name}" тыйым салынған файл кеңейтімі. Тек "{extensions}" рұқсат.', - msgUploadAborted: 'Файлды жүктеу доғарылды', - msgUploadThreshold: 'Өңдеу...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', - msgValidationError: 'Тексеру қатесі', - msgLoading: '{index} файлды {files} … жүктеу', - msgProgress: '{index} файлды {files} - {name} - {percent}% жүктеу аяқталды.', - msgSelected: 'Таңдалған файлдар саны: {n}', - 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: 'Орнын ауыстыру', - indicatorNewTitle: 'Жүктелген жоқ', - indicatorSuccessTitle: 'Жүктелген', - indicatorErrorTitle: 'Жүктелу қатесі ', - indicatorLoadingTitle: 'Жүктелу ...' - }, - previewZoomButtonTitles: { - prev: 'Алдыңғы файлды қарау', - next: 'Келесі файлды қарау', - toggleheader: 'Тақырыпты ауыстыру', - fullscreen: 'Толық экран режимін қосу', - borderless: 'Жиексіз режиміне ауысу', - close: 'Толық көрінісін жабу' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js deleted file mode 100644 index 91f36c94..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput <_LANG_> 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 Mindaugas Varkalys - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['lt'] = { - fileSingle: 'failas', - filePlural: 'failai', - browseLabel: 'Naršyti …', - removeLabel: 'Šalinti', - removeTitle: 'Pašalinti pasirinktus failus', - cancelLabel: 'Atšaukti', - cancelTitle: 'Atšaukti vykstantį įkėlimą', - uploadLabel: 'Įkelti', - uploadTitle: 'Įkelti pasirinktus failus', - msgNo: 'Ne', - msgNoFilesSelected: 'Nepasirinkta jokių failų', - msgCancelled: 'Atšaukta', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Detali Peržiūra', - msgFileRequired: 'Pasirinkite failą įkėlimui.', - msgSizeTooSmall: 'Failas "{name}" ({size} KB) yra per mažas ir turi būti didesnis nei {minSize} KB.', - msgSizeTooLarge: 'Failas "{name}" ({size} KB) viršija maksimalų leidžiamą įkeliamo failo dydį {maxSize} KB.', - msgFilesTooLess: 'Turite pasirinkti bent {n} failus įkėlimui.', - msgFilesTooMany: 'Įkėlimui pasirinktų failų skaičius ({n}) viršija maksimalų leidžiamą limitą {m}.', - msgFileNotFound: 'Failas "{name}" nerastas!', - msgFileSecured: 'Saugumo apribojimai neleidžia perskaityti failo "{name}".', - msgFileNotReadable: 'Failas "{name}" neperskaitomas.', - msgFilePreviewAborted: 'Failo peržiūra nutraukta "{name}".', - msgFilePreviewError: 'Įvyko klaida skaitant failą "{name}".', - msgInvalidFileName: 'Klaidingi arba nepalaikomi simboliai failo pavadinime "{name}".', - msgInvalidFileType: 'Klaidingas failo "{name}" tipas. Tik "{types}" tipai yra palaikomi.', - msgInvalidFileExtension: 'Klaidingas failo "{name}" plėtinys. Tik "{extensions}" plėtiniai yra palaikomi.', - msgFileTypes: { - 'image': 'paveikslėlis', - 'html': 'HTML', - 'text': 'tekstas', - 'video': 'vaizdo įrašas', - 'audio': 'garso įrašas', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'objektas' - }, - msgUploadAborted: 'Failo įkėlimas buvo nutrauktas', - msgUploadThreshold: 'Vykdoma...', - msgUploadBegin: 'Inicijuojama...', - msgUploadEnd: 'Baigta', - msgUploadEmpty: 'Nėra teisingų duomenų įkėlimui.', - msgUploadError: 'Klaida', - msgValidationError: 'Validacijos Klaida', - msgLoading: 'Keliamas failas {index} iš {files} …', - msgProgress: 'Keliamas failas {index} iš {files} - {name} - {percent}% baigta.', - msgSelected: 'Pasirinkti {n} {files}', - msgFoldersNotAllowed: 'Tempkite tik failus! Praleisti {n} nutempti aplankalas(-i).', - msgImageWidthSmall: 'Paveikslėlio "{name}" plotis turi būti bent {size} px.', - msgImageHeightSmall: 'Paveikslėlio "{name}" aukštis turi būti bent {size} px.', - msgImageWidthLarge: 'Paveikslėlio "{name}" plotis negali viršyti {size} px.', - msgImageHeightLarge: 'Paveikslėlio "{name}" aukštis negali viršyti {size} px.', - msgImageResizeError: 'Nepavyksta gauti paveikslėlio matmetų, kad pakeisti jo matmemis.', - msgImageResizeException: 'Klaida keičiant paveikslėlio matmenis.
        {errors}
        ', - msgAjaxError: 'Kažkas nutiko vykdant {operation} operaciją. Prašome pabandyti vėliau!', - msgAjaxProgressError: '{operation} operacija nesėkminga', - ajaxOperations: { - deleteThumb: 'failo trynimo', - uploadThumb: 'failo įkėlimo', - uploadBatch: 'failų rinkinio įkėlimo', - uploadExtra: 'formos duomenų įkėlimo' - }, - dropZoneTitle: 'Tempkite failus čia …', - dropZoneClickTitle: '
        (arba paspauskite, kad pasirinktumėte failus)', - fileActionSettings: { - removeTitle: 'Šalinti failą', - uploadTitle: 'Įkelti failą', - uploadRetryTitle: 'Bandyti įkelti vėl', - zoomTitle: 'Peržiūrėti detales', - dragTitle: 'Perstumti', - indicatorNewTitle: 'Dar neįkelta', - indicatorSuccessTitle: 'Įkelta', - indicatorErrorTitle: 'Įkėlimo Klaida', - indicatorLoadingTitle: 'Įkeliama ...' - }, - previewZoomButtonTitles: { - prev: 'Peržiūrėti ankstesnį failą', - next: 'Peržiūrėti kitą failą', - toggleheader: 'Perjungti viršutinę juostą', - fullscreen: 'Perjungti pilno ekrano rėžimą', - borderless: 'Perjungti berėmį režimą', - close: 'Uždaryti detalią peržiūrą' - } - }; -})(window.jQuery); \ No newline at end of file diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js deleted file mode 100644 index df3f3dc4..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Dutch 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['nl'] = { - fileSingle: 'bestand', - filePlural: 'bestanden', - browseLabel: 'Zoek …', - removeLabel: 'Verwijder', - removeTitle: 'Verwijder geselecteerde bestanden', - cancelLabel: 'Annuleren', - cancelTitle: 'Annuleer upload', - uploadLabel: 'Upload', - uploadTitle: 'Upload geselecteerde bestanden', - msgNo: 'Nee', - msgNoFilesSelected: '', - msgCancelled: 'Geannuleerd', - msgPlaceholder: 'Selecteer {files}...', - msgZoomModalHeading: 'Gedetailleerd voorbeeld', - msgFileRequired: 'U moet een bestand kiezen om te uploaden.', - msgSizeTooSmall: 'Bestand "{name}" ({size} KB) is te klein en moet groter zijn dan {minSize} KB.', - msgSizeTooLarge: 'Bestand "{name}" ({size} KB) is groter dan de toegestane {maxSize} KB.', - msgFilesTooLess: 'U moet minstens {n} {files} selecteren om te uploaden.', - msgFilesTooMany: 'Aantal geselecteerde bestanden ({n}) is meer dan de toegestane {m}.', - msgFileNotFound: 'Bestand "{name}" niet gevonden!', - msgFileSecured: 'Bestand kan niet gelezen worden in verband met beveiligings redenen "{name}".', - msgFileNotReadable: 'Bestand "{name}" is niet leesbaar.', - msgFilePreviewAborted: 'Bestand weergaven geannuleerd voor "{name}".', - msgFilePreviewError: 'Er is een fout opgetreden met het lezen van "{name}".', - msgInvalidFileName: 'Ongeldige of niet ondersteunde karakters in bestandsnaam "{name}".', - msgInvalidFileType: 'Geen geldig bestand "{name}". Alleen "{types}" zijn toegestaan.', - msgInvalidFileExtension: 'Geen geldige extensie "{name}". Alleen "{extensions}" zijn toegestaan.', - msgFileTypes: { - 'image': 'afbeelding', - 'html': 'HTML', - 'text': 'tekst', - 'video': 'video', - 'audio': 'geluid', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Het uploaden van bestanden is afgebroken', - msgUploadThreshold: 'Verwerken...', - msgUploadBegin: 'Initialiseren...', - msgUploadEnd: 'Gedaan', - msgUploadEmpty: 'Geen geldige data beschikbaar voor upload.', - msgUploadError: 'Error', - msgValidationError: 'Bevestiging fout', - msgLoading: 'Bestanden laden {index} van de {files} …', - msgProgress: 'Bestanden laden {index} van de {files} - {name} - {percent}% compleet.', - msgSelected: '{n} {files} geselecteerd', - msgFoldersNotAllowed: 'Drag & drop alleen bestanden! {n} overgeslagen map(pen).', - msgImageWidthSmall: 'Breedte van het foto-bestand "{name}" moet minstens {size} px zijn.', - msgImageHeightSmall: 'Hoogte van het foto-bestand "{name}" moet minstens {size} px zijn.', - msgImageWidthLarge: 'Breedte van het foto-bestand "{name}" kan niet hoger zijn dan {size} px.', - msgImageHeightLarge: 'Hoogte van het foto bestand "{name}" kan niet hoger zijn dan {size} px.', - msgImageResizeError: 'Kon de foto afmetingen niet lezen om te verkleinen.', - msgImageResizeException: 'Fout bij het verkleinen van de foto.
        {errors}
        ', - msgAjaxError: 'Er ging iets mis met de {operation} actie. Gelieve later opnieuw te proberen!', - msgAjaxProgressError: '{operation} mislukt', - ajaxOperations: { - deleteThumb: 'bestand verwijderen', - uploadThumb: 'bestand uploaden', - uploadBatch: 'alle bestanden uploaden', - uploadExtra: 'form data upload' - }, - dropZoneTitle: 'Drag & drop bestanden hier …', - dropZoneClickTitle: '
        (of klik hier om {files} te selecteren)', - fileActionSettings: { - removeTitle: 'Verwijder bestand', - uploadTitle: 'bestand uploaden', - uploadRetryTitle: 'Opnieuw uploaden', - downloadTitle: 'Download file', - zoomTitle: 'Bekijk details', - dragTitle: 'Verplaatsen / herindelen', - indicatorNewTitle: 'Nog niet geupload', - indicatorSuccessTitle: 'geupload', - indicatorErrorTitle: 'fout uploaden', - indicatorLoadingTitle: 'uploaden ...' - }, - previewZoomButtonTitles: { - prev: 'Toon vorig bestand', - next: 'Toon volgend bestand', - toggleheader: 'Toggle header', - fullscreen: 'Toggle volledig scherm', - borderless: 'Toggle randloze modus', - close: 'Sluit gedetailleerde weergave' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js deleted file mode 100644 index 773bb1bd..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js +++ /dev/null @@ -1,99 +0,0 @@ -/*! - * FileInput Norwegian 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['no'] = { - fileSingle: 'fil', - filePlural: 'filer', - browseLabel: 'Bla gjennom …', - removeLabel: 'Fjern', - removeTitle: 'Fjern valgte filer', - cancelLabel: 'Avbryt', - cancelTitle: 'Stopp pågående opplastninger', - uploadLabel: 'Last opp', - uploadTitle: 'Last opp valgte filer', - msgNo: 'Nei', - msgNoFilesSelected: 'Ingen filer er valgt', - msgCancelled: 'Avbrutt', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Detaljert visning', - msgFileRequired: 'You must select a file to upload.', - msgSizeTooSmall: 'Filen "{name}" ({size} KB) er for liten og må være større enn {minSize} KB.', - msgSizeTooLarge: 'Filen "{name}" ({size} KB) er for stor, maksimal filstørrelse er {maxSize} KB.', - msgFilesTooLess: 'Du må velge minst {n} {files} for opplastning.', - msgFilesTooMany: 'For mange filer til opplastning, ({n}) overstiger maksantallet som er {m}.', - msgFileNotFound: 'Fant ikke filen "{name}"!', - msgFileSecured: 'Sikkerhetsrestriksjoner hindrer lesing av filen "{name}".', - msgFileNotReadable: 'Filen "{name}" er ikke lesbar.', - msgFilePreviewAborted: 'Filvisning avbrutt for "{name}".', - msgFilePreviewError: 'En feil oppstod under lesing av filen "{name}".', - msgInvalidFileName: 'Ugyldige tegn i filen "{name}".', - msgInvalidFileType: 'Ugyldig type for filen "{name}". Kun "{types}" filer er tillatt.', - msgInvalidFileExtension: 'Ugyldig endelse for filen "{name}". Kun "{extensions}" filer støttes.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Filopplastningen ble avbrutt', - msgUploadThreshold: 'Prosesserer...', - msgUploadBegin: 'Initialiserer...', - msgUploadEnd: 'Ferdig', - msgUploadEmpty: 'Ingen gyldige data tilgjengelig for opplastning.', - msgUploadError: 'Error', - msgValidationError: 'Valideringsfeil', - msgLoading: 'Laster fil {index} av {files} …', - msgProgress: 'Laster fil {index} av {files} - {name} - {percent}% fullført.', - msgSelected: '{n} {files} valgt', - msgFoldersNotAllowed: 'Kun Dra & slipp filer! Hoppet over {n} mappe(r).', - msgImageWidthSmall: 'Bredde på bildefilen "{name}" må være minst {size} px.', - msgImageHeightSmall: 'Høyde på bildefilen "{name}" må være minst {size} px.', - msgImageWidthLarge: 'Bredde på bildefilen "{name}" kan ikke overstige {size} px.', - msgImageHeightLarge: 'Høyde på bildefilen "{name}" kan ikke overstige {size} px.', - msgImageResizeError: 'Fant ikke dimensjonene som skulle resizes.', - msgImageResizeException: 'En feil oppstod under endring av størrelse .
        {errors}
        ', - msgAjaxError: 'Noe gikk galt med {operation} operasjonen. Vennligst prøv igjen senere!', - msgAjaxProgressError: '{operation} feilet', - ajaxOperations: { - deleteThumb: 'file delete', - uploadThumb: 'file upload', - uploadBatch: 'batch file upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: 'Dra & slipp filer her …', - dropZoneClickTitle: '
        (eller klikk for å velge {files})', - fileActionSettings: { - removeTitle: 'Fjern fil', - uploadTitle: 'Last opp fil', - uploadRetryTitle: 'Retry upload', - zoomTitle: 'Vis detaljer', - dragTitle: 'Flytt / endre rekkefølge', - indicatorNewTitle: 'Opplastning ikke fullført', - indicatorSuccessTitle: 'Opplastet', - indicatorErrorTitle: 'Opplastningsfeil', - indicatorLoadingTitle: 'Laster opp ...' - }, - previewZoomButtonTitles: { - prev: 'Vis forrige fil', - next: 'Vis neste fil', - toggleheader: 'Vis header', - fullscreen: 'Åpne fullskjerm', - borderless: 'Åpne uten kanter', - close: 'Lukk detaljer' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js deleted file mode 100644 index e19a0ed2..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js +++ /dev/null @@ -1,90 +0,0 @@ -/*! - * FileInput Polish 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['pl'] = { - fileSingle: 'plik', - filePlural: 'pliki', - browseLabel: 'Przeglądaj …', - removeLabel: 'Usuń', - removeTitle: 'Usuń zaznaczone pliki', - cancelLabel: 'Przerwij', - cancelTitle: 'Anuluj wysyłanie', - uploadLabel: 'Wgraj', - uploadTitle: 'Wgraj zaznaczone pliki', - msgNo: 'Nie', - msgNoFilesSelected: 'Brak zaznaczonych plików', - msgCancelled: 'Odwołany', - msgPlaceholder: 'Wybierz {files}...', - msgZoomModalHeading: 'Szczegółowy podgląd', - msgFileRequired: 'Musisz wybrać plik do wgrania.', - msgSizeTooSmall: 'Plik "{name}" ({size} KB) jest zbyt mały i musi być większy niż {minSize} KB.', - msgSizeTooLarge: 'Plik o nazwie "{name}" ({size} KB) przekroczył maksymalną dopuszczalną wielkość pliku wynoszącą {maxSize} KB.', - msgFilesTooLess: 'Minimalna liczba plików do wgrania: {n}.', - msgFilesTooMany: 'Liczba plików wybranych do wgrania w liczbie ({n}), przekracza maksymalny dozwolony limit wynoszący {m}.', - msgFileNotFound: 'Plik "{name}" nie istnieje!', - msgFileSecured: 'Ustawienia zabezpieczeń uniemożliwiają odczyt pliku "{name}".', - msgFileNotReadable: 'Plik "{name}" nie jest plikiem do odczytu.', - msgFilePreviewAborted: 'Podgląd pliku "{name}" został przerwany.', - msgFilePreviewError: 'Wystąpił błąd w czasie odczytu pliku "{name}".', - msgInvalidFileName: 'Nieprawidłowe lub nieobsługiwane znaki w nazwie pliku "{name}".', - msgInvalidFileType: 'Nieznany typ pliku "{name}". Tylko następujące rodzaje plików są dozwolone: "{types}".', - msgInvalidFileExtension: 'Złe rozszerzenie dla pliku "{name}". Tylko następujące rozszerzenia plików są dozwolone: "{extensions}".', - msgUploadAborted: 'Przesyłanie pliku zostało przerwane', - msgUploadThreshold: 'Przetwarzanie...', - msgUploadBegin: 'Rozpoczynanie...', - msgUploadEnd: 'Gotowe!', - msgUploadEmpty: 'Brak poprawnych danych do przesłania.', - msgUploadError: 'Błąd', - msgValidationError: 'Błąd walidacji', - msgLoading: 'Wczytywanie pliku {index} z {files} …', - msgProgress: 'Wczytywanie pliku {index} z {files} - {name} - {percent}% zakończone.', - msgSelected: '{n} Plików zaznaczonych', - msgFoldersNotAllowed: 'Metodą przeciągnij i upuść, można przenosić tylko pliki. Pominięto {n} katalogów.', - msgImageWidthSmall: 'Szerokość pliku obrazu "{name}" musi być co najmniej {size} px.', - msgImageHeightSmall: 'Wysokość pliku obrazu "{name}" musi być co najmniej {size} px.', - msgImageWidthLarge: 'Szerokość pliku obrazu "{name}" nie może przekraczać {size} px.', - msgImageHeightLarge: 'Wysokość pliku obrazu "{name}" nie może przekraczać {size} px.', - msgImageResizeError: 'Nie udało się uzyskać wymiaru obrazu, aby zmienić rozmiar.', - msgImageResizeException: 'Błąd podczas zmiany rozmiaru obrazu.
        {errors}
        ', - msgAjaxError: 'Coś poczło nie tak podczas {operation}. Spróbuj ponownie!', - msgAjaxProgressError: '{operation} nie powiodło się', - ajaxOperations: { - deleteThumb: 'usuwanie pliku', - uploadThumb: 'przesyłanie pliku', - uploadBatch: 'masowe przesyłanie plików', - uploadExtra: 'przesyłanie danych formularza' - }, - dropZoneTitle: 'Przeciągnij i upuść pliki tutaj …', - dropZoneClickTitle: '
        (lub kliknij tutaj i wybierz {files} z komputera)', - fileActionSettings: { - removeTitle: 'Usuń plik', - uploadTitle: 'Przesyłanie pliku', - uploadRetryTitle: 'Ponów', - downloadTitle: 'Pobierz plik', - zoomTitle: 'Pokaż szczegóły', - dragTitle: 'Przenies / Ponownie zaaranżuj', - indicatorNewTitle: 'Jeszcze nie przesłany', - indicatorSuccessTitle: 'Dodane', - indicatorErrorTitle: 'Błąd', - indicatorLoadingTitle: 'Przesyłanie ...' - }, - previewZoomButtonTitles: { - prev: 'Pokaż poprzedni plik', - next: 'Pokaż następny plik', - toggleheader: 'Włącz / wyłącz nagłówek', - fullscreen: 'Włącz / wyłącz pełny ekran', - borderless: 'Włącz / wyłącz tryb bez ramek', - close: 'Zamknij szczegółowy widok' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js deleted file mode 100644 index 157ac84c..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Brazillian 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-BR'] = { - fileSingle: 'arquivo', - filePlural: 'arquivos', - browseLabel: 'Procurar…', - removeLabel: 'Remover', - removeTitle: 'Remover arquivos selecionados', - cancelLabel: 'Cancelar', - cancelTitle: 'Interromper envio em andamento', - uploadLabel: 'Enviar', - uploadTitle: 'Enviar arquivos selecionados', - msgNo: 'Não', - msgNoFilesSelected: 'Nenhum arquivo selecionado', - msgCancelled: 'Cancelado', - msgPlaceholder: 'Selecionar {files}...', - msgZoomModalHeading: 'Pré-visualização detalhada', - msgFileRequired: 'Você deve selecionar um arquivo para enviar.', - msgSizeTooSmall: 'O arquivo "{name}" ({size} KB) é muito pequeno e deve ser maior que {minSize} KB.', - msgSizeTooLarge: 'O arquivo "{name}" ({size} KB) excede o tamanho máximo permitido de {maxSize} KB.', - msgFilesTooLess: 'Você deve selecionar pelo menos {n} {files} para enviar.', - msgFilesTooMany: 'O número de arquivos selecionados para o envio ({n}) excede o limite máximo permitido de {m}.', - msgFileNotFound: 'O arquivo "{name}" não foi encontrado!', - msgFileSecured: 'Restrições de segurança impedem a leitura do arquivo "{name}".', - msgFileNotReadable: 'O arquivo "{name}" não pode ser lido.', - msgFilePreviewAborted: 'A pré-visualização do arquivo "{name}" foi interrompida.', - msgFilePreviewError: 'Ocorreu um erro ao ler o arquivo "{name}".', - msgInvalidFileName: 'Caracteres inválidos ou não suportados no arquivo "{name}".', - msgInvalidFileType: 'Tipo inválido para o arquivo "{name}". Apenas arquivos "{types}" são permitidos.', - msgInvalidFileExtension: 'Extensão inválida para o arquivo "{name}". Apenas arquivos "{extensions}" são permitidos.', - msgFileTypes: { - 'image': 'imagem', - 'html': 'HTML', - 'text': 'texto', - 'video': 'vídeo', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'objeto' - }, - msgUploadAborted: 'O envio do arquivo foi abortado', - msgUploadThreshold: 'Processando...', - msgUploadBegin: 'Inicializando...', - msgUploadEnd: 'Concluído', - msgUploadEmpty: 'Nenhuma informação válida para upload.', - msgUploadError: 'Erro de Upload', - msgValidationError: 'Erro de validação', - msgLoading: 'Enviando arquivo {index} de {files}…', - msgProgress: 'Enviando arquivo {index} de {files} - {name} - {percent}% completo.', - msgSelected: '{n} {files} selecionado(s)', - msgFoldersNotAllowed: 'Arraste e solte apenas arquivos! {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: 'Não foi possível obter as dimensões da imagem para redimensionar.', - msgImageResizeException: 'Erro ao redimensionar a imagem.
        {errors}
        ', - msgAjaxError: 'Algo deu errado com a operação {operation}. Por favor tente novamente mais tarde!', - msgAjaxProgressError: '{operation} falhou', - ajaxOperations: { - deleteThumb: 'Exclusão de arquivo', - uploadThumb: 'Upload de arquivos', - uploadBatch: 'Carregamento de arquivos em lote', - uploadExtra: 'Carregamento de dados do formulário' - }, - dropZoneTitle: 'Arraste e solte os arquivos aqui…', - dropZoneClickTitle: '
        (ou clique para selecionar o(s) arquivo(s))', - fileActionSettings: { - removeTitle: 'Remover arquivo', - uploadTitle: 'Enviar arquivo', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'Ver detalhes', - dragTitle: 'Mover / Reordenar', - indicatorNewTitle: 'Ainda não enviado', - indicatorSuccessTitle: 'Enviado', - indicatorErrorTitle: 'Erro', - indicatorLoadingTitle: 'Enviando...' - }, - previewZoomButtonTitles: { - prev: 'Visualizar arquivo anterior', - next: 'Visualizar próximo arquivo', - toggleheader: 'Mostrar cabeçalho', - fullscreen: 'Ativar tela cheia', - borderless: 'Ativar modo sem borda', - close: 'Fechar pré-visualização detalhada' - } - }; -})(window.jQuery); 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}" ({size} KB) is too small and must be larger than {minSize} KB.', - msgSizeTooLarge: 'Ficheiro "{name}" ({size} KB) excede o tamanho máximo permido de {maxSize} KB.', - msgFilesTooLess: 'Deve seleccionar pelo menos {n} {files} para fazer upload.', - msgFilesTooMany: 'Número máximo de ficheiros seleccionados ({n}) excede o limite máximo de {m}.', - 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.
        {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: 'Arrastar e largar ficheiros aqui …', - dropZoneClickTitle: '
        (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/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js deleted file mode 100644 index d31b85bd..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Romanian 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 Ciprian Voicu - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['ro'] = { - fileSingle: 'fișier', - filePlural: 'fișiere', - browseLabel: 'Răsfoiește …', - removeLabel: 'Șterge', - removeTitle: 'Curăță fișierele selectate', - cancelLabel: 'Renunță', - cancelTitle: 'Anulează încărcarea curentă', - uploadLabel: 'Încarcă', - uploadTitle: 'Încarcă fișierele selectate', - msgNo: 'Nu', - msgNoFilesSelected: '', - msgCancelled: 'Anulat', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Previzualizare detaliată', - msgFileRequired: 'You must select a file to upload.', - msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', - msgSizeTooLarge: 'Fișierul "{name}" ({size} KB) depășește limita maximă de încărcare de {maxSize} KB.', - msgFilesTooLess: 'Trebuie să selectezi cel puțin {n} {files} pentru a încărca.', - msgFilesTooMany: 'Numărul fișierelor pentru încărcare ({n}) depășește limita maximă de {m}.', - msgFileNotFound: 'Fișierul "{name}" nu a fost găsit!', - msgFileSecured: 'Restricții de securitate previn citirea fișierului "{name}".', - msgFileNotReadable: 'Fișierul "{name}" nu se poate citi.', - msgFilePreviewAborted: 'Fișierului "{name}" nu poate fi previzualizat.', - msgFilePreviewError: 'A intervenit o eroare în încercarea de citire a fișierului "{name}".', - msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', - msgInvalidFileType: 'Tip de fișier incorect pentru "{name}". Sunt suportate doar fișiere de tipurile "{types}".', - msgInvalidFileExtension: 'Extensie incorectă pentru "{name}". Sunt suportate doar extensiile "{extensions}".', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Fișierul Încărcarea a fost întrerupt', - msgUploadThreshold: 'Processing...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: '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.', - msgSelected: '{n} {files} încărcate', - msgFoldersNotAllowed: 'Se poate doar trăgând fișierele! Se renunță la {n} dosar(e).', - msgImageWidthSmall: 'Lățimea de fișier de imagine "{name}" trebuie să fie de cel puțin {size} px.', - msgImageHeightSmall: 'Înălțimea fișier imagine "{name}" trebuie să fie de cel puțin {size} px.', - msgImageWidthLarge: 'Lățimea de fișier de imagine "{name}" nu poate depăși {size} px.', - msgImageHeightLarge: 'Înălțimea fișier imagine "{name}" nu poate depăși {size} px.', - msgImageResizeError: 'Nu a putut obține dimensiunile imaginii pentru a redimensiona.', - msgImageResizeException: 'Eroare la redimensionarea imaginii.
        {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: 'Trage fișierele aici …', - dropZoneClickTitle: '
        (or click to select {files})', - fileActionSettings: { - removeTitle: 'Scoateți fișier', - uploadTitle: 'Incarca fisier', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'Vezi detalii', - dragTitle: 'Move / Rearrange', - indicatorNewTitle: 'Nu a încărcat încă', - indicatorSuccessTitle: 'încărcat', - indicatorErrorTitle: 'Încărcați eroare', - indicatorLoadingTitle: 'Se încarcă ...' - }, - 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/ru.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js deleted file mode 100644 index 71c5ff7a..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Russian 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 CyanoFresh - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['ru'] = { - fileSingle: 'файл', - filePlural: 'файлы', - browseLabel: 'Выбрать …', - removeLabel: 'Удалить', - removeTitle: 'Очистить выбранные файлы', - cancelLabel: 'Отмена', - cancelTitle: 'Отменить текущую загрузку', - uploadLabel: 'Загрузить', - uploadTitle: 'Загрузить выбранные файлы', - msgNo: 'нет', - msgNoFilesSelected: '', - msgCancelled: 'Отменено', - msgPlaceholder: 'Выбрать {files}...', - msgZoomModalHeading: 'Подробное превью', - msgFileRequired: 'Необходимо выбрать файл для загрузки.', - msgSizeTooSmall: 'Файл "{name}" ({size} KB) имеет слишком маленький размер и должен быть больше {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: 'Неверные или неподдерживаемые символы в названии файла "{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: 'Обработка...', - msgUploadBegin: 'Инициализация...', - msgUploadEnd: 'Готово', - msgUploadEmpty: 'Недопустимые данные для загрузки', - msgUploadError: 'Ошибка загрузки', - msgValidationError: 'Ошибка проверки', - msgLoading: 'Загрузка файла {index} из {files} …', - msgProgress: 'Загрузка файла {index} из {files} - {name} - {percent}% завершено.', - msgSelected: 'Выбрано файлов: {n}', - msgFoldersNotAllowed: 'Разрешено перетаскивание только файлов! Пропущено {n} папок.', - msgImageWidthSmall: 'Ширина изображения {name} должна быть не меньше {size} px.', - msgImageHeightSmall: 'Высота изображения {name} должна быть не меньше {size} px.', - msgImageWidthLarge: 'Ширина изображения "{name}" не может превышать {size} px.', - msgImageHeightLarge: 'Высота изображения "{name}" не может превышать {size} px.', - msgImageResizeError: 'Не удалось получить размеры изображения, чтобы изменить размер.', - msgImageResizeException: 'Ошибка при изменении размера изображения.
        {errors}
        ', - msgAjaxError: 'Произошла ошибка при выполнении операции {operation}. Повторите попытку позже!', - msgAjaxProgressError: 'Не удалось выполнить {operation}', - ajaxOperations: { - deleteThumb: 'удалить файл', - uploadThumb: 'загрузить файл', - uploadBatch: 'загрузить пакет файлов', - uploadExtra: 'загрузка данных с формы' - }, - dropZoneTitle: 'Перетащите файлы сюда …', - dropZoneClickTitle: '
        (Или щёлкните, чтобы выбрать {files})', - fileActionSettings: { - removeTitle: 'Удалить файл', - uploadTitle: 'Загрузить файл', - uploadRetryTitle: 'Повторить загрузку', - downloadTitle: 'Загрузить файл', - zoomTitle: 'Посмотреть детали', - dragTitle: 'Переместить / Изменить порядок', - indicatorNewTitle: 'Еще не загружен', - indicatorSuccessTitle: 'Загружен', - indicatorErrorTitle: 'Ошибка загрузки', - indicatorLoadingTitle: 'Загрузка ...' - }, - previewZoomButtonTitles: { - prev: 'Посмотреть предыдущий файл', - next: 'Посмотреть следующий файл', - toggleheader: 'Переключить заголовок', - fullscreen: 'Переключить полноэкранный режим', - borderless: 'Переключить режим без полей', - close: 'Закрыть подробный предпросмотр' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js deleted file mode 100644 index 28d67e9a..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Slovakian 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['sk'] = { - fileSingle: 'súbor', - filePlural: 'súbory', - browseLabel: 'Vybrať …', - removeLabel: 'Odstrániť', - removeTitle: 'Vyčistiť vybraté súbory', - cancelLabel: 'Storno', - cancelTitle: 'Prerušiť nahrávanie', - uploadLabel: 'Nahrať', - uploadTitle: 'Nahrať vybraté súbory', - msgNo: 'Nie', - msgNoFilesSelected: '', - msgCancelled: 'Zrušené', - msgPlaceholder: 'Vybrať {files}...', - msgZoomModalHeading: 'Detailný náhľad', - msgFileRequired: 'Musíte vybrať súbor, ktorý chcete nahrať.', - msgSizeTooSmall: 'Súbor "{name}" ({size} KB) je príliš malý, musí mať veľkosť najmenej {minSize} KB.', - msgSizeTooLarge: 'Súbor "{name}" ({size} KB) je príliš veľký, maximálna povolená veľkosť {maxSize} KB.', - msgFilesTooLess: 'Musíte vybrať najmenej {n} {files} pre nahranie.', - msgFilesTooMany: 'Počet vybratých súborov ({n}) prekročil maximálny povolený limit {m}.', - msgFileNotFound: 'Súbor "{name}" nebol nájdený!', - msgFileSecured: 'Zabezpečenie súboru znemožnilo čítať súbor "{name}".', - msgFileNotReadable: 'Súbor "{name}" nie je čitateľný.', - msgFilePreviewAborted: 'Náhľad súboru bol prerušený pre "{name}".', - msgFilePreviewError: 'Nastala chyba pri načítaní súboru "{name}".', - msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', - msgInvalidFileType: 'Neplatný typ súboru "{name}". Iba "{types}" súborov sú podporované.', - msgInvalidFileExtension: 'Neplatná extenzia súboru "{name}". Iba "{extensions}" súborov sú podporované.', - msgFileTypes: { - 'image': 'obrázok', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Nahrávanie súboru bolo prerušené', - msgUploadThreshold: 'Spracovávam...', - msgUploadBegin: 'Inicializujem...', - msgUploadEnd: 'Hotovo', - msgUploadEmpty: 'Na nahrávanie nie sú k dispozícii žiadne platné údaje.', - msgUploadError: 'Chyba', - msgValidationError: 'Chyba overenia', - msgLoading: 'Nahrávanie súboru {index} z {files} …', - msgProgress: 'Nahrávanie súboru {index} z {files} - {name} - {percent}% dokončené.', - msgSelected: '{n} {files} vybraté', - msgFoldersNotAllowed: 'Tiahni a pusť iba súbory! Vynechané {n} pustené prečinok(y).', - msgImageWidthSmall: 'Šírka obrázku "{name}", musí byť minimálne {size} px.', - msgImageHeightSmall: 'Výška obrázku "{name}", musí byť minimálne {size} px.', - msgImageWidthLarge: 'Šírka obrázku "{name}" nemôže presiahnuť {size} px.', - msgImageHeightLarge: 'Výška obrázku "{name}" nesmie presiahnuť {size} px.', - msgImageResizeError: 'Nepodarilo sa získať veľkosť obrázka pre zmenu veľkosti.', - msgImageResizeException: 'Chyba pri zmene veľkosti obrázka.
        {errors}
        ', - msgAjaxError: 'Pri operácii {operation} sa vyskytla chyba. Skúste to prosím neskôr!', - msgAjaxProgressError: '{operation} - neúspešné', - ajaxOperations: { - deleteThumb: 'odstrániť súbor', - uploadThumb: 'nahrať súbor', - uploadBatch: 'nahrať várku súborov', - uploadExtra: 'odosielanie údajov z formulára' - }, - dropZoneTitle: 'Tiahni a pusť súbory tu …', - dropZoneClickTitle: '
        (alebo kliknite sem a vyberte {files})', - fileActionSettings: { - removeTitle: 'Odstrániť súbor', - uploadTitle: 'Nahrať súbor', - uploadRetryTitle: 'Znova nahrať', - downloadTitle: 'Stiahnuť súbor', - zoomTitle: 'Zobraziť podrobnosti', - dragTitle: 'Posunúť / Preskládať', - indicatorNewTitle: 'Ešte nenahral', - indicatorSuccessTitle: 'Nahraný', - indicatorErrorTitle: 'Chyba pri nahrávaní', - indicatorLoadingTitle: 'Nahrávanie ...' - }, - previewZoomButtonTitles: { - prev: 'Zobraziť predchádzajúci súbor', - next: 'Zobraziť následujúci súbor', - toggleheader: 'Prepnúť záhlavie', - fullscreen: 'Prepnúť zobrazenie na celú obrazovku', - borderless: 'Prepnúť na bezrámikové zobrazenie', - close: 'Zatvoriť detailný náhľad' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js deleted file mode 100644 index 490d7d61..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js +++ /dev/null @@ -1,98 +0,0 @@ -/*! - * FileInput Slovenian 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 kv1dr - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['sl'] = { - fileSingle: 'datoteka', - filePlural: 'datotek', - browseLabel: 'Prebrskaj …', - removeLabel: 'Odstrani', - removeTitle: 'Počisti izbrane datoteke', - cancelLabel: 'Prekliči', - cancelTitle: 'Prekliči nalaganje', - uploadLabel: 'Naloži', - uploadTitle: 'Naloži izbrane datoteke', - msgNo: 'Ne', - msgNoFilesSelected: 'Nobena datoteka ni izbrana', - msgCancelled: 'Preklicano', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Podroben predogled', - msgSizeTooLarge: 'Datoteka "{name}" ({size} KB) presega največjo dovoljeno velikost za nalaganje {maxSize} KB.', - msgFilesTooLess: 'Za nalaganje morate izbrati vsaj {n} {files}.', - msgFilesTooMany: 'Število datotek, izbranih za nalaganje ({n}) je prekoračilo največjo dovoljeno število {m}.', - msgFileNotFound: 'Datoteka "{name}" ni bila najdena!', - msgFileSecured: 'Zaradi varnostnih omejitev nisem mogel prebrati datoteko "{name}".', - msgFileNotReadable: 'Datoteka "{name}" ni berljiva.', - msgFilePreviewAborted: 'Predogled datoteke "{name}" preklican.', - msgFilePreviewError: 'Pri branju datoteke "{name}" je prišlo do napake.', - msgInvalidFileType: 'Napačen tip datoteke "{name}". Samo "{types}" datoteke so podprte.', - msgInvalidFileExtension: 'Napačna končnica datoteke "{name}". Samo "{extensions}" datoteke so podprte.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Nalaganje datoteke je bilo preklicano', - msgUploadThreshold: 'Procesiram...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', - msgValidationError: 'Napaki pri validiranju', - msgLoading: 'Nalaganje datoteke {index} od {files} …', - msgProgress: 'Nalaganje datoteke {index} od {files} - {name} - {percent}% dokončano.', - msgSelected: '{n} {files} izbrano', - msgFoldersNotAllowed: 'Povlecite in spustite samo datoteke! Izpuščenih je bilo {n} map.', - msgImageWidthSmall: 'Širina slike "{name}" mora biti vsaj {size} px.', - msgImageHeightSmall: 'Višina slike "{name}" mora biti vsaj {size} px.', - msgImageWidthLarge: 'Širina slike "{name}" ne sme preseči {size} px.', - msgImageHeightLarge: 'Višina slike "{name}" ne sme preseči {size} px.', - msgImageResizeError: 'Nisem mogel pridobiti dimenzij slike za spreminjanje velikosti.', - msgImageResizeException: 'Napaka pri spreminjanju velikosti 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: 'Povlecite in spustite datoteke sem …', - dropZoneClickTitle: '
        (ali kliknite sem za izbiro {files})', - fileActionSettings: { - removeTitle: 'Odstrani datoteko', - uploadTitle: 'Naloži datoteko', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'Poglej podrobnosti', - dragTitle: 'Premaki / Razporedi', - indicatorNewTitle: 'Še ni naloženo', - indicatorSuccessTitle: 'Naloženo', - indicatorErrorTitle: 'Napaka pri nalaganju', - indicatorLoadingTitle: 'Nalagam ...' - }, - previewZoomButtonTitles: { - prev: 'Poglej prejšno datoteko', - next: 'Poglej naslednjo datoteko', - toggleheader: 'Preklopi glavo', - fullscreen: 'Preklopi celozaslonski način', - borderless: 'Preklopi način brez robov', - close: 'Zapri predogled podrobnosti' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js deleted file mode 100644 index 038b1d99..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js +++ /dev/null @@ -1,99 +0,0 @@ -/*! - * FileInput <_LANG_> 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['sv'] = { - fileSingle: 'fil', - filePlural: 'filer', - browseLabel: 'Bläddra …', - removeLabel: 'Ta bort', - removeTitle: 'Rensa valda filer', - cancelLabel: 'Avbryt', - cancelTitle: 'Avbryt pågående uppladdning', - uploadLabel: 'Ladda upp', - uploadTitle: 'Ladda upp valda filer', - msgNo: 'Nej', - msgNoFilesSelected: 'Inga filer valda', - msgCancelled: 'Avbruten', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'detaljerad förhandsgranskning', - msgFileRequired: 'You must select a file to upload.', - msgSizeTooSmall: 'Filen "{name}" ({size} KB) är för liten och måste vara större än {minSize} KB.', - msgSizeTooLarge: 'File "{name}" ({size} KB) överstiger högsta tillåtna uppladdningsstorlek {maxSize} KB.', - msgFilesTooLess: 'Du måste välja minst {n} {files} för att ladda upp.', - msgFilesTooMany: 'Antal filer valda för uppladdning ({n}) överstiger högsta tillåtna gränsen {m}.', - msgFileNotFound: 'Filen "{name}" kunde inte hittas!', - msgFileSecured: 'Säkerhetsbegränsningar förhindrar att läsa filen "{name}".', - msgFileNotReadable: 'Filen "{name}" är inte läsbar.', - msgFilePreviewAborted: 'Filförhandsvisning avbröts för "{name}".', - msgFilePreviewError: 'Ett fel uppstod vid inläsning av filen "{name}".', - msgInvalidFileName: 'Ogiltiga eller tecken som inte stöds i filnamnet "{name}".', - msgInvalidFileType: 'Ogiltig typ för filen "{name}". Endast "{types}" filtyper stöds.', - msgInvalidFileExtension: 'Ogiltigt filtillägg för filen "{name}". Endast "{extensions}" filer stöds.', - msgFileTypes: { - 'image': 'bild', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'ljud', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'objekt' - }, - msgUploadAborted: 'Filöverföringen avbröts', - msgUploadThreshold: 'Bearbetar...', - msgUploadBegin: 'Påbörjar...', - msgUploadEnd: 'Färdig', - msgUploadEmpty: 'Ingen giltig data tillgänglig för uppladdning.', - msgUploadError: 'Error', - msgValidationError: 'Valideringsfel', - msgLoading: 'Laddar fil {index} av {files} …', - msgProgress: 'Laddar fil {index} av {files} - {name} - {percent}% färdig.', - msgSelected: '{n} {files} valda', - msgFoldersNotAllowed: 'Endast drag & släppfiler! Skippade {n} släpta mappar.', - msgImageWidthSmall: 'Bredd på bildfilen "{name}" måste minst vara {size} pixlar.', - msgImageHeightSmall: 'Höjden på bildfilen "{name}" måste minst vara {size} pixlar.', - msgImageWidthLarge: 'Bredd på bildfil "{name}" kan inte överstiga {size} pixlar.', - msgImageHeightLarge: 'Höjden på bildfilen "{name}" kan inte överstiga {size} pixlar.', - msgImageResizeError: 'Det gick inte att hämta bildens dimensioner för att ändra storlek.', - msgImageResizeException: 'Fel vid storleksändring av bilden.
        {errors}
        ', - msgAjaxError: 'Något gick fel med {operation} operationen. Försök igen senare!', - msgAjaxProgressError: '{operation} misslyckades', - ajaxOperations: { - deleteThumb: 'file delete', - uploadThumb: 'file upload', - uploadBatch: 'batch file upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: 'Drag & släpp filer här …', - dropZoneClickTitle: '
        (eller klicka för att markera {files})', - fileActionSettings: { - removeTitle: 'Ta bort fil', - uploadTitle: 'Ladda upp fil', - uploadRetryTitle: 'Retry upload', - zoomTitle: 'Visa detaljer', - dragTitle: 'Flytta / Ändra ordning', - indicatorNewTitle: 'Inte uppladdat ännu', - indicatorSuccessTitle: 'Uppladdad', - indicatorErrorTitle: 'Uppladdningsfel', - indicatorLoadingTitle: 'Laddar upp...' - }, - previewZoomButtonTitles: { - prev: 'Visa föregående fil', - next: 'Visa nästa fil', - toggleheader: 'Rubrik', - fullscreen: 'Fullskärm', - borderless: 'Gränslös', - close: 'Stäng detaljerad förhandsgranskning' - } - }; -})(window.jQuery); \ No newline at end of file diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js deleted file mode 100644 index 7a2d0460..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * FileInput Thai 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['th'] = { - 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}" เป็น extension ที่ไมถูกต้อง, อนุญาตเฉพาะไฟล์ extension "{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: 'Drag & drop เฉพาะไฟล์เท่านั้น! ข้าม dropped folder จำนวน {n}', - msgImageWidthSmall: 'ความกว้างของภาพไฟล์ "{name}" ต้องมีอย่างน้อย {size} px.', - msgImageHeightSmall: 'ความสูงของภาพไฟล์ "{name}" ต้องมีอย่างน้อย {size} px.', - msgImageWidthLarge: 'ความกว้างของภาพไฟล์ "{name}" ไม่เกิน {size} พิกเซล.', - msgImageHeightLarge: 'ความสูงของไฟล์ภาพ "{name}" ไม่เกิน {size} พิกเซล.', - 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: 'Drag & drop ไฟล์ตรงนี้ …', - 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); \ No newline at end of file diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js deleted file mode 100644 index 1fe6a383..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js +++ /dev/null @@ -1,99 +0,0 @@ -/*! - * FileInput Turkish 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['tr'] = { - fileSingle: 'dosya', - filePlural: 'dosyalar', - browseLabel: 'Gözat …', - removeLabel: 'Sil', - removeTitle: 'Seçilen dosyaları sil', - cancelLabel: 'İptal', - cancelTitle: 'Devam eden yüklemeyi iptal et', - uploadLabel: 'Yükle', - uploadTitle: 'Seçilen dosyaları yükle', - msgNo: 'Hayır', - msgNoFilesSelected: '', - msgCancelled: 'İptal edildi', - msgPlaceholder: 'Seçilen {files}...', - msgZoomModalHeading: 'Detaylı Önizleme', - msgFileRequired: 'Yüklemek için bir dosya seçmelisiniz.', - msgSizeTooSmall: '"{name}"({size} KB) dosyası çok küçük ve {minSize} KB boyutundan büyük olmalıdır.', - msgSizeTooLarge: '"{name}" dosyasının boyutu ({size} KB) izin verilen azami dosya boyutu olan {maxSize} KB\'tan büyük.', - msgFilesTooLess: 'Yüklemek için en az {n} {files} dosya seçmelisiniz.', - msgFilesTooMany: 'Yüklemek için seçtiğiniz dosya sayısı ({n}) azami limitin ({m}) altında olmalıdır.', - msgFileNotFound: '"{name}" dosyası bulunamadı!', - msgFileSecured: 'Güvenlik kısıtlamaları "{name}" dosyasının okunmasını engelliyor.', - msgFileNotReadable: '"{name}" dosyası okunabilir değil.', - msgFilePreviewAborted: '"{name}" dosyası için önizleme iptal edildi.', - msgFilePreviewError: '"{name}" dosyası okunurken bir hata oluştu.', - msgInvalidFileName: '"{name}" dosya adında geçersiz veya desteklenmeyen karakterler var.', - msgInvalidFileType: '"{name}" dosyasının türü geçerli değil. Yalnızca "{types}" türünde dosyalara izin veriliyor.', - msgInvalidFileExtension: '"{name}" dosyasının uzantısı geçersiz. Yalnızca "{extensions}" uzantılı dosyalara izin veriliyor.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Dosya yükleme iptal edildi', - msgUploadThreshold: 'İşlem yapılıyor...', - msgUploadBegin: 'Başlıyor...', - msgUploadEnd: 'Başarılı', - msgUploadEmpty: 'Yüklemek için geçerli veri mevcut değil.', - msgUploadError: 'Hata', - msgValidationError: 'Doğrulama Hatası', - msgLoading: 'Dosya yükleniyor {index} / {files} …', - msgProgress: 'Dosya yükleniyor {index} / {files} - {name} - %{percent} tamamlandı.', - msgSelected: '{n} {files} seçildi', - msgFoldersNotAllowed: 'Yalnızca dosyaları sürükleyip bırakabilirsiniz! {n} dizin(ler) göz ardı edildi.', - msgImageWidthSmall: '"{name}" adlı görüntü dosyasının genişliği en az {size} piksel olmalıdır.', - msgImageHeightSmall: '"{name}" adlı görüntü dosyasının yüksekliği en az {size} piksel olmalıdır.', - msgImageWidthLarge: '"{name}" adlı görüntü dosyasının genişliği {size} pikseli geçemez.', - msgImageHeightLarge: '"{name}" adlı görüntü dosyasının yüksekliği {size} pikseli geçemez.', - msgImageResizeError: 'Görüntü boyutlarını yeniden boyutlandıramadı.', - msgImageResizeException: 'Görüntü boyutlandırma sırasında hata.
        {errors}
        ', - 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.', - ajaxOperations: { - deleteThumb: 'dosya silme', - uploadThumb: 'dosya yükleme', - uploadBatch: 'toplu dosya yükleme', - uploadExtra: 'form verisi yükleme' - }, - dropZoneTitle: 'Dosyaları buraya sürükleyip bırakın', - dropZoneClickTitle: '
        (ya da {files} seçmek için tıklayınız)', - fileActionSettings: { - removeTitle: 'Dosyayı kaldır', - uploadTitle: 'Dosyayı yükle', - uploadRetryTitle: 'Retry upload', - zoomTitle: 'Ayrıntıları görüntüle', - dragTitle: 'Taşı / Yeniden düzenle', - indicatorNewTitle: 'Henüz yüklenmedi', - indicatorSuccessTitle: 'Yüklendi', - indicatorErrorTitle: 'Yükleme Hatası', - indicatorLoadingTitle: 'Yükleniyor ...' - }, - previewZoomButtonTitles: { - prev: 'Önceki dosyayı göster', - next: 'Sonraki dosyayı göster', - toggleheader: 'Üst bilgi geçiş', - fullscreen: 'Tam ekran geçiş', - borderless: 'Çerçevesiz moda geçiş', - close: 'Detaylı önizlemeyi kapat' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js deleted file mode 100644 index d1b7f3a1..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Ukrainian 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 CyanoFresh - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['uk'] = { - fileSingle: 'файл', - filePlural: 'файли', - browseLabel: 'Вибрати …', - removeLabel: 'Видалити', - removeTitle: 'Видалити вибрані файли', - cancelLabel: 'Скасувати', - cancelTitle: 'Скасувати поточне відвантаження', - uploadLabel: 'Відвантажити', - uploadTitle: 'Відвантажити обрані файли', - msgNo: 'Немає', - msgNoFilesSelected: '', - msgCancelled: 'Cкасовано', - msgPlaceholder: 'Оберіть {files}...', - msgZoomModalHeading: 'Детальний превью', - msgFileRequired: 'Ви повинні обрати файл для завантаження.', - msgSizeTooSmall: 'Файл "{name}" ({size} KB) занадто малий і повинен бути більший, ніж {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: 'Недійсні чи непідтримувані символи в імені файлу "{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: 'Обробка...', - msgUploadBegin: 'Ініціалізація...', - msgUploadEnd: 'Готово', - msgUploadEmpty: 'Немає доступних даних для відвантаження.', - msgUploadError: 'Помилка', - 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: 'Щось не так із операцією {operation}. Будь ласка, спробуйте пізніше!', - msgAjaxProgressError: 'помилка {operation}', - ajaxOperations: { - deleteThumb: 'видалити файл', - uploadThumb: 'відвантажити файл', - uploadBatch: 'batch file upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: 'Перетягніть файли сюди …', - dropZoneClickTitle: '
        (або клацність та оберіть {files})', - fileActionSettings: { - removeTitle: 'Видалити файл', - uploadTitle: 'Відвантажити файл', - uploadRetryTitle: 'Повторити відвантаження', - downloadTitle: 'Завантажити файл', - zoomTitle: 'Подивитися деталі', - dragTitle: 'Перенести / Переставити', - indicatorNewTitle: 'Ще не відвантажено', - indicatorSuccessTitle: 'Відвантажено', - indicatorErrorTitle: 'Помилка при відвантаженні', - indicatorLoadingTitle: 'Завантаження ...' - }, - previewZoomButtonTitles: { - prev: 'Переглянути попередній файл', - next: 'Переглянути наступний файл', - toggleheader: 'Перемкнути заголовок', - fullscreen: 'Перемкнути повноекранний режим', - borderless: 'Перемкнути режим без полів', - close: 'Закрити детальний перегляд' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js deleted file mode 100644 index c2c57168..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Uzbek 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 CyanoFresh - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales.uz = { - fileSingle: 'fayl', - filePlural: 'fayllar', - browseLabel: 'Tanlash …', - removeLabel: 'O\'chirish', - removeTitle: 'Tanlangan fayllarni tozalash', - cancelLabel: 'Bekor qilish', - cancelTitle: 'Joriy yuklab olishni bekor qilish', - uploadLabel: 'Yuklab olish', - uploadTitle: 'Tanlangan fayllarni yuklash', - msgNo: 'No', - msgNoFilesSelected: 'No files selected', - msgCancelled: 'Cancelled', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Detailed Preview', - 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}" fayl ({size} KB) ruxsat etilgan maksimal yuklash hajmidan {maxSize} KB ortiq. Yuklashni qayta urinib ko\'ring!', - msgFilesTooLess: 'Yuklash uchun kamida {n} {files} tanlashingiz kerak. Yuklashni qayta urinib ko\'ring!', - msgFilesTooMany: 'Tanlangan fayllar ({n}) ruxsat etilgan maksimal yuklash hajmidan {m} ortiq. Yuklashni qayta urinib ko\'ring!', - msgFileNotFound: '"{name}" fayl topilmaydi!', - msgFileSecured: 'Security restrictions prevent reading the file "{name}".', - msgFileNotReadable: '"{name}" fayl o\'qilmaydi.', - msgFilePreviewAborted: '"{name}" Ffylni oldindan ko\'rish jarayoni to\'xtatildi.', - msgFilePreviewError: '"{name}" faylni o\'qish paytida xatolik yuz berdi.', - msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', - msgInvalidFileType: '"{name}" fayl uchun yaroqsiz tur. Faqat "{types}" fayllari qo\'llab-quvvatlanadi.', - msgInvalidFileExtension: '"{name}" fayl uchun noto\'g\'ri kengaytma. Faqat "{extensions}" fayllari qo\'llab-quvvatlanadi.', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'The file upload was aborted', - msgUploadThreshold: 'Processing...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: 'Error', - msgValidationError: 'Fayl yuklash xatosi', - msgLoading: '{Files} dan {index} faylini yuklash …', - msgProgress: '{Files} dan {index}{name} faylini yuklashi - {percent}% tugallandi.', - msgSelected: '{n} {files} tanlangan', - msgFoldersNotAllowed: 'Faqat tortib qo\'yiladon fayllar! {n} o\'tirilgan tashlangan papka(lar).', - msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.', - msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.', - msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', - msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', - msgImageResizeError: 'Could not get the image dimensions to resize.', - msgImageResizeException: 'Error while resizing the image.
        {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: 'Fayllarni bu yerga tortib qo\'ying …', - dropZoneClickTitle: '
        (or click to select {files})', - fileActionSettings: { - removeTitle: 'Remove file', - uploadTitle: 'Upload file', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'View details', - dragTitle: 'Move / Rearrange', - indicatorNewTitle: 'Not uploaded yet', - indicatorSuccessTitle: 'Uploaded', - indicatorErrorTitle: 'Upload Error', - indicatorLoadingTitle: 'Uploading ...' - }, - 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/vi.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js deleted file mode 100644 index 7d140b5e..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Vietnamese 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['vi'] = { - fileSingle: 'tập tin', - filePlural: 'các tập tin', - browseLabel: 'Duyệt …', - removeLabel: 'Gỡ bỏ', - removeTitle: 'Bỏ tập tin đã chọn', - cancelLabel: 'Hủy', - cancelTitle: 'Hủy upload', - uploadLabel: 'Upload', - uploadTitle: 'Upload tập tin đã chọn', - msgNo: 'Không', - msgNoFilesSelected: 'Không tập tin nào được chọn', - msgCancelled: 'Đã hủy', - msgPlaceholder: 'Select {files}...', - msgZoomModalHeading: 'Chi tiết xem trước', - msgFileRequired: 'You must select a file to upload.', - msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', - msgSizeTooLarge: 'Tập tin "{name}" ({size} KB) vượt quá kích thước giới hạn cho phép {maxSize} KB.', - msgFilesTooLess: 'Bạn phải chọn ít nhất {n} {files} để upload.', - msgFilesTooMany: 'Số lượng tập tin upload ({n}) vượt quá giới hạn cho phép là {m}.', - msgFileNotFound: 'Không tìm thấy tập tin "{name}"!', - msgFileSecured: 'Các hạn chế về bảo mật không cho phép đọc tập tin "{name}".', - msgFileNotReadable: 'Không đọc được tập tin "{name}".', - msgFilePreviewAborted: 'Đã dừng xem trước tập tin "{name}".', - msgFilePreviewError: 'Đã xảy ra lỗi khi đọc tập tin "{name}".', - msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', - msgInvalidFileType: 'Tập tin "{name}" không hợp lệ. Chỉ hỗ trợ loại tập tin "{types}".', - msgInvalidFileExtension: 'Phần mở rộng của tập tin "{name}" không hợp lệ. Chỉ hỗ trợ phần mở rộng "{extensions}".', - msgFileTypes: { - 'image': 'image', - 'html': 'HTML', - 'text': 'text', - 'video': 'video', - 'audio': 'audio', - 'flash': 'flash', - 'pdf': 'PDF', - 'object': 'object' - }, - msgUploadAborted: 'Đã dừng upload', - msgUploadThreshold: 'Đang xử lý...', - msgUploadBegin: 'Initializing...', - msgUploadEnd: 'Done', - msgUploadEmpty: 'No valid data available for upload.', - msgUploadError: '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.', - msgSelected: '{n} {files} được chọn', - msgFoldersNotAllowed: 'Chỉ kéo thả tập tin! Đã bỏ qua {n} thư mục.', - msgImageWidthSmall: 'Chiều rộng của hình ảnh "{name}" phải tối thiểu là {size} px.', - msgImageHeightSmall: 'Chiều cao của hình ảnh "{name}" phải tối thiểu là {size} px.', - msgImageWidthLarge: 'Chiều rộng của hình ảnh "{name}" không được quá {size} px.', - msgImageHeightLarge: 'Chiều cao của hình ảnh "{name}" không được quá {size} px.', - msgImageResizeError: 'Không lấy được kích thước của hình ảnh để resize.', - msgImageResizeException: 'Resize hình ảnh bị lỗi.
        {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: 'Kéo thả tập tin vào đây …', - dropZoneClickTitle: '
        (hoặc click để chọn {files})', - fileActionSettings: { - removeTitle: 'Gỡ bỏ', - uploadTitle: 'Upload tập tin', - uploadRetryTitle: 'Retry upload', - downloadTitle: 'Download file', - zoomTitle: 'Phóng lớn', - dragTitle: 'Di chuyển / Sắp xếp lại', - indicatorNewTitle: 'Chưa được upload', - indicatorSuccessTitle: 'Đã upload', - indicatorErrorTitle: 'Upload bị lỗi', - indicatorLoadingTitle: 'Đang upload ...' - }, - previewZoomButtonTitles: { - prev: 'Xem tập tin phía trước', - next: 'Xem tập tin tiếp theo', - toggleheader: 'Ẩn/hiện tiêu đề', - fullscreen: 'Bật/tắt toàn màn hình', - borderless: 'Bật/tắt chế độ không viền', - close: 'Đóng' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js deleted file mode 100644 index 49f7710f..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js +++ /dev/null @@ -1,102 +0,0 @@ -/*! - * FileInput Chinese Traditional 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 kangqf - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['zh-TW'] = { - fileSingle: '單一檔案', - filePlural: '複選檔案', - browseLabel: '瀏覽 …', - removeLabel: '移除', - removeTitle: '清除選取檔案', - cancelLabel: '取消', - cancelTitle: '取消上傳中檔案', - uploadLabel: '上傳', - uploadTitle: '上傳選取檔案', - msgNo: '沒有', - msgNoFilesSelected: '未選擇檔案', - msgCancelled: '取消', - zoomTitle: '詳細資料', - msgPlaceholder: '選擇 {files}...', - msgZoomModalHeading: '內容預覽', - msgFileRequired: '必須選擇壹個文件上傳.', - msgSizeTooSmall: '檔案 "{name}" ({size} KB) 必須大於限定大小 {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: '附檔名 "{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: '處理中...', - msgUploadBegin: '正在初始化...', - msgUploadEnd: '完成', - msgUploadEmpty: '無效的文件上傳.', - msgUploadError: '上傳錯誤', - 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: '{operation} 發生錯誤. 請重試!', - msgAjaxProgressError: '{operation} 失敗', - ajaxOperations: { - deleteThumb: 'file delete', - uploadThumb: 'file upload', - uploadBatch: 'batch file upload', - uploadExtra: 'form data upload' - }, - dropZoneTitle: '拖曳檔案至此 …', - dropZoneClickTitle: '
        (或點擊{files}按鈕選擇文件)', - fileActionSettings: { - removeTitle: '刪除檔案', - uploadTitle: '上傳檔案', - uploadRetryTitle: '重試', - downloadTitle: '下載檔案', - zoomTitle: '詳細資料', - dragTitle: '移動 / 重置', - indicatorNewTitle: '尚未上傳', - indicatorSuccessTitle: '上傳成功', - indicatorErrorTitle: '上傳失敗', - indicatorLoadingTitle: '上傳中 ...' - }, - previewZoomButtonTitles: { - prev: '預覽上壹個文件', - next: '預覽下壹個文件', - toggleheader: '縮放', - fullscreen: '全屏', - borderless: '無邊界模式', - close: '關閉當前預覽' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js b/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js deleted file mode 100644 index 469fa380..00000000 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * FileInput Chinese 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 kangqf - * - * NOTE: this file must be saved in UTF-8 encoding. - */ -(function ($) { - "use strict"; - - $.fn.fileinputLocales['zh'] = { - fileSingle: '文件', - filePlural: '个文件', - browseLabel: '选择 …', - removeLabel: '移除', - removeTitle: '清除选中文件', - cancelLabel: '取消', - cancelTitle: '取消进行中的上传', - uploadLabel: '上传', - uploadTitle: '上传选中文件', - msgNo: '没有', - msgNoFilesSelected: '未选择文件', - msgCancelled: '取消', - msgPlaceholder: '选择 {files}...', - msgZoomModalHeading: '详细预览', - msgFileRequired: '必须选择一个文件上传.', - msgSizeTooSmall: '文件 "{name}" ({size} KB) 必须大于限定大小 {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: '文件名 "{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: '处理中...', - msgUploadBegin: '正在初始化...', - msgUploadEnd: '完成', - msgUploadEmpty: '无效的文件上传.', - msgUploadError: '上传出错', - msgValidationError: '验证错误', - msgLoading: '加载第 {index} 文件 共 {files} …', - msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', - msgSelected: '{n} {files} 选中', - msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', - msgImageWidthSmall: '图像文件的"{name}"的宽度必须是至少{size}像素.', - msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', - msgImageWidthLarge: '图像文件"{name}"的宽度不能超过{size}像素.', - msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', - msgImageResizeError: '无法获取的图像尺寸调整。', - msgImageResizeException: '调整图像大小时发生错误。
        {errors}
        ', - msgAjaxError: '{operation} 发生错误. 请重试!', - msgAjaxProgressError: '{operation} 失败', - ajaxOperations: { - deleteThumb: '删除文件', - uploadThumb: '上传文件', - uploadBatch: '批量上传', - uploadExtra: '表单数据上传' - }, - dropZoneTitle: '拖拽文件到这里 …
        支持多文件同时上传', - dropZoneClickTitle: '
        (或点击{files}按钮选择文件)', - fileActionSettings: { - removeTitle: '删除文件', - uploadTitle: '上传文件', - downloadTitle: '下载文件', - uploadRetryTitle: '重试', - zoomTitle: '查看详情', - dragTitle: '移动 / 重置', - indicatorNewTitle: '没有上传', - indicatorSuccessTitle: '上传', - indicatorErrorTitle: '上传错误', - indicatorLoadingTitle: '上传 ...' - }, - previewZoomButtonTitles: { - prev: '预览上一个文件', - next: '预览下一个文件', - toggleheader: '缩放', - fullscreen: '全屏', - borderless: '无边界模式', - close: '关闭当前预览' - } - }; -})(window.jQuery); diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt deleted file mode 100644 index 13c8531b..00000000 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ /dev/null @@ -1,100 +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 test.pl.treksoft.kvision - -import org.w3c.dom.Element -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.panel.Root -import kotlin.browser.document -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -interface TestSpec { - fun beforeTest() - - fun afterTest() - - fun run(code: () -> Unit) { - beforeTest() - code() - afterTest() - } -} - -interface SimpleSpec : TestSpec { - - override fun beforeTest() { - } - - override fun afterTest() { - } - -} - -interface DomSpec : TestSpec { - - override fun beforeTest() { - val fixture = "
        " + - "
        " - document.body?.insertAdjacentHTML("afterbegin", fixture) - } - - override fun afterTest() { - val div = document.getElementById("pretest") - div?.let { jQuery(it).remove() } - jQuery(".modal-backdrop").remove() - Root.shutdown() - } - - fun assertEqualsHtml(expected: String?, actual: String?, message: String?) { - if (expected != null && actual != null) { - val exp = jQuery(expected) - val act = jQuery(actual) - val result = exp[0]?.isEqualNode(act[0]) - if (result == true) { - assertTrue(result == true, message) - } else { - assertEquals(expected, actual, message) - } - } else { - assertEquals(expected, actual, message) - } - } -} - -interface WSpec : DomSpec { - - fun runW(code: (widget: Widget, element: Element?) -> Unit) { - run { - val root = Root("test", fixed = true) - val widget = Widget() - widget.id = "test_id" - root.add(widget) - val element = document.getElementById("test_id") - code(widget, element) - } - } - -} - -external fun require(name: String): dynamic diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt b/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt deleted file mode 100644 index de7a9315..00000000 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt +++ /dev/null @@ -1,57 +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 test.pl.treksoft.kvision.form.upload - -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.form.upload.UploadInput -import pl.treksoft.kvision.panel.Root -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test - -class UploadInputSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val upi = UploadInput(multiple = true).apply { - id = "idti" - } - root.add(upi) - val content = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } - assertEqualsHtml( - "", - content, - "Should render correct file input control for multiple files" - ) - upi.multiple = false - val content2 = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } - assertEqualsHtml( - "", - content2, - "Should render correct file input control for single file" - ) - } - } - -} diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt b/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt deleted file mode 100644 index 92078153..00000000 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt +++ /dev/null @@ -1,56 +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 test.pl.treksoft.kvision.form.upload - -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.form.upload.Upload -import pl.treksoft.kvision.panel.Root -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test - -class UploadSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val upi = Upload(multiple = true) - val id = upi.input.id - root.add(upi) - val content = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } - assertEqualsHtml( - "", - content, - "Should render correct file input control for multiple files" - ) - upi.multiple = false - val content2 = document.getElementById("test")?.let { jQuery(it).find("input.form-control")[0]?.outerHTML } - assertEqualsHtml( - "", - content2, - "Should render correct file input control for single file" - ) - } - } - -} diff --git a/kvision-modules/kvision-upload/webpack.config.d/css.js b/kvision-modules/kvision-upload/webpack.config.d/css.js deleted file mode 100644 index 5d710d35..00000000 --- a/kvision-modules/kvision-upload/webpack.config.d/css.js +++ /dev/null @@ -1,2 +0,0 @@ -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-upload/webpack.config.d/file.js deleted file mode 100644 index a5c7b5da..00000000 --- a/kvision-modules/kvision-upload/webpack.config.d/file.js +++ /dev/null @@ -1,6 +0,0 @@ -config.module.rules.push( - { - test: /\.(jpe?g|png|gif)$/i, - loader: 'file-loader' - } -); \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 3fc250ff..316306ce 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,26 +4,28 @@ include 'kvision-modules:kvision-base', 'kvision-modules:kvision-common-remote', 'kvision-modules:kvision-common-types', 'kvision-modules:kvision-bootstrap', -// 'kvision-modules:kvision-select', -// 'kvision-modules:kvision-datetime', -// 'kvision-modules:kvision-spinner', -// 'kvision-modules:kvision-richtext', -// 'kvision-modules:kvision-upload', -// 'kvision-modules:kvision-handlebars', - 'kvision-modules:kvision-i18n' -// 'kvision-modules:kvision-chart', -// 'kvision-modules:kvision-datacontainer', -// 'kvision-modules:kvision-dialog', -// 'kvision-modules:kvision-redux', -// 'kvision-modules:kvision-redux-kotlin', -// 'kvision-modules:kvision-tabulator', -// 'kvision-modules:kvision-moment', -// 'kvision-modules:kvision-pace', -// 'kvision-modules:kvision-remote', -// 'kvision-modules:kvision-select-remote', -// 'kvision-modules:kvision-tabulator-remote', -// 'kvision-modules:kvision-server-jooby', -// 'kvision-modules:kvision-server-ktor', -// 'kvision-modules:kvision-server-spring-boot', -// 'kvision-modules:kvision-electron', -// 'kvision-modules:kvision-cordova' + 'kvision-modules:kvision-bootstrap-css', + 'kvision-modules:kvision-bootstrap-datetime', + 'kvision-modules:kvision-bootstrap-spinner', + 'kvision-modules:kvision-bootstrap-upload', + 'kvision-modules:kvision-bootstrap-select', + 'kvision-modules:kvision-bootstrap-select-remote', + 'kvision-modules:kvision-bootstrap-dialog', + 'kvision-modules:kvision-richtext', + 'kvision-modules:kvision-handlebars', + 'kvision-modules:kvision-i18n', + 'kvision-modules:kvision-chart', + 'kvision-modules:kvision-datacontainer', + 'kvision-modules:kvision-fontawesome', + 'kvision-modules:kvision-redux', + 'kvision-modules:kvision-redux-kotlin', + 'kvision-modules:kvision-tabulator', + 'kvision-modules:kvision-moment', + 'kvision-modules:kvision-pace', + 'kvision-modules:kvision-remote', + 'kvision-modules:kvision-tabulator-remote', + 'kvision-modules:kvision-server-jooby', + 'kvision-modules:kvision-server-ktor', + 'kvision-modules:kvision-server-spring-boot', + 'kvision-modules:kvision-electron', + 'kvision-modules:kvision-cordova' diff --git a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt index d1a4a8be..d3d00851 100644 --- a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt @@ -30,8 +30,6 @@ import com.github.snabbdom.eventListenersModule import com.github.snabbdom.propsModule import com.github.snabbdom.styleModule import org.w3c.dom.HTMLElement -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.utils.isIE11 import kotlin.browser.document import kotlin.dom.clear @@ -44,20 +42,25 @@ external fun require(name: String): dynamic /** * Internal singleton object which initializes and configures KVision framework. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught", "LargeClass") -internal object KVManager { - private val kvisionBootstrap = try { - require("kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap - } catch (e: Throwable) { - } - private val elementResizeEvent = try { - require("element-resize-event") - } catch (e: Throwable) { - } - private val resizable = try { +@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") +object KVManager { + init { + try { + require("kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap + } catch (e: Throwable) { + } + try { + require("kvision-bootstrap-css").pl.treksoft.kvision.KVManagerBootstrapCss + } catch (e: Throwable) { + } + try { + require("kvision-fontawesome").pl.treksoft.kvision.KVManagerFontAwesome + } catch (e: Throwable) { + } + require("./css/style.css") require("jquery-resizable-dom") - } catch (e: Throwable) { } + internal val fecha = require("fecha") private val sdPatch = Snabbdom.init( arrayOf( @@ -81,28 +84,12 @@ internal object KVManager { return sdPatch(oldVNode, newVNode) } + /** + * @suppress + * Internal function. + */ @Suppress("UnsafeCastFromDynamic") - internal fun virtualize(html: String): VNode { + fun virtualize(html: String): VNode { return sdVirtualize(html) } - - @Suppress("UnsafeCastFromDynamic") - internal fun setResizeEvent(component: Component, callback: () -> Unit) { - if (!isIE11()) { - component.getElement()?.let { - elementResizeEvent(it, callback) - } - } - } - - @Suppress("UnsafeCastFromDynamic") - internal fun clearResizeEvent(component: Component) { - if (!isIE11()) { - if (component.getElement()?.asDynamic()?.__resizeTrigger__?.contentDocument != null) { - component.getElement()?.let { - elementResizeEvent.unbind(it) - } - } - } - } } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index e17d7ba9..24543b1f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -27,11 +27,9 @@ import com.github.snabbdom.h import org.w3c.dom.CustomEventInit import org.w3c.dom.DragEvent import org.w3c.dom.Node -import org.w3c.dom.events.MouseEvent import pl.treksoft.jquery.JQuery import pl.treksoft.jquery.jQuery import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.dropdown.ContextMenu import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.i18n.I18n.trans import pl.treksoft.kvision.panel.Root @@ -82,6 +80,10 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component * A role attribute of generated HTML element. */ var role: String? by refreshOnUpdate() + /** + * A tabindex attribute of generated HTML element. + */ + var tabindex: Int? by refreshOnUpdate() /** * Determines if the current widget is draggable. */ @@ -241,6 +243,9 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component role?.let { snattrs.add("role" to it) } + tabindex?.let { + snattrs.add("tabindex" to it.toString()) + } if (draggable == true) { snattrs.add("draggable" to "true") } @@ -439,7 +444,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun enableTooltip(options: TooltipOptions = TooltipOptions()): Widget { this.tooltipOptions = options - getElementJQueryD()?.tooltip(options.copy(title = options.title?.let { translate(it) }).toJs()) + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip(options.copy(title = options.title?.let { translate(it) }).toJs()) return this } @@ -449,7 +455,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun showTooltip(): Widget { if (this.tooltipOptions != null) { - getElementJQueryD()?.tooltip("show") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("show") } return this } @@ -460,7 +467,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun hideTooltip(): Widget { if (this.tooltipOptions != null) { - getElementJQueryD()?.tooltip("hide") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("hide") } return this } @@ -471,7 +479,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun disableTooltip(): Widget { this.tooltipOptions = null - getElementJQueryD()?.tooltip("destroy") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("dispose") return this } @@ -482,7 +491,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun enablePopover(options: PopoverOptions = PopoverOptions()): Widget { this.popoverOptions = options - getElementJQueryD()?.popover( + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover( options.copy(title = options.title?.let { translate(it) }, content = options.content?.let { translate(it) }).toJs() ) @@ -495,7 +505,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun showPopover(): Widget { if (this.popoverOptions != null) { - getElementJQueryD()?.popover("show") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("show") } return this } @@ -506,7 +517,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun hidePopover(): Widget { if (this.popoverOptions != null) { - getElementJQueryD()?.popover("hide") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("hide") } return this } @@ -517,7 +529,8 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ open fun disablePopover(): Widget { this.popoverOptions = null - getElementJQueryD()?.popover("destroy") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("dispose") return this } @@ -624,11 +637,13 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component internal open fun afterInsertInternal(node: VNode) { this.tooltipOptions?.let { @Suppress("UnsafeCastFromDynamic") - getElementJQueryD().tooltip(it.copy(title = it.title?.let { translate(it) }).toJs()) + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip(it.copy(title = it.title?.let { translate(it) }).toJs()) } this.popoverOptions?.let { @Suppress("UnsafeCastFromDynamic") - getElementJQueryD().popover( + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover( it.copy(title = it.title?.let { translate(it) }, content = it.content?.let { translate(it) }).toJs() ) @@ -647,10 +662,12 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component @Suppress("UnsafeCastFromDynamic") internal open fun afterDestroyInternal() { this.tooltipOptions?.let { - getElementJQueryD().tooltip("destroy") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("dispose") } this.popoverOptions?.let { - getElementJQueryD().popover("destroy") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("dispose") } } @@ -730,21 +747,6 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component } } - /** - * Sets context menu for the current widget. - * @param contextMenu a context menu - * @return current widget - */ - open fun setContextMenu(contextMenu: ContextMenu): Widget { - setEventListener { - contextmenu = { e: MouseEvent -> - e.preventDefault() - contextMenu.positionMenu(e) - } - } - return this - } - /** * @suppress * Internal function @@ -755,11 +757,7 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component ): Array { val translatedLabel = translate(label) return if (icon != null) { - if (icon.startsWith("fa-")) { - arrayOf(KVManager.virtualize(""), " $translatedLabel") - } else { - arrayOf(KVManager.virtualize(""), " $translatedLabel") - } + arrayOf(KVManager.virtualize(""), " $translatedLabel") } else if (image != null) { arrayOf(KVManager.virtualize(""), " $translatedLabel") } else { diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt deleted file mode 100644 index 5fac0494..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt +++ /dev/null @@ -1,98 +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.dropdown - -import org.w3c.dom.events.MouseEvent -import pl.treksoft.kvision.core.Display -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.ListType -import pl.treksoft.kvision.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 = setOf(), init: (ContextMenu.() -> Unit)? = null -) : ListTag(ListType.UL, 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 - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Widget.contextMenu( - fixedPosition: Boolean = false, - classes: Set = setOf(), init: (ContextMenu.() -> Unit)? = null - ): ContextMenu { - val contextMenu = ContextMenu(this, fixedPosition, classes).apply { init?.invoke(this) } - this.setContextMenu(contextMenu) - return contextMenu - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt deleted file mode 100644 index a521fe95..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ /dev/null @@ -1,333 +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.dropdown - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.CssSize -import pl.treksoft.kvision.core.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.Link -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.ListType -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.obj - -/** - * Useful options for use in DropDown's *elements* parameter. - */ -enum class DD(val option: String) { - HEADER("DD#HEADER"), - DISABLED("DD#DISABLED"), - SEPARATOR("DD#SEPARATOR") -} - -/** - * 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 disabled determines if the component is disabled on start - * @param forNavbar determines if the component will be used in a navbar - * @param withCaret determines if the dropdown button renders caret - * @param classes a set of CSS class names - */ -@Suppress("TooManyFunctions") -open class DropDown( - text: String, elements: List? = null, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, disabled: Boolean = false, val forNavbar: Boolean = false, - withCaret: Boolean = true, classes: Set = 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 - } - /** - * Determines if the dropdown is showing upwards. - */ - var dropup by refreshOnUpdate(false) - /** - * 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, withCaret, setOf("dropdown") - ) - - fun buttonId() = button.id - - internal val list: DropDownListTag = DropDownListTag(idc, setOf("dropdown-menu")) - - init { - 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): 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 { - 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 -> { - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(Link(it.first)) - tag - } - else -> Link(it.first, it.second) - } - } - 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 { - val cl = super.getSnClass().toMutableList() - if (dropup) - cl.add("dropup" to true) - else - cl.add("dropdown" to true) - return cl - } - - /** - * Toggles dropdown visibility. - */ - open fun toggle() { - this.list.getElementJQueryD()?.dropdown("toggle") - } - - 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? = null, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, disabled: Boolean = false, forNavbar: Boolean = false, - withCaret: Boolean = true, classes: Set = setOf(), init: (DropDown.() -> Unit)? = null - ): DropDown { - val dropDown = - DropDown( - text, - elements, - icon, - style, - disabled, - forNavbar, - withCaret, - classes - ).apply { init?.invoke(this) } - this.add(dropDown) - return dropDown - } - } -} - -internal class DropDownButton( - id: String, - text: String, - icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, - disabled: Boolean = false, - val forNavbar: Boolean = false, - val withCaret: Boolean = true, - classes: Set = setOf() -) : - Button(text, icon, style, ButtonType.BUTTON, disabled, classes) { - - init { - this.id = id - this.role = "button" - setInternalEventListener { - click = { e -> - if (parent?.parent is ContextMenu) e.asDynamic().dropDownCM = true - } - } - } - - override fun render(): VNode { - val text = createLabelWithIcon(text, icon, image) - return if (forNavbar) { - if (withCaret) { - val textWithCarret = text.toMutableList() - textWithCarret.add(" ") - textWithCarret.add(KVManager.virtualize("")) - render("a", textWithCarret.toTypedArray()) - } else { - render("a", text) - } - } else { - render("button", text) - } - } - - override fun getSnClass(): List { - return if (forNavbar) { - listOf("dropdown" to true) - } else { - super.getSnClass() - } - } - - override fun getSnAttrs(): List { - return super.getSnAttrs() + listOf( - "data-toggle" to "dropdown", "aria-haspopup" to "true", - "aria-expanded" to "false", "href" to "#" - ) - } -} - -internal class DropDownListTag(private val ariaId: String, classes: Set = setOf()) : ListTag( - ListType.UL, null, - false, classes -) { - - override fun getSnAttrs(): List { - return super.getSnAttrs() + listOf("aria-labelledby" to ariaId) - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt deleted file mode 100644 index 4cee7b7b..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt +++ /dev/null @@ -1,62 +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.dropdown - -import pl.treksoft.kvision.html.ListTag -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 = setOf()) : - Tag(TAG.LI, content, classes = classes + "dropdown-header") { - - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun ListTag.header(content: String? = null, classes: Set = 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 = setOf()): Header { - val header = Header(content, classes) - this.add(header) - return header - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt deleted file mode 100644 index c682b0e9..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt +++ /dev/null @@ -1,63 +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.dropdown - -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag - -/** - * Menu separator component. - * - * @constructor - * @param classes a set of CSS class names - */ -open class Separator(classes: Set = setOf()) : Tag(TAG.LI, classes = classes + "divider") { - - init { - role = "separator" - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun ListTag.separator(classes: Set = 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 = setOf()): Separator { - val separator = Separator(classes) - this.add(separator) - return separator - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt index 3019fb6f..f75007c0 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt @@ -30,8 +30,16 @@ import kotlin.js.Date * Input controls sizes. */ enum class InputSize(val className: String) { - LARGE("input-lg"), - SMALL("input-sm") + LARGE("form-control-lg"), + SMALL("form-control-sm") +} + +/** + * Input controls validation status. + */ +enum class ValidationStatus(val className: String) { + VALID("is-valid"), + INVALID("is-invalid") } interface FormInput : Component { @@ -47,6 +55,10 @@ interface FormInput : Component { * The name attribute of the generated HTML input element. */ var name: String? + /** + * Input control validation status. + */ + var validationStatus: ValidationStatus? /** * Makes the input element focused. @@ -78,6 +90,16 @@ interface FormControl : Component { get() = input.size set(value) { input.size = value + if (value == InputSize.SMALL) { + flabel.addCssClass("col-form-label-sm") + } else { + flabel.removeCssClass("col-form-label-sm") + } + if (value == InputSize.LARGE) { + flabel.addCssClass("col-form-label-lg") + } else { + flabel.removeCssClass("col-form-label-lg") + } } /** * The name attribute of the generated HTML input element. @@ -87,6 +109,14 @@ interface FormControl : Component { set(value) { input.name = value } + /** + * Input control validation status. + */ + var validationStatus: ValidationStatus? + get() = input.validationStatus + set(value) { + input.validationStatus = value + } /** * The actual input component. */ @@ -96,9 +126,9 @@ interface FormControl : Component { */ val flabel: FieldLabel /** - * Validation info component. + * Invalid feedback component. */ - val validationInfo: HelpBlock + val invalidFeedback: InvalidFeedback /** * Returns the value of the control. @@ -129,10 +159,11 @@ interface FormControl : Component { * Validator error message. */ var validatorError: String? - get() = validationInfo.content + get() = invalidFeedback.content set(value) { - validationInfo.content = value - validationInfo.visible = value != null + invalidFeedback.content = value + invalidFeedback.visible = value != null + input.validationStatus = if (value != null) ValidationStatus.INVALID else null refresh() } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt index 21281556..41e8010c 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt @@ -30,8 +30,8 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.check.CheckBox import pl.treksoft.kvision.form.check.Radio -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.form.check.RadioGroup +import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.types.KFile import kotlin.js.Date @@ -82,13 +82,14 @@ enum class FormTarget(internal val target: String) { * @param action the URL address to send data * @param enctype form encoding type * @param type form layout + * @param condensed determines if the form is condensed. * @param classes set of CSS class names * @param serializer a serializer for model type */ @Suppress("TooManyFunctions") open class FormPanel( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - private val type: FormType? = null, classes: Set = setOf(), + private val type: FormType? = null, condensed: Boolean = false, classes: Set = setOf(), serializer: KSerializer ) : SimplePanel(classes) { @@ -120,6 +121,10 @@ open class FormPanel( * Determines if the form should have autocomplete. */ var autocomplete: Boolean? by refreshOnUpdate() + /** + * Determines if the form is condensed. + */ + var condensed by refreshOnUpdate(condensed) /** * Function returning validation message. @@ -156,7 +161,7 @@ open class FormPanel( * @suppress * Internal property. */ - protected val validationAlert = Tag(TAG.H5, classes = setOf("alert", "alert-danger")).apply { + protected val validationAlert = Div(classes = setOf("alert", "alert-danger")).apply { role = "alert" visible = false } @@ -173,7 +178,9 @@ open class FormPanel( val cl = super.getSnClass().toMutableList() if (type != null) { cl.add(type.formType to true) + if (type == FormType.HORIZONTAL) cl.add("container-fluid" to true) } + if (condensed) cl.add("kv-form-condensed" to true) return cl } @@ -210,13 +217,28 @@ open class FormPanel( ): FormPanel { if (type == FormType.HORIZONTAL) { if (control is CheckBox || control is Radio) { - control.addCssClass("col-sm-offset-2") + control.addCssClass("form-group") + control.addSurroundingCssClass("row") + control.addCssClass("offset-sm-2") control.addCssClass("col-sm-10") + } else if (control is RadioGroup) { + control.addCssClass("row") + control.flabel.addCssClass("col-sm-2") + control.flabel.addCssClass("col-form-label") + control.container.addCssClass("col-sm-10") + control.invalidFeedback.addCssClass("offset-sm-2") + control.invalidFeedback.addCssClass("col-sm-10") } else { + control.addCssClass("row") control.flabel.addCssClass("col-sm-2") - control.input.addSurroundingCssClass("col-sm-10") - control.validationInfo.addCssClass("col-sm-offset-2") - control.validationInfo.addCssClass("col-sm-10") + control.flabel.addCssClass("col-form-label") + control.input.addCssClass("col-sm-10") + control.invalidFeedback.addCssClass("offset-sm-2") + control.invalidFeedback.addCssClass("col-sm-10") + } + } else { + if (control is CheckBox || control is Radio) { + control.addCssClass("form-group") } } super.add(control) @@ -399,10 +421,10 @@ open class FormPanel( */ inline fun Container.formPanel( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - type: FormType? = null, classes: Set = setOf(), + type: FormType? = null, condensed: Boolean = false, classes: Set = setOf(), noinline init: (FormPanel.() -> Unit)? = null ): FormPanel { - val formPanel = create(method, action, enctype, type, classes) + val formPanel = create(method, action, enctype, type, condensed, classes) init?.invoke(formPanel) this.add(formPanel) return formPanel @@ -411,10 +433,10 @@ open class FormPanel( @UseExperimental(ImplicitReflectionSerializer::class) inline fun create( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - type: FormType? = null, classes: Set = setOf(), + type: FormType? = null, condensed: Boolean = false, classes: Set = setOf(), noinline init: (FormPanel.() -> Unit)? = null ): FormPanel { - val formPanel = FormPanel(method, action, enctype, type, classes, K::class.serializer()) + val formPanel = FormPanel(method, action, enctype, type, condensed, classes, K::class.serializer()) init?.invoke(formPanel) return formPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt b/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt deleted file mode 100644 index 9ec3d8ae..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt +++ /dev/null @@ -1,37 +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 - -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag - -/** - * Helper class for Bootstrap help block element. - * - * @constructor - * @param content the text of the label - * @param rich determines if [content] can contain HTML code - */ -open class HelpBlock(content: String? = null, rich: Boolean = false) : Tag( - TAG.SPAN, content, rich, - classes = setOf("help-block", "small") -) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt b/src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt new file mode 100644 index 00000000..0362d03a --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt @@ -0,0 +1,37 @@ +/* + * 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 + +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +/** + * Helper class for Bootstrap help text element. + * + * @constructor + * @param content the text of the label + * @param rich determines if [content] can contain HTML code + */ +open class HelpText(content: String? = null, rich: Boolean = false) : Tag( + TAG.SMALL, content, rich, + classes = setOf("form-text", "text-muted") +) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt b/src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt new file mode 100644 index 00000000..dad68239 --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt @@ -0,0 +1,37 @@ +/* + * 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 + +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +/** + * Helper class for Bootstrap invalid feedback element. + * + * @constructor + * @param content the text of the label + * @param rich determines if [content] can contain HTML code + */ +open class InvalidFeedback(content: String? = null, rich: Boolean = false) : Tag( + TAG.DIV, content, rich, + classes = setOf("invalid-feedback") +) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt index 730488eb..f011b1cb 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.BoolFormControl import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -35,12 +35,11 @@ import pl.treksoft.kvision.utils.SnOn * Checkbox style options. */ enum class CheckBoxStyle(internal val className: String) { - DEFAULT("checkbox-default"), - PRIMARY("checkbox-primary"), - SUCCESS("checkbox-success"), - INFO("checkbox-info"), - WARNING("checkbox-warning"), - DANGER("checkbox-danger"), + PRIMARY("abc-checkbox-primary"), + SUCCESS("abc-checkbox-success"), + INFO("abc-checkbox-info"), + WARNING("abc-checkbox-warning"), + DANGER("abc-checkbox-danger"), } /** @@ -55,7 +54,7 @@ enum class CheckBoxStyle(internal val className: String) { open class CheckBox( value: Boolean = false, name: String? = null, label: String? = null, rich: Boolean = false -) : SimplePanel(setOf("checkbox")), BoolFormControl { +) : SimplePanel(setOf("form-check", "abc-checkbox")), BoolFormControl { /** * The selection state of the checkbox. @@ -106,22 +105,19 @@ open class CheckBox( var inline by refreshOnUpdate(false) private val idc = "kv_form_checkbox_$counter" - final override val input: CheckBoxInput = CheckBoxInput( - value, - setOf("styled") - ).apply { + final override val input: CheckBoxInput = CheckBoxInput(value, classes = setOf("form-check-input")).apply { this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf("form-check-label")) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) this.addInternal(flabel) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } @@ -147,13 +143,13 @@ open class CheckBox( cl.add(it.className to true) } if (circled) { - cl.add("checkbox-circle" to true) + cl.add("abc-checkbox-circle" to true) } if (inline) { - cl.add("checkbox-inline" to true) + cl.add("form-check-inline" to true) } if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt index a486b82e..f93fd436 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt @@ -28,6 +28,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus /** * Type of the check input control (checkbox or radio). @@ -94,6 +95,10 @@ abstract class CheckInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() override fun render(): VNode { return render("input") @@ -101,6 +106,9 @@ abstract class CheckInput( override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt index 29b3cb35..7ab509c4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.BoolFormControl import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -35,12 +35,12 @@ import pl.treksoft.kvision.utils.SnOn * Radio style options. */ enum class RadioStyle(internal val className: String) { - DEFAULT("radio-default"), - PRIMARY("radio-primary"), - SUCCESS("radio-success"), - INFO("radio-info"), - WARNING("radio-warning"), - DANGER("radio-danger"), + DEFAULT("abc-radio-default"), + PRIMARY("abc-radio-primary"), + SUCCESS("abc-radio-success"), + INFO("abc-radio-info"), + WARNING("abc-radio-warning"), + DANGER("abc-radio-danger"), } /** @@ -56,7 +56,7 @@ enum class RadioStyle(internal val className: String) { open class Radio( value: Boolean = false, extraValue: String? = null, name: String? = null, label: String? = null, rich: Boolean = false -) : SimplePanel(), BoolFormControl { +) : SimplePanel(classes = setOf("form-check")), BoolFormControl { /** * The selection state of the radio button. @@ -115,20 +115,20 @@ open class Radio( var inline by refreshOnUpdate(false) private val idc = "kv_form_radio_$counter" - final override val input: RadioInput = RadioInput(value).apply { + final override val input: RadioInput = RadioInput(value, classes = setOf("form-check-input")).apply { this.id = idc this.extraValue = extraValue this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf("form-check-label")) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this.eventTarget ?: this this.addInternal(input) this.addInternal(flabel) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } @@ -151,25 +151,21 @@ open class Radio( override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() if (!squared) { - cl.add("radio" to true) + cl.add("abc-radio" to true) style?.let { cl.add(it.className to true) } - if (inline) { - cl.add("radio-inline" to true) - } } else { - cl.add("checkbox" to true) - cl.add("kv-radio-checkbox" to true) + cl.add("abc-checkbox" to true) style?.let { cl.add(it.className.replace("radio", "checkbox") to true) } - if (inline) { - cl.add("checkbox-inline" to true) - } + } + if (inline) { + cl.add("form-check-inline" to true) } if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt index 6ac58bb7..b1a0a703 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt @@ -25,9 +25,10 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.panel.SimplePanel /** @@ -97,13 +98,33 @@ open class RadioGroup( set(value) { setSizeToChildren(value) } + override var validationStatus + get() = getValidationStatusFromChildren() + set(value) { + setValidationStatusToChildren(value) + } + override var validatorError: String? + get() = super.validatorError + set(value) { + super.validatorError = value + if (value!=null) { + container.addCssClass("is-invalid") + } else { + container.removeCssClass("is-invalid") + } + } private val idc = "kv_form_radiogroup_$counter" final override val input = RadioInput() final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + internal val container = SimplePanel(setOf("kv-radiogroup-container")) init { + this.addInternal(flabel) + this.addInternal(container) + this.addInternal(invalidFeedback) setChildrenFromOptions() setValueToChildren(value) setNameToChildren(name) @@ -113,7 +134,7 @@ open class RadioGroup( override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } if (inline) { cl.add("kv-radiogroup-inline" to true) @@ -124,7 +145,7 @@ open class RadioGroup( } private fun setValueToChildren(value: String?) { - val radios = getChildren().filterIsInstance() + val radios = container.getChildren().filterIsInstance() radios.forEach { it.value = false } radios.find { it.extraValue == value @@ -132,34 +153,42 @@ open class RadioGroup( } private fun getDisabledFromChildren(): Boolean { - return getChildren().filterIsInstance().firstOrNull()?.disabled ?: false + return container.getChildren().filterIsInstance().firstOrNull()?.disabled ?: false } private fun setDisabledToChildren(disabled: Boolean) { - getChildren().filterIsInstance().forEach { it.disabled = disabled } + container.getChildren().filterIsInstance().forEach { it.disabled = disabled } } private fun getNameFromChildren(): String? { - return getChildren().filterIsInstance().firstOrNull()?.name ?: this.idc + return container.getChildren().filterIsInstance().firstOrNull()?.name ?: this.idc } private fun setNameToChildren(name: String?) { val tname = name ?: this.idc - getChildren().filterIsInstance().forEach { it.name = tname } + container.getChildren().filterIsInstance().forEach { it.name = tname } } private fun getSizeFromChildren(): InputSize? { - return getChildren().filterIsInstance().firstOrNull()?.size + return container.getChildren().filterIsInstance().firstOrNull()?.size } private fun setSizeToChildren(size: InputSize?) { - getChildren().filterIsInstance().forEach { it.size = size } + container.getChildren().filterIsInstance().forEach { it.size = size } + super.size = size + } + + private fun getValidationStatusFromChildren(): ValidationStatus? { + return container.getChildren().filterIsInstance().firstOrNull()?.validationStatus + } + + private fun setValidationStatusToChildren(validationStatus: ValidationStatus?) { + container.getChildren().filterIsInstance().forEach { it.validationStatus = validationStatus } } private fun setChildrenFromOptions() { val currentName = this.name - super.removeAll() - this.addInternal(flabel) + container.removeAll() options?.let { val tname = currentName ?: this.idc val tinline = this.inline @@ -175,17 +204,16 @@ open class RadioGroup( } } } - super.addAll(c) + container.addAll(c) } - this.addInternal(validationInfo) } override fun focus() { - getChildren().filterIsInstance().firstOrNull()?.focus() + container.getChildren().filterIsInstance().firstOrNull()?.focus() } override fun blur() { - getChildren().filterIsInstance().firstOrNull()?.blur() + container.getChildren().filterIsInstance().firstOrNull()?.blur() } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt index fca681f6..d4301709 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt @@ -26,6 +26,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.panel.SimplePanel /** @@ -75,6 +76,11 @@ open class RadioGroupInput( set(value) { setSizeToChildren(value) } + override var validationStatus + get() = getValidationStatusFromChildren() + set(value) { + setValidationStatusToChildren(value) + } private val idc = "kv_form_radiogroup_$counter" @@ -128,6 +134,14 @@ open class RadioGroupInput( getChildren().filterIsInstance().forEach { it.size = size } } + private fun getValidationStatusFromChildren(): ValidationStatus? { + return getChildren().filterIsInstance().firstOrNull()?.validationStatus + } + + private fun setValidationStatusToChildren(validationStatus: ValidationStatus?) { + getChildren().filterIsInstance().forEach { it.validationStatus = validationStatus } + } + private fun setChildrenFromOptions() { val currentName = this.name super.removeAll() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt index 4d278ad2..bef14bfa 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -117,21 +117,21 @@ open class SimpleSelect( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt index b2ba1d43..31d32052 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.SimplePanel @@ -83,6 +84,10 @@ open class SimpleSelectInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() init { setChildrenFromOptions() @@ -129,6 +134,9 @@ open class SimpleSelectInput( override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt index 7c23615a..091278fc 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt @@ -24,7 +24,7 @@ package pl.treksoft.kvision.form.text import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -114,7 +114,7 @@ abstract class AbstractText(label: String? = null, rich: Boolean = false) : protected val idc = "kv_form_text_$counter" abstract override val input: AbstractTextInput final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { this.addInternal(flabel) @@ -128,7 +128,7 @@ abstract class AbstractText(label: String? = null, rich: Boolean = false) : override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt index e7ecba8a..192b33c8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus /** * Base class for basic text components. @@ -87,9 +88,16 @@ abstract class AbstractTextInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt index 7e4127f5..f493b06e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt @@ -64,7 +64,7 @@ open class Text( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt index d5058583..ccf17892 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt @@ -73,7 +73,7 @@ open class TextArea( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt index 0b6b43e5..aaa0f735 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt @@ -33,13 +33,23 @@ import pl.treksoft.kvision.core.Widget * Button styles. */ enum class ButtonStyle(val className: String) { - DEFAULT("btn-default"), PRIMARY("btn-primary"), + SECONDARY("btn-secondary"), SUCCESS("btn-success"), - INFO("btn-info"), - WARNING("btn-warning"), DANGER("btn-danger"), - LINK("btn-link") + WARNING("btn-warning"), + INFO("btn-info"), + LIGHT("btn-light"), + DARK("btn-dark"), + LINK("btn-link"), + OUTLINEPRIMARY("btn-outline-primary"), + OUTLINESECONDARY("btn-outline-secondary"), + OUTLINESUCCESS("btn-outline-success"), + OUTLINEDANGER("btn-outline-danger"), + OUTLINEWARNING("btn-outline-warning"), + OUTLINEINFO("btn-outline-info"), + OUTLINELIGHT("btn-outline-light"), + OUTLINEDARK("btn-outline-dark") } /** @@ -47,8 +57,7 @@ enum class ButtonStyle(val className: String) { */ enum class ButtonSize(internal val className: String) { LARGE("btn-lg"), - SMALL("btn-sm"), - XSMALL("btn-xs") + SMALL("btn-sm") } /** @@ -71,7 +80,7 @@ enum class ButtonType(internal val buttonType: String) { * @param classes a set of CSS class names */ open class Button( - text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.DEFAULT, type: ButtonType = ButtonType.BUTTON, + text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.PRIMARY, type: ButtonType = ButtonType.BUTTON, disabled: Boolean = false, classes: Set = setOf() ) : Widget(classes) { @@ -123,14 +132,16 @@ open class Button( if (block) { cl.add("btn-block" to true) } - if (disabled) { - cl.add("disabled" to true) - } return cl } override fun getSnAttrs(): List { - return super.getSnAttrs() + ("type" to type.buttonType) + val snattrs = super.getSnAttrs().toMutableList() + snattrs.add("type" to type.buttonType) + if (disabled) { + snattrs.add("disabled" to "disabled") + } + return snattrs } /** @@ -154,7 +165,7 @@ open class Button( fun Container.button( text: String, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, + style: ButtonStyle = ButtonStyle.PRIMARY, type: ButtonType = ButtonType.BUTTON, disabled: Boolean = false, classes: Set = setOf(), diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt b/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt index 7e10c10f..a9fb03db 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt @@ -39,13 +39,7 @@ open class Icon(icon: String) : Tag(TAG.SPAN) { override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() - if (icon.startsWith("fa-")) { - cl.add("fa" to true) - cl.add(icon to true) - } else { - cl.add("glyphicon" to true) - cl.add("glyphicon-$icon" to true) - } + icon.split(" ").forEach { cl.add(it to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt index 4d373270..81873088 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt @@ -32,8 +32,8 @@ import pl.treksoft.kvision.core.Widget * Image shapes. */ enum class ImageShape(internal val className: String) { - ROUNDED("img-rounded"), - CIRCLE("img-circle"), + ROUNDED("rounded"), + CIRCLE("rounded-circle"), THUMBNAIL("img-thumbnail") } @@ -89,7 +89,7 @@ open class Image( override fun getSnClass(): List { val cl = super.getSnClass().toMutableList() if (responsive) { - cl.add("img-responsive" to true) + cl.add("img-fluid" to true) } if (centered) { cl.add("center-block" to true) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt b/src/main/kotlin/pl/treksoft/kvision/html/Label.kt deleted file mode 100644 index 827c90fd..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt +++ /dev/null @@ -1,51 +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.html - -import pl.treksoft.kvision.core.Container - -/** - * Simple label component rendered as *span*. - * - * @constructor - * @param content label text - * @param rich determines if [content] can contain HTML code - */ -@Deprecated("Use Span class instead.") -open class Label(content: String? = null, rich: Boolean = false) : Span(content, rich) { - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - @Deprecated("User Span.Companion.span function instead.") - @Suppress("DEPRECATION") - fun Container.label( - content: String? = null, rich: Boolean = false, init: (Label.() -> Unit)? = null - ): Label { - val label = Label(content, rich).apply { init?.invoke(this) } - this.add(label) - return label - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt index 5fc613e2..63104248 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt @@ -26,7 +26,6 @@ import org.w3c.dom.events.MouseEvent import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.dropdown.DropDown import pl.treksoft.kvision.panel.SimplePanel /** @@ -99,37 +98,5 @@ open class Link( this.add(link) return link } - - /** - * DSL builder extension function for a disabled link in a dropdown list. - * - * It takes the same parameters as the constructor of the built component. - */ - fun ListTag.linkDisabled( - label: String, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null - ): Link { - val link = Link(label, null, icon, image, classes).apply { init?.invoke(this) } - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(link) - this.add(tag) - return link - } - - /** - * DSL builder extension function for a disabled link in a dropdown list. - * - * It takes the same parameters as the constructor of the built component. - */ - fun DropDown.linkDisabled( - label: String, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null - ): Link { - val link = Link(label, "javascript:void(0)", icon, image, classes).apply { init?.invoke(this) } - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(link) - this.add(tag) - return link - } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/List.kt b/src/main/kotlin/pl/treksoft/kvision/html/List.kt index 5fb489da..cf3f8be6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/List.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/List.kt @@ -27,7 +27,6 @@ import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.dropdown.DropDown import pl.treksoft.kvision.panel.SimplePanel /** @@ -98,14 +97,14 @@ open class ListTag( val childrenElements = children.filter { it.visible } val res = when (type) { ListType.UL, ListType.OL, ListType.UNSTYLED, ListType.INLINE -> childrenElements.map { v -> - if (v is Tag && v.type == TAG.LI || v is DropDown && v.forNavbar) { + if (v is Tag && v.type == TAG.LI /*|| v is DropDown && v.forNavbar*/) { v.renderVNode() } else { h("li", arrayOf(v.renderVNode())) } } ListType.DL, ListType.DL_HORIZ -> childrenElements.mapIndexed { index, v -> - if (v is Tag && v.type == TAG.LI || v is DropDown && v.forNavbar) { + if (v is Tag && v.type == TAG.LI /*|| v is DropDown && v.forNavbar*/) { v.renderVNode() } else { h(if (index % 2 == 0) "dt" else "dd", arrayOf(v.renderVNode())) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt index 512ca8b8..a5e855ae 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt @@ -73,6 +73,12 @@ enum class TAG(internal val tagName: String) { BR("br"), CAPTION("caption"), + FIGURE("figure"), + FIGCAPTION("figcaption"), + PICTURE("figcaption"), + SOURCE("figcaption"), + + TABLE("table"), THEAD("thead"), TH("th"), TBODY("tbody"), diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt deleted file mode 100644 index 5f5a1a80..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt +++ /dev/null @@ -1,121 +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.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", "ok", 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/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt b/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt deleted file mode 100644 index 5f0440a6..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt +++ /dev/null @@ -1,48 +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.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(""))) - } - - override fun getSnClass(): List { - val cl = super.getSnClass().toMutableList() - cl.add("close" to true) - return cl - } - - override fun getSnAttrs(): List { - return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Close") - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt deleted file mode 100644 index e16ca87e..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt +++ /dev/null @@ -1,176 +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.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, "remove") - private val noButton = Button(noTitle, "ban-circle") - private val yesButton = Button(yesTitle, "ok", 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/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt deleted file mode 100644 index 7f120f73..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt +++ /dev/null @@ -1,298 +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.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.SimplePanel -import pl.treksoft.kvision.utils.obj - -/** - * Modal window sizes. - */ -enum class ModalSize(val className: String) { - 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 = 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.H4, 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.addInternal(dialog) - val content = SimplePanel(setOf("modal-content")) - dialog.role = "document" - dialog.add(content) - closeIcon.visible = closeButton - closeIcon.setEventListener { - click = { - hide() - } - } - header.add(closeIcon) - header.add(captionTag) - checkHeaderVisibility() - content.add(header) - content.add(body) - content.add(footer) - @Suppress("LeakingThis") - modals.add(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): 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 { - 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 getSnAttrs(): List { - val pr = super.getSnAttrs().toMutableList() - pr.add("tabindex" to "-1") - return pr - } - - override fun getSnClass(): List { - 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() { - modals.remove(this) - } - - companion object { - internal var modals = mutableListOf() - } -} - -/** - * 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 { - val cl = super.getSnClass().toMutableList() - size?.let { - cl.add(it.className to true) - } - return cl - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt b/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt deleted file mode 100644 index 3bbb6eed..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt +++ /dev/null @@ -1,73 +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.navbar - -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag - -/** - * 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 = setOf(), init: (Nav.() -> Unit)? = null) : - Tag(TAG.UL, 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 { - val cl = super.getSnClass().toMutableList() - cl.add("nav" to true) - cl.add("navbar-nav" to true) - if (rightAlign) { - cl.add("navbar-right" 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 = setOf(), init: (Nav.() -> Unit)? = null - ): Nav { - val nav = Nav(rightAlign, classes).apply { init?.invoke(this) } - this.add(nav) - return nav - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt b/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt deleted file mode 100644 index 725c298e..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt +++ /dev/null @@ -1,74 +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.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 = 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 { - val cl = super.getSnClass().toMutableList() - cl.add("navbar-form" to true) - if (rightAlign) { - cl.add("navbar-right" to true) - } else { - cl.add("navbar-left" 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 = setOf(), init: (NavForm.() -> Unit)? = null - ): NavForm { - val navForm = NavForm(rightAlign, classes).apply { init?.invoke(this) } - this.add(navForm) - return navForm - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt b/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt deleted file mode 100644 index 2080bb8e..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt +++ /dev/null @@ -1,195 +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.navbar - -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.html.Link -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag.Companion.tag -import pl.treksoft.kvision.panel.SimplePanel - -/** - * Navbar types. - */ -enum class NavbarType(internal val navbarType: String) { - FIXEDTOP("navbar-fixed-top"), - FIXEDBOTTOM("navbar-fixed-bottom"), - STATICTOP("navbar-static-top") -} - -/** - * The Bootstrap Navbar container. - * - * @constructor - * @param label the navbar label - * @param type the navbar type - * @param inverted determines if the navbar is inverted - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class Navbar( - label: String? = null, - type: NavbarType? = null, - inverted: Boolean = false, - classes: Set = 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) - /** - * Determines if the navbar is inverted. - */ - var inverted by refreshOnUpdate(inverted) - - 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 { - val c = SimplePanel(setOf("container-fluid")) { - simplePanel(setOf("navbar-header")) { - add(NavbarButton(idc)) - add(brandLink) - } - add(container) - } - addInternal(c) - 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): 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 { - return container.getChildren() - } - - override fun getSnClass(): List { - val cl = super.getSnClass().toMutableList() - cl.add("navbar" to true) - type?.let { - cl.add(it.navbarType to true) - } - if (inverted) { - cl.add("navbar-inverse" to true) - } else { - cl.add("navbar-default" 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, - inverted: Boolean = false, - classes: Set = setOf(), init: (Navbar.() -> Unit)? = null - ): Navbar { - val navbar = Navbar(label, type, inverted, classes, init) - this.add(navbar) - return navbar - } - } -} - -/** - * @suppress - * Internal component. - * The Bootstrap Navbar header button. - */ -internal class NavbarButton(private val idc: String, toggle: String = "Toggle navigation") : - SimplePanel(setOf("navbar-toggle", "collapsed")) { - - init { - tag(TAG.SPAN, toggle, classes = setOf("sr-only")) - tag(TAG.SPAN, classes = setOf("icon-bar")) - tag(TAG.SPAN, classes = setOf("icon-bar")) - tag(TAG.SPAN, classes = setOf("icon-bar")) - } - - override fun render(): VNode { - return render("button", childrenVNodes()) - } - - override fun getSnAttrs(): List { - return super.getSnAttrs() + listOf( - "type" to "button", - "data-toggle" to "collapse", - "data-target" to "#$idc", - "aria-expanded" to "false" - ) - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt deleted file mode 100644 index 7a5b07d6..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt +++ /dev/null @@ -1,185 +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.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) { - XS("xs"), - SM("sm"), - MD("md"), - LG("lg") -} - -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 = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null -) : SimplePanel(classes + "container-fluid") { - - /** - * Text align of grid cells. - */ - var align by refreshOnUpdate(align) { refreshRowContainers() } - - internal val map = mutableMapOf>() - 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, 0) - val cCol = maxOf(col, 0) - if (row > rows - 1) rows = cRow + 1 - if (col > cols - 1) cols = cCol + 1 - map.getOrPut(cRow) { mutableMapOf() }[cCol] = WidgetParam(child, size, offset) - 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): 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 0 until rows) { - val rowContainer = SimplePanel(setOf("row")) - val row = map[i] - if (row != null) { - (0 until 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("col-" + gridSize.size + "-offset-" + 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 = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null - ): ResponsiveGridPanel { - val responsiveGridPanel = ResponsiveGridPanel(gridSize, rows, cols, align, classes, init) - this.add(responsiveGridPanel) - return responsiveGridPanel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt index 2d9dcc46..e0c70ac4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt @@ -27,8 +27,7 @@ import org.w3c.dom.HTMLElement import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Style -import pl.treksoft.kvision.dropdown.ContextMenu -import pl.treksoft.kvision.modal.Modal +import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.utils.snClasses import pl.treksoft.kvision.utils.snOpt @@ -52,7 +51,7 @@ class Root( private val fixed: Boolean = false, init: (Root.() -> Unit)? = null ) : SimplePanel() { - private val contextMenus: MutableList = mutableListOf() + private val contextMenus: MutableList = mutableListOf() private var rootVnode: VNode = renderVNode() internal var renderDisabled = false @@ -71,7 +70,7 @@ class Root( } roots.add(this) if (isFirstRoot) { - Modal.modals.forEach { it.parent = this } + modals.forEach { it.parent = this } } @Suppress("LeakingThis") init?.invoke(this) @@ -87,7 +86,7 @@ class Root( } } - internal fun addContextMenu(contextMenu: ContextMenu) { + fun addContextMenu(contextMenu: Widget) { contextMenus.add(contextMenu) contextMenu.parent = this this.setInternalEventListener { @@ -114,7 +113,7 @@ class Root( private fun modalsVNodes(): Array { return if (isFirstRoot) { - Modal.modals.filter { it.visible }.map { it.renderVNode() }.toTypedArray() + modals.filter { it.visible }.map { it.renderVNode() }.toTypedArray() } else { arrayOf() } @@ -150,12 +149,13 @@ class Root( roots.remove(this) if (isFirstRoot) { Style.styles.clear() - Modal.modals.clear() + modals.clear() } } companion object { internal var counter = 0 + private val modals: MutableList = mutableListOf() /** * @suppress internal function @@ -167,18 +167,26 @@ class Root( internal val roots: MutableList = mutableListOf() - internal fun getFirstRoot(): Root? { + fun getFirstRoot(): Root? { return if (roots.isNotEmpty()) roots[0] else null } - internal fun getLastRoot(): Root? { + fun getLastRoot(): Root? { return if (roots.isNotEmpty()) roots[roots.size - 1] else null } + + fun addModal(modal: Widget) { + modals.add(modal) + } + + fun removeModal(modal: Widget) { + modals.remove(modal) + } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt index 2f702fad..91eeda80 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt @@ -35,7 +35,7 @@ import pl.treksoft.kvision.core.Widget */ open class SimplePanel(classes: Set = setOf(), init: (SimplePanel.() -> Unit)? = null) : Widget(classes), Container { - internal val children: MutableList = mutableListOf() + protected val children: MutableList = mutableListOf() init { @Suppress("LeakingThis") @@ -94,7 +94,7 @@ open class SimplePanel(classes: Set = setOf(), init: (SimplePanel.() -> } override fun getChildren(): List { - return ArrayList(children) + return children } override fun dispose() { diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt deleted file mode 100644 index f620f2b0..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt +++ /dev/null @@ -1,270 +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.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 = 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.children.forEach { - it.removeCssClass("active") - } - if (content.activeIndex in nav.children.indices) { - nav.children[content.activeIndex].addCssClass("active") - } - } - } - private val navClasses = when (tabPosition) { - TabPosition.TOP -> if (scrollableTabs) setOf("nav", "nav-tabs", "tabs-top") else setOf("nav", "nav-tabs") - TabPosition.LEFT -> setOf("nav", "nav-tabs", "tabs-left") - TabPosition.RIGHT -> setOf("nav", "nav-tabs", "tabs-right") - } - private var nav = Tag(TAG.UL, classes = navClasses) - private var content = StackPanel(false) - - internal val childrenMap = mutableMapOf() - - init { - when (tabPosition) { - TabPosition.TOP -> { - this.addInternal(nav) - this.addInternal(content) - } - TabPosition.LEFT -> { - this.addCssClass("clearfix") - val sizes = calculateSideClasses() - this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding"))) - this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding"))) - } - TabPosition.RIGHT -> { - this.addCssClass("clearfix") - val sizes = calculateSideClasses() - this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding"))) - this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding"))) - } - } - @Suppress("LeakingThis") - init?.invoke(this) - } - - private fun calculateSideClasses(): Pair { - return when (sideTabSize) { - SideTabSize.SIZE_1 -> Pair("col-xs-1", "col-xs-11") - SideTabSize.SIZE_2 -> Pair("col-xs-2", "col-xs-10") - SideTabSize.SIZE_3 -> Pair("col-xs-3", "col-xs-9") - SideTabSize.SIZE_4 -> Pair("col-xs-4", "col-xs-8") - SideTabSize.SIZE_5 -> Pair("col-xs-5", "col-xs-7") - SideTabSize.SIZE_6 -> Pair("col-xs-6", "col-xs-6") - } - } - - /** - * 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) { - role = "presentation" - link(title, "#", icon, image) { - if (closable) { - cicon("remove") { - addCssClass("kv-tab-close") - setEventListener { - click = { e -> - val actIndex = this@TabPanel.content.children.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.children.indexOf(childrenMap[currentIndex]) - e.preventDefault() - if (route != null) { - routing.navigate(route) - } - } - } - } - nav.add(tag) - if (nav.children.size == 1) { - tag.addCssClass("active") - activeIndex = 0 - } - content.add(panel) - if (route != null) { - routing.on(route, { _ -> activeIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) }) - .resolve() - } - return this - } - - /** - * Removes tab at given index. - */ - open fun removeTab(index: Int): TabPanel { - nav.remove(nav.children[index]) - childrenMap.filter { it.value == content.children[index] }.keys.firstOrNull()?.let { - childrenMap.remove(it) - } - content.remove(content.children[index]) - activeIndex = content.activeIndex - return this - } - - override fun add(child: Component): TabPanel { - return addTab("", child) - } - - override fun addAll(children: List): TabPanel { - children.forEach { add(it) } - return this - } - - override fun remove(child: Component): TabPanel { - val index = content.children.indexOf(child) - return removeTab(index) - } - - /** - * Returns child component by tab index. - * @param index tab index - */ - open fun getChildComponent(index: Int): Component? { - return content.children[index] - } - - /** - * Returns tab header component by tab index. - * @param index tab index - */ - open fun getNavComponent(index: Int): Tag? { - return nav.children[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 = setOf(), - init: (TabPanel.() -> Unit)? = null - ): TabPanel { - val tabPanel = TabPanel(tabPosition, sideTabSize, scrollableTabs, classes, init) - this.add(tabPanel) - return tabPanel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt b/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt deleted file mode 100644 index 4d0f4b93..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt +++ /dev/null @@ -1,162 +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.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 = 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 = 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/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt b/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt deleted file mode 100644 index 256d15d7..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt +++ /dev/null @@ -1,125 +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.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 = 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 { - 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 { - 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/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt index 0a79c9f9..44646897 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt @@ -64,6 +64,22 @@ open class Cell( this.add(cell) return cell } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Row.thcell( + content: String? = null, + rich: Boolean = false, + align: Align? = null, + classes: Set = setOf(), init: (HeaderCell.() -> Unit)? = null + ): HeaderCell { + val headerCell = HeaderCell(content, rich, align, Scope.ROW, classes, init) + this.add(headerCell) + return headerCell + } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt index b70845d6..14527f0f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt @@ -25,6 +25,11 @@ import pl.treksoft.kvision.html.Align import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +enum class Scope(internal val scope: String) { + ROW("row"), + COL("col") +} + /** * HTML table header cell component. * @@ -39,11 +44,16 @@ open class HeaderCell( content: String? = null, rich: Boolean = false, align: Align? = null, + scope: Scope? = null, classes: Set = setOf(), init: (HeaderCell.() -> Unit)? = null ) : Tag(TAG.TH, content, rich, align, classes) { init { + scope?.let { + @Suppress("LeakingThis") + setAttribute("scope", it.scope) + } @Suppress("LeakingThis") init?.invoke(this) } @@ -58,9 +68,10 @@ open class HeaderCell( content: String? = null, rich: Boolean = false, align: Align? = null, + scope: Scope? = null, classes: Set = setOf(), init: (HeaderCell.() -> Unit)? = null ): HeaderCell { - val cell = HeaderCell(content, rich, align, classes, init) + val cell = HeaderCell(content, rich, align, scope, classes, init) this.add(cell) return cell } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt index 11ed52fc..6d7c9b6e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt @@ -38,8 +38,29 @@ import pl.treksoft.kvision.utils.snOpt enum class TableType(val type: String) { STRIPED("table-striped"), BORDERED("table-bordered"), + BORDERLESS("table-borderless"), HOVER("table-hover"), - CONDENSED("table-condensed") + SMALL("table-sm"), + DARK("table-dark") +} + +/** + * HTML table responsive types. + */ +enum class ResponsiveType(val type: String) { + RESPONSIVE("table-responsive"), + RESPONSIVESM("table-responsive-sm"), + RESPONSIVEMD("table-responsive-md"), + RESPONSIVELG("table-responsive-lg"), + RESPONSIVEXL("table-responsive-xl") +} + +/** + * HTML table header types. + */ +enum class TheadType(internal val type: String) { + DARK("thead-dark"), + LIGHT("thead-light") } /** @@ -56,8 +77,8 @@ enum class TableType(val type: String) { @Suppress("TooManyFunctions") open class Table( headerNames: List? = null, - types: Set = setOf(), caption: String? = null, responsive: Boolean = false, - classes: Set = setOf(), init: (Table.() -> Unit)? = null + types: Set = setOf(), caption: String? = null, responsiveType: ResponsiveType? = null, + theadType: TheadType? = null, classes: Set = setOf(), init: (Table.() -> Unit)? = null ) : SimplePanel(classes + "table") { /** @@ -75,10 +96,13 @@ open class Table( /** * Determines if the table is responsive. */ - var responsive by refreshOnUpdate(responsive) + var responsiveType by refreshOnUpdate(responsiveType) private val theadRow = Tag(TAG.TR) - private val thead = Tag(TAG.THEAD).add(theadRow) + private val thead = Tag(TAG.THEAD).apply { + if (theadType != null) addCssClass(theadType.type) + add(theadRow) + } private val tbody = Tag(TAG.TBODY) init { @@ -94,7 +118,7 @@ open class Table( private fun refreshHeaders() { theadRow.removeAll() headerNames?.forEach { - theadRow.add(HeaderCell(it)) + theadRow.add(HeaderCell(it, scope = Scope.COL)) } } @@ -128,9 +152,9 @@ open class Table( } override fun render(): VNode { - return if (responsive) { + return if (responsiveType != null) { val opt = snOpt { - `class` = snClasses(listOf("table-responsive" to true)) + `class` = snClasses(listOf(responsiveType!!.type to true)) } h("div", opt, arrayOf(render("table", childrenVNodes()))) } else { @@ -185,11 +209,11 @@ open class Table( */ fun Container.table( headerNames: List? = null, - types: Set = setOf(), caption: String? = null, responsive: Boolean = false, - classes: Set = setOf(), init: (Table.() -> Unit)? = null + types: Set = setOf(), caption: String? = null, responsiveType: ResponsiveType? = null, + theadType: TheadType? = null, classes: Set = setOf(), init: (Table.() -> Unit)? = null ): Table { val table = - Table(headerNames, types, caption, responsive, classes, init) + Table(headerNames, types, caption, responsiveType, theadType, classes, init) this.add(table) return table } diff --git a/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt b/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt deleted file mode 100644 index ae57fc90..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt +++ /dev/null @@ -1,103 +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.toolbar - -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.panel.SimplePanel - -/** - * Button group sizes. - */ -enum class ButtonGroupSize(internal val className: String) { - LARGE("btn-group-lg"), - SMALL("btn-group-sm"), - XSMALL("btn-group-xs") -} - -/** - * Button group styles. - */ -enum class ButtonGroupStyle(internal val className: String) { - VERTICAL("btn-group-vertical"), - JUSTIFIED("btn-group-justified") -} - -/** - * The Bootstrap button group. - * - * @constructor - * @param size button group size - * @param style button group style - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class ButtonGroup( - size: ButtonGroupSize? = null, style: ButtonGroupStyle? = null, - classes: Set = setOf(), init: (ButtonGroup.() -> Unit)? = null -) : SimplePanel(classes) { - - /** - * Button group size. - */ - var size by refreshOnUpdate(size) - /** - * Button group style. - */ - var style by refreshOnUpdate(style) - - init { - role = "group" - @Suppress("LeakingThis") - init?.invoke(this) - } - - override fun getSnClass(): List { - val cl = super.getSnClass().toMutableList() - if (style != ButtonGroupStyle.VERTICAL) { - cl.add("btn-group" to true) - } - style?.let { - cl.add(it.className 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, style: ButtonGroupStyle? = null, - classes: Set = setOf(), init: (ButtonGroup.() -> Unit)? = null - ): ButtonGroup { - val group = ButtonGroup(size, style, classes).apply { init?.invoke(this) } - this.add(group) - return group - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt b/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt deleted file mode 100644 index f348f4cc..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt +++ /dev/null @@ -1,58 +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.toolbar - -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.panel.SimplePanel - -/** - * The Bootstrap toolbar. - * - * @constructor - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class Toolbar( - classes: Set = 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( - classes: Set = setOf(), init: (Toolbar.() -> Unit)? = null - ): Toolbar { - val toolbar = Toolbar(classes).apply { init?.invoke(this) } - this.add(toolbar) - return toolbar - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt b/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt deleted file mode 100644 index a3ceaf61..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt +++ /dev/null @@ -1,48 +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.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(""))) - } - - override fun getSnClass(): List { - val cl = super.getSnClass().toMutableList() - cl.add("close" to true) - return cl - } - - override fun getSnAttrs(): List { - return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Maximize") - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt b/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt deleted file mode 100644 index c8034d09..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt +++ /dev/null @@ -1,48 +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.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(""))) - } - - override fun getSnClass(): List { - val cl = super.getSnClass().toMutableList() - cl.add("close" to true) - return cl - } - - override fun getSnAttrs(): List { - return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Minimize") - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/src/main/kotlin/pl/treksoft/kvision/window/Window.kt deleted file mode 100644 index 3816de3a..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt +++ /dev/null @@ -1,446 +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.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.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 = 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.H4, caption, classes = setOf("modal-title")) - 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 - closeIcon.visible = closeButton - closeIcon.setEventListener { - click = { _ -> - @Suppress("UnsafeCastFromDynamic") - if (this@Window.dispatchEvent("closeWindow", obj {}) != false) { - close() - } - } - mousedown = { e -> - e.stopPropagation() - } - } - header.add(closeIcon) - maximizeIcon.visible = maximizeButton - maximizeIcon.setEventListener { - click = { _ -> - @Suppress("UnsafeCastFromDynamic") - if (this@Window.dispatchEvent("maximizeWindow", obj {}) != false) { - toggleMaximize() - } - } - mousedown = { e -> - e.stopPropagation() - } - } - header.add(maximizeIcon) - minimizeIcon.visible = minimizeButton - minimizeIcon.setEventListener { - click = { _ -> - @Suppress("UnsafeCastFromDynamic") - if (this@Window.dispatchEvent("minimizeWindow", obj {}) != false) { - toggleMinimize() - } - } - mousedown = { e -> - e.stopPropagation() - } - } - header.add(minimizeIcon) - header.add(captionTag) - captionTag.add(windowIcon) - checkHeaderVisibility() - addInternal(header) - addInternal(content) - checkIsDraggable() - if (isResizable) { - @Suppress("LeakingThis") - resize = Resize.BOTH - content.marginBottom = WINDOW_CONTENT_MARGIN_BOTTOM.px - } - @Suppress("LeakingThis") - setEventListener { - 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 { - 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 - KVManager.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) { - KVManager.clearResizeEvent(this) - isResizeEvent = false - } - } - - override fun add(child: Component): SimplePanel { - content.add(child) - return this - } - - override fun addAll(children: List): 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 { - return content.getChildren() - } - - override fun afterCreate(node: VNode) { - checkResizablEventHandler() - } - - override fun afterDestroy() { - if (isResizeEvent) { - KVManager.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 = 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/src/main/resources/css/style.css b/src/main/resources/css/style.css new file mode 100644 index 00000000..7323772b --- /dev/null +++ b/src/main/resources/css/style.css @@ -0,0 +1,78 @@ +.splitpanel-vertical { + display: flex; + flex-direction: row; + overflow: auto; +} + +.splitpanel-vertical > *:first-child { + max-width: calc(100% - 9px); +} + +.splitpanel-vertical > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-vertical > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + +.splitpanel-horizontal { + display: flex; + flex-direction: column; + overflow: auto; +} + +.splitpanel-horizontal > *:first-child { + max-height: calc(100% - 9px); +} + +.splitpanel-horizontal > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-horizontal > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + + +.splitter-vertical { + flex: 0 0 auto; + width: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAhCAQAAABOpSL+AAAAIklEQVR4AWMwbb/PdR+JZDD9f1/oPhI5sgVGBSruc9xHIgGdSQqqQJGkRgAAAABJRU5ErkJggg==') center center no-repeat #cecece; + cursor: col-resize; +} + +.splitter-horizontal { + flex: 0 0 auto; + height: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAICAQAAADdTl4aAAAAIElEQVQoz2MwrTD9TxFsZ7jPcV+IIsjFQAUw6hFqegQA+xzRHT2p7pEAAAAASUVORK5CYII=') center center no-repeat #cecece; + cursor: row-resize; +} + +.trix-control { + overflow-y: auto; +} + +trix-toolbar .trix-button-group { + margin-bottom: 3px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select { + border: 1px solid #ccc; + border-radius: 4px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input:focus, .tabulator-row .tabulator-cell.tabulator-editing select:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.tabulator-row .tabulator-cell.tabulator-editing { + border-right: 1px solid #1d68cd !important; + padding: 2px !important; +} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt deleted file mode 100644 index 35172267..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt +++ /dev/null @@ -1,75 +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 test.pl.treksoft.kvision.dropdown - -import pl.treksoft.kvision.dropdown.ContextMenu -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( - "", - 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( - "", - element?.innerHTML, - "Should place context menu in the correct position" - ) - } - } -} \ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt deleted file mode 100644 index e75baf9e..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt +++ /dev/null @@ -1,46 +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 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( - "
      • Test
      • ", - element?.innerHTML, - "Should render correct drop down header" - ) - } - } -} \ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt deleted file mode 100644 index 86607ec7..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt +++ /dev/null @@ -1,46 +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 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( - "
      • ", - element?.innerHTML, - "Should render correct drop down separator" - ) - } - } -} \ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt deleted file mode 100644 index c7c4ede5..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt +++ /dev/null @@ -1,47 +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 test.pl.treksoft.kvision.form - -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.panel.Root -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test - -class HelpBlockSpec : DomSpec { - - @Test - fun render() { - run { - val root = Root("test", fixed = true) - val fl = HelpBlock("Form Error") - root.add(fl) - val element = document.getElementById("test") - assertEqualsHtml( - "Form Error", - element?.innerHTML, - "Should render correct help block" - ) - } - } - -} \ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.kt new file mode 100644 index 00000000..4be84d22 --- /dev/null +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.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.form + +import pl.treksoft.kvision.form.HelpText +import pl.treksoft.kvision.panel.Root +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test + +class HelpBlockSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test", fixed = true) + val fl = HelpText("Form Error") + root.add(fl) + val element = document.getElementById("test") + assertEqualsHtml( + "Form Error", + element?.innerHTML, + "Should render correct help block" + ) + } + } + +} \ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt index a8fbbcc5..bd0b3993 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt @@ -52,7 +52,7 @@ class RadioSpec : DomSpec { ci.squared = true ci.inline = false assertEqualsHtml( - "
        ", + "
        ", element?.innerHTML, "Should render correct radio button form control" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt index 7ce811fa..2bc35a38 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt @@ -49,7 +49,7 @@ class TextSpec : DomSpec { ) ti.validatorError = "Validation Error" assertEqualsHtml( - "
        Validation Error
        ", + "
        Validation Error
        ", element?.innerHTML, "Should render correct input form control with validation error" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt deleted file mode 100644 index 40720bcb..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt +++ /dev/null @@ -1,54 +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 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( - "
        ", - element?.innerHTML, - "Should render correct nav form" - ) - navf.rightAlign = true - assertEqualsHtml( - "
        ", - element?.innerHTML, - "Should render correct right aligned nav form" - ) - - } - } - -} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt deleted file mode 100644 index 988a706d..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt +++ /dev/null @@ -1,54 +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 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( - "
          ", - element?.innerHTML, - "Should render correct nav" - ) - nav.rightAlign = true - assertEqualsHtml( - "
            ", - element?.innerHTML, - "Should render correct right aligned nav" - ) - - } - } - -} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt deleted file mode 100644 index f38a05f9..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt +++ /dev/null @@ -1,70 +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 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.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( - "", - element?.innerHTML, - "Should render correct navbar" - ) - navbar.inverted = true - assertEqualsHtml( - "", - element?.innerHTML, - "Should render correct inverted navbar" - ) - navbar.add(Nav { - tag(TAG.LI) { - link("Test", "#!/test") - } - }) - assertEqualsHtml( - "", - element?.innerHTML, - "Should render correct navbar with nav link" - ) - - } - } - -} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt deleted file mode 100644 index fcdf9860..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt +++ /dev/null @@ -1,50 +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 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( - "
            abc
            def
            ghi
            ", - element?.innerHTML, - "Should render correct responsive grid panel" - ) - } - } -} \ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt deleted file mode 100644 index 9335562f..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt +++ /dev/null @@ -1,117 +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 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( - "", - 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( - "", - 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( - "
            abc
            ", - 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")[0]?.click() - val element = document.getElementById("test") - assertEqualsHtml( - "", - element?.innerHTML, - "Should select correct tab by clicking" - ) - } - } -} \ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt deleted file mode 100644 index 2f044987..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt +++ /dev/null @@ -1,56 +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 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( - "
            Processing ...
            ", - element?.innerHTML, - "Should render correct progress bar" - ) - progressBar.max = 200 - assertEqualsHtml( - "
            Processing ...
            ", - element?.innerHTML, - "Should render correct progress bar after max value change" - ) - - } - } - -} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt deleted file mode 100644 index 4aa14230..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt +++ /dev/null @@ -1,55 +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 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( - "
            ", - element?.innerHTML, - "Should render correct progress bar indicator" - ) - ind.max = 200 - assertEqualsHtml( - "
            ", - element?.innerHTML, - "Should render correct progress bar indicator after max value change" - ) - - } - } - -} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt index 997da597..c312040a 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt @@ -23,6 +23,7 @@ package test.pl.treksoft.kvision.table import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.table.Cell.Companion.cell +import pl.treksoft.kvision.table.ResponsiveType import pl.treksoft.kvision.table.Row.Companion.row import pl.treksoft.kvision.table.Table import pl.treksoft.kvision.table.TableType @@ -50,7 +51,7 @@ class TableSpec : DomSpec { "Should render correct table" ) table.caption = "Caption" - table.responsive = true + table.responsiveType = ResponsiveType.RESPONSIVE table.types = setOf(TableType.BORDERED) val element2 = document.getElementById("test") assertEqualsHtml( diff --git a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt deleted file mode 100644 index b324b8ab..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt +++ /dev/null @@ -1,57 +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 test.pl.treksoft.kvision.toolbar - -import pl.treksoft.kvision.panel.Root -import pl.treksoft.kvision.toolbar.ButtonGroup -import pl.treksoft.kvision.toolbar.ButtonGroupSize -import pl.treksoft.kvision.toolbar.ButtonGroupStyle -import test.pl.treksoft.kvision.DomSpec -import kotlin.browser.document -import kotlin.test.Test - -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( - "
            ", - element?.innerHTML, - "Should render correct button group" - ) - group.size = ButtonGroupSize.LARGE - group.style = ButtonGroupStyle.JUSTIFIED - assertEqualsHtml( - "
            ", - element?.innerHTML, - "Should render correct button group with large and justified buttons" - ) - - } - } - -} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt deleted file mode 100644 index d41ef05e..00000000 --- a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt +++ /dev/null @@ -1,47 +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 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( - "
            ", - element?.innerHTML, - "Should render correct toolbar" - ) - } - } - -} -- cgit