Jelajahi Sumber

Merge pull request #30514 from overleaf/ii-cms-launchpad-typescript

[web] Convert cms and launchpad to TypeScript

GitOrigin-RevId: d2b38671a2389206dafc7bd50c28cf0bb9683601
ilkin-overleaf 9 bulan lalu
induk
melakukan
291f882aa2

+ 1 - 0
services/web/frontend/js/utils/meta.ts

@@ -76,6 +76,7 @@ export interface Meta {
   >
   'ol-adminCapabilities': AdminCapability[]
   'ol-adminSubscription': AdminSubscription
+  'ol-adminUserExists': boolean
   'ol-aiAssistViaWritefullSource': string
   'ol-algolia': AlgoliaConfig | undefined
   'ol-allInReconfirmNotificationPeriods': UserEmailData[]

+ 0 - 82
services/web/modules/launchpad/frontend/js/pages/launchpad.js

@@ -1,82 +0,0 @@
-/* global io */
-import '@/marketing'
-import {
-  inflightHelper,
-  toggleDisplay,
-} from '../../../../../frontend/js/features/form-helpers/hydrate-form'
-import getMeta from '../../../../../frontend/js/utils/meta'
-
-function setUpStatusIndicator(el, fn) {
-  inflightHelper(el)
-
-  const displaySuccess = el.querySelectorAll('[data-ol-result="success"]')
-  const displayError = el.querySelectorAll('[data-ol-result="error"]')
-
-  // The checks are very lightweight and do not appear to do anything
-  //  from looking at the UI. Add an artificial delay of 1s to show that
-  //  we are actually doing something. :)
-  const artificialProgressDelay = 1000
-
-  function run() {
-    setTimeout(() => {
-      fn()
-        .then(() => {
-          toggleDisplay(displayError, displaySuccess)
-        })
-        .catch(error => {
-          el.querySelector('[data-ol-error]').textContent = error.message
-          toggleDisplay(displaySuccess, displayError)
-        })
-        .finally(() => {
-          el.dispatchEvent(new Event('idle'))
-        })
-    }, artificialProgressDelay)
-  }
-
-  el.querySelectorAll('button').forEach(retryBtn => {
-    retryBtn.addEventListener('click', function (e) {
-      e.preventDefault()
-      el.dispatchEvent(new Event('pending'))
-      run()
-    })
-  })
-
-  run()
-}
-
-function setUpStatusIndicators() {
-  setUpStatusIndicator(
-    document.querySelector('[data-ol-launchpad-check="websocket"]'),
-    () => {
-      const timeout = 10 * 1000
-      const socket = io.connect(null, {
-        reconnect: false,
-        'connect timeout': timeout,
-        'force new connection': true,
-        query: new URLSearchParams({
-          projectId: '404404404404404404404404',
-        }).toString(),
-      })
-      return new Promise((resolve, reject) => {
-        setTimeout(() => reject(new Error('timed out')), timeout)
-        socket.on('connectionRejected', function (err) {
-          if (err.code === 'ProjectNotFound') {
-            // We received the response from joinProject, so the websocket is up.
-            resolve()
-          } else {
-            reject(new Error(err && err.message))
-          }
-        })
-        socket.on('connect_failed', function (err) {
-          reject(new Error(err && err.message))
-        })
-      }).finally(() => {
-        socket.disconnect()
-      })
-    }
-  )
-}
-
-if (getMeta('ol-adminUserExists')) {
-  setUpStatusIndicators()
-}

+ 103 - 0
services/web/modules/launchpad/frontend/js/pages/launchpad.ts

@@ -0,0 +1,103 @@
+import '@/marketing'
+import {
+  inflightHelper,
+  toggleDisplay,
+} from '@/features/form-helpers/hydrate-form'
+import getMeta from '@/utils/meta'
+import { Socket } from '@/features/ide-react/connection/types/socket'
+
+declare const io: {
+  connect: (url: string | null, options?: Record<string, unknown>) => Socket
+}
+
+interface ConnectionRejectedError {
+  code?: string
+  message?: string
+}
+
+function setUpStatusIndicator(el: HTMLElement, fn: () => Promise<void>) {
+  inflightHelper(el)
+
+  const displaySuccess = el.querySelectorAll<HTMLElement>(
+    '[data-ol-result="success"]'
+  )
+  const displayError = el.querySelectorAll<HTMLElement>(
+    '[data-ol-result="error"]'
+  )
+
+  // The checks are very lightweight and do not appear to do anything
+  //  from looking at the UI. Add an artificial delay of 1s to show that
+  //  we are actually doing something. :)
+  const artificialProgressDelay = 1000
+
+  function run() {
+    setTimeout(() => {
+      fn()
+        .then(() => {
+          toggleDisplay(displayError, displaySuccess)
+        })
+        .catch(error => {
+          const errorElement = el.querySelector('[data-ol-error]')
+          if (errorElement) {
+            errorElement.textContent = error.message
+          }
+          toggleDisplay(displaySuccess, displayError)
+        })
+        .finally(() => {
+          el.dispatchEvent(new Event('idle'))
+        })
+    }, artificialProgressDelay)
+  }
+
+  el.querySelectorAll('button').forEach(retryBtn => {
+    retryBtn.addEventListener('click', function (e) {
+      e.preventDefault()
+      el.dispatchEvent(new Event('pending'))
+      run()
+    })
+  })
+
+  run()
+}
+
+function setUpStatusIndicators() {
+  const launchpadCheckElement = document.querySelector<HTMLElement>(
+    '[data-ol-launchpad-check="websocket"]'
+  )
+
+  if (!launchpadCheckElement) {
+    return
+  }
+
+  setUpStatusIndicator(launchpadCheckElement, () => {
+    const timeout = 10 * 1000
+    const socket = io.connect(null, {
+      reconnect: false,
+      'connect timeout': timeout,
+      'force new connection': true,
+      query: new URLSearchParams({
+        projectId: '404404404404404404404404',
+      }).toString(),
+    })
+    return new Promise<void>((resolve, reject) => {
+      setTimeout(() => reject(new Error('timed out')), timeout)
+      socket.on('connectionRejected', function (err?: ConnectionRejectedError) {
+        if (err?.code === 'ProjectNotFound') {
+          // We received the response from joinProject, so the websocket is up.
+          resolve()
+        } else {
+          reject(new Error(err && err.message))
+        }
+      })
+      socket.on('connect_failed', function (err?: Error) {
+        reject(new Error(err && err.message))
+      })
+    }).finally(() => {
+      socket.disconnect()
+    })
+  })
+}
+
+if (getMeta('ol-adminUserExists')) {
+  setUpStatusIndicators()
+}