Skip to content

Commit

Permalink
Merge branch 'develop' into wip/sb/project-manager-host-port
Browse files Browse the repository at this point in the history
  • Loading branch information
somebody1234 committed Aug 11, 2023
2 parents 088e404 + e035b2d commit 9509c7e
Show file tree
Hide file tree
Showing 56 changed files with 3,500 additions and 499 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@
- [Update to GraalVM 23.0.0][7176]
- [Using official BigInteger support][7420]
- [Allow users to give a project other than Upper_Snake_Case name][7397]
- [Support renaming variable or function][7515]

[3227]: https://github.com/enso-org/enso/pull/3227
[3248]: https://github.com/enso-org/enso/pull/3248
Expand Down Expand Up @@ -1040,6 +1041,7 @@
[7291]: https://github.com/enso-org/enso/pull/7291
[7420]: https://github.com/enso-org/enso/pull/7420
[7397]: https://github.com/enso-org/enso/pull/7397
[7515]: https://github.com/enso-org/enso/pull/7515

# Enso 2.0.0-alpha.18 (2021-10-12)

Expand Down
20 changes: 14 additions & 6 deletions app/ide-desktop/lib/content/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ class Main implements AppRunner {

/** Run an app instance with the specified configuration.
* This includes the scene to run and the WebSocket endpoints to the backend. */
async runApp(inputConfig?: StringConfig | null, accessToken?: string) {
async runApp(
inputConfig: StringConfig | null,
accessToken: string | null,
loggingMetadata?: object
) {
this.stopApp()

/** FIXME: https://github.com/enso-org/enso/issues/6475
Expand Down Expand Up @@ -197,13 +201,17 @@ class Main implements AppRunner {
// remote logger at all, and it should be integrated with our logging infrastructure.
const remoteLogger = accessToken != null ? new remoteLog.RemoteLogger(accessToken) : null
newApp.remoteLog = async (message: string, metadata: unknown) => {
if (newApp.config.options.dataCollection.value && remoteLogger) {
await remoteLogger.remoteLog(message, metadata)
const metadataObject =
typeof metadata === 'object' && metadata != null ? metadata : { metadata }
const actualMetadata =
loggingMetadata == null ? metadata : { ...loggingMetadata, ...metadataObject }
if (newApp.config.options.dataCollection.value && remoteLogger != null) {
await remoteLogger.remoteLog(message, actualMetadata)
} else {
const logMessage = [
'Not sending log to remote server. Data collection is disabled.',
`Message: "${message}"`,
`Metadata: ${JSON.stringify(metadata)}`,
`Metadata: ${JSON.stringify(actualMetadata)}`,
].join(' ')

logger.log(logMessage)
Expand Down Expand Up @@ -277,7 +285,7 @@ class Main implements AppRunner {
inputConfig: inputConfig ?? null,
})
} else {
void this.runApp(inputConfig)
void this.runApp(inputConfig ?? null, null)
}
}
}
Expand All @@ -302,7 +310,7 @@ class Main implements AppRunner {
isAuthenticationDisabled: !config.shouldUseAuthentication,
shouldShowDashboard: config.shouldUseNewDashboard,
initialProjectName: config.initialProjectName,
onAuthenticated: (accessToken?: string) => {
onAuthenticated: (accessToken: string | null) => {
if (config.isInAuthenticationFlow) {
const initialUrl = localStorage.getItem(INITIAL_URL_KEY)
if (initialUrl != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* hook also provides methods for registering a user, logging in, logging out, etc. */
import * as React from 'react'
import * as router from 'react-router-dom'
import * as toastify from 'react-toastify'
import * as toast from 'react-toastify'

import * as app from '../../components/app'
import * as authServiceModule from '../service'
Expand All @@ -14,6 +14,7 @@ import * as backendProvider from '../../providers/backend'
import * as errorModule from '../../error'
import * as http from '../../http'
import * as localBackend from '../../dashboard/localBackend'
import * as localStorageProvider from '../../providers/localStorage'
import * as loggerProvider from '../../providers/logger'
import * as remoteBackend from '../../dashboard/remoteBackend'
import * as sessionProvider from './session'
Expand Down Expand Up @@ -167,7 +168,7 @@ export interface AuthProviderProps {
supportsLocalBackend: boolean
authService: authServiceModule.AuthService
/** Callback to execute once the user has authenticated successfully. */
onAuthenticated: (accessToken?: string) => void
onAuthenticated: (accessToken: string | null) => void
children: React.ReactNode
projectManagerUrl: string | null
}
Expand All @@ -182,23 +183,25 @@ export function AuthProvider(props: AuthProviderProps) {
children,
projectManagerUrl,
} = props
const logger = loggerProvider.useLogger()
const { cognito } = authService
const { session, deinitializeSession } = sessionProvider.useSession()
const { setBackendWithoutSavingType } = backendProvider.useSetBackend()
const logger = loggerProvider.useLogger()
const { localStorage } = localStorageProvider.useLocalStorage()
// This must not be `hooks.useNavigate` as `goOffline` would be inaccessible,
// and the function call would error.
// eslint-disable-next-line no-restricted-properties
const navigate = router.useNavigate()
const [forceOfflineMode, setForceOfflineMode] = React.useState(shouldStartInOfflineMode)
const [initialized, setInitialized] = React.useState(false)
const [userSession, setUserSession] = React.useState<UserSession | null>(null)
const toastId = React.useId()

const goOfflineInternal = React.useCallback(() => {
setInitialized(true)
setUserSession(OFFLINE_USER_SESSION)
if (supportsLocalBackend) {
setBackendWithoutSavingType(new localBackend.LocalBackend(projectManagerUrl))
setBackendWithoutSavingType(new localBackend.LocalBackend(projectManagerUrl, null))
} else {
// Provide dummy headers to avoid errors. This `Backend` will never be called as
// the entire UI will be disabled.
Expand All @@ -215,7 +218,7 @@ export function AuthProvider(props: AuthProviderProps) {
const goOffline = React.useCallback(
(shouldShowToast = true) => {
if (shouldShowToast) {
toastify.toast.error('You are offline, switching to offline mode.')
toast.toast.error('You are offline, switching to offline mode.')
}
goOfflineInternal()
navigate(app.DASHBOARD_PATH)
Expand Down Expand Up @@ -321,7 +324,7 @@ export function AuthProvider(props: AuthProviderProps) {

fetchSession().catch(error => {
if (isUserFacingError(error)) {
toastify.toast.error(error.message)
toast.toast.error(error.message)
logger.error(error.message)
} else {
logger.error(error)
Expand All @@ -341,28 +344,46 @@ export function AuthProvider(props: AuthProviderProps) {
/* should never change */ setBackendWithoutSavingType,
])

/** Wrap a function returning a {@link Promise} to displays a loading toast notification
/** Wrap a function returning a {@link Promise} to display a loading toast notification
* until the returned {@link Promise} finishes loading. */
const withLoadingToast =
<T extends unknown[], R>(action: (...args: T) => Promise<R>) =>
async (...args: T) => {
const loadingToast = toastify.toast.loading(MESSAGES.pleaseWait)
let result
try {
result = await action(...args)
} finally {
toastify.toast.dismiss(loadingToast)
}
return result
toast.toast.loading(MESSAGES.pleaseWait, { toastId })
return await action(...args)
}

const toastSuccess = (message: string) => {
toast.toast.update(toastId, {
isLoading: null,
autoClose: null,
closeOnClick: null,
closeButton: null,
draggable: null,
type: toast.toast.TYPE.SUCCESS,
render: message,
})
}

const toastError = (message: string) => {
toast.toast.update(toastId, {
isLoading: null,
autoClose: null,
closeOnClick: null,
closeButton: null,
draggable: null,
type: toast.toast.TYPE.ERROR,
render: message,
})
}

const signUp = async (username: string, password: string, organizationId: string | null) => {
const result = await cognito.signUp(username, password, organizationId)
if (result.ok) {
toastify.toast.success(MESSAGES.signUpSuccess)
toastSuccess(MESSAGES.signUpSuccess)
navigate(app.LOGIN_PATH)
} else {
toastify.toast.error(result.val.message)
toastError(result.val.message)
}
return result.ok
}
Expand All @@ -377,36 +398,34 @@ export function AuthProvider(props: AuthProviderProps) {
throw new errorModule.UnreachableCaseError(result.val.kind)
}
}

toastify.toast.success(MESSAGES.confirmSignUpSuccess)
toastSuccess(MESSAGES.confirmSignUpSuccess)
navigate(app.LOGIN_PATH)
return result.ok
}

const signInWithPassword = async (email: string, password: string) => {
const result = await cognito.signInWithPassword(email, password)
if (result.ok) {
toastify.toast.success(MESSAGES.signInWithPasswordSuccess)
toastSuccess(MESSAGES.signInWithPasswordSuccess)
} else {
if (result.val.kind === 'UserNotFound') {
navigate(app.REGISTRATION_PATH)
}

toastify.toast.error(result.val.message)
toastError(result.val.message)
}
return result.ok
}

const setUsername = async (backend: backendModule.Backend, username: string, email: string) => {
if (backend.type === backendModule.BackendType.local) {
toastify.toast.error('You cannot set your username on the local backend.')
toastError('You cannot set your username on the local backend.')
return false
} else {
try {
const organizationId = await authService.cognito.organizationId()
// This should not omit success and error toasts as it is not possible
// to render this optimistically.
await toastify.toast.promise(
await toast.toast.promise(
backend.createUser({
userName: username,
userEmail: backendModule.EmailAddress(email),
Expand All @@ -423,7 +442,7 @@ export function AuthProvider(props: AuthProviderProps) {
)
navigate(app.DASHBOARD_PATH)
return true
} catch (e) {
} catch {
return false
}
}
Expand All @@ -432,31 +451,31 @@ export function AuthProvider(props: AuthProviderProps) {
const forgotPassword = async (email: string) => {
const result = await cognito.forgotPassword(email)
if (result.ok) {
toastify.toast.success(MESSAGES.forgotPasswordSuccess)
toastSuccess(MESSAGES.forgotPasswordSuccess)
navigate(app.RESET_PASSWORD_PATH)
} else {
toastify.toast.error(result.val.message)
toastError(result.val.message)
}
return result.ok
}

const resetPassword = async (email: string, code: string, password: string) => {
const result = await cognito.forgotPasswordSubmit(email, code, password)
if (result.ok) {
toastify.toast.success(MESSAGES.resetPasswordSuccess)
toastSuccess(MESSAGES.resetPasswordSuccess)
navigate(app.LOGIN_PATH)
} else {
toastify.toast.error(result.val.message)
toastError(result.val.message)
}
return result.ok
}

const changePassword = async (oldPassword: string, newPassword: string) => {
const result = await cognito.changePassword(oldPassword, newPassword)
if (result.ok) {
toastify.toast.success(MESSAGES.changePasswordSuccess)
toastSuccess(MESSAGES.changePasswordSuccess)
} else {
toastify.toast.error(result.val.message)
toastError(result.val.message)
}
return result.ok
}
Expand All @@ -465,9 +484,10 @@ export function AuthProvider(props: AuthProviderProps) {
deinitializeSession()
setInitialized(false)
setUserSession(null)
localStorage.clear()
// This should not omit success and error toasts as it is not possible
// to render this optimistically.
await toastify.toast.promise(cognito.signOut(), {
await toast.toast.promise(cognito.signOut(), {
success: MESSAGES.signOutSuccess,
error: MESSAGES.signOutError,
pending: MESSAGES.signOutLoading,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import * as shortcutsModule from '../dashboard/shortcuts'

import * as authProvider from '../authentication/providers/auth'
import * as backendProvider from '../providers/backend'
import * as localStorageProvider from '../providers/localStorage'
import * as loggerProvider from '../providers/logger'
import * as modalProvider from '../providers/modal'
import * as sessionProvider from '../authentication/providers/session'
Expand Down Expand Up @@ -117,7 +118,7 @@ export interface AppProps {
shouldShowDashboard: boolean
/** The name of the project to open on startup, if any. */
initialProjectName: string | null
onAuthenticated: () => void
onAuthenticated: (accessToken: string | null) => void
projectManagerUrl: string | null
appRunner: AppRunner
}
Expand Down Expand Up @@ -193,7 +194,7 @@ function AppRouter(props: AppProps) {
const userSession = authService.cognito.userSession.bind(authService.cognito)
const registerAuthEventListener = authService.registerAuthEventListener
const initialBackend: backend.Backend = isAuthenticationDisabled
? new localBackend.LocalBackend(projectManagerUrl)
? new localBackend.LocalBackend(projectManagerUrl, null)
: // This is safe, because the backend is always set by the authentication flow.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
null!
Expand Down Expand Up @@ -224,28 +225,32 @@ function AppRouter(props: AppProps) {
</React.Fragment>
</router.Routes>
)
/** {@link backendProvider.BackendProvider} depends on
* {@link localStorageProvider.LocalStorageProvider}. */
return (
<loggerProvider.LoggerProvider logger={logger}>
<sessionProvider.SessionProvider
mainPageUrl={mainPageUrl}
userSession={userSession}
registerAuthEventListener={registerAuthEventListener}
>
<backendProvider.BackendProvider initialBackend={initialBackend}>
<authProvider.AuthProvider
shouldStartInOfflineMode={isAuthenticationDisabled}
supportsLocalBackend={supportsLocalBackend}
authService={authService}
onAuthenticated={onAuthenticated}
projectManagerUrl={projectManagerUrl}
>
<modalProvider.ModalProvider>
<shortcutsProvider.ShortcutsProvider shortcuts={shortcuts}>
{routes}
</shortcutsProvider.ShortcutsProvider>
</modalProvider.ModalProvider>
</authProvider.AuthProvider>
</backendProvider.BackendProvider>
<localStorageProvider.LocalStorageProvider>
<backendProvider.BackendProvider initialBackend={initialBackend}>
<authProvider.AuthProvider
shouldStartInOfflineMode={isAuthenticationDisabled}
supportsLocalBackend={supportsLocalBackend}
authService={authService}
onAuthenticated={onAuthenticated}
projectManagerUrl={projectManagerUrl}
>
<modalProvider.ModalProvider>
<shortcutsProvider.ShortcutsProvider shortcuts={shortcuts}>
{routes}
</shortcutsProvider.ShortcutsProvider>
</modalProvider.ModalProvider>
</authProvider.AuthProvider>
</backendProvider.BackendProvider>
</localStorageProvider.LocalStorageProvider>
</sessionProvider.SessionProvider>
</loggerProvider.LoggerProvider>
)
Expand Down
Loading

0 comments on commit 9509c7e

Please sign in to comment.