saleor-dashboard/src/taxes/pages/TaxClassesPage/TaxClassesPage.tsx
Michał Droń 5c1a62171d
🦄 Simple taxes (#2072)
* Tax configuration - implement channels view (#2048)

* Add channels view

* Fix channels view import

* Remove legacy stories references

* Fix link in configuration

* Update snapshots

* Remove sample checkboxes props

* Disable hover in country exceptions

* Update snapshots

* Extract country exception rows to seperate component

* Extract components to seperate files

* Remove duplicated section name

* Remove backlink

* Add translations to section names

* Extract messages

* Add ListItemLink component

* Replace navigator with link in TaxChannelsMenu

* Fix horizontal scroll in TaxChannelsMenu

* Change codegen to build from custom schema

* Build types

* Update fragments

* Add fixtures

* Change any to proper types

* Add story for tax channels page

* Replace MUI Skeleton with Saleor Skeleton

* Change clsx import to classnames

* Fix checkboxes shadows in settings card

* Update IDs in fixtures

* Fix offset in TaxChannelsMenu

* Update snapshots

* Remove any from TaxSettings

* Fix todos

* Change relative marginLeft to before pseudoelement

* Extract styles to seperate files

* Change folder structure

* Extract redirect logic to custom hook

* Update snapshots

* Fix comment

* Add early return in channels view

* Tax configuration - implement countries view (#2053)

* Add channels view

* Remove sample checkboxes props

* Disable hover in country exceptions

* Extract country exception rows to seperate component

* Extract components to seperate files

* Remove duplicated section name

* Remove backlink

* Add translations to section names

* Replace navigator with link in TaxChannelsMenu

* Fix horizontal scroll in TaxChannelsMenu

* Change any to proper types

* Add story for tax channels page

* Replace MUI Skeleton with Saleor Skeleton

* Change clsx import to classnames

* Fix checkboxes shadows in settings card

* Update IDs in fixtures

* Fix offset in TaxChannelsMenu

* Remove any from TaxSettings

* Add countries list view

* Add TaxCountryMenu component

* Add CountryList page

* Change channels menu rows height

* Change countries menu rows height

* Add TaxInput component

* Add tax classes rates to countries page

* Fix search input padding

* Add minmax to TaxInput

* Add searching through tax class rates

* Extract messages

* Add better handlers

* Add fullWidth to TaxInput

* Specify type for TaxInputs

* Remove spinboxes on firefox

* Remove custom spinboxes

* Remove maxHeight from menu rows

* Post-rebase fix

* Change setter to formchagne

* Add TaxConfiguration fragment

* Add isDefault field to taxClass

* Add fixtures

* Shape data

* Replace useEffect with useTaxUrlRedirect

* Fix country names in menu

* Add country page story

* Add early return in countries view

* Unify loading states between channels and countries pages

* Handle special chars and case insensitiveness in local search

* Replace navigate function with ListItemLink

* Move styles to seperate file

* Move styles to seperate file

* Migrate to strict null checks

* Remove unnecessary optional chaining

* Change overflow scroll to Y only

* Add useMemo on finding selected country

* Add useMemo on local search

* Translate labels in page tabs

* Change url from /taxes/classes to /taxes/tax-classes

* Remove capitalization from strings

* Extract messages

* Bump macaw to 0.6.2

* Update snapshots

* Add spinboxes explanation comment

* Handle empty state

* Add tax classes view (#2093)

* Add TaxClass fragment

* Build types

* Add tax classes to fixtures

* Add tax classes view

* wip Add tax classes page

* Add tax classes menu

* Add TaxRate fragment

* Extract logic

* Handle loading state & add story

* Extract messages

* Update snapshots

* Change schema building from schema back to introspection

* Update schema

* Update fragments

* Build types

* Update fixtures

* Reshape data

* Move styles to seperate file

* Use getById

* Add explicit undefined

* Comment out unfinished modal stories

* Update snapshots

* Taxes - add API calls in channels view (#2106)

* Build types

* Add TaxRate fragment

* Update snapshots

* Add taxConfigurationList query

* Add taxCountriesList query

* Add TaxClassesList query

* Rename TaxConfigurationsList query

* Handle empty state

* Fix types post-rebase

* Add form to TaxChannelsPage

* wip Add dialog for handling country exceptions

* wip Fix dialog url

* wip Add update exceptions handlers

* Add dialog story

* Fix type errors

* Add mutation support

* Fix types in story

* Add transition state to submit button

* Add notifier

* Extract messages

* Remove unused import

* Add backlink in savebar

* Update snapshots

* Fix link in navigation

* Update snapshots

* Remove message from tax config error fragment

* Add hook description

* Use useStateFromProps

* Remove error handling

* Improve url & path function names

* Use theme.spacing in TaxCountryDialog styles

* Remove redundant key modification

* Revert "Use useStateFromProps"

This reverts commit d3c68b04701cf935e917d7baa3ed1361ca3446d5.

* Move initial map to parent & add open dependency to countries state

* Use useModalDialogOpen

* Fix state update

* Remove scrolls & add ellipsis in side menu

* Center checkboxes

* Update snapshots

* Add fake div for list alignment

* Trigger deployment

* Close modal on submit

* Remove divider on last ListItem

* Align add country button

* Wrap grid child in div to avoid card stretching

* Update snapshots

* Trigger changes in add/delete exceptions

* Trigger change on expcetion checkboxes

* Add trailing commas

* Connect countries view to API (#2178)

* Add empty states

* Update countries view urls

* Remove unused import

* Add country modal to countries view

* Update schema

* Implement country view mutations & error fragments

* Implement tax class update mutation

* Add sidebar temporary state for new configs

* Remove unused imports

* Wrap in form

* Add savebar & fix search

* Update schema

* Add form wrapper

* Fix types

* Extract messages

* Bump macaw

* Update snapshots

* Fix comma dangles

* Update snapshots

* Notify about mutation success

* Add logic for mixing current and new rates

* Workaround for sending null rates

* Fix filling form with correct data after submitting

* Handle deleting configuration

* Fix selected banner

* Remove leftover comment

* Add handler for country configuration delete

* Trigger deployment

* Clean up useEffects causing infinite render loops

* Sort countries from api by name

* Fix card bottom padding

* Remove bottom divider & fix padding

* Remove scroll wrapper in side menu

* Update snapshots

* Remove scroll wrapper from tax classes menu

* Update snapshots

* Refresh form to initial onSubmit

* Revert "Refresh form to initial onSubmit"

This reverts commit 42414237d35086da63f4aa088c8072411429b1d8.

* Allow only 3 decimal characters in tax inputs

* Update snapshots

* Update schema

* Update types

* Change logic from default tax class to null class

* Fix sorting

* Send empty country rates as nulls in mutation

* Extract messages

* Update lockfile

* Update schema

* Drop default tax classes

* Update snapshots

* Post-rebase fixes

* Connect tax classes view to API (#2334)

* Add mutations

* Handle empty state

* Wrap page in form

* Update stories

* Build types

* Handle tax class delete

* Handle update tax class

* Update stories

* Handle tax class change name

* Add mutation state to savebar

* Handle creating new tax classes

* Extract messages

* Specify type

* Update stories

* Sort rates

* Fix skeleton rendering

* Remove placeholders

* Fix skeleton rendering on country list

* Update snapshots

* Change initial pagination to 100

* Disallow creating multiple new tax classes

* Disallow creating multiple country configurations

* Fix messages

* Autofocus on new tax class name

* Add country name to header

* Temporarily comment out broken code in tax channels

* Update snapshots

* Update snapshots post-rebase

* Add tax strategies & assigning tax classes (#2369)

* Update fragments

* Add optional merging in useForm

* Handle tax strategies

* Update snapshots

* Update fixtures

* Extract messages

* Remove unused shop query fields

* Fix breaking bug when fetchMore is used in non-searchable SingleAutocompleteSelectFields

* Migrate product types to tax classes

* Add tax classes to shipping methods

* Use encapsulated logic in product types

* Fix product type stories

* Fix shipping fixtures

* Fix product type type mismatch

* Fix shipping stories

* Fix product type fixtures

* Fix mismatching types

* Extract messages

* Update snapshots

* Update snapshots

* Fix comment

* Drop deprecated graphql fields

* Replace tax types with tax classes in product create view

* Replace tax types with tax classes in product update view

* Fix tests, stories, fixtures

* Extract messages

* Update snapshots

* Move status messages to commonStatusMessages

* Handle empty array case in tax class change handler

* Reuse messages

* Simple taxes bugfixes (#2395)

* Fix tax channels menu - dense layout

* Change view names to fit convention

* Fix per country exceptions in tax channels view

* Fix skeleton rendering on tax countries card title

* Filter out existing countries from modal

* Update snapshots

* Fix deleting country configuration

* Disallow negative values in tax inputs

* Handle empty tax classes view

* Allow empty options in shipping & product types views tax class assignment field

* Modify undefined rates in tax classes view

* Update macaw-ui

* Fix UI on channels view

* Fix UI on countries view

* Fix UI on countries view

* Align tax class rate label to the right

* Updaste snapshots

* Extract messages

* Fix adding rates on new tax class

* Fix key errors

* Update schema

* Build types

* Allow empty rates in taxClassUpdate mutation

* Extract tax channels change country function as a handler

* Deprecate useStateFromProps

* Change useStateFromProps to useStateUpdate

* Fix dividers

* Delete delete icon on new tax classes

* Update snapshots

* Update lockfile

* Update macaw to 0.6.6

* Update snapshots

* Specify type of input in country change handler

* Extract autofocus logic to custom hook

* Replace alternative with switch statement

* Extract country exclusion logic from JSX

* Update lockfile

* Update lockfile

* Trigger deployment

* Fix invisible select markers

* Fix linter issue

* Fix crashing product details page

* Fix e2e error

* Update snapshots

* Allow view taxes with any staff permissions (#2510)

* Update after rebase

Co-authored-by: Dawid <tarasiukdawid@gmail.com>
2022-11-17 13:48:50 +01:00

257 lines
9.4 KiB
TypeScript

import {
Card,
CardContent,
Divider,
InputAdornment,
TextField,
} from "@material-ui/core";
import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
import CardTitle from "@saleor/components/CardTitle";
import Container from "@saleor/components/Container";
import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader";
import Savebar from "@saleor/components/Savebar";
import Skeleton from "@saleor/components/Skeleton";
import { configurationMenuUrl } from "@saleor/configuration";
import {
TaxClassCreateInput,
TaxClassFragment,
TaxClassUpdateInput,
} from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm";
import useNavigator from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl";
import {
ConfirmButtonTransitionState,
List,
ListHeader,
ListItem,
ListItemCell,
PageTab,
PageTabs,
SearchIcon,
} from "@saleor/macaw-ui";
import { parseQuery } from "@saleor/orders/components/OrderCustomerAddressesEditDialog/utils";
import { getById } from "@saleor/orders/components/OrderReturnPage/utils";
import { taxesMessages } from "@saleor/taxes/messages";
import { useAutofocus } from "@saleor/taxes/utils/useAutofocus";
import { isLastElement } from "@saleor/taxes/utils/utils";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import TaxInput from "../../components/TaxInput";
import TaxClassesForm from "./form";
import { useStyles } from "./styles";
import TaxClassesMenu from "./TaxClassesMenu";
interface TaxClassesPageProps {
taxClasses: TaxClassFragment[] | undefined;
selectedTaxClassId: string;
handleTabChange: (tab: string) => void;
savebarState: ConfirmButtonTransitionState;
disabled: boolean;
onCreateNewButtonClick: () => void;
onTaxClassDelete: (id: string) => SubmitPromise;
onTaxClassCreate: (input: TaxClassCreateInput) => SubmitPromise;
onTaxClassUpdate: (id: string, input: TaxClassUpdateInput) => SubmitPromise;
}
export const TaxClassesPage: React.FC<TaxClassesPageProps> = props => {
const {
taxClasses,
selectedTaxClassId,
handleTabChange,
savebarState,
disabled,
onCreateNewButtonClick,
onTaxClassDelete,
onTaxClassCreate,
onTaxClassUpdate,
} = props;
const intl = useIntl();
const navigate = useNavigator();
const classes = useStyles();
const [query, setQuery] = React.useState("");
const currentTaxClass = React.useMemo(
() => taxClasses?.find(getById(selectedTaxClassId)),
[selectedTaxClassId, taxClasses],
);
const nameInputRef = useAutofocus(currentTaxClass?.id === "new", [
currentTaxClass?.id,
]);
return (
<TaxClassesForm
taxClass={currentTaxClass}
onTaxClassCreate={onTaxClassCreate}
onTaxClassUpdate={onTaxClassUpdate}
disabled={disabled}
>
{({ data, handlers, submit, change }) => {
const filteredRates = data.updateTaxClassRates.filter(
rate => rate.label.search(new RegExp(parseQuery(query), "i")) >= 0,
);
return (
<Container>
<PageHeader title={intl.formatMessage(sectionNames.taxes)} />
<PageTabs value="tax-classes" onChange={handleTabChange}>
<PageTab
label={intl.formatMessage(taxesMessages.channelsSection)}
value="channels"
/>
<PageTab
label={intl.formatMessage(taxesMessages.countriesSection)}
value="countries"
/>
<PageTab
label={intl.formatMessage(taxesMessages.taxClassesSection)}
value="tax-classes"
/>
</PageTabs>
<VerticalSpacer spacing={2} />
<Grid variant="inverted">
<TaxClassesMenu
taxClasses={taxClasses}
selectedTaxClassId={selectedTaxClassId}
onTaxClassDelete={onTaxClassDelete}
onCreateNew={onCreateNewButtonClick}
/>
{taxClasses?.length !== 0 && (
<div>
<Card>
<CardTitle
title={intl.formatMessage(
taxesMessages.generalInformation,
)}
/>
<CardContent>
<TextField
value={data?.name}
onChange={change}
name="name"
variant="outlined"
placeholder={intl.formatMessage(
taxesMessages.taxRateName,
)}
fullWidth
inputProps={{ className: classes.namePadding }}
inputRef={nameInputRef}
/>
</CardContent>
</Card>
<VerticalSpacer spacing={3} />
<Card>
<CardTitle
title={intl.formatMessage(taxesMessages.taxClassRates)}
/>
{currentTaxClass?.countries.length === 0 ? (
<CardContent className={classes.supportText}>
<FormattedMessage
{...taxesMessages.noRatesInTaxClass}
values={{
tab: (
<b>
{intl.formatMessage(
taxesMessages.countriesSection,
)}
</b>
),
}}
/>
</CardContent>
) : (
<>
<CardContent>
<TextField
value={query}
variant="outlined"
onChange={e => setQuery(e.target.value)}
placeholder={intl.formatMessage(
taxesMessages.searchTaxClasses,
)}
fullWidth
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
inputProps={{ className: classes.searchPadding }}
/>
</CardContent>
<List gridTemplate={["5fr 2fr"]}>
<ListHeader>
<ListItem>
<ListItemCell>
<FormattedMessage
{...taxesMessages.countryNameHeader}
/>
</ListItemCell>
<ListItemCell className={classes.right}>
<FormattedMessage
{...taxesMessages.taxRateHeader}
/>
</ListItemCell>
</ListItem>
</ListHeader>
<Divider />
{filteredRates?.map(
(countryRate, countryRateIndex) => (
<React.Fragment key={countryRate.id}>
<ListItem
hover={false}
className={classes.noDivider}
>
<ListItemCell>
{countryRate.label}
</ListItemCell>
<ListItemCell>
<TaxInput
value={countryRate.value}
change={e =>
handlers.handleRateChange(
countryRate.id,
e.target.value,
)
}
/>
</ListItemCell>
</ListItem>
{!isLastElement(
filteredRates,
countryRateIndex,
) && <Divider />}
</React.Fragment>
),
) ?? (
<>
<Skeleton />
<VerticalSpacer />
</>
)}
</List>
</>
)}
</Card>
</div>
)}
</Grid>
<Savebar
state={savebarState}
disabled={disabled}
onSubmit={submit}
onCancel={() => navigate(configurationMenuUrl)}
/>
</Container>
);
}}
</TaxClassesForm>
);
};
export default TaxClassesPage;