Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit215dd7b

Browse files
authored
feat: show version on login page (#13033)
1 parenta69fc65 commit215dd7b

File tree

19 files changed

+101
-83
lines changed

19 files changed

+101
-83
lines changed

‎site/src/api/queries/appearance.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ const initialAppearanceData = getMetadataAsJSON<AppearanceConfig>("appearance");
88
constappearanceConfigKey=["appearance"]asconst;
99

1010
exportconstappearance=():UseQueryOptions<AppearanceConfig>=>{
11-
return{
12-
// We either have our initial data or should immediately
13-
// fetch and never again!
14-
...cachedQuery(initialAppearanceData),
11+
// We either have our initial data or should immediately fetch and never again!
12+
returncachedQuery({
13+
initialData:initialAppearanceData,
1514
queryKey:["appearance"],
1615
queryFn:()=>API.getAppearance(),
17-
};
16+
});
1817
};
1918

2019
exportconstupdateAppearance=(queryClient:QueryClient)=>{

‎site/src/api/queries/buildInfo.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ const initialBuildInfoData = getMetadataAsJSON<BuildInfoResponse>("build-info");
88
constbuildInfoKey=["buildInfo"]asconst;
99

1010
exportconstbuildInfo=():UseQueryOptions<BuildInfoResponse>=>{
11-
return{
12-
// We either have our initial data or should immediately
13-
// fetch and never again!
14-
...cachedQuery(initialBuildInfoData),
11+
// The version of the app can't change without reloading the page.
12+
returncachedQuery({
13+
initialData:initialBuildInfoData,
1514
queryKey:buildInfoKey,
1615
queryFn:()=>API.getBuildInfo(),
17-
};
16+
});
1817
};

‎site/src/api/queries/entitlements.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ const initialEntitlementsData = getMetadataAsJSON<Entitlements>("entitlements");
88
constentitlementsQueryKey=["entitlements"]asconst;
99

1010
exportconstentitlements=():UseQueryOptions<Entitlements>=>{
11-
return{
12-
...cachedQuery(initialEntitlementsData),
11+
returncachedQuery({
12+
initialData:initialEntitlementsData,
1313
queryKey:entitlementsQueryKey,
1414
queryFn:()=>API.getEntitlements(),
15-
};
15+
});
1616
};
1717

1818
exportconstrefreshEntitlements=(queryClient:QueryClient)=>{

‎site/src/api/queries/experiments.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ const initialExperimentsData = getMetadataAsJSON<Experiments>("experiments");
88
constexperimentsKey=["experiments"]asconst;
99

1010
exportconstexperiments=():UseQueryOptions<Experiments>=>{
11-
return{
12-
...cachedQuery(initialExperimentsData),
11+
returncachedQuery({
12+
initialData:initialExperimentsData,
1313
queryKey:experimentsKey,
1414
queryFn:()=>API.getExperiments(),
15-
}satisfiesUseQueryOptions<Experiments>;
15+
});
1616
};
1717

1818
exportconstavailableExperiments=()=>{

‎site/src/api/queries/users.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ const meKey = ["me"];
129129
exportconstme=():UseQueryOptions<User>&{
130130
queryKey:QueryKey;
131131
}=>{
132-
return{
133-
...cachedQuery(initialUserData),
132+
returncachedQuery({
133+
initialData:initialUserData,
134134
queryKey:meKey,
135135
queryFn:API.getAuthenticatedUser,
136-
};
136+
});
137137
};
138138

139139
exportfunctionapiKey():UseQueryOptions<GenerateAPIKeyResponse>{
@@ -144,12 +144,12 @@ export function apiKey(): UseQueryOptions<GenerateAPIKeyResponse> {
144144
}
145145

146146
exportconsthasFirstUser=():UseQueryOptions<boolean>=>{
147-
return{
147+
returncachedQuery({
148148
// This cannot be false otherwise it will not fetch!
149-
...cachedQuery(typeofinitialUserData!=="undefined" ?true :undefined),
149+
initialData:Boolean(initialUserData)||undefined,
150150
queryKey:["hasFirstUser"],
151151
queryFn:API.hasFirstUser,
152-
};
152+
});
153153
};
154154

155155
exportconstlogin=(

‎site/src/api/queries/util.ts

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
importtype{UseQueryOptions}from"react-query";
22

3-
// cachedQuery allows the caller to only make a request
4-
// a single time, and use `initialData` if it is provided.
5-
//
6-
// This is particularly helpful for passing values injected
7-
// via metadata. We do this for the initial user fetch, buildinfo,
8-
// and a few others to reduce page load time.
9-
exportconstcachedQuery=<T>(initialData?:T):Partial<UseQueryOptions<T>>=>
10-
// Only do this if there is initial data,
11-
// otherwise it can conflict with tests.
12-
initialData
13-
?{
14-
cacheTime:Infinity,
15-
staleTime:Infinity,
16-
refetchOnMount:false,
17-
refetchOnReconnect:false,
18-
refetchOnWindowFocus:false,
19-
initialData,
20-
}
21-
:{
22-
initialData,
23-
};
3+
/**
4+
* cachedQuery allows the caller to only make a request a single time, and use
5+
* `initialData` if it is provided. This is particularly helpful for passing
6+
* values injected via metadata. We do this for the initial user fetch,
7+
* buildinfo, and a few others to reduce page load time.
8+
*/
9+
exportconstcachedQuery=<
10+
TQueryOptionsextendsUseQueryOptions<TData>,
11+
TData,
12+
>(
13+
options:TQueryOptions,
14+
):TQueryOptions=>
15+
// Only do this if there is initial data, otherwise it can conflict with tests.
16+
({
17+
...(options.initialData
18+
?{
19+
cacheTime:Infinity,
20+
staleTime:Infinity,
21+
refetchOnMount:false,
22+
refetchOnReconnect:false,
23+
refetchOnWindowFocus:false,
24+
}
25+
:{}),
26+
...options,
27+
});

‎site/src/contexts/ProxyContext.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
useEffect,
88
useState,
99
}from"react";
10-
import{typeUseQueryOptions,useQuery}from"react-query";
10+
import{useQuery}from"react-query";
1111
import{getWorkspaceProxies,getWorkspaceProxyRegions}from"api/api";
1212
import{cachedQuery}from"api/queries/util";
1313
importtype{Region,WorkspaceProxy}from"api/typesGenerated";
@@ -131,11 +131,13 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
131131
error:proxiesError,
132132
isLoading:proxiesLoading,
133133
isFetched:proxiesFetched,
134-
}=useQuery({
135-
...cachedQuery(initialData),
136-
queryKey,
137-
queryFn:query,
138-
}asUseQueryOptions<readonlyRegion[]>);
134+
}=useQuery(
135+
cachedQuery({
136+
initialData,
137+
queryKey,
138+
queryFn:query,
139+
}),
140+
);
139141

140142
// Every time we get a new proxiesResponse, update the latency check
141143
// to each workspace proxy.

‎site/src/modules/dashboard/DashboardProvider.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ import {
77
}from"react";
88
import{useQuery}from"react-query";
99
import{appearance}from"api/queries/appearance";
10-
import{buildInfo}from"api/queries/buildInfo";
1110
import{entitlements}from"api/queries/entitlements";
1211
import{experiments}from"api/queries/experiments";
1312
importtype{
1413
AppearanceConfig,
15-
BuildInfoResponse,
1614
Entitlements,
1715
Experiments,
1816
}from"api/typesGenerated";
@@ -27,7 +25,6 @@ interface Appearance {
2725
}
2826

2927
exportinterfaceDashboardValue{
30-
buildInfo:BuildInfoResponse;
3128
entitlements:Entitlements;
3229
experiments:Experiments;
3330
appearance:Appearance;
@@ -38,16 +35,12 @@ export const DashboardContext = createContext<DashboardValue | undefined>(
3835
);
3936

4037
exportconstDashboardProvider:FC<PropsWithChildren>=({ children})=>{
41-
constbuildInfoQuery=useQuery(buildInfo());
4238
constentitlementsQuery=useQuery(entitlements());
4339
constexperimentsQuery=useQuery(experiments());
4440
constappearanceQuery=useQuery(appearance());
4541

4642
constisLoading=
47-
!buildInfoQuery.data||
48-
!entitlementsQuery.data||
49-
!appearanceQuery.data||
50-
!experimentsQuery.data;
43+
!entitlementsQuery.data||!appearanceQuery.data||!experimentsQuery.data;
5144

5245
const[configPreview,setConfigPreview]=useState<AppearanceConfig>();
5346

@@ -84,7 +77,6 @@ export const DashboardProvider: FC<PropsWithChildren> = ({ children }) => {
8477
return(
8578
<DashboardContext.Provider
8679
value={{
87-
buildInfo:buildInfoQuery.data,
8880
entitlements:entitlementsQuery.data,
8981
experiments:experimentsQuery.data,
9082
appearance:{

‎site/src/modules/dashboard/Navbar/Navbar.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
importtype{FC}from"react";
2+
import{useQuery}from"react-query";
3+
import{buildInfo}from"api/queries/buildInfo";
24
import{useAuthenticated}from"contexts/auth/RequireAuth";
35
import{useProxy}from"contexts/ProxyContext";
46
import{useDashboard}from"modules/dashboard/useDashboard";
57
import{useFeatureVisibility}from"../useFeatureVisibility";
68
import{NavbarView}from"./NavbarView";
79

810
exportconstNavbar:FC=()=>{
9-
const{ appearance, buildInfo}=useDashboard();
11+
const{ appearance}=useDashboard();
12+
constbuildInfoQuery=useQuery(buildInfo());
1013
const{user:me, permissions, signOut}=useAuthenticated();
1114
constfeatureVisibility=useFeatureVisibility();
1215
constcanViewAuditLog=
@@ -19,7 +22,7 @@ export const Navbar: FC = () => {
1922
<NavbarView
2023
user={me}
2124
logo_url={appearance.config.logo_url}
22-
buildInfo={buildInfo}
25+
buildInfo={buildInfoQuery.data}
2326
supportLinks={appearance.config.support_links}
2427
onSignOut={signOut}
2528
canViewAuditLog={canViewAuditLog}

‎site/src/modules/dashboard/Navbar/UserDropdown/UserDropdown.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import{css,typeInterpolation,typeTheme,useTheme}from"@emotion/react";
22
importBadgefrom"@mui/material/Badge";
3-
importtype{FC,ReactNode}from"react";
3+
importtype{FC}from"react";
44
importtype*asTypesGenfrom"api/typesGenerated";
55
import{DropdownArrow}from"components/DropdownArrow/DropdownArrow";
66
import{
@@ -17,7 +17,6 @@ export interface UserDropdownProps {
1717
buildInfo?:TypesGen.BuildInfoResponse;
1818
supportLinks?:readonlyTypesGen.LinkConfig[];
1919
onSignOut:()=>void;
20-
children?:ReactNode;
2120
}
2221

2322
exportconstUserDropdown:FC<UserDropdownProps>=({

‎site/src/modules/resources/AgentVersion.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const AgentVersion: FC<AgentVersionProps> = ({
2424
);
2525

2626
if(status===agentVersionStatus.Updated){
27-
return<span>Updated</span>;
27+
returnnull;
2828
}
2929

3030
return(

‎site/src/modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge.stories.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
importtype{Meta,StoryObj}from"@storybook/react";
22
import{DashboardContext}from"modules/dashboard/DashboardProvider";
33
import{
4+
MockAppearanceConfig,
5+
MockBuildInfo,
46
MockCanceledWorkspace,
57
MockCancelingWorkspace,
68
MockDeletedWorkspace,
79
MockDeletingWorkspace,
10+
MockEntitlementsWithScheduling,
11+
MockExperiments,
812
MockFailedWorkspace,
913
MockPendingWorkspace,
1014
MockStartingWorkspace,
1115
MockStoppedWorkspace,
1216
MockStoppingWorkspace,
1317
MockWorkspace,
14-
MockBuildInfo,
15-
MockEntitlementsWithScheduling,
16-
MockExperiments,
17-
MockAppearanceConfig,
1818
}from"testHelpers/entities";
1919
import{WorkspaceStatusBadge}from"./WorkspaceStatusBadge";
2020

@@ -27,11 +27,18 @@ const MockedAppearance = {
2727
constmeta:Meta<typeofWorkspaceStatusBadge>={
2828
title:"modules/workspaces/WorkspaceStatusBadge",
2929
component:WorkspaceStatusBadge,
30+
parameters:{
31+
queries:[
32+
{
33+
key:["buildInfo"],
34+
data:MockBuildInfo,
35+
},
36+
],
37+
},
3038
decorators:[
3139
(Story)=>(
3240
<DashboardContext.Provider
3341
value={{
34-
buildInfo:MockBuildInfo,
3542
entitlements:MockEntitlementsWithScheduling,
3643
experiments:MockExperiments,
3744
appearance:MockedAppearance,

‎site/src/pages/LoginPage/LoginPage.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { FC } from "react";
22
import{Helmet}from"react-helmet-async";
33
import{useQuery}from"react-query";
44
import{Navigate,useLocation,useNavigate}from"react-router-dom";
5+
import{buildInfo}from"api/queries/buildInfo";
56
import{authMethods}from"api/queries/users";
67
import{useAuthContext}from"contexts/auth/AuthProvider";
78
import{getApplicationName}from"utils/appearance";
@@ -22,6 +23,7 @@ export const LoginPage: FC = () => {
2223
constredirectTo=retrieveRedirect(location.search);
2324
constapplicationName=getApplicationName();
2425
constnavigate=useNavigate();
26+
constbuildInfoQuery=useQuery(buildInfo());
2527

2628
if(isSignedIn){
2729
// If the redirect is going to a workspace application, and we
@@ -65,6 +67,7 @@ export const LoginPage: FC = () => {
6567
authMethods={authMethodsQuery.data}
6668
error={signInError}
6769
isLoading={isLoading||authMethodsQuery.isLoading}
70+
buildInfo={buildInfoQuery.data}
6871
isSigningIn={isSigningIn}
6972
onSignIn={async({ email, password})=>{
7073
awaitsignIn(email,password);

‎site/src/pages/LoginPage/LoginPageView.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
importtype{Interpolation,Theme}from"@emotion/react";
22
importtype{FC}from"react";
33
import{useLocation}from"react-router-dom";
4-
importtype{AuthMethods}from"api/typesGenerated";
4+
importtype{AuthMethods,BuildInfoResponse}from"api/typesGenerated";
55
import{CoderIcon}from"components/Icons/CoderIcon";
66
import{Loader}from"components/Loader/Loader";
77
import{getApplicationName,getLogoURL}from"utils/appearance";
@@ -12,6 +12,7 @@ export interface LoginPageViewProps {
1212
authMethods:AuthMethods|undefined;
1313
error:unknown;
1414
isLoading:boolean;
15+
buildInfo?:BuildInfoResponse;
1516
isSigningIn:boolean;
1617
onSignIn:(credentials:{email:string;password:string})=>void;
1718
}
@@ -20,6 +21,7 @@ export const LoginPageView: FC<LoginPageViewProps> = ({
2021
authMethods,
2122
error,
2223
isLoading,
24+
buildInfo,
2325
isSigningIn,
2426
onSignIn,
2527
})=>{
@@ -64,7 +66,10 @@ export const LoginPageView: FC<LoginPageViewProps> = ({
6466
/>
6567
)}
6668
<footercss={styles.footer}>
67-
Copyright ©{newDate().getFullYear()} Coder Technologies, Inc.
69+
<div>
70+
Copyright &copy;{newDate().getFullYear()} Coder Technologies, Inc.
71+
</div>
72+
<div>{buildInfo?.version}</div>
6873
</footer>
6974
</div>
7075
</div>

‎site/src/pages/WorkspacePage/Workspace.stories.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ const meta: Meta<typeof Workspace> = {
2727
component:Workspace,
2828
parameters:{
2929
queries:[
30+
{
31+
key:["buildInfo"],
32+
data:Mocks.MockBuildInfo,
33+
},
3034
{
3135
key:["portForward",Mocks.MockWorkspaceAgent.id],
3236
data:Mocks.MockListeningPortsResponse,
@@ -37,7 +41,6 @@ const meta: Meta<typeof Workspace> = {
3741
(Story)=>(
3842
<DashboardContext.Provider
3943
value={{
40-
buildInfo:Mocks.MockBuildInfo,
4144
entitlements:Mocks.MockEntitlementsWithScheduling,
4245
experiments:Mocks.MockExperiments,
4346
appearance:MockedAppearance,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp