From 2abbc1ca07440e4c8e4511510e16686202bcee64 Mon Sep 17 00:00:00 2001 From: Presley Pizzo Date: Fri, 9 Sep 2022 00:33:39 +0000 Subject: [PATCH 1/2] Turn predictable action arguments on --- site/src/xServices/audit/auditXService.ts | 3 +- site/src/xServices/auth/authXService.ts | 19 +- .../xServices/buildInfo/buildInfoXService.ts | 3 +- .../createWorkspaceXService.ts | 5 +- .../entitlements/entitlementsXService.ts | 5 +- site/src/xServices/roles/siteRolesXService.ts | 5 +- site/src/xServices/setup/setupXService.ts | 3 +- .../xServices/template/templateXService.ts | 3 +- .../templateSettingsXService.ts | 7 +- .../xServices/templates/templatesXService.ts | 171 +-- .../xServices/terminal/terminalXService.ts | 3 +- site/src/xServices/users/usersXService.ts | 3 +- .../xServices/workspace/workspaceXService.ts | 1014 +++++++++-------- .../workspaceBuild/workspaceBuildXService.ts | 3 +- .../workspaceScheduleBannerXService.ts | 3 +- .../workspaceScheduleXService.ts | 3 +- .../workspaces/workspacesXService.ts | 4 +- 17 files changed, 683 insertions(+), 574 deletions(-) diff --git a/site/src/xServices/audit/auditXService.ts b/site/src/xServices/audit/auditXService.ts index b26fcb1313583..2ab414900d79b 100644 --- a/site/src/xServices/audit/auditXService.ts +++ b/site/src/xServices/audit/auditXService.ts @@ -7,6 +7,8 @@ import { assign, createMachine } from "xstate" export const auditMachine = createMachine( { id: "auditMachine", + predictableActionArguments: true, + tsTypes: {} as import("./auditXService.typegen").Typegen0, schema: { context: {} as { auditLogs?: AuditLog[]; count?: number; page: number; limit: number }, services: {} as { @@ -29,7 +31,6 @@ export const auditMachine = createMachine( page: number }, }, - tsTypes: {} as import("./auditXService.typegen").Typegen0, initial: "loading", states: { loading: { diff --git a/site/src/xServices/auth/authXService.ts b/site/src/xServices/auth/authXService.ts index d3c0a27ab2bd2..b90d0d7321b97 100644 --- a/site/src/xServices/auth/authXService.ts +++ b/site/src/xServices/auth/authXService.ts @@ -91,14 +91,8 @@ export const authMachine = /** @xstate-layout N4IgpgJg5mDOIC5QEMCuAXAFgZXc9YAdLAJZQB2kA8hgMTYCSA4gHID6DLioADgPal0JPuW4gAHogBsATimEAzDIAcAFgUB2VTJ26ANCACeiAIwaADKsLKFtu-dsBfRwbRZc+IqQolyUBuS0ECJEvgBufADWXmTkAWL8gsKiSBKICubKhKpSyhoArAbGCGaqGoRSlVXVlfnOrhg4eATEsb7+gWAATl18XYQ8ADb4AGZ9ALatFPGpiSRCImKSCLLySmqa2ro6RaYFAEzWDscK9SBuTZ6EMOhCfgCqsN1BIYThUUQ3ALJgCQLzySW6Uy2VyBV2JXyUhMFRqcLqLnOjQ8LRudygj2e3V6-SGowm1zA6B+fySi1Sy32MnyhHyyksYK2ug0EJM1IURxO9jOFxRnyJ6IACt1xiRYKQRLAXpQ3uQItFCABjTBgRWRYVdUXi5LwWb-BYpUDLZRScygvKFIyIGQaQ4FHnI5r827tDVaiXkKXYvoDYboMaapUqtVusUe3W8fWAimIE1mnIW1l0rImOE1BENdxOwkuvw-LB8CBS4Iy94K75EzCFiMgOYGoEIZRUwgyVT5BQmfaW4omGxZGxcuwOrNXNHtfNVou0b24v0ByYVgtF0kA8lG2PN1vtzvd0zszmD06I3nZ7yUCABAa9EYkQahCB32j3QUAEQAggAVACibEFACUqAAMQYAAZL8V3rGMSjbGQKihLsISkOlaWHS4WjPSBLx4a9byIVAeAgfBXRwx8S1COUPkIE8rgwi9yCvPgbzvQh8MIoUSLABB3kVIiRAAbXMABdCDo3XaD8lgpCpAQq0EA0eTUL5KZzywjiWIIoi-EFDjpx6H08X9AlqPQ2JMPo7DGNw9S2OIyy7y4iieINAThL1MlDTScTJPg3dGxkfZFNPUy6OIWBMDeB8wFoJgvw-NhsGwAAJNgAGkvwATREtdPM7VQrE0XyTF7coB0PQKaOCy9xXCsc-ASxKUrAQxpXI+UiGMmIKDM0KaoFdp6sawwHIiJzkhcrKPOWIqkOscFZNTfYOXtY9HQqrqQuqnN0QGprdJxX18UDDrlO6zbaqgHahu43jyHGtzV0m0x9jyxQ5p7ExzBhUrB3Kkz1qqsLCEGPhkAgSAIsfP8vxilgvz-T8f3q1KMomht9g+8ocnMGQCtZDRZAPLkMyREc-pU+jNuB0HwcVEQb01S6-zAGBKC6TxaAAYTfFgOa-EC2ChmG4YR+KkuRzL7sgsT0bMQhzCUcxpMK20vsPBRieO2iAfCqmwYgJU6ZIBmksGpmWe6dmOaoFhgL-L4Behr9Yfh79ReStKJcjdy0Yx0Fsdx+b23MX7OvJnqgZBvXCC6ZmwFZzSLpN3ayNlNqqNWsnTsB3XwZj822e2pOrscm67q9h6GzMBQrDy7cZJ7DR1ZQlbSdDrOdcj3PY-jwuGt2mcDsMo6M7bjbs87-W87ji3e8G4a+FG-ihNRqCq5rtsO3r0wpG0ZvMzQ0eqtVVAunmQwIai5931d7Avw5+4-wYD9PdrKNsqmsoOQyBM3sQZ6pBDidDax9T7oHPqxBO2AQFnxaqnSimtKoU2gWA6ykDkHFxGqXZektRI5U-ooBkiZZIKFyHvEmB8gFH0VCfM+qDtroL2vpOcRkR6UKQdQ0B4CNL0I4Wfeei9brYPLlLPBjcCE-18m2KwGtWFa0CIwVgbAqD3A-CvaWWgYSEN-iUDIZpUxpiqBoQBZ52g0HQLAssoczFqM8k2WCW5N6+X2OYeShMTgyNbspUxdAB4GXnMpaxOD35-w0XLCRrJ0ZWH0QYqQRiW4UOVKqSI7RAJG1gOgTEXQLEUQVMdRJaoUlpIyU8Lo-CsGuWEbg5YmhCD7B3nU-YA5lA6HVhCZxYjoRshyDvJQ+NVCAIAO7IABH4QCfQPwqlSV0dJmT6DMHYJwGx1Sm7Yx0I3SwziTBOLqWaLQdIpC2HyKoLZ5gESInIIWOAYgEHrUCZU4JJRsY0iIT2akZoPEUJMX4GY9zHoIDbIcdGLzt4qFhDEpCgDzqZKWYgVQ+xWSyCyOC2okK+paRFGGHUML-mmnNNorZbIwUxI+Upc6E5qzYq2LUuQwKSitnymrI8+8lJyIYkxe8zELlfj0l0bFVcaRlCklvRspzjGILZVZEgkVCAzj5Y3AV+MfIQjyEy8hLLxUWXZRfOVRVsiKqVhCRuhxtgaBVY3A5MgxX-XMmpCB7E7K-CCX8oq+RnnaIKJa+J6rrUSrvHykwHZZq+X2bScwYbzUSTUBCr1QUfWbSlX6p1lctlusKp2Q4JLY1hzOmixOfdii-MrlIiotKPpyCtdm8e1N9YJsdYWqCmyshyH9vigoVhkWxIre3CO1aDbkHpuMRm3cZ51tft7BtqhzAZoVga+aGhexuOOJmtalaO69qnj3fqRc+UKHpIQIq87S25GXZnMea69Y7qhPuswxVCptnKNsOQ7Z2xUhPYfCmYV-WBtLVOjkJqzUkP6TGldp10EX0IFynlcroRywsI4iEu6ArAdPVQmhKDa0yqg0m1e+NNFwZ3BCNswdkPvuIGB2tcqakuPlgR4h2MWzMgAxartwDeEoLtf1dB-rXVBoQyQljqHOFfq+q2v9jHG7mqUKqm55N-UuN4-NT6DGdD5C0Gp-Ypq31eL8HcsdFcG0yA+rB5QtHijOKOYoNWgD8nJNGUU6F2GxK9LlvSTIcLGn5C2ZUNpLj5CxIUFSD6XmuyDOGeiMZXQJlgCmTMkp2LGm1OUFCHQORGkyEVqoZQbTNly2-poaERy6kh0pYl5LrZpLNIy1l2Sm5dAkPRs4wz+NlDOGcEAA */ createMachine( { - context: { - me: undefined, - getUserError: undefined, - authError: undefined, - updateProfileError: undefined, - methods: undefined, - getMethodsError: undefined, - }, + id: "authState", + predictableActionArguments: true, tsTypes: {} as import("./authXService.typegen").Typegen0, schema: { context: {} as AuthContext, @@ -133,7 +127,14 @@ export const authMachine = } }, }, - id: "authState", + context: { + me: undefined, + getUserError: undefined, + authError: undefined, + updateProfileError: undefined, + methods: undefined, + getMethodsError: undefined, + }, initial: "gettingUser", states: { signedOut: { diff --git a/site/src/xServices/buildInfo/buildInfoXService.ts b/site/src/xServices/buildInfo/buildInfoXService.ts index f5cfc8bf7ac45..56948865012fa 100644 --- a/site/src/xServices/buildInfo/buildInfoXService.ts +++ b/site/src/xServices/buildInfo/buildInfoXService.ts @@ -9,6 +9,8 @@ export interface BuildInfoContext { export const buildInfoMachine = createMachine( { + id: "buildInfoState", + predictableActionArguments: true, tsTypes: {} as import("./buildInfoXService.typegen").Typegen0, schema: { context: {} as BuildInfoContext, @@ -21,7 +23,6 @@ export const buildInfoMachine = createMachine( context: { buildInfo: undefined, }, - id: "buildInfoState", initial: "gettingBuildInfo", states: { gettingBuildInfo: { diff --git a/site/src/xServices/createWorkspace/createWorkspaceXService.ts b/site/src/xServices/createWorkspace/createWorkspaceXService.ts index ec679731036f1..a63605852183f 100644 --- a/site/src/xServices/createWorkspace/createWorkspaceXService.ts +++ b/site/src/xServices/createWorkspace/createWorkspaceXService.ts @@ -28,7 +28,8 @@ type CreateWorkspaceEvent = { export const createWorkspaceMachine = createMachine( { id: "createWorkspaceState", - initial: "gettingTemplates", + predictableActionArguments: true, + tsTypes: {} as import("./createWorkspaceXService.typegen").Typegen0, schema: { context: {} as CreateWorkspaceContext, events: {} as CreateWorkspaceEvent, @@ -44,7 +45,7 @@ export const createWorkspaceMachine = createMachine( } }, }, - tsTypes: {} as import("./createWorkspaceXService.typegen").Typegen0, + initial: "gettingTemplates", states: { gettingTemplates: { entry: "clearGetTemplatesError", diff --git a/site/src/xServices/entitlements/entitlementsXService.ts b/site/src/xServices/entitlements/entitlementsXService.ts index 0da90acd79237..3eee8a5e43ac6 100644 --- a/site/src/xServices/entitlements/entitlementsXService.ts +++ b/site/src/xServices/entitlements/entitlementsXService.ts @@ -28,7 +28,8 @@ const emptyEntitlements = { export const entitlementsMachine = createMachine( { id: "entitlementsMachine", - initial: "idle", + predictableActionArguments: true, + tsTypes: {} as import("./entitlementsXService.typegen").Typegen0, schema: { context: {} as EntitlementsContext, events: {} as EntitlementsEvent, @@ -38,10 +39,10 @@ export const entitlementsMachine = createMachine( }, }, }, - tsTypes: {} as import("./entitlementsXService.typegen").Typegen0, context: { entitlements: emptyEntitlements, }, + initial: "idle", states: { idle: { on: { diff --git a/site/src/xServices/roles/siteRolesXService.ts b/site/src/xServices/roles/siteRolesXService.ts index ee9eaa47d8198..0f100be2d85f1 100644 --- a/site/src/xServices/roles/siteRolesXService.ts +++ b/site/src/xServices/roles/siteRolesXService.ts @@ -19,7 +19,8 @@ type SiteRolesEvent = { export const siteRolesMachine = createMachine( { id: "siteRolesState", - initial: "idle", + predictableActionArguments: true, + tsTypes: {} as import("./siteRolesXService.typegen").Typegen0, schema: { context: {} as SiteRolesContext, events: {} as SiteRolesEvent, @@ -29,7 +30,7 @@ export const siteRolesMachine = createMachine( }, }, }, - tsTypes: {} as import("./siteRolesXService.typegen").Typegen0, + initial: "idle", states: { idle: { on: { diff --git a/site/src/xServices/setup/setupXService.ts b/site/src/xServices/setup/setupXService.ts index 564d1fb6b9d14..4d02c0b5b376b 100644 --- a/site/src/xServices/setup/setupXService.ts +++ b/site/src/xServices/setup/setupXService.ts @@ -26,6 +26,8 @@ export const setupMachine = /** @xstate-layout N4IgpgJg5mDOIC5QGUwBcCuAHZaCGaYAdAJYQA2YAxAMIBKAogIIAqDA+gGICSdyL7AKrIGdRKCwB7WCTQlJAO3EgAHogDMAViKaAnPoDsABgBMRgCy6jpkwBoQAT0QBGI+qIA2N0ePOAHJqa-qYAviH2qJg4+IREAMYATmAEJApQnCQJsGiCsGAJVBCKxKkAbpIA1sSJyYQZWTl5CcpSMnKKymoI6ibuzmZGuiYG6kYemn4eHvZOCObOzjom-X7qHsZGmuq6mmER6Ni4BNVJKWn12bn5VPkJkglEWOQEAGb3ALbxp3WZl00t0lk8iUSFUGl07g8-XMxlWmmsWnUMxcUyIzg86hhPgWvg8JjC4RACkkEDgykihxiJQoYABbWBnUQflcRAMZlc6jWwwMfmRCDM2ksfgMzl0Bisbj85j8exAFOixy+tVS6V+jXydKBHVBXQAtDsiOyeVp-OoFrpnHyzboiKZ1CMDCNzEY-H4xbL5UdYi81VcEjRvpBNe0QaAuoEbZzpfaRh4rFM+eYTOZbcsTBD0b0bB6DgrCMGGTrELrzYajM5jUFVubLY4NIsvKM2eMtKZNOMCSEgA */ createMachine( { + id: "SetupState", + predictableActionArguments: true, tsTypes: {} as import("./setupXService.typegen").Typegen0, schema: { context: {} as SetupContext, @@ -36,7 +38,6 @@ export const setupMachine = } }, }, - id: "SetupState", initial: "idle", states: { idle: { diff --git a/site/src/xServices/template/templateXService.ts b/site/src/xServices/template/templateXService.ts index d9944d382ed4b..992b9edb3716d 100644 --- a/site/src/xServices/template/templateXService.ts +++ b/site/src/xServices/template/templateXService.ts @@ -33,6 +33,8 @@ export const templateMachine = /** @xstate-layout N4IgpgJg5mDOIC5QAoC2BDAxgCwJYDswBKAOhgBdyCoAVMVABwBt1ywBiCAe0JIIDcuAazAk0WPIVIUq+WvWaswCAV0ytcPANoAGALqJQDLrFxUehkAA9EAJgDsOkgGZbO2wE5bANg8BGABZnHR0AgBoQAE9EPx0-Eg9EpIAOe28-D28ggF9siPEcAmI+fDNcdCYASXwAMy4SLCp+MDpGFjYANTAAJ1MeMjBKagBBTCaWhXawLt7NfE4eUVURMQxCqRKyiuq6hrHcZtbFTp6+-AGhuVHxo6mZs5V8QXVzfF0DJBBjU1fLGwQAgF4t4AKzeWzOTIhEEhZIRaIIZI6EEkEIhZyg2xuEF+XL5NaSYoELZVWr1NhtJQAJTgXAArt1MHALrJ5JS2DTYPTGXAFrxlqICoTSMSqNsySQKccwJzuUzYCzqLdqbSGfLHs8NNp9JZvmULJ9-kDkiRks4QR50SDkh5nH5nPCYjpXKi0SDnObbeaAniQEKiiLSmLSbspXdTnMFTIlZMlPdI3ylk9hIKCQHNsGduTYydZjwo4NWcrc2dYBq1Fq3jrPnrfobEAFQqbQt5kiCcf4go6ECD7Ca0XFMskAmksr7-RtReUQ1xEyRYOQlKsJOmp+K6rqTPr8H9ELaTclkg5wQEzRidB5u-Y0q6QgFbAEsuCMuO0xsmFx0BBIOwACIAUQAGX-Gh-03H45ksBFrycGE7zcW1bD8e0In+Pw3G8EggT8M0-Fbc8PGSV8Vw2TAeBqXBulQahfzAJhBg4ABhAB5AA5AAxSoqQAWQAfQA4DQPA7ddwQZCMVRUF7Bw3svXsEFuz8MFMNtC8bRtHQzWHYj1mKMjako6i5Fo+i2HYRjhlYxigP4oCQLAmstzrUA0OcaSSHsZwbSUjwAl83zwiiGJGw8LCwTtU8vGQnI8j9N9im-UzqDnAUSEShjizAYTnOsRB7BHEglLwoqskCWxFJ8ewPJ0bx8tsC1IQhZwdOFNK6MGZKem6LhuhIY46iotrTImdkssciCDRcvcbVRJrwr8fLXHsRTYRIOCau8WqYRxIjfXwLhv3gT4J2KaM5Ey7LIPrAFyqChBLVvEJPGk2w21PFrVyDacsz2G4c2mCN+jOqBrgOEbpXjSavicq6prEhar1tR7IXSaSfVik7AxJH7GjBzLIfOWA6UweUjqMGGof+TzbEKsEMiRdwYUhbtkhw5HnHvXx0g8D7Jy+9d6lxw5-oJy7Kb3B07vsJDkekjwcSyWxeaJfmZ0lf7ZTVZlgcyzWeTJ6GJp3a7kOWu7YjcR6wQCEFAQfbxlaxzMJTDFUuS1hUiZJuADdrWHcoQVtMJxdtWfvaL0hWm2rfcRXHxBR2M2+l2NdVfWxeNuHbW7Xz+xCWJkm8ZE3LbRO1zV12S0jRVzpFwH8F9inM4D03u2Ux6sWvQj2wTjH4qd5PQzrvMG-nYnSYz0TQRNG3gnUyE+zNNv-EevDrUya9mr7kiVexlPRoJxujdE7O7r8gIO+dXtUkyMvVazSfrt8bt7xpgcFttC1nXsROPy-SBH5w1iO6MKwRghAkbH2BSUtHBrTRPeC8rhxKJ30hRKiNF2psEAS3ZCNMkR4R8MOWqfloEIntCvDmnoRzyUIvLRO6VWTYP+F4TCNt0g22REhV6pCYgEJIPVDENsPBpA9GkehmCAHjREtdVmmFPCKy2u6RwcJzaQicMOb0wQ3ALVxNvXSRAmExBUWQvOA5baqXlrbXIuQgA */ createMachine( { + id: "templateMachine", + predictableActionArguments: true, tsTypes: {} as import("./templateXService.typegen").Typegen0, schema: { context: {} as TemplateContext, @@ -58,7 +60,6 @@ export const templateMachine = } }, }, - id: "(machine)", initial: "gettingTemplate", states: { gettingTemplate: { diff --git a/site/src/xServices/templateSettings/templateSettingsXService.ts b/site/src/xServices/templateSettings/templateSettingsXService.ts index de80fbcedc842..d0fce5d9b4ee0 100644 --- a/site/src/xServices/templateSettings/templateSettingsXService.ts +++ b/site/src/xServices/templateSettings/templateSettingsXService.ts @@ -7,7 +7,9 @@ export const templateSettingsMachine = /** @xstate-layout N4IgpgJg5mDOIC5QBcwFsAOAbAhqgymMsgJYB2UsAdFgPY4TlQDEEtZYV5AbrQNadUmXASKkK1OgyYIetAMZ4S7ANoAGALqJQGWrBKl22kAA9EANgCMVAKwB2AByWATJbWWAnABYv55w-MAGhAAT0RnAGZnKgibGw9nD3M1JJsHNQiAX0zgoWw8MEJiJmpIAyZmfABBADUAUWNdfUMyYzMESx9bSK8IhwdncwcbF2dgsIRejypzX2dXf09zCLUbbNz0fNFiiSpYHG4Ktg4uMl4BKjyRQrESvYOZOUUW9S0kECbyo3f25KoHOxeDwODx9EYeNTzcYWGxqKgeGw+SJ2cx+VZebI5EBkWgQODGK4FIriSg0eiMCiNPRfVo-RBeMahRAQqhqNnuWERFFeOyedYgQnbEmlRgkqnNZS00DtSwRcz-EY2PzeeYOLk2aEIWJ2WwOIEBNIeBG8-mCm47Un7Q6U96fFptenWRJDIZy+y9AFBJkIEbRbxeWUBRwIyx2U2ba7Eu5WyDimkOhAI2yxSx+foMpWWTV2RLJgIrPoA4bh4RE24SOP2ukdHXOgJq8zuvoozWWBys9nzSydNt2NQYzFAA */ createMachine( { - initial: "loading", + id: "templateSettings", + predictableActionArguments: true, + tsTypes: {} as import("./templateSettingsXService.typegen").Typegen0, schema: {} as { context: { organizationId: string @@ -26,7 +28,7 @@ export const templateSettingsMachine = } events: { type: "SAVE"; templateSettings: UpdateTemplateMeta } }, - tsTypes: {} as import("./templateSettingsXService.typegen").Typegen0, + initial: "loading", states: { loading: { invoke: { @@ -71,7 +73,6 @@ export const templateSettingsMachine = type: "final", }, }, - id: "templateSettings", }, { services: { diff --git a/site/src/xServices/templates/templatesXService.ts b/site/src/xServices/templates/templatesXService.ts index 68e7a847e9fb7..9b0d9484cf71b 100644 --- a/site/src/xServices/templates/templatesXService.ts +++ b/site/src/xServices/templates/templatesXService.ts @@ -11,94 +11,101 @@ interface TemplatesContext { templatesError?: Error | unknown } -export const templatesMachine = createMachine( - { - tsTypes: {} as import("./templatesXService.typegen").Typegen0, - schema: { - context: {} as TemplatesContext, - services: {} as { - getOrganizations: { - data: TypesGen.Organization[] - } - getPermissions: { - data: boolean - } - getTemplates: { - data: TypesGen.Template[] - } - }, - }, - id: "templatesState", - initial: "gettingOrganizations", - states: { - gettingOrganizations: { - entry: "clearOrganizationsError", - invoke: { - src: "getOrganizations", - id: "getOrganizations", - onDone: [ - { - actions: ["assignOrganizations", "clearOrganizationsError"], - target: "gettingTemplates", - }, - ], - onError: [ - { - actions: "assignOrganizationsError", - target: "error", - }, - ], +export const templatesMachine = + /** @xstate-layout N4IgpgJg5mDOIC5QBcwFsAOAbAhq2AysnmAHQzLICWAdlAPIBOUONVAXnlQPY2wDEEXmVoA3bgGsyFJizadqveEhAZusKopqJQAD0QAWAMwHSATgDsANgCsNgzeuOATABoQAT0QBGb89I2AAzB3oEAHH7eFtFhAL6x7qiYuPhEJORglLQMzKwcXEr8YIyM3Iyk2HgAZmVoGciyeQo8fDqq6potbfoIxqaWtvaOthZunogmRgHBgc4Wvs5mYbPxieiVqcSo9dR0ACrrKXCCwqRiktKZB8kkyqBqGlrdPsH9Zs6+VlZhxlbOBu4vAgzIFSDNgot5s4wnZViAkhs4GlthRdlBroiBMVSuUNjVGHUKBijnd2o8uioeqFAm8Pt4vj8jH8AeMEM5AjYwTMouEDGEzPTnPEEiAaNwIHA2giScjLlk6I15AVWioHp1eM9emMgb4zNMZh8wvMzH8LHDpbdZTtssTbm01U9KYgvqDmUsIt4+TYIoDECbzGZA2Y+lYjIEjIHzYdLVsyEIaGB7R1HXofOyLKQDIsrKELAYogKjL6EL4wlyZjCswYHBEozdNulsWUk+SNU6S+nM9nc-mLIXi845qQjCOjDZg3YwjC65jZS31dp294wsXl8LYkA */ + createMachine( + { + id: "templatesState", + predictableActionArguments: true, + tsTypes: {} as import("./templatesXService.typegen").Typegen0, + schema: { + context: {} as TemplatesContext, + services: {} as { + getOrganizations: { + data: TypesGen.Organization[] + } + getPermissions: { + data: boolean + } + getTemplates: { + data: TypesGen.Template[] + } }, - tags: "loading", }, - gettingTemplates: { - entry: "clearTemplatesError", - invoke: { - src: "getTemplates", - id: "getTemplates", - onDone: { - target: "done", - actions: ["assignTemplates", "clearTemplatesError"], + initial: "gettingOrganizations", + states: { + gettingOrganizations: { + entry: "clearOrganizationsError", + invoke: { + src: "getOrganizations", + id: "getOrganizations", + onDone: [ + { + actions: ["assignOrganizations", "clearOrganizationsError"], + target: "gettingTemplates", + }, + ], + onError: [ + { + actions: "assignOrganizationsError", + target: "error", + }, + ], }, - onError: { - target: "error", - actions: "assignTemplatesError", + tags: "loading", + }, + gettingTemplates: { + entry: "clearTemplatesError", + invoke: { + src: "getTemplates", + id: "getTemplates", + onDone: [ + { + actions: ["assignTemplates", "clearTemplatesError"], + target: "done", + }, + ], + onError: [ + { + actions: "assignTemplatesError", + target: "error", + }, + ], }, + tags: "loading", }, - tags: "loading", + done: {}, + error: {}, }, - done: {}, - error: {}, }, - }, - { - actions: { - assignOrganizations: assign({ - organizations: (_, event) => event.data, - }), - assignOrganizationsError: assign({ - organizationsError: (_, event) => event.data, - }), - clearOrganizationsError: assign((context) => ({ - ...context, - organizationsError: undefined, - })), - assignTemplates: assign({ - templates: (_, event) => event.data, - }), - assignTemplatesError: assign({ - templatesError: (_, event) => event.data, - }), - clearTemplatesError: (context) => assign({ ...context, getWorkspacesError: undefined }), - }, - services: { - getOrganizations: API.getOrganizations, - getTemplates: async (context) => { - if (!context.organizations || context.organizations.length === 0) { - throw new Error("no organizations") - } - return API.getTemplates(context.organizations[0].id) + { + actions: { + assignOrganizations: assign({ + organizations: (_, event) => event.data, + }), + assignOrganizationsError: assign({ + organizationsError: (_, event) => event.data, + }), + clearOrganizationsError: assign((context) => ({ + ...context, + organizationsError: undefined, + })), + assignTemplates: assign({ + templates: (_, event) => event.data, + }), + assignTemplatesError: assign({ + templatesError: (_, event) => event.data, + }), + clearTemplatesError: (context) => assign({ ...context, getWorkspacesError: undefined }), + }, + services: { + getOrganizations: API.getOrganizations, + getTemplates: async (context) => { + if (!context.organizations || context.organizations.length === 0) { + throw new Error("no organizations") + } + return API.getTemplates(context.organizations[0].id) + }, }, }, - }, -) + ) diff --git a/site/src/xServices/terminal/terminalXService.ts b/site/src/xServices/terminal/terminalXService.ts index 3bc57cc0ba8c9..392aaa503f052 100644 --- a/site/src/xServices/terminal/terminalXService.ts +++ b/site/src/xServices/terminal/terminalXService.ts @@ -36,6 +36,8 @@ export const terminalMachine = /** @xstate-layout N4IgpgJg5mDOIC5QBcwCcC2BLAdgQwBsBlZPVAOhmWVygHk0o8csAvMrAex1gGIJuYcrgBunANZCqDJi3Y1u8JCAAOnWFgU5EoAB6IA7AE4AzOSMBGAEwBWCyYAsANgs2bVgDQgAnohNGbcgsnEIcHCwAOBwAGCKMHAF8Er1RMXEISMikwaloZZjYORV50NE40chUCMgAzcoxKHPy5Ip4dVXVNLm1lfQQIiLMIpxMbQYjYo2jXL18EawtyAwGwk1HTMdGklPRsfGJSCioaHCgAdXLxWBU8AGMwfkFhHDFJRuQLtCub+-a1DS07T69icVnILisDhspiccQ2sz8y3INmiqNGsMcBmiNm2IFSewyh2yuVOn2+dwepXKlWqyDqmHeZOuFL+nUBvUQILBEKhMLhowRCAMTkCIzWDkcEyMBhsBlx+PSByy7xO50uzPuAEEYDhkI8cEJRBJiUyfmBtWBdayAd0gZyjCFyFZbKjnC4jKYLIK7GYYqirCYBk5olYDIlknjdorMkccqrTRSLbqSmgyhUqrV6oz1Wak8hrV1uHb5g6nE6XdE3RYPSYvT5EWCA2s7E4sbZhfKo-sY0JbtwDbdVfrDS9jeQ+zgB-nlP9Cz09IhIcLyCZIUYotEDCZNxEDN7peY1ms4gYrNNBp20t2ieP+2BB7QU2maZmGROpwX2QuEEuy6uHOuMRbjue71ggdiLPY4phiYMoWNYl4EkqFDvveqAQLwZwAEoAJIACoAKKfraHI-gYkTkCGAFYmG0TbnWcw2A4YKmGskJno44RWIh0Y3qhg6QLwWEEZqAAixFFqRobViusKngYMpWEGgpQmWUFsSEcSOHRPHXsq-Hobwok4UQADCdAAHIWQRpl4RJ84gH0SmtuQDgTNWMJTDKJgqUEq4RNCljTOs3ERgqekUBAWCwAZgnmVZNl2TObIkd+zplrEYanvY0SwrCESCs6BiuaidGrgGTgekYSQRjgnAQHA7ThYSyrHHkjAFPI3RKKAs5fo5iAxIEXHMSMErWNiTiFa4K6ldi1ayu4FjhjsV4tbGJJql8GpgPZxYWNMDiubBdh2Ju7pGIK-jFW6rYiq4bZOLp63EvGOaJjq069Slknfq4jrOii51udiMpXbC5ATKi1ghNEljNs9yG9neD6nHtUlnhErmgqeIyosKazejNZ7+qMi3BiYiM9rek5oZA6NpeR0ROmGpgnhT0qCmNSxHhKW4BiGERUzeUUxSj6EMwN4HM5ukLLXBViRKGNhXVj64etM0JOG5YTC1kktORlp7hA4CtK2DYEALQQ8M5FKQd27OJTNVAA */ createMachine( { + id: "terminalState", + predictableActionArguments: true, tsTypes: {} as import("./terminalXService.typegen").Typegen0, schema: { context: {} as TerminalContext, @@ -52,7 +54,6 @@ export const terminalMachine = } }, }, - id: "terminalState", initial: "gettingWorkspace", states: { gettingWorkspace: { diff --git a/site/src/xServices/users/usersXService.ts b/site/src/xServices/users/usersXService.ts index 4d22c9534771a..8bd01931ea2ba 100644 --- a/site/src/xServices/users/usersXService.ts +++ b/site/src/xServices/users/usersXService.ts @@ -70,6 +70,8 @@ export type UsersEvent = export const usersMachine = createMachine( { + id: "usersState", + predictableActionArguments: true, tsTypes: {} as import("./usersXService.typegen").Typegen0, schema: { context: {} as UsersContext, @@ -95,7 +97,6 @@ export const usersMachine = createMachine( } }, }, - id: "usersState", initial: "idle", states: { idle: { diff --git a/site/src/xServices/workspace/workspaceXService.ts b/site/src/xServices/workspace/workspaceXService.ts index 67d5bfa6674cb..88ac29ff029a0 100644 --- a/site/src/xServices/workspace/workspaceXService.ts +++ b/site/src/xServices/workspace/workspaceXService.ts @@ -79,291 +79,372 @@ const permissionsToCheck = (workspace: TypesGen.Workspace) => ({ }, }) -export const workspaceMachine = createMachine( - { - tsTypes: {} as import("./workspaceXService.typegen").Typegen0, - schema: { - context: {} as WorkspaceContext, - events: {} as WorkspaceEvent, - services: {} as { - getWorkspace: { - data: TypesGen.Workspace - } - getTemplate: { - data: TypesGen.Template - } - startWorkspace: { - data: TypesGen.WorkspaceBuild - } - stopWorkspace: { - data: TypesGen.WorkspaceBuild - } - deleteWorkspace: { - data: TypesGen.WorkspaceBuild - } - cancelWorkspace: { - data: Types.Message - } - refreshWorkspace: { - data: TypesGen.Workspace | undefined - } - getResources: { - data: TypesGen.WorkspaceResource[] - } - getBuilds: { - data: TypesGen.WorkspaceBuild[] - } - loadMoreBuilds: { - data: TypesGen.WorkspaceBuild[] - } - checkPermissions: { - data: TypesGen.UserAuthorizationResponse - } - }, - }, - id: "workspaceState", - initial: "idle", - on: { - GET_WORKSPACE: "gettingWorkspace", - }, - states: { - idle: { - tags: "loading", - }, - gettingWorkspace: { - entry: ["clearGetWorkspaceError", "clearContext"], - invoke: { - src: "getWorkspace", - id: "getWorkspace", - onDone: { - target: "refreshingTemplate", - actions: ["assignWorkspace"], - }, - onError: { - target: "error", - actions: "assignGetWorkspaceError", - }, +export const workspaceMachine = + /** @xstate-layout N4IgpgJg5mDOIC5QHcD2AnA1rADgQwGMwBlAFz1LADoZTSBLAOygHUNt8iBiCVR6pgDdUmarTZZchMIlA5Usegz6yQAD0QAWAAwAmKgHYAbAFYjADgDMB80YCcu87oA0IAJ6JLARhP6Dly01dO1tzAztTAF9I1zRJThJyShowOiZWdiluMHR0DCocABsKADMMAFsU0gkOaVV5RWVGVQ0EOwMvQxNw7VsHbU1Nc1cPBEtgy0MAoIcTE20vI0to2MyEsgpqdDAS7dgAC3SAFTByos2ePgFGYVEqbd24fZOz4sp6hSV6FSR1LT1DKYLNY+o4XO5EI4DH5prpfHYAgYViA4rUiBtkg89odmC9zpQuDk8ugCm8yuhKlinni3jJfg0vj9QK0dH4gVYbPYwSNPNprFNAroDNptAYOl4kTEUWtpBixKkGMwAAo5cr0WCKPiwS78KhCETUAj7MAETAqinqzWMeD0z5NFqILx6fQWAwmOzzfzmII8hCLTSTIxB8USyxGLzLKWorKJTZVRVQc1qjXfa2E3L5fHkypGk1m1WW1M2uR21MOv3Oqiu92eyze8GjRx2OxUXSw0yaIxw8zI6PrJJbMB4CBuAqoQqFdI1GP3HbYqcy7i8XX6u5Ug7ThIfRpl36tUOTbQI8wDMxeHxGX0dcxUEUirwRJ29Nu9xexzFDkdjicL+LSWePAcv5omA6bEqSpQVAB2KbnUto7kyfx+v4h7Hqe4YXr6Sz6Heei9NYRhBJor5-uiA6zsOo7yD+zCwUQVDIHgXzMFwaiwOReAlJQ6AABRPtoACUXB9rK5HbJR36TrRb4MUxCbboyzR7o65gmJorZ8hKHQdJY2hzL6Jjered4RuYXi2JoEYkSBcoUV+ABGACu9CFBAeoQIUoHEEcACCABKRwKfaykILoR7aLeXZzIE4yqZoBi+hGenGSKgzaEGdh6SY1kxrZ4kOc5rnuZ5XDeQA8kqQW7sykLhZFcImDFjhqQlEKhboXj6AEgTpeeekSsRUZvnln6jk5LlufQHmgT5xAANIAPoACIAKIADIrUcK1VYhrRhZl9XRQGzXxYlAwGClAznuK3p2Dl-ZxvlY2FZN01cAAqkqS0+VtO1KTVoV1elDVNXFrWjANRiXUGFhmeG92iY9o1UONRVTSVADCPkAHIY+tf3lvtEXA0dsUtYlhmHneZgniebqDaspHvoOEmo25eCwJg6RLWAnkEqtG2-fBimE7ouhQ2YcJ2BK5hme0l5tR6nS4UKEbeE4d1DUzI2sy9VAc1zzA83zoFY7j63Letm3bcLwUAx1RgRR1R4RHYllOhKvrNi2uGBD4HXegjZFI7rE2zgAjo5cAJhs6CkDq1y3NQ7F4HHdF0iWCH-UhQomJ04bQnpEwB4lqk3t1Oi6Z2miekHzN2c9YfbJH0fpLH8dEpmZJQSnadvgTIW5+pEqu7Y8wim7iVePFVDjwMst8hERh1zrBVN2ALfsW3pCoDgCd6jcBpUOxu-pwP9udfoedmEYxidYRnttftF0V3yuiaG74zL1rNlicjbMRyjlvZgZBd5gS7pBCkx8d44DPrbaqOdOomFvDYRYR57DHXBrVc8VBX6DGMM2SMjNf4hzXkVZuQCEzG1SKBZcicj4QF5jQuBmcRYhQlGLKsZMlhBCDJ2CmhlcHdQRDYBYNciHSm1n-UO5CN6UO5kwgkncSRZigowk2LCQAMjtkhDhLpuGCj4QrCG8UurCPHmKPSEiRLBw-DItyFDW7MAxngRgRBCj71XIaVx7jNHaIQXtOqVhHaWBvtfMwiUAw+zvB-MugQlgr2kWQhxcinFQBcW43m4CVHdygQQHxvM-Gll2pCJ0N53R1mnldEIdhEqhKpiKPOvR3TpWyj-XKSTG6yMAjiKANILh0IPknaC1JTj4gzlo4p2c9oGBnt4OEEpF6NXaIlYUyDX5hm0sYRJpCukpJ6ccMZtJskQVINmEZBx+nvHgSUwGB0SaNWOmDRKSxlZ3iWE4YUxhJTEI6bsyS6Q-JwFQI5dARBYDxkBcC0F4LPGHzuLQIFsAQVgrgOfXRFhOjvzbD4XopjjC+jrMTEyfJvTmUajsuxX5qJSSgEilF4LIXMHpTCuAJzVFQMRdC1FxZJlZ3LIsMyrYgjeHmN6aEBKn5u0uueDCsy1IM0kSQqlVFxy0pZTy2SzEoCsRTskTi3EeJzyEjY+uT0AXMu5Yyxi2r0X7jFFi8y5gIgBFUosSwvp35Q1wqeBwsyAxtN+Q9FVVAGDlF5kweUaRmAACEXrakGV4hiw1OmhvoOGqSUaExxomrABA+p8lNAANraAALp2sdLFW8x4P7iLmA2SElgERUCsH7PQbsF4-KVX8kNYaI26loNm+N7LcmVFNavUcfbM1MqgDm1yeaC0UFTCW8tNzpmVscNWustbGr1sJRGKGFcxaVNsLoSlLMvxTsjVQQoqBhyQDnRACF6NQJrTKj5JaC0ACyZU-IrQWjG96ABJNaS1iAVuQr0Ks15vmEVmV4T1jsWwV2njFWV38g2I17em-t1Bb33ogI+59b0-0ADE-3EAABILSOEBr960gPYxtqwnRgTGpUAlOZJtstOqy09f6ltsJRQRmFGe9pwaL2Tpw9O-DjDCPxpvXeiA6Qv0YDAERuFwzx2pqvbqWTD6FOyZU2poj+bD6FuXWWiDiwPQcfCB0AYEQ5iGU9SeZDsIwxHiCGJzDtjJNpozde-T8nc2KeHMZ7YGnlGnPOdp-5um8NKYM6FozzBVORfjWZ4QFm+Arus-YZBI8HMf1MHMYYT9oSTCPUMMMIQfPdok1QZRXAADim0FosF-XNYgSofJ4wg+0ToboeiggGEMQl79kEoW822R2PhA0Naw6BNrRwOtdZ6315jfK2EAx9G1AITpWywjzt4fw3RohSkYKgRhvK4vJBfRBvbowAgWCO01XF-gu13azcBGMEHwxO00mEMMnUwwmAmz4WewZb5+sIhS8TS2Lm9KuRM-xtynu8nfgKAMnGWkInPTOpMhYtT-c4dWQicsTzg6flYCK039oM4w4tvzDcLUZCZkj37W410CvVlu26dbfBYQ-rPO8wQP7dk7AT81NKuf-htfJHn7CQgXRsJlR8YpVLGMQBTy678RFWBfAjlnMu1Vy6INZ8X-Od2hKF21POOETJ1kakKaE0v-56we0rgGD485Q7hKyewftqcQ26BdOecwPnYvd-Y-WnMFEmwg22OZSDwwIgfPUs6ukugigIuGCwNcY-JMAWk9uSeVdHaiXTd+7rS4iiET1MWrT2g9mN2aj369N4xxgUnwIL9U8Z4z41T1SVBM9VmdLXw78i97JL8AqA1DrksYCZW8y1u3a7rtyYptY+m3BAn44axKb-kAMcfPjJ7je8p7hGn7wCJh9tWnmYUXIoljzF8KpL7x+Q2n7nE8Q5rwmwvejsuCmUt8syz85kLyboDeOg7qzqzYM+KML0lu0qR426G+tuDaCAYQ0S94Yo8q08revm7eEksulqyKrKEKg6UKlBPK1mfO6BAum+2Boql0ooD86utgSB5BdKVqcAWqiuy+tyD4UGRW0sCIuchE+6xK7y6sryR+Ui-yvBGq4KqB6kTBNue6j+syl0sUoowQ4sSBCWxUqOUyAqH+uCjgD4nGQIQo+6IuralkwosssyxBzOpBl60m16NBsa8aSe+uXCru0swoiwWCoUt8w8wYkecOiq32rOJhwWRGph1mCI6kt8oh5khEYUYo-GO+FcdYAQ50hExh3hemSWIW86YWymaWJm-h3uuiYYqEGBgu2B4scIY+OgHa0InYTO8R5qiRFRRGDBO+mhmB2hjYjUL80wQQcwxgUQbeE6AWuGDBAw6+rRnq4wnQThE8YYHUcIM+luwo6xLBZ0jur+ToAcOgqkBOyilugiYxGx+2hhsBHUPgAYeg561m5WEMN4uEecQYp24scwF2kQQAA */ + createMachine( + { + id: "workspaceState", + predictableActionArguments: true, + tsTypes: {} as import("./workspaceXService.typegen").Typegen0, + schema: { + context: {} as WorkspaceContext, + events: {} as WorkspaceEvent, + services: {} as { + getWorkspace: { + data: TypesGen.Workspace + } + getTemplate: { + data: TypesGen.Template + } + startWorkspace: { + data: TypesGen.WorkspaceBuild + } + stopWorkspace: { + data: TypesGen.WorkspaceBuild + } + deleteWorkspace: { + data: TypesGen.WorkspaceBuild + } + cancelWorkspace: { + data: Types.Message + } + refreshWorkspace: { + data: TypesGen.Workspace | undefined + } + getResources: { + data: TypesGen.WorkspaceResource[] + } + getBuilds: { + data: TypesGen.WorkspaceBuild[] + } + loadMoreBuilds: { + data: TypesGen.WorkspaceBuild[] + } + checkPermissions: { + data: TypesGen.UserAuthorizationResponse + } }, - tags: "loading", }, - refreshingTemplate: { - entry: ["clearRefreshTemplateError"], - invoke: { - id: "refreshTemplate", - src: "getTemplate", - onDone: { - target: "gettingPermissions", - actions: ["assignTemplate"], - }, - onError: { - target: "error", - actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], - }, + initial: "idle", + on: { + GET_WORKSPACE: { + target: ".gettingWorkspace", + internal: false, }, - tags: "loading", }, - gettingPermissions: { - entry: "clearGetPermissionsError", - invoke: { - src: "checkPermissions", - id: "checkPermissions", - onDone: [ - { - actions: ["assignPermissions"], - target: "ready", - }, - ], - onError: [ - { - actions: "assignGetPermissionsError", - target: "error", - }, - ], + states: { + idle: { + tags: "loading", }, - }, - ready: { - type: "parallel", - states: { - // We poll the workspace consistently to know if it becomes outdated and to update build status - pollingWorkspace: { - initial: "refreshingWorkspace", - states: { - refreshingWorkspace: { - entry: "clearRefreshWorkspaceError", - invoke: { - id: "refreshWorkspace", - src: "refreshWorkspace", - onDone: { target: "waiting", actions: ["refreshTimeline", "assignWorkspace"] }, - onError: { target: "waiting", actions: "assignRefreshWorkspaceError" }, - }, + gettingWorkspace: { + entry: ["clearGetWorkspaceError", "clearContext"], + invoke: { + src: "getWorkspace", + id: "getWorkspace", + onDone: [ + { + actions: "assignWorkspace", + target: "refreshingTemplate", }, - waiting: { - after: { - 1000: "refreshingWorkspace", - }, + ], + onError: [ + { + actions: "assignGetWorkspaceError", + target: "error", }, - }, + ], }, - build: { - initial: "idle", - states: { - idle: { - on: { - START: "requestingStart", - STOP: "requestingStop", - ASK_DELETE: "askingDelete", - UPDATE: "refreshingTemplate", - CANCEL: "requestingCancel", - }, + tags: "loading", + }, + refreshingTemplate: { + entry: "clearRefreshTemplateError", + invoke: { + src: "getTemplate", + id: "refreshTemplate", + onDone: [ + { + actions: "assignTemplate", + target: "gettingPermissions", }, - askingDelete: { - on: { - DELETE: "requestingDelete", - CANCEL_DELETE: "idle", - }, + ], + onError: [ + { + actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], + target: "error", }, - requestingStart: { - entry: "clearBuildError", - invoke: { - id: "startWorkspace", - src: "startWorkspace", - onDone: { - target: "idle", - actions: ["assignBuild", "refreshTimeline"], + ], + }, + tags: "loading", + }, + gettingPermissions: { + entry: "clearGetPermissionsError", + invoke: { + src: "checkPermissions", + id: "checkPermissions", + onDone: [ + { + actions: "assignPermissions", + target: "ready", + }, + ], + onError: [ + { + actions: "assignGetPermissionsError", + target: "error", + }, + ], + }, + }, + ready: { + type: "parallel", + states: { + pollingWorkspace: { + initial: "refreshingWorkspace", + states: { + refreshingWorkspace: { + entry: "clearRefreshWorkspaceError", + invoke: { + src: "refreshWorkspace", + id: "refreshWorkspace", + onDone: [ + { + actions: ["refreshTimeline", "assignWorkspace"], + target: "waiting", + }, + ], + onError: [ + { + actions: "assignRefreshWorkspaceError", + target: "waiting", + }, + ], }, - onError: { - target: "idle", - actions: ["assignBuildError"], + }, + waiting: { + after: { + "1000": { + target: "refreshingWorkspace", + }, }, }, }, - requestingStop: { - entry: "clearBuildError", - invoke: { - id: "stopWorkspace", - src: "stopWorkspace", - onDone: { - target: "idle", - actions: ["assignBuild", "refreshTimeline"], - }, - onError: { - target: "idle", - actions: ["assignBuildError"], + }, + build: { + initial: "idle", + states: { + idle: { + on: { + START: { + target: "requestingStart", + }, + STOP: { + target: "requestingStop", + }, + ASK_DELETE: { + target: "askingDelete", + }, + UPDATE: { + target: "refreshingTemplate", + }, + CANCEL: { + target: "requestingCancel", + }, }, }, - }, - requestingDelete: { - entry: "clearBuildError", - invoke: { - id: "deleteWorkspace", - src: "deleteWorkspace", - onDone: { - target: "idle", - actions: ["assignBuild", "refreshTimeline"], + askingDelete: { + on: { + DELETE: { + target: "requestingDelete", + }, + CANCEL_DELETE: { + target: "idle", + }, }, - onError: { - target: "idle", - actions: ["assignBuildError"], + }, + requestingStart: { + entry: "clearBuildError", + invoke: { + src: "startWorkspace", + id: "startWorkspace", + onDone: [ + { + actions: ["assignBuild", "refreshTimeline"], + target: "idle", + }, + ], + onError: [ + { + actions: "assignBuildError", + target: "idle", + }, + ], }, }, - }, - requestingCancel: { - entry: ["clearCancellationMessage", "clearCancellationError"], - invoke: { - id: "cancelWorkspace", - src: "cancelWorkspace", - onDone: { - target: "idle", - actions: [ - "assignCancellationMessage", - "displayCancellationMessage", - "refreshTimeline", + requestingStop: { + entry: "clearBuildError", + invoke: { + src: "stopWorkspace", + id: "stopWorkspace", + onDone: [ + { + actions: ["assignBuild", "refreshTimeline"], + target: "idle", + }, + ], + onError: [ + { + actions: "assignBuildError", + target: "idle", + }, ], }, - onError: { - target: "idle", - actions: ["assignCancellationError"], + }, + requestingDelete: { + entry: "clearBuildError", + invoke: { + src: "deleteWorkspace", + id: "deleteWorkspace", + onDone: [ + { + actions: ["assignBuild", "refreshTimeline"], + target: "idle", + }, + ], + onError: [ + { + actions: "assignBuildError", + target: "idle", + }, + ], }, }, - }, - refreshingTemplate: { - entry: "clearRefreshTemplateError", - invoke: { - id: "refreshTemplate", - src: "getTemplate", - onDone: { - target: "requestingStart", - actions: "assignTemplate", + requestingCancel: { + entry: ["clearCancellationMessage", "clearCancellationError"], + invoke: { + src: "cancelWorkspace", + id: "cancelWorkspace", + onDone: [ + { + actions: [ + "assignCancellationMessage", + "displayCancellationMessage", + "refreshTimeline", + ], + target: "idle", + }, + ], + onError: [ + { + actions: "assignCancellationError", + target: "idle", + }, + ], }, - onError: { - target: "idle", - actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], + }, + refreshingTemplate: { + entry: "clearRefreshTemplateError", + invoke: { + src: "getTemplate", + id: "refreshTemplate", + onDone: [ + { + actions: "assignTemplate", + target: "requestingStart", + }, + ], + onError: [ + { + actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], + target: "idle", + }, + ], }, }, }, }, - }, - pollingResources: { - initial: "gettingResources", - states: { - gettingResources: { - entry: "clearGetResourcesError", - invoke: { - id: "getResources", - src: "getResources", - onDone: { target: "waiting", actions: "assignResources" }, - onError: { target: "waiting", actions: "assignGetResourcesError" }, + pollingResources: { + initial: "gettingResources", + states: { + gettingResources: { + entry: "clearGetResourcesError", + invoke: { + src: "getResources", + id: "getResources", + onDone: [ + { + actions: "assignResources", + target: "waiting", + }, + ], + onError: [ + { + actions: "assignGetResourcesError", + target: "waiting", + }, + ], + }, }, - }, - waiting: { - after: { - 5000: "gettingResources", + waiting: { + after: { + "5000": { + target: "gettingResources", + }, + }, }, }, }, - }, - - timeline: { - initial: "gettingBuilds", - states: { - idle: {}, - gettingBuilds: { - entry: "clearGetBuildsError", - invoke: { - src: "getBuilds", - onDone: { - actions: ["assignBuilds"], - target: "loadedBuilds", - }, - onError: { - actions: ["assignGetBuildsError"], - target: "idle", + timeline: { + initial: "gettingBuilds", + states: { + idle: {}, + gettingBuilds: { + entry: "clearGetBuildsError", + invoke: { + src: "getBuilds", + onDone: [ + { + actions: "assignBuilds", + target: "loadedBuilds", + }, + ], + onError: [ + { + actions: "assignGetBuildsError", + target: "idle", + }, + ], }, }, - }, - loadedBuilds: { - initial: "idle", - states: { - idle: { - on: { - LOAD_MORE_BUILDS: { - target: "loadingMoreBuilds", - cond: "hasMoreBuilds", + loadedBuilds: { + initial: "idle", + states: { + idle: { + on: { + LOAD_MORE_BUILDS: { + cond: "hasMoreBuilds", + target: "loadingMoreBuilds", + }, + REFRESH_TIMELINE: { + target: "#workspaceState.ready.timeline.gettingBuilds", + }, }, - REFRESH_TIMELINE: "#workspaceState.ready.timeline.gettingBuilds", }, - }, - loadingMoreBuilds: { - entry: "clearLoadMoreBuildsError", - invoke: { - src: "loadMoreBuilds", - onDone: { - actions: ["assignNewBuilds"], - target: "idle", - }, - onError: { - actions: ["assignLoadMoreBuildsError"], - target: "idle", + loadingMoreBuilds: { + entry: "clearLoadMoreBuildsError", + invoke: { + src: "loadMoreBuilds", + onDone: [ + { + actions: "assignNewBuilds", + target: "idle", + }, + ], + onError: [ + { + actions: "assignLoadMoreBuildsError", + target: "idle", + }, + ], }, }, }, @@ -372,231 +453,236 @@ export const workspaceMachine = createMachine( }, }, }, - }, - error: { - on: { - GET_WORKSPACE: "gettingWorkspace", + error: { + on: { + GET_WORKSPACE: { + target: "gettingWorkspace", + }, + }, }, }, }, - }, - { - actions: { - // Clear data about an old workspace when looking at a new one - clearContext: () => - assign({ - workspace: undefined, - template: undefined, - build: undefined, - permissions: undefined, + { + actions: { + // Clear data about an old workspace when looking at a new one + clearContext: () => + assign({ + workspace: undefined, + template: undefined, + build: undefined, + permissions: undefined, + }), + assignWorkspace: assign({ + workspace: (_, event) => event.data, }), - assignWorkspace: assign({ - workspace: (_, event) => event.data, - }), - assignGetWorkspaceError: assign({ - getWorkspaceError: (_, event) => event.data, - }), - clearGetWorkspaceError: (context) => assign({ ...context, getWorkspaceError: undefined }), - assignTemplate: assign({ - template: (_, event) => event.data, - }), - assignPermissions: assign({ - // Setting event.data as Permissions to be more stricted. So we know - // what permissions we asked for. - permissions: (_, event) => event.data as Permissions, - }), - assignGetPermissionsError: assign({ - checkPermissionsError: (_, event) => event.data, - }), - clearGetPermissionsError: assign({ - checkPermissionsError: (_) => undefined, - }), - assignBuild: assign({ - build: (_, event) => event.data, - }), - assignBuildError: assign({ - buildError: (_, event) => event.data, - }), - clearBuildError: assign({ - buildError: (_) => undefined, - }), - assignCancellationMessage: assign({ - cancellationMessage: (_, event) => event.data, - }), - clearCancellationMessage: assign({ - cancellationMessage: (_) => undefined, - }), - displayCancellationMessage: (context) => { - if (context.cancellationMessage) { - displaySuccess(context.cancellationMessage.message) - } - }, - assignCancellationError: assign({ - cancellationError: (_, event) => event.data, - }), - clearCancellationError: assign({ - cancellationError: (_) => undefined, - }), - assignRefreshWorkspaceError: assign({ - refreshWorkspaceError: (_, event) => event.data, - }), - clearRefreshWorkspaceError: assign({ - refreshWorkspaceError: (_) => undefined, - }), - assignRefreshTemplateError: assign({ - refreshTemplateError: (_, event) => event.data, - }), - displayRefreshTemplateError: () => { - displayError(Language.refreshTemplateError) - }, - clearRefreshTemplateError: assign({ - refreshTemplateError: (_) => undefined, - }), - // Resources - assignResources: assign({ - resources: (_, event) => event.data, - }), - assignGetResourcesError: assign({ - getResourcesError: (_, event) => event.data, - }), - clearGetResourcesError: assign({ - getResourcesError: (_) => undefined, - }), - // Timeline - assignBuilds: assign({ - builds: (_, event) => event.data, - }), - assignGetBuildsError: assign({ - getBuildsError: (_, event) => event.data, - }), - clearGetBuildsError: assign({ - getBuildsError: (_) => undefined, - }), - assignNewBuilds: assign({ - builds: (context, event) => { - const oldBuilds = context.builds - - if (!oldBuilds) { - // This state is theoretically impossible, but helps TS - throw new Error("workspaceXService: failed to load workspace builds") + assignGetWorkspaceError: assign({ + getWorkspaceError: (_, event) => event.data, + }), + clearGetWorkspaceError: (context) => assign({ ...context, getWorkspaceError: undefined }), + assignTemplate: assign({ + template: (_, event) => event.data, + }), + assignPermissions: assign({ + // Setting event.data as Permissions to be more stricted. So we know + // what permissions we asked for. + permissions: (_, event) => event.data as Permissions, + }), + assignGetPermissionsError: assign({ + checkPermissionsError: (_, event) => event.data, + }), + clearGetPermissionsError: assign({ + checkPermissionsError: (_) => undefined, + }), + assignBuild: assign({ + build: (_, event) => event.data, + }), + assignBuildError: assign({ + buildError: (_, event) => event.data, + }), + clearBuildError: assign({ + buildError: (_) => undefined, + }), + assignCancellationMessage: assign({ + cancellationMessage: (_, event) => event.data, + }), + clearCancellationMessage: assign({ + cancellationMessage: (_) => undefined, + }), + displayCancellationMessage: (context) => { + if (context.cancellationMessage) { + displaySuccess(context.cancellationMessage.message) } - - return [...oldBuilds, ...event.data] }, - }), - assignLoadMoreBuildsError: assign({ - loadMoreBuildsError: (_, event) => event.data, - }), - clearLoadMoreBuildsError: assign({ - loadMoreBuildsError: (_) => undefined, - }), - refreshTimeline: pure((context, event) => { - // No need to refresh the timeline if it is not loaded - if (!context.builds) { - return - } - // When it is a refresh workspace event, we want to check if the latest - // build was updated to not over fetch the builds - if (event.type === "done.invoke.refreshWorkspace") { - const latestBuildInTimeline = latestBuild(context.builds) - const isUpdated = event.data?.latest_build.updated_at !== latestBuildInTimeline.updated_at - if (isUpdated) { + assignCancellationError: assign({ + cancellationError: (_, event) => event.data, + }), + clearCancellationError: assign({ + cancellationError: (_) => undefined, + }), + assignRefreshWorkspaceError: assign({ + refreshWorkspaceError: (_, event) => event.data, + }), + clearRefreshWorkspaceError: assign({ + refreshWorkspaceError: (_) => undefined, + }), + assignRefreshTemplateError: assign({ + refreshTemplateError: (_, event) => event.data, + }), + displayRefreshTemplateError: () => { + displayError(Language.refreshTemplateError) + }, + clearRefreshTemplateError: assign({ + refreshTemplateError: (_) => undefined, + }), + // Resources + assignResources: assign({ + resources: (_, event) => event.data, + }), + assignGetResourcesError: assign({ + getResourcesError: (_, event) => event.data, + }), + clearGetResourcesError: assign({ + getResourcesError: (_) => undefined, + }), + // Timeline + assignBuilds: assign({ + builds: (_, event) => event.data, + }), + assignGetBuildsError: assign({ + getBuildsError: (_, event) => event.data, + }), + clearGetBuildsError: assign({ + getBuildsError: (_) => undefined, + }), + assignNewBuilds: assign({ + builds: (context, event) => { + const oldBuilds = context.builds + + if (!oldBuilds) { + // This state is theoretically impossible, but helps TS + throw new Error("workspaceXService: failed to load workspace builds") + } + + return [...oldBuilds, ...event.data] + }, + }), + assignLoadMoreBuildsError: assign({ + loadMoreBuildsError: (_, event) => event.data, + }), + clearLoadMoreBuildsError: assign({ + loadMoreBuildsError: (_) => undefined, + }), + refreshTimeline: pure((context, event) => { + // No need to refresh the timeline if it is not loaded + if (!context.builds) { + return + } + // When it is a refresh workspace event, we want to check if the latest + // build was updated to not over fetch the builds + if (event.type === "done.invoke.refreshWorkspace") { + const latestBuildInTimeline = latestBuild(context.builds) + const isUpdated = + event.data?.latest_build.updated_at !== latestBuildInTimeline.updated_at + if (isUpdated) { + return send({ type: "REFRESH_TIMELINE" }) + } + } else { return send({ type: "REFRESH_TIMELINE" }) } - } else { - return send({ type: "REFRESH_TIMELINE" }) - } - }), - }, - guards: { - hasMoreBuilds: (_) => false, - }, - services: { - getWorkspace: async (_, event) => { - return await API.getWorkspaceByOwnerAndName(event.username, event.workspaceName, { - include_deleted: true, - }) - }, - getTemplate: async (context) => { - if (context.workspace) { - return await API.getTemplate(context.workspace.template_id) - } else { - throw Error("Cannot get template without workspace") - } - }, - startWorkspace: async (context) => { - if (context.workspace) { - return await API.startWorkspace(context.workspace.id, context.template?.active_version_id) - } else { - throw Error("Cannot start workspace without workspace id") - } - }, - stopWorkspace: async (context) => { - if (context.workspace) { - return await API.stopWorkspace(context.workspace.id) - } else { - throw Error("Cannot stop workspace without workspace id") - } - }, - deleteWorkspace: async (context) => { - if (context.workspace) { - return await API.deleteWorkspace(context.workspace.id) - } else { - throw Error("Cannot delete workspace without workspace id") - } - }, - cancelWorkspace: async (context) => { - if (context.workspace) { - return await API.cancelWorkspaceBuild(context.workspace.latest_build.id) - } else { - throw Error("Cannot cancel workspace without build id") - } - }, - refreshWorkspace: async (context) => { - if (context.workspace) { - return await API.getWorkspaceByOwnerAndName( - context.workspace.owner_name, - context.workspace.name, - { - include_deleted: true, - }, - ) - } else { - throw Error("Cannot refresh workspace without id") - } - }, - getResources: async (context) => { - // If the job hasn't completed, fetching resources will result - // in an unfriendly error for the user. - if (!context.workspace?.latest_build.job.completed_at) { - return [] - } - const resources = await API.getWorkspaceResources(context.workspace.latest_build.id) - return resources - }, - getBuilds: async (context) => { - if (context.workspace) { - return await API.getWorkspaceBuilds(context.workspace.id) - } else { - throw Error("Cannot get builds without id") - } + }), }, - loadMoreBuilds: async (context) => { - if (context.workspace) { - return await API.getWorkspaceBuilds(context.workspace.id) - } else { - throw Error("Cannot load more builds without id") - } + guards: { + hasMoreBuilds: (_) => false, }, - checkPermissions: async (context) => { - if (context.workspace && context.userId) { - return await API.checkUserPermissions(context.userId, { - checks: permissionsToCheck(context.workspace), + services: { + getWorkspace: async (_, event) => { + return await API.getWorkspaceByOwnerAndName(event.username, event.workspaceName, { + include_deleted: true, }) - } else { - throw Error("Cannot check permissions without both workspace and user id") - } + }, + getTemplate: async (context) => { + if (context.workspace) { + return await API.getTemplate(context.workspace.template_id) + } else { + throw Error("Cannot get template without workspace") + } + }, + startWorkspace: async (context) => { + if (context.workspace) { + return await API.startWorkspace( + context.workspace.id, + context.template?.active_version_id, + ) + } else { + throw Error("Cannot start workspace without workspace id") + } + }, + stopWorkspace: async (context) => { + if (context.workspace) { + return await API.stopWorkspace(context.workspace.id) + } else { + throw Error("Cannot stop workspace without workspace id") + } + }, + deleteWorkspace: async (context) => { + if (context.workspace) { + return await API.deleteWorkspace(context.workspace.id) + } else { + throw Error("Cannot delete workspace without workspace id") + } + }, + cancelWorkspace: async (context) => { + if (context.workspace) { + return await API.cancelWorkspaceBuild(context.workspace.latest_build.id) + } else { + throw Error("Cannot cancel workspace without build id") + } + }, + refreshWorkspace: async (context) => { + if (context.workspace) { + return await API.getWorkspaceByOwnerAndName( + context.workspace.owner_name, + context.workspace.name, + { + include_deleted: true, + }, + ) + } else { + throw Error("Cannot refresh workspace without id") + } + }, + getResources: async (context) => { + // If the job hasn't completed, fetching resources will result + // in an unfriendly error for the user. + if (!context.workspace?.latest_build.job.completed_at) { + return [] + } + const resources = await API.getWorkspaceResources(context.workspace.latest_build.id) + return resources + }, + getBuilds: async (context) => { + if (context.workspace) { + return await API.getWorkspaceBuilds(context.workspace.id) + } else { + throw Error("Cannot get builds without id") + } + }, + loadMoreBuilds: async (context) => { + if (context.workspace) { + return await API.getWorkspaceBuilds(context.workspace.id) + } else { + throw Error("Cannot load more builds without id") + } + }, + checkPermissions: async (context) => { + if (context.workspace && context.userId) { + return await API.checkUserPermissions(context.userId, { + checks: permissionsToCheck(context.workspace), + }) + } else { + throw Error("Cannot check permissions without both workspace and user id") + } + }, }, }, - }, -) + ) diff --git a/site/src/xServices/workspaceBuild/workspaceBuildXService.ts b/site/src/xServices/workspaceBuild/workspaceBuildXService.ts index b49fa75a98e31..cbe080e0dbda7 100644 --- a/site/src/xServices/workspaceBuild/workspaceBuildXService.ts +++ b/site/src/xServices/workspaceBuild/workspaceBuildXService.ts @@ -24,6 +24,8 @@ type LogsEvent = { export const workspaceBuildMachine = createMachine( { id: "workspaceBuildState", + predictableActionArguments: true, + tsTypes: {} as import("./workspaceBuildXService.typegen").Typegen0, schema: { context: {} as LogsContext, events: {} as LogsEvent, @@ -36,7 +38,6 @@ export const workspaceBuildMachine = createMachine( } }, }, - tsTypes: {} as import("./workspaceBuildXService.typegen").Typegen0, initial: "gettingBuild", states: { gettingBuild: { diff --git a/site/src/xServices/workspaceSchedule/workspaceScheduleBannerXService.ts b/site/src/xServices/workspaceSchedule/workspaceScheduleBannerXService.ts index 007cd862c1835..5dd803bc3b9ae 100644 --- a/site/src/xServices/workspaceSchedule/workspaceScheduleBannerXService.ts +++ b/site/src/xServices/workspaceSchedule/workspaceScheduleBannerXService.ts @@ -21,11 +21,12 @@ export type WorkspaceScheduleBannerEvent = { export const workspaceScheduleBannerMachine = createMachine( { + id: "workspaceScheduleBannerState", + predictableActionArguments: true, tsTypes: {} as import("./workspaceScheduleBannerXService.typegen").Typegen0, schema: { events: {} as WorkspaceScheduleBannerEvent, }, - id: "workspaceScheduleBannerState", initial: "idle", states: { idle: { diff --git a/site/src/xServices/workspaceSchedule/workspaceScheduleXService.ts b/site/src/xServices/workspaceSchedule/workspaceScheduleXService.ts index 9fef3b34cd0f4..be45a8fdcb075 100644 --- a/site/src/xServices/workspaceSchedule/workspaceScheduleXService.ts +++ b/site/src/xServices/workspaceSchedule/workspaceScheduleXService.ts @@ -53,6 +53,8 @@ export type WorkspaceScheduleEvent = export const workspaceSchedule = createMachine( { + id: "workspaceScheduleState", + predictableActionArguments: true, tsTypes: {} as import("./workspaceScheduleXService.typegen").Typegen0, schema: { context: {} as WorkspaceScheduleContext, @@ -63,7 +65,6 @@ export const workspaceSchedule = createMachine( } }, }, - id: "workspaceScheduleState", initial: "idle", on: { GET_WORKSPACE: "gettingWorkspace", diff --git a/site/src/xServices/workspaces/workspacesXService.ts b/site/src/xServices/workspaces/workspacesXService.ts index 9bc3df854b711..026efec7ff1e4 100644 --- a/site/src/xServices/workspaces/workspacesXService.ts +++ b/site/src/xServices/workspaces/workspacesXService.ts @@ -28,6 +28,8 @@ type WorkspaceItemEvent = export const workspaceItemMachine = createMachine( { id: "workspaceItemMachine", + predictableActionArguments: true, + tsTypes: {} as import("./workspacesXService.typegen").Typegen0, schema: { context: {} as WorkspaceItemContext, events: {} as WorkspaceItemEvent, @@ -43,7 +45,6 @@ export const workspaceItemMachine = createMachine( } }, }, - tsTypes: {} as import("./workspacesXService.typegen").Typegen0, type: "parallel", states: { @@ -196,6 +197,7 @@ type WorkspacesEvent = export const workspacesMachine = createMachine( { + predictableActionArguments: true, tsTypes: {} as import("./workspacesXService.typegen").Typegen1, schema: { context: {} as WorkspacesContext, From 5a2088c819dabee7512e5068564a85c52dfb7bd3 Mon Sep 17 00:00:00 2001 From: Presley Pizzo Date: Mon, 12 Sep 2022 16:37:41 +0000 Subject: [PATCH 2/2] Remove layout strings --- .../xServices/templates/templatesXService.ts | 180 ++- .../xServices/workspace/workspaceXService.ts | 1092 ++++++++--------- 2 files changed, 632 insertions(+), 640 deletions(-) diff --git a/site/src/xServices/templates/templatesXService.ts b/site/src/xServices/templates/templatesXService.ts index 9b0d9484cf71b..8f59341550921 100644 --- a/site/src/xServices/templates/templatesXService.ts +++ b/site/src/xServices/templates/templatesXService.ts @@ -11,101 +11,99 @@ interface TemplatesContext { templatesError?: Error | unknown } -export const templatesMachine = - /** @xstate-layout N4IgpgJg5mDOIC5QBcwFsAOAbAhq2AysnmAHQzLICWAdlAPIBOUONVAXnlQPY2wDEEXmVoA3bgGsyFJizadqveEhAZusKopqJQAD0QAWAMwHSATgDsANgCsNgzeuOATABoQAT0QBGb89I2AAzB3oEAHH7eFtFhAL6x7qiYuPhEJORglLQMzKwcXEr8YIyM3Iyk2HgAZmVoGciyeQo8fDqq6potbfoIxqaWtvaOthZunogmRgHBgc4Wvs5mYbPxieiVqcSo9dR0ACrrKXCCwqRiktKZB8kkyqBqGlrdPsH9Zs6+VlZhxlbOBu4vAgzIFSDNgot5s4wnZViAkhs4GlthRdlBroiBMVSuUNjVGHUKBijnd2o8uioeqFAm8Pt4vj8jH8AeMEM5AjYwTMouEDGEzPTnPEEiAaNwIHA2giScjLlk6I15AVWioHp1eM9emMgb4zNMZh8wvMzH8LHDpbdZTtssTbm01U9KYgvqDmUsIt4+TYIoDECbzGZA2Y+lYjIEjIHzYdLVsyEIaGB7R1HXofOyLKQDIsrKELAYogKjL6EL4wlyZjCswYHBEozdNulsWUk+SNU6S+nM9nc-mLIXi845qQjCOjDZg3YwjC65jZS31dp294wsXl8LYkA */ - createMachine( - { - id: "templatesState", - predictableActionArguments: true, - tsTypes: {} as import("./templatesXService.typegen").Typegen0, - schema: { - context: {} as TemplatesContext, - services: {} as { - getOrganizations: { - data: TypesGen.Organization[] - } - getPermissions: { - data: boolean - } - getTemplates: { - data: TypesGen.Template[] - } - }, +export const templatesMachine = createMachine( + { + id: "templatesState", + predictableActionArguments: true, + tsTypes: {} as import("./templatesXService.typegen").Typegen0, + schema: { + context: {} as TemplatesContext, + services: {} as { + getOrganizations: { + data: TypesGen.Organization[] + } + getPermissions: { + data: boolean + } + getTemplates: { + data: TypesGen.Template[] + } }, - initial: "gettingOrganizations", - states: { - gettingOrganizations: { - entry: "clearOrganizationsError", - invoke: { - src: "getOrganizations", - id: "getOrganizations", - onDone: [ - { - actions: ["assignOrganizations", "clearOrganizationsError"], - target: "gettingTemplates", - }, - ], - onError: [ - { - actions: "assignOrganizationsError", - target: "error", - }, - ], - }, - tags: "loading", + }, + initial: "gettingOrganizations", + states: { + gettingOrganizations: { + entry: "clearOrganizationsError", + invoke: { + src: "getOrganizations", + id: "getOrganizations", + onDone: [ + { + actions: ["assignOrganizations", "clearOrganizationsError"], + target: "gettingTemplates", + }, + ], + onError: [ + { + actions: "assignOrganizationsError", + target: "error", + }, + ], }, - gettingTemplates: { - entry: "clearTemplatesError", - invoke: { - src: "getTemplates", - id: "getTemplates", - onDone: [ - { - actions: ["assignTemplates", "clearTemplatesError"], - target: "done", - }, - ], - onError: [ - { - actions: "assignTemplatesError", - target: "error", - }, - ], - }, - tags: "loading", + tags: "loading", + }, + gettingTemplates: { + entry: "clearTemplatesError", + invoke: { + src: "getTemplates", + id: "getTemplates", + onDone: [ + { + actions: ["assignTemplates", "clearTemplatesError"], + target: "done", + }, + ], + onError: [ + { + actions: "assignTemplatesError", + target: "error", + }, + ], }, - done: {}, - error: {}, + tags: "loading", }, + done: {}, + error: {}, }, - { - actions: { - assignOrganizations: assign({ - organizations: (_, event) => event.data, - }), - assignOrganizationsError: assign({ - organizationsError: (_, event) => event.data, - }), - clearOrganizationsError: assign((context) => ({ - ...context, - organizationsError: undefined, - })), - assignTemplates: assign({ - templates: (_, event) => event.data, - }), - assignTemplatesError: assign({ - templatesError: (_, event) => event.data, - }), - clearTemplatesError: (context) => assign({ ...context, getWorkspacesError: undefined }), - }, - services: { - getOrganizations: API.getOrganizations, - getTemplates: async (context) => { - if (!context.organizations || context.organizations.length === 0) { - throw new Error("no organizations") - } - return API.getTemplates(context.organizations[0].id) - }, + }, + { + actions: { + assignOrganizations: assign({ + organizations: (_, event) => event.data, + }), + assignOrganizationsError: assign({ + organizationsError: (_, event) => event.data, + }), + clearOrganizationsError: assign((context) => ({ + ...context, + organizationsError: undefined, + })), + assignTemplates: assign({ + templates: (_, event) => event.data, + }), + assignTemplatesError: assign({ + templatesError: (_, event) => event.data, + }), + clearTemplatesError: (context) => assign({ ...context, getWorkspacesError: undefined }), + }, + services: { + getOrganizations: API.getOrganizations, + getTemplates: async (context) => { + if (!context.organizations || context.organizations.length === 0) { + throw new Error("no organizations") + } + return API.getTemplates(context.organizations[0].id) }, }, - ) + }, +) diff --git a/site/src/xServices/workspace/workspaceXService.ts b/site/src/xServices/workspace/workspaceXService.ts index 88ac29ff029a0..08f5261147964 100644 --- a/site/src/xServices/workspace/workspaceXService.ts +++ b/site/src/xServices/workspace/workspaceXService.ts @@ -79,373 +79,370 @@ const permissionsToCheck = (workspace: TypesGen.Workspace) => ({ }, }) -export const workspaceMachine = - /** @xstate-layout N4IgpgJg5mDOIC5QHcD2AnA1rADgQwGMwBlAFz1LADoZTSBLAOygHUNt8iBiCVR6pgDdUmarTZZchMIlA5Usegz6yQAD0QAWAAwAmKgHYAbAFYjADgDMB80YCcu87oA0IAJ6JLARhP6Dly01dO1tzAztTAF9I1zRJThJyShowOiZWdiluMHR0DCocABsKADMMAFsU0gkOaVV5RWVGVQ0EOwMvQxNw7VsHbU1Nc1cPBEtgy0MAoIcTE20vI0to2MyEsgpqdDAS7dgAC3SAFTByos2ePgFGYVEqbd24fZOz4sp6hSV6FSR1LT1DKYLNY+o4XO5EI4DH5prpfHYAgYViA4rUiBtkg89odmC9zpQuDk8ugCm8yuhKlinni3jJfg0vj9QK0dH4gVYbPYwSNPNprFNAroDNptAYOl4kTEUWtpBixKkGMwAAo5cr0WCKPiwS78KhCETUAj7MAETAqinqzWMeD0z5NFqILx6fQWAwmOzzfzmII8hCLTSTIxB8USyxGLzLKWorKJTZVRVQc1qjXfa2E3L5fHkypGk1m1WW1M2uR21MOv3Oqiu92eyze8GjRx2OxUXSw0yaIxw8zI6PrJJbMB4CBuAqoQqFdI1GP3HbYqcy7i8XX6u5Ug7ThIfRpl36tUOTbQI8wDMxeHxGX0dcxUEUirwRJ29Nu9xexzFDkdjicL+LSWePAcv5omA6bEqSpQVAB2KbnUto7kyfx+v4h7Hqe4YXr6Sz6Heei9NYRhBJor5-uiA6zsOo7yD+zCwUQVDIHgXzMFwaiwOReAlJQ6AABRPtoACUXB9rK5HbJR36TrRb4MUxCbboyzR7o65gmJorZ8hKHQdJY2hzL6Jjered4RuYXi2JoEYkSBcoUV+ABGACu9CFBAeoQIUoHEEcACCABKRwKfaykILoR7aLeXZzIE4yqZoBi+hGenGSKgzaEGdh6SY1kxrZ4kOc5rnuZ5XDeQA8kqQW7sykLhZFcImDFjhqQlEKhboXj6AEgTpeeekSsRUZvnln6jk5LlufQHmgT5xAANIAPoACIAKIADIrUcK1VYhrRhZl9XRQGzXxYlAwGClAznuK3p2Dl-ZxvlY2FZN01cAAqkqS0+VtO1KTVoV1elDVNXFrWjANRiXUGFhmeG92iY9o1UONRVTSVADCPkAHIY+tf3lvtEXA0dsUtYlhmHneZgniebqDaspHvoOEmo25eCwJg6RLWAnkEqtG2-fBimE7ouhQ2YcJ2BK5hme0l5tR6nS4UKEbeE4d1DUzI2sy9VAc1zzA83zoFY7j63Letm3bcLwUAx1RgRR1R4RHYllOhKvrNi2uGBD4HXegjZFI7rE2zgAjo5cAJhs6CkDq1y3NQ7F4HHdF0iWCH-UhQomJ04bQnpEwB4lqk3t1Oi6Z2miekHzN2c9YfbJH0fpLH8dEpmZJQSnadvgTIW5+pEqu7Y8wim7iVePFVDjwMst8hERh1zrBVN2ALfsW3pCoDgCd6jcBpUOxu-pwP9udfoedmEYxidYRnttftF0V3yuiaG74zL1rNlicjbMRyjlvZgZBd5gS7pBCkx8d44DPrbaqOdOomFvDYRYR57DHXBrVc8VBX6DGMM2SMjNf4hzXkVZuQCEzG1SKBZcicj4QF5jQuBmcRYhQlGLKsZMlhBCDJ2CmhlcHdQRDYBYNciHSm1n-UO5CN6UO5kwgkncSRZigowk2LCQAMjtkhDhLpuGCj4QrCG8UurCPHmKPSEiRLBw-DItyFDW7MAxngRgRBCj71XIaVx7jNHaIQXtOqVhHaWBvtfMwiUAw+zvB-MugQlgr2kWQhxcinFQBcW43m4CVHdygQQHxvM-Gll2pCJ0N53R1mnldEIdhEqhKpiKPOvR3TpWyj-XKSTG6yMAjiKANILh0IPknaC1JTj4gzlo4p2c9oGBnt4OEEpF6NXaIlYUyDX5hm0sYRJpCukpJ6ccMZtJskQVINmEZBx+nvHgSUwGB0SaNWOmDRKSxlZ3iWE4YUxhJTEI6bsyS6Q-JwFQI5dARBYDxkBcC0F4LPGHzuLQIFsAQVgrgOfXRFhOjvzbD4XopjjC+jrMTEyfJvTmUajsuxX5qJSSgEilF4LIXMHpTCuAJzVFQMRdC1FxZJlZ3LIsMyrYgjeHmN6aEBKn5u0uueDCsy1IM0kSQqlVFxy0pZTy2SzEoCsRTskTi3EeJzyEjY+uT0AXMu5Yyxi2r0X7jFFi8y5gIgBFUosSwvp35Q1wqeBwsyAxtN+Q9FVVAGDlF5kweUaRmAACEXrakGV4hiw1OmhvoOGqSUaExxomrABA+p8lNAANraAALp2sdLFW8x4P7iLmA2SElgERUCsH7PQbsF4-KVX8kNYaI26loNm+N7LcmVFNavUcfbM1MqgDm1yeaC0UFTCW8tNzpmVscNWustbGr1sJRGKGFcxaVNsLoSlLMvxTsjVQQoqBhyQDnRACF6NQJrTKj5JaC0ACyZU-IrQWjG96ABJNaS1iAVuQr0Ks15vmEVmV4T1jsWwV2njFWV38g2I17em-t1Bb33ogI+59b0-0ADE-3EAABILSOEBr960gPYxtqwnRgTGpUAlOZJtstOqy09f6ltsJRQRmFGe9pwaL2Tpw9O-DjDCPxpvXeiA6Qv0YDAERuFwzx2pqvbqWTD6FOyZU2poj+bD6FuXWWiDiwPQcfCB0AYEQ5iGU9SeZDsIwxHiCGJzDtjJNpozde-T8nc2KeHMZ7YGnlGnPOdp-5um8NKYM6FozzBVORfjWZ4QFm+Arus-YZBI8HMf1MHMYYT9oSTCPUMMMIQfPdok1QZRXAADim0FosF-XNYgSofJ4wg+0ToboeiggGEMQl79kEoW822R2PhA0Naw6BNrRwOtdZ6315jfK2EAx9G1AITpWywjzt4fw3RohSkYKgRhvK4vJBfRBvbowAgWCO01XF-gu13azcBGMEHwxO00mEMMnUwwmAmz4WewZb5+sIhS8TS2Lm9KuRM-xtynu8nfgKAMnGWkInPTOpMhYtT-c4dWQicsTzg6flYCK039oM4w4tvzDcLUZCZkj37W410CvVlu26dbfBYQ-rPO8wQP7dk7AT81NKuf-htfJHn7CQgXRsJlR8YpVLGMQBTy678RFWBfAjlnMu1Vy6INZ8X-Od2hKF21POOETJ1kakKaE0v-56we0rgGD485Q7hKyewftqcQ26BdOecwPnYvd-Y-WnMFEmwg22OZSDwwIgfPUs6ukugigIuGCwNcY-JMAWk9uSeVdHaiXTd+7rS4iiET1MWrT2g9mN2aj369N4xxgUnwIL9U8Z4z41T1SVBM9VmdLXw78i97JL8AqA1DrksYCZW8y1u3a7rtyYptY+m3BAn44axKb-kAMcfPjJ7je8p7hGn7wCJh9tWnmYUXIoljzF8KpL7x+Q2n7nE8Q5rwmwvejsuCmUt8syz85kLyboDeOg7qzqzYM+KML0lu0qR426G+tuDaCAYQ0S94Yo8q08revm7eEksulqyKrKEKg6UKlBPK1mfO6BAum+2Boql0ooD86utgSB5BdKVqcAWqiuy+tyD4UGRW0sCIuchE+6xK7y6sryR+Ui-yvBGq4KqB6kTBNue6j+syl0sUoowQ4sSBCWxUqOUyAqH+uCjgD4nGQIQo+6IuralkwosssyxBzOpBl60m16NBsa8aSe+uXCru0swoiwWCoUt8w8wYkecOiq32rOJhwWRGph1mCI6kt8oh5khEYUYo-GO+FcdYAQ50hExh3hemSWIW86YWymaWJm-h3uuiYYqEGBgu2B4scIY+OgHa0InYTO8R5qiRFRRGDBO+mhmB2hjYjUL80wQQcwxgUQbeE6AWuGDBAw6+rRnq4wnQThE8YYHUcIM+luwo6xLBZ0jur+ToAcOgqkBOyilugiYxGx+2hhsBHUPgAYeg561m5WEMN4uEecQYp24scwF2kQQAA */ - createMachine( - { - id: "workspaceState", - predictableActionArguments: true, - tsTypes: {} as import("./workspaceXService.typegen").Typegen0, - schema: { - context: {} as WorkspaceContext, - events: {} as WorkspaceEvent, - services: {} as { - getWorkspace: { - data: TypesGen.Workspace - } - getTemplate: { - data: TypesGen.Template - } - startWorkspace: { - data: TypesGen.WorkspaceBuild - } - stopWorkspace: { - data: TypesGen.WorkspaceBuild - } - deleteWorkspace: { - data: TypesGen.WorkspaceBuild - } - cancelWorkspace: { - data: Types.Message - } - refreshWorkspace: { - data: TypesGen.Workspace | undefined - } - getResources: { - data: TypesGen.WorkspaceResource[] - } - getBuilds: { - data: TypesGen.WorkspaceBuild[] - } - loadMoreBuilds: { - data: TypesGen.WorkspaceBuild[] - } - checkPermissions: { - data: TypesGen.UserAuthorizationResponse - } - }, +export const workspaceMachine = createMachine( + { + id: "workspaceState", + predictableActionArguments: true, + tsTypes: {} as import("./workspaceXService.typegen").Typegen0, + schema: { + context: {} as WorkspaceContext, + events: {} as WorkspaceEvent, + services: {} as { + getWorkspace: { + data: TypesGen.Workspace + } + getTemplate: { + data: TypesGen.Template + } + startWorkspace: { + data: TypesGen.WorkspaceBuild + } + stopWorkspace: { + data: TypesGen.WorkspaceBuild + } + deleteWorkspace: { + data: TypesGen.WorkspaceBuild + } + cancelWorkspace: { + data: Types.Message + } + refreshWorkspace: { + data: TypesGen.Workspace | undefined + } + getResources: { + data: TypesGen.WorkspaceResource[] + } + getBuilds: { + data: TypesGen.WorkspaceBuild[] + } + loadMoreBuilds: { + data: TypesGen.WorkspaceBuild[] + } + checkPermissions: { + data: TypesGen.UserAuthorizationResponse + } }, - initial: "idle", - on: { - GET_WORKSPACE: { - target: ".gettingWorkspace", - internal: false, - }, + }, + initial: "idle", + on: { + GET_WORKSPACE: { + target: ".gettingWorkspace", + internal: false, + }, + }, + states: { + idle: { + tags: "loading", }, - states: { - idle: { - tags: "loading", + gettingWorkspace: { + entry: ["clearGetWorkspaceError", "clearContext"], + invoke: { + src: "getWorkspace", + id: "getWorkspace", + onDone: [ + { + actions: "assignWorkspace", + target: "refreshingTemplate", + }, + ], + onError: [ + { + actions: "assignGetWorkspaceError", + target: "error", + }, + ], }, - gettingWorkspace: { - entry: ["clearGetWorkspaceError", "clearContext"], - invoke: { - src: "getWorkspace", - id: "getWorkspace", - onDone: [ - { - actions: "assignWorkspace", - target: "refreshingTemplate", - }, - ], - onError: [ - { - actions: "assignGetWorkspaceError", - target: "error", - }, - ], - }, - tags: "loading", + tags: "loading", + }, + refreshingTemplate: { + entry: "clearRefreshTemplateError", + invoke: { + src: "getTemplate", + id: "refreshTemplate", + onDone: [ + { + actions: "assignTemplate", + target: "gettingPermissions", + }, + ], + onError: [ + { + actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], + target: "error", + }, + ], }, - refreshingTemplate: { - entry: "clearRefreshTemplateError", - invoke: { - src: "getTemplate", - id: "refreshTemplate", - onDone: [ - { - actions: "assignTemplate", - target: "gettingPermissions", - }, - ], - onError: [ - { - actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], - target: "error", - }, - ], - }, - tags: "loading", + tags: "loading", + }, + gettingPermissions: { + entry: "clearGetPermissionsError", + invoke: { + src: "checkPermissions", + id: "checkPermissions", + onDone: [ + { + actions: "assignPermissions", + target: "ready", + }, + ], + onError: [ + { + actions: "assignGetPermissionsError", + target: "error", + }, + ], }, - gettingPermissions: { - entry: "clearGetPermissionsError", - invoke: { - src: "checkPermissions", - id: "checkPermissions", - onDone: [ - { - actions: "assignPermissions", - target: "ready", + }, + ready: { + type: "parallel", + states: { + pollingWorkspace: { + initial: "refreshingWorkspace", + states: { + refreshingWorkspace: { + entry: "clearRefreshWorkspaceError", + invoke: { + src: "refreshWorkspace", + id: "refreshWorkspace", + onDone: [ + { + actions: ["refreshTimeline", "assignWorkspace"], + target: "waiting", + }, + ], + onError: [ + { + actions: "assignRefreshWorkspaceError", + target: "waiting", + }, + ], + }, }, - ], - onError: [ - { - actions: "assignGetPermissionsError", - target: "error", + waiting: { + after: { + "1000": { + target: "refreshingWorkspace", + }, + }, }, - ], + }, }, - }, - ready: { - type: "parallel", - states: { - pollingWorkspace: { - initial: "refreshingWorkspace", - states: { - refreshingWorkspace: { - entry: "clearRefreshWorkspaceError", - invoke: { - src: "refreshWorkspace", - id: "refreshWorkspace", - onDone: [ - { - actions: ["refreshTimeline", "assignWorkspace"], - target: "waiting", - }, - ], - onError: [ - { - actions: "assignRefreshWorkspaceError", - target: "waiting", - }, - ], + build: { + initial: "idle", + states: { + idle: { + on: { + START: { + target: "requestingStart", + }, + STOP: { + target: "requestingStop", + }, + ASK_DELETE: { + target: "askingDelete", + }, + UPDATE: { + target: "refreshingTemplate", + }, + CANCEL: { + target: "requestingCancel", }, }, - waiting: { - after: { - "1000": { - target: "refreshingWorkspace", - }, + }, + askingDelete: { + on: { + DELETE: { + target: "requestingDelete", + }, + CANCEL_DELETE: { + target: "idle", }, }, }, - }, - build: { - initial: "idle", - states: { - idle: { - on: { - START: { - target: "requestingStart", - }, - STOP: { - target: "requestingStop", + requestingStart: { + entry: "clearBuildError", + invoke: { + src: "startWorkspace", + id: "startWorkspace", + onDone: [ + { + actions: ["assignBuild", "refreshTimeline"], + target: "idle", }, - ASK_DELETE: { - target: "askingDelete", + ], + onError: [ + { + actions: "assignBuildError", + target: "idle", }, - UPDATE: { - target: "refreshingTemplate", + ], + }, + }, + requestingStop: { + entry: "clearBuildError", + invoke: { + src: "stopWorkspace", + id: "stopWorkspace", + onDone: [ + { + actions: ["assignBuild", "refreshTimeline"], + target: "idle", }, - CANCEL: { - target: "requestingCancel", + ], + onError: [ + { + actions: "assignBuildError", + target: "idle", }, - }, + ], }, - askingDelete: { - on: { - DELETE: { - target: "requestingDelete", + }, + requestingDelete: { + entry: "clearBuildError", + invoke: { + src: "deleteWorkspace", + id: "deleteWorkspace", + onDone: [ + { + actions: ["assignBuild", "refreshTimeline"], + target: "idle", }, - CANCEL_DELETE: { + ], + onError: [ + { + actions: "assignBuildError", target: "idle", }, - }, + ], }, - requestingStart: { - entry: "clearBuildError", - invoke: { - src: "startWorkspace", - id: "startWorkspace", - onDone: [ - { - actions: ["assignBuild", "refreshTimeline"], - target: "idle", - }, - ], - onError: [ - { - actions: "assignBuildError", - target: "idle", - }, - ], - }, - }, - requestingStop: { - entry: "clearBuildError", - invoke: { - src: "stopWorkspace", - id: "stopWorkspace", - onDone: [ - { - actions: ["assignBuild", "refreshTimeline"], - target: "idle", - }, - ], - onError: [ - { - actions: "assignBuildError", - target: "idle", - }, - ], - }, + }, + requestingCancel: { + entry: ["clearCancellationMessage", "clearCancellationError"], + invoke: { + src: "cancelWorkspace", + id: "cancelWorkspace", + onDone: [ + { + actions: [ + "assignCancellationMessage", + "displayCancellationMessage", + "refreshTimeline", + ], + target: "idle", + }, + ], + onError: [ + { + actions: "assignCancellationError", + target: "idle", + }, + ], }, - requestingDelete: { - entry: "clearBuildError", - invoke: { - src: "deleteWorkspace", - id: "deleteWorkspace", - onDone: [ - { - actions: ["assignBuild", "refreshTimeline"], - target: "idle", - }, - ], - onError: [ - { - actions: "assignBuildError", - target: "idle", - }, - ], - }, + }, + refreshingTemplate: { + entry: "clearRefreshTemplateError", + invoke: { + src: "getTemplate", + id: "refreshTemplate", + onDone: [ + { + actions: "assignTemplate", + target: "requestingStart", + }, + ], + onError: [ + { + actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], + target: "idle", + }, + ], }, - requestingCancel: { - entry: ["clearCancellationMessage", "clearCancellationError"], - invoke: { - src: "cancelWorkspace", - id: "cancelWorkspace", - onDone: [ - { - actions: [ - "assignCancellationMessage", - "displayCancellationMessage", - "refreshTimeline", - ], - target: "idle", - }, - ], - onError: [ - { - actions: "assignCancellationError", - target: "idle", - }, - ], - }, + }, + }, + }, + pollingResources: { + initial: "gettingResources", + states: { + gettingResources: { + entry: "clearGetResourcesError", + invoke: { + src: "getResources", + id: "getResources", + onDone: [ + { + actions: "assignResources", + target: "waiting", + }, + ], + onError: [ + { + actions: "assignGetResourcesError", + target: "waiting", + }, + ], }, - refreshingTemplate: { - entry: "clearRefreshTemplateError", - invoke: { - src: "getTemplate", - id: "refreshTemplate", - onDone: [ - { - actions: "assignTemplate", - target: "requestingStart", - }, - ], - onError: [ - { - actions: ["assignRefreshTemplateError", "displayRefreshTemplateError"], - target: "idle", - }, - ], + }, + waiting: { + after: { + "5000": { + target: "gettingResources", }, }, }, }, - pollingResources: { - initial: "gettingResources", - states: { - gettingResources: { - entry: "clearGetResourcesError", - invoke: { - src: "getResources", - id: "getResources", - onDone: [ - { - actions: "assignResources", - target: "waiting", - }, - ], - onError: [ - { - actions: "assignGetResourcesError", - target: "waiting", - }, - ], - }, - }, - waiting: { - after: { - "5000": { - target: "gettingResources", + }, + timeline: { + initial: "gettingBuilds", + states: { + idle: {}, + gettingBuilds: { + entry: "clearGetBuildsError", + invoke: { + src: "getBuilds", + onDone: [ + { + actions: "assignBuilds", + target: "loadedBuilds", }, - }, + ], + onError: [ + { + actions: "assignGetBuildsError", + target: "idle", + }, + ], }, }, - }, - timeline: { - initial: "gettingBuilds", - states: { - idle: {}, - gettingBuilds: { - entry: "clearGetBuildsError", - invoke: { - src: "getBuilds", - onDone: [ - { - actions: "assignBuilds", - target: "loadedBuilds", + loadedBuilds: { + initial: "idle", + states: { + idle: { + on: { + LOAD_MORE_BUILDS: { + cond: "hasMoreBuilds", + target: "loadingMoreBuilds", }, - ], - onError: [ - { - actions: "assignGetBuildsError", - target: "idle", + REFRESH_TIMELINE: { + target: "#workspaceState.ready.timeline.gettingBuilds", }, - ], + }, }, - }, - loadedBuilds: { - initial: "idle", - states: { - idle: { - on: { - LOAD_MORE_BUILDS: { - cond: "hasMoreBuilds", - target: "loadingMoreBuilds", + loadingMoreBuilds: { + entry: "clearLoadMoreBuildsError", + invoke: { + src: "loadMoreBuilds", + onDone: [ + { + actions: "assignNewBuilds", + target: "idle", }, - REFRESH_TIMELINE: { - target: "#workspaceState.ready.timeline.gettingBuilds", + ], + onError: [ + { + actions: "assignLoadMoreBuildsError", + target: "idle", }, - }, - }, - loadingMoreBuilds: { - entry: "clearLoadMoreBuildsError", - invoke: { - src: "loadMoreBuilds", - onDone: [ - { - actions: "assignNewBuilds", - target: "idle", - }, - ], - onError: [ - { - actions: "assignLoadMoreBuildsError", - target: "idle", - }, - ], - }, + ], }, }, }, @@ -453,236 +450,233 @@ export const workspaceMachine = }, }, }, - error: { - on: { - GET_WORKSPACE: { - target: "gettingWorkspace", - }, + }, + error: { + on: { + GET_WORKSPACE: { + target: "gettingWorkspace", }, }, }, }, - { - actions: { - // Clear data about an old workspace when looking at a new one - clearContext: () => - assign({ - workspace: undefined, - template: undefined, - build: undefined, - permissions: undefined, - }), - assignWorkspace: assign({ - workspace: (_, event) => event.data, - }), - assignGetWorkspaceError: assign({ - getWorkspaceError: (_, event) => event.data, - }), - clearGetWorkspaceError: (context) => assign({ ...context, getWorkspaceError: undefined }), - assignTemplate: assign({ - template: (_, event) => event.data, - }), - assignPermissions: assign({ - // Setting event.data as Permissions to be more stricted. So we know - // what permissions we asked for. - permissions: (_, event) => event.data as Permissions, - }), - assignGetPermissionsError: assign({ - checkPermissionsError: (_, event) => event.data, - }), - clearGetPermissionsError: assign({ - checkPermissionsError: (_) => undefined, - }), - assignBuild: assign({ - build: (_, event) => event.data, - }), - assignBuildError: assign({ - buildError: (_, event) => event.data, - }), - clearBuildError: assign({ - buildError: (_) => undefined, - }), - assignCancellationMessage: assign({ - cancellationMessage: (_, event) => event.data, - }), - clearCancellationMessage: assign({ - cancellationMessage: (_) => undefined, - }), - displayCancellationMessage: (context) => { - if (context.cancellationMessage) { - displaySuccess(context.cancellationMessage.message) - } - }, - assignCancellationError: assign({ - cancellationError: (_, event) => event.data, - }), - clearCancellationError: assign({ - cancellationError: (_) => undefined, - }), - assignRefreshWorkspaceError: assign({ - refreshWorkspaceError: (_, event) => event.data, - }), - clearRefreshWorkspaceError: assign({ - refreshWorkspaceError: (_) => undefined, - }), - assignRefreshTemplateError: assign({ - refreshTemplateError: (_, event) => event.data, - }), - displayRefreshTemplateError: () => { - displayError(Language.refreshTemplateError) - }, - clearRefreshTemplateError: assign({ - refreshTemplateError: (_) => undefined, - }), - // Resources - assignResources: assign({ - resources: (_, event) => event.data, - }), - assignGetResourcesError: assign({ - getResourcesError: (_, event) => event.data, - }), - clearGetResourcesError: assign({ - getResourcesError: (_) => undefined, - }), - // Timeline - assignBuilds: assign({ - builds: (_, event) => event.data, - }), - assignGetBuildsError: assign({ - getBuildsError: (_, event) => event.data, - }), - clearGetBuildsError: assign({ - getBuildsError: (_) => undefined, + }, + { + actions: { + // Clear data about an old workspace when looking at a new one + clearContext: () => + assign({ + workspace: undefined, + template: undefined, + build: undefined, + permissions: undefined, }), - assignNewBuilds: assign({ - builds: (context, event) => { - const oldBuilds = context.builds - - if (!oldBuilds) { - // This state is theoretically impossible, but helps TS - throw new Error("workspaceXService: failed to load workspace builds") - } + assignWorkspace: assign({ + workspace: (_, event) => event.data, + }), + assignGetWorkspaceError: assign({ + getWorkspaceError: (_, event) => event.data, + }), + clearGetWorkspaceError: (context) => assign({ ...context, getWorkspaceError: undefined }), + assignTemplate: assign({ + template: (_, event) => event.data, + }), + assignPermissions: assign({ + // Setting event.data as Permissions to be more stricted. So we know + // what permissions we asked for. + permissions: (_, event) => event.data as Permissions, + }), + assignGetPermissionsError: assign({ + checkPermissionsError: (_, event) => event.data, + }), + clearGetPermissionsError: assign({ + checkPermissionsError: (_) => undefined, + }), + assignBuild: assign({ + build: (_, event) => event.data, + }), + assignBuildError: assign({ + buildError: (_, event) => event.data, + }), + clearBuildError: assign({ + buildError: (_) => undefined, + }), + assignCancellationMessage: assign({ + cancellationMessage: (_, event) => event.data, + }), + clearCancellationMessage: assign({ + cancellationMessage: (_) => undefined, + }), + displayCancellationMessage: (context) => { + if (context.cancellationMessage) { + displaySuccess(context.cancellationMessage.message) + } + }, + assignCancellationError: assign({ + cancellationError: (_, event) => event.data, + }), + clearCancellationError: assign({ + cancellationError: (_) => undefined, + }), + assignRefreshWorkspaceError: assign({ + refreshWorkspaceError: (_, event) => event.data, + }), + clearRefreshWorkspaceError: assign({ + refreshWorkspaceError: (_) => undefined, + }), + assignRefreshTemplateError: assign({ + refreshTemplateError: (_, event) => event.data, + }), + displayRefreshTemplateError: () => { + displayError(Language.refreshTemplateError) + }, + clearRefreshTemplateError: assign({ + refreshTemplateError: (_) => undefined, + }), + // Resources + assignResources: assign({ + resources: (_, event) => event.data, + }), + assignGetResourcesError: assign({ + getResourcesError: (_, event) => event.data, + }), + clearGetResourcesError: assign({ + getResourcesError: (_) => undefined, + }), + // Timeline + assignBuilds: assign({ + builds: (_, event) => event.data, + }), + assignGetBuildsError: assign({ + getBuildsError: (_, event) => event.data, + }), + clearGetBuildsError: assign({ + getBuildsError: (_) => undefined, + }), + assignNewBuilds: assign({ + builds: (context, event) => { + const oldBuilds = context.builds - return [...oldBuilds, ...event.data] - }, - }), - assignLoadMoreBuildsError: assign({ - loadMoreBuildsError: (_, event) => event.data, - }), - clearLoadMoreBuildsError: assign({ - loadMoreBuildsError: (_) => undefined, - }), - refreshTimeline: pure((context, event) => { - // No need to refresh the timeline if it is not loaded - if (!context.builds) { - return + if (!oldBuilds) { + // This state is theoretically impossible, but helps TS + throw new Error("workspaceXService: failed to load workspace builds") } - // When it is a refresh workspace event, we want to check if the latest - // build was updated to not over fetch the builds - if (event.type === "done.invoke.refreshWorkspace") { - const latestBuildInTimeline = latestBuild(context.builds) - const isUpdated = - event.data?.latest_build.updated_at !== latestBuildInTimeline.updated_at - if (isUpdated) { - return send({ type: "REFRESH_TIMELINE" }) - } - } else { + + return [...oldBuilds, ...event.data] + }, + }), + assignLoadMoreBuildsError: assign({ + loadMoreBuildsError: (_, event) => event.data, + }), + clearLoadMoreBuildsError: assign({ + loadMoreBuildsError: (_) => undefined, + }), + refreshTimeline: pure((context, event) => { + // No need to refresh the timeline if it is not loaded + if (!context.builds) { + return + } + // When it is a refresh workspace event, we want to check if the latest + // build was updated to not over fetch the builds + if (event.type === "done.invoke.refreshWorkspace") { + const latestBuildInTimeline = latestBuild(context.builds) + const isUpdated = event.data?.latest_build.updated_at !== latestBuildInTimeline.updated_at + if (isUpdated) { return send({ type: "REFRESH_TIMELINE" }) } - }), + } else { + return send({ type: "REFRESH_TIMELINE" }) + } + }), + }, + guards: { + hasMoreBuilds: (_) => false, + }, + services: { + getWorkspace: async (_, event) => { + return await API.getWorkspaceByOwnerAndName(event.username, event.workspaceName, { + include_deleted: true, + }) + }, + getTemplate: async (context) => { + if (context.workspace) { + return await API.getTemplate(context.workspace.template_id) + } else { + throw Error("Cannot get template without workspace") + } + }, + startWorkspace: async (context) => { + if (context.workspace) { + return await API.startWorkspace(context.workspace.id, context.template?.active_version_id) + } else { + throw Error("Cannot start workspace without workspace id") + } }, - guards: { - hasMoreBuilds: (_) => false, + stopWorkspace: async (context) => { + if (context.workspace) { + return await API.stopWorkspace(context.workspace.id) + } else { + throw Error("Cannot stop workspace without workspace id") + } }, - services: { - getWorkspace: async (_, event) => { - return await API.getWorkspaceByOwnerAndName(event.username, event.workspaceName, { - include_deleted: true, + deleteWorkspace: async (context) => { + if (context.workspace) { + return await API.deleteWorkspace(context.workspace.id) + } else { + throw Error("Cannot delete workspace without workspace id") + } + }, + cancelWorkspace: async (context) => { + if (context.workspace) { + return await API.cancelWorkspaceBuild(context.workspace.latest_build.id) + } else { + throw Error("Cannot cancel workspace without build id") + } + }, + refreshWorkspace: async (context) => { + if (context.workspace) { + return await API.getWorkspaceByOwnerAndName( + context.workspace.owner_name, + context.workspace.name, + { + include_deleted: true, + }, + ) + } else { + throw Error("Cannot refresh workspace without id") + } + }, + getResources: async (context) => { + // If the job hasn't completed, fetching resources will result + // in an unfriendly error for the user. + if (!context.workspace?.latest_build.job.completed_at) { + return [] + } + const resources = await API.getWorkspaceResources(context.workspace.latest_build.id) + return resources + }, + getBuilds: async (context) => { + if (context.workspace) { + return await API.getWorkspaceBuilds(context.workspace.id) + } else { + throw Error("Cannot get builds without id") + } + }, + loadMoreBuilds: async (context) => { + if (context.workspace) { + return await API.getWorkspaceBuilds(context.workspace.id) + } else { + throw Error("Cannot load more builds without id") + } + }, + checkPermissions: async (context) => { + if (context.workspace && context.userId) { + return await API.checkUserPermissions(context.userId, { + checks: permissionsToCheck(context.workspace), }) - }, - getTemplate: async (context) => { - if (context.workspace) { - return await API.getTemplate(context.workspace.template_id) - } else { - throw Error("Cannot get template without workspace") - } - }, - startWorkspace: async (context) => { - if (context.workspace) { - return await API.startWorkspace( - context.workspace.id, - context.template?.active_version_id, - ) - } else { - throw Error("Cannot start workspace without workspace id") - } - }, - stopWorkspace: async (context) => { - if (context.workspace) { - return await API.stopWorkspace(context.workspace.id) - } else { - throw Error("Cannot stop workspace without workspace id") - } - }, - deleteWorkspace: async (context) => { - if (context.workspace) { - return await API.deleteWorkspace(context.workspace.id) - } else { - throw Error("Cannot delete workspace without workspace id") - } - }, - cancelWorkspace: async (context) => { - if (context.workspace) { - return await API.cancelWorkspaceBuild(context.workspace.latest_build.id) - } else { - throw Error("Cannot cancel workspace without build id") - } - }, - refreshWorkspace: async (context) => { - if (context.workspace) { - return await API.getWorkspaceByOwnerAndName( - context.workspace.owner_name, - context.workspace.name, - { - include_deleted: true, - }, - ) - } else { - throw Error("Cannot refresh workspace without id") - } - }, - getResources: async (context) => { - // If the job hasn't completed, fetching resources will result - // in an unfriendly error for the user. - if (!context.workspace?.latest_build.job.completed_at) { - return [] - } - const resources = await API.getWorkspaceResources(context.workspace.latest_build.id) - return resources - }, - getBuilds: async (context) => { - if (context.workspace) { - return await API.getWorkspaceBuilds(context.workspace.id) - } else { - throw Error("Cannot get builds without id") - } - }, - loadMoreBuilds: async (context) => { - if (context.workspace) { - return await API.getWorkspaceBuilds(context.workspace.id) - } else { - throw Error("Cannot load more builds without id") - } - }, - checkPermissions: async (context) => { - if (context.workspace && context.userId) { - return await API.checkUserPermissions(context.userId, { - checks: permissionsToCheck(context.workspace), - }) - } else { - throw Error("Cannot check permissions without both workspace and user id") - } - }, + } else { + throw Error("Cannot check permissions without both workspace and user id") + } }, }, - ) + }, +) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy