Use links instead of onClick navigate function (#1969)

Add links instead of navigate + onClick in:
* Lists - ex. product list (except Plugins, see below)
* SortableTables - ex. product variants
* Sidebar
* Buttons that open new page - ex. "Create product"
* Backlinks
* Menus - ex. "Account Settings"
* Links that actually used onClick - ex. warehouse shipping zone, reset password
This commit is contained in:
Jonatan Witoszek 2022-05-06 10:59:55 +02:00 committed by GitHub
parent a95a3021e4
commit 1e38c14116
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
376 changed files with 5191 additions and 2163 deletions

View file

@ -3,6 +3,7 @@
All notable, unreleased changes to this project will be documented in this file. For the released changes, please visit the [Releases](https://github.com/saleor/saleor-dashboard/releases) page. All notable, unreleased changes to this project will be documented in this file. For the released changes, please visit the [Releases](https://github.com/saleor/saleor-dashboard/releases) page.
## [Unreleased] ## [Unreleased]
- Added links instead of imperative navigation with onClick - #1969 by @taniotanio7
## 3.1 ## 3.1
### PREVIEW FEATURES ### PREVIEW FEATURES

View file

@ -368,6 +368,10 @@
"context": "dialog header", "context": "dialog header",
"string": "Change customer shipping address" "string": "Change customer shipping address"
}, },
"142MJn": {
"context": "select visible columns button",
"string": "Columns"
},
"15PiOX": { "15PiOX": {
"context": "button title", "context": "button title",
"string": "Unassign" "string": "Unassign"

View file

@ -11,8 +11,7 @@ const props: AppDetailsPageProps = {
navigateToApp: () => undefined, navigateToApp: () => undefined,
navigateToAppSettings: () => undefined, navigateToAppSettings: () => undefined,
onAppActivateOpen: () => undefined, onAppActivateOpen: () => undefined,
onAppDeactivateOpen: () => undefined, onAppDeactivateOpen: () => undefined
onBack: () => undefined
}; };
storiesOf("Views / Apps / App details", module) storiesOf("Views / Apps / App details", module)

View file

@ -1,4 +1,7 @@
import { ButtonBase, Card, CardContent, Typography } from "@material-ui/core"; import { ButtonBase, Card, CardContent, Typography } from "@material-ui/core";
import { appsListPath } from "@saleor/apps/urls";
import { Backlink } from "@saleor/components/Backlink";
import { Button } from "@saleor/components/Button";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
@ -7,7 +10,6 @@ import PageHeader from "@saleor/components/PageHeader";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { AppQuery } from "@saleor/graphql"; import { AppQuery } from "@saleor/graphql";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, Button } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import SVG from "react-inlinesvg"; import SVG from "react-inlinesvg";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -26,7 +28,6 @@ export interface AppDetailsPageProps {
navigateToAppSettings: () => void; navigateToAppSettings: () => void;
onAppActivateOpen: () => void; onAppActivateOpen: () => void;
onAppDeactivateOpen: () => void; onAppDeactivateOpen: () => void;
onBack: () => void;
} }
export const AppDetailsPage: React.FC<AppDetailsPageProps> = ({ export const AppDetailsPage: React.FC<AppDetailsPageProps> = ({
@ -35,15 +36,14 @@ export const AppDetailsPage: React.FC<AppDetailsPageProps> = ({
navigateToApp, navigateToApp,
navigateToAppSettings, navigateToAppSettings,
onAppActivateOpen, onAppActivateOpen,
onAppDeactivateOpen, onAppDeactivateOpen
onBack
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const classes = useStyles({}); const classes = useStyles({});
return ( return (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={appsListPath}>
{intl.formatMessage(sectionNames.apps)} {intl.formatMessage(sectionNames.apps)}
</Backlink> </Backlink>
<PageHeader <PageHeader

View file

@ -1,7 +1,7 @@
import errorImg from "@assets/images/app-install-error.svg"; import errorImg from "@assets/images/app-install-error.svg";
import { Grid, Typography } from "@material-ui/core"; import { Grid, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import { Button } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";

View file

@ -1,6 +1,7 @@
import saleorDarkLogoSmall from "@assets/images/logo-dark-small.svg"; import saleorDarkLogoSmall from "@assets/images/logo-dark-small.svg";
import plusIcon from "@assets/images/plus-icon.svg"; import plusIcon from "@assets/images/plus-icon.svg";
import { Card, CardContent, Grid, Typography } from "@material-ui/core"; import { Card, CardContent, Grid, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
@ -9,7 +10,6 @@ import Skeleton from "@saleor/components/Skeleton";
import { AppFetchMutation, AppInstallMutation } from "@saleor/graphql"; import { AppFetchMutation, AppInstallMutation } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { Button } from "@saleor/macaw-ui";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -8,8 +8,7 @@ import AppPage, { AppPageProps } from "./AppPage";
const props: AppPageProps = { const props: AppPageProps = {
data: appDetails, data: appDetails,
url: appDetails.appUrl, url: appDetails.appUrl,
navigateToAbout: () => undefined, aboutHref: "",
onBack: () => undefined,
onError: () => undefined onError: () => undefined
}; };

View file

@ -1,11 +1,13 @@
import { Typography } from "@material-ui/core"; import { Typography } from "@material-ui/core";
import { appsListPath } from "@saleor/apps/urls";
import { Backlink } from "@saleor/components/Backlink";
import { Button } from "@saleor/components/Button";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
import Hr from "@saleor/components/Hr"; import Hr from "@saleor/components/Hr";
import { AppQuery } from "@saleor/graphql"; import { AppQuery } from "@saleor/graphql";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, Button } from "@saleor/macaw-ui";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -17,16 +19,14 @@ import useSettingsBreadcrumbs from "./useSettingsBreadcrumbs";
export interface AppPageProps { export interface AppPageProps {
data: AppQuery["app"]; data: AppQuery["app"];
url: string; url: string;
navigateToAbout: () => void;
onBack: () => void;
onError: () => void; onError: () => void;
aboutHref: string;
} }
export const AppPage: React.FC<AppPageProps> = ({ export const AppPage: React.FC<AppPageProps> = ({
data, data,
url, url,
navigateToAbout, aboutHref,
onBack,
onError onError
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
@ -35,7 +35,7 @@ export const AppPage: React.FC<AppPageProps> = ({
return ( return (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={appsListPath}>
{intl.formatMessage(sectionNames.apps)} {intl.formatMessage(sectionNames.apps)}
</Backlink> </Backlink>
<Grid variant="uniform"> <Grid variant="uniform">
@ -63,7 +63,7 @@ export const AppPage: React.FC<AppPageProps> = ({
</div> </div>
</div> </div>
<div className={classes.appSettingsHeader}> <div className={classes.appSettingsHeader}>
<Button onClick={navigateToAbout} variant="primary"> <Button href={aboutHref} variant="primary">
<FormattedMessage <FormattedMessage
id="UCHtG6" id="UCHtG6"
defaultMessage="About" defaultMessage="About"

View file

@ -26,15 +26,13 @@ const props: AppsListPageProps = {
disabled: false, disabled: false,
installedAppsList: appsList, installedAppsList: appsList,
loadingAppsInProgress: false, loadingAppsInProgress: false,
navigateToCustomApp: () => undefined, getCustomAppHref: () => "",
navigateToCustomAppCreate: () => undefined,
onAppInProgressRemove: () => undefined, onAppInProgressRemove: () => undefined,
onAppInstallRetry: () => undefined, onAppInstallRetry: () => undefined,
onCustomAppRemove: () => undefined, onCustomAppRemove: () => undefined,
onInstalledAppRemove: () => undefined, onInstalledAppRemove: () => undefined,
onNextPage: () => undefined, onNextPage: () => undefined,
onPreviousPage: () => undefined, onPreviousPage: () => undefined,
onRowClick: () => undefined,
onRowAboutClick: () => undefined onRowAboutClick: () => undefined
}; };

View file

@ -17,8 +17,7 @@ export interface AppsListPageProps extends ListProps {
customAppsList: AppsListQuery["apps"]["edges"]; customAppsList: AppsListQuery["apps"]["edges"];
appsInProgressList?: AppsInstallationsQuery; appsInProgressList?: AppsInstallationsQuery;
loadingAppsInProgress: boolean; loadingAppsInProgress: boolean;
navigateToCustomApp: (id: string) => () => void; getCustomAppHref: (id: string) => string;
navigateToCustomAppCreate: () => void;
onInstalledAppRemove: (id: string) => void; onInstalledAppRemove: (id: string) => void;
onCustomAppRemove: (id: string) => void; onCustomAppRemove: (id: string) => void;
onAppInProgressRemove: (id: string) => void; onAppInProgressRemove: (id: string) => void;
@ -31,8 +30,7 @@ const AppsListPage: React.FC<AppsListPageProps> = ({
customAppsList, customAppsList,
installedAppsList, installedAppsList,
loadingAppsInProgress, loadingAppsInProgress,
navigateToCustomApp, getCustomAppHref,
navigateToCustomAppCreate,
onInstalledAppRemove, onInstalledAppRemove,
onCustomAppRemove, onCustomAppRemove,
onAppInProgressRemove, onAppInProgressRemove,
@ -67,8 +65,7 @@ const AppsListPage: React.FC<AppsListPageProps> = ({
<CardSpacer /> <CardSpacer />
<CustomApps <CustomApps
appsList={customAppsList} appsList={customAppsList}
navigateToCustomApp={navigateToCustomApp} getCustomAppHref={getCustomAppHref}
navigateToCustomAppCreate={navigateToCustomAppCreate}
onRemove={onCustomAppRemove} onRemove={onCustomAppRemove}
/> />
<CardSpacer /> <CardSpacer />

View file

@ -1,4 +1,6 @@
import { appsListUrl } from "@saleor/apps/urls";
import AccountPermissions from "@saleor/components/AccountPermissions"; import AccountPermissions from "@saleor/components/AccountPermissions";
import { Backlink } from "@saleor/components/Backlink";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
@ -10,8 +12,9 @@ import {
PermissionFragment PermissionFragment
} from "@saleor/graphql"; } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import { getFormErrors } from "@saleor/utils/errors"; import { getFormErrors } from "@saleor/utils/errors";
import getAppErrorMessage from "@saleor/utils/errors/app"; import getAppErrorMessage from "@saleor/utils/errors/app";
import React from "react"; import React from "react";
@ -29,22 +32,15 @@ export interface CustomAppCreatePageProps {
errors: AppErrorFragment[]; errors: AppErrorFragment[];
permissions: PermissionFragment[]; permissions: PermissionFragment[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void;
onSubmit: ( onSubmit: (
data: CustomAppCreatePageFormData data: CustomAppCreatePageFormData
) => SubmitPromise<AppErrorFragment[]>; ) => SubmitPromise<AppErrorFragment[]>;
} }
const CustomAppCreatePage: React.FC<CustomAppCreatePageProps> = props => { const CustomAppCreatePage: React.FC<CustomAppCreatePageProps> = props => {
const { const { disabled, errors, permissions, saveButtonBarState, onSubmit } = props;
disabled,
errors,
permissions,
saveButtonBarState,
onBack,
onSubmit
} = props;
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigator();
const initialForm: CustomAppCreatePageFormData = { const initialForm: CustomAppCreatePageFormData = {
hasFullAccess: false, hasFullAccess: false,
@ -64,7 +60,7 @@ const CustomAppCreatePage: React.FC<CustomAppCreatePageProps> = props => {
> >
{({ data, change, submit, isSaveDisabled }) => ( {({ data, change, submit, isSaveDisabled }) => (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={appsListUrl()}>
{intl.formatMessage(sectionNames.apps)} {intl.formatMessage(sectionNames.apps)}
</Backlink> </Backlink>
<PageHeader <PageHeader
@ -106,7 +102,7 @@ const CustomAppCreatePage: React.FC<CustomAppCreatePageProps> = props => {
<Savebar <Savebar
disabled={isSaveDisabled} disabled={isSaveDisabled}
state={saveButtonBarState} state={saveButtonBarState}
onCancel={onBack} onCancel={() => navigate(appsListUrl())}
onSubmit={submit} onSubmit={submit}
/> />
</Container> </Container>

View file

@ -1,8 +1,9 @@
import { Card, CardContent, Paper, Typography } from "@material-ui/core"; import { Card, CardContent, Paper, Typography } from "@material-ui/core";
import CloseIcon from "@material-ui/icons/Close"; import CloseIcon from "@material-ui/icons/Close";
import { Button } from "@saleor/components/Button";
import Link from "@saleor/components/Link"; import Link from "@saleor/components/Link";
import useClipboard from "@saleor/hooks/useClipboard"; import useClipboard from "@saleor/hooks/useClipboard";
import { Button, IconButton } from "@saleor/macaw-ui"; import { IconButton } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";

View file

@ -1,3 +1,4 @@
import { appsListUrl } from "@saleor/apps/urls";
import AccountPermissions from "@saleor/components/AccountPermissions"; import AccountPermissions from "@saleor/components/AccountPermissions";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
@ -12,6 +13,7 @@ import {
ShopInfoQuery ShopInfoQuery
} from "@saleor/graphql"; } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { import {
Backlink, Backlink,
@ -45,16 +47,14 @@ export interface CustomAppDetailsPageProps {
app: AppUpdateMutation["appUpdate"]["app"]; app: AppUpdateMutation["appUpdate"]["app"];
token: string; token: string;
onApiUriClick: () => void; onApiUriClick: () => void;
onBack: () => void;
onTokenDelete: (id: string) => void; onTokenDelete: (id: string) => void;
onTokenClose: () => void; onTokenClose: () => void;
onTokenCreate: () => void; onTokenCreate: () => void;
onSubmit: ( onSubmit: (
data: CustomAppDetailsPageFormData data: CustomAppDetailsPageFormData
) => SubmitPromise<AppErrorFragment[]>; ) => SubmitPromise<AppErrorFragment[]>;
onWebhookCreate: () => void; webhookCreateHref: string;
onWebhookRemove: (id: string) => void; onWebhookRemove: (id: string) => void;
navigateToWebhookDetails: (id: string) => () => void;
onAppActivateOpen: () => void; onAppActivateOpen: () => void;
onAppDeactivateOpen: () => void; onAppDeactivateOpen: () => void;
} }
@ -67,21 +67,20 @@ const CustomAppDetailsPage: React.FC<CustomAppDetailsPageProps> = props => {
permissions, permissions,
saveButtonBarState, saveButtonBarState,
app, app,
navigateToWebhookDetails,
token, token,
onApiUriClick, onApiUriClick,
onBack,
onTokenClose, onTokenClose,
onTokenCreate, onTokenCreate,
onTokenDelete, onTokenDelete,
onSubmit, onSubmit,
onWebhookCreate, webhookCreateHref,
onWebhookRemove, onWebhookRemove,
onAppActivateOpen, onAppActivateOpen,
onAppDeactivateOpen onAppDeactivateOpen
} = props; } = props;
const intl = useIntl(); const intl = useIntl();
const classes = useStyles({}); const classes = useStyles({});
const navigate = useNavigator();
const webhooks = app?.webhooks; const webhooks = app?.webhooks;
@ -109,7 +108,7 @@ const CustomAppDetailsPage: React.FC<CustomAppDetailsPageProps> = props => {
> >
{({ data, change, submit, isSaveDisabled }) => ( {({ data, change, submit, isSaveDisabled }) => (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={appsListUrl()}>
{intl.formatMessage(sectionNames.apps)} {intl.formatMessage(sectionNames.apps)}
</Backlink> </Backlink>
<PageHeader title={app?.name}> <PageHeader title={app?.name}>
@ -164,8 +163,7 @@ const CustomAppDetailsPage: React.FC<CustomAppDetailsPageProps> = props => {
<WebhooksList <WebhooksList
webhooks={webhooks} webhooks={webhooks}
onRemove={onWebhookRemove} onRemove={onWebhookRemove}
onRowClick={navigateToWebhookDetails} createHref={app?.isActive && webhookCreateHref}
onCreate={app?.isActive && onWebhookCreate}
/> />
</div> </div>
<div> <div>
@ -193,7 +191,7 @@ const CustomAppDetailsPage: React.FC<CustomAppDetailsPageProps> = props => {
<Savebar <Savebar
disabled={isSaveDisabled} disabled={isSaveDisabled}
state={saveButtonBarState} state={saveButtonBarState}
onCancel={onBack} onCancel={() => navigate(appsListUrl())}
onSubmit={submit} onSubmit={submit}
/> />
</Container> </Container>

View file

@ -5,11 +5,12 @@ import {
TableHead, TableHead,
TableRow TableRow
} from "@material-ui/core"; } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import ResponsiveTable from "@saleor/components/ResponsiveTable"; import ResponsiveTable from "@saleor/components/ResponsiveTable";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { AppUpdateMutation } from "@saleor/graphql"; import { AppUpdateMutation } from "@saleor/graphql";
import { Button, DeleteIcon, IconButton } from "@saleor/macaw-ui"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
import { renderCollection } from "@saleor/misc"; import { renderCollection } from "@saleor/misc";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -5,15 +5,13 @@ import {
TableRow, TableRow,
Typography Typography
} from "@material-ui/core"; } from "@material-ui/core";
import { customAppAddUrl } from "@saleor/apps/urls";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import TableRowLink from "@saleor/components/TableRowLink";
import { AppsListQuery } from "@saleor/graphql"; import { AppsListQuery } from "@saleor/graphql";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { import { DeleteIcon, IconButton, ResponsiveTable } from "@saleor/macaw-ui";
Button,
DeleteIcon,
IconButton,
ResponsiveTable
} from "@saleor/macaw-ui";
import { renderCollection, stopPropagation } from "@saleor/misc"; import { renderCollection, stopPropagation } from "@saleor/misc";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -24,16 +22,14 @@ import DeactivatedText from "../DeactivatedText";
export interface CustomAppsProps { export interface CustomAppsProps {
appsList: AppsListQuery["apps"]["edges"]; appsList: AppsListQuery["apps"]["edges"];
navigateToCustomApp: (id: string) => () => void; getCustomAppHref: (id: string) => string;
navigateToCustomAppCreate?: () => void;
onRemove: (id: string) => void; onRemove: (id: string) => void;
} }
const CustomApps: React.FC<CustomAppsProps> = ({ const CustomApps: React.FC<CustomAppsProps> = ({
appsList, appsList,
navigateToCustomAppCreate,
onRemove, onRemove,
navigateToCustomApp getCustomAppHref
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const classes = useStyles({}); const classes = useStyles({});
@ -42,19 +38,17 @@ const CustomApps: React.FC<CustomAppsProps> = ({
<Card className={classes.customApps}> <Card className={classes.customApps}>
<CardTitle <CardTitle
toolbar={ toolbar={
!!navigateToCustomAppCreate && ( <Button
<Button variant="secondary"
variant="secondary" href={customAppAddUrl}
onClick={navigateToCustomAppCreate} data-test-id="create-app"
data-test-id="create-app" >
> <FormattedMessage
<FormattedMessage id="XB2Jj9"
id="XB2Jj9" defaultMessage="Create App"
defaultMessage="Create App" description="create app button"
description="create app button" />
/> </Button>
</Button>
)
} }
title={intl.formatMessage(commonMessages.customApps)} title={intl.formatMessage(commonMessages.customApps)}
/> />
@ -64,10 +58,10 @@ const CustomApps: React.FC<CustomAppsProps> = ({
appsList, appsList,
(app, index) => (app, index) =>
app ? ( app ? (
<TableRow <TableRowLink
key={app.node.id} key={app.node.id}
className={classes.tableRow} className={classes.tableRow}
onClick={navigateToCustomApp(app.node.id)} href={getCustomAppHref(app.node.id)}
> >
<TableCell className={classes.colName}> <TableCell className={classes.colName}>
<span data-tc="name" className={classes.appName}> <span data-tc="name" className={classes.appName}>
@ -88,7 +82,7 @@ const CustomApps: React.FC<CustomAppsProps> = ({
<DeleteIcon /> <DeleteIcon />
</IconButton> </IconButton>
</TableCell> </TableCell>
</TableRow> </TableRowLink>
) : ( ) : (
<AppsSkeleton key={index} /> <AppsSkeleton key={index} />
), ),

View file

@ -6,8 +6,10 @@ import {
TableRow, TableRow,
Typography Typography
} from "@material-ui/core"; } from "@material-ui/core";
import { appUrl } from "@saleor/apps/urls";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TableRowLink from "@saleor/components/TableRowLink";
import { AppsListQuery } from "@saleor/graphql"; import { AppsListQuery } from "@saleor/graphql";
import { import {
Button, Button,
@ -39,7 +41,6 @@ const InstalledApps: React.FC<InstalledAppsProps> = ({
disabled, disabled,
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onRowClick,
onRowAboutClick, onRowAboutClick,
onUpdateListSettings, onUpdateListSettings,
pageInfo, pageInfo,
@ -78,10 +79,10 @@ const InstalledApps: React.FC<InstalledAppsProps> = ({
appsList, appsList,
(app, index) => (app, index) =>
app ? ( app ? (
<TableRow <TableRowLink
key={app.node.id} key={app.node.id}
className={classes.tableRow} className={classes.tableRow}
onClick={onRowClick(app.node.id)} href={appUrl(app.node.id)}
> >
<TableCell className={classes.colName}> <TableCell className={classes.colName}>
<span data-tc="name" className={classes.appName}> <span data-tc="name" className={classes.appName}>
@ -119,7 +120,7 @@ const InstalledApps: React.FC<InstalledAppsProps> = ({
<DeleteIcon /> <DeleteIcon />
</IconButton> </IconButton>
</TableCell> </TableCell>
</TableRow> </TableRowLink>
) : ( ) : (
<AppsSkeleton key={index} /> <AppsSkeleton key={index} />
), ),

View file

@ -1,6 +1,6 @@
import { Card, CardContent, Typography } from "@material-ui/core"; import { Card, CardContent, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { Button } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -8,6 +8,7 @@ import {
Typography Typography
} from "@material-ui/core"; } from "@material-ui/core";
import BackButton from "@saleor/components/BackButton"; import BackButton from "@saleor/components/BackButton";
import { Button } from "@saleor/components/Button";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import ConfirmButton from "@saleor/components/ConfirmButton"; import ConfirmButton from "@saleor/components/ConfirmButton";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
@ -15,7 +16,7 @@ import FormSpacer from "@saleor/components/FormSpacer";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen"; import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { Button, ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -45,8 +45,7 @@ export const App: React.FC<AppProps> = ({ id }) => {
<AppPage <AppPage
data={data?.app} data={data?.app}
url={appCompleteUrl} url={appCompleteUrl}
navigateToAbout={() => navigate(appDetailsUrl(id))} aboutHref={appDetailsUrl(id)}
onBack={() => navigate(appsListPath)}
onError={() => onError={() =>
notify({ notify({
status: "error", status: "error",

View file

@ -98,7 +98,7 @@ export const AppDetails: React.FC<AppDetailsProps> = ({ id, params }) => {
}; };
if (!appExists) { if (!appExists) {
return <NotFoundPage onBack={() => navigate(appsListPath)} />; return <NotFoundPage backHref={appsListPath} />;
} }
return ( return (
@ -124,7 +124,6 @@ export const AppDetails: React.FC<AppDetailsProps> = ({ id, params }) => {
navigateToAppSettings={() => navigate(appSettingsUrl(id))} navigateToAppSettings={() => navigate(appSettingsUrl(id))}
onAppActivateOpen={() => openModal("app-activate")} onAppActivateOpen={() => openModal("app-activate")}
onAppDeactivateOpen={() => openModal("app-deactivate")} onAppDeactivateOpen={() => openModal("app-deactivate")}
onBack={() => navigate(appsListPath)}
/> />
</> </>
); );

View file

@ -1,7 +1,6 @@
import { appMessages } from "@saleor/apps/messages"; import { appMessages } from "@saleor/apps/messages";
import NotFoundPage from "@saleor/components/NotFoundPage"; import NotFoundPage from "@saleor/components/NotFoundPage";
import { useAppQuery } from "@saleor/graphql"; import { useAppQuery } from "@saleor/graphql";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
@ -21,20 +20,18 @@ export const AppSettings: React.FC<AppSettingsProps> = ({ id }) => {
const appExists = data?.app !== null; const appExists = data?.app !== null;
const navigate = useNavigator();
const notify = useNotifier(); const notify = useNotifier();
const intl = useIntl(); const intl = useIntl();
if (!appExists) { if (!appExists) {
return <NotFoundPage onBack={() => navigate(appsListPath)} />; return <NotFoundPage backHref={appsListPath} />;
} }
return ( return (
<AppPage <AppPage
data={data?.app} data={data?.app}
url={data?.app.configurationUrl} url={data?.app.configurationUrl}
navigateToAbout={() => navigate(appDetailsUrl(id))} aboutHref={appDetailsUrl(id)}
onBack={() => navigate(appsListPath)}
onError={() => onError={() =>
notify({ notify({
status: "error", status: "error",

View file

@ -36,8 +36,6 @@ import {
AppListUrlDialog, AppListUrlDialog,
AppListUrlQueryParams, AppListUrlQueryParams,
appsListUrl, appsListUrl,
appUrl,
customAppAddUrl,
customAppUrl customAppUrl
} from "../../urls"; } from "../../urls";
import { messages } from "./messages"; import { messages } from "./messages";
@ -314,11 +312,9 @@ export const AppsList: React.FC<AppsListProps> = ({ params }) => {
onNextPage={loadNextPage} onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage} onPreviousPage={loadPreviousPage}
onUpdateListSettings={updateListSettings} onUpdateListSettings={updateListSettings}
onRowClick={id => () => navigate(appUrl(id))}
onRowAboutClick={id => () => navigate(appDetailsUrl(id))} onRowAboutClick={id => () => navigate(appDetailsUrl(id))}
onAppInstallRetry={onAppInstallRetry} onAppInstallRetry={onAppInstallRetry}
navigateToCustomApp={id => () => navigate(customAppUrl(id))} getCustomAppHref={id => customAppUrl(id)}
navigateToCustomAppCreate={() => navigate(customAppAddUrl)}
onInstalledAppRemove={id => onInstalledAppRemove={id =>
openModal("remove-app", { openModal("remove-app", {
id id

View file

@ -11,7 +11,7 @@ import { useIntl } from "react-intl";
import CustomAppCreatePage, { import CustomAppCreatePage, {
CustomAppCreatePageFormData CustomAppCreatePageFormData
} from "../../components/CustomAppCreatePage"; } from "../../components/CustomAppCreatePage";
import { appsListUrl, customAppUrl } from "../../urls"; import { customAppUrl } from "../../urls";
import { messages } from "./messages"; import { messages } from "./messages";
interface CustomAppCreateProps { interface CustomAppCreateProps {
@ -36,8 +36,6 @@ export const CustomAppCreate: React.FC<CustomAppCreateProps> = ({
} }
}; };
const handleBack = () => navigate(appsListUrl());
const [createApp, createAppOpts] = useAppCreateMutation({ const [createApp, createAppOpts] = useAppCreateMutation({
onCompleted: onSubmit onCompleted: onSubmit
}); });
@ -62,7 +60,6 @@ export const CustomAppCreate: React.FC<CustomAppCreateProps> = ({
<CustomAppCreatePage <CustomAppCreatePage
disabled={false} disabled={false}
errors={createAppOpts.data?.appCreate.errors || []} errors={createAppOpts.data?.appCreate.errors || []}
onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
permissions={shop?.permissions} permissions={shop?.permissions}
saveButtonBarState={createAppOpts.status} saveButtonBarState={createAppOpts.status}

View file

@ -27,7 +27,7 @@ import { extractMutationErrors, getStringOrPlaceholder } from "@saleor/misc";
import getAppErrorMessage from "@saleor/utils/errors/app"; import getAppErrorMessage from "@saleor/utils/errors/app";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog"; import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
import { webhookAddPath, webhookPath } from "@saleor/webhooks/urls"; import { webhookAddPath } from "@saleor/webhooks/urls";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
@ -143,11 +143,10 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
}); });
} }
}; };
const handleBack = () => navigate(appsListUrl());
const customApp = data?.app; const customApp = data?.app;
if (customApp === null) { if (customApp === null) {
return <NotFoundPage onBack={handleBack} />; return <NotFoundPage backHref={appsListUrl()} />;
} }
const onTokenCreate = (data: AppTokenCreateMutation) => { const onTokenCreate = (data: AppTokenCreateMutation) => {
@ -225,9 +224,7 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
disabled={loading} disabled={loading}
errors={updateAppOpts.data?.appUpdate?.errors || []} errors={updateAppOpts.data?.appUpdate?.errors || []}
token={token} token={token}
navigateToWebhookDetails={id => () => navigate(webhookPath(id))}
onApiUriClick={() => open(API_URI, "blank")} onApiUriClick={() => open(API_URI, "blank")}
onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onTokenClose={onTokenClose} onTokenClose={onTokenClose}
onTokenCreate={() => openModal("create-token")} onTokenCreate={() => openModal("create-token")}
@ -236,7 +233,7 @@ export const CustomAppDetails: React.FC<OrderListProps> = ({
id id
}) })
} }
onWebhookCreate={() => navigate(webhookAddPath(id))} webhookCreateHref={webhookAddPath(id)}
onWebhookRemove={id => onWebhookRemove={id =>
openModal("remove-webhook", { openModal("remove-webhook", {
id id

View file

@ -1,11 +1,15 @@
import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core"; import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core";
import { AttributeListUrlSortField } from "@saleor/attributes/urls"; import {
AttributeListUrlSortField,
attributeUrl
} from "@saleor/attributes/urls";
import Checkbox from "@saleor/components/Checkbox"; import Checkbox from "@saleor/components/Checkbox";
import ResponsiveTable from "@saleor/components/ResponsiveTable"; import ResponsiveTable from "@saleor/components/ResponsiveTable";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TableRowLink from "@saleor/components/TableRowLink";
import { AttributeFragment } from "@saleor/graphql"; import { AttributeFragment } from "@saleor/graphql";
import { translateBoolean } from "@saleor/intl"; import { translateBoolean } from "@saleor/intl";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
@ -69,7 +73,6 @@ const AttributeList: React.FC<AttributeListProps> = ({
isChecked, isChecked,
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onRowClick,
pageInfo, pageInfo,
selected, selected,
sort, sort,
@ -187,11 +190,11 @@ const AttributeList: React.FC<AttributeListProps> = ({
const isSelected = attribute ? isChecked(attribute.id) : false; const isSelected = attribute ? isChecked(attribute.id) : false;
return ( return (
<TableRow <TableRowLink
selected={isSelected} selected={isSelected}
hover={!!attribute} hover={!!attribute}
key={attribute ? attribute.id : "skeleton"} key={attribute ? attribute.id : "skeleton"}
onClick={attribute && onRowClick(attribute.id)} href={attribute && attributeUrl(attribute.id)}
className={classes.link} className={classes.link}
data-test-id={"id-" + maybe(() => attribute.id)} data-test-id={"id-" + maybe(() => attribute.id)}
> >
@ -246,7 +249,7 @@ const AttributeList: React.FC<AttributeListProps> = ({
<Skeleton /> <Skeleton />
)} )}
</TableCell> </TableCell>
</TableRow> </TableRowLink>
); );
}, },
() => ( () => (

View file

@ -1,9 +1,14 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import { AttributeListUrlSortField } from "@saleor/attributes/urls"; import {
attributeAddUrl,
AttributeListUrlSortField
} from "@saleor/attributes/urls";
import { Backlink } from "@saleor/components/Backlink";
import { Button } from "@saleor/components/Button";
import FilterBar from "@saleor/components/FilterBar"; import FilterBar from "@saleor/components/FilterBar";
import { configurationMenuUrl } from "@saleor/configuration";
import { AttributeFragment } from "@saleor/graphql"; import { AttributeFragment } from "@saleor/graphql";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, Button } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -30,14 +35,11 @@ export interface AttributeListPageProps
SortPage<AttributeListUrlSortField>, SortPage<AttributeListUrlSortField>,
TabPageProps { TabPageProps {
attributes: AttributeFragment[]; attributes: AttributeFragment[];
onBack: () => void;
} }
const AttributeListPage: React.FC<AttributeListPageProps> = ({ const AttributeListPage: React.FC<AttributeListPageProps> = ({
filterOpts, filterOpts,
initialSearch, initialSearch,
onAdd,
onBack,
onFilterChange, onFilterChange,
onSearchChange, onSearchChange,
currentTab, currentTab,
@ -54,12 +56,12 @@ const AttributeListPage: React.FC<AttributeListPageProps> = ({
return ( return (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={configurationMenuUrl}>
<FormattedMessage {...sectionNames.configuration} /> <FormattedMessage {...sectionNames.configuration} />
</Backlink> </Backlink>
<PageHeader title={intl.formatMessage(sectionNames.attributes)}> <PageHeader title={intl.formatMessage(sectionNames.attributes)}>
<Button <Button
onClick={onAdd} href={attributeAddUrl()}
variant="primary" variant="primary"
data-test-id="create-attribute-button" data-test-id="create-attribute-button"
> >

View file

@ -1,4 +1,6 @@
import { attributeListUrl } from "@saleor/attributes/urls";
import { ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES } from "@saleor/attributes/utils/data"; import { ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES } from "@saleor/attributes/utils/data";
import { Backlink } from "@saleor/components/Backlink";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
@ -18,8 +20,9 @@ import {
MeasurementUnitsEnum MeasurementUnitsEnum
} from "@saleor/graphql"; } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import { maybe } from "@saleor/misc"; import { maybe } from "@saleor/misc";
import { ListSettings, ReorderAction } from "@saleor/types"; import { ListSettings, ReorderAction } from "@saleor/types";
import { mapEdgesToItems, mapMetadataItemToInput } from "@saleor/utils/maps"; import { mapEdgesToItems, mapMetadataItemToInput } from "@saleor/utils/maps";
@ -39,7 +42,6 @@ export interface AttributePageProps {
errors: AttributeErrorFragment[]; errors: AttributeErrorFragment[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
values: AttributeDetailsQuery["attribute"]["choices"]; values: AttributeDetailsQuery["attribute"]["choices"];
onBack: () => void;
onDelete: () => void; onDelete: () => void;
onSubmit: (data: AttributePageFormData) => SubmitPromise; onSubmit: (data: AttributePageFormData) => SubmitPromise;
onValueAdd: () => void; onValueAdd: () => void;
@ -78,7 +80,6 @@ const AttributePage: React.FC<AttributePageProps> = ({
errors: apiErrors, errors: apiErrors,
saveButtonBarState, saveButtonBarState,
values, values,
onBack,
onDelete, onDelete,
onSubmit, onSubmit,
onValueAdd, onValueAdd,
@ -93,6 +94,8 @@ const AttributePage: React.FC<AttributePageProps> = ({
children children
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigator();
const { const {
isMetadataModified, isMetadataModified,
isPrivateMetadataModified, isPrivateMetadataModified,
@ -177,7 +180,7 @@ const AttributePage: React.FC<AttributePageProps> = ({
return ( return (
<> <>
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={attributeListUrl()}>
{intl.formatMessage(sectionNames.attributes)} {intl.formatMessage(sectionNames.attributes)}
</Backlink> </Backlink>
<PageHeader <PageHeader
@ -247,7 +250,7 @@ const AttributePage: React.FC<AttributePageProps> = ({
<Savebar <Savebar
disabled={isSaveDisabled} disabled={isSaveDisabled}
state={saveButtonBarState} state={saveButtonBarState}
onCancel={onBack} onCancel={() => navigate(attributeListUrl())}
onSubmit={submit} onSubmit={submit}
onDelete={attribute === null ? undefined : onDelete} onDelete={attribute === null ? undefined : onDelete}
/> />

View file

@ -5,6 +5,7 @@ import {
TableHead, TableHead,
TableRow TableRow
} from "@material-ui/core"; } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import ResponsiveTable from "@saleor/components/ResponsiveTable"; import ResponsiveTable from "@saleor/components/ResponsiveTable";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
@ -17,14 +18,14 @@ import {
AttributeInputTypeEnum, AttributeInputTypeEnum,
AttributeValueListFragment AttributeValueListFragment
} from "@saleor/graphql"; } from "@saleor/graphql";
import { Button, DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
import { renderCollection, stopPropagation } from "@saleor/misc"; import { renderCollection, stopPropagation } from "@saleor/misc";
import { ListProps, RelayToFlat, ReorderAction } from "@saleor/types"; import { ListProps, RelayToFlat, ReorderAction } from "@saleor/types";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
export interface AttributeValuesProps export interface AttributeValuesProps
extends Pick<ListProps, Exclude<keyof ListProps, "onRowClick">> { extends Pick<ListProps, Exclude<keyof ListProps, "getRowHref">> {
disabled: boolean; disabled: boolean;
values: RelayToFlat<AttributeValueListFragment>; values: RelayToFlat<AttributeValueListFragment>;
onValueAdd: () => void; onValueAdd: () => void;
@ -160,7 +161,7 @@ const AttributeValues: React.FC<AttributeValuesProps> = ({
{renderCollection( {renderCollection(
values, values,
(value, valueIndex) => ( (value, valueIndex) => (
<SortableTableRow <SortableTableRow<"row">
className={!!value ? classes.link : undefined} className={!!value ? classes.link : undefined}
hover={!!value} hover={!!value}
onClick={!!value ? () => onValueUpdate(value.id) : undefined} onClick={!!value ? () => onValueUpdate(value.id) : undefined}

View file

@ -33,7 +33,6 @@ import {
attributeAddUrl, attributeAddUrl,
AttributeAddUrlDialog, AttributeAddUrlDialog,
AttributeAddUrlQueryParams, AttributeAddUrlQueryParams,
attributeListUrl,
attributeUrl attributeUrl
} from "../../urls"; } from "../../urls";
import { import {
@ -179,7 +178,6 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
attribute={null} attribute={null}
disabled={attributeCreateOpts.loading} disabled={attributeCreateOpts.loading}
errors={attributeCreateOpts.data?.attributeCreate.errors || []} errors={attributeCreateOpts.data?.attributeCreate.errors || []}
onBack={() => navigate(attributeListUrl())}
onDelete={undefined} onDelete={undefined}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onValueAdd={() => openModal("add-value")} onValueAdd={() => openModal("add-value")}

View file

@ -248,7 +248,6 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
attribute={data?.attribute} attribute={data?.attribute}
disabled={loading} disabled={loading}
errors={attributeUpdateOpts.data?.attributeUpdate.errors || []} errors={attributeUpdateOpts.data?.attributeUpdate.errors || []}
onBack={() => navigate(attributeListUrl())}
onDelete={() => openModal("remove")} onDelete={() => openModal("remove")}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onValueAdd={() => openModal("add-value")} onValueAdd={() => openModal("add-value")}

View file

@ -11,7 +11,6 @@ import DeleteFilterTabDialog from "@saleor/components/DeleteFilterTabDialog";
import SaveFilterTabDialog, { import SaveFilterTabDialog, {
SaveFilterTabDialogFormData SaveFilterTabDialogFormData
} from "@saleor/components/SaveFilterTabDialog"; } from "@saleor/components/SaveFilterTabDialog";
import { configurationMenuUrl } from "@saleor/configuration";
import { import {
useAttributeBulkDeleteMutation, useAttributeBulkDeleteMutation,
useAttributeListQuery useAttributeListQuery
@ -36,11 +35,9 @@ import { maybe } from "../../../misc";
import AttributeBulkDeleteDialog from "../../components/AttributeBulkDeleteDialog"; import AttributeBulkDeleteDialog from "../../components/AttributeBulkDeleteDialog";
import AttributeListPage from "../../components/AttributeListPage"; import AttributeListPage from "../../components/AttributeListPage";
import { import {
attributeAddUrl,
attributeListUrl, attributeListUrl,
AttributeListUrlDialog, AttributeListUrlDialog,
AttributeListUrlQueryParams, AttributeListUrlQueryParams
attributeUrl
} from "../../urls"; } from "../../urls";
import { getFilterQueryParam } from "./filters"; import { getFilterQueryParam } from "./filters";
import { getSortQueryVariables } from "./sort"; import { getSortQueryVariables } from "./sort";
@ -151,13 +148,10 @@ const AttributeList: React.FC<AttributeListProps> = ({ params }) => {
filterOpts={getFilterOpts(params)} filterOpts={getFilterOpts(params)}
initialSearch={params.query || ""} initialSearch={params.query || ""}
isChecked={isSelected} isChecked={isSelected}
onAdd={() => navigate(attributeAddUrl())}
onAll={resetFilters} onAll={resetFilters}
onBack={() => navigate(configurationMenuUrl)}
onFilterChange={changeFilters} onFilterChange={changeFilters}
onNextPage={loadNextPage} onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage} onPreviousPage={loadPreviousPage}
onRowClick={id => () => navigate(attributeUrl(id))}
onSearchChange={handleSearchChange} onSearchChange={handleSearchChange}
onSort={handleSort} onSort={handleSort}
onTabChange={handleTabChange} onTabChange={handleTabChange}

View file

@ -16,7 +16,6 @@ const props: Omit<LoginCardProps, "classes"> = {
], ],
loading: false, loading: false,
onExternalAuthentication: () => undefined, onExternalAuthentication: () => undefined,
onPasswordRecovery: undefined,
onSubmit: () => undefined onSubmit: () => undefined
}; };

View file

@ -5,13 +5,16 @@ import {
Typography Typography
} from "@material-ui/core"; } from "@material-ui/core";
import { UserContextError } from "@saleor/auth/types"; import { UserContextError } from "@saleor/auth/types";
import { passwordResetUrl } from "@saleor/auth/urls";
import { Button } from "@saleor/components/Button";
import { FormSpacer } from "@saleor/components/FormSpacer"; import { FormSpacer } from "@saleor/components/FormSpacer";
import { AvailableExternalAuthenticationsQuery } from "@saleor/graphql"; import { AvailableExternalAuthenticationsQuery } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { Button, EyeIcon, IconButton } from "@saleor/macaw-ui"; import { EyeIcon, IconButton } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { Link } from "react-router-dom";
import useStyles from "../styles"; import useStyles from "../styles";
import LoginForm, { LoginFormData } from "./form"; import LoginForm, { LoginFormData } from "./form";
@ -23,7 +26,6 @@ export interface LoginCardProps {
loading: boolean; loading: boolean;
externalAuthentications?: AvailableExternalAuthenticationsQuery["shop"]["availableExternalAuthentications"]; externalAuthentications?: AvailableExternalAuthenticationsQuery["shop"]["availableExternalAuthentications"];
onExternalAuthentication: (pluginId: string) => void; onExternalAuthentication: (pluginId: string) => void;
onPasswordRecovery: () => void;
onSubmit?: (event: LoginFormData) => SubmitPromise; onSubmit?: (event: LoginFormData) => SubmitPromise;
} }
@ -34,7 +36,6 @@ const LoginCard: React.FC<LoginCardProps> = props => {
loading, loading,
externalAuthentications = [], externalAuthentications = [],
onExternalAuthentication, onExternalAuthentication,
onPasswordRecovery,
onSubmit onSubmit
} = props; } = props;
@ -109,9 +110,9 @@ const LoginCard: React.FC<LoginCardProps> = props => {
</IconButton> </IconButton>
</div> </div>
<Typography <Typography
component="a" component={Link}
className={classes.link} className={classes.link}
onClick={onPasswordRecovery} to={passwordResetUrl}
variant="body2" variant="body2"
data-test-id="reset-password-link" data-test-id="reset-password-link"
> >

View file

@ -1,8 +1,8 @@
import { TextField, Typography } from "@material-ui/core"; import { TextField, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import { Button } from "@saleor/macaw-ui";
import { SetPasswordData } from "@saleor/sdk"; import { SetPasswordData } from "@saleor/sdk";
import getAccountErrorMessage from "@saleor/utils/errors/account"; import getAccountErrorMessage from "@saleor/utils/errors/account";
import React from "react"; import React from "react";

View file

@ -9,7 +9,6 @@ import ResetPasswordPage, { ResetPasswordPageProps } from "./ResetPasswordPage";
const props: ResetPasswordPageProps = { const props: ResetPasswordPageProps = {
disabled: false, disabled: false,
error: undefined, error: undefined,
onBack: () => undefined,
onSubmit: () => undefined onSubmit: () => undefined
}; };
storiesOf("Views / Authentication / Reset password", module) storiesOf("Views / Authentication / Reset password", module)

View file

@ -1,10 +1,13 @@
import { TextField, Typography } from "@material-ui/core"; import { TextField, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
import { IconButton } from "@saleor/components/IconButton";
import { APP_MOUNT_URI } from "@saleor/config";
import { RequestPasswordResetMutation } from "@saleor/graphql"; import { RequestPasswordResetMutation } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { ArrowRightIcon, Button, IconButton } from "@saleor/macaw-ui"; import { ArrowRightIcon } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -16,7 +19,6 @@ export interface ResetPasswordPageFormData {
export interface ResetPasswordPageProps { export interface ResetPasswordPageProps {
disabled: boolean; disabled: boolean;
error: string; error: string;
onBack: () => void;
onSubmit: ( onSubmit: (
data: ResetPasswordPageFormData data: ResetPasswordPageFormData
) => SubmitPromise< ) => SubmitPromise<
@ -25,7 +27,7 @@ export interface ResetPasswordPageProps {
} }
const ResetPasswordPage: React.FC<ResetPasswordPageProps> = props => { const ResetPasswordPage: React.FC<ResetPasswordPageProps> = props => {
const { disabled, error, onBack, onSubmit } = props; const { disabled, error, onSubmit } = props;
const classes = useStyles(props); const classes = useStyles(props);
const intl = useIntl(); const intl = useIntl();
@ -34,7 +36,7 @@ const ResetPasswordPage: React.FC<ResetPasswordPageProps> = props => {
<Form initial={{ email: "" }} onSubmit={onSubmit}> <Form initial={{ email: "" }} onSubmit={onSubmit}>
{({ change: handleChange, data, submit: handleSubmit }) => ( {({ change: handleChange, data, submit: handleSubmit }) => (
<> <>
<IconButton className={classes.backBtn} onClick={onBack}> <IconButton className={classes.backBtn} href={APP_MOUNT_URI}>
<ArrowRightIcon className={classes.arrow} /> <ArrowRightIcon className={classes.arrow} />
</IconButton> </IconButton>
<Typography variant="h3" className={classes.header}> <Typography variant="h3" className={classes.header}>

View file

@ -1,6 +1,7 @@
import { Typography } from "@material-ui/core"; import { Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import FormSpacer from "@saleor/components/FormSpacer"; import FormSpacer from "@saleor/components/FormSpacer";
import { Button } from "@saleor/macaw-ui"; import {} from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";

View file

@ -9,11 +9,7 @@ import useRouter from "use-react-router";
import { useUser } from ".."; import { useUser } from "..";
import LoginPage from "../components/LoginPage"; import LoginPage from "../components/LoginPage";
import { LoginFormData } from "../components/LoginPage/types"; import { LoginFormData } from "../components/LoginPage/types";
import { import { loginCallbackPath, LoginUrlQueryParams } from "../urls";
loginCallbackPath,
LoginUrlQueryParams,
passwordResetUrl
} from "../urls";
interface LoginViewProps { interface LoginViewProps {
params: LoginUrlQueryParams; params: LoginUrlQueryParams;
@ -97,7 +93,6 @@ const LoginView: React.FC<LoginViewProps> = ({ params }) => {
} }
loading={externalAuthenticationsLoading || authenticating} loading={externalAuthenticationsLoading || authenticating}
onExternalAuthentication={handleRequestExternalAuthentication} onExternalAuthentication={handleRequestExternalAuthentication}
onPasswordRecovery={() => navigate(passwordResetUrl)}
onSubmit={handleSubmit} onSubmit={handleSubmit}
/> />
); );

View file

@ -60,7 +60,6 @@ const ResetPasswordView: React.FC = () => {
<ResetPasswordPage <ResetPasswordPage
disabled={requestPasswordResetOpts.loading} disabled={requestPasswordResetOpts.loading}
error={error} error={error}
onBack={() => navigate(APP_MOUNT_URI)}
onSubmit={handleSubmit} onSubmit={handleSubmit}
/> />
); );

View file

@ -1,4 +1,5 @@
import { Card, CardContent, TextField } from "@material-ui/core"; import { Card, CardContent, TextField } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import Hr from "@saleor/components/Hr"; import Hr from "@saleor/components/Hr";
import ImageUpload from "@saleor/components/ImageUpload"; import ImageUpload from "@saleor/components/ImageUpload";
@ -6,7 +7,7 @@ import MediaTile from "@saleor/components/MediaTile";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { CategoryDetailsFragment } from "@saleor/graphql"; import { CategoryDetailsFragment } from "@saleor/graphql";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -1,3 +1,4 @@
import { Backlink } from "@saleor/components/Backlink";
import { CardSpacer } from "@saleor/components/CardSpacer"; import { CardSpacer } from "@saleor/components/CardSpacer";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import Metadata from "@saleor/components/Metadata"; import Metadata from "@saleor/components/Metadata";
@ -5,8 +6,9 @@ import PageHeader from "@saleor/components/PageHeader";
import Savebar from "@saleor/components/Savebar"; import Savebar from "@saleor/components/Savebar";
import SeoForm from "@saleor/components/SeoForm"; import SeoForm from "@saleor/components/SeoForm";
import { ProductErrorFragment } from "@saleor/graphql"; import { ProductErrorFragment } from "@saleor/graphql";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
@ -17,24 +19,25 @@ export interface CategoryCreatePageProps {
errors: ProductErrorFragment[]; errors: ProductErrorFragment[];
disabled: boolean; disabled: boolean;
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
backUrl: string;
onSubmit(data: CategoryCreateData); onSubmit(data: CategoryCreateData);
onBack();
} }
export const CategoryCreatePage: React.FC<CategoryCreatePageProps> = ({ export const CategoryCreatePage: React.FC<CategoryCreatePageProps> = ({
disabled, disabled,
onSubmit, onSubmit,
onBack,
errors, errors,
saveButtonBarState saveButtonBarState,
backUrl
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigator();
return ( return (
<CategoryCreateForm onSubmit={onSubmit} disabled={disabled}> <CategoryCreateForm onSubmit={onSubmit} disabled={disabled}>
{({ data, change, handlers, submit, isSaveDisabled }) => ( {({ data, change, handlers, submit, isSaveDisabled }) => (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={backUrl}>
{intl.formatMessage(sectionNames.categories)} {intl.formatMessage(sectionNames.categories)}
</Backlink> </Backlink>
<PageHeader <PageHeader
@ -73,7 +76,7 @@ export const CategoryCreatePage: React.FC<CategoryCreatePageProps> = ({
<CardSpacer /> <CardSpacer />
<Metadata data={data} onChange={handlers.changeMetadata} /> <Metadata data={data} onChange={handlers.changeMetadata} />
<Savebar <Savebar
onCancel={onBack} onCancel={() => navigate(backUrl)}
onSubmit={submit} onSubmit={submit}
state={saveButtonBarState} state={saveButtonBarState}
disabled={isSaveDisabled} disabled={isSaveDisabled}

View file

@ -6,8 +6,9 @@ import {
DialogTitle DialogTitle
} from "@material-ui/core"; } from "@material-ui/core";
import BackButton from "@saleor/components/BackButton"; import BackButton from "@saleor/components/BackButton";
import { Button } from "@saleor/components/Button";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";

View file

@ -1,11 +1,12 @@
import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core"; import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core";
import { CategoryListUrlSortField } from "@saleor/categories/urls"; import { CategoryListUrlSortField, categoryUrl } from "@saleor/categories/urls";
import Checkbox from "@saleor/components/Checkbox"; import Checkbox from "@saleor/components/Checkbox";
import ResponsiveTable from "@saleor/components/ResponsiveTable"; import ResponsiveTable from "@saleor/components/ResponsiveTable";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TableRowLink from "@saleor/components/TableRowLink";
import { CategoryFragment } from "@saleor/graphql"; import { CategoryFragment } from "@saleor/graphql";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import { maybe, renderCollection } from "@saleor/misc"; import { maybe, renderCollection } from "@saleor/misc";
@ -49,7 +50,6 @@ interface CategoryListProps
SortPage<CategoryListUrlSortField> { SortPage<CategoryListUrlSortField> {
categories?: CategoryFragment[]; categories?: CategoryFragment[];
isRoot: boolean; isRoot: boolean;
onAdd?();
} }
const CategoryList: React.FC<CategoryListProps> = props => { const CategoryList: React.FC<CategoryListProps> = props => {
@ -68,7 +68,6 @@ const CategoryList: React.FC<CategoryListProps> = props => {
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onUpdateListSettings, onUpdateListSettings,
onRowClick,
onSort onSort
} = props; } = props;
@ -157,10 +156,10 @@ const CategoryList: React.FC<CategoryListProps> = props => {
const isSelected = category ? isChecked(category.id) : false; const isSelected = category ? isChecked(category.id) : false;
return ( return (
<TableRow <TableRowLink
className={classes.tableRow} className={classes.tableRow}
hover={!!category} hover={!!category}
onClick={category ? onRowClick(category.id) : undefined} href={category && categoryUrl(category.id)}
key={category ? category.id : "skeleton"} key={category ? category.id : "skeleton"}
selected={isSelected} selected={isSelected}
data-test-id={"id-" + maybe(() => category.id)} data-test-id={"id-" + maybe(() => category.id)}
@ -194,7 +193,7 @@ const CategoryList: React.FC<CategoryListProps> = props => {
<Skeleton /> <Skeleton />
)} )}
</TableCell> </TableCell>
</TableRow> </TableRowLink>
); );
}, },
() => ( () => (

View file

@ -1,11 +1,14 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import { CategoryListUrlSortField } from "@saleor/categories/urls"; import {
categoryAddUrl,
CategoryListUrlSortField
} from "@saleor/categories/urls";
import { Button } from "@saleor/components/Button";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import SearchBar from "@saleor/components/SearchBar"; import SearchBar from "@saleor/components/SearchBar";
import { CategoryFragment } from "@saleor/graphql"; import { CategoryFragment } from "@saleor/graphql";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Button } from "@saleor/macaw-ui";
import { import {
ListActions, ListActions,
PageListProps, PageListProps,
@ -40,11 +43,9 @@ export const CategoryListPage: React.FC<CategoryTableProps> = ({
toggle, toggle,
toggleAll, toggleAll,
toolbar, toolbar,
onAdd,
onAll, onAll,
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onRowClick,
onSearchChange, onSearchChange,
onTabChange, onTabChange,
onTabDelete, onTabDelete,
@ -59,7 +60,7 @@ export const CategoryListPage: React.FC<CategoryTableProps> = ({
<PageHeader title={intl.formatMessage(sectionNames.categories)}> <PageHeader title={intl.formatMessage(sectionNames.categories)}>
<Button <Button
variant="primary" variant="primary"
onClick={onAdd} href={categoryAddUrl()}
data-test-id="create-category" data-test-id="create-category"
> >
<FormattedMessage <FormattedMessage
@ -100,10 +101,8 @@ export const CategoryListPage: React.FC<CategoryTableProps> = ({
toggle={toggle} toggle={toggle}
toggleAll={toggleAll} toggleAll={toggleAll}
toolbar={toolbar} toolbar={toolbar}
onAdd={onAdd}
onNextPage={onNextPage} onNextPage={onNextPage}
onPreviousPage={onPreviousPage} onPreviousPage={onPreviousPage}
onRowClick={onRowClick}
onUpdateListSettings={onUpdateListSettings} onUpdateListSettings={onUpdateListSettings}
{...listProps} {...listProps}
/> />

View file

@ -6,9 +6,11 @@ import TableCellAvatar from "@saleor/components/TableCellAvatar";
import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar"; import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TableRowLink from "@saleor/components/TableRowLink";
import { CategoryDetailsQuery } from "@saleor/graphql"; import { CategoryDetailsQuery } from "@saleor/graphql";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import { maybe, renderCollection } from "@saleor/misc"; import { maybe, renderCollection } from "@saleor/misc";
import { productUrl } from "@saleor/products/urls";
import { ListActions, ListProps, RelayToFlat } from "@saleor/types"; import { ListActions, ListProps, RelayToFlat } from "@saleor/types";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
@ -64,8 +66,7 @@ export const CategoryProductList: React.FC<CategoryProductListProps> = props =>
toggleAll, toggleAll,
toolbar, toolbar,
onNextPage, onNextPage,
onPreviousPage, onPreviousPage
onRowClick
} = props; } = props;
const classes = useStyles(props); const classes = useStyles(props);
@ -117,12 +118,12 @@ export const CategoryProductList: React.FC<CategoryProductListProps> = props =>
const isSelected = product ? isChecked(product.id) : false; const isSelected = product ? isChecked(product.id) : false;
return ( return (
<TableRow <TableRowLink
data-test-id="product-row" data-test-id="product-row"
selected={isSelected} selected={isSelected}
hover={!!product} hover={!!product}
key={product ? product.id : "skeleton"} key={product ? product.id : "skeleton"}
onClick={product && onRowClick(product.id)} href={product && productUrl(product.id)}
className={classes.link} className={classes.link}
> >
<TableCell padding="checkbox"> <TableCell padding="checkbox">
@ -139,7 +140,7 @@ export const CategoryProductList: React.FC<CategoryProductListProps> = props =>
> >
{product ? product.name : <Skeleton />} {product ? product.name : <Skeleton />}
</TableCellAvatar> </TableCellAvatar>
</TableRow> </TableRowLink>
); );
}, },
() => ( () => (

View file

@ -1,10 +1,10 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer"; import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { InternalLink } from "@saleor/components/InternalLink"; import { InternalLink } from "@saleor/components/InternalLink";
import { CategoryDetailsQuery } from "@saleor/graphql"; import { CategoryDetailsQuery } from "@saleor/graphql";
import { Button } from "@saleor/macaw-ui"; import { productAddUrl, productListUrl } from "@saleor/products/urls";
import { productListUrl } from "@saleor/products/urls";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -22,10 +22,8 @@ export const CategoryProducts: React.FC<CategoryProductsProps> = ({
products, products,
disabled, disabled,
pageInfo, pageInfo,
onAdd,
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onRowClick,
categoryId, categoryId,
categoryName, categoryName,
isChecked, isChecked,
@ -66,7 +64,7 @@ export const CategoryProducts: React.FC<CategoryProductsProps> = ({
<HorizontalSpacer /> <HorizontalSpacer />
<Button <Button
variant="tertiary" variant="tertiary"
onClick={onAdd} href={productAddUrl()}
data-test-id="add-products" data-test-id="add-products"
> >
<FormattedMessage <FormattedMessage
@ -84,7 +82,6 @@ export const CategoryProducts: React.FC<CategoryProductsProps> = ({
pageInfo={pageInfo} pageInfo={pageInfo}
onNextPage={onNextPage} onNextPage={onNextPage}
onPreviousPage={onPreviousPage} onPreviousPage={onPreviousPage}
onRowClick={onRowClick}
selected={selected} selected={selected}
isChecked={isChecked} isChecked={isChecked}
toggle={toggle} toggle={toggle}

View file

@ -1,4 +1,6 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import { categoryListUrl, categoryUrl } from "@saleor/categories/urls";
import { Backlink } from "@saleor/components/Backlink";
import { CardSpacer } from "@saleor/components/CardSpacer"; import { CardSpacer } from "@saleor/components/CardSpacer";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
@ -9,12 +11,9 @@ import SeoForm from "@saleor/components/SeoForm";
import { Tab, TabContainer } from "@saleor/components/Tab"; import { Tab, TabContainer } from "@saleor/components/Tab";
import { CategoryDetailsQuery, ProductErrorFragment } from "@saleor/graphql"; import { CategoryDetailsQuery, ProductErrorFragment } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { import { Button, ConfirmButtonTransitionState } from "@saleor/macaw-ui";
Backlink,
Button,
ConfirmButtonTransitionState
} from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -45,17 +44,14 @@ export interface CategoryUpdatePageProps
hasPreviousPage: boolean; hasPreviousPage: boolean;
}; };
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
addProductHref: string;
addCategoryHref: string;
onImageDelete: () => void; onImageDelete: () => void;
onSubmit: (data: CategoryUpdateData) => SubmitPromise; onSubmit: (data: CategoryUpdateData) => SubmitPromise;
onImageUpload(file: File); onImageUpload(file: File);
onNextPage(); onNextPage();
onPreviousPage(); onPreviousPage();
onProductClick(id: string): () => void;
onAddProduct();
onBack();
onDelete(); onDelete();
onAddCategory();
onCategoryClick(id: string): () => void;
} }
const CategoriesTab = Tab(CategoryPageTab.categories); const CategoriesTab = Tab(CategoryPageTab.categories);
@ -71,14 +67,10 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
products, products,
saveButtonBarState, saveButtonBarState,
subcategories, subcategories,
onAddCategory, addCategoryHref,
onAddProduct,
onBack,
onCategoryClick,
onDelete, onDelete,
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onProductClick,
onSubmit, onSubmit,
onImageDelete, onImageDelete,
onImageUpload, onImageUpload,
@ -90,6 +82,11 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
toggleAll toggleAll
}: CategoryUpdatePageProps) => { }: CategoryUpdatePageProps) => {
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigator();
const backHref = category?.parent?.id
? categoryUrl(category?.parent?.id)
: categoryListUrl();
return ( return (
<CategoryUpdateForm <CategoryUpdateForm
@ -99,7 +96,7 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
> >
{({ data, change, handlers, submit, isSaveDisabled }) => ( {({ data, change, handlers, submit, isSaveDisabled }) => (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={backHref}>
{intl.formatMessage(sectionNames.categories)} {intl.formatMessage(sectionNames.categories)}
</Backlink> </Backlink>
<PageHeader title={category?.name} /> <PageHeader title={category?.name} />
@ -174,7 +171,7 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
toolbar={ toolbar={
<Button <Button
variant="tertiary" variant="tertiary"
onClick={onAddCategory} href={addCategoryHref}
data-test-id="create-subcategory" data-test-id="create-subcategory"
> >
<FormattedMessage <FormattedMessage
@ -198,7 +195,6 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
toolbar={subcategoryListToolbar} toolbar={subcategoryListToolbar}
onNextPage={onNextPage} onNextPage={onNextPage}
onPreviousPage={onPreviousPage} onPreviousPage={onPreviousPage}
onRowClick={onCategoryClick}
onSort={() => undefined} onSort={() => undefined}
/> />
</Card> </Card>
@ -212,8 +208,6 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
pageInfo={pageInfo} pageInfo={pageInfo}
onNextPage={onNextPage} onNextPage={onNextPage}
onPreviousPage={onPreviousPage} onPreviousPage={onPreviousPage}
onRowClick={onProductClick}
onAdd={onAddProduct}
toggle={toggle} toggle={toggle}
toggleAll={toggleAll} toggleAll={toggleAll}
selected={selected} selected={selected}
@ -222,7 +216,7 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
/> />
)} )}
<Savebar <Savebar
onCancel={onBack} onCancel={() => navigate(backHref)}
onDelete={onDelete} onDelete={onDelete}
onSubmit={submit} onSubmit={submit}
state={saveButtonBarState} state={saveButtonBarState}

View file

@ -88,9 +88,7 @@ export const CategoryCreateView: React.FC<CategoryCreateViewProps> = ({
saveButtonBarState={createCategoryResult.status} saveButtonBarState={createCategoryResult.status}
errors={createCategoryResult.data?.categoryCreate.errors || []} errors={createCategoryResult.data?.categoryCreate.errors || []}
disabled={createCategoryResult.loading} disabled={createCategoryResult.loading}
onBack={() => backUrl={parentId ? categoryUrl(parentId) : categoryListUrl()}
navigate(parentId ? categoryUrl(parentId) : categoryListUrl())
}
onSubmit={handleSubmit} onSubmit={handleSubmit}
/> />
</> </>

View file

@ -32,7 +32,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import { PAGINATE_BY } from "../../config"; import { PAGINATE_BY } from "../../config";
import { extractMutationErrors, maybe } from "../../misc"; import { extractMutationErrors, maybe } from "../../misc";
import { productAddUrl, productUrl } from "../../products/urls"; import { productAddUrl } from "../../products/urls";
import { import {
CategoryPageTab, CategoryPageTab,
CategoryUpdatePage CategoryUpdatePage
@ -217,14 +217,8 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
category={maybe(() => data.category)} category={maybe(() => data.category)}
disabled={loading} disabled={loading}
errors={updateResult.data?.categoryUpdate.errors || []} errors={updateResult.data?.categoryUpdate.errors || []}
onAddCategory={() => navigate(categoryAddUrl(id))} addCategoryHref={categoryAddUrl(id)}
onAddProduct={() => navigate(productAddUrl())} addProductHref={productAddUrl()}
onBack={() =>
navigate(
maybe(() => categoryUrl(data.category.parent.id), categoryListUrl())
)
}
onCategoryClick={id => () => navigate(categoryUrl(id))}
onDelete={() => openModal("delete")} onDelete={() => openModal("delete")}
onImageDelete={() => onImageDelete={() =>
updateCategory({ updateCategory({
@ -249,7 +243,6 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
onNextPage={loadNextPage} onNextPage={loadNextPage}
onPreviousPage={loadPreviousPage} onPreviousPage={loadPreviousPage}
pageInfo={pageInfo} pageInfo={pageInfo}
onProductClick={id => () => navigate(productUrl(id))}
onSubmit={handleSubmit} onSubmit={handleSubmit}
products={mapEdgesToItems(data?.category?.products)} products={mapEdgesToItems(data?.category?.products)}
saveButtonBarState={updateResult.status} saveButtonBarState={updateResult.status}

View file

@ -28,12 +28,10 @@ import { FormattedMessage, useIntl } from "react-intl";
import { CategoryListPage } from "../../components/CategoryListPage/CategoryListPage"; import { CategoryListPage } from "../../components/CategoryListPage/CategoryListPage";
import { import {
categoryAddUrl,
categoryListUrl, categoryListUrl,
CategoryListUrlDialog, CategoryListUrlDialog,
CategoryListUrlFilters, CategoryListUrlFilters,
CategoryListUrlQueryParams, CategoryListUrlQueryParams
categoryUrl
} from "../../urls"; } from "../../urls";
import { import {
deleteFilterTab, deleteFilterTab,
@ -156,8 +154,6 @@ export const CategoryList: React.FC<CategoryListProps> = ({ params }) => {
tabs={tabs.map(tab => tab.name)} tabs={tabs.map(tab => tab.name)}
settings={settings} settings={settings}
sort={getSortParams(params)} sort={getSortParams(params)}
onAdd={() => navigate(categoryAddUrl())}
onRowClick={id => () => navigate(categoryUrl(id))}
onSort={handleSort} onSort={handleSort}
disabled={loading} disabled={loading}
onNextPage={loadNextPage} onNextPage={loadNextPage}

View file

@ -1,6 +1,6 @@
import { Card, CardContent, Typography } from "@material-ui/core"; import { Card, CardContent, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { Button } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -17,7 +17,6 @@ const props: ChannelDetailsPageProps<ChannelErrorFragment[]> = {
disabled: false, disabled: false,
disabledStatus: false, disabledStatus: false,
errors: [], errors: [],
onBack: () => undefined,
onSubmit: () => undefined, onSubmit: () => undefined,
saveButtonBarState: "default", saveButtonBarState: "default",
updateChannelStatus: () => undefined, updateChannelStatus: () => undefined,

View file

@ -1,4 +1,5 @@
import ShippingZonesCard from "@saleor/channels/components/ShippingZonesCard/ShippingZonesCard"; import ShippingZonesCard from "@saleor/channels/components/ShippingZonesCard/ShippingZonesCard";
import { channelsListUrl } from "@saleor/channels/urls";
import CardSpacer from "@saleor/components/CardSpacer"; import CardSpacer from "@saleor/components/CardSpacer";
import Form from "@saleor/components/Form"; import Form from "@saleor/components/Form";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
@ -14,6 +15,7 @@ import {
import { SearchData } from "@saleor/hooks/makeTopLevelSearch"; import { SearchData } from "@saleor/hooks/makeTopLevelSearch";
import { getParsedSearchData } from "@saleor/hooks/makeTopLevelSearch/utils"; import { getParsedSearchData } from "@saleor/hooks/makeTopLevelSearch/utils";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import useStateFromProps from "@saleor/hooks/useStateFromProps"; import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import { import {
@ -41,7 +43,6 @@ export interface ChannelDetailsPageProps<TErrors> {
fetchMoreShippingZones: FetchMoreProps; fetchMoreShippingZones: FetchMoreProps;
channelShippingZones?: ChannelShippingZones; channelShippingZones?: ChannelShippingZones;
countries: CountryFragment[]; countries: CountryFragment[];
onBack?: () => void;
onDelete?: () => void; onDelete?: () => void;
onSubmit: (data: FormData) => SubmitPromise<TErrors[]>; onSubmit: (data: FormData) => SubmitPromise<TErrors[]>;
updateChannelStatus?: () => void; updateChannelStatus?: () => void;
@ -55,7 +56,6 @@ const ChannelDetailsPage = function<TErrors>({
disabledStatus, disabledStatus,
onSubmit, onSubmit,
errors, errors,
onBack,
onDelete, onDelete,
saveButtonBarState, saveButtonBarState,
updateChannelStatus, updateChannelStatus,
@ -65,6 +65,8 @@ const ChannelDetailsPage = function<TErrors>({
countries, countries,
channelShippingZones = [] channelShippingZones = []
}: ChannelDetailsPageProps<TErrors>) { }: ChannelDetailsPageProps<TErrors>) {
const navigate = useNavigator();
const [selectedCurrencyCode, setSelectedCurrencyCode] = useState(""); const [selectedCurrencyCode, setSelectedCurrencyCode] = useState("");
const [ const [
selectedCountryDisplayName, selectedCountryDisplayName,
@ -202,7 +204,7 @@ const ChannelDetailsPage = function<TErrors>({
</div> </div>
</Grid> </Grid>
<Savebar <Savebar
onCancel={onBack} onCancel={() => navigate(channelsListUrl())}
onSubmit={submit} onSubmit={submit}
onDelete={onDelete} onDelete={onDelete}
state={saveButtonBarState} state={saveButtonBarState}

View file

@ -9,10 +9,7 @@ import ChannelsListPage, { ChannelsListPageProps } from "./ChannelsListPage";
const props: ChannelsListPageProps = { const props: ChannelsListPageProps = {
channelsList, channelsList,
limits, limits,
navigateToChannelCreate: () => undefined, onRemove: () => undefined
onBack: () => undefined,
onRemove: () => undefined,
onRowClick: () => undefined
}; };
storiesOf("Views / Channels / Channels list", module) storiesOf("Views / Channels / Channels list", module)

View file

@ -5,15 +5,20 @@ import {
TableHead, TableHead,
TableRow TableRow
} from "@material-ui/core"; } from "@material-ui/core";
import { channelAddUrl, channelUrl } from "@saleor/channels/urls";
import { Backlink } from "@saleor/components/Backlink";
import { Button } from "@saleor/components/Button";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import LimitReachedAlert from "@saleor/components/LimitReachedAlert"; import LimitReachedAlert from "@saleor/components/LimitReachedAlert";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import ResponsiveTable from "@saleor/components/ResponsiveTable"; import ResponsiveTable from "@saleor/components/ResponsiveTable";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableRowLink from "@saleor/components/TableRowLink";
import { configurationMenuUrl } from "@saleor/configuration";
import { ChannelDetailsFragment, RefreshLimitsQuery } from "@saleor/graphql"; import { ChannelDetailsFragment, RefreshLimitsQuery } from "@saleor/graphql";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, Button, DeleteIcon, IconButton } from "@saleor/macaw-ui"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
import { renderCollection, stopPropagation } from "@saleor/misc"; import { renderCollection, stopPropagation } from "@saleor/misc";
import { hasLimits, isLimitReached } from "@saleor/utils/limits"; import { hasLimits, isLimitReached } from "@saleor/utils/limits";
import React from "react"; import React from "react";
@ -24,9 +29,6 @@ import { useStyles } from "./styles";
export interface ChannelsListPageProps { export interface ChannelsListPageProps {
channelsList: ChannelDetailsFragment[] | undefined; channelsList: ChannelDetailsFragment[] | undefined;
limits: RefreshLimitsQuery["shop"]["limits"]; limits: RefreshLimitsQuery["shop"]["limits"];
navigateToChannelCreate: () => void;
onBack: () => void;
onRowClick: (id: string) => () => void;
onRemove: (id: string) => void; onRemove: (id: string) => void;
} }
@ -35,10 +37,7 @@ const numberOfColumns = 2;
export const ChannelsListPage: React.FC<ChannelsListPageProps> = ({ export const ChannelsListPage: React.FC<ChannelsListPageProps> = ({
channelsList, channelsList,
limits, limits,
navigateToChannelCreate, onRemove
onBack,
onRemove,
onRowClick
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const classes = useStyles({}); const classes = useStyles({});
@ -47,7 +46,7 @@ export const ChannelsListPage: React.FC<ChannelsListPageProps> = ({
return ( return (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={configurationMenuUrl}>
{intl.formatMessage(sectionNames.configuration)} {intl.formatMessage(sectionNames.configuration)}
</Backlink> </Backlink>
<PageHeader <PageHeader
@ -69,7 +68,7 @@ export const ChannelsListPage: React.FC<ChannelsListPageProps> = ({
> >
<Button <Button
disabled={limitReached} disabled={limitReached}
onClick={navigateToChannelCreate} href={channelAddUrl}
variant="primary" variant="primary"
data-test-id="add-channel" data-test-id="add-channel"
> >
@ -118,11 +117,11 @@ export const ChannelsListPage: React.FC<ChannelsListPageProps> = ({
{renderCollection( {renderCollection(
channelsList, channelsList,
channel => ( channel => (
<TableRow <TableRowLink
hover={!!channel} hover={!!channel}
key={channel ? channel.id : "skeleton"} key={channel ? channel.id : "skeleton"}
className={classes.tableRow} className={classes.tableRow}
onClick={!!channel ? onRowClick(channel.id) : undefined} href={channel && channelUrl(channel.id)}
> >
<TableCell className={classes.colName}> <TableCell className={classes.colName}>
<span data-test-id="name"> <span data-test-id="name">
@ -144,7 +143,7 @@ export const ChannelsListPage: React.FC<ChannelsListPageProps> = ({
</IconButton> </IconButton>
)} )}
</TableCell> </TableCell>
</TableRow> </TableRowLink>
), ),
() => ( () => (
<TableRow> <TableRow>

View file

@ -1,4 +1,5 @@
import { FormData } from "@saleor/channels/components/ChannelForm/ChannelForm"; import { FormData } from "@saleor/channels/components/ChannelForm/ChannelForm";
import { Backlink } from "@saleor/components/Backlink";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
@ -13,7 +14,6 @@ import useNotifier from "@saleor/hooks/useNotifier";
import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils"; import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink } from "@saleor/macaw-ui";
import { extractMutationErrors } from "@saleor/misc"; import { extractMutationErrors } from "@saleor/misc";
import useShippingZonesSearch from "@saleor/searches/useShippingZonesSearch"; import useShippingZonesSearch from "@saleor/searches/useShippingZonesSearch";
import currencyCodes from "currency-codes"; import currencyCodes from "currency-codes";
@ -29,8 +29,6 @@ export const ChannelCreateView = ({}) => {
const intl = useIntl(); const intl = useIntl();
const shop = useShop(); const shop = useShop();
const handleBack = () => navigate(channelsListUrl());
const [createChannel, createChannelOpts] = useChannelCreateMutation({ const [createChannel, createChannelOpts] = useChannelCreateMutation({
onCompleted: ({ onCompleted: ({
channelCreate: { errors, channel } channelCreate: { errors, channel }
@ -94,7 +92,7 @@ export const ChannelCreateView = ({}) => {
})} })}
/> />
<Container> <Container>
<Backlink onClick={handleBack}> <Backlink href={channelsListUrl()}>
{intl.formatMessage(sectionNames.channels)} {intl.formatMessage(sectionNames.channels)}
</Backlink> </Backlink>
<PageHeader <PageHeader
@ -115,7 +113,6 @@ export const ChannelCreateView = ({}) => {
errors={createChannelOpts?.data?.channelCreate?.errors || []} errors={createChannelOpts?.data?.channelCreate?.errors || []}
currencyCodes={currencyCodeChoices} currencyCodes={currencyCodeChoices}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onBack={handleBack}
saveButtonBarState={createChannelOpts.status} saveButtonBarState={createChannelOpts.status}
countries={shop?.countries || []} countries={shop?.countries || []}
/> />

View file

@ -1,6 +1,7 @@
import ChannelDeleteDialog from "@saleor/channels/components/ChannelDeleteDialog"; import ChannelDeleteDialog from "@saleor/channels/components/ChannelDeleteDialog";
import { FormData } from "@saleor/channels/components/ChannelForm/ChannelForm"; import { FormData } from "@saleor/channels/components/ChannelForm/ChannelForm";
import { getChannelsCurrencyChoices } from "@saleor/channels/utils"; import { getChannelsCurrencyChoices } from "@saleor/channels/utils";
import { Backlink } from "@saleor/components/Backlink";
import Container from "@saleor/components/Container"; import Container from "@saleor/components/Container";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
@ -23,7 +24,6 @@ import useNotifier from "@saleor/hooks/useNotifier";
import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils"; import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink } from "@saleor/macaw-ui";
import { extractMutationErrors } from "@saleor/misc"; import { extractMutationErrors } from "@saleor/misc";
import useShippingZonesSearch from "@saleor/searches/useShippingZonesSearch"; import useShippingZonesSearch from "@saleor/searches/useShippingZonesSearch";
import getChannelsErrorMessage from "@saleor/utils/errors/channels"; import getChannelsErrorMessage from "@saleor/utils/errors/channels";
@ -53,8 +53,6 @@ export const ChannelDetails: React.FC<ChannelDetailsProps> = ({
const intl = useIntl(); const intl = useIntl();
const shop = useShop(); const shop = useShop();
const handleBack = () => navigate(channelsListUrl());
const channelsListData = useChannelsQuery({ displayLoader: true }); const channelsListData = useChannelsQuery({ displayLoader: true });
const [openModal, closeModal] = createDialogActionHandlers< const [openModal, closeModal] = createDialogActionHandlers<
@ -188,7 +186,7 @@ export const ChannelDetails: React.FC<ChannelDetailsProps> = ({
})} })}
/> />
<Container> <Container>
<Backlink onClick={handleBack}> <Backlink href={channelsListUrl()}>
{intl.formatMessage(sectionNames.channels)} {intl.formatMessage(sectionNames.channels)}
</Backlink> </Backlink>
<PageHeader title={data?.channel?.name} /> <PageHeader title={data?.channel?.name} />
@ -210,7 +208,6 @@ export const ChannelDetails: React.FC<ChannelDetailsProps> = ({
activateChannelOpts.loading || deactivateChannelOpts.loading activateChannelOpts.loading || deactivateChannelOpts.loading
} }
errors={updateChannelOpts?.data?.channelUpdate?.errors || []} errors={updateChannelOpts?.data?.channelUpdate?.errors || []}
onBack={handleBack}
onDelete={() => openModal("remove")} onDelete={() => openModal("remove")}
onSubmit={handleSubmit} onSubmit={handleSubmit}
updateChannelStatus={() => updateChannelStatus={() =>

View file

@ -1,6 +1,5 @@
import { getChannelsCurrencyChoices } from "@saleor/channels/utils"; import { getChannelsCurrencyChoices } from "@saleor/channels/utils";
import { useShopLimitsQuery } from "@saleor/components/Shop/queries"; import { useShopLimitsQuery } from "@saleor/components/Shop/queries";
import { configurationMenuUrl } from "@saleor/configuration";
import { import {
ChannelDeleteMutation, ChannelDeleteMutation,
useChannelDeleteMutation, useChannelDeleteMutation,
@ -16,11 +15,9 @@ import { useIntl } from "react-intl";
import ChannelDeleteDialog from "../../components/ChannelDeleteDialog"; import ChannelDeleteDialog from "../../components/ChannelDeleteDialog";
import ChannelsListPage from "../../pages/ChannelsListPage"; import ChannelsListPage from "../../pages/ChannelsListPage";
import { import {
channelAddUrl,
channelsListUrl, channelsListUrl,
ChannelsListUrlDialog, ChannelsListUrlDialog,
ChannelsListUrlQueryParams, ChannelsListUrlQueryParams
channelUrl
} from "../../urls"; } from "../../urls";
interface ChannelsListProps { interface ChannelsListProps {
@ -81,8 +78,6 @@ export const ChannelsList: React.FC<ChannelsListProps> = ({ params }) => {
data?.channels data?.channels
); );
const navigateToChannelCreate = () => navigate(channelAddUrl);
const handleRemoveConfirm = (channelId?: string) => { const handleRemoveConfirm = (channelId?: string) => {
const inputVariables = channelId ? { input: { channelId } } : {}; const inputVariables = channelId ? { input: { channelId } } : {};
@ -99,9 +94,6 @@ export const ChannelsList: React.FC<ChannelsListProps> = ({ params }) => {
<ChannelsListPage <ChannelsListPage
channelsList={data?.channels} channelsList={data?.channels}
limits={limitOpts.data?.shop.limits} limits={limitOpts.data?.shop.limits}
navigateToChannelCreate={navigateToChannelCreate}
onBack={() => navigate(configurationMenuUrl)}
onRowClick={id => () => navigate(channelUrl(id))}
onRemove={id => onRemove={id =>
openModal("remove", { openModal("remove", {
id id

View file

@ -1,4 +1,6 @@
import { ChannelCollectionData } from "@saleor/channels/utils"; import { ChannelCollectionData } from "@saleor/channels/utils";
import { collectionListUrl } from "@saleor/collections/urls";
import { Backlink } from "@saleor/components/Backlink";
import { CardSpacer } from "@saleor/components/CardSpacer"; import { CardSpacer } from "@saleor/components/CardSpacer";
import ChannelsAvailabilityCard from "@saleor/components/ChannelsAvailabilityCard"; import ChannelsAvailabilityCard from "@saleor/components/ChannelsAvailabilityCard";
import { Container } from "@saleor/components/Container"; import { Container } from "@saleor/components/Container";
@ -13,8 +15,9 @@ import {
PermissionEnum PermissionEnum
} from "@saleor/graphql"; } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
@ -29,7 +32,6 @@ export interface CollectionCreatePageProps {
disabled: boolean; disabled: boolean;
errors: CollectionErrorFragment[]; errors: CollectionErrorFragment[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void;
onSubmit: (data: CollectionCreateData) => SubmitPromise; onSubmit: (data: CollectionCreateData) => SubmitPromise;
onChannelsChange: (data: ChannelCollectionData[]) => void; onChannelsChange: (data: ChannelCollectionData[]) => void;
openChannelsModal: () => void; openChannelsModal: () => void;
@ -42,12 +44,12 @@ const CollectionCreatePage: React.FC<CollectionCreatePageProps> = ({
disabled, disabled,
errors, errors,
saveButtonBarState, saveButtonBarState,
onBack,
onChannelsChange, onChannelsChange,
openChannelsModal, openChannelsModal,
onSubmit onSubmit
}: CollectionCreatePageProps) => { }: CollectionCreatePageProps) => {
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigator();
return ( return (
<CollectionCreateForm <CollectionCreateForm
@ -58,7 +60,7 @@ const CollectionCreatePage: React.FC<CollectionCreatePageProps> = ({
> >
{({ change, data, handlers, submit, isSaveDisabled }) => ( {({ change, data, handlers, submit, isSaveDisabled }) => (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={collectionListUrl()}>
{intl.formatMessage(sectionNames.collections)} {intl.formatMessage(sectionNames.collections)}
</Backlink> </Backlink>
<PageHeader <PageHeader
@ -162,7 +164,7 @@ const CollectionCreatePage: React.FC<CollectionCreatePageProps> = ({
<Savebar <Savebar
state={saveButtonBarState} state={saveButtonBarState}
disabled={isSaveDisabled} disabled={isSaveDisabled}
onCancel={onBack} onCancel={() => navigate(collectionListUrl())}
onSubmit={submit} onSubmit={submit}
/> />
</Container> </Container>

View file

@ -1,4 +1,6 @@
import { ChannelCollectionData } from "@saleor/channels/utils"; import { ChannelCollectionData } from "@saleor/channels/utils";
import { collectionListUrl } from "@saleor/collections/urls";
import { Backlink } from "@saleor/components/Backlink";
import { CardSpacer } from "@saleor/components/CardSpacer"; import { CardSpacer } from "@saleor/components/CardSpacer";
import ChannelsAvailabilityCard from "@saleor/components/ChannelsAvailabilityCard"; import ChannelsAvailabilityCard from "@saleor/components/ChannelsAvailabilityCard";
import { Container } from "@saleor/components/Container"; import { Container } from "@saleor/components/Container";
@ -14,8 +16,9 @@ import {
PermissionEnum PermissionEnum
} from "@saleor/graphql"; } from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm"; import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Backlink, ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
@ -29,13 +32,13 @@ export interface CollectionDetailsPageProps
extends PageListProps, extends PageListProps,
ListActions, ListActions,
ChannelProps { ChannelProps {
onAdd: () => void;
channelsCount: number; channelsCount: number;
channelsErrors: CollectionChannelListingErrorFragment[]; channelsErrors: CollectionChannelListingErrorFragment[];
collection: CollectionDetailsQuery["collection"]; collection: CollectionDetailsQuery["collection"];
currentChannels: ChannelCollectionData[]; currentChannels: ChannelCollectionData[];
errors: CollectionErrorFragment[]; errors: CollectionErrorFragment[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
onBack: () => void;
onCollectionRemove: () => void; onCollectionRemove: () => void;
onImageDelete: () => void; onImageDelete: () => void;
onImageUpload: (file: File) => void; onImageUpload: (file: File) => void;
@ -53,8 +56,6 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
disabled, disabled,
errors, errors,
saveButtonBarState, saveButtonBarState,
selectedChannelId,
onBack,
onCollectionRemove, onCollectionRemove,
onImageDelete, onImageDelete,
onImageUpload, onImageUpload,
@ -64,6 +65,7 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
...collectionProductsProps ...collectionProductsProps
}: CollectionDetailsPageProps) => { }: CollectionDetailsPageProps) => {
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigator();
return ( return (
<CollectionUpdateForm <CollectionUpdateForm
@ -75,7 +77,7 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
> >
{({ change, data, handlers, submit, isSaveDisabled }) => ( {({ change, data, handlers, submit, isSaveDisabled }) => (
<Container> <Container>
<Backlink onClick={onBack}> <Backlink href={collectionListUrl()}>
{intl.formatMessage(sectionNames.collections)} {intl.formatMessage(sectionNames.collections)}
</Backlink> </Backlink>
<PageHeader title={collection?.name} /> <PageHeader title={collection?.name} />
@ -153,7 +155,7 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
<Savebar <Savebar
state={saveButtonBarState} state={saveButtonBarState}
disabled={isSaveDisabled} disabled={isSaveDisabled}
onCancel={onBack} onCancel={() => navigate(collectionListUrl())}
onDelete={onCollectionRemove} onDelete={onCollectionRemove}
onSubmit={submit} onSubmit={submit}
/> />

View file

@ -1,4 +1,5 @@
import { Card, CardContent, TextField } from "@material-ui/core"; import { Card, CardContent, TextField } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import Hr from "@saleor/components/Hr"; import Hr from "@saleor/components/Hr";
import ImageUpload from "@saleor/components/ImageUpload"; import ImageUpload from "@saleor/components/ImageUpload";
@ -6,7 +7,7 @@ import MediaTile from "@saleor/components/MediaTile";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { CollectionDetailsFragment } from "@saleor/graphql"; import { CollectionDetailsFragment } from "@saleor/graphql";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -1,5 +1,8 @@
import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core"; import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core";
import { CollectionListUrlSortField } from "@saleor/collections/urls"; import {
CollectionListUrlSortField,
collectionUrl
} from "@saleor/collections/urls";
import { canBeSorted } from "@saleor/collections/views/CollectionList/sort"; import { canBeSorted } from "@saleor/collections/views/CollectionList/sort";
import { ChannelsAvailabilityDropdown } from "@saleor/components/ChannelsAvailabilityDropdown"; import { ChannelsAvailabilityDropdown } from "@saleor/components/ChannelsAvailabilityDropdown";
import { import {
@ -12,6 +15,7 @@ import Skeleton from "@saleor/components/Skeleton";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TableRowLink from "@saleor/components/TableRowLink";
import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader"; import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader";
import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages"; import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages";
import { CollectionListQuery } from "@saleor/graphql"; import { CollectionListQuery } from "@saleor/graphql";
@ -72,7 +76,6 @@ const CollectionList: React.FC<CollectionListProps> = props => {
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onUpdateListSettings, onUpdateListSettings,
onRowClick,
onSort, onSort,
pageInfo, pageInfo,
isChecked, isChecked,
@ -169,10 +172,10 @@ const CollectionList: React.FC<CollectionListProps> = props => {
listing => listing?.channel?.id === selectedChannelId listing => listing?.channel?.id === selectedChannelId
); );
return ( return (
<TableRow <TableRowLink
className={classes.tableRow} className={classes.tableRow}
hover={!!collection} hover={!!collection}
onClick={collection ? onRowClick(collection.id) : undefined} href={collection && collectionUrl(collection.id)}
key={collection ? collection.id : "skeleton"} key={collection ? collection.id : "skeleton"}
selected={isSelected} selected={isSelected}
data-test-id={"id-" + maybe(() => collection.id)} data-test-id={"id-" + maybe(() => collection.id)}
@ -213,7 +216,7 @@ const CollectionList: React.FC<CollectionListProps> = props => {
/> />
))} ))}
</TableCell> </TableCell>
</TableRow> </TableRowLink>
); );
}, },
() => ( () => (

View file

@ -1,10 +1,11 @@
import { Card } from "@material-ui/core"; import { Card } from "@material-ui/core";
import { collectionAddUrl } from "@saleor/collections/urls";
import { Button } from "@saleor/components/Button";
import { Container } from "@saleor/components/Container"; import { Container } from "@saleor/components/Container";
import { getByName } from "@saleor/components/Filter/utils"; import { getByName } from "@saleor/components/Filter/utils";
import FilterBar from "@saleor/components/FilterBar"; import FilterBar from "@saleor/components/FilterBar";
import PageHeader from "@saleor/components/PageHeader"; import PageHeader from "@saleor/components/PageHeader";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { Button } from "@saleor/macaw-ui";
import { import {
FilterPageProps, FilterPageProps,
PageListProps, PageListProps,
@ -27,16 +28,12 @@ export interface CollectionListPageProps
SearchPageProps, SearchPageProps,
TabPageProps, TabPageProps,
FilterPageProps<CollectionFilterKeys, CollectionListFilterOpts>, FilterPageProps<CollectionFilterKeys, CollectionListFilterOpts>,
CollectionListProps { CollectionListProps {}
channelsCount: number;
}
const CollectionListPage: React.FC<CollectionListPageProps> = ({ const CollectionListPage: React.FC<CollectionListPageProps> = ({
channelsCount,
currentTab, currentTab,
disabled, disabled,
initialSearch, initialSearch,
onAdd,
onAll, onAll,
onSearchChange, onSearchChange,
onTabChange, onTabChange,
@ -60,7 +57,7 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
<Button <Button
disabled={disabled} disabled={disabled}
variant="primary" variant="primary"
onClick={onAdd} href={collectionAddUrl()}
data-test-id="create-collection" data-test-id="create-collection"
> >
<FormattedMessage <FormattedMessage

View file

@ -5,6 +5,7 @@ import {
TableFooter, TableFooter,
TableRow TableRow
} from "@material-ui/core"; } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import { ChannelsAvailabilityDropdown } from "@saleor/components/ChannelsAvailabilityDropdown"; import { ChannelsAvailabilityDropdown } from "@saleor/components/ChannelsAvailabilityDropdown";
import Checkbox from "@saleor/components/Checkbox"; import Checkbox from "@saleor/components/Checkbox";
@ -14,8 +15,10 @@ import TableCellAvatar from "@saleor/components/TableCellAvatar";
import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar"; import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar";
import TableHead from "@saleor/components/TableHead"; import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import TableRowLink from "@saleor/components/TableRowLink";
import { CollectionDetailsQuery } from "@saleor/graphql"; import { CollectionDetailsQuery } from "@saleor/graphql";
import { Button, DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
import { productUrl } from "@saleor/products/urls";
import { mapEdgesToItems } from "@saleor/utils/maps"; import { mapEdgesToItems } from "@saleor/utils/maps";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
@ -55,6 +58,7 @@ const useStyles = makeStyles(
export interface CollectionProductsProps extends PageListProps, ListActions { export interface CollectionProductsProps extends PageListProps, ListActions {
collection: CollectionDetailsQuery["collection"]; collection: CollectionDetailsQuery["collection"];
onProductUnassign: (id: string, event: React.MouseEvent<any>) => void; onProductUnassign: (id: string, event: React.MouseEvent<any>) => void;
onAdd: () => void;
} }
const CollectionProducts: React.FC<CollectionProductsProps> = props => { const CollectionProducts: React.FC<CollectionProductsProps> = props => {
@ -65,7 +69,6 @@ const CollectionProducts: React.FC<CollectionProductsProps> = props => {
onNextPage, onNextPage,
onPreviousPage, onPreviousPage,
onProductUnassign, onProductUnassign,
onRowClick,
pageInfo, pageInfo,
isChecked, isChecked,
selected, selected,
@ -166,10 +169,10 @@ const CollectionProducts: React.FC<CollectionProductsProps> = props => {
const isSelected = product ? isChecked(product.id) : false; const isSelected = product ? isChecked(product.id) : false;
return ( return (
<TableRow <TableRowLink
className={classes.tableRow} className={classes.tableRow}
hover={!!product} hover={!!product}
onClick={!!product ? onRowClick(product.id) : undefined} href={product && productUrl(product.id)}
key={product ? product.id : "skeleton"} key={product ? product.id : "skeleton"}
selected={isSelected} selected={isSelected}
> >
@ -214,7 +217,7 @@ const CollectionProducts: React.FC<CollectionProductsProps> = props => {
<DeleteIcon /> <DeleteIcon />
</IconButton> </IconButton>
</TableCell> </TableCell>
</TableRow> </TableRowLink>
); );
}, },
() => ( () => (

View file

@ -26,7 +26,6 @@ import { CollectionCreateData } from "../components/CollectionCreatePage/form";
import { import {
collectionAddUrl, collectionAddUrl,
CollectionCreateUrlQueryParams, CollectionCreateUrlQueryParams,
collectionListUrl,
collectionUrl collectionUrl
} from "../urls"; } from "../urls";
import { COLLECTION_CREATE_FORM_ID } from "./consts"; import { COLLECTION_CREATE_FORM_ID } from "./consts";
@ -180,7 +179,6 @@ export const CollectionCreate: React.FC<CollectionCreateProps> = ({
channelsCount={availableChannels.length} channelsCount={availableChannels.length}
openChannelsModal={handleChannelsModalOpen} openChannelsModal={handleChannelsModalOpen}
onChannelsChange={setCurrentChannels} onChannelsChange={setCurrentChannels}
onBack={() => navigate(collectionListUrl())}
disabled={createCollectionOpts.loading || updateChannelsOpts.loading} disabled={createCollectionOpts.loading || updateChannelsOpts.loading}
onSubmit={handleSubmit} onSubmit={handleSubmit}
saveButtonBarState={createCollectionOpts.status} saveButtonBarState={createCollectionOpts.status}

View file

@ -6,6 +6,7 @@ import {
import ActionDialog from "@saleor/components/ActionDialog"; import ActionDialog from "@saleor/components/ActionDialog";
import useAppChannel from "@saleor/components/AppLayout/AppChannelContext"; import useAppChannel from "@saleor/components/AppLayout/AppChannelContext";
import AssignProductDialog from "@saleor/components/AssignProductDialog"; import AssignProductDialog from "@saleor/components/AssignProductDialog";
import { Button } from "@saleor/components/Button";
import ChannelsAvailabilityDialog from "@saleor/components/ChannelsAvailabilityDialog"; import ChannelsAvailabilityDialog from "@saleor/components/ChannelsAvailabilityDialog";
import NotFoundPage from "@saleor/components/NotFoundPage"; import NotFoundPage from "@saleor/components/NotFoundPage";
import { WindowTitle } from "@saleor/components/WindowTitle"; import { WindowTitle } from "@saleor/components/WindowTitle";
@ -31,7 +32,6 @@ import useLocalStorage from "@saleor/hooks/useLocalStorage";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import { commonMessages, errorMessages } from "@saleor/intl"; import { commonMessages, errorMessages } from "@saleor/intl";
import { Button } from "@saleor/macaw-ui";
import useProductSearch from "@saleor/searches/useProductSearch"; import useProductSearch from "@saleor/searches/useProductSearch";
import { arrayDiff } from "@saleor/utils/arrays"; import { arrayDiff } from "@saleor/utils/arrays";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
@ -42,7 +42,6 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { getMutationErrors, getMutationState, maybe } from "../../misc"; import { getMutationErrors, getMutationState, maybe } from "../../misc";
import { productUrl } from "../../products/urls";
import CollectionDetailsPage from "../components/CollectionDetailsPage/CollectionDetailsPage"; import CollectionDetailsPage from "../components/CollectionDetailsPage/CollectionDetailsPage";
import { CollectionUpdateData } from "../components/CollectionDetailsPage/form"; import { CollectionUpdateData } from "../components/CollectionDetailsPage/form";
import { import {
@ -165,8 +164,6 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
); );
const paginate = useLocalPaginator(setPaginationState); const paginate = useLocalPaginator(setPaginationState);
const handleBack = () => navigate(collectionListUrl());
const [selectedChannel] = useLocalStorage("collectionListChannel", ""); const [selectedChannel] = useLocalStorage("collectionListChannel", "");
const { data, loading } = useCollectionDetailsQuery({ const { data, loading } = useCollectionDetailsQuery({
@ -176,7 +173,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
const collection = data?.collection; const collection = data?.collection;
if (collection === null) { if (collection === null) {
return <NotFoundPage onBack={handleBack} />; return <NotFoundPage backHref={collectionListUrl()} />;
} }
const allChannels = createCollectionChannels( const allChannels = createCollectionChannels(
availableChannels availableChannels
@ -286,7 +283,6 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
)} )}
<CollectionDetailsPage <CollectionDetailsPage
onAdd={() => openModal("assign")} onAdd={() => openModal("assign")}
onBack={handleBack}
disabled={loading || updateChannelsOpts.loading} disabled={loading || updateChannelsOpts.loading}
collection={data?.collection} collection={data?.collection}
channelsErrors={ channelsErrors={
@ -319,7 +315,6 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
} }
}); });
}} }}
onRowClick={id => () => navigate(productUrl(id))}
saveButtonBarState={formTransitionState} saveButtonBarState={formTransitionState}
toolbar={ toolbar={
<Button <Button

View file

@ -31,11 +31,9 @@ import { FormattedMessage, useIntl } from "react-intl";
import CollectionListPage from "../../components/CollectionListPage/CollectionListPage"; import CollectionListPage from "../../components/CollectionListPage/CollectionListPage";
import { import {
collectionAddUrl,
collectionListUrl, collectionListUrl,
CollectionListUrlDialog, CollectionListUrlDialog,
CollectionListUrlQueryParams, CollectionListUrlQueryParams
collectionUrl
} from "../../urls"; } from "../../urls";
import { import {
deleteFilterTab, deleteFilterTab,
@ -175,7 +173,6 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
currentTab={currentTab} currentTab={currentTab}
initialSearch={params.query || ""} initialSearch={params.query || ""}
onSearchChange={handleSearchChange} onSearchChange={handleSearchChange}
onAdd={() => navigate(collectionAddUrl())}
onAll={resetFilters} onAll={resetFilters}
onTabChange={handleTabChange} onTabChange={handleTabChange}
onTabDelete={() => openModal("delete-search")} onTabDelete={() => openModal("delete-search")}
@ -190,7 +187,6 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
onUpdateListSettings={updateListSettings} onUpdateListSettings={updateListSettings}
pageInfo={pageInfo} pageInfo={pageInfo}
sort={getSortParams(params)} sort={getSortParams(params)}
onRowClick={id => () => navigate(collectionUrl(id))}
toolbar={ toolbar={
<IconButton <IconButton
variant="secondary" variant="secondary"
@ -209,7 +205,6 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
selected={listElements.length} selected={listElements.length}
toggle={toggle} toggle={toggle}
toggleAll={toggleAll} toggleAll={toggleAll}
channelsCount={availableChannels?.length}
selectedChannelId={selectedChannel?.id} selectedChannelId={selectedChannel?.id}
filterOpts={filterOpts} filterOpts={filterOpts}
onFilterChange={changeFilters} onFilterChange={changeFilters}

View file

@ -12,7 +12,6 @@ import {
useTheme useTheme
} from "@saleor/macaw-ui"; } from "@saleor/macaw-ui";
import { isDarkTheme } from "@saleor/misc"; import { isDarkTheme } from "@saleor/misc";
import { staffMemberDetailsUrl } from "@saleor/staff/urls";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import useRouter from "use-react-router"; import useRouter from "use-react-router";
@ -26,6 +25,7 @@ import useAppChannel from "./AppChannelContext";
import AppChannelSelect from "./AppChannelSelect"; import AppChannelSelect from "./AppChannelSelect";
import { appLoaderHeight } from "./consts"; import { appLoaderHeight } from "./consts";
import useMenuStructure from "./menuStructure"; import useMenuStructure from "./menuStructure";
import { SidebarLink } from "./SidebarLink";
import { isMenuActive } from "./utils"; import { isMenuActive } from "./utils";
const useStyles = makeStyles( const useStyles = makeStyles(
@ -171,6 +171,8 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
activeId={activeMenu} activeId={activeMenu}
menuItems={menuStructure} menuItems={menuStructure}
onMenuItemClick={handleMenuItemClick} onMenuItemClick={handleMenuItemClick}
logoHref="/"
linkComponent={SidebarLink}
/> />
)} )}
<div className={classes.content}> <div className={classes.content}>
@ -188,7 +190,9 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
{!isMdUp && ( {!isMdUp && (
<SidebarDrawer <SidebarDrawer
menuItems={menuStructure} menuItems={menuStructure}
logoHref="/"
onMenuItemClick={handleMenuItemClick} onMenuItemClick={handleMenuItemClick}
linkComponent={SidebarLink}
/> />
)} )}
<div className={classes.spacer} /> <div className={classes.spacer} />
@ -208,9 +212,6 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
isDarkThemeEnabled={isDarkTheme(themeType)} isDarkThemeEnabled={isDarkTheme(themeType)}
user={user} user={user}
onLogout={logout} onLogout={logout}
onProfileClick={() =>
navigate(staffMemberDetailsUrl(user?.id))
}
onThemeToggle={toggleTheme} onThemeToggle={toggleTheme}
/> />
</div> </div>

View file

@ -0,0 +1,13 @@
import React from "react";
import { Link, LinkProps } from "react-router-dom";
interface SidebarLinkProps extends Omit<LinkProps, "to"> {
href?: string;
}
export const SidebarLink = React.forwardRef<
HTMLAnchorElement,
SidebarLinkProps
>(({ href, ...props }, ref) => <Link to={href} {...props} innerRef={ref} />);
SidebarLink.displayName = "SidebarLink";

View file

@ -15,7 +15,6 @@ import { configurationMenuUrl } from "@saleor/configuration";
import { getConfigMenuItemsPermissions } from "@saleor/configuration/utils"; import { getConfigMenuItemsPermissions } from "@saleor/configuration/utils";
import { giftCardListUrl } from "@saleor/giftCards/urls"; import { giftCardListUrl } from "@saleor/giftCards/urls";
import { PermissionEnum, UserFragment } from "@saleor/graphql"; import { PermissionEnum, UserFragment } from "@saleor/graphql";
import useNavigator from "@saleor/hooks/useNavigator";
import { commonMessages, sectionNames } from "@saleor/intl"; import { commonMessages, sectionNames } from "@saleor/intl";
import { SidebarMenuItem } from "@saleor/macaw-ui"; import { SidebarMenuItem } from "@saleor/macaw-ui";
import { pageListPath } from "@saleor/pages/urls"; import { pageListPath } from "@saleor/pages/urls";
@ -40,7 +39,6 @@ function useMenuStructure(
intl: IntlShape, intl: IntlShape,
user: UserFragment user: UserFragment
): [SidebarMenuItem[], (menuItem: SidebarMenuItem) => void] { ): [SidebarMenuItem[], (menuItem: SidebarMenuItem) => void] {
const navigate = useNavigator();
const extensions = useExtensions(extensionMountPoints.NAVIGATION_SIDEBAR); const extensions = useExtensions(extensionMountPoints.NAVIGATION_SIDEBAR);
const handleMenuItemClick = (menuItem: SidebarMenuItem) => { const handleMenuItemClick = (menuItem: SidebarMenuItem) => {
@ -49,7 +47,6 @@ function useMenuStructure(
extension.open(); extension.open();
return; return;
} }
navigate(menuItem.url, { resetScroll: true });
}; };
const appExtensionsHeaderItem = { const appExtensionsHeaderItem = {

View file

@ -1,6 +1,7 @@
import { Typography } from "@material-ui/core"; import { Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import Grid from "@saleor/components/Grid"; import Grid from "@saleor/components/Grid";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
const useStyles = makeStyles( const useStyles = makeStyles(

View file

@ -1,5 +1,6 @@
import { Button } from "@saleor/components/Button";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { Button, ButtonProps } from "@saleor/macaw-ui"; import { ButtonProps } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";

View file

@ -0,0 +1,27 @@
import { Backlink as MacawBacklink, BacklinkProps } from "@saleor/macaw-ui";
import { isExternalURL } from "@saleor/utils/urls";
import React from "react";
import { Link, LinkProps } from "react-router-dom";
type LinkType = React.FunctionComponent<LinkProps>;
export const Backlink = ({
href,
...props
}: BacklinkProps<"a"> & BacklinkProps<"button">) => {
if (href && !isExternalURL(href)) {
return (
<MacawBacklink<LinkType>
{...props}
component={(Link as unknown) as LinkType}
to={href}
/>
);
}
if (href) {
return <MacawBacklink<"a"> href={href} {...props} />;
}
return <MacawBacklink<"button"> {...props} />;
};

View file

@ -0,0 +1 @@
export * from "./Backlink";

View file

@ -0,0 +1,16 @@
import { OverridableComponent } from "@material-ui/core/OverridableComponent";
import { Button as MacawButton, ButtonTypeMap } from "@saleor/macaw-ui";
import { isExternalURL } from "@saleor/utils/urls";
import React from "react";
import { Link } from "react-router-dom";
const _Button: React.FC<any> = React.forwardRef(({ href, ...props }, ref) => {
if (href && !isExternalURL(href)) {
return <MacawButton {...props} to={href} component={Link} ref={ref} />;
}
return <MacawButton href={href} {...props} ref={ref} />;
});
_Button.displayName = "Button";
export const Button = _Button as OverridableComponent<ButtonTypeMap>;

View file

@ -0,0 +1 @@
export { Button } from "./Button";

View file

@ -1,5 +1,4 @@
import { import {
Button,
ButtonGroup, ButtonGroup,
ButtonGroupProps, ButtonGroupProps,
ClickAwayListener, ClickAwayListener,
@ -10,6 +9,7 @@ import {
Popper Popper
} from "@material-ui/core"; } from "@material-ui/core";
import { ArrowDropDown as ArrowDropDownIcon } from "@material-ui/icons"; import { ArrowDropDown as ArrowDropDownIcon } from "@material-ui/icons";
import { Button } from "@saleor/components/Button";
import React from "react"; import React from "react";
import { useStyles } from "./styles"; import { useStyles } from "./styles";
@ -23,13 +23,13 @@ interface Option {
export interface ButtonWithSelectProps export interface ButtonWithSelectProps
extends Omit<ButtonGroupProps, "onClick"> { extends Omit<ButtonGroupProps, "onClick"> {
options: Option[]; options: Option[];
onClick(e: React.MouseEvent<HTMLButtonElement, MouseEvent>): void; href: string;
} }
export const ButtonWithSelect: React.FC<ButtonWithSelectProps> = ({ export const ButtonWithSelect: React.FC<ButtonWithSelectProps> = ({
options, options,
children, children,
onClick, href,
...props ...props
}) => { }) => {
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
@ -68,7 +68,7 @@ export const ButtonWithSelect: React.FC<ButtonWithSelectProps> = ({
aria-label="button with select" aria-label="button with select"
{...props} {...props}
> >
<Button onClick={onClick} style={{ width: "100%" }}> <Button variant="primary" href={href} style={{ width: "100%" }}>
{children} {children}
</Button> </Button>
{options.length > 0 && ( {options.length > 0 && (

View file

@ -8,11 +8,12 @@ import {
Popper, Popper,
Typography Typography
} from "@material-ui/core"; } from "@material-ui/core";
import { IconButton, makeStyles, MoreIcon } from "@saleor/macaw-ui"; import { makeStyles, MoreIcon } from "@saleor/macaw-ui";
import classNames from "classnames"; import classNames from "classnames";
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { IconButton } from "../IconButton";
import { cardMenuMessages as messages } from "./messages"; import { cardMenuMessages as messages } from "./messages";
const ITEM_HEIGHT = 48; const ITEM_HEIGHT = 48;

View file

@ -1,9 +1,9 @@
import { Card, CardContent, Typography } from "@material-ui/core"; import { Card, CardContent, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import Hr from "@saleor/components/Hr"; import Hr from "@saleor/components/Hr";
import RequirePermissions from "@saleor/components/RequirePermissions"; import RequirePermissions from "@saleor/components/RequirePermissions";
import { PermissionEnum } from "@saleor/graphql"; import { PermissionEnum } from "@saleor/graphql";
import { Button } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";

View file

@ -0,0 +1,65 @@
import { fade } from "@material-ui/core/styles/colorManipulator";
import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
import { Button } from "@saleor/components/Button";
import { makeStyles } from "@saleor/macaw-ui";
import classNames from "classnames";
import React from "react";
import { FormattedMessage } from "react-intl";
interface ColumnPickerButtonProps {
active: boolean;
className?: string;
onClick: () => void;
}
const useStyles = makeStyles(
theme => ({
icon: {
marginLeft: theme.spacing(2),
transition: theme.transitions.duration.short + "ms"
},
root: {
"& span": {
color: theme.palette.primary.main
},
paddingRight: theme.spacing(1)
},
rootActive: {
background: fade(theme.palette.primary.main, 0.1)
},
rotate: {
transform: "rotate(180deg)"
}
}),
{
name: "ColumnPickerButton"
}
);
const ColumnPickerButton: React.FC<ColumnPickerButtonProps> = props => {
const { active, className, onClick } = props;
const classes = useStyles(props);
return (
<Button
className={classNames(classes.root, className, {
[classes.rootActive]: active
})}
onClick={onClick}
variant="secondary"
>
<FormattedMessage
id="142MJn"
defaultMessage="Columns"
description="select visible columns button"
/>
<ArrowDropDownIcon
className={classNames(classes.icon, {
[classes.rotate]: active
})}
/>
</Button>
);
};
export default ColumnPickerButton;

View file

@ -6,10 +6,10 @@ import {
MenuItem, MenuItem,
Typography Typography
} from "@material-ui/core"; } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import { FormChange } from "@saleor/hooks/useForm"; import { FormChange } from "@saleor/hooks/useForm";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { import {
Button,
Choice, Choice,
CloseIcon, CloseIcon,
IconButton, IconButton,

View file

@ -1,10 +1,11 @@
import { Card, TableBody, TableCell, TableRow } from "@material-ui/core"; import { Card, TableBody, TableCell, TableRow } from "@material-ui/core";
import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown"; import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
import { Button } from "@saleor/components/Button";
import CardTitle from "@saleor/components/CardTitle"; import CardTitle from "@saleor/components/CardTitle";
import ResponsiveTable from "@saleor/components/ResponsiveTable"; import ResponsiveTable from "@saleor/components/ResponsiveTable";
import Skeleton from "@saleor/components/Skeleton"; import Skeleton from "@saleor/components/Skeleton";
import { CountryFragment } from "@saleor/graphql"; import { CountryFragment } from "@saleor/graphql";
import { Button, DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";

View file

@ -1,5 +1,5 @@
import { Button } from "@saleor/components/Button";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { Button } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";

View file

@ -1,7 +1,8 @@
import { Typography } from "@material-ui/core"; import { Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import { FileFragment } from "@saleor/graphql"; import { FileFragment } from "@saleor/graphql";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { Button, DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";

View file

@ -1,6 +1,7 @@
import { Typography } from "@material-ui/core"; import { Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import { buttonMessages } from "@saleor/intl"; import { buttonMessages } from "@saleor/intl";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";

View file

@ -1,4 +1,5 @@
import { Button, makeStyles } from "@saleor/macaw-ui"; import { Button } from "@saleor/components/Button";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -0,0 +1,25 @@
import {
IconButton as MacawIconButton,
IconButtonProps
} from "@saleor/macaw-ui";
import { isExternalURL } from "@saleor/utils/urls";
import React from "react";
import { Link } from "react-router-dom";
const _IconButton: React.FC<any> = React.forwardRef(
({ href, ...props }, ref) => {
if (href && !isExternalURL(href)) {
return (
<MacawIconButton {...props} to={href} component={Link} ref={ref} />
);
}
return <MacawIconButton href={href} {...props} ref={ref} />;
}
);
export const IconButton = _IconButton as <
T extends React.ElementType = "button"
>(
props: IconButtonProps<T>
) => ReturnType<typeof _IconButton>;

View file

@ -0,0 +1 @@
export * from "./IconButton";

View file

@ -14,11 +14,12 @@ import { makeStyles } from "@saleor/macaw-ui";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
export interface LanguageSwitchProps { export interface LanguageSwitchProps {
currentLanguage: LanguageCodeEnum; currentLanguage: LanguageCodeEnum;
languages: LanguageFragment[]; languages: LanguageFragment[];
onLanguageChange: (lang: LanguageCodeEnum) => void; getLanguageUrl: (lang: LanguageCodeEnum) => string;
} }
const useStyles = makeStyles( const useStyles = makeStyles(
@ -54,8 +55,9 @@ const useStyles = makeStyles(
}), }),
{ name: "LanguageSwitch" } { name: "LanguageSwitch" }
); );
const LanguageSwitch: React.FC<LanguageSwitchProps> = props => { const LanguageSwitch: React.FC<LanguageSwitchProps> = props => {
const { currentLanguage, languages, onLanguageChange } = props; const { currentLanguage, languages, getLanguageUrl } = props;
const classes = useStyles(props); const classes = useStyles(props);
const [isExpanded, setExpandedState] = React.useState(false); const [isExpanded, setExpandedState] = React.useState(false);
@ -101,18 +103,19 @@ const LanguageSwitch: React.FC<LanguageSwitchProps> = props => {
className={classes.menuItem} className={classes.menuItem}
onClick={() => { onClick={() => {
setExpandedState(false); setExpandedState(false);
onLanguageChange(lang.code);
}} }}
> >
<FormattedMessage <Link to={getLanguageUrl(lang.code)}>
id="62T585" <FormattedMessage
defaultMessage="{languageName} - {languageCode}" id="62T585"
description="button" defaultMessage="{languageName} - {languageCode}"
values={{ description="button"
languageCode: lang.code, values={{
languageName: lang.language languageCode: lang.code,
}} languageName: lang.language
/> }}
/>
</Link>
</MenuItem> </MenuItem>
))} ))}
</Menu> </Menu>

View file

@ -1,6 +1,7 @@
import { Typography } from "@material-ui/core"; import { Typography } from "@material-ui/core";
import { TypographyProps } from "@material-ui/core/Typography"; import { TypographyProps } from "@material-ui/core/Typography";
import { makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import { isExternalURL } from "@saleor/utils/urls";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { Link as RouterLink } from "react-router-dom"; import { Link as RouterLink } from "react-router-dom";
@ -31,8 +32,6 @@ const useStyles = makeStyles(
{ name: "Link" } { name: "Link" }
); );
const isExternalURL = url => /^https?:\/\//.test(url);
interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> { interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
href?: string; href?: string;
color?: "primary" | "secondary"; color?: "primary" | "secondary";

View file

@ -1,4 +1,5 @@
import { CircularProgress } from "@material-ui/core"; import { CircularProgress } from "@material-ui/core";
import { IconButton } from "@saleor/components/IconButton";
import { DeleteIcon, EditIcon, makeStyles } from "@saleor/macaw-ui"; import { DeleteIcon, EditIcon, makeStyles } from "@saleor/macaw-ui";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
@ -67,7 +68,7 @@ const useStyles = makeStyles(
{ name: "MediaTile" } { name: "MediaTile" }
); );
interface MediaTileProps { interface MediaTileBaseProps {
media: { media: {
alt: string; alt: string;
url: string; url: string;
@ -79,8 +80,20 @@ interface MediaTileProps {
onEdit?: (event: React.ChangeEvent<any>) => void; onEdit?: (event: React.ChangeEvent<any>) => void;
} }
export type MediaTileProps = MediaTileBaseProps &
(
| {
onEdit?: React.MouseEventHandler<HTMLButtonElement>;
editHref?: never;
}
| {
onEdit?: never;
editHref?: string;
}
);
const MediaTile: React.FC<MediaTileProps> = props => { const MediaTile: React.FC<MediaTileProps> = props => {
const { loading, onDelete, onEdit, media } = props; const { loading, onDelete, onEdit, editHref, media } = props;
const classes = useStyles(props); const classes = useStyles(props);
const parsedMediaOembedData = media?.oembedData const parsedMediaOembedData = media?.oembedData
? JSON.parse(media.oembedData) ? JSON.parse(media.oembedData)
@ -98,15 +111,26 @@ const MediaTile: React.FC<MediaTileProps> = props => {
<CircularProgress size={32} /> <CircularProgress size={32} />
) : ( ) : (
<div className={classes.mediaOverlayToolbar}> <div className={classes.mediaOverlayToolbar}>
{onEdit && ( {(onEdit || editHref) && (
<button className={classes.controlButton} onClick={onEdit}> <IconButton
href={editHref}
hoverOutline={false}
variant="secondary"
className={classes.controlButton}
onClick={onEdit}
>
<EditIcon /> <EditIcon />
</button> </IconButton>
)} )}
{onDelete && ( {onDelete && (
<button className={classes.controlButton} onClick={onDelete}> <IconButton
variant="secondary"
hoverOutline={false}
className={classes.controlButton}
onClick={onDelete}
>
<DeleteIcon /> <DeleteIcon />
</button> </IconButton>
)} )}
</div> </div>
)} )}

View file

@ -10,9 +10,10 @@ import {
TextField, TextField,
Typography Typography
} from "@material-ui/core"; } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import { MetadataInput } from "@saleor/graphql"; import { MetadataInput } from "@saleor/graphql";
import { FormChange } from "@saleor/hooks/useForm"; import { FormChange } from "@saleor/hooks/useForm";
import { Button, DeleteIcon, ExpandIcon, IconButton } from "@saleor/macaw-ui"; import { DeleteIcon, ExpandIcon, IconButton } from "@saleor/macaw-ui";
import classNames from "classnames"; import classNames from "classnames";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -1,6 +1,7 @@
import notFoundImage from "@assets/images/not-found-404.svg"; import notFoundImage from "@assets/images/not-found-404.svg";
import { Typography } from "@material-ui/core"; import { Typography } from "@material-ui/core";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { Button } from "@saleor/components/Button";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import SVG from "react-inlinesvg"; import SVG from "react-inlinesvg";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
@ -48,12 +49,18 @@ const useStyles = makeStyles(
{ name: "NotFoundPage" } { name: "NotFoundPage" }
); );
interface NotFoundPageProps { type NotFoundPageProps =
onBack: () => void; | {
} onBack: () => void;
backHref?: never;
}
| {
onBack?: never;
backHref: string;
};
const NotFoundPage: React.FC<NotFoundPageProps> = props => { const NotFoundPage: React.FC<NotFoundPageProps> = props => {
const { onBack } = props; const { onBack, backHref } = props;
const classes = useStyles(props); const classes = useStyles(props);
@ -83,6 +90,7 @@ const NotFoundPage: React.FC<NotFoundPageProps> = props => {
className={classes.button} className={classes.button}
variant="primary" variant="primary"
onClick={onBack} onClick={onBack}
href={backHref}
> >
<FormattedMessage <FormattedMessage
id="95oJ5d" id="95oJ5d"

View file

@ -1,4 +1,5 @@
import { Button, makeStyles } from "@saleor/macaw-ui"; import { Button } from "@saleor/components/Button";
import { makeStyles } from "@saleor/macaw-ui";
import { SearchPageProps, TabPageProps } from "@saleor/types"; import { SearchPageProps, TabPageProps } from "@saleor/types";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -1,10 +1,11 @@
import { Card, CardContent, TextField, Typography } from "@material-ui/core"; import { Card, CardContent, TextField, Typography } from "@material-ui/core";
import { Button } from "@saleor/components/Button";
import { import {
CollectionErrorFragment, CollectionErrorFragment,
PageErrorFragment, PageErrorFragment,
ProductErrorFragment ProductErrorFragment
} from "@saleor/graphql"; } from "@saleor/graphql";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { makeStyles } from "@saleor/macaw-ui";
import { getFieldError, getProductErrorMessage } from "@saleor/utils/errors"; import { getFieldError, getProductErrorMessage } from "@saleor/utils/errors";
import getPageErrorMessage from "@saleor/utils/errors/page"; import getPageErrorMessage from "@saleor/utils/errors/page";
import classNames from "classnames"; import classNames from "classnames";

View file

@ -1,17 +1,23 @@
import { TableRow } from "@material-ui/core"; import { TableRowProps } from "@material-ui/core";
import { TableRowProps } from "@material-ui/core/TableRow";
import React from "react"; import React from "react";
import { SortableElement } from "react-sortable-hoc"; import { SortableElement, SortableElementProps } from "react-sortable-hoc";
import TableRowLink, { TableRowLinkProps } from "../TableRowLink";
import SortableHandle from "./SortableHandle"; import SortableHandle from "./SortableHandle";
const SortableTableRow = SortableElement<TableRowProps>( type SortableTableRowTypesUnion = "link" | "row";
({ children, ...props }) => (
<TableRow {...props}> type SortableTableRowProps<
<SortableHandle /> T extends SortableTableRowTypesUnion
{children} > = T extends "link" ? TableRowLinkProps : TableRowProps;
</TableRow>
) const SortableTableRow = (SortableElement<any>(({ children, ...props }) => (
); <TableRowLink {...props}>
<SortableHandle />
{children}
</TableRowLink>
)) as unknown) as <T extends SortableTableRowTypesUnion = "link">(
props: SortableElementProps & SortableTableRowProps<T>
) => JSX.Element;
export default SortableTableRow; export default SortableTableRow;

View file

@ -0,0 +1,50 @@
import { TableRow, TableRowTypeMap } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import clsx from "classnames";
import React from "react";
import Link from "../Link";
type MaterialTableRowPropsType = TableRowTypeMap["props"];
export interface TableRowLinkProps
extends Omit<MaterialTableRowPropsType, "onClick"> {
children: React.ReactNode;
href?: string;
className?: string;
linkClassName?: string;
}
const useStyles = makeStyles(
{
link: {
all: "inherit",
display: "contents"
}
},
{ name: "TableRowLink" }
);
const TableRowLink = ({
href,
children,
linkClassName,
...props
}: TableRowLinkProps) => {
const classes = useStyles();
if (!href) {
return <TableRow {...props}>{children}</TableRow>;
}
return (
<TableRow {...props}>
<Link className={clsx(classes.link, linkClassName)} href={href}>
{children}
</Link>
</TableRow>
);
};
TableRowLink.displayName = "TableRowLink";
export default TableRowLink;

View file

@ -0,0 +1,2 @@
export { default } from "./TableRowLink";
export * from "./TableRowLink";

View file

@ -1,7 +1,8 @@
import { Avatar, CardContent, TextField } from "@material-ui/core"; import { Avatar, CardContent, TextField } from "@material-ui/core";
import deepPurple from "@material-ui/core/colors/deepPurple"; import deepPurple from "@material-ui/core/colors/deepPurple";
import PersonIcon from "@material-ui/icons/Person"; import PersonIcon from "@material-ui/icons/Person";
import { Button, makeStyles } from "@saleor/macaw-ui"; import { Button } from "@saleor/components/Button";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";

View file

@ -2,8 +2,10 @@ import { FormControlLabel, Switch } from "@material-ui/core";
import { UserFragment } from "@saleor/graphql"; import { UserFragment } from "@saleor/graphql";
import { makeStyles, UserChipMenu, UserChipMenuItem } from "@saleor/macaw-ui"; import { makeStyles, UserChipMenu, UserChipMenuItem } from "@saleor/macaw-ui";
import { getUserInitials, getUserName } from "@saleor/misc"; import { getUserInitials, getUserName } from "@saleor/misc";
import { staffMemberDetailsUrl } from "@saleor/staff/urls";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { FormattedMessage, useIntl } from "react-intl";
import { Link } from "react-router-dom";
const useStyles = makeStyles( const useStyles = makeStyles(
() => ({ () => ({
@ -22,7 +24,6 @@ export interface UserChipProps {
isDarkThemeEnabled: boolean; isDarkThemeEnabled: boolean;
user: UserFragment; user: UserFragment;
onLogout: () => void; onLogout: () => void;
onProfileClick: () => void;
onThemeToggle: () => void; onThemeToggle: () => void;
} }
@ -30,7 +31,6 @@ const UserChip: React.FC<UserChipProps> = ({
isDarkThemeEnabled, isDarkThemeEnabled,
user, user,
onLogout, onLogout,
onProfileClick,
onThemeToggle onThemeToggle
}) => { }) => {
const classes = useStyles({}); const classes = useStyles({});
@ -42,15 +42,14 @@ const UserChip: React.FC<UserChipProps> = ({
name={getUserName(user, true)} name={getUserName(user, true)}
avatar={user?.avatar?.url} avatar={user?.avatar?.url}
> >
<UserChipMenuItem <UserChipMenuItem data-test-id="account-settings-button">
onClick={onProfileClick} <Link to={staffMemberDetailsUrl(user?.id)}>
data-test-id="account-settings-button" <FormattedMessage
> id="X8+Lpa"
<FormattedMessage defaultMessage="Account Settings"
id="X8+Lpa" description="button"
defaultMessage="Account Settings" />
description="button" </Link>
/>
</UserChipMenuItem> </UserChipMenuItem>
<UserChipMenuItem onClick={onLogout} data-test-id="log-out-button"> <UserChipMenuItem onClick={onLogout} data-test-id="log-out-button">
<FormattedMessage <FormattedMessage

Some files were not shown because too many files have changed in this diff Show more