Skip to content

Commit 03865fc

Browse files
authored
feat(import): allow continuing the import after an error (#6614)
This PR adds the ability to control the import process after an error: 1. Import a different project 2. Decide to continue anyway (for example to correct it using our editor). This PR distinguishes between an `Error` (that can be continued) and a `Critical Error` (for example a non-existent repo) - that we cannot recover from. **PR details:** 1. In [editor/src/core/shared/github/operations/load-branch.ts](https://github.com/concrete-utopia/utopia/pull/6614/files#diff-3c1474cac72b0e757d951539630bd72175135c05eddbff91d9f10639d2796440) this PR adds the ability to stop before dependencies fetching and resume afterwards 2. In [editor/src/components/editor/import-wizard/import-wizard.tsx](https://github.com/concrete-utopia/utopia/pull/6614/files#diff-a1ec93eec4b0720f01ff6ec77bb4efb6cc3ac0ba4297d3fe7bb77049c601ca94) this PR adds the UI for displaying the correct status/buttons according to the current import state. 3. The rest of the changes are mostly actions/state changes. For example this flow: 1. Importing a non-existing repo (critical error) 2. Then importing a project with errors (TS/server packages, etc), choosing to continue importing 3. Deciding to import a different project - which is a success <video src="https://github.com/user-attachments/assets/39eaeedd-14fd-4819-b590-39a92629ad8e"></video> Current design: <img width="693" alt="image" src="https://github.com/user-attachments/assets/a609068f-dece-4448-a31d-c266969a6341"> **Manual Tests:** I hereby swear that: - [x] I opened a hydrogen project and it loaded - [x] I could navigate to various routes in Play mode
1 parent d5006bf commit 03865fc

16 files changed

+333
-101
lines changed

editor/src/components/editor/action-types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ import { assertNever } from '../../core/shared/utils'
9090
import type {
9191
ImportOperation,
9292
ImportOperationAction,
93+
ImportStatus,
9394
} from '../../core/shared/import/import-operation-types'
9495
import type { ProjectRequirements } from '../../core/shared/import/project-health-check/utopia-requirements-types'
9596
export { isLoggedIn, loggedInUser, notLoggedIn } from '../../common/user'
@@ -1008,6 +1009,11 @@ export interface UpdateImportOperations {
10081009
type: ImportOperationAction
10091010
}
10101011

1012+
export interface UpdateImportStatus {
1013+
action: 'UPDATE_IMPORT_STATUS'
1014+
importStatus: ImportStatus
1015+
}
1016+
10111017
export interface UpdateProjectRequirements {
10121018
action: 'UPDATE_PROJECT_REQUIREMENTS'
10131019
requirements: Partial<ProjectRequirements>
@@ -1376,6 +1382,7 @@ export type EditorAction =
13761382
| SetImageDragSessionState
13771383
| UpdateGithubOperations
13781384
| UpdateImportOperations
1385+
| UpdateImportStatus
13791386
| UpdateProjectRequirements
13801387
| SetImportWizardOpen
13811388
| UpdateBranchContents

editor/src/components/editor/actions/action-creators.ts

+9
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ import type {
240240
SetImportWizardOpen,
241241
UpdateImportOperations,
242242
UpdateProjectRequirements,
243+
UpdateImportStatus,
243244
} from '../action-types'
244245
import type { InsertionSubjectWrapper, Mode } from '../editor-modes'
245246
import { EditorModes, insertionSubject } from '../editor-modes'
@@ -274,6 +275,7 @@ import type { ElementPathTrees } from '../../../core/shared/element-path-tree'
274275
import type {
275276
ImportOperation,
276277
ImportOperationAction,
278+
ImportStatus,
277279
} from '../../../core/shared/import/import-operation-types'
278280
import type { ProjectRequirements } from '../../../core/shared/import/project-health-check/utopia-requirements-types'
279281

@@ -1610,6 +1612,13 @@ export function updateImportOperations(
16101612
}
16111613
}
16121614

1615+
export function updateImportStatus(importStatus: ImportStatus): UpdateImportStatus {
1616+
return {
1617+
action: 'UPDATE_IMPORT_STATUS',
1618+
importStatus: importStatus,
1619+
}
1620+
}
1621+
16131622
export function updateProjectRequirements(
16141623
requirements: Partial<ProjectRequirements>,
16151624
): UpdateProjectRequirements {

editor/src/components/editor/actions/action-utils.ts

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ export function isTransientAction(action: EditorAction): boolean {
141141
case 'SET_ERROR_BOUNDARY_HANDLING':
142142
case 'SET_IMPORT_WIZARD_OPEN':
143143
case 'UPDATE_IMPORT_OPERATIONS':
144+
case 'UPDATE_IMPORT_STATUS':
144145
case 'UPDATE_PROJECT_REQUIREMENTS':
145146
return true
146147

editor/src/components/editor/actions/actions.tsx

+13-3
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ import type {
355355
SetImportWizardOpen,
356356
UpdateImportOperations,
357357
UpdateProjectRequirements,
358+
UpdateImportStatus,
358359
} from '../action-types'
359360
import { isAlignment, isLoggedIn } from '../action-types'
360361
import type { Mode } from '../editor-modes'
@@ -1034,7 +1035,7 @@ export function restoreEditorState(
10341035
githubSettings: currentEditor.githubSettings,
10351036
imageDragSessionState: currentEditor.imageDragSessionState,
10361037
githubOperations: currentEditor.githubOperations,
1037-
importOperations: currentEditor.importOperations,
1038+
importState: currentEditor.importState,
10381039
projectRequirements: currentEditor.projectRequirements,
10391040
importWizardOpen: currentEditor.importWizardOpen,
10401041
branchOriginContents: currentEditor.branchOriginContents,
@@ -2178,13 +2179,22 @@ export const UPDATE_FNS = {
21782179
},
21792180
UPDATE_IMPORT_OPERATIONS: (action: UpdateImportOperations, editor: EditorModel): EditorModel => {
21802181
const resultImportOperations = getUpdateOperationResult(
2181-
editor.importOperations,
2182+
editor.importState.importOperations,
21822183
action.operations,
21832184
action.type,
21842185
)
21852186
return {
21862187
...editor,
2187-
importOperations: resultImportOperations,
2188+
importState: { ...editor.importState, importOperations: resultImportOperations },
2189+
}
2190+
},
2191+
UPDATE_IMPORT_STATUS: (action: UpdateImportStatus, editor: EditorModel): EditorModel => {
2192+
return {
2193+
...editor,
2194+
importState: {
2195+
...editor.importState,
2196+
importStatus: action.importStatus,
2197+
},
21882198
}
21892199
},
21902200
UPDATE_PROJECT_REQUIREMENTS: (

editor/src/components/editor/import-wizard/components.tsx

+25-14
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@ import { RequirementResolutionResult } from '../../../core/shared/import/project
1515

1616
export function OperationLine({ operation }: { operation: ImportOperation }) {
1717
const operationRunningStatus = React.useMemo(() => {
18-
return operation.timeStarted == null
19-
? 'waiting'
20-
: operation.timeDone == null
21-
? 'running'
22-
: 'done'
18+
if (operation.timeDone != null) {
19+
return 'done'
20+
}
21+
return operation.timeStarted == null ? 'waiting' : 'running'
2322
}, [operation.timeStarted, operation.timeDone])
2423
const colorTheme = useColorTheme()
2524
const textColor = operationRunningStatus === 'waiting' ? 'gray' : colorTheme.fg0.value
@@ -29,7 +28,7 @@ export function OperationLine({ operation }: { operation: ImportOperation }) {
2928
() =>
3029
childrenShown ||
3130
operation.timeDone == null ||
32-
operation.result == ImportOperationResult.Error,
31+
operation.result != ImportOperationResult.Success,
3332
[childrenShown, operation.timeDone, operation.result],
3433
)
3534
const hasChildren = React.useMemo(
@@ -253,14 +252,26 @@ function getImportOperationText(operation: ImportOperation): React.ReactNode {
253252
}
254253
switch (operation.type) {
255254
case 'loadBranch':
256-
return (
257-
<span>
258-
Loading branch{' '}
259-
<strong>
260-
{operation.githubRepo?.owner}/{operation.githubRepo?.repository}@{operation.branchName}
261-
</strong>
262-
</span>
263-
)
255+
if (operation.branchName != null) {
256+
return (
257+
<span>
258+
Loading branch{' '}
259+
<strong>
260+
{operation.githubRepo?.owner}/{operation.githubRepo?.repository}@
261+
{operation.branchName}
262+
</strong>
263+
</span>
264+
)
265+
} else {
266+
return (
267+
<span>
268+
Loading repository{' '}
269+
<strong>
270+
{operation.githubRepo?.owner}/{operation.githubRepo?.repository}
271+
</strong>
272+
</span>
273+
)
274+
}
264275
case 'fetchDependency':
265276
return `Fetching ${operation.dependencyName}@${operation.dependencyVersion}`
266277
case 'parseFiles':

0 commit comments

Comments
 (0)