Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const dummyStore: Partial<AppState> = {
disabling: {},
adding: false,
loading: false,
fetchApplicationError: null,
},
environments: {
entities: {
Expand Down
44 changes: 39 additions & 5 deletions pkg/app/web/src/components/application-detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { AppState } from "../modules";
import {
Application,
ApplicationDeploymentReference,
fetchApplication,
selectById as selectApplicationById,
syncApplication,
} from "../modules/applications";
Expand All @@ -38,6 +39,8 @@ import { DetailTableRow } from "./detail-table-row";
import { ApplicationHealthStatusIcon } from "./health-status-icon";
import { SyncStateReason } from "./sync-state-reason";
import { SyncStatusIcon } from "./sync-status-icon";
import { SerializedError } from "@reduxjs/toolkit";
import { UI_TEXT_REFRESH } from "../constants/ui-text";

const useStyles = makeStyles((theme) => ({
root: {
Expand Down Expand Up @@ -95,13 +98,15 @@ const useIsSyncingApplication = (
});
};

const ERROR_MESSAGE = "It was unable to fetch the application.";

const MostRecentlySuccessfulDeployment: FC<{
deployment?: ApplicationDeploymentReference.AsObject;
}> = ({ deployment }) => {
const classes = useStyles();

if (!deployment) {
return <Skeleton height={63} width={500} />;
return <Skeleton height={105} width={500} />;
}

const date = dayjs(deployment.startedAt * 1000);
Expand Down Expand Up @@ -139,12 +144,17 @@ export const ApplicationDetail: FC<Props> = memo(function ApplicationDetail({
const classes = useStyles();
const dispatch = useDispatch();

const [app, liveState] = useSelector<
const [app, liveState, fetchApplicationError] = useSelector<
AppState,
[Application | undefined, ApplicationLiveState | undefined]
[
Application | undefined,
ApplicationLiveState | undefined,
SerializedError | null
]
>((state) => [
selectApplicationById(state.applications, applicationId),
selectLiveStateById(state.applicationLiveState, applicationId),
state.applications.fetchApplicationError,
]);

const [pipe, env] = useSelector<
Expand All @@ -163,6 +173,30 @@ export const ApplicationDetail: FC<Props> = memo(function ApplicationDetail({
}
};

if (fetchApplicationError) {
return (
<Paper square elevation={1} className={classes.root}>
<Box
height={200}
display="flex"
flexDirection="column"
justifyContent="center"
alignItems="center"
>
<Typography variant="body1">{ERROR_MESSAGE}</Typography>
<Button
color="primary"
onClick={() => {
dispatch(fetchApplication(applicationId));
}}
>
{UI_TEXT_REFRESH}
</Button>
</Box>
</Paper>
);
}

return (
<Paper square elevation={1} className={classes.root}>
<Box flex={1}>
Expand Down Expand Up @@ -242,7 +276,7 @@ export const ApplicationDetail: FC<Props> = memo(function ApplicationDetail({
</tbody>
</table>
) : (
<Skeleton height={63} width={500} />
<Skeleton height={105} width={500} />
)}
</div>

Expand All @@ -258,7 +292,7 @@ export const ApplicationDetail: FC<Props> = memo(function ApplicationDetail({
variant="outlined"
color="primary"
onClick={handleSync}
disabled={isSyncing}
disabled={isSyncing || !app}
startIcon={<SyncIcon />}
>
SYNC
Expand Down
6 changes: 4 additions & 2 deletions pkg/app/web/src/components/application-state-view.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { createStore, render, screen } from "../../test-utils";
import { ApplicationStateView } from "./application-state-view";
import { dummyApplicationLiveState } from "../__fixtures__/dummy-application-live-state";
import { clearError } from "../modules/applications-live-state";
import { fetchApplicationStateById } from "../modules/applications-live-state";
import { UI_TEXT_REFRESH } from "../constants/ui-text";
import userEvent from "@testing-library/user-event";

Expand Down Expand Up @@ -35,5 +35,7 @@ it("shows refresh button if live state fetching has error", () => {

userEvent.click(screen.getByRole("button", { name: UI_TEXT_REFRESH }));

expect(store.getActions()).toMatchObject([{ type: clearError.type }]);
expect(store.getActions()).toMatchObject([
{ type: fetchApplicationStateById.pending.type },
]);
});
4 changes: 2 additions & 2 deletions pkg/app/web/src/components/application-state-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { UI_TEXT_REFRESH } from "../constants/ui-text";
import { AppState } from "../modules";
import {
ApplicationLiveState,
clearError,
fetchApplicationStateById,
selectById as selectLiveStateById,
selectHasError,
} from "../modules/applications-live-state";
Expand Down Expand Up @@ -52,7 +52,7 @@ export const ApplicationStateView: FC<Props> = memo(
<Button
color="primary"
onClick={() => {
dispatch(clearError(applicationId));
dispatch(fetchApplicationStateById(applicationId));
}}
>
{UI_TEXT_REFRESH}
Expand Down
9 changes: 1 addition & 8 deletions pkg/app/web/src/modules/applications-live-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
createAsyncThunk,
createEntityAdapter,
createSlice,
PayloadAction,
} from "@reduxjs/toolkit";
import {
ApplicationLiveStateSnapshot as ApplicationLiveStateSnapshotModel,
Expand Down Expand Up @@ -55,11 +54,7 @@ export const selectHasError = (
export const applicationLiveStateSlice = createSlice({
name: "applicationLiveState",
initialState,
reducers: {
clearError(state, action: PayloadAction<string>) {
state.hasError[action.payload] = false;
},
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchApplicationStateById.pending, (state, action) => {
Expand All @@ -77,6 +72,4 @@ export const applicationLiveStateSlice = createSlice({
},
});

export const { clearError } = applicationLiveStateSlice.actions;

export { ApplicationLiveStateSnapshot as ApplicationLiveStateSnapshotModel } from "pipe/pkg/app/web/model/application_live_state_pb";
Loading