Skip to content

Revert "Refine workspace API (#19138)" #19172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/dashboard/src/data/setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import * as SSHClasses from "@gitpod/public-api/lib/gitpod/v1/ssh_pb";
// This is used to version the cache
// If data we cache changes in a non-backwards compatible way, increment this version
// That will bust any previous cache versions a client may have stored
const CACHE_VERSION = "12";
const CACHE_VERSION = "13";

export function noPersistence(queryKey: QueryKey): QueryKey {
return [...queryKey, "no-persistence"];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { getGitpodService } from "../../service/service";
import { getListWorkspacesQueryKey, ListWorkspacesQueryResult } from "./list-workspaces-query";
import { useCurrentOrg } from "../organizations/orgs-query";
import { Workspace, WorkspaceMetadata } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
import { Workspace } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";

type ToggleWorkspacePinnedArgs = {
workspaceId: string;
Expand All @@ -33,10 +33,7 @@ export const useToggleWorkspacedPinnedMutation = () => {
return info;
}
const workspace = new Workspace(info);
if (!workspace.metadata) {
workspace.metadata = new WorkspaceMetadata();
}
workspace.metadata.pinned = !workspace.metadata.pinned;
workspace.pinned = !workspace.pinned;
return workspace;
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { getGitpodService } from "../../service/service";
import { getListWorkspacesQueryKey, ListWorkspacesQueryResult } from "./list-workspaces-query";
import { useCurrentOrg } from "../organizations/orgs-query";
import { AdmissionLevel, Workspace, WorkspaceSpec } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
import { AdmissionLevel, Workspace } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";

type ToggleWorkspaceSharedArgs = {
workspaceId: string;
Expand Down Expand Up @@ -44,10 +44,9 @@ export const useToggleWorkspaceSharedMutation = () => {
}

const workspace = new Workspace(info);
if (!workspace.spec) {
workspace.spec = new WorkspaceSpec();
if (workspace.status) {
workspace.status.admission = level;
}
workspace.spec.admission = level;
return workspace;
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { getGitpodService } from "../../service/service";
import { getListWorkspacesQueryKey, ListWorkspacesQueryResult } from "./list-workspaces-query";
import { useCurrentOrg } from "../organizations/orgs-query";
import { Workspace, WorkspaceMetadata } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
import { Workspace } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";

type UpdateWorkspaceDescriptionArgs = {
workspaceId: string;
Expand Down Expand Up @@ -36,10 +36,7 @@ export const useUpdateWorkspaceDescriptionMutation = () => {
// TODO: Once the update description response includes an updated record,
// we can return that instead of having to know what to merge manually (same for other mutations)
const workspace = new Workspace(info);
if (!workspace.metadata) {
workspace.metadata = new WorkspaceMetadata();
}
workspace.metadata.name = newDescription;
workspace.name = newDescription;
return workspace;
});
});
Expand Down
36 changes: 9 additions & 27 deletions components/dashboard/src/service/json-rpc-workspace-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ import {
SendHeartBeatResponse,
WorkspacePhase_Phase,
GetWorkspaceDefaultImageResponse_Source,
ParseContextURLRequest,
ParseContextURLResponse,
UpdateWorkspaceRequest,
UpdateWorkspaceResponse,
} from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
import { converter } from "./public-api";
import { getGitpodService } from "./service";
Expand Down Expand Up @@ -135,25 +131,25 @@ export class JsonRpcWorkspaceClient implements PromiseClient<typeof WorkspaceSer
if (request.source?.case !== "contextUrl") {
throw new ApplicationError(ErrorCodes.UNIMPLEMENTED, "not implemented");
}
if (!request.metadata || !request.metadata.organizationId || !uuidValidate(request.metadata.organizationId)) {
if (!request.organizationId || !uuidValidate(request.organizationId)) {
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "organizationId is required");
}
if (!request.source.value.editor?.name) {
if (!request.editor) {
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "editor is required");
}
if (!request.source.value.url) {
if (!request.source.value) {
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "source is required");
}
const response = await getGitpodService().server.createWorkspace({
organizationId: request.metadata.organizationId,
organizationId: request.organizationId,
ignoreRunningWorkspaceOnSameCommit: true,
contextUrl: request.source.value.url,
contextUrl: request.source.value,
forceDefaultConfig: request.forceDefaultConfig,
workspaceClass: request.source.value.workspaceClass,
projectId: request.metadata.configurationId,
workspaceClass: request.workspaceClass,
projectId: request.configurationId,
ideSettings: {
defaultIde: request.source.value.editor.name,
useLatestVersion: request.source.value.editor.version === "latest",
defaultIde: request.editor.name,
useLatestVersion: request.editor.version === "latest",
},
});
const workspace = await this.getWorkspace({ workspaceId: response.createdWorkspaceId });
Expand Down Expand Up @@ -244,18 +240,4 @@ export class JsonRpcWorkspaceClient implements PromiseClient<typeof WorkspaceSer
result.editorCredentials = credentials;
return result;
}

async updateWorkspace(
request: PartialMessage<UpdateWorkspaceRequest>,
_options?: CallOptions | undefined,
): Promise<UpdateWorkspaceResponse> {
throw new ApplicationError(ErrorCodes.UNIMPLEMENTED, "not implemented");
}

async parseContextURL(
request: PartialMessage<ParseContextURLRequest>,
_options?: CallOptions | undefined,
): Promise<ParseContextURLResponse> {
throw new ApplicationError(ErrorCodes.UNIMPLEMENTED, "not implemented");
}
}
20 changes: 7 additions & 13 deletions components/dashboard/src/start/StartWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
StartWorkspaceResponse,
Workspace,
WorkspacePhase_Phase,
WorkspaceSpec_WorkspaceType,
} from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
import { PartialMessage } from "@bufbuild/protobuf";

Expand Down Expand Up @@ -170,7 +169,7 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
componentDidUpdate(prevPros: StartWorkspaceProps, prevState: StartWorkspaceState) {
const newPhase = this.state?.workspace?.status?.phase?.name;
const oldPhase = prevState.workspace?.status?.phase?.name;
const type = this.state.workspace?.spec?.type === WorkspaceSpec_WorkspaceType.PREBUILD ? "prebuild" : "regular";
const type = !!this.state.workspace?.prebuild ? "prebuild" : "regular";
if (newPhase !== oldPhase) {
getGitpodService().server.trackEvent({
event: "status_rendered",
Expand Down Expand Up @@ -374,10 +373,10 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,
if (
!error &&
workspace.status.phase?.name === WorkspacePhase_Phase.STOPPED &&
this.state.workspace?.spec?.type === WorkspaceSpec_WorkspaceType.PREBUILD
!!this.state.workspace?.prebuild
) {
// here we want to point to the original context, w/o any modifiers "workspace" was started with (as this might have been a manually triggered prebuild!)
const contextURL = this.state.workspace.metadata?.originalContextUrl;
const contextURL = this.state.workspace.contextUrl;
if (contextURL) {
this.redirectTo(gitpodHostUrl.withContext(contextURL.toString()).toString());
} else {
Expand Down Expand Up @@ -458,20 +457,15 @@ export default class StartWorkspace extends React.Component<StartWorkspaceProps,

render() {
const { error } = this.state;
const isPrebuild = this.state.workspace?.spec?.type === WorkspaceSpec_WorkspaceType.PREBUILD;
let withPrebuild = false;
for (const initializer of this.state.workspace?.spec?.initializer?.specs ?? []) {
if (initializer.spec.case === "prebuild") {
withPrebuild = !!initializer.spec.value.prebuildId;
}
}
const isPrebuild = this.state.workspace?.prebuild;
const withPrebuild = !!this.state.workspace?.prebuildId;
let phase: StartPhase | undefined = StartPhase.Preparing;
let title = undefined;
let isStoppingOrStoppedPhase = false;
let isError = error ? true : false;
let statusMessage = !!error ? undefined : <p className="text-base text-gray-400">Preparing workspace …</p>;
const contextURL = this.state.workspace?.metadata?.originalContextUrl;
const useLatest = this.state.workspace?.spec?.editor?.version === "latest";
const contextURL = this.state.workspace?.contextUrl;
const useLatest = this.state.workspace?.editor?.version === "latest";

switch (this.state?.workspace?.status?.phase?.name) {
// unknown indicates an issue within the system in that it cannot determine the actual phase of
Expand Down
41 changes: 15 additions & 26 deletions components/dashboard/src/workspaces/CreateWorkspacePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { SelectAccountModal } from "../user-settings/SelectAccountModal";
import { settingsPathIntegrations } from "../user-settings/settings.routes";
import { WorkspaceEntry } from "./WorkspaceEntry";
import { AuthProviderType } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb";
import { WorkspaceMetadata, WorkspacePhase_Phase } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
import { WorkspacePhase_Phase } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
import { Button } from "@podkit/buttons/Button";
import { LoadingButton } from "@podkit/buttons/LoadingButton";
import { CreateAndStartWorkspaceRequest } from "@gitpod/public-api/lib/gitpod/v1/workspace_pb";
Expand Down Expand Up @@ -172,14 +172,7 @@ export function CreateWorkspacePage() {
const [selectAccountError, setSelectAccountError] = useState<SelectAccountPayload | undefined>(undefined);

const createWorkspace = useCallback(
/**
* options will omit
* - source.url
* - source.workspaceClass
* - metadata.organizationId
* - metadata.configurationId
*/
async (options?: PartialMessage<CreateAndStartWorkspaceRequest>) => {
async (options?: Omit<PartialMessage<CreateAndStartWorkspaceRequest>, "contextUrl" | "organizationId">) => {
// add options from search params
const opts = options || {};

Expand All @@ -199,6 +192,16 @@ export function CreateWorkspacePage() {
opts.forceDefaultConfig = true;
}

if (!opts.workspaceClass) {
opts.workspaceClass = selectedWsClass;
}
if (!opts.editor) {
opts.editor = {
name: selectedIde,
version: useLatestIde ? "latest" : undefined,
};
}

try {
if (createWorkspaceMutation.isStarting) {
console.log("Skipping duplicate createWorkspace call.");
Expand All @@ -207,28 +210,14 @@ export function CreateWorkspacePage() {
// we wait at least 5 secs
const timeout = new Promise((resolve) => setTimeout(resolve, 5000));

if (!opts.metadata) {
opts.metadata = new WorkspaceMetadata();
}
opts.metadata.organizationId = organizationId;
opts.metadata.configurationId = selectedProjectID;

const result = await createWorkspaceMutation.createWorkspace({
source: {
case: "contextUrl",
value: {
url: contextURL,
workspaceClass: selectedWsClass,
editor:
opts.source?.case === "contextUrl" && opts.source.value.editor
? opts.source.value.editor
: {
name: selectedIde,
version: useLatestIde ? "latest" : undefined,
},
},
value: contextURL,
},
...opts,
organizationId,
configurationId: selectedProjectID,
});
await storeAutoStartOptions();
await timeout;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const DeleteWorkspaceModal: FunctionComponent<Props> = ({ workspace, onCl
areYouSureText="Are you sure you want to delete this workspace?"
children={{
name: workspace.id,
description: workspace.metadata?.name,
description: workspace.name,
}}
buttonText="Delete Workspace"
warningText={deleteWorkspace.isError ? "There was a problem deleting your workspace." : undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Props = {
};
export const RenameWorkspaceModal: FunctionComponent<Props> = ({ workspace, onClose }) => {
const [errorMessage, setErrorMessage] = useState("");
const [description, setDescription] = useState(workspace.metadata?.name || "");
const [description, setDescription] = useState(workspace.name || "");
const updateDescription = useUpdateWorkspaceDescriptionMutation();

const updateWorkspaceDescription = useCallback(async () => {
Expand Down
8 changes: 4 additions & 4 deletions components/dashboard/src/workspaces/WorkspaceEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export const WorkspaceEntry: FunctionComponent<Props> = ({ info, shortVersion })
const workspace = info;
const currentBranch = gitStatus?.branch || "<unknown>";
const project = getProjectPath(workspace);
const normalizedContextUrl = workspace.metadata!.originalContextUrl;
const normalizedContextUrlDescription = workspace.metadata!.originalContextUrl; // Instead of showing nothing, we prefer to show the raw content instead
const normalizedContextUrl = workspace.contextUrl;
const normalizedContextUrlDescription = workspace.contextUrl; // Instead of showing nothing, we prefer to show the raw content instead

const changeMenuState = (state: boolean) => {
setMenuActive(state);
Expand Down Expand Up @@ -69,7 +69,7 @@ export const WorkspaceEntry: FunctionComponent<Props> = ({ info, shortVersion })
<>
<ItemField className="w-4/12 flex flex-col my-auto">
<div className="text-gray-500 dark:text-gray-400 overflow-ellipsis truncate">
{workspace.metadata!.name}
{workspace.name}
</div>
<a href={normalizedContextUrl}>
<div className="text-sm text-gray-400 dark:text-gray-500 overflow-ellipsis truncate hover:text-blue-600 dark:hover:text-blue-400">
Expand Down Expand Up @@ -105,5 +105,5 @@ export const WorkspaceEntry: FunctionComponent<Props> = ({ info, shortVersion })

export function getProjectPath(ws: Workspace) {
// TODO: Remove and call papi ContextService
return ws.metadata!.originalContextUrl.replace("https://", "");
return ws.contextUrl.replace("https://", "");
}
10 changes: 6 additions & 4 deletions components/dashboard/src/workspaces/WorkspaceOverflowMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ export const WorkspaceEntryOverflowMenu: FunctionComponent<WorkspaceEntryOverflo

const toggleShared = useCallback(() => {
const newLevel =
workspace.spec?.admission === AdmissionLevel.EVERYONE ? AdmissionLevel.OWNER_ONLY : AdmissionLevel.EVERYONE;
workspace.status?.admission === AdmissionLevel.EVERYONE
? AdmissionLevel.OWNER_ONLY
: AdmissionLevel.EVERYONE;

toggleWorkspaceShared.mutate({
workspaceId: workspace.id,
level: newLevel,
});
}, [toggleWorkspaceShared, workspace.id, workspace.spec?.admission]);
}, [toggleWorkspaceShared, workspace.id, workspace.status?.admission]);

const togglePinned = useCallback(() => {
toggleWorkspacePinned.mutate({
Expand Down Expand Up @@ -127,12 +129,12 @@ export const WorkspaceEntryOverflowMenu: FunctionComponent<WorkspaceEntryOverflo
menuEntries.push(
{
title: "Share",
active: workspace.spec?.admission === AdmissionLevel.EVERYONE,
active: workspace.status?.admission === AdmissionLevel.EVERYONE,
onClick: toggleShared,
},
{
title: "Pin",
active: !!workspace.metadata?.pinned,
active: !!workspace.pinned,
separator: true,
onClick: togglePinned,
},
Expand Down
10 changes: 3 additions & 7 deletions components/dashboard/src/workspaces/Workspaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,14 @@ const WorkspacesPage: FunctionComponent = () => {
const { filteredActiveWorkspaces, filteredInactiveWorkspaces } = useMemo(() => {
const filteredActiveWorkspaces = activeWorkspaces.filter(
(info) =>
`${info.metadata!.name}${info.id}${info.metadata!.originalContextUrl}${
info.status?.gitStatus?.cloneUrl
}${info.status?.gitStatus?.branch}`
`${info.name}${info.id}${info.contextUrl}${info.status?.gitStatus?.cloneUrl}${info.status?.gitStatus?.branch}`
.toLowerCase()
.indexOf(searchTerm.toLowerCase()) !== -1,
);

const filteredInactiveWorkspaces = inactiveWorkspaces.filter(
(info) =>
`${info.metadata!.name}${info.id}${info.metadata!.originalContextUrl}${
info.status?.gitStatus?.cloneUrl
}${info.status?.gitStatus?.branch}`
`${info.name}${info.id}${info.contextUrl}${info.status?.gitStatus?.cloneUrl}${info.status?.gitStatus?.branch}`
.toLowerCase()
.indexOf(searchTerm.toLowerCase()) !== -1,
);
Expand Down Expand Up @@ -205,5 +201,5 @@ function isWorkspaceActive(info: Workspace): boolean {
const twentyfourHoursAgo = hoursBefore(new Date().toISOString(), 24);

const isStopped = info.status?.phase?.name === WorkspacePhase_Phase.STOPPED;
return info.metadata!.pinned || !isStopped || isDateSmallerOrEqual(twentyfourHoursAgo, lastSessionStart);
return info.pinned || !isStopped || isDateSmallerOrEqual(twentyfourHoursAgo, lastSessionStart);
}
9 changes: 4 additions & 5 deletions components/public-api/gitpod/v1/envvar.proto
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,9 @@ message ResolveWorkspaceEnvironmentVariablesRequest {
}

message ResolveWorkspaceEnvironmentVariablesResponse {
message EnvironmentVariable {
string name = 1;
string value = 2;
}
repeated EnvironmentVariable environment_variables = 1;
}

message EnvironmentVariable {
string name = 1;
string value = 2;
}
Loading