diff --git a/.changeset/eight-wombats-do.md b/.changeset/eight-wombats-do.md new file mode 100644 index 000000000..ce06cbba4 --- /dev/null +++ b/.changeset/eight-wombats-do.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": minor +--- + +Added information in Plugins Page about the App Store. Now plugins page informs that Apps will replace plugins in the future. Also every plugin that is "active" will display an inline message to visit the App Store for the app replacement diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 1e32d76be..0dd73b262 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -3511,6 +3511,9 @@ "context": "dialog header", "string": "Cancel Orders" }, + "NL6mvR": { + "string": "Visit App Store to replace with the App" + }, "NLNonj": { "context": "send to channel select label", "string": "Send to channel" @@ -8667,6 +8670,9 @@ "context": "table header channel col label", "string": "Channel" }, + "yfhLcv": { + "string": "We are working on replacing plugins with apps. Read more about" + }, "yhv3HX": { "context": "voucher requirements, header", "string": "Minimum Requirements" diff --git a/src/components/ExternalLink/ExternalLink.tsx b/src/components/ExternalLink/ExternalLink.tsx index 69c961894..ce37d4586 100644 --- a/src/components/ExternalLink/ExternalLink.tsx +++ b/src/components/ExternalLink/ExternalLink.tsx @@ -1,7 +1,8 @@ import { Typography } from "@material-ui/core"; import { TypographyProps } from "@material-ui/core/Typography"; import { makeStyles } from "@saleor/macaw-ui"; -import React from "react"; +import { Text, TextProps } from "@saleor/macaw-ui/next"; +import React, { HTMLAttributes } from "react"; const useStyles = makeStyles( { @@ -18,6 +19,9 @@ interface ExternalLinkProps extends React.HTMLProps { typographyProps?: TypographyProps; } +/** + * @deprecated use ExternalLinkNext + */ const ExternalLink: React.FC = props => { const { className, children, href, typographyProps, target, rel, ...rest } = props; @@ -42,3 +46,18 @@ const ExternalLink: React.FC = props => { }; ExternalLink.displayName = "ExternalLink"; export default ExternalLink; + +export const ExternalLinkNext = ( + props: TextProps & Omit, "children">, +) => { + const opensNewTab = props.target === "_blank"; + + return ( + + ); +}; diff --git a/src/plugins/components/PluginsList/PluginsList.tsx b/src/plugins/components/PluginsList/PluginsList.tsx index 8bc7e99cf..e12629549 100644 --- a/src/plugins/components/PluginsList/PluginsList.tsx +++ b/src/plugins/components/PluginsList/PluginsList.tsx @@ -5,13 +5,20 @@ import TableRowLink from "@dashboard/components/TableRowLink"; import { PluginBaseFragment } from "@dashboard/graphql"; import useNavigator from "@dashboard/hooks/useNavigator"; import { renderCollection } from "@dashboard/misc"; +import { getPluginsWithAppReplacementsIds } from "@dashboard/plugins/plugins-with-app-replacements"; import { PluginListUrlSortField, pluginUrl } from "@dashboard/plugins/urls"; import { ListProps, SortPage } from "@dashboard/types"; -import { TableBody, TableCell, TableFooter } from "@material-ui/core"; +import { + TableBody, + TableCell, + TableFooter, + Typography, +} from "@material-ui/core"; import { EditIcon, makeStyles } from "@saleor/macaw-ui"; import React from "react"; import { useIntl } from "react-intl"; +import { pluginsMiscMessages } from "./messages"; import PluginChannelAvailabilityCell from "./PluginChannelAvailabilityCell"; import PluginChannelConfigurationCell from "./PluginChannelConfigurationCell"; import PluginListTableHead from "./PluginListTableHead"; @@ -25,6 +32,10 @@ export const useStyles = makeStyles( { name: "PluginsList" }, ); +const pluginsWithAppReplacements = getPluginsWithAppReplacementsIds(); +const hasAppReplacement = (pluginId: string) => + pluginsWithAppReplacements.includes(pluginId); + export interface PluginListProps extends ListProps, SortPage { @@ -56,8 +67,16 @@ const PluginList: React.FC = props => { {renderCollection( plugins, - plugin => - plugin ? ( + plugin => { + const hasReplacement = plugin && hasAppReplacement(plugin.id); + const activeChannelConfigurations = + plugin?.channelConfigurations?.filter(c => c.active); + const isActive = + plugin?.globalConfiguration?.active || + (activeChannelConfigurations && + activeChannelConfigurations.length > 0); + + return plugin ? ( = props => { onClick={() => plugin && navigate(pluginUrl(plugin.id))} key={plugin ? plugin.id : "skeleton"} > - {plugin.name} + + {plugin.name} + {hasReplacement && isActive && ( + + {intl.formatMessage( + pluginsMiscMessages.appReplacementMessage, + )} + + )} + @@ -80,7 +108,8 @@ const PluginList: React.FC = props => { - ), + ); + }, () => ( diff --git a/src/plugins/components/PluginsList/messages.ts b/src/plugins/components/PluginsList/messages.ts index 5ebb18d2d..9cfcb7c96 100644 --- a/src/plugins/components/PluginsList/messages.ts +++ b/src/plugins/components/PluginsList/messages.ts @@ -75,3 +75,10 @@ export const pluginStatusMessages = defineMessages({ description: "status label deactivated", }, }); + +export const pluginsMiscMessages = defineMessages({ + appReplacementMessage: { + defaultMessage: "Visit App Store to replace with the App", + id: 'NL6mvR', + }, +}); diff --git a/src/plugins/components/PluginsListPage/PluginsListPage.tsx b/src/plugins/components/PluginsListPage/PluginsListPage.tsx index 7905f7f2b..e289b3fa0 100644 --- a/src/plugins/components/PluginsListPage/PluginsListPage.tsx +++ b/src/plugins/components/PluginsListPage/PluginsListPage.tsx @@ -1,10 +1,12 @@ // @ts-strict-ignore import { TopNav } from "@dashboard/components/AppLayout/TopNav"; +import { ExternalLinkNext } from "@dashboard/components/ExternalLink"; import FilterBar from "@dashboard/components/FilterBar"; import { ListPageLayout } from "@dashboard/components/Layouts"; import { configurationMenuUrl } from "@dashboard/configuration"; import { PluginBaseFragment } from "@dashboard/graphql"; import { sectionNames } from "@dashboard/intl"; +import { getStatusColor } from "@dashboard/misc"; import { PluginListUrlSortField } from "@dashboard/plugins/urls"; import { FilterPageProps, @@ -13,6 +15,7 @@ import { TabPageProps, } from "@dashboard/types"; import { Card } from "@material-ui/core"; +import { Box, Text } from "@saleor/macaw-ui/next"; import React from "react"; import { useIntl } from "react-intl"; @@ -22,7 +25,10 @@ import { PluginFilterKeys, PluginListFilterOpts, } from "./filters"; -import { pluginsFilterErrorMessages } from "./messages"; +import { + pluginsFilterErrorMessages, + pluginsListPageMessages, +} from "./messages"; export interface PluginsListPageProps extends PageListProps, @@ -56,6 +62,27 @@ const PluginsListPage: React.FC = ({ title={intl.formatMessage(sectionNames.plugins)} /> +
+ + + {intl.formatMessage(pluginsListPageMessages.warningHeadline)} + + + {intl.formatMessage(pluginsListPageMessages.appStoreWarning)}{" "} + + Saleor App Store. + + + +
{ + return [ + "mirumee.payments.adyen", + "mirumee.taxes.avalara", + "mirumee.invoicing", + "mirumee.notifications.sendgrid_email", + "saleor.payments.stripe", + "mirumee.payments.stripe", + "mirumee.notifications.user_email", + ]; +};