Skip to content

Commit a2d4b99

Browse files
authored
fix: hide app icon if not found (coder#16684)
Fixes: coder#14759
1 parent 6bdddd5 commit a2d4b99

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

site/src/modules/resources/AppLink/AppLink.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
3737
const preferredPathBase = proxy.preferredPathAppURL;
3838
const appsHost = proxy.preferredWildcardHostname;
3939
const [fetchingSessionToken, setFetchingSessionToken] = useState(false);
40+
const [iconError, setIconError] = useState(false);
4041

4142
const theme = useTheme();
4243
const username = workspace.owner_name;
@@ -67,7 +68,9 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
6768
// To avoid bugs in the healthcheck code locking users out of apps, we no
6869
// longer block access to apps if they are unhealthy/initializing.
6970
let canClick = true;
70-
let icon = <BaseIcon app={app} />;
71+
let icon = !iconError && (
72+
<BaseIcon app={app} onIconPathError={() => setIconError(true)} />
73+
);
7174

7275
let primaryTooltip = "";
7376
if (app.health === "initializing") {

site/src/modules/resources/AppLink/BaseIcon.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@ import type { FC } from "react";
44

55
interface BaseIconProps {
66
app: WorkspaceApp;
7+
onIconPathError?: () => void;
78
}
89

9-
export const BaseIcon: FC<BaseIconProps> = ({ app }) => {
10+
export const BaseIcon: FC<BaseIconProps> = ({ app, onIconPathError }) => {
1011
return app.icon ? (
1112
<img
1213
alt={`${app.display_name} Icon`}
1314
src={app.icon}
1415
style={{ pointerEvents: "none" }}
16+
onError={() => {
17+
console.warn(
18+
`Application icon for "${app.id}" has invalid source "${app.icon}".`,
19+
);
20+
onIconPathError?.();
21+
}}
1522
/>
1623
) : (
1724
<ComputerIcon />

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,43 @@ export const Running: Story = {
8080
},
8181
};
8282

83+
export const AppIcons: Story = {
84+
args: {
85+
...Running.args,
86+
workspace: {
87+
...Mocks.MockWorkspace,
88+
latest_build: {
89+
...Mocks.MockWorkspace.latest_build,
90+
resources: [
91+
{
92+
...Mocks.MockWorkspaceResource,
93+
agents: [
94+
{
95+
...Mocks.MockWorkspaceAgent,
96+
apps: [
97+
{
98+
...Mocks.MockWorkspaceApp,
99+
id: "test-app-1",
100+
slug: "test-app-1",
101+
display_name: "Default Icon",
102+
},
103+
{
104+
...Mocks.MockWorkspaceApp,
105+
id: "test-app-2",
106+
slug: "test-app-2",
107+
display_name: "Broken Icon",
108+
icon: "/foobar/broken.png",
109+
},
110+
],
111+
},
112+
],
113+
},
114+
],
115+
},
116+
},
117+
},
118+
};
119+
83120
export const Favorite: Story = {
84121
args: {
85122
...Running.args,

0 commit comments

Comments
 (0)