Skip to content

chore(site): remove create workspace xservice #10217

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 22 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
Next Next commit
Move xstate transitions to provider
  • Loading branch information
BrunoQuaresma committed Oct 10, 2023
commit 10f3c100c77147648fe124b734a796f65d6bca6c
51 changes: 39 additions & 12 deletions site/src/components/AuthProvider/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,63 @@
import { useActor, useInterpret } from "@xstate/react";
import { createContext, FC, PropsWithChildren, useContext } from "react";
import { UpdateUserProfileRequest } from "api/typesGenerated";
import {
createContext,
FC,
PropsWithChildren,
useCallback,
useContext,
} from "react";
import { authMachine } from "xServices/auth/authXService";
import { ActorRefFrom } from "xstate";

interface AuthContextValue {
type AuthContextValue = {
signOut: () => void;
signIn: (email: string, password: string) => void;
updateProfile: (data: UpdateUserProfileRequest) => void;
authService: ActorRefFrom<typeof authMachine>;
}
};

const AuthContext = createContext<AuthContextValue | undefined>(undefined);

export const AuthProvider: FC<PropsWithChildren> = ({ children }) => {
const authService = useInterpret(authMachine);

const signOut = useCallback(() => {
authService.send("SIGN_OUT");
}, [authService]);

const signIn = useCallback(
(email: string, password: string) => {
authService.send({ type: "SIGN_IN", email, password });
},
[authService],
);

const updateProfile = useCallback(
(data: UpdateUserProfileRequest) => {
authService.send({ type: "UPDATE_PROFILE", data });
},
[authService],
);

return (
<AuthContext.Provider value={{ authService }}>
<AuthContext.Provider
value={{ authService, signOut, signIn, updateProfile }}
>
{children}
</AuthContext.Provider>
);
};

type UseAuthReturnType = ReturnType<
typeof useActor<AuthContextValue["authService"]>
>;

export const useAuth = (): UseAuthReturnType => {
export const useAuth = () => {
const context = useContext(AuthContext);

if (!context) {
throw new Error("useAuth should be used inside of <AuthProvider />");
}

const auth = useActor(context.authService);

return auth;
return {
...context,
actor: useActor(context.authService),
};
};
5 changes: 2 additions & 3 deletions site/src/components/Dashboard/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import { useProxy } from "contexts/ProxyContext";

export const Navbar: FC = () => {
const { appearance, buildInfo } = useDashboard();
const [_, authSend] = useAuth();
const { signOut } = useAuth();
const me = useMe();
const permissions = usePermissions();
const featureVisibility = useFeatureVisibility();
const canViewAuditLog =
featureVisibility["audit_log"] && Boolean(permissions.viewAuditLog);
const canViewDeployment = Boolean(permissions.viewDeploymentValues);
const canViewAllUsers = Boolean(permissions.readAllUsers);
const onSignOut = () => authSend("SIGN_OUT");
const proxyContextValue = useProxy();
const dashboard = useDashboard();

Expand All @@ -27,7 +26,7 @@ export const Navbar: FC = () => {
logo_url={appearance.config.logo_url}
buildInfo={buildInfo}
supportLinks={appearance.config.support_links}
onSignOut={onSignOut}
onSignOut={signOut}
canViewAuditLog={canViewAuditLog}
canViewDeployment={canViewDeployment}
canViewAllUsers={canViewAllUsers}
Expand Down
7 changes: 4 additions & 3 deletions site/src/components/RequireAuth/RequireAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { ProxyProvider } from "contexts/ProxyContext";
import { isApiError } from "api/errors";

export const RequireAuth: FC = () => {
const [authState, authSend] = useAuth();
const { signOut, actor } = useAuth();
const [authState] = actor;
const location = useLocation();
const isHomePage = location.pathname === "/";
const navigateTo = isHomePage
Expand All @@ -24,7 +25,7 @@ export const RequireAuth: FC = () => {
// If we encountered an authentication error, then our token is probably
// invalid and we should update the auth state to reflect that.
if (isApiError(error) && error.response.status === 401) {
authSend("SIGN_OUT");
signOut();
}

// Otherwise, pass the response through so that it can be displayed in the UI
Expand All @@ -35,7 +36,7 @@ export const RequireAuth: FC = () => {
return () => {
axios.interceptors.response.eject(interceptorHandle);
};
}, [authSend]);
}, [signOut]);

if (authState.matches("signedOut")) {
return <Navigate to={navigateTo} state={{ isRedirect: !isHomePage }} />;
Expand Down
3 changes: 2 additions & 1 deletion site/src/hooks/useMe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useAuth } from "components/AuthProvider/AuthProvider";
import { isAuthenticated } from "xServices/auth/authXService";

export const useMe = (): User => {
const [authState] = useAuth();
const { actor } = useAuth();
const [authState] = actor;
const { data } = authState.context;

if (isAuthenticated(data)) {
Expand Down
3 changes: 2 additions & 1 deletion site/src/hooks/useOrganizationId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { useAuth } from "components/AuthProvider/AuthProvider";
import { isAuthenticated } from "xServices/auth/authXService";

export const useOrganizationId = (): string => {
const [authState] = useAuth();
const { actor } = useAuth();
const [authState] = actor;
const { data } = authState.context;

if (isAuthenticated(data)) {
Expand Down
3 changes: 2 additions & 1 deletion site/src/hooks/usePermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { useAuth } from "components/AuthProvider/AuthProvider";
import { isAuthenticated, Permissions } from "xServices/auth/authXService";

export const usePermissions = (): Permissions => {
const [authState] = useAuth();
const { actor } = useAuth();
const [authState] = actor;
const { data } = authState.context;

if (isAuthenticated(data)) {
Expand Down
5 changes: 3 additions & 2 deletions site/src/pages/LoginPage/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { getApplicationName } from "utils/appearance";

export const LoginPage: FC = () => {
const location = useLocation();
const [authState, authSend] = useAuth();
const { actor, signIn } = useAuth();
const [authState] = actor;
const redirectTo = retrieveRedirect(location.search);
const applicationName = getApplicationName();

Expand All @@ -27,7 +28,7 @@ export const LoginPage: FC = () => {
isLoading={authState.matches("loadingInitialAuthData")}
isSigningIn={authState.matches("signingIn")}
onSignIn={({ email, password }) => {
authSend({ type: "SIGN_IN", email, password });
signIn(email, password);
}}
/>
</>
Expand Down
9 changes: 3 additions & 6 deletions site/src/pages/SetupPage/SetupPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { useMutation } from "react-query";
import { createFirstUser } from "api/queries/users";

export const SetupPage: FC = () => {
const [authState, authSend] = useAuth();
const { signIn, actor } = useAuth();
const [authState] = actor;
const createFirstUserMutation = useMutation(createFirstUser());
const userIsSignedIn = authState.matches("signedIn");
const setupIsComplete =
Expand All @@ -35,11 +36,7 @@ export const SetupPage: FC = () => {
error={createFirstUserMutation.error}
onSubmit={async (firstUser) => {
await createFirstUserMutation.mutateAsync(firstUser);
authSend({
type: "SIGN_IN",
email: firstUser.email,
password: firstUser.password,
});
signIn(firstUser.email, firstUser.password);
}}
/>
</>
Expand Down
33 changes: 13 additions & 20 deletions site/src/pages/UserSettingsPage/AccountPage/AccountForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import TextField from "@mui/material/TextField";
import { FormikContextType, FormikTouched, useFormik } from "formik";
import { FormikTouched, useFormik } from "formik";
import { FC } from "react";
import * as Yup from "yup";
import {
Expand All @@ -10,10 +10,7 @@ import {
import { LoadingButton } from "components/LoadingButton/LoadingButton";
import { ErrorAlert } from "components/Alert/ErrorAlert";
import { Form, FormFields } from "components/Form/Form";

export interface AccountFormValues {
username: string;
}
import { UpdateUserProfileRequest } from "api/typesGenerated";

export const Language = {
usernameLabel: "Username",
Expand All @@ -29,14 +26,14 @@ export interface AccountFormProps {
editable: boolean;
email: string;
isLoading: boolean;
initialValues: AccountFormValues;
onSubmit: (values: AccountFormValues) => void;
initialValues: UpdateUserProfileRequest;
onSubmit: (values: UpdateUserProfileRequest) => void;
updateProfileError?: unknown;
// initialTouched is only used for testing the error state of the form.
initialTouched?: FormikTouched<AccountFormValues>;
initialTouched?: FormikTouched<UpdateUserProfileRequest>;
}

export const AccountForm: FC<React.PropsWithChildren<AccountFormProps>> = ({
export const AccountForm: FC<AccountFormProps> = ({
editable,
email,
isLoading,
Expand All @@ -45,17 +42,13 @@ export const AccountForm: FC<React.PropsWithChildren<AccountFormProps>> = ({
updateProfileError,
initialTouched,
}) => {
const form: FormikContextType<AccountFormValues> =
useFormik<AccountFormValues>({
initialValues,
validationSchema,
onSubmit,
initialTouched,
});
const getFieldHelpers = getFormHelpers<AccountFormValues>(
form,
updateProfileError,
);
const form = useFormik({
initialValues,
validationSchema,
onSubmit,
initialTouched,
});
const getFieldHelpers = getFormHelpers(form, updateProfileError);

return (
<>
Expand Down
10 changes: 3 additions & 7 deletions site/src/pages/UserSettingsPage/AccountPage/AccountPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { useMe } from "hooks/useMe";
import { usePermissions } from "hooks/usePermissions";

export const AccountPage: FC = () => {
const [authState, authSend] = useAuth();
const { updateProfile, actor } = useAuth();
const [authState] = actor;
const me = useMe();
const permissions = usePermissions();
const { updateProfileError } = authState.context;
Expand All @@ -22,12 +23,7 @@ export const AccountPage: FC = () => {
initialValues={{
username: me.username,
}}
onSubmit={(data) => {
authSend({
type: "UPDATE_PROFILE",
data,
});
}}
onSubmit={updateProfile}
/>
</Section>
);
Expand Down