Extract useDashboardNotification (#362)
* Extract useDashboardNotification Play with config to make app-sdk working in monorepo bump pnpm remove local locks unify deps Changesets Replace appBridge.dispatch(Notification()) with shared useDashboardNotification package Fix build Update klaviyo packages update deps update deps - root next version * update and ix * Restore logic in cms
This commit is contained in:
parent
74174c4763
commit
2e518906d1
46 changed files with 233 additions and 80745 deletions
17
.changeset/lazy-seas-hope.md
Normal file
17
.changeset/lazy-seas-hope.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
"eslint-config-saleor": patch
|
||||||
|
"saleor-app-emails-and-messages": patch
|
||||||
|
"saleor-app-data-importer": patch
|
||||||
|
"saleor-app-products-feed": patch
|
||||||
|
"saleor-app-monitoring": patch
|
||||||
|
"@saleor/apps-shared": patch
|
||||||
|
"saleor-app-invoices": patch
|
||||||
|
"saleor-app-klaviyo": patch
|
||||||
|
"saleor-app-search": patch
|
||||||
|
"saleor-app-slack": patch
|
||||||
|
"saleor-app-taxes": patch
|
||||||
|
"saleor-app-cms": patch
|
||||||
|
"saleor-app-crm": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Update next.js to 13.3.0
|
17
.changeset/proud-laws-live.md
Normal file
17
.changeset/proud-laws-live.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
"eslint-config-saleor": patch
|
||||||
|
"saleor-app-emails-and-messages": patch
|
||||||
|
"saleor-app-data-importer": patch
|
||||||
|
"saleor-app-products-feed": patch
|
||||||
|
"saleor-app-monitoring": patch
|
||||||
|
"@saleor/apps-shared": patch
|
||||||
|
"saleor-app-invoices": patch
|
||||||
|
"saleor-app-klaviyo": patch
|
||||||
|
"saleor-app-search": patch
|
||||||
|
"saleor-app-slack": patch
|
||||||
|
"saleor-app-taxes": patch
|
||||||
|
"saleor-app-cms": patch
|
||||||
|
"saleor-app-crm": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Update @saleor/app-sdk to 0.37.2
|
5
.changeset/spicy-jokes-count.md
Normal file
5
.changeset/spicy-jokes-count.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@saleor/apps-shared": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Added useDashboardNotification hook, that allows quick access to AppBridge.dispatch(Notification())
|
15
.changeset/tasty-badgers-remain.md
Normal file
15
.changeset/tasty-badgers-remain.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
"saleor-app-emails-and-messages": patch
|
||||||
|
"saleor-app-data-importer": patch
|
||||||
|
"saleor-app-products-feed": patch
|
||||||
|
"saleor-app-monitoring": patch
|
||||||
|
"saleor-app-invoices": patch
|
||||||
|
"saleor-app-klaviyo": patch
|
||||||
|
"saleor-app-search": patch
|
||||||
|
"saleor-app-slack": patch
|
||||||
|
"saleor-app-taxes": patch
|
||||||
|
"saleor-app-cms": patch
|
||||||
|
"saleor-app-crm": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Use useDashboardNotification hook from shared package, instead of direct AppBridge usage
|
|
@ -2,7 +2,7 @@ import { useChannelsFetch } from "./useChannelsFetch";
|
||||||
import { MergedChannelSchema, SingleChannelSchema } from "../../../../lib/cms/config";
|
import { MergedChannelSchema, SingleChannelSchema } from "../../../../lib/cms/config";
|
||||||
import { useChannelsQuery } from "../../../../../generated/graphql";
|
import { useChannelsQuery } from "../../../../../generated/graphql";
|
||||||
import { useIsMounted } from "usehooks-ts";
|
import { useIsMounted } from "usehooks-ts";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
export interface ChannelsDataLoading {
|
export interface ChannelsDataLoading {
|
||||||
fetching: boolean;
|
fetching: boolean;
|
||||||
|
@ -15,7 +15,6 @@ export interface ChannelsDataErrors {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useChannels = () => {
|
export const useChannels = () => {
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
const isMounted = useIsMounted();
|
const isMounted = useIsMounted();
|
||||||
const [channelsQueryData, channelsQueryOpts] = useChannelsQuery({
|
const [channelsQueryData, channelsQueryOpts] = useChannelsQuery({
|
||||||
pause: !isMounted,
|
pause: !isMounted,
|
||||||
|
@ -27,6 +26,7 @@ export const useChannels = () => {
|
||||||
error: fetchingError,
|
error: fetchingError,
|
||||||
isFetching,
|
isFetching,
|
||||||
} = useChannelsFetch();
|
} = useChannelsFetch();
|
||||||
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
|
|
||||||
const saveChannel = async (channelToSave: SingleChannelSchema) => {
|
const saveChannel = async (channelToSave: SingleChannelSchema) => {
|
||||||
console.log("saveChannel", channelToSave);
|
console.log("saveChannel", channelToSave);
|
||||||
|
@ -55,21 +55,9 @@ export const useChannels = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (fetchResult.success) {
|
if (fetchResult.success) {
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Configuration saved");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
status: "success",
|
|
||||||
text: "Configuration saved",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", "Error while saving configuration");
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
status: "error",
|
|
||||||
text: "Error while saving configuration",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
import { ProviderInstancesSelect } from "./provider-instances-list";
|
import { ProviderInstancesSelect } from "./provider-instances-list";
|
||||||
import { Add } from "@material-ui/icons";
|
import { Add } from "@material-ui/icons";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
wrapper: {
|
wrapper: {
|
||||||
|
@ -18,13 +19,14 @@ const useStyles = makeStyles({
|
||||||
|
|
||||||
export const ProviderInstances = () => {
|
export const ProviderInstances = () => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
const { providerInstances, saveProviderInstance, deleteProviderInstance, loading, errors } =
|
const { providerInstances, saveProviderInstance, deleteProviderInstance, loading, errors } =
|
||||||
useProviderInstances();
|
useProviderInstances();
|
||||||
|
|
||||||
const [activeProviderInstanceId, setActiveProviderInstanceId] = useState<string | null>(null);
|
const [activeProviderInstanceId, setActiveProviderInstanceId] = useState<string | null>(null);
|
||||||
const [newProviderInstance, setNewProviderInstance] = useState<SingleProviderSchema | null>(null);
|
const [newProviderInstance, setNewProviderInstance] = useState<SingleProviderSchema | null>(null);
|
||||||
|
|
||||||
|
const { notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (providerInstances.length && !activeProviderInstanceId) {
|
if (providerInstances.length && !activeProviderInstanceId) {
|
||||||
setActiveProviderInstanceId(providerInstances[0].id);
|
setActiveProviderInstanceId(providerInstances[0].id);
|
||||||
|
@ -48,13 +50,7 @@ export const ProviderInstances = () => {
|
||||||
const handleSaveProviderInstance = async (providerInstance: SingleProviderSchema) => {
|
const handleSaveProviderInstance = async (providerInstance: SingleProviderSchema) => {
|
||||||
const savedProviderInstance = await saveProviderInstance(providerInstance);
|
const savedProviderInstance = await saveProviderInstance(providerInstance);
|
||||||
|
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Configuration saved");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
status: "success",
|
|
||||||
text: "Configuration saved",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
if (newProviderInstance) {
|
if (newProviderInstance) {
|
||||||
setNewProviderInstance(null);
|
setNewProviderInstance(null);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,21 +0,0 @@
|
||||||
import { useCallback } from "react";
|
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
|
|
||||||
export const useDashboardNotification = () => {
|
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
|
|
||||||
return {
|
|
||||||
notifySuccess: useCallback(
|
|
||||||
(title: string, text: string) => {
|
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
|
||||||
status: "success",
|
|
||||||
title,
|
|
||||||
text,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[appBridge]
|
|
||||||
),
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -2,7 +2,7 @@ import { Box, Button, Checkbox, Text } from "@saleor/macaw-ui/next";
|
||||||
import { trpcClient } from "../../../trpc/trpc-client";
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { ComponentProps, useEffect, useState } from "react";
|
import { ComponentProps, useEffect, useState } from "react";
|
||||||
import { Section } from "../../../ui/section/section";
|
import { Section } from "../../../ui/section/section";
|
||||||
import { useDashboardNotification } from "../../../../lib/use-dashboard-notification";
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
import { MailchimpListPicker } from "../../mailchimp-list-picker/mailchimp-list-picker";
|
import { MailchimpListPicker } from "../../mailchimp-list-picker/mailchimp-list-picker";
|
||||||
|
|
||||||
type EnabledState = {
|
type EnabledState = {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ComponentProps, useEffect, useState } from "react";
|
import { ComponentProps, useEffect, useState } from "react";
|
||||||
import { Box, Button, Text, useTheme, WarningIcon } from "@saleor/macaw-ui/next";
|
import { Box, Button, Text, useTheme, WarningIcon } from "@saleor/macaw-ui/next";
|
||||||
import { trpcClient } from "../trpc/trpc-client";
|
import { trpcClient } from "../trpc/trpc-client";
|
||||||
import { useDashboardNotification } from "../../lib/use-dashboard-notification";
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
import { useFetchAllCustomers } from "./use-fetch-all-customers";
|
import { useFetchAllCustomers } from "./use-fetch-all-customers";
|
||||||
import { Section } from "../ui/section/section";
|
import { Section } from "../ui/section/section";
|
||||||
import { MailchimpListPicker } from "../mailchimp/mailchimp-list-picker/mailchimp-list-picker";
|
import { MailchimpListPicker } from "../mailchimp/mailchimp-list-picker/mailchimp-list-picker";
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,5 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
|
transpilePackages: ["@saleor/apps-shared"],
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,6 +7,7 @@ import { trpcClient } from "../../trpc/trpc-client";
|
||||||
import { SideMenu } from "./side-menu";
|
import { SideMenu } from "./side-menu";
|
||||||
import { LoadingIndicator } from "../../ui/loading-indicator";
|
import { LoadingIndicator } from "../../ui/loading-indicator";
|
||||||
import { Instructions } from "./instructions";
|
import { Instructions } from "./instructions";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -26,6 +27,7 @@ export const ChannelsConfigurationTab = () => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
const { appBridge } = useAppBridge();
|
||||||
const [activeChannelSlug, setActiveChannelSlug] = useState<string | null>(null);
|
const [activeChannelSlug, setActiveChannelSlug] = useState<string | null>(null);
|
||||||
|
const { notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
const { data: channelsData, isLoading: isChannelsDataLoading } =
|
const { data: channelsData, isLoading: isChannelsDataLoading } =
|
||||||
trpcClient.channels.fetch.useQuery(undefined, {
|
trpcClient.channels.fetch.useQuery(undefined, {
|
||||||
|
@ -75,13 +77,8 @@ export const ChannelsConfigurationTab = () => {
|
||||||
trpcClient.appConfiguration.setChannelConfiguration.useMutation({
|
trpcClient.appConfiguration.setChannelConfiguration.useMutation({
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
refetchConfig();
|
refetchConfig();
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
notifySuccess("Success", "Saved app configuration");
|
||||||
title: "Success",
|
|
||||||
text: "Saved app configuration",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { MjmlConfiguration, smtpEncryptionTypes } from "../mjml-config";
|
||||||
import { trpcClient } from "../../../trpc/trpc-client";
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
field: {
|
field: {
|
||||||
|
@ -30,7 +31,7 @@ type Props = {
|
||||||
|
|
||||||
export const MjmlConfigurationForm = (props: Props) => {
|
export const MjmlConfigurationForm = (props: Props) => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
|
|
||||||
const { handleSubmit, control, reset, setError } = useForm<MjmlConfiguration>({
|
const { handleSubmit, control, reset, setError } = useForm<MjmlConfiguration>({
|
||||||
defaultValues: props.initialData,
|
defaultValues: props.initialData,
|
||||||
|
@ -64,12 +65,7 @@ export const MjmlConfigurationForm = (props: Props) => {
|
||||||
|
|
||||||
// Trigger refetch to make sure we have a fresh data
|
// Trigger refetch to make sure we have a fresh data
|
||||||
props.onConfigurationSaved();
|
props.onConfigurationSaved();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Configuration saved");
|
||||||
actions.Notification({
|
|
||||||
title: "Configuration saved",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
let isFieldErrorSet = false;
|
let isFieldErrorSet = false;
|
||||||
|
@ -85,13 +81,10 @@ export const MjmlConfigurationForm = (props: Props) => {
|
||||||
}
|
}
|
||||||
const formErrors = error.data?.zodError?.formErrors || [];
|
const formErrors = error.data?.zodError?.formErrors || [];
|
||||||
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
||||||
appBridge?.dispatch(
|
notifyError(
|
||||||
actions.Notification({
|
"Could not save the configuration",
|
||||||
title: "Could not save the configuration",
|
isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
||||||
text: isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
formErrorMessage
|
||||||
apiMessage: formErrorMessage,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { IconButton, makeStyles } from "@saleor/macaw-ui";
|
import { IconButton, makeStyles } from "@saleor/macaw-ui";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { AppColumnsLayout } from "../../../ui/app-columns-layout";
|
import { AppColumnsLayout } from "../../../ui/app-columns-layout";
|
||||||
import { trpcClient } from "../../../trpc/trpc-client";
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { MjmlConfigurationForm } from "./mjml-configuration-form";
|
import { MjmlConfigurationForm } from "./mjml-configuration-form";
|
||||||
|
@ -14,6 +13,7 @@ import { LoadingIndicator } from "../../../ui/loading-indicator";
|
||||||
import { Add } from "@material-ui/icons";
|
import { Add } from "@material-ui/icons";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { MjmlInstructions } from "./mjml-instructions";
|
import { MjmlInstructions } from "./mjml-instructions";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -50,7 +50,7 @@ const navigateToFirstConfiguration = (router: NextRouter, configurations?: MjmlC
|
||||||
|
|
||||||
export const MjmlConfigurationTab = ({ configurationId }: MjmlConfigurationTabProps) => {
|
export const MjmlConfigurationTab = ({ configurationId }: MjmlConfigurationTabProps) => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
const { notifyError, notifySuccess } = useDashboardNotification();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
@ -72,13 +72,7 @@ export const MjmlConfigurationTab = ({ configurationId }: MjmlConfigurationTabPr
|
||||||
const { mutate: deleteConfiguration } =
|
const { mutate: deleteConfiguration } =
|
||||||
trpcClient.mjmlConfiguration.deleteConfiguration.useMutation({
|
trpcClient.mjmlConfiguration.deleteConfiguration.useMutation({
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
appBridge?.dispatch(
|
notifyError("Could not remove the configuration", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Could not remove the configuration",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onSuccess: async (_data, variables) => {
|
onSuccess: async (_data, variables) => {
|
||||||
await queryClient.cancelQueries({ queryKey: ["mjmlConfiguration", "getConfigurations"] });
|
await queryClient.cancelQueries({ queryKey: ["mjmlConfiguration", "getConfigurations"] });
|
||||||
|
@ -103,13 +97,7 @@ export const MjmlConfigurationTab = ({ configurationId }: MjmlConfigurationTabPr
|
||||||
}
|
}
|
||||||
|
|
||||||
refetchConfigurations();
|
refetchConfigurations();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Removed successfully");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: "Removed successfully",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { useRouter } from "next/router";
|
||||||
import { mjmlUrls } from "../../urls";
|
import { mjmlUrls } from "../../urls";
|
||||||
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
||||||
import { examplePayloads } from "../../../event-handlers/default-payloads";
|
import { examplePayloads } from "../../../event-handlers/default-payloads";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const PREVIEW_DEBOUNCE_DELAY = 500;
|
const PREVIEW_DEBOUNCE_DELAY = 500;
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ export const EventConfigurationForm = ({
|
||||||
configurationId,
|
configurationId,
|
||||||
eventType,
|
eventType,
|
||||||
}: EventConfigurationFormProps) => {
|
}: EventConfigurationFormProps) => {
|
||||||
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { appBridge } = useAppBridge();
|
const { appBridge } = useAppBridge();
|
||||||
const { handleSubmit, control, getValues, setError } = useForm<MjmlEventConfiguration>({
|
const { handleSubmit, control, getValues, setError } = useForm<MjmlEventConfiguration>({
|
||||||
|
@ -113,12 +115,7 @@ export const EventConfigurationForm = ({
|
||||||
const { mutate: updateEventConfiguration } =
|
const { mutate: updateEventConfiguration } =
|
||||||
trpcClient.mjmlConfiguration.updateEventConfiguration.useMutation({
|
trpcClient.mjmlConfiguration.updateEventConfiguration.useMutation({
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Configuration saved");
|
||||||
actions.Notification({
|
|
||||||
title: "Configuration saved",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
let isFieldErrorSet = false;
|
let isFieldErrorSet = false;
|
||||||
|
@ -134,13 +131,11 @@ export const EventConfigurationForm = ({
|
||||||
}
|
}
|
||||||
const formErrors = error.data?.zodError?.formErrors || [];
|
const formErrors = error.data?.zodError?.formErrors || [];
|
||||||
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
notifyError(
|
||||||
title: "Could not save the configuration",
|
"Could not save the configuration",
|
||||||
text: isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
||||||
apiMessage: formErrorMessage,
|
formErrorMessage
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { mjmlUrls } from "../../urls";
|
||||||
import { messageEventTypesLabels } from "../../../event-handlers/message-event-types";
|
import { messageEventTypesLabels } from "../../../event-handlers/message-event-types";
|
||||||
import { MjmlConfiguration } from "../mjml-config";
|
import { MjmlConfiguration } from "../mjml-config";
|
||||||
import { trpcClient } from "../../../trpc/trpc-client";
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -52,18 +52,14 @@ export const MjmlTemplatesCard = ({
|
||||||
}: MjmlTemplatesCardProps) => {
|
}: MjmlTemplatesCardProps) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { appBridge } = useAppBridge();
|
const { notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
const { mutate: updateEventConfiguration } =
|
const { mutate: updateEventConfiguration } =
|
||||||
trpcClient.mjmlConfiguration.updateEventConfiguration.useMutation({
|
trpcClient.mjmlConfiguration.updateEventConfiguration.useMutation({
|
||||||
onSuccess(data, variables) {
|
onSuccess(data, variables) {
|
||||||
onEventChanged();
|
onEventChanged();
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
notifySuccess(variables.active ? "Event enabled" : "Event disabled");
|
||||||
title: variables.active ? "Event enabled" : "Event disabled",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
||||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { fetchSenders } from "../../sendgrid-api";
|
import { fetchSenders } from "../../sendgrid-api";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
field: {
|
field: {
|
||||||
|
@ -41,6 +42,7 @@ type Props = {
|
||||||
export const SendgridConfigurationForm = (props: Props) => {
|
export const SendgridConfigurationForm = (props: Props) => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
const { appBridge } = useAppBridge();
|
||||||
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
const [senderId, setSenderId] = useState<string | undefined>(undefined);
|
const [senderId, setSenderId] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
const { handleSubmit, control, reset, setError, setValue } = useForm<SendgridConfiguration>({
|
const { handleSubmit, control, reset, setError, setValue } = useForm<SendgridConfiguration>({
|
||||||
|
@ -93,12 +95,7 @@ export const SendgridConfigurationForm = (props: Props) => {
|
||||||
|
|
||||||
// Trigger refetch to make sure we have a fresh data
|
// Trigger refetch to make sure we have a fresh data
|
||||||
props.onConfigurationSaved();
|
props.onConfigurationSaved();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Configuration saved");
|
||||||
actions.Notification({
|
|
||||||
title: "Configuration saved",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
let isFieldErrorSet = false;
|
let isFieldErrorSet = false;
|
||||||
|
@ -114,13 +111,11 @@ export const SendgridConfigurationForm = (props: Props) => {
|
||||||
}
|
}
|
||||||
const formErrors = error.data?.zodError?.formErrors || [];
|
const formErrors = error.data?.zodError?.formErrors || [];
|
||||||
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
notifyError(
|
||||||
title: "Could not save the configuration",
|
"Could not save the configuration",
|
||||||
text: isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
||||||
apiMessage: formErrorMessage,
|
formErrorMessage
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { IconButton, makeStyles } from "@saleor/macaw-ui";
|
import { IconButton, makeStyles } from "@saleor/macaw-ui";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { AppColumnsLayout } from "../../../ui/app-columns-layout";
|
import { AppColumnsLayout } from "../../../ui/app-columns-layout";
|
||||||
import { trpcClient } from "../../../trpc/trpc-client";
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { SendgridConfigurationForm } from "./sendgrid-configuration-form";
|
import { SendgridConfigurationForm } from "./sendgrid-configuration-form";
|
||||||
|
@ -14,6 +13,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { sendgridUrls } from "../../urls";
|
import { sendgridUrls } from "../../urls";
|
||||||
import { SendgridTemplatesCard } from "./sendgrid-templates-card";
|
import { SendgridTemplatesCard } from "./sendgrid-templates-card";
|
||||||
import { SendgridInstructions } from "./sendgrid-instructions";
|
import { SendgridInstructions } from "./sendgrid-instructions";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -53,9 +53,9 @@ const navigateToFirstConfiguration = (
|
||||||
|
|
||||||
export const SendgridConfigurationTab = ({ configurationId }: SendgridConfigurationTabProps) => {
|
export const SendgridConfigurationTab = ({ configurationId }: SendgridConfigurationTabProps) => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: configurations,
|
data: configurations,
|
||||||
|
@ -75,13 +75,7 @@ export const SendgridConfigurationTab = ({ configurationId }: SendgridConfigurat
|
||||||
const { mutate: deleteConfiguration } =
|
const { mutate: deleteConfiguration } =
|
||||||
trpcClient.sendgridConfiguration.deleteConfiguration.useMutation({
|
trpcClient.sendgridConfiguration.deleteConfiguration.useMutation({
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
appBridge?.dispatch(
|
notifyError("Could not remove the configuration", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Could not remove the configuration",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onSuccess: async (_data, variables) => {
|
onSuccess: async (_data, variables) => {
|
||||||
await queryClient.cancelQueries({
|
await queryClient.cancelQueries({
|
||||||
|
@ -108,13 +102,8 @@ export const SendgridConfigurationTab = ({ configurationId }: SendgridConfigurat
|
||||||
}
|
}
|
||||||
|
|
||||||
refetchConfigurations();
|
refetchConfigurations();
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
notifySuccess("Success", "Removed successfully");
|
||||||
title: "Success",
|
|
||||||
text: "Removed successfully",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {
|
||||||
InputLabel,
|
InputLabel,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Select,
|
Select,
|
||||||
TextField,
|
|
||||||
TextFieldProps,
|
TextFieldProps,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
@ -26,9 +25,9 @@ import {
|
||||||
import { trpcClient } from "../../../trpc/trpc-client";
|
import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { sendgridUrls } from "../../urls";
|
import { sendgridUrls } from "../../urls";
|
||||||
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { fetchTemplates } from "../../sendgrid-api";
|
import { fetchTemplates } from "../../sendgrid-api";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
viewContainer: {
|
viewContainer: {
|
||||||
|
@ -79,7 +78,8 @@ export const EventConfigurationForm = ({
|
||||||
configuration,
|
configuration,
|
||||||
}: EventConfigurationFormProps) => {
|
}: EventConfigurationFormProps) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { appBridge } = useAppBridge();
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
|
|
||||||
const { handleSubmit, control, getValues, setError } = useForm<SendgridEventConfiguration>({
|
const { handleSubmit, control, getValues, setError } = useForm<SendgridEventConfiguration>({
|
||||||
defaultValues: initialData,
|
defaultValues: initialData,
|
||||||
});
|
});
|
||||||
|
@ -100,12 +100,7 @@ export const EventConfigurationForm = ({
|
||||||
const { mutate: updateEventConfiguration } =
|
const { mutate: updateEventConfiguration } =
|
||||||
trpcClient.sendgridConfiguration.updateEventConfiguration.useMutation({
|
trpcClient.sendgridConfiguration.updateEventConfiguration.useMutation({
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
appBridge?.dispatch(
|
notifySuccess("Configuration saved");
|
||||||
actions.Notification({
|
|
||||||
title: "Configuration saved",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
let isFieldErrorSet = false;
|
let isFieldErrorSet = false;
|
||||||
|
@ -121,13 +116,10 @@ export const EventConfigurationForm = ({
|
||||||
}
|
}
|
||||||
const formErrors = error.data?.zodError?.formErrors || [];
|
const formErrors = error.data?.zodError?.formErrors || [];
|
||||||
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
const formErrorMessage = formErrors.length ? formErrors.join("\n") : undefined;
|
||||||
appBridge?.dispatch(
|
notifyError(
|
||||||
actions.Notification({
|
"Could not save the configuration",
|
||||||
title: "Could not save the configuration",
|
isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
||||||
text: isFieldErrorSet ? "Submitted form contain errors" : "Error saving configuration",
|
formErrorMessage
|
||||||
apiMessage: formErrorMessage,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { trpcClient } from "../../../trpc/trpc-client";
|
||||||
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
import { useAppBridge, actions } from "@saleor/app-sdk/app-bridge";
|
||||||
import { SendgridConfiguration } from "../sendgrid-config";
|
import { SendgridConfiguration } from "../sendgrid-config";
|
||||||
import { sendgridUrls } from "../../urls";
|
import { sendgridUrls } from "../../urls";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -52,18 +53,13 @@ export const SendgridTemplatesCard = ({
|
||||||
}: SendgridTemplatesCardProps) => {
|
}: SendgridTemplatesCardProps) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { appBridge } = useAppBridge();
|
const { notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
const { mutate: updateEventConfiguration } =
|
const { mutate: updateEventConfiguration } =
|
||||||
trpcClient.sendgridConfiguration.updateEventConfiguration.useMutation({
|
trpcClient.sendgridConfiguration.updateEventConfiguration.useMutation({
|
||||||
onSuccess(_data, variables) {
|
onSuccess(_data, variables) {
|
||||||
onEventChanged();
|
onEventChanged();
|
||||||
appBridge?.dispatch(
|
notifySuccess(variables.active ? "Event enabled" : "Event disabled");
|
||||||
actions.Notification({
|
|
||||||
title: variables.active ? "Event enabled" : "Event disabled",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,6 +7,7 @@ import { AddressForm } from "./address-form";
|
||||||
import { ChannelsList } from "./channels-list";
|
import { ChannelsList } from "./channels-list";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||||
import { AppColumnsLayout } from "../../ui/app-columns-layout";
|
import { AppColumnsLayout } from "../../ui/app-columns-layout";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -23,6 +24,7 @@ const useStyles = makeStyles((theme) => {
|
||||||
export const ChannelsConfiguration = () => {
|
export const ChannelsConfiguration = () => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
const { appBridge } = useAppBridge();
|
||||||
|
const { notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
const { data: configurationData, refetch: refetchConfig } =
|
const { data: configurationData, refetch: refetchConfig } =
|
||||||
trpcClient.appConfiguration.fetch.useQuery();
|
trpcClient.appConfiguration.fetch.useQuery();
|
||||||
|
@ -34,13 +36,7 @@ export const ChannelsConfiguration = () => {
|
||||||
const { mutate, error: saveError } = trpcClient.appConfiguration.setAndReplace.useMutation({
|
const { mutate, error: saveError } = trpcClient.appConfiguration.setAndReplace.useMutation({
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
refetchConfig();
|
refetchConfig();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Saved app configuration");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: "Saved app configuration",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ const nextConfig = {
|
||||||
disableServerWebpackPlugin: !isSentryPropertiesInEnvironment,
|
disableServerWebpackPlugin: !isSentryPropertiesInEnvironment,
|
||||||
disableClientWebpackPlugin: !isSentryPropertiesInEnvironment,
|
disableClientWebpackPlugin: !isSentryPropertiesInEnvironment,
|
||||||
},
|
},
|
||||||
transpilePackages: ["nuvo-react", "@saleor/apps-shared"],
|
transpilePackages: ["@saleor/apps-shared"],
|
||||||
redirects() {
|
redirects() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,8 +9,7 @@ import { ChangeEvent, SyntheticEvent, useEffect, useState } from "react";
|
||||||
import { AccessWarning } from "../components/AccessWarning/AccessWarning";
|
import { AccessWarning } from "../components/AccessWarning/AccessWarning";
|
||||||
import { useAppApi } from "../hooks/useAppApi";
|
import { useAppApi } from "../hooks/useAppApi";
|
||||||
import { AppColumnsLayout } from "../lib/ui/app-columns-layout";
|
import { AppColumnsLayout } from "../lib/ui/app-columns-layout";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
import { useDashboardNotifier } from "../utils/useDashboardNotifier";
|
|
||||||
|
|
||||||
interface ConfigurationField {
|
interface ConfigurationField {
|
||||||
key: string;
|
key: string;
|
||||||
|
@ -124,7 +123,7 @@ function Instructions() {
|
||||||
function Configuration() {
|
function Configuration() {
|
||||||
const { appBridgeState } = useAppBridge();
|
const { appBridgeState } = useAppBridge();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const [notify] = useDashboardNotifier();
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
const [configuration, setConfiguration] = useState<ConfigurationField[]>();
|
const [configuration, setConfiguration] = useState<ConfigurationField[]>();
|
||||||
const [transitionState, setTransitionState] = useState<ConfirmButtonTransitionState>("default");
|
const [transitionState, setTransitionState] = useState<ConfirmButtonTransitionState>("default");
|
||||||
|
|
||||||
|
@ -160,19 +159,13 @@ function Configuration() {
|
||||||
}
|
}
|
||||||
setTransitionState("success");
|
setTransitionState("success");
|
||||||
|
|
||||||
await notify({
|
notifySuccess("Success", "Configuration updated successfully");
|
||||||
status: "success",
|
|
||||||
title: "Success",
|
|
||||||
text: "Configuration updated successfully",
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(async () => {
|
.catch(async () => {
|
||||||
setTransitionState("error");
|
setTransitionState("error");
|
||||||
await notify({
|
await notifyError(
|
||||||
status: "error",
|
"Configuration update failed. Ensure fields are filled correctly and you have MANAGE_APPS permission"
|
||||||
title:
|
);
|
||||||
"Configuration update failed. Ensure fields are filled correctly and you have MANAGE_APPS permission",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { actions, NotificationPayload, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
|
|
||||||
export const useDashboardNotifier = () => {
|
|
||||||
const { appBridgeState, appBridge } = useAppBridge();
|
|
||||||
|
|
||||||
const notify = (payload: NotificationPayload) =>
|
|
||||||
appBridgeState?.ready && appBridge?.dispatch(actions.Notification(payload));
|
|
||||||
|
|
||||||
return [notify];
|
|
||||||
};
|
|
|
@ -1,5 +1,6 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
transpilePackages: ["@saleor/apps-shared"],
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
rewrites() {
|
rewrites() {
|
||||||
/**
|
/**
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,30 +0,0 @@
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
|
|
||||||
export const useDashboardNotifications = () => {
|
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
|
|
||||||
const showSuccessNotification = (title: string, text: string) => {
|
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
|
||||||
title: title,
|
|
||||||
text: text,
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const showErrorNotification = (title: string, text: string) => {
|
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
|
||||||
title: title,
|
|
||||||
text: text,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
showSuccessNotification,
|
|
||||||
showErrorNotification,
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -28,8 +28,9 @@ import { gql, useMutation } from "urql";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||||
import { ArrowBack } from "@material-ui/icons";
|
import { ArrowBack } from "@material-ui/icons";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useDashboardNotifications } from "../../lib/use-dashboard-notifications";
|
|
||||||
import { API_KEYS_LINKS } from "../../datadog-urls";
|
import { API_KEYS_LINKS } from "../../datadog-urls";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
form: {
|
form: {
|
||||||
|
@ -133,7 +134,7 @@ export const DatadogConfig = () => {
|
||||||
const [, mutateCredentials] = useUpdateCredentialsMutation();
|
const [, mutateCredentials] = useUpdateCredentialsMutation();
|
||||||
const [, deleteCredentials] = useDeleteDatadogCredentialsMutation();
|
const [, deleteCredentials] = useDeleteDatadogCredentialsMutation();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { showSuccessNotification, showErrorNotification } = useDashboardNotifications();
|
const { notifyError, notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
const { register, handleSubmit, setValue, control, reset, watch } = useForm<
|
const { register, handleSubmit, setValue, control, reset, watch } = useForm<
|
||||||
DataDogCredentialsInput & {
|
DataDogCredentialsInput & {
|
||||||
|
@ -213,14 +214,11 @@ export const DatadogConfig = () => {
|
||||||
setValue("apiKey", buildMaskedKey(updatedConfig.credentials.apiKeyLast4));
|
setValue("apiKey", buildMaskedKey(updatedConfig.credentials.apiKeyLast4));
|
||||||
setValue("site", updatedConfig.credentials.site);
|
setValue("site", updatedConfig.credentials.site);
|
||||||
|
|
||||||
showSuccessNotification(
|
notifySuccess("Configuration updated", "Successfully updated Datadog settings");
|
||||||
"Configuration updated",
|
|
||||||
"Successfully updated Datadog settings"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errors?.length) {
|
if (errors?.length) {
|
||||||
showErrorNotification("Error configuring Datadog", errors[0].message);
|
notifyError("Error configuring Datadog", errors[0].message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})}
|
})}
|
||||||
|
@ -278,10 +276,7 @@ export const DatadogConfig = () => {
|
||||||
deleteCredentials({}).then(() => {
|
deleteCredentials({}).then(() => {
|
||||||
fetchConfig();
|
fetchConfig();
|
||||||
reset();
|
reset();
|
||||||
showSuccessNotification(
|
notifySuccess("Configuration updated", "Successfully deleted Datadog settings");
|
||||||
"Configuration updated",
|
|
||||||
"Successfully deleted Datadog settings"
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
|
transpilePackages: ["@saleor/apps-shared"],
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,7 @@ import { AppColumnsLayout } from "../../ui/app-columns-layout";
|
||||||
import { FeedPreviewCard } from "./feed-preview-card";
|
import { FeedPreviewCard } from "./feed-preview-card";
|
||||||
import { Instructions } from "./instructions";
|
import { Instructions } from "./instructions";
|
||||||
import { SideMenu } from "./side-menu";
|
import { SideMenu } from "./side-menu";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => {
|
const useStyles = makeStyles((theme) => {
|
||||||
return {
|
return {
|
||||||
|
@ -33,6 +34,7 @@ export const ChannelsConfiguration = () => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
|
|
||||||
const { appBridge } = useAppBridge();
|
const { appBridge } = useAppBridge();
|
||||||
|
const { notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
const { data: configurationData, refetch: refetchConfig } =
|
const { data: configurationData, refetch: refetchConfig } =
|
||||||
trpcClient.appConfiguration.fetch.useQuery();
|
trpcClient.appConfiguration.fetch.useQuery();
|
||||||
|
@ -44,13 +46,7 @@ export const ChannelsConfiguration = () => {
|
||||||
const { mutate, error: saveError } = trpcClient.appConfiguration.setAndReplace.useMutation({
|
const { mutate, error: saveError } = trpcClient.appConfiguration.setAndReplace.useMutation({
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
refetchConfig();
|
refetchConfig();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Saved app configuration");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: "Saved app configuration",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,7 @@
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import {
|
import { FormControl, Grid, InputLabel, MenuItem, Select, Typography } from "@material-ui/core";
|
||||||
FormControl,
|
|
||||||
Grid,
|
|
||||||
InputLabel,
|
|
||||||
MenuItem,
|
|
||||||
Select,
|
|
||||||
TextFieldProps,
|
|
||||||
Typography,
|
|
||||||
} from "@material-ui/core";
|
|
||||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import {
|
import {
|
||||||
SetCategoryMappingInputSchema,
|
SetCategoryMappingInputSchema,
|
||||||
|
@ -19,6 +10,7 @@ import {
|
||||||
import { CategoryWithMappingFragmentFragment } from "../../../../generated/graphql";
|
import { CategoryWithMappingFragmentFragment } from "../../../../generated/graphql";
|
||||||
import { GoogleProductCategories } from "../google-product-categories";
|
import { GoogleProductCategories } from "../google-product-categories";
|
||||||
import { trpcClient } from "../../trpc/trpc-client";
|
import { trpcClient } from "../../trpc/trpc-client";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
field: {
|
field: {
|
||||||
|
@ -39,7 +31,7 @@ type CategoryMappingFormProps = {
|
||||||
|
|
||||||
export const CategoryMappingForm = ({ category }: CategoryMappingFormProps) => {
|
export const CategoryMappingForm = ({ category }: CategoryMappingFormProps) => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
|
|
||||||
const { control, handleSubmit, formState } = useForm<SetCategoryMappingInputType>({
|
const { control, handleSubmit, formState } = useForm<SetCategoryMappingInputType>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
|
@ -50,20 +42,10 @@ export const CategoryMappingForm = ({ category }: CategoryMappingFormProps) => {
|
||||||
});
|
});
|
||||||
const { mutate, isLoading } = trpcClient.categoryMapping.setCategoryMapping.useMutation({
|
const { mutate, isLoading } = trpcClient.categoryMapping.setCategoryMapping.useMutation({
|
||||||
onError() {
|
onError() {
|
||||||
appBridge?.dispatch(
|
notifyError("Could not save the category mapping");
|
||||||
actions.Notification({
|
|
||||||
title: "Could not save the category mapping",
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -17,8 +17,8 @@ import { ChangeEvent, ReactElement, SyntheticEvent, useEffect, useState } from "
|
||||||
import { AccessWarning } from "../components/AccessWarning/AccessWarning";
|
import { AccessWarning } from "../components/AccessWarning/AccessWarning";
|
||||||
import { ConfigurationError } from "../components/ConfigurationError/ConfigurationError";
|
import { ConfigurationError } from "../components/ConfigurationError/ConfigurationError";
|
||||||
import { useAppApi } from "../hooks/useAppApi";
|
import { useAppApi } from "../hooks/useAppApi";
|
||||||
import { useDashboardNotifier } from "../utils/useDashboardNotifier";
|
|
||||||
import { AppColumnsLayout } from "../components/AppColumnsLayout/AppColumnsLayout";
|
import { AppColumnsLayout } from "../components/AppColumnsLayout/AppColumnsLayout";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
interface ConfigurationField {
|
interface ConfigurationField {
|
||||||
key: string;
|
key: string;
|
||||||
|
@ -40,7 +40,7 @@ const useStyles = makeStyles((theme) => ({
|
||||||
function Configuration() {
|
function Configuration() {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { appBridgeState } = useAppBridge();
|
const { appBridgeState } = useAppBridge();
|
||||||
const [notify] = useDashboardNotifier();
|
const { notifyError, notifySuccess } = useDashboardNotification();
|
||||||
const [configuration, setConfiguration] = useState<ConfigurationField[]>();
|
const [configuration, setConfiguration] = useState<ConfigurationField[]>();
|
||||||
const [transitionState, setTransitionState] = useState<ConfirmButtonTransitionState>("default");
|
const [transitionState, setTransitionState] = useState<ConfirmButtonTransitionState>("default");
|
||||||
|
|
||||||
|
@ -69,18 +69,11 @@ function Configuration() {
|
||||||
})
|
})
|
||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
setTransitionState(response.status === 200 ? "success" : "error");
|
setTransitionState(response.status === 200 ? "success" : "error");
|
||||||
await notify({
|
notifySuccess("Success", "Configuration updated successfully");
|
||||||
status: "success",
|
|
||||||
title: "Success",
|
|
||||||
text: "Configuration updated successfully",
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(async () => {
|
.catch(async () => {
|
||||||
setTransitionState("error");
|
setTransitionState("error");
|
||||||
await notify({
|
await notifyError("Configuration update failed");
|
||||||
status: "error",
|
|
||||||
title: "Configuration update failed",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { actions, NotificationPayload, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
|
|
||||||
export const useDashboardNotifier = () => {
|
|
||||||
const { appBridge, appBridgeState } = useAppBridge();
|
|
||||||
|
|
||||||
const notify = (payload: NotificationPayload) =>
|
|
||||||
appBridgeState?.ready && appBridge?.dispatch(actions.Notification(payload));
|
|
||||||
|
|
||||||
return [notify];
|
|
||||||
};
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,7 +8,6 @@ import {
|
||||||
TextFieldProps,
|
TextFieldProps,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { Delete, Save } from "@material-ui/icons";
|
import { Delete, Save } from "@material-ui/icons";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
@ -17,6 +16,7 @@ import { useInstanceId } from "../../taxes/tax-context";
|
||||||
import { trpcClient } from "../../trpc/trpc-client";
|
import { trpcClient } from "../../trpc/trpc-client";
|
||||||
import { AppLink } from "../../ui/app-link";
|
import { AppLink } from "../../ui/app-link";
|
||||||
import { avataxConfigSchema } from "../avatax-config";
|
import { avataxConfigSchema } from "../avatax-config";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
reverseRow: {
|
reverseRow: {
|
||||||
|
@ -39,9 +39,9 @@ const defaultValues: FormValues = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AvataxConfigurationForm = () => {
|
export const AvataxConfigurationForm = () => {
|
||||||
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
const [isWarningDialogOpen, setIsWarningDialogOpen] = React.useState(false);
|
const [isWarningDialogOpen, setIsWarningDialogOpen] = React.useState(false);
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
const { handleSubmit, reset, control, formState } = useForm<FormValues>({
|
const { handleSubmit, reset, control, formState } = useForm<FormValues>({
|
||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
defaultValues,
|
defaultValues,
|
||||||
|
@ -50,13 +50,7 @@ export const AvataxConfigurationForm = () => {
|
||||||
const { refetch: refetchChannelConfigurationData } =
|
const { refetch: refetchChannelConfigurationData } =
|
||||||
trpcClient.channelsConfiguration.fetch.useQuery(undefined, {
|
trpcClient.channelsConfiguration.fetch.useQuery(undefined, {
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { refetch: refetchProvidersConfigurationData } =
|
const { refetch: refetchProvidersConfigurationData } =
|
||||||
|
@ -66,13 +60,7 @@ export const AvataxConfigurationForm = () => {
|
||||||
{
|
{
|
||||||
enabled: !!instanceId,
|
enabled: !!instanceId,
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -95,22 +83,10 @@ export const AvataxConfigurationForm = () => {
|
||||||
onSuccess({ id }) {
|
onSuccess({ id }) {
|
||||||
setInstanceId(id);
|
setInstanceId(id);
|
||||||
refetchProvidersConfigurationData();
|
refetchProvidersConfigurationData();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Saved app configuration");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: "Saved app configuration",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -118,22 +94,10 @@ export const AvataxConfigurationForm = () => {
|
||||||
trpcClient.avataxConfiguration.patch.useMutation({
|
trpcClient.avataxConfiguration.patch.useMutation({
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
refetchProvidersConfigurationData();
|
refetchProvidersConfigurationData();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Updated Avalara configuration");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: "Updated Avalara configuration",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -142,22 +106,10 @@ export const AvataxConfigurationForm = () => {
|
||||||
resetInstanceId();
|
resetInstanceId();
|
||||||
refetchProvidersConfigurationData();
|
refetchProvidersConfigurationData();
|
||||||
refetchChannelConfigurationData();
|
refetchChannelConfigurationData();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Removed Avatax instance");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: "Removed Avatax instance",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import {
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { Save } from "@material-ui/icons";
|
import { Save } from "@material-ui/icons";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -25,6 +24,7 @@ import { ProvidersConfig } from "../../providers-configuration/providers-config"
|
||||||
import { ProviderIcon } from "../../providers-configuration/ui/provider-icon";
|
import { ProviderIcon } from "../../providers-configuration/ui/provider-icon";
|
||||||
import { useChannelSlug } from "../../taxes/tax-context";
|
import { useChannelSlug } from "../../taxes/tax-context";
|
||||||
import { trpcClient } from "../../trpc/trpc-client";
|
import { trpcClient } from "../../trpc/trpc-client";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
type ChannelTaxProviderFormValues = ChannelConfig;
|
type ChannelTaxProviderFormValues = ChannelConfig;
|
||||||
|
|
||||||
|
@ -70,23 +70,17 @@ const getDefaultFormValues = (
|
||||||
// todo: rename because address is here
|
// todo: rename because address is here
|
||||||
export const ChannelTaxProviderForm = () => {
|
export const ChannelTaxProviderForm = () => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
const { control, reset, handleSubmit } = useForm<ChannelTaxProviderFormValues>({
|
const { control, reset, handleSubmit } = useForm<ChannelTaxProviderFormValues>({
|
||||||
resolver: zodResolver(channelSchema),
|
resolver: zodResolver(channelSchema),
|
||||||
});
|
});
|
||||||
|
const { notifyError, notifySuccess } = useDashboardNotification();
|
||||||
|
|
||||||
const { channelSlug } = useChannelSlug();
|
const { channelSlug } = useChannelSlug();
|
||||||
|
|
||||||
const { data: channelConfigurationData, refetch: refetchChannelConfigurationData } =
|
const { data: channelConfigurationData, refetch: refetchChannelConfigurationData } =
|
||||||
trpcClient.channelsConfiguration.fetch.useQuery(undefined, {
|
trpcClient.channelsConfiguration.fetch.useQuery(undefined, {
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -94,13 +88,7 @@ export const ChannelTaxProviderForm = () => {
|
||||||
undefined,
|
undefined,
|
||||||
{
|
{
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -109,22 +97,10 @@ export const ChannelTaxProviderForm = () => {
|
||||||
const { mutate, isLoading } = trpcClient.channelsConfiguration.upsert.useMutation({
|
const { mutate, isLoading } = trpcClient.channelsConfiguration.upsert.useMutation({
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
refetchChannelConfigurationData();
|
refetchChannelConfigurationData();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", `Saved configuration of channel: ${channelSlug}`);
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: `Saved configuration of channel: ${channelSlug}`,
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
TextFieldProps,
|
TextFieldProps,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { Delete, Save } from "@material-ui/icons";
|
import { Delete, Save } from "@material-ui/icons";
|
||||||
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
||||||
import { Button, makeStyles } from "@saleor/macaw-ui";
|
import { Button, makeStyles } from "@saleor/macaw-ui";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
@ -16,6 +15,7 @@ import { z } from "zod";
|
||||||
import { useInstanceId } from "../../taxes/tax-context";
|
import { useInstanceId } from "../../taxes/tax-context";
|
||||||
import { trpcClient } from "../../trpc/trpc-client";
|
import { trpcClient } from "../../trpc/trpc-client";
|
||||||
import { taxJarConfigSchema } from "../taxjar-config";
|
import { taxJarConfigSchema } from "../taxjar-config";
|
||||||
|
import { useDashboardNotification } from "@saleor/apps-shared";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
reverseRow: {
|
reverseRow: {
|
||||||
|
@ -38,11 +38,11 @@ export const TaxJarConfigurationForm = () => {
|
||||||
const [isWarningDialogOpen, setIsWarningDialogOpen] = React.useState(false);
|
const [isWarningDialogOpen, setIsWarningDialogOpen] = React.useState(false);
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { instanceId, setInstanceId } = useInstanceId();
|
const { instanceId, setInstanceId } = useInstanceId();
|
||||||
const { appBridge } = useAppBridge();
|
|
||||||
const { handleSubmit, reset, control, formState } = useForm<FormValues>({
|
const { handleSubmit, reset, control, formState } = useForm<FormValues>({
|
||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
defaultValues,
|
defaultValues,
|
||||||
});
|
});
|
||||||
|
const { notifySuccess, notifyError } = useDashboardNotification();
|
||||||
|
|
||||||
const resetInstanceId = () => {
|
const resetInstanceId = () => {
|
||||||
setInstanceId(null);
|
setInstanceId(null);
|
||||||
|
@ -51,13 +51,7 @@ export const TaxJarConfigurationForm = () => {
|
||||||
const { refetch: refetchChannelConfigurationData } =
|
const { refetch: refetchChannelConfigurationData } =
|
||||||
trpcClient.channelsConfiguration.fetch.useQuery(undefined, {
|
trpcClient.channelsConfiguration.fetch.useQuery(undefined, {
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,13 +62,7 @@ export const TaxJarConfigurationForm = () => {
|
||||||
{
|
{
|
||||||
enabled: !!instanceId,
|
enabled: !!instanceId,
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -85,22 +73,11 @@ export const TaxJarConfigurationForm = () => {
|
||||||
setInstanceId(id);
|
setInstanceId(id);
|
||||||
refetchProvidersConfigurationData();
|
refetchProvidersConfigurationData();
|
||||||
refetchChannelConfigurationData();
|
refetchChannelConfigurationData();
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
notifySuccess("Success", "Saved TaxJar configuration");
|
||||||
title: "Success",
|
|
||||||
text: "Saved TaxJar configuration",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -109,22 +86,10 @@ export const TaxJarConfigurationForm = () => {
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
refetchProvidersConfigurationData();
|
refetchProvidersConfigurationData();
|
||||||
refetchChannelConfigurationData();
|
refetchChannelConfigurationData();
|
||||||
appBridge?.dispatch(
|
notifySuccess("Success", "Updated TaxJar configuration");
|
||||||
actions.Notification({
|
|
||||||
title: "Success",
|
|
||||||
text: "Updated TaxJar configuration",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -134,22 +99,11 @@ export const TaxJarConfigurationForm = () => {
|
||||||
resetInstanceId();
|
resetInstanceId();
|
||||||
refetchProvidersConfigurationData();
|
refetchProvidersConfigurationData();
|
||||||
refetchChannelConfigurationData();
|
refetchChannelConfigurationData();
|
||||||
appBridge?.dispatch(
|
|
||||||
actions.Notification({
|
notifySuccess("Success", "Removed TaxJar instance");
|
||||||
title: "Success",
|
|
||||||
text: "Removed TaxJar instance",
|
|
||||||
status: "success",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
appBridge?.dispatch(
|
notifyError("Error", error.message);
|
||||||
actions.Notification({
|
|
||||||
title: "Error",
|
|
||||||
text: error.message,
|
|
||||||
status: "error",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
export * from "./src/is-in-iframe";
|
export * from "./src/is-in-iframe";
|
||||||
export * from "./src/macaw-theme-provider/macaw-theme-provider";
|
export * from "./src/macaw-theme-provider/macaw-theme-provider";
|
||||||
export * from "./src/no-ssr-wrapper";
|
export * from "./src/no-ssr-wrapper";
|
||||||
|
export * from "./src/use-dashboard-notification";
|
||||||
|
|
58
packages/shared/src/use-dashboard-notification.ts
Normal file
58
packages/shared/src/use-dashboard-notification.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
||||||
|
|
||||||
|
export const useDashboardNotification = () => {
|
||||||
|
const { appBridge } = useAppBridge();
|
||||||
|
|
||||||
|
return {
|
||||||
|
notifySuccess: useCallback(
|
||||||
|
(title: string, text?: string) => {
|
||||||
|
appBridge?.dispatch(
|
||||||
|
actions.Notification({
|
||||||
|
status: "success",
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[appBridge]
|
||||||
|
),
|
||||||
|
notifyError: useCallback(
|
||||||
|
(title: string, text?: string, apiMessage?: string) => {
|
||||||
|
appBridge?.dispatch(
|
||||||
|
actions.Notification({
|
||||||
|
status: "error",
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
apiMessage: apiMessage,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[appBridge]
|
||||||
|
),
|
||||||
|
notifyWarning: useCallback(
|
||||||
|
(title: string, text?: string) => {
|
||||||
|
appBridge?.dispatch(
|
||||||
|
actions.Notification({
|
||||||
|
status: "warning",
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[appBridge]
|
||||||
|
),
|
||||||
|
notifyInfo: useCallback(
|
||||||
|
(title: string, text?: string) => {
|
||||||
|
appBridge?.dispatch(
|
||||||
|
actions.Notification({
|
||||||
|
status: "info",
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[appBridge]
|
||||||
|
),
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in a new issue