All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.internal.actions.SetTouchedAction.kt Maven / Gradle / Ivy

There is a newer version: 0.23.0
Show newest version
package io.kform.internal.actions

import io.kform.*
import io.kform.internal.*

/** Action that sets all values whose path matches [path] as touched, as well as their parents. */
internal class SetTouchedAction(formManager: FormManager, private val path: AbsolutePath) :
    ValueStateAction(formManager) {
    override fun toString() = "SetTouched($path)"

    override val accesses =
        listOf(
            AccessValueStateTree(ActionAccessType.Read),
            AccessIsTouched(ActionAccessType.Write),
            AccessValidationState(ActionAccessType.Read),
            AccessDescendantsDisplayingIssues(ActionAccessType.Write)
        )
    override val accessedPaths = parentPaths(path) + path

    override suspend fun run() = stateInfo(path).forEach { info -> setTouched(info) }

    private tailrec suspend fun setTouched(info: StateInfo<*>) {
        val (state, schema, path) = info
        state as StateImpl?
        if (state != null && !state.isTouched) {
            state.isTouched = true
            formManager.eventsBus.emit(StateEvent.TouchedChange(true, path, schema))

            val newDisplayStatus = state.displayStatus()
            if (newDisplayStatus != DisplayStatus.Valid) {
                formManager.eventsBus.emit(StateEvent.DisplayChange(newDisplayStatus, path, schema))
            }

            if (info.path != AbsolutePath.ROOT) {
                val parentPath = path.parent()
                // Once the value has been touched, if it has issues, we need to increment the count
                // of "descendants displaying issues" for all ancestors
                val dominantSeverity = state.dominantIssueSeverity()
                if (dominantSeverity != null) {
                    incrementDescendantsDisplayingIssues(parentPath, dominantSeverity)
                }

                setTouched(stateInfo(parentPath).single())
            }
        }
    }

    private tailrec suspend fun incrementDescendantsDisplayingIssues(
        path: AbsolutePath,
        dominantSeverity: ValidationIssueSeverity
    ) {
        val info = stateInfo(path).single()
        val state = info.state as ParentStateImpl

        val oldDisplayStatus = state.displayStatus()
        if (dominantSeverity == ValidationIssueSeverity.Error) {
            ++state.descendantsDisplayingErrors
        } else {
            ++state.descendantsDisplayingWarnings
        }
        val newDisplayStatus = state.displayStatus()

        if (oldDisplayStatus != newDisplayStatus) {
            formManager.eventsBus.emit(
                StateEvent.DisplayChange(newDisplayStatus, path, info.schema)
            )
        }
        if (path != AbsolutePath.ROOT) {
            incrementDescendantsDisplayingIssues(path.parent(), dominantSeverity)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy