2023-03-07 21:02:37 +00:00
|
|
|
import React, { useMemo, useState } from "react";
|
2023-03-06 13:01:03 +00:00
|
|
|
import { EditIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
|
|
|
|
import { AppConfigurationForm } from "./app-configuration-form";
|
|
|
|
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
|
|
|
|
import { AppColumnsLayout } from "../../ui/app-columns-layout";
|
|
|
|
import { trpcClient } from "../../trpc/trpc-client";
|
|
|
|
import SideMenu from "./side-menu";
|
|
|
|
import { LoadingIndicator } from "../../ui/loading-indicator";
|
|
|
|
|
|
|
|
const useStyles = makeStyles((theme) => {
|
|
|
|
return {
|
|
|
|
formContainer: {
|
|
|
|
top: 0,
|
|
|
|
},
|
|
|
|
instructionsContainer: {
|
|
|
|
padding: 15,
|
|
|
|
},
|
|
|
|
configurationColumn: {
|
|
|
|
display: "flex",
|
|
|
|
flexDirection: "column",
|
|
|
|
gap: 20,
|
|
|
|
maxWidth: 600,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
export const ChannelsConfigurationTab = () => {
|
|
|
|
const styles = useStyles();
|
|
|
|
const { appBridge } = useAppBridge();
|
2023-03-07 21:02:37 +00:00
|
|
|
const [activeChannelSlug, setActiveChannelSlug] = useState<string | null>(null);
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const { data: channelsData, isLoading: isChannelsDataLoading } =
|
|
|
|
trpcClient.channels.fetch.useQuery(undefined, {
|
|
|
|
onSuccess: (data) => {
|
|
|
|
if (data?.length) {
|
|
|
|
setActiveChannelSlug(data[0].slug);
|
|
|
|
}
|
2023-03-06 13:01:03 +00:00
|
|
|
},
|
2023-03-07 21:02:37 +00:00
|
|
|
});
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const {
|
|
|
|
data: configurationData,
|
|
|
|
refetch: refetchConfig,
|
|
|
|
isLoading: isConfigurationDataLoading,
|
|
|
|
} = trpcClient.appConfiguration.getChannelConfiguration.useQuery(
|
|
|
|
{
|
|
|
|
channelSlug: activeChannelSlug!,
|
2023-03-06 13:01:03 +00:00
|
|
|
},
|
2023-03-07 21:02:37 +00:00
|
|
|
{ enabled: !!activeChannelSlug }
|
|
|
|
);
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const { data: mjmlConfigurations, isLoading: isMjmlQueryLoading } =
|
|
|
|
trpcClient.mjmlConfiguration.getConfigurations.useQuery({});
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const mjmlConfigurationsListData = useMemo(() => {
|
|
|
|
return (
|
|
|
|
mjmlConfigurations?.map((configuration) => ({
|
|
|
|
value: configuration.id,
|
|
|
|
label: configuration.configurationName,
|
|
|
|
})) ?? []
|
|
|
|
);
|
|
|
|
}, [mjmlConfigurations]);
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const { data: sendgridConfigurations, isLoading: isSendgridQueryLoading } =
|
|
|
|
trpcClient.sendgridConfiguration.fetch.useQuery();
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const sendgridConfigurationsListData = useMemo(() => {
|
|
|
|
if (!sendgridConfigurations) {
|
|
|
|
return [];
|
2023-03-06 13:01:03 +00:00
|
|
|
}
|
2023-03-07 21:02:37 +00:00
|
|
|
const keys = Object.keys(sendgridConfigurations.availableConfigurations ?? {}) || [];
|
|
|
|
|
|
|
|
return (
|
|
|
|
keys.map((key) => ({
|
|
|
|
value: key,
|
|
|
|
label: sendgridConfigurations.availableConfigurations[key].configurationName,
|
|
|
|
})) ?? []
|
|
|
|
);
|
|
|
|
}, [sendgridConfigurations]);
|
|
|
|
|
|
|
|
const { mutate: mutateAppChannelConfiguration, error: saveError } =
|
|
|
|
trpcClient.appConfiguration.setChannelConfiguration.useMutation({
|
|
|
|
onSuccess() {
|
|
|
|
refetchConfig();
|
|
|
|
appBridge?.dispatch(
|
|
|
|
actions.Notification({
|
|
|
|
title: "Success",
|
|
|
|
text: "Saved app configuration",
|
|
|
|
status: "success",
|
|
|
|
})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
});
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const activeChannel = channelsData?.find((c) => c.slug === activeChannelSlug);
|
2023-03-06 13:01:03 +00:00
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
if (isChannelsDataLoading) {
|
2023-03-06 13:01:03 +00:00
|
|
|
return <LoadingIndicator />;
|
|
|
|
}
|
2023-03-07 21:02:37 +00:00
|
|
|
if (!channelsData?.length) {
|
2023-03-06 13:01:03 +00:00
|
|
|
return <div>NO CHANNELS</div>;
|
|
|
|
}
|
|
|
|
|
2023-03-07 21:02:37 +00:00
|
|
|
const isFormDataLoading =
|
|
|
|
isConfigurationDataLoading || isMjmlQueryLoading || isSendgridQueryLoading;
|
2023-03-06 13:01:03 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<AppColumnsLayout>
|
|
|
|
<SideMenu
|
|
|
|
title="Channels"
|
2023-03-07 21:02:37 +00:00
|
|
|
selectedItemId={activeChannel?.slug}
|
2023-03-06 13:01:03 +00:00
|
|
|
headerToolbar={
|
|
|
|
<IconButton
|
|
|
|
variant="secondary"
|
|
|
|
onClick={() => {
|
|
|
|
appBridge?.dispatch(
|
|
|
|
actions.Redirect({
|
|
|
|
to: `/channels/`,
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<EditIcon />
|
|
|
|
</IconButton>
|
|
|
|
}
|
|
|
|
onClick={(id) => setActiveChannelSlug(id)}
|
2023-03-07 21:02:37 +00:00
|
|
|
items={channelsData.map((c) => ({ label: c.name, id: c.slug })) || []}
|
2023-03-06 13:01:03 +00:00
|
|
|
/>
|
2023-03-07 21:02:37 +00:00
|
|
|
<div className={styles.configurationColumn}>
|
|
|
|
{!activeChannel || isFormDataLoading ? (
|
|
|
|
<LoadingIndicator />
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<AppConfigurationForm
|
|
|
|
channelID={activeChannel.id}
|
|
|
|
key={activeChannelSlug}
|
|
|
|
channelSlug={activeChannel.slug}
|
|
|
|
mjmlConfigurationChoices={mjmlConfigurationsListData}
|
|
|
|
sendgridConfigurationChoices={sendgridConfigurationsListData}
|
|
|
|
onSubmit={async (data) => {
|
|
|
|
mutateAppChannelConfiguration({
|
|
|
|
channel: activeChannel.slug,
|
|
|
|
configuration: data,
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
initialData={configurationData}
|
|
|
|
channelName={activeChannel?.name ?? activeChannelSlug}
|
|
|
|
/>
|
|
|
|
{saveError && <span>{saveError.message}</span>}
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</div>
|
2023-03-06 13:01:03 +00:00
|
|
|
</AppColumnsLayout>
|
|
|
|
);
|
|
|
|
};
|