mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: refactor workspace count to single route (#4809)
Co-authored-by: Presley Pizzo <presley@coder.com>
This commit is contained in:
co-authored by
Presley Pizzo
parent
5fb9c33ecd
commit
766a2ad590
+2
-10
@@ -298,17 +298,9 @@ export const getURLWithSearchParams = (
|
||||
|
||||
export const getWorkspaces = async (
|
||||
options: TypesGen.WorkspacesRequest,
|
||||
): Promise<TypesGen.Workspace[]> => {
|
||||
): Promise<TypesGen.WorkspacesResponse> => {
|
||||
const url = getURLWithSearchParams("/api/v2/workspaces", options)
|
||||
const response = await axios.get<TypesGen.Workspace[]>(url)
|
||||
return response.data
|
||||
}
|
||||
|
||||
export const getWorkspacesCount = async (
|
||||
options: TypesGen.WorkspaceCountRequest,
|
||||
): Promise<TypesGen.WorkspaceCountResponse> => {
|
||||
const url = getURLWithSearchParams("/api/v2/workspaces/count", options)
|
||||
const response = await axios.get(url)
|
||||
const response = await axios.get<TypesGen.WorkspacesResponse>(url)
|
||||
return response.data
|
||||
}
|
||||
|
||||
|
||||
@@ -883,16 +883,6 @@ export interface WorkspaceBuildsRequest extends Pagination {
|
||||
readonly Since: string
|
||||
}
|
||||
|
||||
// From codersdk/workspaces.go
|
||||
export interface WorkspaceCountRequest {
|
||||
readonly q?: string
|
||||
}
|
||||
|
||||
// From codersdk/workspaces.go
|
||||
export interface WorkspaceCountResponse {
|
||||
readonly count: number
|
||||
}
|
||||
|
||||
// From codersdk/workspaces.go
|
||||
export interface WorkspaceFilter {
|
||||
readonly q?: string
|
||||
@@ -935,6 +925,12 @@ export interface WorkspacesRequest extends Pagination {
|
||||
readonly q?: string
|
||||
}
|
||||
|
||||
// From codersdk/workspaces.go
|
||||
export interface WorkspacesResponse {
|
||||
readonly workspaces: Workspace[]
|
||||
readonly count: number
|
||||
}
|
||||
|
||||
// From codersdk/apikey.go
|
||||
export type APIKeyScope = "all" | "application_connect"
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ describe("WorkspacesPage", () => {
|
||||
// Given
|
||||
server.use(
|
||||
rest.get("/api/v2/workspaces", async (req, res, ctx) => {
|
||||
return res(ctx.status(200), ctx.json([]))
|
||||
return res(ctx.status(200), ctx.json({ workspaces: [], count: 0 }))
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -53,6 +53,6 @@ describe("WorkspacesPage", () => {
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
)
|
||||
await screen.findByText(MockWorkspace.name)
|
||||
await screen.findByText(`${MockWorkspace.name}1`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FieldError } from "api/errors"
|
||||
import { everyOneGroup } from "util/groups"
|
||||
import * as Types from "../api/types"
|
||||
import * as TypesGen from "../api/typesGenerated"
|
||||
import { range } from "lodash"
|
||||
|
||||
export const MockTemplateDAUResponse: TypesGen.TemplateDAUsResponse = {
|
||||
entries: [
|
||||
@@ -523,6 +524,16 @@ export const MockPendingWorkspace: TypesGen.Workspace = {
|
||||
},
|
||||
}
|
||||
|
||||
// just over one page of workspaces
|
||||
export const MockWorkspacesResponse: TypesGen.WorkspacesResponse = {
|
||||
workspaces: range(1, 27).map((id: number) => ({
|
||||
...MockWorkspace,
|
||||
id: id.toString(),
|
||||
name: `${MockWorkspace.name}${id}`,
|
||||
})),
|
||||
count: 26,
|
||||
}
|
||||
|
||||
// requests the MockWorkspace
|
||||
export const MockWorkspaceRequest: TypesGen.CreateWorkspaceRequest = {
|
||||
name: "test",
|
||||
@@ -530,10 +541,6 @@ export const MockWorkspaceRequest: TypesGen.CreateWorkspaceRequest = {
|
||||
template_id: "test-template",
|
||||
}
|
||||
|
||||
export const MockWorkspaceCountResponse: TypesGen.WorkspaceCountResponse = {
|
||||
count: 26, // just over 1 page
|
||||
}
|
||||
|
||||
export const MockUserAgent: Types.UserAgent = {
|
||||
browser: "Chrome 99.0.4844",
|
||||
device: "Other",
|
||||
|
||||
@@ -138,11 +138,7 @@ export const handlers = [
|
||||
|
||||
// workspaces
|
||||
rest.get("/api/v2/workspaces", async (req, res, ctx) => {
|
||||
return res(ctx.status(200), ctx.json([M.MockWorkspace]))
|
||||
}),
|
||||
// has to come before the parameterized endpoints
|
||||
rest.get("/api/v2/workspaces/count", async (req, res, ctx) => {
|
||||
return res(ctx.status(200), ctx.json(M.MockWorkspaceCountResponse))
|
||||
return res(ctx.status(200), ctx.json(M.MockWorkspacesResponse))
|
||||
}),
|
||||
rest.get("/api/v2/workspaces/:workspaceId", async (req, res, ctx) => {
|
||||
return res(ctx.status(200), ctx.json(M.MockWorkspace))
|
||||
|
||||
@@ -226,7 +226,7 @@ type WorkspacesEvent =
|
||||
| { type: "UPDATE_FILTER"; query?: string }
|
||||
|
||||
export const workspacesMachine =
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QHcD2AnA1rADgQwGM4BlAFz1LADoDUBXAO1KplNIEsGoBhepgYgioG1TgDdUmaqwDqGbPiKxejUgG0ADAF1EoHKljsOw3SAAeiAIyWNVAMwA2AJwAOACyWnAJjsuvGty8AGhAAT0QfWxcAVm9ohwcXAHYkp0sXFwBfTJC0LFxCEnJKGj5mVg4uFQEwdHQMKhwAGwoAMwwAWxYwUjl8xThq9W1TfUNjBlMLBDsnaKovaMtfDQ00jLckhxDwhEiqGO9-OxPZk69s3PkCpTIKalpVfgBVAAUAEQBBABUAUQB9ABiAEkADJ-ABKmh0SBAYyM7BMsOmbm8VA00Q0KRcli2di86TcOwiDioDk8DjcMS8Lm8dg0LgclxAeQUhVgdxKrJucCosHI6EqUFeeCgnAoiIY-GhowMCKRoGmAFocU57J4vG58VSMqliQglR4FmsvF5sX5XMloszuQMOcVqLb2d02JwoH02UpBMJRAwJFIXR6ebAZbD4RMpoglfF5gSGWt8ZYdZZ9ekXFQktEXI58dn3B4LjkWdc7ZzHSXnRU3UG7d6RFRxJJpD0a+y1JYYXo5RHkVHGZYqE43AEYgnnNE7PqaUl0dFTU4NA5Ui41m4bRXbg6qE6lC6ha2vbV6uhGi1SO10F1ZBu4KGu+NJZGDdFAmTacscTSnLn9RkFvS-CTKlNmia0ix3Ip7m3G9YCoOgcAgCUuAPMAITAVpYDrX1-WoeDEMoFC0Iwu84W7R9ewNelSQ0JNyQ0Al4hsE59XOKg3GHId0gcHwkgyMCrn6dky2gwTd2QPAjG+VAiPQOAAAsUMwsx+SgvBWkodAAApMVWABKfgIPtKDDO3CTSCkmT5MUkjw3IxUoznGdVksHw7FA1xZicFi1QcRccVpAleIcF911EyCuRgl4Ph+AFXk+ABxX4bLIhVzAc78DjsawHDc7wdW2MIo2WNVeNNTMaTNLLF1Cz1wrAKKvj+f4ADVfghYhgQAeQAOWSh9UumWYM2cWjVixdxJ0Kg1NXmXzEhcjF3Bo7IiwYVAIDgUxDOEx4mAbCAmjAWV+smCj-HTLK50xZxFg0WZgimxwSrcSkkheuY3GiJJCwE2qjJKXbyh6IUhmO+VTvshBuIORJKQJHx4esKcfOOfwEi-OxUhq4MdrKMGe0hpMYcZQIXMTAkXP1JVoZWNyGSTQkMX44swv+8tWb5AUhRFMUGAlVLbIGvtGSoSxYj8LNPretIqaTWwvG-JwcvYrxfJfH6Wb+4STKrZCYPxuy0oNWlYxiNyTi1fx0inUlYnJJwHY8dwJ3ibHSy3Ey8KQ90byI+AwxSiGjaVJJrCoJYGUCF9s3xFjUTJD7VdcdItjFt2hI9mDTMk6T0Nk2AFP1gOTqfJU3IHb7UmxSI3qxFi7AWKuFbSBImacdPN2Mov73B0uhwbmkXYt-EaJcKn5wWRXuN4r6XNAju6oNoWDQdgdB-NuxLdHqmsvTBXZm4lyMgpJkVqAA */
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QHcD2AnA1rADgQwGM4BlAFz1LADpZz1SBLAOygAU8pmKHUmBiANoAGALqJQOVLAaNe4kAA9EAWgAcANnVUAzAEYATOoCcAdiFHt+obtUAaEAE9Euo6qo2LR0y-3bV+1QBfQPs0LFxCEnJKKhhSRhYAdQxsfCJYPgheamYAN1RMajjk8LS4YTEkEElpWSZ5JQRlAFYjABYdA1UjXVbmtu1teycENqN9KhNm5tVVbXU5nvHm4NCUiPSyCiKweOYoEtTIjKymHKZ8wtjdw43y3UqJKRkeeqrG5X02rT11XSEAiYBl4TMNEG1+lQhEJ1FZtF4hM0TPpdKsQGEjptojs9kl1mUMmB0OgMFQcAAbCgAMwwAFtrqRbgSKvIai85O8VM11EIdNMNEJtBCBkNHODoVQAtChCZ4eYbNo0Ri7rAtjEAK44CDcPGlSIAJTAVJO2SoeQK1E12soTINRtgLKqbLqDRU+n0RioRn6JhMqiRQjaQn96jBCBszSozX0zW0rSMxnUst0ipC6PxxzV1GQeBkABVUIaqeg4AALW3pPgKWjbKh4KmUdAACma0oAlHxlQSs1Qc-nC0aS7Byxn0o6nrVXq6mtzPULevDdEm2kHQWKEB6Jt045ZoUn-uo2krR1FtnwAKqsAAiAEE8wBRAD6ADV7-riABJADyADlx9VnhdTkmksXRJgTBY-GMYNvTDZRek9TRej9XQDFcP0VjTLtM2xC9rzvJ9WBvABxe9-2dKdgOUWUtGjL5Az8QY-TsdcEyjVCTBsIEvB49Rjz1LEz0vW8H0fAAxD8ABkH31cjAMo0APn6Dpvhlf4E3+GNmjgpdtCoMYYVUAZuQ0JMgjRJhUAgOB5GwwSYhreh9nYTgmG4DkJ3ZN5FJULwOiFMw-SsVRrEFMNvS9Hiouikx+MxU8YjiBIDhPeAnXkjzFF8gYdERfwEy8PwUTDQw9KRZoU2hcZNDafRYqw1KeytHUUoEsAizSzygJ8poAjcKxvmMNpZW5VoSosL0iu6UrLGROKVR7PtSALIshxHNrOoAydMqUmYo00ExTCM-pBhK8woRTWFWh5WYgyPBqNqzVkMu8rKmn+WqdGGmV-GDULRRGLQotUXRfVBsx2kRYJgiAA */
|
||||
createMachine(
|
||||
{
|
||||
tsTypes: {} as import("./workspacesXService.typegen").Typegen1,
|
||||
@@ -235,10 +235,7 @@ export const workspacesMachine =
|
||||
events: {} as WorkspacesEvent,
|
||||
services: {} as {
|
||||
getWorkspaces: {
|
||||
data: TypesGen.Workspace[]
|
||||
}
|
||||
getWorkspacesCount: {
|
||||
data: { count: number }
|
||||
data: TypesGen.WorkspacesResponse
|
||||
}
|
||||
updateWorkspaceRefs: {
|
||||
data: {
|
||||
@@ -254,98 +251,64 @@ export const workspacesMachine =
|
||||
UPDATE_VERSION: {
|
||||
actions: "triggerUpdateVersion",
|
||||
},
|
||||
UPDATE_PAGE: {
|
||||
target: "gettingWorkspaces",
|
||||
actions: "updateURL",
|
||||
},
|
||||
UPDATE_FILTER: {
|
||||
actions: ["assignFilter", "sendResetPage"],
|
||||
},
|
||||
},
|
||||
type: "parallel",
|
||||
initial: "startingPagination",
|
||||
states: {
|
||||
count: {
|
||||
initial: "gettingCount",
|
||||
states: {
|
||||
idle: {},
|
||||
gettingCount: {
|
||||
entry: "clearGetCountError",
|
||||
invoke: {
|
||||
src: "getWorkspacesCount",
|
||||
id: "getWorkspacesCount",
|
||||
onDone: [
|
||||
{
|
||||
target: "idle",
|
||||
actions: "assignCount",
|
||||
},
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
target: "idle",
|
||||
actions: "assignGetCountError",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
on: {
|
||||
UPDATE_FILTER: {
|
||||
target: ".gettingCount",
|
||||
actions: ["assignFilter", "sendResetPage"],
|
||||
},
|
||||
startingPagination: {
|
||||
entry: "assignPaginationRef",
|
||||
always: {
|
||||
target: "gettingWorkspaces",
|
||||
},
|
||||
},
|
||||
workspaces: {
|
||||
initial: "startingPagination",
|
||||
states: {
|
||||
startingPagination: {
|
||||
entry: "assignPaginationRef",
|
||||
always: {
|
||||
target: "gettingWorkspaces",
|
||||
gettingWorkspaces: {
|
||||
entry: "clearGetWorkspacesError",
|
||||
invoke: {
|
||||
src: "getWorkspaces",
|
||||
id: "getWorkspaces",
|
||||
onDone: [
|
||||
{
|
||||
target: "waitToRefreshWorkspaces",
|
||||
cond: "isEmpty",
|
||||
actions: ["assignWorkspaceRefs", "assignCount"],
|
||||
},
|
||||
},
|
||||
gettingWorkspaces: {
|
||||
entry: "clearGetWorkspacesError",
|
||||
invoke: {
|
||||
src: "getWorkspaces",
|
||||
id: "getWorkspaces",
|
||||
onDone: [
|
||||
{
|
||||
target: "waitToRefreshWorkspaces",
|
||||
cond: "isEmpty",
|
||||
actions: "assignWorkspaceRefs",
|
||||
},
|
||||
{
|
||||
target: "updatingWorkspaceRefs",
|
||||
},
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
target: "waitToRefreshWorkspaces",
|
||||
actions: "assignGetWorkspacesError",
|
||||
},
|
||||
],
|
||||
{
|
||||
target: "updatingWorkspaceRefs",
|
||||
actions: "assignCount",
|
||||
},
|
||||
},
|
||||
updatingWorkspaceRefs: {
|
||||
invoke: {
|
||||
src: "updateWorkspaceRefs",
|
||||
id: "updateWorkspaceRefs",
|
||||
onDone: [
|
||||
{
|
||||
target: "waitToRefreshWorkspaces",
|
||||
actions: "assignUpdatedWorkspaceRefs",
|
||||
},
|
||||
],
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
target: "waitToRefreshWorkspaces",
|
||||
actions: "assignGetWorkspacesError",
|
||||
},
|
||||
},
|
||||
waitToRefreshWorkspaces: {
|
||||
after: {
|
||||
"5000": {
|
||||
target: "#workspacesState.workspaces.gettingWorkspaces",
|
||||
actions: [],
|
||||
internal: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
on: {
|
||||
UPDATE_PAGE: {
|
||||
target: ".gettingWorkspaces",
|
||||
actions: "updateURL",
|
||||
},
|
||||
updatingWorkspaceRefs: {
|
||||
invoke: {
|
||||
src: "updateWorkspaceRefs",
|
||||
id: "updateWorkspaceRefs",
|
||||
onDone: [
|
||||
{
|
||||
target: "waitToRefreshWorkspaces",
|
||||
actions: "assignUpdatedWorkspaceRefs",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
waitToRefreshWorkspaces: {
|
||||
after: {
|
||||
"5000": {
|
||||
target: "gettingWorkspaces",
|
||||
actions: [],
|
||||
internal: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -358,10 +321,13 @@ export const workspacesMachine =
|
||||
actions: {
|
||||
assignWorkspaceRefs: assign({
|
||||
workspaceRefs: (_, event) =>
|
||||
event.data.map((data) => {
|
||||
event.data.workspaces.map((data) => {
|
||||
return spawn(workspaceItemMachine.withContext({ data }), data.id)
|
||||
}),
|
||||
}),
|
||||
assignCount: assign({
|
||||
count: (_, event) => event.data.count,
|
||||
}),
|
||||
assignPaginationRef: assign({
|
||||
paginationRef: (context) =>
|
||||
spawn(
|
||||
@@ -403,15 +369,6 @@ export const workspacesMachine =
|
||||
return event.data.refsToKeep.concat(newWorkspaceRefs)
|
||||
},
|
||||
}),
|
||||
assignCount: assign({
|
||||
count: (_, event) => event.data.count,
|
||||
}),
|
||||
assignGetCountError: assign({
|
||||
getCountError: (_, event) => event.data,
|
||||
}),
|
||||
clearGetCountError: assign({
|
||||
getCountError: (_) => undefined,
|
||||
}),
|
||||
},
|
||||
services: {
|
||||
getWorkspaces: (context) => {
|
||||
@@ -429,7 +386,7 @@ export const workspacesMachine =
|
||||
updateWorkspaceRefs: (context, event) => {
|
||||
const refsToKeep: WorkspaceItemMachineRef[] = []
|
||||
context.workspaceRefs?.forEach((ref) => {
|
||||
const matchingWorkspace = event.data.find(
|
||||
const matchingWorkspace = event.data.workspaces.find(
|
||||
(workspace) => ref.id === workspace.id,
|
||||
)
|
||||
if (matchingWorkspace) {
|
||||
@@ -443,7 +400,7 @@ export const workspacesMachine =
|
||||
}
|
||||
})
|
||||
|
||||
const newWorkspaces = event.data.filter(
|
||||
const newWorkspaces = event.data.workspaces.filter(
|
||||
(workspace) =>
|
||||
!context.workspaceRefs?.find((ref) => ref.id === workspace.id),
|
||||
)
|
||||
@@ -453,8 +410,6 @@ export const workspacesMachine =
|
||||
newWorkspaces,
|
||||
})
|
||||
},
|
||||
getWorkspacesCount: (context) =>
|
||||
API.getWorkspacesCount({ q: context.filter }),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user