diff options
26 files changed, 747 insertions, 491 deletions
@@ -15,6 +15,10 @@ Full-featured chart component based on chart.js library. Kotlin bindings for chart.js API. +# Package pl.treksoft.kvision.cordova + +Kotlin bindings for core Apache Cordova API. + # Package pl.treksoft.kvision.data Base component and container class with data binding support for observable data model. @@ -81,6 +85,10 @@ Classes supporting general purpose Bootstrap modals with convenient helpers for Bootstrap navbar components. +# Package pl.treksoft.kvision.pace + +Automatic progress bar module. + # Package pl.treksoft.kvision.panel Rich set of container classes, supporting both simple use cases and sophisticated layouts (including CSS flexbox, @@ -39,6 +39,8 @@ allows to build full-stack, multiplatform applications with shared common code. - [Tabulator](http://tabulator.info/) - [Redux](https://redux.js.org/) - [Navigo](https://github.com/krasimir/navigo) + - [Moment.js](https://momentjs.com/) + - [Pace](https://github.hubspot.com/pace/docs/welcome/) - Includes sophisticated layout containers, including CSS flexbox, CSS grid and Bootstrap responsive 12 columns grid. - Includes convenient forms implementation, with support for many different input components and easy to use validation. @@ -48,6 +50,7 @@ allows to build full-stack, multiplatform applications with shared common code. - Type-safe REST connectivity. - Innovative integration interface for [Ktor](https://ktor.io), [Jooby](https://jooby.org) and [Spring Boot](https://spring.io/projects/spring-boot) frameworks on the server side, including support for type-safe websockets connections. +- Support for building hybrid mobile applications with [Apache Cordova](https://cordova.apache.org/). - Support for building cross-platform, desktop applications with [Electron](https://electronjs.org). - KVision applications are built with [Gradle](https://gradle.org/) with support for Webpack's [Hot Module Replacement (HMR)](https://webpack.js.org/concepts/hot-module-replacement/) and [Kotlin JavaScript DCE (dead code elimination)](https://kotlinlang.org/docs/reference/javascript-dce.html). diff --git a/build.gradle b/build.gradle index 1c77ff6e..180406e4 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,6 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" classpath "org.jetbrains.kotlin:kotlin-serialization:${kotlinVersion}" classpath "org.jetbrains.kotlin:kotlin-frontend-plugin:${frontendPluginVersion}" - classpath "gradle.plugin.io.gitlab.arturbosch.detekt:detekt-gradle-plugin:${detektVersion}" classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokkaVersion}" classpath "io.spring.gradle:dependency-management-plugin:${dependencyManagementPluginVersion}" } @@ -21,6 +20,7 @@ buildscript { plugins { id "com.jfrog.bintray" version "1.7.3" + id "io.gitlab.arturbosch.detekt" version "1.0.0-RC14" } configure(allprojects - project(':kvision-modules')) { @@ -172,6 +172,7 @@ dokka { 'kvision-modules/kvision-redux/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-common/src/main/kotlin', @@ -1,24 +1,3 @@ -autoCorrect: true -failFast: false - -test-pattern: # Configure exclusions for test sources - active: true - patterns: # Test file regexes - - '.*/test/.*' - - '.*Test.kt' - - '.*Spec.kt' - exclude-rule-sets: - - 'comments' - exclude-rules: - - 'NamingRules' - - 'WildcardImport' - - 'MagicNumber' - - 'MaxLineLength' - - 'LateinitUsage' - - 'StringLiteralDuplication' - - 'SpreadOperator' - - 'TooManyFunctions' - build: maxIssues: 10 weights: @@ -45,22 +24,16 @@ console-reports: # - 'FindingsReport' # - 'BuildFailureReport' -output-reports: - active: true - exclude: - # - 'HtmlOutputReport' - # - 'PlainOutputReport' - # - 'XmlOutputReport' - comments: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" CommentOverPrivateFunction: active: false CommentOverPrivateProperty: active: false EndOfSentenceFormat: active: false - endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!]$) + endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!:]$) UndocumentedPublicClass: active: false searchInNestedClass: true @@ -83,18 +56,20 @@ complexity: active: true threshold: 10 ignoreSingleWhenExpression: false + ignoreSimpleWhenEntries: false LabeledExpression: active: false + ignoredLabels: "" LargeClass: active: true - threshold: 150 + threshold: 600 LongMethod: - active: true - threshold: 20 + active: false + threshold: 60 LongParameterList: - active: true + active: false threshold: 6 - ignoreDefaultParameters: true + ignoreDefaultParameters: false MethodOverloading: active: false threshold: 6 @@ -103,23 +78,28 @@ complexity: threshold: 4 StringLiteralDuplication: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" threshold: 3 ignoreAnnotation: true excludeStringsWithLessThan5Characters: true ignoreStringsRegex: '$^' TooManyFunctions: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" thresholdInFiles: 11 thresholdInClasses: 11 thresholdInInterfaces: 11 thresholdInObjects: 11 thresholdInEnums: 11 + ignoreDeprecated: false + ignorePrivate: false + ignoreOverridden: false empty-blocks: active: true EmptyCatchBlock: active: true - allowedExceptionNameRegex: "^(ignore|expected).*" + allowedExceptionNameRegex: "^(_|(ignore|expected).*)" EmptyClassBlock: active: true EmptyDefaultConstructor: @@ -134,6 +114,7 @@ empty-blocks: active: true EmptyFunctionBlock: active: true + ignoreOverriddenFunctions: false EmptyIfBlock: active: true EmptyInitBlock: @@ -154,6 +135,7 @@ exceptions: methodNames: 'toString,hashCode,equals,finalize' InstanceOfCheckForException: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" NotImplementedDeclaration: active: false PrintStackTrace: @@ -164,6 +146,7 @@ exceptions: active: false SwallowedException: active: false + ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException' ThrowingExceptionFromFinally: active: false ThrowingExceptionInMain: @@ -175,6 +158,7 @@ exceptions: active: false TooGenericExceptionCaught: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" exceptionNames: - ArrayIndexOutOfBoundsException - Error @@ -184,6 +168,7 @@ exceptions: - IndexOutOfBoundsException - RuntimeException - Throwable + allowedExceptionNameRegex: "^(_|(ignore|expected).*)" TooGenericExceptionThrown: active: true exceptionNames: @@ -192,27 +177,144 @@ exceptions: - Throwable - RuntimeException +formatting: + active: true + android: false + autoCorrect: true + ChainWrapping: + active: true + autoCorrect: true + CommentSpacing: + active: true + autoCorrect: true + Filename: + active: true + FinalNewline: + active: true + autoCorrect: true + ImportOrdering: + active: false + Indentation: + active: true + autoCorrect: true + indentSize: 4 + continuationIndentSize: 4 + MaximumLineLength: + active: true + maxLineLength: 120 + ModifierOrdering: + active: true + autoCorrect: true + NoBlankLineBeforeRbrace: + active: true + autoCorrect: true + NoConsecutiveBlankLines: + active: true + autoCorrect: true + NoEmptyClassBody: + active: true + autoCorrect: true + NoItParamInMultilineLambda: + active: false + NoLineBreakAfterElse: + active: true + autoCorrect: true + NoLineBreakBeforeAssignment: + active: true + autoCorrect: true + NoMultipleSpaces: + active: true + autoCorrect: true + NoSemicolons: + active: true + autoCorrect: true + NoTrailingSpaces: + active: true + autoCorrect: true + NoUnitReturn: + active: true + autoCorrect: true + NoUnusedImports: + active: true + autoCorrect: true + NoWildcardImports: + active: true + autoCorrect: true + PackageName: + active: true + autoCorrect: true + ParameterListWrapping: + active: true + autoCorrect: true + indentSize: 4 + SpacingAroundColon: + active: true + autoCorrect: true + SpacingAroundComma: + active: true + autoCorrect: true + SpacingAroundCurly: + active: true + autoCorrect: true + SpacingAroundKeyword: + active: true + autoCorrect: true + SpacingAroundOperators: + active: true + autoCorrect: true + SpacingAroundParens: + active: true + autoCorrect: true + SpacingAroundRangeOperator: + active: true + autoCorrect: true + StringTemplate: + active: true + autoCorrect: true + naming: active: true ClassNaming: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" classPattern: '[A-Z$][a-zA-Z0-9$]*' + ConstructorParameterNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' EnumNaming: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*' ForbiddenClassName: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" forbiddenName: '' FunctionMaxLength: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" maximumFunctionNameLength: 30 FunctionMinLength: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" minimumFunctionNameLength: 3 FunctionNaming: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' excludeClassPattern: '$^' + ignoreOverridden: true + FunctionParameterNaming: + active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverriddenFunctions: true + InvalidPackageDeclaration: + active: false + rootPackage: '' MatchingDeclarationName: active: true MemberNameEqualsClassName: @@ -220,33 +322,46 @@ naming: ignoreOverriddenFunction: true ObjectPropertyNaming: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + constantPattern: '[A-Za-z][_A-Za-z0-9]*' propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' PackageNaming: active: true - packagePattern: '^[a-z]+(\.[a-z][a-z0-9]*)*$' + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" + packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$' TopLevelPropertyNaming: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" constantPattern: '[A-Z][_A-Z0-9]*' - propertyPattern: '[a-z][A-Za-z\d]*' - privatePropertyPattern: '(_)?[a-z][A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' VariableMaxLength: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" maximumVariableNameLength: 64 VariableMinLength: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" minimumVariableNameLength: 1 VariableNaming: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" variablePattern: '[a-z][A-Za-z0-9]*' privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' excludeClassPattern: '$^' + ignoreOverridden: true performance: active: true + ArrayPrimitive: + active: false ForEachOnRange: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" SpreadOperator: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" UnnecessaryTemporaryInstantiation: active: true @@ -268,8 +383,13 @@ potential-bugs: active: false LateinitUsage: active: false + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" excludeAnnotatedProperties: "" ignoreOnClassesPattern: "" + MissingWhenCase: + active: false + RedundantElseInWhen: + active: false UnconditionalJumpStatementInLoop: active: false UnreachableCode: @@ -290,16 +410,26 @@ style: DataClassContainsFunctions: active: false conversionFunctionPrefix: 'to' + DataClassShouldBeImmutable: + active: false EqualsNullCall: active: false + EqualsOnSignatureLine: + active: false + ExplicitItLambdaParameter: + active: false ExpressionBodySyntax: active: false + includeLineWrapping: false ForbiddenComment: active: true values: 'TODO:,FIXME:,STOPSHIP:' ForbiddenImport: active: false imports: '' + ForbiddenVoid: + active: false + ignoreOverridden: false FunctionOnlyReturningConstant: active: false ignoreOverridableFunction: true @@ -309,19 +439,24 @@ style: maxJumpCount: 1 MagicNumber: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" ignoreNumbers: '-1,0,1,2' - ignoreHashCodeFunction: false + ignoreHashCodeFunction: true ignorePropertyDeclaration: false ignoreConstantDeclaration: true ignoreCompanionObjectPropertyDeclaration: true ignoreAnnotation: false ignoreNamedArgument: true ignoreEnums: false + ignoreRanges: false + MandatoryBracesIfStatements: + active: false MaxLineLength: active: true maxLineLength: 120 - excludePackageStatements: false - excludeImportStatements: false + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false MayBeConst: active: false ModifierOrder: @@ -338,6 +473,8 @@ style: active: false OptionalWhenBraces: active: false + PreferToOverPairSyntax: + active: false ProtectedMemberInFinalClass: active: false RedundantVisibilityModifierRule: @@ -346,6 +483,8 @@ style: active: true max: 2 excludedFunctions: "equals" + excludeLabeled: false + excludeReturnFromLambda: true SafeCast: active: true SerialVersionUIDInSerializableClass: @@ -357,23 +496,43 @@ style: max: 2 TrailingWhitespace: active: false + UnderscoresInNumericLiterals: + active: false + acceptableDecimalLength: 5 UnnecessaryAbstractClass: active: false + excludeAnnotatedClasses: "dagger.Module" + UnnecessaryApply: + active: false UnnecessaryInheritance: active: false + UnnecessaryLet: + active: false UnnecessaryParentheses: active: false UntilInsteadOfRangeTo: active: false UnusedImports: active: false + UnusedPrivateClass: + active: false UnusedPrivateMember: active: false + allowedNames: "(_|ignored|expected|serialVersionUID)" + UseCheckOrError: + active: false UseDataClass: active: false excludeAnnotatedClasses: "" + UseRequire: + active: false + UselessCallOnNotNull: + active: false UtilityClassWithPublicConstructor: active: false + VarCouldBeVal: + active: false WildcardImport: active: true + excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt" excludeImports: 'java.util.*,kotlinx.android.synthetic.*' diff --git a/gradle.properties b/gradle.properties index e51a8eb4..78a4d488 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,23 +1,23 @@ group=pl.treksoft -version=0.0.36 -kotlinVersion=1.3.31 +version=0.0.37 +kotlinVersion=1.3.40 javaVersion=1.8 -coroutinesVersion=1.2.1 -serializationVersion=0.11.0 +coroutinesVersion=1.2.2 +serializationVersion=0.11.1 frontendPluginVersion=0.0.45 dokkaVersion=0.9.18 -detektVersion=1.0.0.RC9.2 +detektVersion=1.0.0-RC14 junitVersion=4.12 joobyVersion=1.6.0 -springBootVersion=2.1.4.RELEASE -ktorVersion=1.1.4 +springBootVersion=2.1.6.RELEASE +ktorVersion=1.2.2 guiceVersion=4.2.2 pac4jVersion=3.5.0 dependencyManagementPluginVersion=1.0.4.RELEASE -jacksonModuleKotlinVersion=2.9.8 +jacksonModuleKotlinVersion=2.9.9 jqueryKotlinVersion=0.0.4 snabbdomKotlinVersion=0.1.1 navigoKotlinVersion=0.0.3 kotlinObservableVersion=0.0.4 nodeKtVersion=0.1.0 -kotlinReduxVersion=4.0.0-pre.70-kotlin-1.3.21 +kotlinReduxVersion=4.0.0-pre.73-kotlin-1.3.40 diff --git a/kvision-modules/kvision-datetime/webpack.config.d/css.js b/kvision-modules/kvision-datetime/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-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-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt b/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt index 0000db83..330d818d 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-present Robert Jaros + * Copyright (c) 2019-present Robert Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/moment/Moment.kt b/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/moment/Moment.kt index 39e7c2dc..5f21bfe2 100644 --- a/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/moment/Moment.kt +++ b/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/moment/Moment.kt @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-present Robert Jaros + * Copyright (c) 2019-present Robert Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/kvision-modules/kvision-pace/build.gradle b/kvision-modules/kvision-pace/build.gradle index d577df20..238f9efa 100644 --- a/kvision-modules/kvision-pace/build.gradle +++ b/kvision-modules/kvision-pace/build.gradle @@ -4,6 +4,10 @@ kotlinFrontend { npm { dependency("pace-progressbar", "1.0.8") + devDependency("karma", "3.1.4") + devDependency("karma-chrome-launcher", "2.2.0") + devDependency("karma-webpack", "3.0.5") + devDependency("qunit", "2.8.0") } }
\ No newline at end of file diff --git a/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt b/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt index 38a83fb5..9678d1fa 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 @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-present Robert Jaros + * Copyright (c) 2019-present Robert Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,10 +27,13 @@ internal val kVManagerPaceInit = KVManagerPace.init() /** * Internal singleton object which initializes and configures KVision Moment module. */ +@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerPace { - fun init() {} + fun init() { + } private val pace = try { require("pace-progressbar").default - } catch (e: Throwable) {} + } catch (e: Throwable) { + } } diff --git a/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/pace/Pace.kt b/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/pace/Pace.kt index a5d80908..d5c77534 100644 --- a/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/pace/Pace.kt +++ b/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/pace/Pace.kt @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-present Robert Jaros + * Copyright (c) 2019-present Robert Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,108 +23,125 @@ package pl.treksoft.kvision.pace -import pl.treksoft.kvision.require -import pl.treksoft.kvision.utils.obj import org.w3c.dom.events.Event import org.w3c.dom.get +import pl.treksoft.kvision.require +import pl.treksoft.kvision.utils.obj import kotlin.browser.window -class PaceAjaxOptions(trackMethods:Array<dynamic>? = null, - trackWebSockets:Boolean? = null, - ignoreURLs:Array<dynamic>? = null) { +class PaceAjaxOptions( + trackMethods: Array<dynamic>? = null, + trackWebSockets: Boolean? = null, + ignoreURLs: Array<dynamic>? = null +) { internal var paceAjaxOptionsJs: dynamic = obj { - if (trackMethods != null) { this.trackMethods = trackMethods } - if (trackWebSockets != null) { this.trackWebSockets = trackWebSockets } - if (ignoreURLs != null) { this.ignoreURLs = ignoreURLs } + if (trackMethods != null) { + this.trackMethods = trackMethods + } + if (trackWebSockets != null) { + this.trackWebSockets = trackWebSockets + } + if (ignoreURLs != null) { + this.ignoreURLs = ignoreURLs + } } } -class PaceElementsOptions(minSamples:Int? = null, - selectors:Array<dynamic>? = null) { +class PaceElementsOptions( + minSamples: Int? = null, + selectors: Array<dynamic>? = null +) { internal var paceElementsOptionsJs: dynamic = obj { - if (minSamples != null) { this.minSamples = minSamples } - if (selectors != null) { this.selectors = selectors } + if (minSamples != null) { + this.minSamples = minSamples + } + if (selectors != null) { + this.selectors = selectors + } } } -class PaceEventLagOptions(minSamples:Int? = null, - sampleCount:Int? = null, - lagThreshold:Int? = null) { +class PaceEventLagOptions( + minSamples: Int? = null, + sampleCount: Int? = null, + lagThreshold: Int? = null +) { internal var paceEventLagOptionsJs: dynamic = obj { - if (minSamples != null) { this.minSamples = minSamples } - if (sampleCount != null) { this.sampleCount = sampleCount } - if (lagThreshold != null) { this.lagThreshold = lagThreshold } + if (minSamples != null) { + this.minSamples = minSamples + } + if (sampleCount != null) { + this.sampleCount = sampleCount + } + if (lagThreshold != null) { + this.lagThreshold = lagThreshold + } } } class PaceOptions( - ajax:PaceAjaxOptions? = null, - catchupTime:Int? = null, - easeFactor:Double? = null, - elements:PaceElementsOptions? = null, - eventLag:PaceEventLagOptions? = null, - ghostTime:Int? = null, - initialRate:Double? = null, - maxProgressPerFrame:Int? = null, - minTime:Int? = null, - restartOnPushState:Boolean? = null, - restartOnRequestAfter:Double? = null, - startOnPageLoad:Boolean? = null, - target:String? = null + ajax: PaceAjaxOptions? = null, + catchupTime: Int? = null, + easeFactor: Double? = null, + elements: PaceElementsOptions? = null, + eventLag: PaceEventLagOptions? = null, + ghostTime: Int? = null, + initialRate: Double? = null, + maxProgressPerFrame: Int? = null, + minTime: Int? = null, + restartOnPushState: Boolean? = null, + restartOnRequestAfter: Double? = null, + startOnPageLoad: Boolean? = null, + target: String? = null ) { internal var paceOptionsJs: dynamic = obj { - if (ajax != null) { this.ajax = ajax.paceAjaxOptionsJs } - if (catchupTime != null) { this.catchupTime = catchupTime } - if (easeFactor != null) { this.easeFactor = easeFactor } - if (elements != null) { this.elements = elements.paceElementsOptionsJs } - if (eventLag != null) { this.eventLag = eventLag.paceEventLagOptionsJs } - if (ghostTime != null) { this.ghostTime = ghostTime } - if (initialRate != null) { this.initialRate = initialRate } - if (maxProgressPerFrame != null) { this.maxProgressPerFrame = maxProgressPerFrame } - if (minTime != null) { this.minTime = minTime } - if (restartOnPushState != null) { this.restartOnPushState = restartOnPushState } - if (restartOnRequestAfter != null) { this.restartOnRequestAfter = restartOnRequestAfter } - if (startOnPageLoad != null) { this.startOnPageLoad = startOnPageLoad } - if (target != null) { this.target = target } + if (ajax != null) { + this.ajax = ajax.paceAjaxOptionsJs + } + if (catchupTime != null) { + this.catchupTime = catchupTime + } + if (easeFactor != null) { + this.easeFactor = easeFactor + } + if (elements != null) { + this.elements = elements.paceElementsOptionsJs + } + if (eventLag != null) { + this.eventLag = eventLag.paceEventLagOptionsJs + } + if (ghostTime != null) { + this.ghostTime = ghostTime + } + if (initialRate != null) { + this.initialRate = initialRate + } + if (maxProgressPerFrame != null) { + this.maxProgressPerFrame = maxProgressPerFrame + } + if (minTime != null) { + this.minTime = minTime + } + if (restartOnPushState != null) { + this.restartOnPushState = restartOnPushState + } + if (restartOnRequestAfter != null) { + this.restartOnRequestAfter = restartOnRequestAfter + } + if (startOnPageLoad != null) { + this.startOnPageLoad = startOnPageLoad + } + if (target != null) { + this.target = target + } } } -enum class PaceColor(var paceColorString: String) { - Black("black"), - Blue("blue"), - Green("green"), - Orange("orange"), - Pink("pink"), - Purple("purple"), - Red("red"), - Silver("silver"), - White("white"), - Yellow("yellow") -} - -enum class PaceTheme(var paceThemeString: String) { - BarberShop("barber-shop"), - BigCounter("big-counter"), - Bounce("bounce"), - CenterAtom("center-atom"), - CenterCircle("center-circle"), - CenterRadar("center-radar"), - CenterSimple("center-simple"), - CornerIndicator("corner-indicator"), - FillLeft("fill-left"), - Flash("flash"), - FlatTop("flat-top"), - LoadingBar("loading-bar"), - MacOSX("mac-osx"), - Material("material"), - Minimal("minimal") -} - class Pace { companion object { - fun setNewTheme(color: PaceColor, theme: PaceTheme) { - require("pace-progressbar/themes/${color.paceColorString}/pace-theme-${theme.paceThemeString}.css") + fun init(req: dynamic = require("pace-progressbar/themes/blue/pace-theme-flash.css")) { } + fun setOptions(options: PaceOptions) { window["Pace"].options = options.paceOptionsJs } @@ -140,4 +158,4 @@ class Pace { window["Pace"].stop() } } -}
\ No newline at end of file +} diff --git a/kvision-modules/kvision-pace/webpack.config.d/css.js b/kvision-modules/kvision-pace/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-pace/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt index 246ccef5..bfe7bc50 100644 --- a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt +++ b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt @@ -21,11 +21,7 @@ */ package pl.treksoft.kvision.redux -import kotlinx.serialization.ImplicitReflectionSerializer -import kotlinx.serialization.KSerializer -import kotlinx.serialization.serializer import pl.treksoft.kvision.KVManagerRedux -import pl.treksoft.kvision.utils.JSON import redux.RAction import redux.Reducer import redux.Store @@ -43,49 +39,45 @@ typealias ActionCreator<A, S> = (Dispatch<A>, GetState<S>) -> Unit * @param initialState an initial state * @param middlewares a list of optional Redux JS middlewares */ -@UseExperimental(ImplicitReflectionSerializer::class) -inline fun <reified S : Any, A : RAction> createReduxStore( - noinline reducer: Reducer<S, A>, +fun <S : Any, A : RAction> createReduxStore( + reducer: Reducer<S, A>, initialState: S, vararg middlewares: dynamic ): ReduxStore<S, A> { @Suppress("SpreadOperator") - return ReduxStore(reducer, initialState, S::class.serializer(), *middlewares) + return ReduxStore(reducer, initialState, *middlewares) } /** * A class implementing redux pattern backed by the original Redux JS library. - * It requires @Serializable state. * * @constructor Creates a Redux store with given reducer function and initial state. - * @param S redux state type (@Serializable) + * @param S redux state type * @param A redux action type * @param reducer a reducer function * @param initialState an initial state - * @param stateSerializer a serializer for the state type * @param middlewares a list of optional Redux JS middlewares */ class ReduxStore<S : Any, A : RAction>( reducer: Reducer<S, A>, initialState: S, - val stateSerializer: KSerializer<S>, vararg middlewares: dynamic ) { - private val store: Store<String, dynamic, WrapperAction> + private val store: Store<S, dynamic, WrapperAction> init { @Suppress("UnsafeCastFromDynamic") store = KVManagerRedux.createStore( - { s: String, a: RAction -> + { s: S, a: RAction -> @Suppress("UnsafeCastFromDynamic") if (a == undefined || (a.asDynamic().type is String && a.asDynamic().type.startsWith("@@"))) { s } else { @Suppress("UNCHECKED_CAST") - JSON.plain.stringify(stateSerializer, reducer(JSON.plain.parse(stateSerializer, s), a as A)) + reducer(s, a as A) } }, - JSON.plain.stringify(stateSerializer, initialState), + initialState, @Suppress("SpreadOperator") KVManagerRedux.compose(KVManagerRedux.applyMiddleware(KVManagerRedux.reduxThunk, *middlewares), rEnhancer()) ) @@ -95,7 +87,7 @@ class ReduxStore<S : Any, A : RAction>( * Returns the current state. */ fun getState(): S { - return JSON.plain.parse(stateSerializer, store.getState()) + return store.getState() } /** @@ -109,7 +101,7 @@ class ReduxStore<S : Any, A : RAction>( * Dispatches an asynchronous action function. */ fun dispatch(actionCreator: ActionCreator<dynamic, S>): WrapperAction { - return store.dispatch({ reduxDispatch: Dispatch<dynamic>, reduxGetState: GetState<String> -> + return store.dispatch({ reduxDispatch: Dispatch<dynamic>, reduxGetState: GetState<S> -> val newDispatch: Dispatch<dynamic> = { elem -> @Suppress("UnsafeCastFromDynamic") if (js("typeof elem === 'function'")) { @@ -118,7 +110,7 @@ class ReduxStore<S : Any, A : RAction>( reduxDispatch(elem) } } - actionCreator(newDispatch) { JSON.plain.parse(stateSerializer, reduxGetState()) } + actionCreator(newDispatch) { reduxGetState() } }) } diff --git a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt index 3be83556..b45eb9dd 100644 --- a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt +++ b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt @@ -21,15 +21,13 @@ */ package test.pl.treksoft.kvision.redux -import kotlinx.serialization.Serializable import pl.treksoft.kvision.redux.createReduxStore import redux.RAction import test.pl.treksoft.kvision.SimpleSpec import kotlin.test.Test import kotlin.test.assertEquals -@Serializable -data class TestState(val counter: Int) +data class TestState(val counter: Int, val values: List<Int>) sealed class TestAction : RAction { object Inc : TestAction() @@ -38,10 +36,10 @@ sealed class TestAction : RAction { fun testReducer(state: TestState, action: TestAction): TestState = when (action) { is TestAction.Inc -> { - state.copy(counter = state.counter + 1) + state.copy(counter = state.counter + 1, values = state.values + state.counter) } is TestAction.Dec -> { - state.copy(counter = state.counter - 1) + state.copy(counter = state.counter - 1, values = state.values + state.counter) } } @@ -50,20 +48,21 @@ class ReduxStoreSpec : SimpleSpec { @Test fun getState() { run { - val store = createReduxStore(::testReducer, TestState(10)) - assertEquals(TestState(10), store.getState()) + val store = createReduxStore(::testReducer, TestState(10, listOf())) + assertEquals(TestState(10, listOf()), store.getState()) } } @Test fun dispatch() { run { - val store = createReduxStore(::testReducer, TestState(10)) + val store = createReduxStore(::testReducer, TestState(10, listOf())) store.dispatch(TestAction.Inc) store.dispatch(TestAction.Inc) store.dispatch(TestAction.Inc) store.dispatch(TestAction.Dec) - assertEquals(TestState(12), store.getState()) + store.dispatch(TestAction.Dec) + assertEquals(TestState(11, listOf(10, 11, 12, 13, 12)), store.getState()) } } @@ -71,7 +70,7 @@ class ReduxStoreSpec : SimpleSpec { fun subscribe() { run { var counter = 0 - val store = createReduxStore(::testReducer, TestState(10)) + val store = createReduxStore(::testReducer, TestState(10, listOf())) store.subscribe { counter++ } diff --git a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt index 5204402d..ec32d0d6 100644 --- a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt +++ b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt @@ -21,7 +21,6 @@ */ package test.pl.treksoft.kvision.redux -import kotlinx.serialization.Serializable import pl.treksoft.kvision.html.Div.Companion.div import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.panel.SimplePanel @@ -33,7 +32,6 @@ import test.pl.treksoft.kvision.DomSpec import kotlin.browser.document import kotlin.test.Test -@Serializable data class State(val counter: Int) sealed class StateAction : RAction { diff --git a/kvision-modules/kvision-richtext/webpack.config.d/css.js b/kvision-modules/kvision-richtext/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-richtext/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-select/webpack.config.d/css.js b/kvision-modules/kvision-select/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-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-spinner/webpack.config.d/css.js b/kvision-modules/kvision-spinner/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-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-tabulator/build.gradle b/kvision-modules/kvision-tabulator/build.gradle index 5ea97e50..b74ef2d4 100644 --- a/kvision-modules/kvision-tabulator/build.gradle +++ b/kvision-modules/kvision-tabulator/build.gradle @@ -8,7 +8,7 @@ dependencies { kotlinFrontend { npm { - dependency("tabulator-tables", "4.2.5") + dependency("tabulator-tables", "4.2.7") devDependency("karma", "3.1.4") devDependency("karma-chrome-launcher", "2.2.0") devDependency("karma-webpack", "3.0.5") diff --git a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Options.kt b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Options.kt index 906b0c82..a6f9c740 100644 --- a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Options.kt +++ b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Options.kt @@ -30,7 +30,6 @@ import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.tabulator.EditorRoot.disposeTimer import pl.treksoft.kvision.tabulator.EditorRoot.root import pl.treksoft.kvision.tabulator.js.Tabulator -import pl.treksoft.kvision.utils.JSON import pl.treksoft.kvision.utils.obj import kotlin.browser.document import kotlin.browser.window @@ -238,9 +237,9 @@ enum class AddRowMode(internal val mode: String) { * Download config options. */ data class DownloadConfig( - val columnGroups: Boolean? = null, - val rowGroups: Boolean? = null, - val columnCalcs: Boolean? = null + val columnGroups: Boolean? = null, + val rowGroups: Boolean? = null, + val columnCalcs: Boolean? = null ) /** @@ -259,102 +258,103 @@ fun DownloadConfig.toJs(): Tabulator.DownloadConfig { * Column definition options. */ data class ColumnDefinition<T : Any>( - val title: String, - val field: String? = null, - val visible: Boolean? = null, - val align: Align? = null, - val width: String? = null, - val minWidth: Int? = null, - val widthGrow: Int? = null, - val widthShrink: Int? = null, - val resizable: Boolean? = null, - val frozen: Boolean? = null, - val responsive: Int? = null, - val tooltip: ((cell: Tabulator.CellComponent) -> String)? = null, - val cssClass: String? = null, - val rowHandle: Boolean? = null, - val hideInHtml: Boolean? = null, - val sorter: Sorter? = null, - val sorterFunction: (( - a: dynamic, b: dynamic, aRow: Tabulator.RowComponent, bRow: Tabulator.RowComponent, - column: Tabulator.ColumnComponent, dir: SortingDir, sorterParams: dynamic - ) -> Number)? = null, - val sorterParams: dynamic = null, - val formatter: Formatter? = null, - val formatterFunction: (( - cell: Tabulator.CellComponent, formatterParams: dynamic, - onRendered: (callback: () -> Unit) -> Unit - ) -> dynamic)? = null, - val formatterComponentFunction: (( - cell: Tabulator.CellComponent, onRendered: (callback: () -> Unit) -> Unit, data: T - ) -> Component)? = null, - val formatterParams: dynamic = null, - val variableHeight: Boolean? = null, - val editable: ((cell: Tabulator.CellComponent) -> Boolean)? = null, - val editor: Editor? = null, - val editorFunction: (( - cell: Tabulator.CellComponent, - onRendered: (callback: () -> Unit) -> Unit, - success: (value: dynamic) -> Unit, cancel: (value: dynamic) -> Unit, editorParams: dynamic - ) -> dynamic)? = null, - val editorComponentFunction: (( - cell: Tabulator.CellComponent, - onRendered: (callback: () -> Unit) -> Unit, - success: (value: dynamic) -> Unit, cancel: (value: dynamic) -> Unit, data: T - ) -> Component)? = null, - val editorParams: dynamic = null, - val validator: Validator? = null, - val validatorFunction: dynamic = null, - val validatorParams: String? = null, - val download: Boolean? = null, - val downloadTitle: String? = null, - val topCalc: Calc? = null, - val topCalcParams: dynamic = null, - val topCalcFormatter: Formatter? = null, - val topCalcFormatterParams: dynamic = null, - val bottomCalc: Calc? = null, - val bottomCalcParams: dynamic = null, - val bottomCalcFormatter: Formatter? = null, - val bottomCalcFormatterParams: dynamic = null, - val headerSort: Boolean? = null, - val headerSortStartingDir: SortingDir? = null, - val headerSortTristate: Boolean? = null, - val headerClick: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, - val headerDblClick: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, - val headerContext: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, - val headerTap: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, - val headerDblTap: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, - val headerTapHold: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, - val headerTooltip: ((column: Tabulator.ColumnComponent) -> String)? = null, - val headerVertical: Boolean? = null, - val editableTitle: Boolean? = null, - val titleFormatter: Formatter? = null, - val titleFormatterParams: dynamic = null, - val headerFilter: Editor? = null, - val headerFilterParams: dynamic = null, - val headerFilterPlaceholder: String? = null, - val headerFilterEmptyCheck: ((value: Any) -> Boolean)? = null, - val headerFilterFunc: Filter? = null, - val headerFilterFuncParams: dynamic = null, - val headerFilterLiveFilter: Boolean? = null, - val cellClick: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellDblClick: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellContext: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellTap: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellDblTap: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellTapHold: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellMouseEnter: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellMouseLeave: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellMouseOver: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellMouseOut: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellMouseMove: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, - val cellEditing: ((cell: Tabulator.CellComponent) -> Unit)? = null, - val cellEdited: ((cell: Tabulator.CellComponent) -> Unit)? = null, - val cellEditCancelled: ((cell: Tabulator.CellComponent) -> Unit)? = null + val title: String, + val field: String? = null, + val visible: Boolean? = null, + val align: Align? = null, + val width: String? = null, + val minWidth: Int? = null, + val widthGrow: Int? = null, + val widthShrink: Int? = null, + val resizable: Boolean? = null, + val frozen: Boolean? = null, + val responsive: Int? = null, + val tooltip: ((cell: Tabulator.CellComponent) -> String)? = null, + val cssClass: String? = null, + val rowHandle: Boolean? = null, + val hideInHtml: Boolean? = null, + val sorter: Sorter? = null, + val sorterFunction: (( + a: dynamic, b: dynamic, aRow: Tabulator.RowComponent, bRow: Tabulator.RowComponent, + column: Tabulator.ColumnComponent, dir: SortingDir, sorterParams: dynamic + ) -> Number)? = null, + val sorterParams: dynamic = null, + val formatter: Formatter? = null, + val formatterFunction: (( + cell: Tabulator.CellComponent, formatterParams: dynamic, + onRendered: (callback: () -> Unit) -> Unit + ) -> dynamic)? = null, + val formatterComponentFunction: (( + cell: Tabulator.CellComponent, onRendered: (callback: () -> Unit) -> Unit, data: T + ) -> Component)? = null, + val formatterParams: dynamic = null, + val variableHeight: Boolean? = null, + val editable: ((cell: Tabulator.CellComponent) -> Boolean)? = null, + val editor: Editor? = null, + val editorFunction: (( + cell: Tabulator.CellComponent, + onRendered: (callback: () -> Unit) -> Unit, + success: (value: dynamic) -> Unit, cancel: (value: dynamic) -> Unit, editorParams: dynamic + ) -> dynamic)? = null, + val editorComponentFunction: (( + cell: Tabulator.CellComponent, + onRendered: (callback: () -> Unit) -> Unit, + success: (value: dynamic) -> Unit, cancel: (value: dynamic) -> Unit, data: T + ) -> Component)? = null, + val editorParams: dynamic = null, + val validator: Validator? = null, + val validatorFunction: dynamic = null, + val validatorParams: String? = null, + val download: Boolean? = null, + val downloadTitle: String? = null, + val topCalc: Calc? = null, + val topCalcParams: dynamic = null, + val topCalcFormatter: Formatter? = null, + val topCalcFormatterParams: dynamic = null, + val bottomCalc: Calc? = null, + val bottomCalcParams: dynamic = null, + val bottomCalcFormatter: Formatter? = null, + val bottomCalcFormatterParams: dynamic = null, + val headerSort: Boolean? = null, + val headerSortStartingDir: SortingDir? = null, + val headerSortTristate: Boolean? = null, + val headerClick: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, + val headerDblClick: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, + val headerContext: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, + val headerTap: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, + val headerDblTap: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, + val headerTapHold: ((e: dynamic, column: Tabulator.ColumnComponent) -> Unit)? = null, + val headerTooltip: ((column: Tabulator.ColumnComponent) -> String)? = null, + val headerVertical: Boolean? = null, + val editableTitle: Boolean? = null, + val titleFormatter: Formatter? = null, + val titleFormatterParams: dynamic = null, + val headerFilter: Editor? = null, + val headerFilterParams: dynamic = null, + val headerFilterPlaceholder: String? = null, + val headerFilterEmptyCheck: ((value: Any) -> Boolean)? = null, + val headerFilterFunc: Filter? = null, + val headerFilterFuncParams: dynamic = null, + val headerFilterLiveFilter: Boolean? = null, + val cellClick: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellDblClick: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellContext: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellTap: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellDblTap: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellTapHold: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellMouseEnter: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellMouseLeave: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellMouseOver: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellMouseOut: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellMouseMove: ((e: dynamic, cell: Tabulator.CellComponent) -> Unit)? = null, + val cellEditing: ((cell: Tabulator.CellComponent) -> Unit)? = null, + val cellEdited: ((cell: Tabulator.CellComponent) -> Unit)? = null, + val cellEditCancelled: ((cell: Tabulator.CellComponent) -> Unit)? = null ) internal object EditorRoot { internal var root: Root? = null + internal var cancel: ((value: dynamic) -> Unit)? = null internal var disposeTimer: Int? = null } @@ -363,12 +363,13 @@ internal object EditorRoot { */ @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE", "ComplexMethod", "MagicNumber") fun <T : Any> ColumnDefinition<T>.toJs( - i18nTranslator: (String) -> (String) + i18nTranslator: (String) -> (String) ): Tabulator.ColumnDefinition { val tmpEditorFunction = editorComponentFunction?.let { { cell: Tabulator.CellComponent, onRendered: (callback: () -> Unit) -> Unit, success: (value: dynamic) -> Unit, cancel: (value: dynamic) -> Unit, _: dynamic -> + cell.getElement().style.asDynamic().overflow = "visible" var onRenderedCallback: (() -> Unit)? = null @Suppress("UNCHECKED_CAST") val data = cell.getData() as T val component = it(cell, { callback -> @@ -379,6 +380,7 @@ fun <T : Any> ColumnDefinition<T>.toJs( root?.dispose() disposeTimer = null root = null + EditorRoot.cancel = null }, 500) }, cancel, data) val rootElement = document.createElement("div") as HTMLElement @@ -388,6 +390,7 @@ fun <T : Any> ColumnDefinition<T>.toJs( root?.dispose() } root = Root(element = rootElement) + EditorRoot.cancel = cancel @Suppress("UnsafeCastFromDynamic") root?.add(component) (component as? FormControl)?.focus() @@ -402,6 +405,7 @@ fun <T : Any> ColumnDefinition<T>.toJs( val tmpFormatterFunction = formatterComponentFunction?.let { { cell: Tabulator.CellComponent, _: dynamic, onRendered: (callback: () -> Unit) -> Unit -> + cell.getElement().style.asDynamic().overflow = "visible" var onRenderedCallback: (() -> Unit)? = null @Suppress("UNCHECKED_CAST") val data = cell.getData() as T val component = it(cell, { callback -> @@ -515,160 +519,160 @@ fun <T : Any> ColumnDefinition<T>.toJs( * Tabulator options. */ data class TabulatorOptions<T : Any>( - val height: String? = null, - val virtualDom: Boolean? = null, - val virtualDomBuffer: Int? = null, - val placeholder: String? = null, - val footerElement: String? = null, - val tooltips: ((cell: Tabulator.CellComponent) -> String)? = null, - val tooltipGenerationMode: TooltipGenerationMode? = null, - val history: Boolean? = null, - val keybindings: dynamic = null, - val downloadDataFormatter: dynamic = null, - val downloadConfig: DownloadConfig? = null, - val reactiveData: Boolean? = null, - val autoResize: Boolean? = null, - val columns: List<ColumnDefinition<T>>? = null, - val autoColumns: Boolean? = null, - val layout: Layout? = null, - val layoutColumnsOnNewData: Boolean? = null, - val responsiveLayout: ResponsiveLayout? = null, - val responsiveLayoutCollapseStartOpen: Boolean? = null, - val responsiveLayoutCollapseUseFormatters: Boolean? = null, - val columnMinWidth: Int? = null, - val resizableColumns: Boolean? = null, - val movableColumns: Boolean? = null, - val tooltipsHeader: Boolean? = null, - val headerFilterPlaceholder: String? = null, - val scrollToColumnPosition: ColumnPosition? = null, - val scrollToColumnIfVisible: Boolean? = null, - val rowFormatter: ((row: Tabulator.RowComponent) -> Unit)? = null, - val addRowPos: RowPos? = null, - val selectable: dynamic = null, - val selectableRangeMode: RangeMode? = null, - val selectableRollingSelection: Boolean? = null, - val selectablePersistence: Boolean? = null, - val selectableCheck: ((row: Tabulator.RowComponent) -> Boolean)? = null, - val movableRows: Boolean? = null, - val movableRowsConnectedTables: dynamic = null, - val movableRowsSender: dynamic = null, - val movableRowsReceiver: dynamic = null, - val resizableRows: Boolean? = null, - val scrollToRowPosition: RowPosition? = null, - val scrollToRowIfVisible: Boolean? = null, - val index: String? = null, - @Suppress("ArrayInDataClass") var data: Array<T>? = null, - val ajaxURL: String? = null, - val ajaxParams: dynamic = null, - val ajaxConfig: dynamic = null, - val ajaxContentType: dynamic = null, - val ajaxURLGenerator: ((url: String, config: dynamic, params: dynamic) -> String)? = null, - val ajaxRequestFunc: ((url: String, config: dynamic, params: dynamic) -> Promise<Any>)? = null, - val ajaxFiltering: Boolean? = null, - val ajaxSorting: Boolean? = null, - val ajaxProgressiveLoad: ProgressiveMode? = null, - val ajaxProgressiveLoadDelay: Int? = null, - val ajaxProgressiveLoadScrollMargin: Int? = null, - val ajaxLoader: Boolean? = null, - val ajaxLoaderLoading: String? = null, - val ajaxLoaderError: String? = null, - val initialSort: List<Tabulator.Sorter>? = null, - val sortOrderReverse: Boolean? = null, - val initialFilter: List<Tabulator.Filter>? = null, - val initialHeaderFilter: List<Any?>? = null, - val pagination: PaginationMode? = null, - val paginationSize: Int? = null, - val paginationSizeSelector: Boolean? = null, - val paginationElement: dynamic = null, - val paginationDataReceived: dynamic = null, - val paginationDataSent: dynamic = null, - val paginationAddRow: AddRowMode? = null, - val paginationButtonCount: Int? = null, - var persistenceID: String? = null, - var persistenceMode: Boolean? = null, - var persistentLayout: Boolean? = null, - var persistentSort: Boolean? = null, - var persistentFilter: Boolean? = null, - val locale: String? = null, - var langs: dynamic = null, - val localized: ((locale: String, lang: dynamic) -> Unit)? = null, - val dataTreeRowExpanded: ((row: Tabulator.RowComponent, level: Number) -> Unit)? = null, - val dataTreeRowCollapsed: ((row: Tabulator.RowComponent, level: Number) -> Unit)? = null, - val movableRowsSendingStart: ((toTables: Array<Any>) -> Unit)? = null, - val movableRowsSent: (( - fromRow: Tabulator.RowComponent, - toRow: Tabulator.RowComponent, toTable: Tabulator - ) -> Unit)? = null, - val movableRowsSentFailed: (( - fromRow: Tabulator.RowComponent, - toRow: Tabulator.RowComponent, toTable: Tabulator - ) -> Unit)? = null, - val movableRowsSendingStop: ((toTables: Array<Any>) -> Unit)? = null, - val movableRowsReceivingStart: ((fromRow: Tabulator.RowComponent, toTable: Tabulator) -> Unit)? = null, - val movableRowsReceived: (( - fromRow: Tabulator.RowComponent, - toRow: Tabulator.RowComponent, fromTable: Tabulator - ) -> Unit)? = null, - val movableRowsReceivedFailed: (( - fromRow: Tabulator.RowComponent, - toRow: Tabulator.RowComponent, fromTable: Tabulator - ) -> Unit)? = null, - val movableRowsReceivingStop: ((fromTable: Tabulator) -> Unit)? = null, - var rowClick: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowDblClick: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowContext: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowTap: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowDblTap: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowTapHold: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowMouseEnter: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowMouseLeave: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowMouseOver: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowMouseOut: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowMouseMove: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, - var rowAdded: ((row: Tabulator.RowComponent) -> Unit)? = null, - var rowUpdated: ((row: Tabulator.RowComponent) -> Unit)? = null, - var rowDeleted: ((row: Tabulator.RowComponent) -> Unit)? = null, - var rowMoved: ((row: Tabulator.RowComponent) -> Unit)? = null, - var rowResized: ((row: Tabulator.RowComponent) -> Unit)? = null, - var rowSelectionChanged: ((data: Array<Any>, rows: Array<Tabulator.RowComponent>) -> Unit)? = null, - var rowSelected: ((row: Tabulator.RowComponent) -> Unit)? = null, - var rowDeselected: ((row: Tabulator.RowComponent) -> Unit)? = null, - var cellClick: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellDblClick: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellContext: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellTap: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellDblTap: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellTapHold: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellMouseEnter: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellMouseLeave: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellMouseOver: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellMouseOut: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellMouseMove: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, - var cellEditing: ((cell: Tabulator.CellComponent) -> Unit)? = null, - var cellEdited: ((cell: Tabulator.CellComponent) -> Unit)? = null, - var cellEditCancelled: ((cell: Tabulator.CellComponent) -> Unit)? = null, - var columnMoved: ((column: Tabulator.ColumnComponent, columns: Array<dynamic>) -> Unit)? = null, - var columnResized: ((column: Tabulator.ColumnComponent) -> Unit)? = null, - var columnVisibilityChanged: ((column: Tabulator.ColumnComponent, visible: Boolean) -> Unit)? = null, - var columnTitleChanged: ((column: Tabulator.ColumnComponent) -> Unit)? = null, - var tableBuilding: (() -> Unit)? = null, - var tableBuilt: (() -> Unit)? = null, - var renderStarted: (() -> Unit)? = null, - var renderComplete: (() -> Unit)? = null, - var htmlImporting: (() -> Unit)? = null, - var htmlImported: (() -> Unit)? = null, - var dataLoading: ((data: List<T>) -> Unit)? = null, - var dataLoaded: ((data: List<T>) -> Unit)? = null, - var dataEdited: ((data: List<T>) -> Unit)? = null, - var pageLoaded: ((pageno: Int) -> Unit)? = null, - var dataSorting: ((sorters: Array<Tabulator.Sorter>) -> Unit)? = null, - var dataSorted: ((sorters: Array<Tabulator.Sorter>, rows: Array<Tabulator.RowComponent>) -> Unit)? = null, - var dataFiltering: ((filters: Array<Tabulator.Filter>) -> Unit)? = null, - var dataFiltered: ((filters: Array<Tabulator.Filter>, rows: Array<Tabulator.RowComponent>) -> Unit)? = null, - var validationFailed: ((cell: Tabulator.CellComponent, value: Any, validators: dynamic) -> Unit)? = null, - var ajaxRequesting: ((url: String, params: dynamic) -> Boolean)? = null, - var ajaxResponse: ((url: String, params: dynamic, response: dynamic) -> Any)? = null, - var ajaxError: ((xhr: dynamic, textStatus: String, errorThrown: dynamic) -> Unit)? = null + val height: String? = null, + val virtualDom: Boolean? = null, + val virtualDomBuffer: Int? = null, + val placeholder: String? = null, + val footerElement: String? = null, + val tooltips: ((cell: Tabulator.CellComponent) -> String)? = null, + val tooltipGenerationMode: TooltipGenerationMode? = null, + val history: Boolean? = null, + val keybindings: dynamic = null, + val downloadDataFormatter: dynamic = null, + val downloadConfig: DownloadConfig? = null, + val reactiveData: Boolean? = null, + val autoResize: Boolean? = null, + val columns: List<ColumnDefinition<T>>? = null, + val autoColumns: Boolean? = null, + val layout: Layout? = null, + val layoutColumnsOnNewData: Boolean? = null, + val responsiveLayout: ResponsiveLayout? = null, + val responsiveLayoutCollapseStartOpen: Boolean? = null, + val responsiveLayoutCollapseUseFormatters: Boolean? = null, + val columnMinWidth: Int? = null, + val resizableColumns: Boolean? = null, + val movableColumns: Boolean? = null, + val tooltipsHeader: Boolean? = null, + val headerFilterPlaceholder: String? = null, + val scrollToColumnPosition: ColumnPosition? = null, + val scrollToColumnIfVisible: Boolean? = null, + val rowFormatter: ((row: Tabulator.RowComponent) -> Unit)? = null, + val addRowPos: RowPos? = null, + val selectable: dynamic = null, + val selectableRangeMode: RangeMode? = null, + val selectableRollingSelection: Boolean? = null, + val selectablePersistence: Boolean? = null, + val selectableCheck: ((row: Tabulator.RowComponent) -> Boolean)? = null, + val movableRows: Boolean? = null, + val movableRowsConnectedTables: dynamic = null, + val movableRowsSender: dynamic = null, + val movableRowsReceiver: dynamic = null, + val resizableRows: Boolean? = null, + val scrollToRowPosition: RowPosition? = null, + val scrollToRowIfVisible: Boolean? = null, + val index: String? = null, + @Suppress("ArrayInDataClass") var data: Array<T>? = null, + val ajaxURL: String? = null, + val ajaxParams: dynamic = null, + val ajaxConfig: dynamic = null, + val ajaxContentType: dynamic = null, + val ajaxURLGenerator: ((url: String, config: dynamic, params: dynamic) -> String)? = null, + val ajaxRequestFunc: ((url: String, config: dynamic, params: dynamic) -> Promise<Any>)? = null, + val ajaxFiltering: Boolean? = null, + val ajaxSorting: Boolean? = null, + val ajaxProgressiveLoad: ProgressiveMode? = null, + val ajaxProgressiveLoadDelay: Int? = null, + val ajaxProgressiveLoadScrollMargin: Int? = null, + val ajaxLoader: Boolean? = null, + val ajaxLoaderLoading: String? = null, + val ajaxLoaderError: String? = null, + val initialSort: List<Tabulator.Sorter>? = null, + val sortOrderReverse: Boolean? = null, + val initialFilter: List<Tabulator.Filter>? = null, + val initialHeaderFilter: List<Any?>? = null, + val pagination: PaginationMode? = null, + val paginationSize: Int? = null, + val paginationSizeSelector: Boolean? = null, + val paginationElement: dynamic = null, + val paginationDataReceived: dynamic = null, + val paginationDataSent: dynamic = null, + val paginationAddRow: AddRowMode? = null, + val paginationButtonCount: Int? = null, + var persistenceID: String? = null, + var persistenceMode: Boolean? = null, + var persistentLayout: Boolean? = null, + var persistentSort: Boolean? = null, + var persistentFilter: Boolean? = null, + val locale: String? = null, + var langs: dynamic = null, + val localized: ((locale: String, lang: dynamic) -> Unit)? = null, + val dataTreeRowExpanded: ((row: Tabulator.RowComponent, level: Number) -> Unit)? = null, + val dataTreeRowCollapsed: ((row: Tabulator.RowComponent, level: Number) -> Unit)? = null, + val movableRowsSendingStart: ((toTables: Array<Any>) -> Unit)? = null, + val movableRowsSent: (( + fromRow: Tabulator.RowComponent, + toRow: Tabulator.RowComponent, toTable: Tabulator + ) -> Unit)? = null, + val movableRowsSentFailed: (( + fromRow: Tabulator.RowComponent, + toRow: Tabulator.RowComponent, toTable: Tabulator + ) -> Unit)? = null, + val movableRowsSendingStop: ((toTables: Array<Any>) -> Unit)? = null, + val movableRowsReceivingStart: ((fromRow: Tabulator.RowComponent, toTable: Tabulator) -> Unit)? = null, + val movableRowsReceived: (( + fromRow: Tabulator.RowComponent, + toRow: Tabulator.RowComponent, fromTable: Tabulator + ) -> Unit)? = null, + val movableRowsReceivedFailed: (( + fromRow: Tabulator.RowComponent, + toRow: Tabulator.RowComponent, fromTable: Tabulator + ) -> Unit)? = null, + val movableRowsReceivingStop: ((fromTable: Tabulator) -> Unit)? = null, + var rowClick: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowDblClick: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowContext: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowTap: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowDblTap: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowTapHold: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowMouseEnter: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowMouseLeave: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowMouseOver: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowMouseOut: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowMouseMove: ((e: dynamic, row: Tabulator.RowComponent) -> Unit)? = null, + var rowAdded: ((row: Tabulator.RowComponent) -> Unit)? = null, + var rowUpdated: ((row: Tabulator.RowComponent) -> Unit)? = null, + var rowDeleted: ((row: Tabulator.RowComponent) -> Unit)? = null, + var rowMoved: ((row: Tabulator.RowComponent) -> Unit)? = null, + var rowResized: ((row: Tabulator.RowComponent) -> Unit)? = null, + var rowSelectionChanged: ((data: Array<Any>, rows: Array<Tabulator.RowComponent>) -> Unit)? = null, + var rowSelected: ((row: Tabulator.RowComponent) -> Unit)? = null, + var rowDeselected: ((row: Tabulator.RowComponent) -> Unit)? = null, + var cellClick: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellDblClick: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellContext: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellTap: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellDblTap: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellTapHold: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellMouseEnter: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellMouseLeave: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellMouseOver: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellMouseOut: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellMouseMove: ((e: Any, cell: Tabulator.CellComponent) -> Unit)? = null, + var cellEditing: ((cell: Tabulator.CellComponent) -> Unit)? = null, + var cellEdited: ((cell: Tabulator.CellComponent) -> Unit)? = null, + var cellEditCancelled: ((cell: Tabulator.CellComponent) -> Unit)? = null, + var columnMoved: ((column: Tabulator.ColumnComponent, columns: Array<dynamic>) -> Unit)? = null, + var columnResized: ((column: Tabulator.ColumnComponent) -> Unit)? = null, + var columnVisibilityChanged: ((column: Tabulator.ColumnComponent, visible: Boolean) -> Unit)? = null, + var columnTitleChanged: ((column: Tabulator.ColumnComponent) -> Unit)? = null, + var tableBuilding: (() -> Unit)? = null, + var tableBuilt: (() -> Unit)? = null, + var renderStarted: (() -> Unit)? = null, + var renderComplete: (() -> Unit)? = null, + var htmlImporting: (() -> Unit)? = null, + var htmlImported: (() -> Unit)? = null, + var dataLoading: ((data: List<T>) -> Unit)? = null, + var dataLoaded: ((data: List<T>) -> Unit)? = null, + var dataEdited: ((data: List<T>) -> Unit)? = null, + var pageLoaded: ((pageno: Int) -> Unit)? = null, + var dataSorting: ((sorters: Array<Tabulator.Sorter>) -> Unit)? = null, + var dataSorted: ((sorters: Array<Tabulator.Sorter>, rows: Array<Tabulator.RowComponent>) -> Unit)? = null, + var dataFiltering: ((filters: Array<Tabulator.Filter>) -> Unit)? = null, + var dataFiltered: ((filters: Array<Tabulator.Filter>, rows: Array<Tabulator.RowComponent>) -> Unit)? = null, + var validationFailed: ((cell: Tabulator.CellComponent, value: Any, validators: dynamic) -> Unit)? = null, + var ajaxRequesting: ((url: String, params: dynamic) -> Boolean)? = null, + var ajaxResponse: ((url: String, params: dynamic, response: dynamic) -> Any)? = null, + var ajaxError: ((xhr: dynamic, textStatus: String, errorThrown: dynamic) -> Unit)? = null ) /** @@ -676,7 +680,7 @@ data class TabulatorOptions<T : Any>( */ @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE", "ComplexMethod") fun <T : Any> TabulatorOptions<T>.toJs( - i18nTranslator: (String) -> (String) + i18nTranslator: (String) -> (String) ): Tabulator.Options { val tmpCellEditCancelled = this.columns?.find { it.editorComponentFunction != null }?.let { { cell: Tabulator.CellComponent -> @@ -709,9 +713,9 @@ fun <T : Any> TabulatorOptions<T>.toJs( if (layoutColumnsOnNewData != null) this.layoutColumnsOnNewData = layoutColumnsOnNewData if (responsiveLayout != null) this.responsiveLayout = responsiveLayout.layout if (responsiveLayoutCollapseStartOpen != null) this.responsiveLayoutCollapseStartOpen = - responsiveLayoutCollapseStartOpen + responsiveLayoutCollapseStartOpen if (responsiveLayoutCollapseUseFormatters != null) this.responsiveLayoutCollapseUseFormatters = - responsiveLayoutCollapseUseFormatters + responsiveLayoutCollapseUseFormatters if (columnMinWidth != null) this.columnMinWidth = columnMinWidth if (resizableColumns != null) this.resizableColumns = resizableColumns if (movableColumns != null) this.movableColumns = movableColumns @@ -746,7 +750,7 @@ fun <T : Any> TabulatorOptions<T>.toJs( if (ajaxProgressiveLoad != null) this.ajaxProgressiveLoad = ajaxProgressiveLoad.mode if (ajaxProgressiveLoadDelay != null) this.ajaxProgressiveLoadDelay = ajaxProgressiveLoadDelay if (ajaxProgressiveLoadScrollMargin != null) this.ajaxProgressiveLoadScrollMargin = - ajaxProgressiveLoadScrollMargin + ajaxProgressiveLoadScrollMargin if (ajaxLoader != null) this.ajaxLoader = ajaxLoader if (ajaxLoaderLoading != null) this.ajaxLoaderLoading = i18nTranslator(ajaxLoaderLoading) if (ajaxLoaderError != null) this.ajaxLoaderError = i18nTranslator(ajaxLoaderError) @@ -825,9 +829,24 @@ fun <T : Any> TabulatorOptions<T>.toJs( if (renderComplete != null) this.renderComplete = renderComplete if (htmlImporting != null) this.htmlImporting = htmlImporting if (htmlImported != null) this.htmlImported = htmlImported - if (dataLoading != null) this.dataLoading = dataLoading - if (dataLoaded != null) this.dataLoaded = dataLoaded - if (dataEdited != null) this.dataEdited = dataEdited + val dataLoadingFun = dataLoading?.let { + { data: Array<T> -> + it(data.toList()) + } + } + if (dataLoadingFun != null) this.dataLoading = dataLoadingFun + val dataLoadedFun = dataLoaded?.let { + { data: Array<T> -> + it(data.toList()) + } + } + if (dataLoadedFun != null) this.dataLoaded = dataLoadedFun + val dataEditedFun = dataEdited?.let { + { data: Array<T> -> + it(data.toList()) + } + } + if (dataEditedFun != null) this.dataEdited = dataEditedFun if (pageLoaded != null) this.pageLoaded = pageLoaded if (dataSorting != null) this.dataSorting = dataSorting if (dataSorted != null) this.dataSorted = dataSorted diff --git a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt index ed803109..bd17d7bf 100644 --- a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt +++ b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt @@ -23,23 +23,20 @@ package pl.treksoft.kvision.tabulator import com.github.snabbdom.VNode import com.lightningkite.kotlin.observable.list.ObservableList -import kotlinx.serialization.KSerializer -import kotlinx.serialization.list -import kotlinx.serialization.serializer import org.w3c.dom.HTMLElement import pl.treksoft.kvision.KVManagerTabulator import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.i18n.I18n +import pl.treksoft.kvision.redux.ReduxStore import pl.treksoft.kvision.table.TableType -import pl.treksoft.kvision.utils.JSON import pl.treksoft.kvision.utils.createInstance import pl.treksoft.kvision.utils.obj import pl.treksoft.kvision.utils.syncWithList -import pl.treksoft.kvision.tabulator.js.Tabulator as JsTabulator import redux.RAction -import pl.treksoft.kvision.redux.* +import kotlin.browser.window +import pl.treksoft.kvision.tabulator.js.Tabulator as JsTabulator /** * Tabulator component. @@ -54,13 +51,13 @@ import pl.treksoft.kvision.redux.* */ @Suppress("LargeClass", "TooManyFunctions") open class Tabulator<T : Any>( - protected val data: List<T>? = null, - protected val dataUpdateOnEdit: Boolean = true, - val options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf() + protected val data: List<T>? = null, + protected val dataUpdateOnEdit: Boolean = true, + val options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf() ) : - Widget(classes) { + Widget(classes) { /** * Table types. @@ -211,8 +208,8 @@ open class Tabulator<T : Any>( protected fun createJsTabulator() { (this.getElement() as? HTMLElement)?.let { jsTabulator = - KVManagerTabulator.getConstructor() - .createInstance(it, options.toJs(this::translate)) + KVManagerTabulator.getConstructor() + .createInstance(it, options.toJs(this::translate)) if (currentPage != null) { jsTabulator?.setPageSize(pageSize ?: 0) jsTabulator?.setPage(currentPage) @@ -249,6 +246,9 @@ open class Tabulator<T : Any>( open fun replaceData(data: Array<T>) { @Suppress("UnsafeCastFromDynamic") options.data = data + if ((getElementJQuery()?.find(".tabulator-editing")?.length?.toInt() ?: 0) > 0) { + this.removeCustomEditors() + } jsTabulator?.replaceData(data, null, null) } @@ -267,10 +267,10 @@ open class Tabulator<T : Any>( * @param active return only visible data * @return current data */ + @Suppress("UNCHECKED_CAST") open fun getData(active: Boolean): List<T>? { return if (jsTabulator != null) { - val native = jsTabulator?.getData(active) as? List<T> - native + jsTabulator?.getData(active)?.toList() as? List<T> } else { data } @@ -280,10 +280,10 @@ open class Tabulator<T : Any>( * Returns the selected data in the table. * @return selected data */ + @Suppress("UNCHECKED_CAST") open fun getSelectedData(): List<T> { return if (jsTabulator != null) { - val native = jsTabulator?.getSelectedData() as List<T> - native + jsTabulator?.getSelectedData()?.toList() as List<T> } else { listOf() } @@ -337,9 +337,9 @@ open class Tabulator<T : Any>( * @param ifVisible scroll to already visible row */ open fun scrollToRow( - row: Int, - position: RowPosition? = null, - ifVisible: Boolean? = null + row: Int, + position: RowPosition? = null, + ifVisible: Boolean? = null ) { jsTabulator?.scrollToRow(row, position, ifVisible) } @@ -528,6 +528,13 @@ open class Tabulator<T : Any>( jsTabulator?.navigateDown() } + internal fun removeCustomEditors() { + EditorRoot.cancel?.invoke(null) + EditorRoot.disposeTimer?.let { window.clearTimeout(it) } + EditorRoot.root?.dispose() + EditorRoot.root = null + } + companion object { internal var counter = 0 @@ -536,13 +543,13 @@ open class Tabulator<T : Any>( * * It takes the same parameters as the constructor of the built component. */ - inline fun <reified T : Any> Container.tabulator( - data: List<T>? = null, - dataUpdateOnEdit: Boolean = true, - options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf(), - noinline init: (Tabulator<T>.() -> Unit)? = null + fun <T : Any> Container.tabulator( + data: List<T>? = null, + dataUpdateOnEdit: Boolean = true, + options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf(), + init: (Tabulator<T>.() -> Unit)? = null ): Tabulator<T> { val tabulator = create(data, dataUpdateOnEdit, options, types, classes) init?.invoke(tabulator) @@ -553,13 +560,13 @@ open class Tabulator<T : Any>( /** * DSL builder extension function for general redux store. */ - inline fun <reified T : Any, S : Any, A: RAction> Container.tabulator( - store: ReduxStore<S, A>, - noinline dataFactory: (S) -> List<T>, - options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf(), - noinline init: (Tabulator<T>.() -> Unit)? = null + fun <T : Any, S : Any, A : RAction> Container.tabulator( + store: ReduxStore<S, A>, + dataFactory: (S) -> List<T>, + options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf(), + init: (Tabulator<T>.() -> Unit)? = null ): Tabulator<T> { val tabulator = create(store, dataFactory, options, types, classes) init?.invoke(tabulator) @@ -570,12 +577,12 @@ open class Tabulator<T : Any>( /** * DSL builder extension function for dedicated redux store (backed with a list). */ - inline fun <reified T : Any, A: RAction> Container.tabulator( - store: ReduxStore<List<T>, A>, - options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf(), - noinline init: (Tabulator<T>.() -> Unit)? = null + fun <T : Any, A : RAction> Container.tabulator( + store: ReduxStore<List<T>, A>, + options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf(), + init: (Tabulator<T>.() -> Unit)? = null ): Tabulator<T> { val tabulator = create(store, options, types, classes) init?.invoke(tabulator) @@ -587,10 +594,10 @@ open class Tabulator<T : Any>( * DSL builder extension function for dynamic data (send within options parameter). */ fun <T : Any> Container.tabulator( - options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf(), - init: (Tabulator<T>.() -> Unit)? = null + options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf(), + init: (Tabulator<T>.() -> Unit)? = null ): Tabulator<T> { val tabulator = Tabulator(dataUpdateOnEdit = false, options = options, types = types, classes = classes) init?.invoke(tabulator) @@ -601,13 +608,13 @@ open class Tabulator<T : Any>( /** * A helper function to create a Tabulator object with correct serializer. */ - inline fun <reified T : Any> create( - data: List<T>? = null, - dataUpdateOnEdit: Boolean = true, - options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf(), - noinline init: (Tabulator<T>.() -> Unit)? = null + fun <T : Any> create( + data: List<T>? = null, + dataUpdateOnEdit: Boolean = true, + options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf(), + init: (Tabulator<T>.() -> Unit)? = null ): Tabulator<T> { val tabulator = Tabulator(data, dataUpdateOnEdit, options, types, classes) init?.invoke(tabulator) @@ -617,13 +624,13 @@ open class Tabulator<T : Any>( /** * A helper function to create a Tabulator object with correct serializer and general redux store. */ - inline fun <reified T : Any, S : Any, A : RAction> create( - store: ReduxStore<S, A>, - noinline dataFactory: (S) -> List<T>, - options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf(), - noinline init: (Tabulator<T>.() -> Unit)? = null + fun <T : Any, S : Any, A : RAction> create( + store: ReduxStore<S, A>, + dataFactory: (S) -> List<T>, + options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf(), + init: (Tabulator<T>.() -> Unit)? = null ): Tabulator<T> { val data = dataFactory(store.getState()) val tabulator = Tabulator(data, false, options, types, classes) @@ -637,12 +644,12 @@ open class Tabulator<T : Any>( /** * A helper function to create a Tabulator object with correct serializer and dedicated redux store. */ - inline fun <reified T : Any, A : RAction> create( - store: ReduxStore<List<T>, A>, - options: TabulatorOptions<T> = TabulatorOptions(), - types: Set<TableType> = setOf(), - classes: Set<String> = setOf(), - noinline init: (Tabulator<T>.() -> Unit)? = null + fun <T : Any, A : RAction> create( + store: ReduxStore<List<T>, A>, + options: TabulatorOptions<T> = TabulatorOptions(), + types: Set<TableType> = setOf(), + classes: Set<String> = setOf(), + init: (Tabulator<T>.() -> Unit)? = null ): Tabulator<T> { val data = store.getState() val tabulator = Tabulator(data, false, options, types, classes) diff --git a/kvision-modules/kvision-tabulator/webpack.config.d/css.js b/kvision-modules/kvision-tabulator/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-tabulator/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-upload/webpack.config.d/css.js b/kvision-modules/kvision-upload/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-upload/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-upload/webpack.config.d/file.js b/kvision-modules/kvision-upload/webpack.config.d/file.js new file mode 100644 index 00000000..a5c7b5da --- /dev/null +++ b/kvision-modules/kvision-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/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index fbcd89da..414356ce 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -86,6 +86,10 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component * Determines if the current widget is draggable. */ var draggable: Boolean? by refreshOnUpdate() + /** + * Determines if the current widget is strictly bound to the DOM. + */ + var strictDOM: Boolean by refreshOnUpdate(false) protected var surroundingSpan by refreshOnUpdate(false) @@ -184,7 +188,11 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ private fun getSnOpt(): VNodeData { return snOpt { - if (vnkey != null) key = vnkey + if (vnkey != null) { + key = vnkey + } else if (strictDOM) { + key = hashCode().toString() + } attrs = snAttrs(getSnAttrsInternal()) style = snStyle(getSnStyleInternal()) `class` = snClasses(getSnClassInternal()) diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt index f376de5a..5fac0494 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt +++ b/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt @@ -33,9 +33,13 @@ import pl.treksoft.kvision.utils.px * Context menu component. * * @constructor + * @param element an element to bind + * @param fixedPosition use fixed positioning * @param classes a set of CSS class names */ open class ContextMenu( + element: Widget? = null, + protected val fixedPosition: Boolean = false, classes: Set<String> = setOf(), init: (ContextMenu.() -> Unit)? = null ) : ListTag(ListType.UL, classes = classes + "dropdown-menu") { @@ -44,7 +48,7 @@ open class ContextMenu( hide() @Suppress("LeakingThis") display = Display.BLOCK - val root = Root.getLastRoot() + val root = element?.getRoot() ?: Root.getLastRoot() if (root != null) { @Suppress("LeakingThis") root.addContextMenu(this) @@ -61,22 +65,32 @@ open class ContextMenu( * @return current context menu */ open fun positionMenu(mouseEvent: MouseEvent): ContextMenu { - this.top = mouseEvent.pageY.toInt().px - this.left = mouseEvent.pageX.toInt().px + 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<String> = setOf(), init: (ContextMenu.() -> Unit)? = null ): ContextMenu { - val contextMenu = ContextMenu(classes).apply { init?.invoke(this) } + val contextMenu = ContextMenu(this, fixedPosition, classes).apply { init?.invoke(this) } this.setContextMenu(contextMenu) return contextMenu } |