diff --git a/src/services/components/ServiceDefaultToken/ServiceDefaultToken.tsx b/src/services/components/ServiceDefaultToken/ServiceDefaultToken.tsx new file mode 100644 index 000000000..769802621 --- /dev/null +++ b/src/services/components/ServiceDefaultToken/ServiceDefaultToken.tsx @@ -0,0 +1,98 @@ +import Button from "@material-ui/core/Button"; +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; +import IconButton from "@material-ui/core/IconButton"; +import Paper from "@material-ui/core/Paper"; +import { Theme } from "@material-ui/core/styles"; +import { fade } from "@material-ui/core/styles/colorManipulator"; +import Typography from "@material-ui/core/Typography"; +import CloseIcon from "@material-ui/icons/Close"; +import { makeStyles } from "@material-ui/styles"; +import React from "react"; +import { FormattedMessage } from "react-intl"; + +export interface ServiceDefaultTokenProps { + token: string; + onTokenClose: () => void; +} + +const useStyles = makeStyles( + (theme: Theme) => ({ + cancel: { + marginRight: theme.spacing.unit + }, + closeContainer: { + display: "flex", + justifyContent: "flex-end", + position: "relative", + right: -theme.spacing.unit, + top: -theme.spacing.unit + }, + copy: { + marginTop: theme.spacing.unit, + position: "relative", + right: theme.spacing.unit + }, + paper: { + background: fade(theme.palette.primary.main, 0.05), + padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px` + }, + root: { + boxShadow: "0px 5px 10px rgba(0, 0, 0, 0.05)" + }, + text: { + display: "grid", + gridColumnGap: theme.spacing.unit * 3 + "px", + gridTemplateColumns: "1fr 60px", + marginBottom: theme.spacing.unit * 3 + } + }), + { + name: "ServiceTokenCreateDialog" + } +); + +function handleCopy(token: string) { + navigator.clipboard.writeText(token); +} + +const ServiceDefaultToken: React.FC = props => { + const { token, onTokenClose } = props; + const classes = useStyles(props); + + return ( + + +
+ + + +
+ + + +
+
+ + + + + {token} + + +
+
+ ); +}; + +ServiceDefaultToken.displayName = "ServiceDefaultToken"; +export default ServiceDefaultToken; diff --git a/src/services/components/ServiceDefaultToken/index.ts b/src/services/components/ServiceDefaultToken/index.ts new file mode 100644 index 000000000..554fd2e80 --- /dev/null +++ b/src/services/components/ServiceDefaultToken/index.ts @@ -0,0 +1,2 @@ +export { default } from "./ServiceDefaultToken"; +export * from "./ServiceDefaultToken"; diff --git a/src/services/components/ServiceDetailsPage/ServiceDetailsPage.stories.tsx b/src/services/components/ServiceDetailsPage/ServiceDetailsPage.stories.tsx index 19d537f47..3f9745ba7 100644 --- a/src/services/components/ServiceDetailsPage/ServiceDetailsPage.stories.tsx +++ b/src/services/components/ServiceDetailsPage/ServiceDetailsPage.stories.tsx @@ -15,11 +15,13 @@ const props: ServiceDetailsPageProps = { onBack: () => undefined, onDelete: () => undefined, onSubmit: () => undefined, + onTokenClose: () => undefined, onTokenCreate: () => undefined, onTokenDelete: () => undefined, permissions, saveButtonBarState: "default", - service + service, + token: null }; storiesOf("Views / Services / Service details", module) .addDecorator(Decorator) @@ -32,4 +34,7 @@ storiesOf("Views / Services / Service details", module) {...props} errors={["name"].map(field => formError(field))} /> + )) + .add("default token", () => ( + )); diff --git a/src/services/components/ServiceDetailsPage/ServiceDetailsPage.tsx b/src/services/components/ServiceDetailsPage/ServiceDetailsPage.tsx index 9c6bcf9e9..05bc918b7 100644 --- a/src/services/components/ServiceDetailsPage/ServiceDetailsPage.tsx +++ b/src/services/components/ServiceDetailsPage/ServiceDetailsPage.tsx @@ -17,6 +17,7 @@ import { maybe } from "@saleor/misc"; import { ServiceDetails_serviceAccount } from "@saleor/services/types/ServiceDetails"; import { UserError } from "@saleor/types"; import { PermissionEnum } from "@saleor/types/globalTypes"; +import ServiceDefaultToken from "../ServiceDefaultToken"; import ServiceInfo from "../ServiceInfo"; import ServiceTokens from "../ServiceTokens"; @@ -32,9 +33,11 @@ export interface ServiceDetailsPageProps { permissions: ShopInfo_shop_permissions[]; saveButtonBarState: ConfirmButtonTransitionState; service: ServiceDetails_serviceAccount; + token: string; onBack: () => void; onTokenDelete: (id: string) => void; onDelete: () => void; + onTokenClose: () => void; onTokenCreate: () => void; onSubmit: (data: ServiceDetailsPageFormData) => void; } @@ -46,8 +49,10 @@ const ServiceDetailsPage: React.FC = props => { permissions, saveButtonBarState, service, + token, onBack, onDelete, + onTokenClose, onTokenCreate, onTokenDelete, onSubmit @@ -84,6 +89,15 @@ const ServiceDetailsPage: React.FC = props => { service.name)} />
+ {token && ( + <> + + + + )} = props => { @@ -71,88 +76,84 @@ const ServiceTokenCreateDialog: React.FC< return (
onCreate(data.name)}> - {({ change, data, submit }) => { - const handleCopy = () => navigator.clipboard.writeText(token); - - return ( - <> - - - - - {step === "form" ? ( - <> - - + {({ change, data, submit }) => ( + <> + + + + + {step === "form" ? ( + <> + + + + + + + ) : ( + <> + + + + + + + - - - - ) : ( - <> - - - - - - - - - {token} - - {" "} - - )} - - - {step === "form" ? ( - <> + {token} - handleCopy(token)} > - - - ) : ( - + + + )} + + + {step === "form" ? ( + <> + - )} - - - ); - }} + + + + + ) : ( + + )} + + + )}
); diff --git a/src/services/index.tsx b/src/services/index.tsx index aa9693fec..630aa5e0e 100644 --- a/src/services/index.tsx +++ b/src/services/index.tsx @@ -23,8 +23,14 @@ const ServiceList: React.FC = ({ location }) => { return ; }; -const ServiceDetails: React.FC> = ({ - match +interface ServiceDetailsProps extends RouteComponentProps<{ id: string }> { + token: string; + onTokenClose: () => void; +} +const ServiceDetails: React.FC = ({ + match, + token, + onTokenClose }) => { const qs = parseQs(location.search.substr(1)); const params: ServiceUrlQueryParams = qs; @@ -33,20 +39,36 @@ const ServiceDetails: React.FC> = ({ ); }; const ServiceSection = () => { const intl = useIntl(); + const [token, setToken] = React.useState(null); return ( <> - - + } + /> + ( + setToken(null)} + /> + )} + /> ); diff --git a/src/services/mutations.ts b/src/services/mutations.ts index c13fefbef..92096ddad 100644 --- a/src/services/mutations.ts +++ b/src/services/mutations.ts @@ -22,6 +22,7 @@ const serviceCreateMutation = gql` field message } + authToken serviceAccount { ...ServiceFragment } diff --git a/src/services/types/ServiceCreate.ts b/src/services/types/ServiceCreate.ts index 3f5cde471..d64cbcfec 100644 --- a/src/services/types/ServiceCreate.ts +++ b/src/services/types/ServiceCreate.ts @@ -24,6 +24,7 @@ export interface ServiceCreate_serviceAccountCreate_serviceAccount { export interface ServiceCreate_serviceAccountCreate { __typename: "ServiceAccountCreate"; errors: ServiceCreate_serviceAccountCreate_errors[] | null; + authToken: string | null; serviceAccount: ServiceCreate_serviceAccountCreate_serviceAccount | null; } diff --git a/src/services/views/ServiceCreate/ServiceCreate.tsx b/src/services/views/ServiceCreate/ServiceCreate.tsx index 7c81a33a4..f4a8d631b 100644 --- a/src/services/views/ServiceCreate/ServiceCreate.tsx +++ b/src/services/views/ServiceCreate/ServiceCreate.tsx @@ -14,7 +14,10 @@ import ServiceCreatePage, { } from "../../components/ServiceCreatePage"; import { serviceListUrl, serviceUrl } from "../../urls"; -export const ServiceCreate: React.StatelessComponent = () => { +interface ServiceCreateProps { + setToken: (token: string) => void; +} +export const ServiceCreate: React.FC = ({ setToken }) => { const navigate = useNavigator(); const notify = useNotifier(); const intl = useIntl(); @@ -26,6 +29,7 @@ export const ServiceCreate: React.StatelessComponent = () => { text: intl.formatMessage(commonMessages.savedChanges) }); navigate(serviceUrl(data.serviceAccountCreate.serviceAccount.id)); + setToken(data.serviceAccountCreate.authToken); } }; diff --git a/src/services/views/ServiceDetails/ServiceDetails.tsx b/src/services/views/ServiceDetails/ServiceDetails.tsx index e6dc1fa8f..b7414c1d3 100644 --- a/src/services/views/ServiceDetails/ServiceDetails.tsx +++ b/src/services/views/ServiceDetails/ServiceDetails.tsx @@ -34,17 +34,23 @@ import { interface OrderListProps { id: string; params: ServiceUrlQueryParams; + token: string; + onTokenClose: () => void; } export const ServiceDetails: React.StatelessComponent = ({ id, - params + params, + token, + onTokenClose }) => { const navigate = useNavigator(); const notify = useNotifier(); const intl = useIntl(); const shop = useShop(); + React.useEffect(() => onTokenClose, []); + const closeModal = () => navigate( serviceUrl(id, { @@ -203,9 +209,11 @@ export const ServiceDetails: React.StatelessComponent = ({ openModal("remove")} onSubmit={handleSubmit} + onTokenClose={onTokenClose} onTokenCreate={() => openModal("create-token")} onTokenDelete={id => openModal("remove-token", id) diff --git a/src/theme.ts b/src/theme.ts index 6e9698d6e..c8d42b7a8 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -1,3 +1,4 @@ +import Card from "@material-ui/core/Card"; import { createMuiTheme, Theme } from "@material-ui/core/styles"; import { darken, fade } from "@material-ui/core/styles/colorManipulator"; import TextField from "@material-ui/core/TextField"; @@ -84,7 +85,6 @@ export default (colors: IThemeColors): Theme => borderRadius: 8, borderStyle: "solid", borderWidth: 1, - boxShadow: "none", overflow: "visible" } }, @@ -540,3 +540,8 @@ TextField.defaultProps = { ...TextField.defaultProps, variant: "outlined" }; + +Card.defaultProps = { + ...Card.defaultProps, + elevation: 0 +}; diff --git a/src/types/globalTypes.ts b/src/types/globalTypes.ts index b18eee0ac..1e8cfaf3a 100644 --- a/src/types/globalTypes.ts +++ b/src/types/globalTypes.ts @@ -321,6 +321,8 @@ export interface AttributeFilterInput { availableInGrid?: boolean | null; search?: string | null; ids?: (string | null)[] | null; + inCollection?: string | null; + inCategory?: string | null; } export interface AttributeInput {