mirror of
https://github.com/enso-org/enso.git
synced 2024-08-17 00:40:34 +03:00
Fix dashboard issues (#8347)
- Fixes https://github.com/enso-org/cloud-v2/issues/770 - Fixes https://github.com/enso-org/cloud-v2/issues/772 - Fixes https://github.com/enso-org/cloud-v2/issues/775 - Fixes #8335 # Important Notes The fix for "Reopening cloud projects" has not been tested, as opening projects on the cloud are currently broken - *however*, the logic change is very small - the only thing it does is make the reopening conditional. This means that, at the very least, it should not be a regression.
This commit is contained in:
parent
feb59be0a1
commit
d136c8e40c
@ -19,25 +19,24 @@
|
||||
"dependencies": {
|
||||
"@types/mime-types": "^2.1.1",
|
||||
"@types/opener": "^1.4.0",
|
||||
"@types/tar": "^6.1.4",
|
||||
"@types/yargs": "^17.0.30",
|
||||
"chalk": "^5.2.0",
|
||||
"create-servers": "3.2.0",
|
||||
"electron-is-dev": "^2.0.0",
|
||||
"mime-types": "^2.1.35",
|
||||
"opener": "^1.5.2",
|
||||
"string-length": "^5.0.1",
|
||||
"@types/tar": "^6.1.4",
|
||||
"tar": "^6.1.13",
|
||||
"@types/yargs": "^17.0.30",
|
||||
"yargs": "17.6.2"
|
||||
},
|
||||
"comments": {
|
||||
"electron-builder": "Cannot be updated to a newer version because of a NSIS installer issue: https://github.com/enso-org/enso/issues/5169"
|
||||
},
|
||||
"devDependencies": {
|
||||
"crypto-js": "4.1.1",
|
||||
"@electron/notarize": "2.1.0",
|
||||
"electron": "25.7.0",
|
||||
"electron-builder": "^22.14.13",
|
||||
"@electron/notarize": "2.1.0",
|
||||
"enso-common": "^1.0.0",
|
||||
"esbuild": "^0.19.3",
|
||||
"fast-glob": "^3.2.12",
|
||||
@ -45,10 +44,10 @@
|
||||
"tsx": "^3.12.6"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"dmg-license": "^1.0.11",
|
||||
"@esbuild/darwin-x64": "^0.17.15",
|
||||
"@esbuild/linux-x64": "^0.17.15",
|
||||
"@esbuild/windows-x64": "^0.17.15"
|
||||
"@esbuild/windows-x64": "^0.17.15",
|
||||
"dmg-license": "^1.0.11"
|
||||
},
|
||||
"scripts": {
|
||||
"typecheck": "npm run --workspace=enso-gui2 compile-server && tsc --noEmit",
|
||||
|
@ -114,8 +114,7 @@ const ALL_BUNDLES_READY = new Promise<Watches>((resolve, reject) => {
|
||||
path.resolve(THIS_PATH, '..', '..', 'debugGlobals.ts')
|
||||
)
|
||||
contentOpts.outdir = path.resolve(IDE_DIR_PATH, 'assets')
|
||||
contentOpts.define['process.env.REDIRECT_OVERRIDE'] =
|
||||
JSON.stringify('http://localhost:8080')
|
||||
contentOpts.define.REDIRECT_OVERRIDE = JSON.stringify('http://localhost:8080')
|
||||
const contentBuilder = await esbuild.context(contentOpts)
|
||||
const content = await contentBuilder.rebuild()
|
||||
console.log('Result of content bundling: ', content)
|
||||
|
@ -40,7 +40,7 @@ async function watch() {
|
||||
)
|
||||
opts.pure.splice(opts.pure.indexOf('assert'), 1)
|
||||
;(opts.inject = opts.inject ?? []).push(path.resolve(THIS_PATH, '..', '..', 'debugGlobals.ts'))
|
||||
opts.define['process.env.REDIRECT_OVERRIDE'] = JSON.stringify('http://localhost:8080')
|
||||
opts.define.REDIRECT_OVERRIDE = JSON.stringify('http://localhost:8080')
|
||||
// This is safe as this entry point is statically known.
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const serviceWorkerEntryPoint = opts.entryPoints.find(
|
||||
|
@ -5,12 +5,12 @@ import * as router from 'react-router-dom'
|
||||
import * as toastify from 'react-toastify'
|
||||
|
||||
import ArrowRightIcon from 'enso-assets/arrow_right.svg'
|
||||
import AtIcon from 'enso-assets/at.svg'
|
||||
import GoBackIcon from 'enso-assets/go_back.svg'
|
||||
import LockIcon from 'enso-assets/lock.svg'
|
||||
|
||||
import * as app from '../../components/app'
|
||||
import * as auth from '../providers/auth'
|
||||
import * as hooks from '../../hooks'
|
||||
import * as string from '../../string'
|
||||
import * as validation from '../../dashboard/validation'
|
||||
|
||||
@ -35,20 +35,30 @@ const RESET_PASSWORD_QUERY_PARAMS = {
|
||||
export default function ResetPassword() {
|
||||
const { resetPassword } = auth.useAuth()
|
||||
const { search } = router.useLocation()
|
||||
const navigate = hooks.useNavigate()
|
||||
|
||||
const { verificationCode: initialCode, email: initialEmail } = parseUrlSearchParams(search)
|
||||
const { verificationCode, email } = parseUrlSearchParams(search)
|
||||
|
||||
const [email, setEmail] = React.useState(initialEmail ?? '')
|
||||
const [code, setCode] = React.useState(initialCode ?? '')
|
||||
const [newPassword, setNewPassword] = React.useState('')
|
||||
const [newPasswordConfirm, setNewPasswordConfirm] = React.useState('')
|
||||
|
||||
React.useEffect(() => {
|
||||
if (email == null) {
|
||||
toastify.toast.error('Could not reset password: missing email address')
|
||||
navigate(app.LOGIN_PATH)
|
||||
} else if (verificationCode == null) {
|
||||
toastify.toast.error('Could not reset password: missing verification code')
|
||||
navigate(app.LOGIN_PATH)
|
||||
}
|
||||
}, [email, navigate, verificationCode])
|
||||
|
||||
const onSubmit = () => {
|
||||
if (newPassword !== newPasswordConfirm) {
|
||||
toastify.toast.error('Passwords do not match')
|
||||
return Promise.resolve()
|
||||
} else {
|
||||
return resetPassword(email, code, newPassword)
|
||||
// These should never be nullish, as the effect should immediately navigate away.
|
||||
return resetPassword(email ?? '', verificationCode ?? '', newPassword)
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,25 +72,23 @@ export default function ResetPassword() {
|
||||
}}
|
||||
>
|
||||
<div className="font-medium self-center text-xl">Reset your password</div>
|
||||
<Input
|
||||
<input
|
||||
required
|
||||
readOnly
|
||||
hidden
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
label="Email"
|
||||
icon={AtIcon}
|
||||
placeholder="Enter your email"
|
||||
value={email}
|
||||
setValue={setEmail}
|
||||
value={email ?? ''}
|
||||
/>
|
||||
<Input
|
||||
<input
|
||||
required
|
||||
readOnly
|
||||
hidden
|
||||
type="text"
|
||||
autoComplete="one-time-code"
|
||||
label="Confirmation code"
|
||||
icon={LockIcon}
|
||||
placeholder="Enter the confirmation code"
|
||||
value={code}
|
||||
setValue={setCode}
|
||||
value={verificationCode ?? ''}
|
||||
/>
|
||||
<Input
|
||||
required
|
||||
|
@ -494,7 +494,7 @@ export function AuthProvider(props: AuthProviderProps) {
|
||||
const result = await cognito.forgotPassword(email)
|
||||
if (result.ok) {
|
||||
toastSuccess(MESSAGES.forgotPasswordSuccess)
|
||||
navigate(app.RESET_PASSWORD_PATH)
|
||||
navigate(app.LOGIN_PATH)
|
||||
} else {
|
||||
toastError(result.val.message)
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ function setDeepLinkHandler(logger: loggerProvider.Logger, navigate: (url: strin
|
||||
* the password reset page, with the verification code and email passed in the URL s-o they can
|
||||
* be filled in automatically. */
|
||||
case app.RESET_PASSWORD_PATH: {
|
||||
const resetPasswordRedirectUrl = `${app.RESET_PASSWORD_PATH}${parsedUrl.search}`
|
||||
const resetPasswordRedirectUrl = app.RESET_PASSWORD_PATH + parsedUrl.search
|
||||
navigate(resetPasswordRedirectUrl)
|
||||
break
|
||||
}
|
||||
|
@ -93,11 +93,9 @@ export default function Dashboard(props: DashboardProps) {
|
||||
|
||||
React.useEffect(() => {
|
||||
unsetModal()
|
||||
if (page === pageSwitcher.Page.editor) {
|
||||
document.body.style.cursor = 'none'
|
||||
} else {
|
||||
document.body.style.cursor = 'auto'
|
||||
}
|
||||
// FIXME [sb]: https://github.com/enso-org/cloud-v2/issues/777
|
||||
// Workarounds for GUI1 should be removed when they are no longer necessary.
|
||||
document.body.style.cursor = page === pageSwitcher.Page.editor ? 'none' : 'auto'
|
||||
}, [page, /* should never change */ unsetModal])
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -153,19 +151,29 @@ export default function Dashboard(props: DashboardProps) {
|
||||
void (async () => {
|
||||
const abortController = new AbortController()
|
||||
setOpenProjectAbortController(abortController)
|
||||
await remoteBackendModule.waitUntilProjectIsReady(
|
||||
remoteBackend,
|
||||
savedProjectStartupInfo.projectAsset,
|
||||
abortController
|
||||
const oldProject = await backend.getProjectDetails(
|
||||
savedProjectStartupInfo.projectAsset.id,
|
||||
savedProjectStartupInfo.projectAsset.title
|
||||
)
|
||||
if (!abortController.signal.aborted) {
|
||||
const project = await remoteBackend.getProjectDetails(
|
||||
savedProjectStartupInfo.projectAsset.id,
|
||||
savedProjectStartupInfo.projectAsset.title
|
||||
if (
|
||||
backendModule.DOES_PROJECT_STATE_INDICATE_VM_EXISTS[
|
||||
oldProject.state.type
|
||||
]
|
||||
) {
|
||||
await remoteBackendModule.waitUntilProjectIsReady(
|
||||
remoteBackend,
|
||||
savedProjectStartupInfo.projectAsset,
|
||||
abortController
|
||||
)
|
||||
setProjectStartupInfo({ ...savedProjectStartupInfo, project })
|
||||
if (page === pageSwitcher.Page.editor) {
|
||||
setPage(page)
|
||||
if (!abortController.signal.aborted) {
|
||||
const project = await remoteBackend.getProjectDetails(
|
||||
savedProjectStartupInfo.projectAsset.id,
|
||||
savedProjectStartupInfo.projectAsset.title
|
||||
)
|
||||
setProjectStartupInfo({ ...savedProjectStartupInfo, project })
|
||||
if (page === pageSwitcher.Page.editor) {
|
||||
setPage(page)
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
@ -136,7 +136,9 @@ export default function ProjectIcon(props: ProjectIconProps) {
|
||||
switch (backend.type) {
|
||||
case backendModule.BackendType.remote: {
|
||||
if (state !== backendModule.ProjectState.opened) {
|
||||
setToastId(toast.toast.loading(LOADING_MESSAGE))
|
||||
if (!shouldRunInBackground) {
|
||||
setToastId(toast.toast.loading(LOADING_MESSAGE))
|
||||
}
|
||||
await backend.openProject(
|
||||
item.id,
|
||||
{
|
||||
|
@ -98,7 +98,7 @@ function ProjectsEntry(props: InternalProjectsEntryProps) {
|
||||
return (
|
||||
<div className="flex flex-col gap-1.5 h-51">
|
||||
<button
|
||||
className="relative grow cursor-pointer before:absolute before:bg-frame before:rounded-2xl before:w-full before:h-full before:opacity-60"
|
||||
className="relative grow cursor-pointer before:absolute before:inset-0 before:bg-frame before:rounded-2xl before:w-full before:h-full before:opacity-60"
|
||||
onClick={() => {
|
||||
setSpinnerState(spinner.SpinnerState.initial)
|
||||
onTemplateClick(null, newSpinnerState => {
|
||||
|
@ -16,7 +16,7 @@ export default function WhatsNew() {
|
||||
<h2 className="text-xl leading-144.5 py-0.5">Discover what’s new</h2>
|
||||
<div className="grid gap-3 grid-cols-fill-75">
|
||||
<a
|
||||
className="relative whatsnew-span-2 col-span-2 bg-v3 text-tag-text rounded-2xl h-45"
|
||||
className="relative whatsnew-span-2 col-span-1 sm:col-span-2 bg-v3 text-tag-text rounded-2xl h-45"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
href="https://enso.org/"
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -153,7 +153,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/notarize": "2.1.0",
|
||||
"crypto-js": "4.1.1",
|
||||
"electron": "25.7.0",
|
||||
"electron-builder": "^22.14.13",
|
||||
"enso-common": "^1.0.0",
|
||||
@ -6554,11 +6553,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/crypto-random-string": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
|
Loading…
Reference in New Issue
Block a user