diff --git a/src/apps/components/AppActivateDialog/AppActivateDialog.stories.tsx b/src/apps/components/AppActivateDialog/AppActivateDialog.stories.tsx
index 27816d680..8e3991fca 100644
--- a/src/apps/components/AppActivateDialog/AppActivateDialog.stories.tsx
+++ b/src/apps/components/AppActivateDialog/AppActivateDialog.stories.tsx
@@ -15,4 +15,4 @@ const props: AppActivateDialogProps = {
storiesOf("Views / Apps / Activate app", module)
.addDecorator(Decorator)
.add("default", () => )
- .add("unnamed app", () => );
+ .add("unnamed app", () => );
diff --git a/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.stories.tsx b/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.stories.tsx
index 456e1db3c..ab30b1bde 100644
--- a/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.stories.tsx
+++ b/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.stories.tsx
@@ -17,4 +17,4 @@ const props: AppDeactivateDialogProps = {
storiesOf("Views / Apps / Deactivate app", module)
.addDecorator(Decorator)
.add("default", () => )
- .add("unnamed app", () => );
+ .add("unnamed app", () => );
diff --git a/src/apps/components/AppDeleteDialog/AppDeleteDialog.stories.tsx b/src/apps/components/AppDeleteDialog/AppDeleteDialog.stories.tsx
index cf9e00eba..3f62edb13 100644
--- a/src/apps/components/AppDeleteDialog/AppDeleteDialog.stories.tsx
+++ b/src/apps/components/AppDeleteDialog/AppDeleteDialog.stories.tsx
@@ -16,4 +16,4 @@ const props: AppDeleteDialogProps = {
storiesOf("Views / Apps / Delete app", module)
.addDecorator(Decorator)
.add("default", () => )
- .add("unnamed app", () => );
+ .add("unnamed app", () => );
diff --git a/src/apps/components/AppDetailsPage/AppDetailsPage.tsx b/src/apps/components/AppDetailsPage/AppDetailsPage.tsx
index a433b10cb..0eeb4d0ff 100644
--- a/src/apps/components/AppDetailsPage/AppDetailsPage.tsx
+++ b/src/apps/components/AppDetailsPage/AppDetailsPage.tsx
@@ -63,7 +63,7 @@ export const AppDetailsPage: React.FC = ({
@@ -109,7 +109,11 @@ export const AppDetailsPage: React.FC = ({
})}
/>
- {!loading ? : }
+ {!loading ? (
+
+ ) : (
+
+ )}
@@ -146,7 +150,7 @@ export const AppDetailsPage: React.FC = ({
- {(loading || data?.dataPrivacyUrl) && (
+ {data?.dataPrivacyUrl && (
= ({
{!loading ? (
= ({
refetch,
}) => {
const shop = useShop();
- const frameRef = React.useRef();
+ const frameRef = React.useRef(null);
const { themeType } = useTheme();
const classes = useStyles();
const appOrigin = getOrigin(src);
diff --git a/src/apps/components/AppFrame/useAppActions.ts b/src/apps/components/AppFrame/useAppActions.ts
index 20c9c0b22..4a83c92ad 100644
--- a/src/apps/components/AppFrame/useAppActions.ts
+++ b/src/apps/components/AppFrame/useAppActions.ts
@@ -34,7 +34,7 @@ const isAppDeepUrlChange = (appId: string, from: string, to: string) => {
};
export const useAppActions = (
- frameEl: React.MutableRefObject,
+ frameEl: React.MutableRefObject,
appOrigin: string,
appId: string,
) => {
@@ -125,7 +125,7 @@ export const useAppActions = (
};
const postToExtension = (event: Events) => {
- if (frameEl.current) {
+ if (frameEl?.current?.contentWindow) {
frameEl.current.contentWindow.postMessage(event, appOrigin);
}
};
diff --git a/src/apps/components/AppFrame/useTokenRefresh.ts b/src/apps/components/AppFrame/useTokenRefresh.ts
index e07e5801c..456330828 100644
--- a/src/apps/components/AppFrame/useTokenRefresh.ts
+++ b/src/apps/components/AppFrame/useTokenRefresh.ts
@@ -9,7 +9,10 @@ interface AppToken {
const TIME_BEFORE_REFRESH = 30 * 1000; // 30 seconds
const useTokenRefresh = (token?: string, refetch?: () => void) => {
- let decoded: AppToken;
+ let decoded: AppToken = {
+ exp: 0,
+ iat: 0,
+ };
// For some reason jwt_decode causes seemingly unrelated error in tests
// It seems like at some point undefined token is passed
@@ -26,11 +29,13 @@ const useTokenRefresh = (token?: string, refetch?: () => void) => {
const refreshTimeout = useRef>(null);
- const tokenLife = (decoded?.exp - decoded?.iat) * 1000; // in ms
+ const tokenLife = ((decoded?.exp || 0) - (decoded?.iat || 0)) * 1000; // in ms
const refreshTime = tokenLife - TIME_BEFORE_REFRESH;
const setUpTimeout = () => {
- refetch();
+ if (refetch) {
+ refetch();
+ }
createTimeout();
};
@@ -50,7 +55,11 @@ const useTokenRefresh = (token?: string, refetch?: () => void) => {
createTimeout();
}
- return () => !!refetch && decodedSuccesfully && deleteTimeout();
+ return () => {
+ if (!!refetch && decodedSuccesfully) {
+ deleteTimeout();
+ }
+ };
}, [token]);
};
diff --git a/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.stories.tsx b/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.stories.tsx
index c72c53cd1..8a274cddd 100644
--- a/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.stories.tsx
+++ b/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.stories.tsx
@@ -17,6 +17,4 @@ const props: AppInProgressDeleteDialogProps = {
storiesOf("Views / Apps / Delete app failed installation", module)
.addDecorator(Decorator)
.add("default", () => )
- .add("unnamed app", () => (
-
- ));
+ .add("unnamed app", () => );
diff --git a/src/apps/components/AppInstallPage/AppInstallPage.stories.tsx b/src/apps/components/AppInstallPage/AppInstallPage.stories.tsx
index 532c93f70..26d248955 100644
--- a/src/apps/components/AppInstallPage/AppInstallPage.stories.tsx
+++ b/src/apps/components/AppInstallPage/AppInstallPage.stories.tsx
@@ -9,7 +9,7 @@ const props: AppInstallPageProps = {
data: installApp,
loading: false,
navigateToAppsList: () => undefined,
- onSubmit: () => undefined,
+ onSubmit: () => Promise.resolve([]),
};
storiesOf("Views / Apps / Install App", module)
diff --git a/src/apps/components/AppInstallPage/AppInstallPage.tsx b/src/apps/components/AppInstallPage/AppInstallPage.tsx
index 4f8946c61..8ad28b827 100644
--- a/src/apps/components/AppInstallPage/AppInstallPage.tsx
+++ b/src/apps/components/AppInstallPage/AppInstallPage.tsx
@@ -17,10 +17,12 @@ import { FormattedMessage, useIntl } from "react-intl";
import { useStyles } from "../../styles";
export interface AppInstallPageProps {
- data: AppFetchMutation["appFetchManifest"]["manifest"];
+ data: NonNullable["manifest"];
loading: boolean;
navigateToAppsList: () => void;
- onSubmit: () => SubmitPromise;
+ onSubmit: () => SubmitPromise<
+ NonNullable["errors"]
+ >;
}
export const AppInstallPage: React.FC = ({
diff --git a/src/apps/components/AppPage/AppPage.stories.tsx b/src/apps/components/AppPage/AppPage.stories.tsx
index 4ef7c2cde..61a8f7995 100644
--- a/src/apps/components/AppPage/AppPage.stories.tsx
+++ b/src/apps/components/AppPage/AppPage.stories.tsx
@@ -7,7 +7,7 @@ import AppPage, { AppPageProps } from "./AppPage";
const props: AppPageProps = {
data: appDetails,
- url: appDetails.appUrl,
+ url: appDetails.appUrl!,
aboutHref: "",
onError: () => undefined,
};
@@ -16,5 +16,5 @@ storiesOf("Views / Apps / App", module)
.addDecorator(Decorator)
.add("default", () => )
.add("settings", () => (
-
+
));
diff --git a/src/apps/components/AppPage/AppPage.tsx b/src/apps/components/AppPage/AppPage.tsx
index 4559585b5..16164fd54 100644
--- a/src/apps/components/AppPage/AppPage.tsx
+++ b/src/apps/components/AppPage/AppPage.tsx
@@ -80,9 +80,9 @@ export const AppPage: React.FC = ({
{url && (
)}
diff --git a/src/apps/components/AppsInProgress/AppsInProgress.tsx b/src/apps/components/AppsInProgress/AppsInProgress.tsx
index 442478450..25feac9a3 100644
--- a/src/apps/components/AppsInProgress/AppsInProgress.tsx
+++ b/src/apps/components/AppsInProgress/AppsInProgress.tsx
@@ -51,65 +51,79 @@ const AppsInProgress: React.FC = ({
/>
- {renderCollection(appsList, ({ status, appName, id, message }) => (
-
-
- {appName}
-
- {status === JobStatusEnum.PENDING && (
-
-
-
-
-
+ {renderCollection(
+ appsList,
+ ({
+ status,
+ appName,
+ id,
+ message,
+ }: AppsInstallationsQuery["appsInstallations"][number]) => (
+
+
+ {appName}
- )}
- {status === JobStatusEnum.FAILED && (
-
-
-
-
-
-
-
-
-
-
-
-
-
- onRemove(id)}
- >
-
-
-
-
- )}
-
- ))}
+
+
+
+ )}
+ {status === JobStatusEnum.FAILED && (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ onRemove(id)}
+ >
+
+
+
+
+ )}
+
+ ),
+ )}
diff --git a/src/apps/components/AppsListPage/AppListPage.stories.tsx b/src/apps/components/AppsListPage/AppListPage.stories.tsx
index af5633bf1..160a3f5ad 100644
--- a/src/apps/components/AppsListPage/AppListPage.stories.tsx
+++ b/src/apps/components/AppsListPage/AppListPage.stories.tsx
@@ -47,7 +47,7 @@ storiesOf("Views / Apps / Apps list", module)
{...props}
appsInProgressList={undefined}
disabled={true}
- installedAppsList={undefined}
+ installedAppsList={[]}
/>
))
.add("no data", () => (
diff --git a/src/apps/components/AppsListPage/AppsListPage.tsx b/src/apps/components/AppsListPage/AppsListPage.tsx
index d92fd0c8c..35808b392 100644
--- a/src/apps/components/AppsListPage/AppsListPage.tsx
+++ b/src/apps/components/AppsListPage/AppsListPage.tsx
@@ -78,15 +78,19 @@ const AppsListPage: React.FC = ({
[installedAppsList, fetchedSaleorApps],
);
- const saleorApps = useMemo(
+ const saleorApps = useMemo(
() =>
- fetchedSaleorApps
- ?.map(app =>
- installedAppsList?.find(installedApp =>
- installedApp.manifestUrl?.includes(app.hostname),
- ),
- )
- .filter(Boolean),
+ (fetchedSaleorApps || []).reduce((acc, app) => {
+ const foundedApp = installedAppsList?.find(installedApp =>
+ installedApp.manifestUrl?.includes(app.hostname),
+ );
+
+ if (foundedApp) {
+ acc.push(foundedApp);
+ }
+
+ return acc;
+ }, []),
[installedAppsList, fetchedSaleorApps],
);
diff --git a/src/apps/components/ExternalAppContext/context.ts b/src/apps/components/ExternalAppContext/context.ts
index c540b8933..c847dcb3c 100644
--- a/src/apps/components/ExternalAppContext/context.ts
+++ b/src/apps/components/ExternalAppContext/context.ts
@@ -16,4 +16,9 @@ export const ExternalAppContext = React.createContext<{
appData: AppData | undefined;
setOpen: React.Dispatch>;
setAppData: React.Dispatch>;
-}>(undefined);
+}>({
+ open: false,
+ appData: undefined,
+ setOpen: () => null,
+ setAppData: () => null,
+});
diff --git a/src/apps/components/HorizontalSpacer/HorizontalSpacer.tsx b/src/apps/components/HorizontalSpacer/HorizontalSpacer.tsx
index 162c239d4..5cbdccb10 100644
--- a/src/apps/components/HorizontalSpacer/HorizontalSpacer.tsx
+++ b/src/apps/components/HorizontalSpacer/HorizontalSpacer.tsx
@@ -7,7 +7,7 @@ export interface HorizontalSpacerProps {
const useStyles = makeStyles(
theme => ({
- container: ({ spacing }: HorizontalSpacerProps) => ({
+ container: ({ spacing }: Required) => ({
width: theme.spacing(spacing),
}),
}),
diff --git a/src/apps/components/InstalledApps/InstalledApps.tsx b/src/apps/components/InstalledApps/InstalledApps.tsx
index 6130a8e84..e22a3b436 100644
--- a/src/apps/components/InstalledApps/InstalledApps.tsx
+++ b/src/apps/components/InstalledApps/InstalledApps.tsx
@@ -104,11 +104,11 @@ const InstalledApps: React.FC = ({
)}
-
+
({
- container: ({ spacing }: VerticalSpacerProps) => ({
+ container: ({ spacing }: Required) => ({
height: theme.spacing(spacing),
}),
}),
diff --git a/src/apps/fixtures.ts b/src/apps/fixtures.ts
index 19790a97c..02f40b359 100644
--- a/src/apps/fixtures.ts
+++ b/src/apps/fixtures.ts
@@ -99,7 +99,7 @@ export const appsInProgress: AppsInstallationsQuery["appsInstallations"] = [
},
];
-export const appDetails: AppQuery["app"] = {
+export const appDetails: NonNullable = {
__typename: "App",
aboutApp: "Lorem ipsum",
accessToken: "token",
@@ -134,7 +134,9 @@ export const appDetails: AppQuery["app"] = {
webhooks: [],
};
-export const installApp: AppFetchMutation["appFetchManifest"]["manifest"] = {
+export const installApp: NonNullable<
+ AppFetchMutation["appFetchManifest"]
+>["manifest"] = {
__typename: "Manifest",
about: "Lorem ipsum",
appUrl: null,
diff --git a/src/apps/useExtensions.ts b/src/apps/useExtensions.ts
index 82f2ac762..b8f0b4a1f 100644
--- a/src/apps/useExtensions.ts
+++ b/src/apps/useExtensions.ts
@@ -14,7 +14,7 @@ import { AppDetailsUrlMountQueryParams } from "./urls";
export interface Extension {
id: string;
- app: RelayToFlat[0]["app"];
+ app: RelayToFlat>[0]["app"];
accessToken: string;
permissions: PermissionEnum[];
label: string;
@@ -54,14 +54,14 @@ export const extensionMountPoints = {
};
const filterAndMapToTarget = (
- extensions: RelayToFlat,
+ extensions: RelayToFlat>,
openApp: (appData: AppData) => void,
): ExtensionWithParams[] =>
extensions.map(
({ id, accessToken, permissions, url, label, mount, target, app }) => ({
id,
app,
- accessToken,
+ accessToken: accessToken || "",
permissions: permissions.map(({ code }) => code),
url,
label,
@@ -69,7 +69,7 @@ const filterAndMapToTarget = (
open: (params: AppDetailsUrlMountQueryParams) =>
openApp({
id: app.id,
- appToken: accessToken,
+ appToken: accessToken || "",
src: url,
label,
target,
@@ -153,7 +153,7 @@ export const useExtensions = (
});
const extensions = filterAndMapToTarget(
- mapEdgesToItems(data?.appExtensions) || [],
+ mapEdgesToItems(data?.appExtensions ?? undefined) || [],
openApp,
);
diff --git a/src/apps/views/App/App.tsx b/src/apps/views/App/App.tsx
index f7e59d66c..4f649d25f 100644
--- a/src/apps/views/App/App.tsx
+++ b/src/apps/views/App/App.tsx
@@ -37,14 +37,14 @@ export const App: React.FC = ({ id }) => {
const appCompleteUrl = getAppCompleteUrlFromDashboardUrl(
location.pathname,
- data?.app.appUrl,
+ data?.app?.appUrl || "",
id,
);
return (
diff --git a/src/apps/views/AppDetails/AppDetails.tsx b/src/apps/views/AppDetails/AppDetails.tsx
index ab8834c47..e51067b78 100644
--- a/src/apps/views/AppDetails/AppDetails.tsx
+++ b/src/apps/views/AppDetails/AppDetails.tsx
@@ -51,7 +51,7 @@ export const AppDetails: React.FC = ({ id, params }) => {
refetch();
closeModal();
} else {
- if (appExists) {
+ if (appExists && errors) {
errors.forEach(error =>
notify({
status: "error",
@@ -65,7 +65,7 @@ export const AppDetails: React.FC = ({ id, params }) => {
const [deactivateApp, deactivateAppResult] = useAppDeactivateMutation({
onCompleted: data => {
const errors = data?.appDeactivate?.errors;
- if (errors.length === 0) {
+ if (errors?.length === 0) {
notify({
status: "success",
text: intl.formatMessage(appMessages.appDeactivated),
@@ -73,7 +73,7 @@ export const AppDetails: React.FC = ({ id, params }) => {
refetch();
closeModal();
} else {
- if (appExists) {
+ if (appExists && errors) {
errors.forEach(error =>
notify({
status: "error",
@@ -105,20 +105,20 @@ export const AppDetails: React.FC = ({ id, params }) => {
<>
navigate(appUrl(id))}
onAppActivateOpen={() => openModal("app-activate")}
diff --git a/src/apps/views/AppInstall/AppInstall.tsx b/src/apps/views/AppInstall/AppInstall.tsx
index d7ba39126..9845c4cfa 100644
--- a/src/apps/views/AppInstall/AppInstall.tsx
+++ b/src/apps/views/AppInstall/AppInstall.tsx
@@ -24,7 +24,9 @@ interface InstallAppCreateProps extends RouteComponentProps {
export const InstallAppCreate: React.FC = ({
params,
}) => {
- const [, setActiveInstallations] = useLocalStorage("activeInstallations", []);
+ const [, setActiveInstallations] = useLocalStorage<
+ Array>
+ >("activeInstallations", []);
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
@@ -32,7 +34,7 @@ export const InstallAppCreate: React.FC = ({
const [fetchManifest, fetchManifestOpts] = useAppFetchMutation({
onCompleted: data => {
- if (data.appFetchManifest.errors.length) {
+ if (data?.appFetchManifest?.errors.length) {
data.appFetchManifest.errors.forEach(error => {
notify({
status: "error",
@@ -44,15 +46,20 @@ export const InstallAppCreate: React.FC = ({
});
const [installApp] = useAppInstallMutation({
onCompleted: data => {
- const installationData = data.appInstall.appInstallation;
- if (data.appInstall.errors.length === 0) {
- setActiveInstallations(activeInstallations => [
- ...activeInstallations,
- { id: installationData.id, name: installationData.appName },
- ]);
+ const installationData = data?.appInstall?.appInstallation;
+ if (data.appInstall?.errors.length === 0) {
+ if (installationData) {
+ setActiveInstallations(activeInstallations => [
+ ...activeInstallations,
+ {
+ id: installationData.id,
+ name: installationData.appName,
+ },
+ ]);
+ }
navigateToAppsList();
} else {
- data.appInstall.errors.forEach(error => {
+ (data?.appInstall?.errors ?? []).forEach(error => {
notify({
status: "error",
text: getAppErrorMessage(error, intl),
@@ -72,7 +79,7 @@ export const InstallAppCreate: React.FC = ({
input: {
appName: manifest?.name,
manifestUrl,
- permissions: manifest?.permissions.map(
+ permissions: manifest?.permissions?.map(
permission => permission.code,
),
},
@@ -97,7 +104,7 @@ export const InstallAppCreate: React.FC = ({
navigate("/")} />
) : (
= ({ id }) => {
return (
diff --git a/src/apps/views/AppsList/AppsList.tsx b/src/apps/views/AppsList/AppsList.tsx
index 313b56621..0beab77b6 100644
--- a/src/apps/views/AppsList/AppsList.tsx
+++ b/src/apps/views/AppsList/AppsList.tsx
@@ -22,6 +22,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import usePaginator, {
createPaginationState,
+ PageInfo,
PaginatorContext,
} from "@saleor/hooks/usePaginator";
import { findById } from "@saleor/misc";
@@ -45,7 +46,7 @@ import { messages } from "./messages";
const getAppInProgressName = (
id: string,
collection?: AppsInstallationsQuery["appsInstallations"],
-) => collection?.find(app => app.id === id)?.appName;
+) => collection?.find(app => app.id === id)?.appName || id;
interface AppsListProps {
params: AppListUrlQueryParams;
}
@@ -92,7 +93,7 @@ export const AppsList: React.FC = ({ params }) => {
});
const paginationValues = usePaginator({
- pageInfo: data?.apps?.pageInfo,
+ pageInfo: data?.apps?.pageInfo as PageInfo,
paginationState,
queryString: params,
});
@@ -113,11 +114,16 @@ export const AppsList: React.FC = ({ params }) => {
const [retryInstallApp] = useAppRetryInstallMutation({
onCompleted: data => {
if (!data?.appRetryInstall?.errors?.length) {
- const appInstallation = data.appRetryInstall.appInstallation;
- setActiveInstallations(installations => [
- ...installations,
- { id: appInstallation.id, name: appInstallation.appName },
- ]);
+ const appInstallation = data.appRetryInstall?.appInstallation;
+ if (appInstallation) {
+ setActiveInstallations(installations => [
+ ...installations,
+ {
+ id: appInstallation.id,
+ name: appInstallation.appName,
+ },
+ ]);
+ }
}
},
});
@@ -226,14 +232,14 @@ export const AppsList: React.FC = ({ params }) => {
const handleRemoveInProgressConfirm = () =>
deleteInProgressApp({
variables: {
- id: params.id,
+ id: params?.id || "",
},
});
const handleRemoveConfirm = () =>
deleteApp({
variables: {
- id: params.id,
+ id: params?.id || "",
},
});
@@ -245,10 +251,10 @@ export const AppsList: React.FC = ({ params }) => {
};
const handleActivateAppConfirm = () =>
- activateApp({ variables: { id: params.id } });
+ activateApp({ variables: { id: params?.id || "" } });
const handleDeactivateAppConfirm = () =>
- deactivateApp({ variables: { id: params.id } });
+ deactivateApp({ variables: { id: params?.id || "" } });
const onAppInstallRetry = (id: string) =>
retryInstallApp({ variables: { id } });
@@ -261,8 +267,8 @@ export const AppsList: React.FC = ({ params }) => {
[activateApp, deactivateApp],
);
- const installedApps = mapEdgesToItems(data?.apps);
- const currentAppName = findById(params.id, installedApps)?.name;
+ const installedApps = mapEdgesToItems(data?.apps || { edges: [] }) || [];
+ const currentAppName = findById(params?.id || "", installedApps)?.name || "";
return (
@@ -292,7 +298,7 @@ export const AppsList: React.FC = ({ params }) => {
(
+ const newPageInfo = useMemo(
() =>
pageInfo
? {
diff --git a/tsconfig.json b/tsconfig.json
index edefe6f39..6bee63da1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -25,4 +25,4 @@
"resolveJsonModule": true
},
"exclude": ["node_modules", "cypress"]
-}
\ No newline at end of file
+}