Add inline service remove
This commit is contained in:
parent
8990940fc6
commit
9535563939
10 changed files with 296 additions and 45 deletions
|
@ -0,0 +1,19 @@
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import Decorator from "@saleor/storybook/Decorator";
|
||||||
|
import ServiceDeleteDialog, {
|
||||||
|
ServiceDeleteDialogProps
|
||||||
|
} from "./ServiceDeleteDialog";
|
||||||
|
|
||||||
|
const props: ServiceDeleteDialogProps = {
|
||||||
|
confirmButtonState: "default",
|
||||||
|
name: "Magento Importer",
|
||||||
|
onClose: () => undefined,
|
||||||
|
onConfirm: () => undefined,
|
||||||
|
open: true
|
||||||
|
};
|
||||||
|
|
||||||
|
storiesOf("Views / Services / Delete service", module)
|
||||||
|
.addDecorator(Decorator)
|
||||||
|
.add("default", () => <ServiceDeleteDialog {...props} />);
|
|
@ -0,0 +1,50 @@
|
||||||
|
import DialogContentText from "@material-ui/core/DialogContentText";
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import ActionDialog from "@saleor/components/ActionDialog";
|
||||||
|
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
|
||||||
|
|
||||||
|
export interface ServiceDeleteDialogProps {
|
||||||
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
|
open: boolean;
|
||||||
|
name: string;
|
||||||
|
onClose: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ServiceDeleteDialog: React.FC<ServiceDeleteDialogProps> = ({
|
||||||
|
confirmButtonState,
|
||||||
|
open,
|
||||||
|
name,
|
||||||
|
onClose,
|
||||||
|
onConfirm
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionDialog
|
||||||
|
confirmButtonState={confirmButtonState}
|
||||||
|
open={open}
|
||||||
|
onClose={onClose}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Delete Service Account",
|
||||||
|
description: "dialog header"
|
||||||
|
})}
|
||||||
|
variant="delete"
|
||||||
|
>
|
||||||
|
<DialogContentText>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Are you sure you want to delete {name}?"
|
||||||
|
description="delete service account"
|
||||||
|
values={{
|
||||||
|
name: <strong>{name}</strong>
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</DialogContentText>
|
||||||
|
</ActionDialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
ServiceDeleteDialog.displayName = "ServiceDeleteDialog";
|
||||||
|
export default ServiceDeleteDialog;
|
2
src/services/components/ServiceDeleteDialog/index.ts
Normal file
2
src/services/components/ServiceDeleteDialog/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { default } from "./ServiceDeleteDialog";
|
||||||
|
export * from "./ServiceDeleteDialog";
|
|
@ -17,10 +17,9 @@ import EditIcon from "@material-ui/icons/Edit";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
import Checkbox from "@saleor/components/Checkbox";
|
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import TablePagination from "@saleor/components/TablePagination";
|
import TablePagination from "@saleor/components/TablePagination";
|
||||||
import { maybe, renderCollection } from "@saleor/misc";
|
import { maybe, renderCollection, stopPropagation } from "@saleor/misc";
|
||||||
import { ListProps } from "@saleor/types";
|
import { ListProps } from "@saleor/types";
|
||||||
import { ServiceList_serviceAccounts_edges_node } from "../../types/ServiceList";
|
import { ServiceList_serviceAccounts_edges_node } from "../../types/ServiceList";
|
||||||
|
|
||||||
|
@ -76,10 +75,15 @@ const ServiceList = withStyles(styles, {
|
||||||
}: ServiceListProps & WithStyles<typeof styles>) => (
|
}: ServiceListProps & WithStyles<typeof styles>) => (
|
||||||
<Table className={classes.table}>
|
<Table className={classes.table}>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
<TableCell className={classes.colName}>
|
<TableCell className={classes.colName}>
|
||||||
<FormattedMessage defaultMessage="Name" description="service name" />
|
<FormattedMessage
|
||||||
|
defaultMessage="Name"
|
||||||
|
description="service name"
|
||||||
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell />
|
<TableCell />
|
||||||
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableFooter>
|
<TableFooter>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
@ -135,7 +139,11 @@ const ServiceList = withStyles(styles, {
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
<IconButton
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={service ? () => onRemove(service.id) : undefined}
|
onClick={
|
||||||
|
service
|
||||||
|
? stopPropagation(() => onRemove(service.id))
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<DeleteIcon />
|
<DeleteIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
import { TypedMutation } from "../mutations";
|
import { TypedMutation } from "../mutations";
|
||||||
import { serviceFragment } from "./queries";
|
import { serviceDetailsFragment, serviceFragment } from "./queries";
|
||||||
import { ServiceCreate, ServiceCreateVariables } from "./types/ServiceCreate";
|
import { ServiceCreate, ServiceCreateVariables } from "./types/ServiceCreate";
|
||||||
|
import { ServiceDelete, ServiceDeleteVariables } from "./types/ServiceDelete";
|
||||||
|
import { ServiceUpdate, ServiceUpdateVariables } from "./types/ServiceUpdate";
|
||||||
|
|
||||||
export const serviceCreateMutation = gql`
|
const serviceCreateMutation = gql`
|
||||||
${serviceFragment}
|
${serviceFragment}
|
||||||
mutation ServiceCreate($input: ServiceAccountInput!) {
|
mutation ServiceCreate($input: ServiceAccountInput!) {
|
||||||
serviceAccountCreate(input: $input) {
|
serviceAccountCreate(input: $input) {
|
||||||
|
@ -18,7 +20,43 @@ export const serviceCreateMutation = gql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ServiceCreateMutation = TypedMutation<
|
export const ServiceCreateMutation = TypedMutation<
|
||||||
ServiceCreate,
|
ServiceCreate,
|
||||||
ServiceCreateVariables
|
ServiceCreateVariables
|
||||||
>(serviceCreateMutation);
|
>(serviceCreateMutation);
|
||||||
|
|
||||||
|
const serviceDeleteMutation = gql`
|
||||||
|
mutation ServiceDelete($id: ID!) {
|
||||||
|
serviceAccountDelete(id: $id) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const ServiceDeleteMutation = TypedMutation<
|
||||||
|
ServiceDelete,
|
||||||
|
ServiceDeleteVariables
|
||||||
|
>(serviceDeleteMutation);
|
||||||
|
|
||||||
|
const serviceUpdateMutation = gql`
|
||||||
|
${serviceDetailsFragment}
|
||||||
|
mutation ServiceUpdate($id: ID!, $input: ServiceAccountInput!) {
|
||||||
|
serviceAccountUpdate(id: $id, input: $input) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
|
serviceAccount {
|
||||||
|
...ServiceDetailsFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ServiceUpdateMutation = TypedMutation<
|
||||||
|
ServiceUpdate,
|
||||||
|
ServiceUpdateVariables
|
||||||
|
>(serviceUpdateMutation);
|
||||||
|
|
|
@ -47,7 +47,7 @@ export const ServiceListQuery = TypedQuery<ServiceList, ServiceListVariables>(
|
||||||
serviceList
|
serviceList
|
||||||
);
|
);
|
||||||
|
|
||||||
const serviceDetailsFragment = gql`
|
export const serviceDetailsFragment = gql`
|
||||||
${serviceFragment}
|
${serviceFragment}
|
||||||
fragment ServiceDetailsFragment on ServiceAccount {
|
fragment ServiceDetailsFragment on ServiceAccount {
|
||||||
...ServiceFragment
|
...ServiceFragment
|
||||||
|
|
26
src/services/types/ServiceDelete.ts
Normal file
26
src/services/types/ServiceDelete.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL mutation operation: ServiceDelete
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ServiceDelete_serviceAccountDelete_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceDelete_serviceAccountDelete {
|
||||||
|
__typename: "ServiceAccountDelete";
|
||||||
|
errors: ServiceDelete_serviceAccountDelete_errors[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceDelete {
|
||||||
|
serviceAccountDelete: ServiceDelete_serviceAccountDelete | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceDeleteVariables {
|
||||||
|
id: string;
|
||||||
|
}
|
52
src/services/types/ServiceUpdate.ts
Normal file
52
src/services/types/ServiceUpdate.ts
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ServiceAccountInput, PermissionEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL mutation operation: ServiceUpdate
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ServiceUpdate_serviceAccountUpdate_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceUpdate_serviceAccountUpdate_serviceAccount_permissions {
|
||||||
|
__typename: "PermissionDisplay";
|
||||||
|
code: PermissionEnum;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceUpdate_serviceAccountUpdate_serviceAccount_tokens {
|
||||||
|
__typename: "ServiceAccountToken";
|
||||||
|
id: string;
|
||||||
|
name: string | null;
|
||||||
|
authToken: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceUpdate_serviceAccountUpdate_serviceAccount {
|
||||||
|
__typename: "ServiceAccount";
|
||||||
|
id: string;
|
||||||
|
name: string | null;
|
||||||
|
isActive: boolean | null;
|
||||||
|
permissions: (ServiceUpdate_serviceAccountUpdate_serviceAccount_permissions | null)[] | null;
|
||||||
|
tokens: (ServiceUpdate_serviceAccountUpdate_serviceAccount_tokens | null)[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceUpdate_serviceAccountUpdate {
|
||||||
|
__typename: "ServiceAccountUpdate";
|
||||||
|
errors: ServiceUpdate_serviceAccountUpdate_errors[] | null;
|
||||||
|
serviceAccount: ServiceUpdate_serviceAccountUpdate_serviceAccount | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceUpdate {
|
||||||
|
serviceAccountUpdate: ServiceUpdate_serviceAccountUpdate | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceUpdateVariables {
|
||||||
|
id: string;
|
||||||
|
input: ServiceAccountInput;
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ import urlJoin from "url-join";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActiveTab,
|
ActiveTab,
|
||||||
BulkAction,
|
|
||||||
Dialog,
|
Dialog,
|
||||||
Filters,
|
Filters,
|
||||||
Pagination,
|
Pagination,
|
||||||
|
@ -20,10 +19,10 @@ export enum ServiceListUrlFiltersEnum {
|
||||||
export type ServiceListUrlFilters = Filters<ServiceListUrlFiltersEnum>;
|
export type ServiceListUrlFilters = Filters<ServiceListUrlFiltersEnum>;
|
||||||
export type ServiceListUrlDialog = "remove" | TabActionDialog;
|
export type ServiceListUrlDialog = "remove" | TabActionDialog;
|
||||||
export type ServiceListUrlQueryParams = ActiveTab &
|
export type ServiceListUrlQueryParams = ActiveTab &
|
||||||
BulkAction &
|
|
||||||
ServiceListUrlFilters &
|
ServiceListUrlFilters &
|
||||||
Dialog<ServiceListUrlDialog> &
|
Dialog<ServiceListUrlDialog> &
|
||||||
Pagination;
|
Pagination &
|
||||||
|
SingleAction;
|
||||||
export const serviceListUrl = (params?: ServiceListUrlQueryParams) =>
|
export const serviceListUrl = (params?: ServiceListUrlQueryParams) =>
|
||||||
serviceListPath + "?" + stringifyQs(params);
|
serviceListPath + "?" + stringifyQs(params);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,10 @@ import { configurationMenuUrl } from "@saleor/configuration";
|
||||||
import useShop from "@saleor/hooks/useShop";
|
import useShop from "@saleor/hooks/useShop";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { getMutationState, maybe } from "@saleor/misc";
|
import { getMutationState, maybe } from "@saleor/misc";
|
||||||
|
import { ServiceDeleteMutation } from "@saleor/services/mutations";
|
||||||
|
import { ServiceDelete } from "@saleor/services/types/ServiceDelete";
|
||||||
import { ListViews } from "@saleor/types";
|
import { ListViews } from "@saleor/types";
|
||||||
|
import ServiceDeleteDialog from "../../components/ServiceDeleteDialog";
|
||||||
import ServiceListPage from "../../components/ServiceListPage";
|
import ServiceListPage from "../../components/ServiceListPage";
|
||||||
import { ServiceListQuery } from "../../queries";
|
import { ServiceListQuery } from "../../queries";
|
||||||
import {
|
import {
|
||||||
|
@ -50,7 +53,6 @@ export const ServiceList: React.StatelessComponent<ServiceListProps> = ({
|
||||||
ListViews.STAFF_MEMBERS_LIST
|
ListViews.STAFF_MEMBERS_LIST
|
||||||
);
|
);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const shop = useShop();
|
|
||||||
|
|
||||||
const tabs = getFilterTabs();
|
const tabs = getFilterTabs();
|
||||||
|
|
||||||
|
@ -75,17 +77,17 @@ export const ServiceList: React.StatelessComponent<ServiceListProps> = ({
|
||||||
serviceListUrl({
|
serviceListUrl({
|
||||||
...params,
|
...params,
|
||||||
action: undefined,
|
action: undefined,
|
||||||
ids: undefined
|
id: undefined
|
||||||
}),
|
}),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
const openModal = (action: ServiceListUrlDialog, ids?: string[]) =>
|
const openModal = (action: ServiceListUrlDialog, id?: string) =>
|
||||||
navigate(
|
navigate(
|
||||||
serviceListUrl({
|
serviceListUrl({
|
||||||
...params,
|
...params,
|
||||||
action,
|
action,
|
||||||
ids
|
id
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -119,7 +121,7 @@ export const ServiceList: React.StatelessComponent<ServiceListProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ServiceListQuery displayLoader variables={queryVariables}>
|
<ServiceListQuery displayLoader variables={queryVariables}>
|
||||||
{({ data, loading }) => {
|
{({ data, loading, refetch }) => {
|
||||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||||
maybe(() => data.serviceAccounts.pageInfo),
|
maybe(() => data.serviceAccounts.pageInfo),
|
||||||
paginationState,
|
paginationState,
|
||||||
|
@ -127,13 +129,39 @@ export const ServiceList: React.StatelessComponent<ServiceListProps> = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleCreate = () => navigate(serviceAddUrl);
|
const handleCreate = () => navigate(serviceAddUrl);
|
||||||
const handleRemove = () =>
|
const handleRemove = (id: string) =>
|
||||||
navigate(
|
navigate(
|
||||||
serviceListUrl({
|
serviceListUrl({
|
||||||
...params,
|
...params,
|
||||||
action: "remove"
|
action: "remove",
|
||||||
|
id
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
const onRemove = (data: ServiceDelete) => {
|
||||||
|
if (data.serviceAccountDelete.errors.length === 0) {
|
||||||
|
notify({
|
||||||
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
|
});
|
||||||
|
closeModal();
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ServiceDeleteMutation onCompleted={onRemove}>
|
||||||
|
{(deleteService, deleteServiceOpts) => {
|
||||||
|
const handleRemoveConfirm = () =>
|
||||||
|
deleteService({
|
||||||
|
variables: {
|
||||||
|
id: params.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const removeTransitionState = getMutationState(
|
||||||
|
deleteServiceOpts.called,
|
||||||
|
deleteServiceOpts.loading,
|
||||||
|
maybe(() => deleteServiceOpts.data.serviceAccountDelete.errors)
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -160,9 +188,38 @@ export const ServiceList: React.StatelessComponent<ServiceListProps> = ({
|
||||||
onRowClick={id => () => navigate(serviceUrl(id))}
|
onRowClick={id => () => navigate(serviceUrl(id))}
|
||||||
onRemove={handleRemove}
|
onRemove={handleRemove}
|
||||||
/>
|
/>
|
||||||
|
<ServiceDeleteDialog
|
||||||
|
confirmButtonState={removeTransitionState}
|
||||||
|
name={maybe(
|
||||||
|
() =>
|
||||||
|
data.serviceAccounts.edges.find(
|
||||||
|
edge => edge.node.id === params.id
|
||||||
|
).node.name,
|
||||||
|
"..."
|
||||||
|
)}
|
||||||
|
onClose={closeModal}
|
||||||
|
onConfirm={handleRemoveConfirm}
|
||||||
|
open={params.action === "remove"}
|
||||||
|
/>
|
||||||
|
<SaveFilterTabDialog
|
||||||
|
open={params.action === "save-search"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={handleTabSave}
|
||||||
|
/>
|
||||||
|
<DeleteFilterTabDialog
|
||||||
|
open={params.action === "delete-search"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
onClose={closeModal}
|
||||||
|
onSubmit={handleTabDelete}
|
||||||
|
tabName={maybe(() => tabs[currentTab - 1].name, "...")}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
</ServiceDeleteMutation>
|
||||||
|
);
|
||||||
|
}}
|
||||||
</ServiceListQuery>
|
</ServiceListQuery>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue