JetBrains / kotlin-wrappers

Kotlin wrappers for popular JavaScript libraries
Apache License 2.0
1.34k stars 164 forks source link

How to create Routes on Kotlin/Js #2544

Closed bruimafia closed 2 weeks ago

bruimafia commented 2 weeks ago

I have a great application. It used the implementation library("org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:0.0.1-pre.282-kotlin-1.6.10"). I decided to gradually increase the library version by making +1. I have reached version 1.0.0-pre.291, fixed some bugs and innovations in the versions. But when switching to 1.0.0-pre.292, I swear at the Routers and I don't understand how to fix it. Please help me, I want to move gradually, and not immediately to the current version, since in this case I have several hundred errors. And with this approach, I correct them gradually. Swears at the ignorance of the Browser Router class, as well as Navigate, attr.path and attr.element

` //import react.router.dom.BrowserRouter import kotlinx.browser.window import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.await import kotlinx.coroutines.launch import org.w3c.fetch.RequestInit import react.dom.render import react.redux.provider import react.router.dom.BrowserRouter import serviceRegistry.SERVICE_REGISTRY_ENDPOINT import stateManagement.store import structure.pageComponent import transport.utils.decodeURIComponent import web.dom.document import wrappers.d3.d3Selection import kotlin.coroutines.CoroutineContext

  private class Application : CoroutineScope {
      override val coroutineContext: CoroutineContext = Job()

      fun start() {
          // TODO подумать над тем, чтобы упавший сервис регистрации не блокировал отрисовку приложения
          launch {
              setServiceRegistryAddress()
              renderApp()
          }
      }

      private suspend fun setServiceRegistryAddress() {
          val response = window.fetch(
              "/$SERVICE_REGISTRY_ENDPOINT", RequestInit(method = "GET")
          ).await()
          val message = response.text().await()
          MicroserviceApplication.fromStringAddress(decodeURIComponent(message))
      }

      private fun renderApp() {
          render(document.getElementById("react-app") ?: return) {
              BrowserRouter {
                  provider(store) {
                          pageComponent()
                  }
              }
          }
      }

  }

  fun main() {
      // hack to import module for change of multiple attributes (.attrs { })
      d3Selection
      val application = Application()
      application.start()
  }

`

` import kotlinx.browser.localStorage import kotlinx.browser.sessionStorage import kotlinx.css. import pages.login.loginSection.Login import pages.releases.releasePage import pages.sections.analytic.analyticsPage import pages.sections.decisionTree.decisionSection import pages.sections.documents.documentsPage import pages.sections.journalLogs.features.journalLogsPage import pages.sections.layout. import pages.sections.model.model import pages.sections.notFound.notFoundPage import pages.sections.notifications.popUpNotifications import pages.sections.projects.saveProjectKeyToSessionStorage import pages.sections.projectsEmz.projectsEmz import pages.sections.queries. import pages.sections.settings.settingsFile.fileManagerPage import pages.sections.settings.settingsLayout import pages.sections.summary.summary import pages.sections.users.usersPage.UsersPage import pages.tokenMonitor.useTokenMonitor import react. import react.redux.useDispatch import react.router. import redux.RAction import scope.Section import stateManagement. import stateManagement.State import structure.modals.modal import styled.css import styled.styledDiv import utils.auth.OS import utils.auth.getOS import utils.getProjectKey import utils.hooks.useWatchingCleanup import utils.hooks.voiceAssistant.useMicrophoneListener import utils.hooks.voiceAssistant.useVoiceAssistantNavigator import utils.savedProjectStorageKey import utils.savedUserStorageKey import wrappers.leafleth.leafletMarkerCluster

        val pageComponent = memo(fc {

            val dispatch = useDispatch<RAction, State>()
            val navigate = useNavigate()
            val location = useLocation()

            useWatchingCleanup()
            useMicrophoneListener()
            useVoiceAssistantNavigator()
            useTokenMonitor()

            useEffect {
                cleanup {
                    localStorage.setItem(savedProjectStorageKey, sessionStorage.getItem(savedProjectStorageKey) ?: "")
                }
            }

            useEffectOnce {
                if (getOS() == OS.LINUX) {
                    dispatch(dcLogin())
                }

                val userID = localStorage.getItem(savedUserStorageKey) ?: ""
                if (userID.isNotEmpty()) {
                    dispatch(getUserById(userID.toLong()))
                    dispatch(ChangeAppInitStatus(true))
                }
                val projectKey = localStorage.getItem(savedProjectStorageKey) ?: ""
                saveProjectKeyToSessionStorage(projectKey)
                val routes = listOf(Section.Users.path, Section.Projects.path, "/login", "/")
                if (location.pathname !in routes) {
                    if (getProjectKey().isEmpty()) navigate(Section.Projects.path)
                    else dispatch(initializeKeyspace())
                }
            }

            leafletMarkerCluster // Необходимо для корректного распределения кастомных отметок на карте, находящихся в одинаковых координатах

            val loginPage = createElement<Props> {
                Login()
            }

            val createTemplatesPage = createElement<Props> {
                buildPage(templatesPage).withLayout(mainSectionLayout)
            }

            val createQueriesPage = createElement<Props> {
                buildPage(queriesPage).withLayout(mainSectionLayout)
            }

            val createSnapshotsPage = createElement<Props> {
                buildPage(snapshotsPage).withLayout(mainSectionLayout)
            }

            val createSummary = createElement<Props> {
                buildPage(summary).withLayout(summaryLayout)
            }

            val createModel = createElement<Props> {
                buildPage(model).withLayout(twoPanelsLayout)
            }

            val createProjectsEmz = createElement<Props> {
                buildPage(projectsEmz).withLayout(mainSectionLayout)
            }

            val createTemplates = createElement<Props> {
                buildPage(localTemplates).withLayout(twoPanelsLayout)
            }

            val createQueries = createElement<Props> {
                buildPage(queries).withLayout(twoPanelsLayout)
            }

            val createSnapshots = createElement<Props> {
                buildPage(snapshots).withLayout(twoPanelsLayout)
            }

            val releasesPage = createElement<Props> { buildPage(releasePage).withLayout(mainSectionLayout) }

            val createNotFound = createElement<Props> { buildPage(notFoundPage).withLayout(mainSectionLayout) }

            val usersPage = createElement<Props> { buildPage(UsersPage).withLayout(mainSectionLayout) }

            val documentsPage = createElement<Props> { buildPage(documentsPage).withLayout(mainSectionLayout) }

            val fileManagerPage = createElement<Props> {
                settingsLayout { fileManagerPage() }
            }

            val analyticsPage = createElement<Props> {
                settingsLayout { analyticsPage() }
            }

            val journalLogsPage = createElement<Props> {
                settingsLayout { journalLogsPage() }
            }

            val iconDesignerPage = createElement<Props> {
                settingsLayout {
                    styledDiv {
                        css {
                            height = 100.pct
                            display = Display.flex
                            justifyContent = JustifyContent.center
                            alignItems = Align.center
                        }
                        styledDiv { +"В разработке" }
                    }
                }
            }

            val decisionTreePage = createElement<Props> {
                buildPage(decisionSection).withLayout(decisionTreeLayout)
            }

            val indexPage = createElement<Props> {
                Navigate {
                    attrs.to = "/login"
                }
            }

            modal()
            popUpNotifications()

            Routes {
                Route {
                    attrs.path = "/login"
                    attrs.element = loginPage
                }
                Route {
                    attrs.index = true
                    attrs.element = indexPage
                }
                Route {
                    attrs.path = Section.DecisionTree.path
                    attrs.element = decisionTreePage
                }
                Route {
                    attrs.path = Section.Summary.path
                    attrs.element = createSummary
                }
                Route {
                    attrs.path = Section.Model.path
                    attrs.element = createModel
                }
                Route {
                    attrs.path = Section.Templates.path
                    attrs.element = createTemplates
                }
                Route {
                    attrs.path = Section.Snapshots.path
                    attrs.element = createSnapshots
                }
                Route {
                    attrs.path = Section.Queries.path
                    attrs.element = createQueries
                }
                Route {
                    attrs.path = Section.TemplatesPage.path
                    attrs.element = createTemplatesPage
                }
                Route {
                    attrs.path = Section.QueriesPage.path
                    attrs.element = createQueriesPage
                }
                Route {
                    attrs.path = Section.SnapshotsPage.path
                    attrs.element = createSnapshotsPage
                }
                Route {
                    attrs.path = Section.Releases.path
                    attrs.element = releasesPage
                }
                Route {
                    attrs.path = Section.Projects.path
                    attrs.element = createProjectsEmz
                }
                Route {
                    attrs.path = Section.Users.path
                    attrs.element = usersPage
                }
                Route {
                    attrs.path = Section.Documents.path
                    attrs.element = documentsPage
                }
                Route {
                    attrs.path = Section.FileManager.path
                    attrs.element = fileManagerPage
                }
                Route {
                    attrs.path = Section.Analytics.path
                    attrs.element = analyticsPage
                }
                Route {
                    attrs.path = Section.JournalLogs.path
                    attrs.element = journalLogsPage
                }
                Route {
                    attrs.path = Section.IconDesigner.path
                    attrs.element = iconDesignerPage
                }
                Route {
                    attrs.path = "/api/logout"
                    attrs.element = null
                }
                Route {
                    attrs.path = "*"
                    attrs.element = createNotFound
                }
            }
        })

`

turansky commented 2 weeks ago

@bruimafia latest example of router usage you can find here

bruimafia commented 2 weeks ago

@turansky There's for the kotlin-wrappers version.version=pre.812. I need it for the kotlin-wrapper version.version=pre.492. I don't see the import react.router.dom.createBrowserRouter dependency

turansky commented 2 weeks ago

@bruimafia additional hints you can find in history of this repository