From 4efac168d8ab45551204920fa514f7d81f4da602 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Wed, 24 Apr 2019 15:44:14 +0200 Subject: [PATCH 01/14] Add avatar hover --- package.json | 1 + .../StaffProperties/StaffProperties.tsx | 34 +++++++++++++++++-- saleor/static/images/photo-icon.svg | 9 +++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 saleor/static/images/photo-icon.svg diff --git a/package.json b/package.json index 1d4a9cfd459..e9110bb1c4a 100644 --- a/package.json +++ b/package.json @@ -199,6 +199,7 @@ "generate-component": "plop --plopfile .plop/plopfile.js", "heroku-postbuild": "npm run build-assets && npm run build-emails", "lint": "tslint 'saleor/static/dashboard-next/**/*.{ts,tsx}'", + "lint-fix": "tslint 'saleor/static/dashboard-next/**/*.{ts,tsx}' --fix", "start": "webpack -d --watch", "build-emails": "mjml --config.beautify false -l skip \"templates/templated_email/source/*.mjml\" -o templates/templated_email/compiled", "storybook": "start-storybook -p 3000 -c saleor/static/dashboard-next/storybook/", diff --git a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx index 2ab88f3d2e2..cca100caec2 100644 --- a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx @@ -6,23 +6,49 @@ import { withStyles, WithStyles } from "@material-ui/core/styles"; -import TextField from "@material-ui/core/TextField"; import * as React from "react"; +import SVG from "react-inlinesvg"; +import TextField from "@material-ui/core/TextField"; +import Typography from "@material-ui/core/Typography"; import CardTitle from "../../../components/CardTitle"; import i18n from "../../../i18n"; import { maybe } from "../../../misc"; import { StaffMemberDetails_user } from "../../types/StaffMemberDetails"; +import * as photoIcon from "../../../../images/photo-icon.svg"; + const styles = (theme: Theme) => createStyles({ avatar: { + "&:hover $avatarHover": { + opacity: 1, + }, alignItems: "center", borderRadius: "100%", display: "grid", height: 120, justifyContent: "center", - width: 120 + position: "relative", + width: 120, + }, + avatarHover: { + "& p": { + color: theme.palette.primary.main, + fontSize: 12, + fontWeight: 500, + }, + background: "#00000080", + borderRadius: "100%", + cursor: "pointer", + height: 120, + opacity: 0, + position: "absolute", + padding: `${theme.spacing.unit * 3}px 0`, + textAlign: "center", + textTransform: "uppercase", + transition: 'opacity 0.5s', + width: 120, }, avatarImage: { pointerEvents: "none", @@ -77,6 +103,10 @@ const StaffProperties = withStyles(styles, { name: "StaffProperties" })( className={classes.avatarImage} src={maybe(() => staffMember.avatar.url)} /> +
+ + {i18n.t("Change photo")} +
diff --git a/saleor/static/images/photo-icon.svg b/saleor/static/images/photo-icon.svg new file mode 100644 index 00000000000..57ee59835e8 --- /dev/null +++ b/saleor/static/images/photo-icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + From 083bf2684eac3c0c0a25871857ef7710a757762b Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Fri, 26 Apr 2019 13:06:54 +0200 Subject: [PATCH 02/14] Fix products types --- .../static/dashboard-next/categories/types/CategoryDetails.ts | 2 +- saleor/static/dashboard-next/products/types/Product.ts | 2 +- saleor/static/dashboard-next/products/types/ProductCreate.ts | 2 +- saleor/static/dashboard-next/products/types/ProductDetails.ts | 2 +- .../static/dashboard-next/products/types/ProductFragment.ts | 2 +- .../dashboard-next/products/types/ProductImageCreate.ts | 2 +- .../dashboard-next/products/types/ProductImageUpdate.ts | 2 +- saleor/static/dashboard-next/products/types/ProductList.ts | 2 +- saleor/static/dashboard-next/products/types/ProductUpdate.ts | 2 +- .../dashboard-next/products/types/SimpleProductUpdate.ts | 2 +- saleor/static/dashboard-next/types/globalTypes.ts | 4 ++++ 11 files changed, 14 insertions(+), 10 deletions(-) diff --git a/saleor/static/dashboard-next/categories/types/CategoryDetails.ts b/saleor/static/dashboard-next/categories/types/CategoryDetails.ts index dfd03d48f92..101a84c3ac0 100644 --- a/saleor/static/dashboard-next/categories/types/CategoryDetails.ts +++ b/saleor/static/dashboard-next/categories/types/CategoryDetails.ts @@ -54,7 +54,7 @@ export interface CategoryDetails_category_products_pageInfo { } export interface CategoryDetails_category_products_edges_node_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; } diff --git a/saleor/static/dashboard-next/products/types/Product.ts b/saleor/static/dashboard-next/products/types/Product.ts index 10ebd1f2ce0..9797b91e990 100644 --- a/saleor/static/dashboard-next/products/types/Product.ts +++ b/saleor/static/dashboard-next/products/types/Product.ts @@ -104,7 +104,7 @@ export interface Product_availability_priceRange { } export interface Product_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; priceRange: Product_availability_priceRange | null; } diff --git a/saleor/static/dashboard-next/products/types/ProductCreate.ts b/saleor/static/dashboard-next/products/types/ProductCreate.ts index d4443194300..a8e9bb0283b 100644 --- a/saleor/static/dashboard-next/products/types/ProductCreate.ts +++ b/saleor/static/dashboard-next/products/types/ProductCreate.ts @@ -112,7 +112,7 @@ export interface ProductCreate_productCreate_product_availability_priceRange { } export interface ProductCreate_productCreate_product_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; priceRange: ProductCreate_productCreate_product_availability_priceRange | null; } diff --git a/saleor/static/dashboard-next/products/types/ProductDetails.ts b/saleor/static/dashboard-next/products/types/ProductDetails.ts index 2a3e64f5211..1623b5985a2 100644 --- a/saleor/static/dashboard-next/products/types/ProductDetails.ts +++ b/saleor/static/dashboard-next/products/types/ProductDetails.ts @@ -104,7 +104,7 @@ export interface ProductDetails_product_availability_priceRange { } export interface ProductDetails_product_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; priceRange: ProductDetails_product_availability_priceRange | null; } diff --git a/saleor/static/dashboard-next/products/types/ProductFragment.ts b/saleor/static/dashboard-next/products/types/ProductFragment.ts index 6b1f88316bf..b831bfed3ce 100644 --- a/saleor/static/dashboard-next/products/types/ProductFragment.ts +++ b/saleor/static/dashboard-next/products/types/ProductFragment.ts @@ -12,7 +12,7 @@ export interface ProductFragment_thumbnail { } export interface ProductFragment_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; } diff --git a/saleor/static/dashboard-next/products/types/ProductImageCreate.ts b/saleor/static/dashboard-next/products/types/ProductImageCreate.ts index 90cc2fe767d..f751ed83f51 100644 --- a/saleor/static/dashboard-next/products/types/ProductImageCreate.ts +++ b/saleor/static/dashboard-next/products/types/ProductImageCreate.ts @@ -110,7 +110,7 @@ export interface ProductImageCreate_productImageCreate_product_availability_pric } export interface ProductImageCreate_productImageCreate_product_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; priceRange: ProductImageCreate_productImageCreate_product_availability_priceRange | null; } diff --git a/saleor/static/dashboard-next/products/types/ProductImageUpdate.ts b/saleor/static/dashboard-next/products/types/ProductImageUpdate.ts index b05ef90ae4f..734eaf0fdd8 100644 --- a/saleor/static/dashboard-next/products/types/ProductImageUpdate.ts +++ b/saleor/static/dashboard-next/products/types/ProductImageUpdate.ts @@ -110,7 +110,7 @@ export interface ProductImageUpdate_productImageUpdate_product_availability_pric } export interface ProductImageUpdate_productImageUpdate_product_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; priceRange: ProductImageUpdate_productImageUpdate_product_availability_priceRange | null; } diff --git a/saleor/static/dashboard-next/products/types/ProductList.ts b/saleor/static/dashboard-next/products/types/ProductList.ts index 4ccbd10f8ee..cfb7cd582a0 100644 --- a/saleor/static/dashboard-next/products/types/ProductList.ts +++ b/saleor/static/dashboard-next/products/types/ProductList.ts @@ -14,7 +14,7 @@ export interface ProductList_products_edges_node_thumbnail { } export interface ProductList_products_edges_node_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; } diff --git a/saleor/static/dashboard-next/products/types/ProductUpdate.ts b/saleor/static/dashboard-next/products/types/ProductUpdate.ts index d49b7c077a5..615a089ef4f 100644 --- a/saleor/static/dashboard-next/products/types/ProductUpdate.ts +++ b/saleor/static/dashboard-next/products/types/ProductUpdate.ts @@ -112,7 +112,7 @@ export interface ProductUpdate_productUpdate_product_availability_priceRange { } export interface ProductUpdate_productUpdate_product_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; priceRange: ProductUpdate_productUpdate_product_availability_priceRange | null; } diff --git a/saleor/static/dashboard-next/products/types/SimpleProductUpdate.ts b/saleor/static/dashboard-next/products/types/SimpleProductUpdate.ts index fd9c816e2b0..99e9d6e5f49 100644 --- a/saleor/static/dashboard-next/products/types/SimpleProductUpdate.ts +++ b/saleor/static/dashboard-next/products/types/SimpleProductUpdate.ts @@ -112,7 +112,7 @@ export interface SimpleProductUpdate_productUpdate_product_availability_priceRan } export interface SimpleProductUpdate_productUpdate_product_availability { - __typename: "ProductAvailability"; + __typename: "ProductPricingInfo"; available: boolean | null; priceRange: SimpleProductUpdate_productUpdate_product_availability_priceRange | null; } diff --git a/saleor/static/dashboard-next/types/globalTypes.ts b/saleor/static/dashboard-next/types/globalTypes.ts index 1a3ca41d9a7..7cc2d0d9b88 100644 --- a/saleor/static/dashboard-next/types/globalTypes.ts +++ b/saleor/static/dashboard-next/types/globalTypes.ts @@ -115,8 +115,12 @@ export enum OrderStatus { } export enum OrderStatusFilter { + CANCELED = "CANCELED", + FULFILLED = "FULFILLED", + PARTIALLY_FULFILLED = "PARTIALLY_FULFILLED", READY_TO_CAPTURE = "READY_TO_CAPTURE", READY_TO_FULFILL = "READY_TO_FULFILL", + UNFULFILLED = "UNFULFILLED", } export enum PaymentChargeStatusEnum { From a1fbcd07d8a7f9aee7b6a6cc180c82402b7b3f29 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Fri, 26 Apr 2019 15:09:26 +0200 Subject: [PATCH 03/14] Fix productAvability name in fixtures --- .../dashboard-next/categories/fixtures.ts | 20 +++++++++---------- .../dashboard-next/products/fixtures.ts | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/saleor/static/dashboard-next/categories/fixtures.ts b/saleor/static/dashboard-next/categories/fixtures.ts index a865375303c..9fc71ce5c32 100644 --- a/saleor/static/dashboard-next/categories/fixtures.ts +++ b/saleor/static/dashboard-next/categories/fixtures.ts @@ -92,7 +92,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyMQ==", @@ -116,7 +116,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyMg==", @@ -140,7 +140,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyMw==", @@ -164,7 +164,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyNA==", @@ -188,7 +188,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyNQ==", @@ -212,7 +212,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyNg==", @@ -236,7 +236,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyNw==", @@ -260,7 +260,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyOA==", @@ -284,7 +284,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDoyOQ==", @@ -308,7 +308,7 @@ export const category: ( node: { __typename: "Product", availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: true }, id: "UHJvZHVjdDozMA==", diff --git a/saleor/static/dashboard-next/products/fixtures.ts b/saleor/static/dashboard-next/products/fixtures.ts index 2484fda1867..016b1868a61 100644 --- a/saleor/static/dashboard-next/products/fixtures.ts +++ b/saleor/static/dashboard-next/products/fixtures.ts @@ -91,7 +91,7 @@ export const product: ( } ], availability: { - __typename: "ProductAvailability", + __typename: "ProductPricingInfo", available: false, priceRange: { __typename: "TaxedMoneyRange", From 14b6c9bccf01c1f81eee228ad0f415bb978cc8ad Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Fri, 26 Apr 2019 15:52:29 +0200 Subject: [PATCH 04/14] Add upload avatar --- .../StaffDetailsPage/StaffDetailsPage.tsx | 3 + .../StaffProperties/StaffProperties.tsx | 132 ++++++++------- .../static/dashboard-next/staff/mutations.ts | 41 +++++ .../staff/types/StaffAvatarDelete.ts | 28 ++++ .../staff/types/StaffAvatarUpdate.ts | 38 +++++ .../staff/views/StaffDetails.tsx | 151 ++++++++++-------- .../stories/staff/StaffDetailsPage.tsx | 1 + 7 files changed, 269 insertions(+), 125 deletions(-) create mode 100644 saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts create mode 100644 saleor/static/dashboard-next/staff/types/StaffAvatarUpdate.ts diff --git a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx index 822315c09db..53ab40c40c9 100644 --- a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx @@ -37,6 +37,7 @@ export interface StaffDetailsPageProps { staffMember: StaffMemberDetails_user; onBack: () => void; onDelete: () => void; + onImageUpload(file: File); onSubmit: (data: FormData) => void; } @@ -49,6 +50,7 @@ const StaffDetailsPage: React.StatelessComponent = ({ staffMember, onBack, onDelete, + onImageUpload, onSubmit }: StaffDetailsPageProps) => { const initialForm: FormData = { @@ -81,6 +83,7 @@ const StaffDetailsPage: React.StatelessComponent = ({ disabled={disabled} staffMember={staffMember} onChange={change} + onImageUpload={onImageUpload} />
{canEditStatus && ( diff --git a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx index cca100caec2..6c7864b7d78 100644 --- a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx @@ -6,10 +6,10 @@ import { withStyles, WithStyles } from "@material-ui/core/styles"; -import * as React from "react"; -import SVG from "react-inlinesvg"; import TextField from "@material-ui/core/TextField"; import Typography from "@material-ui/core/Typography"; +import * as React from "react"; +import SVG from "react-inlinesvg"; import CardTitle from "../../../components/CardTitle"; import i18n from "../../../i18n"; @@ -21,39 +21,46 @@ import * as photoIcon from "../../../../images/photo-icon.svg"; const styles = (theme: Theme) => createStyles({ avatar: { + "& svg": { + fill: "#fff" + }, "&:hover $avatarHover": { - opacity: 1, + opacity: 1 }, alignItems: "center", borderRadius: "100%", display: "grid", height: 120, justifyContent: "center", + overflow: "hidden", position: "relative", - width: 120, + width: 120 }, avatarHover: { "& p": { color: theme.palette.primary.main, fontSize: 12, - fontWeight: 500, + fontWeight: 500 }, background: "#00000080", borderRadius: "100%", cursor: "pointer", height: 120, opacity: 0, - position: "absolute", padding: `${theme.spacing.unit * 3}px 0`, + position: "absolute", textAlign: "center", textTransform: "uppercase", - transition: 'opacity 0.5s', - width: 120, + transition: "opacity 0.5s", + width: 120 }, avatarImage: { pointerEvents: "none", width: "100%" }, + fileField: { + display: "none" + }, prop: { marginBottom: theme.spacing.unit * 2 + "px" }, @@ -83,6 +90,7 @@ interface StaffPropertiesProps extends WithStyles { disabled: boolean; staffMember: StaffMemberDetails_user; onChange: (event: React.ChangeEvent) => void; + onImageUpload: (file: File) => void; } const StaffProperties = withStyles(styles, { name: "StaffProperties" })( @@ -91,59 +99,71 @@ const StaffProperties = withStyles(styles, { name: "StaffProperties" })( className, data, staffMember, - onChange - }: StaffPropertiesProps) => ( - - - -
-
-
- staffMember.avatar.url)} - /> -
- - {i18n.t("Change photo")} -
-
-
-
-
-
- { + const imgInputAnchor = React.createRef(); + const clickImgInput = () => imgInputAnchor.current.click(); + return ( + + + +
+
+
+ staffMember.avatar.url)} /> +
+ + {i18n.t("Change photo")} + onImageUpload(event.target.files[0])} + type="file" + ref={imgInputAnchor} + /> +
-
- -
-
- +
+
+
+
+ +
+
+ +
+
+ +
-
-
-
- ) + + + ); + } ); StaffProperties.displayName = "StaffProperties"; export default StaffProperties; diff --git a/saleor/static/dashboard-next/staff/mutations.ts b/saleor/static/dashboard-next/staff/mutations.ts index 4f2d352e81a..d3bd0379a2d 100644 --- a/saleor/static/dashboard-next/staff/mutations.ts +++ b/saleor/static/dashboard-next/staff/mutations.ts @@ -2,6 +2,11 @@ import gql from "graphql-tag"; import { TypedMutation } from "../mutations"; import { staffMemberDetailsFragment } from "./queries"; +import { StaffAvatarDelete } from "./types/StaffAvatarDelete"; +import { + StaffAvatarUpdate, + StaffAvatarUpdateVariables +} from "./types/StaffAvatarUpdate"; import { StaffMemberAdd, StaffMemberAddVariables @@ -67,3 +72,39 @@ export const TypedStaffMemberDeleteMutation = TypedMutation< StaffMemberDelete, StaffMemberDeleteVariables >(staffMemberDeleteMutation); + +const staffAvatarUpdateMutation = gql` + mutation StaffAvatarUpdate($image: Upload!) { + userAvatarUpdate(image: $image) { + errors { + field + message + } + user { + id + avatar { + url + } + } + } + } +`; +export const TypedStaffAvatarUpdateMutation = TypedMutation< + StaffAvatarUpdate, + StaffAvatarUpdateVariables +>(staffAvatarUpdateMutation); + +const staffAvatarDeleteMutation = gql` + mutation StaffAvatarDelete { + userAvatarDelete { + errors { + field + message + } + } + } +`; +export const TypedStaffAvatarDeleteMutation = TypedMutation< + StaffAvatarDelete, + {} +>(staffAvatarDeleteMutation); diff --git a/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts b/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts new file mode 100644 index 00000000000..d37a1a84d40 --- /dev/null +++ b/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts @@ -0,0 +1,28 @@ +/* tslint:disable */ +/* eslint-disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: StaffAvatarDelete +// ==================================================== + +export interface StaffAvatarDelete_userAvatarDelete_errors { + __typename: "Error"; + field: string | null; + message: string | null; +} + +export interface StaffAvatarDelete_userAvatarDelete_user { + __typename: "User"; + id: string; +} + +export interface StaffAvatarDelete_userAvatarDelete { + __typename: "UserAvatarDelete"; + errors: StaffAvatarDelete_userAvatarDelete_errors[] | null; + user: StaffAvatarDelete_userAvatarDelete_user | null; +} + +export interface StaffAvatarDelete { + userAvatarDelete: StaffAvatarDelete_userAvatarDelete | null; +} diff --git a/saleor/static/dashboard-next/staff/types/StaffAvatarUpdate.ts b/saleor/static/dashboard-next/staff/types/StaffAvatarUpdate.ts new file mode 100644 index 00000000000..847f5c80d09 --- /dev/null +++ b/saleor/static/dashboard-next/staff/types/StaffAvatarUpdate.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +// This file was automatically generated and should not be edited. + +// ==================================================== +// GraphQL mutation operation: StaffAvatarUpdate +// ==================================================== + +export interface StaffAvatarUpdate_userAvatarUpdate_errors { + __typename: "Error"; + field: string | null; + message: string | null; +} + +export interface StaffAvatarUpdate_userAvatarUpdate_user_avatar { + __typename: "Image"; + url: string; +} + +export interface StaffAvatarUpdate_userAvatarUpdate_user { + __typename: "User"; + id: string; + avatar: StaffAvatarUpdate_userAvatarUpdate_user_avatar | null; +} + +export interface StaffAvatarUpdate_userAvatarUpdate { + __typename: "UserAvatarUpdate"; + errors: StaffAvatarUpdate_userAvatarUpdate_errors[] | null; + user: StaffAvatarUpdate_userAvatarUpdate_user | null; +} + +export interface StaffAvatarUpdate { + userAvatarUpdate: StaffAvatarUpdate_userAvatarUpdate | null; +} + +export interface StaffAvatarUpdateVariables { + image: any; +} diff --git a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx index 66e39a8ed68..dd3f7f22df9 100644 --- a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx +++ b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx @@ -10,10 +10,12 @@ import i18n from "../../i18n"; import { getMutationState, maybe } from "../../misc"; import StaffDetailsPage from "../components/StaffDetailsPage/StaffDetailsPage"; import { + TypedStaffAvatarUpdateMutation, TypedStaffMemberDeleteMutation, TypedStaffMemberUpdateMutation } from "../mutations"; import { TypedStaffMemberDetailsQuery } from "../queries"; +import { StaffAvatarUpdate } from "../types/StaffAvatarUpdate"; import { StaffMemberDelete } from "../types/StaffMemberDelete"; import { StaffMemberUpdate } from "../types/StaffMemberUpdate"; import { @@ -64,77 +66,88 @@ export const StaffDetails: React.StatelessComponent = ({ variables={{ id }} onCompleted={handleStaffMemberDelete} > - {(deleteStaffMember, deleteResult) => { - const formTransitionState = getMutationState( - updateResult.called, - updateResult.loading, - maybe(() => updateResult.data.staffUpdate.errors) - ); - const deleteTransitionState = getMutationState( - deleteResult.called, - deleteResult.loading, - maybe(() => deleteResult.data.staffDelete.errors) - ); - const isUserSameAsViewer = maybe( - () => user.user.id === data.user.id, - true - ); + {(deleteStaffMember, deleteResult) => ( + + {updateStaffAvatar => { + const formTransitionState = getMutationState( + updateResult.called, + updateResult.loading, + maybe(() => updateResult.data.staffUpdate.errors) + ); + const deleteTransitionState = getMutationState( + deleteResult.called, + deleteResult.loading, + maybe(() => deleteResult.data.staffDelete.errors) + ); + const isUserSameAsViewer = maybe( + () => user.user.id === data.user.id, + true + ); - return ( - <> - data.user.email)} /> - navigate(staffListUrl())} - onDelete={() => - navigate( - staffMemberDetailsUrl(id, { - action: "remove" - }) - ) - } - onSubmit={variables => - updateStaffMember({ - variables: { - id, - input: { - email: variables.email, - firstName: variables.firstName, - isActive: variables.isActive, - lastName: variables.lastName, - permissions: variables.permissions - } + return ( + <> + data.user.email)} /> + navigate(staffListUrl())} + onDelete={() => + navigate( + staffMemberDetailsUrl(id, { + action: "remove" + }) + ) } - }) - } - permissions={maybe(() => data.shop.permissions)} - staffMember={maybe(() => data.user)} - saveButtonBarState={formTransitionState} - /> - navigate(staffMemberDetailsUrl(id))} - onConfirm={deleteStaffMember} - > - {{ email }} from staff members?", - { - email: maybe(() => data.user.email) - } - ) - }} - /> - - - ); - }} + onSubmit={variables => + updateStaffMember({ + variables: { + id, + input: { + email: variables.email, + firstName: variables.firstName, + isActive: variables.isActive, + lastName: variables.lastName, + permissions: variables.permissions + } + } + }) + } + onImageUpload={file => + updateStaffAvatar({ + variables: { + image: file + } + }) + } + permissions={maybe(() => data.shop.permissions)} + staffMember={maybe(() => data.user)} + saveButtonBarState={formTransitionState} + /> + navigate(staffMemberDetailsUrl(id))} + onConfirm={deleteStaffMember} + > + {{ email }} from staff members?", + { + email: maybe(() => data.user.email) + } + ) + }} + /> + + + ); + }} + + )} )} diff --git a/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx b/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx index 62bed81fd0b..47040bd3014 100644 --- a/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx +++ b/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx @@ -15,6 +15,7 @@ const props: Omit = { onBack: () => undefined, onDelete: () => undefined, onSubmit: () => undefined, + onImageUpload: () => undefined, permissions, saveButtonBarState: "default", staffMember From 38b7f1c42d78122c21d8716f6aacc71111bbb330 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Fri, 26 Apr 2019 16:37:25 +0200 Subject: [PATCH 05/14] Add delete avatar --- .../StaffDetailsPage/StaffDetailsPage.tsx | 3 + .../StaffProperties/StaffProperties.tsx | 18 +- .../staff/views/StaffDetails.tsx | 161 ++++++++++-------- .../stories/staff/StaffDetailsPage.tsx | 3 +- 4 files changed, 105 insertions(+), 80 deletions(-) diff --git a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx index 53ab40c40c9..5d1eba79000 100644 --- a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx @@ -37,6 +37,7 @@ export interface StaffDetailsPageProps { staffMember: StaffMemberDetails_user; onBack: () => void; onDelete: () => void; + onImageDelete: () => void; onImageUpload(file: File); onSubmit: (data: FormData) => void; } @@ -50,6 +51,7 @@ const StaffDetailsPage: React.StatelessComponent = ({ staffMember, onBack, onDelete, + onImageDelete, onImageUpload, onSubmit }: StaffDetailsPageProps) => { @@ -84,6 +86,7 @@ const StaffDetailsPage: React.StatelessComponent = ({ staffMember={staffMember} onChange={change} onImageUpload={onImageUpload} + onImageDelete={onImageDelete} />
{canEditStatus && ( diff --git a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx index 6c7864b7d78..7d46f3c54a4 100644 --- a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx @@ -38,16 +38,19 @@ const styles = (theme: Theme) => }, avatarHover: { "& p": { + "&:hover": { + textDecoration: "underline" + }, color: theme.palette.primary.main, + cursor: "pointer", fontSize: 12, fontWeight: 500 }, background: "#00000080", borderRadius: "100%", - cursor: "pointer", height: 120, opacity: 0, - padding: `${theme.spacing.unit * 3}px 0`, + padding: `${theme.spacing.unit * 2.5}px 0`, position: "absolute", textAlign: "center", textTransform: "uppercase", @@ -90,6 +93,7 @@ interface StaffPropertiesProps extends WithStyles { disabled: boolean; staffMember: StaffMemberDetails_user; onChange: (event: React.ChangeEvent) => void; + onImageDelete: () => void; onImageUpload: (file: File) => void; } @@ -100,6 +104,7 @@ const StaffProperties = withStyles(styles, { name: "StaffProperties" })( data, staffMember, onChange, + onImageDelete, onImageUpload }: StaffPropertiesProps) => { const imgInputAnchor = React.createRef(); @@ -115,9 +120,14 @@ const StaffProperties = withStyles(styles, { name: "StaffProperties" })( className={classes.avatarImage} src={maybe(() => staffMember.avatar.url)} /> -
+
- {i18n.t("Change photo")} + + {i18n.t("Change photo")} + + + {i18n.t("Delete photo")} + = ({ > {(deleteStaffMember, deleteResult) => ( - {updateStaffAvatar => { - const formTransitionState = getMutationState( - updateResult.called, - updateResult.loading, - maybe(() => updateResult.data.staffUpdate.errors) - ); - const deleteTransitionState = getMutationState( - deleteResult.called, - deleteResult.loading, - maybe(() => deleteResult.data.staffDelete.errors) - ); - const isUserSameAsViewer = maybe( - () => user.user.id === data.user.id, - true - ); + {updateStaffAvatar => ( + + {deleteStaffAvatar => { + const formTransitionState = getMutationState( + updateResult.called, + updateResult.loading, + maybe(() => updateResult.data.staffUpdate.errors) + ); + const deleteTransitionState = getMutationState( + deleteResult.called, + deleteResult.loading, + maybe(() => deleteResult.data.staffDelete.errors) + ); + const isUserSameAsViewer = maybe( + () => user.user.id === data.user.id, + true + ); - return ( - <> - data.user.email)} /> - navigate(staffListUrl())} - onDelete={() => - navigate( - staffMemberDetailsUrl(id, { - action: "remove" - }) - ) - } - onSubmit={variables => - updateStaffMember({ - variables: { - id, - input: { - email: variables.email, - firstName: variables.firstName, - isActive: variables.isActive, - lastName: variables.lastName, - permissions: variables.permissions - } + return ( + <> + data.user.email)} + /> + navigate(staffListUrl())} + onDelete={() => + navigate( + staffMemberDetailsUrl(id, { + action: "remove" + }) + ) } - }) - } - onImageUpload={file => - updateStaffAvatar({ - variables: { - image: file + onSubmit={variables => + updateStaffMember({ + variables: { + id, + input: { + email: variables.email, + firstName: variables.firstName, + isActive: variables.isActive, + lastName: variables.lastName, + permissions: variables.permissions + } + } + }) } - }) - } - permissions={maybe(() => data.shop.permissions)} - staffMember={maybe(() => data.user)} - saveButtonBarState={formTransitionState} - /> - navigate(staffMemberDetailsUrl(id))} - onConfirm={deleteStaffMember} - > - {{ email }} from staff members?", - { - email: maybe(() => data.user.email) - } - ) - }} - /> - - - ); - }} + onImageUpload={file => + updateStaffAvatar({ + variables: { + image: file + } + }) + } + onImageDelete={() => deleteStaffAvatar()} + permissions={maybe(() => data.shop.permissions)} + staffMember={maybe(() => data.user)} + saveButtonBarState={formTransitionState} + /> + + navigate(staffMemberDetailsUrl(id)) + } + onConfirm={deleteStaffMember} + > + {{ email }} from staff members?", + { + email: maybe(() => data.user.email) + } + ) + }} + /> + + + ); + }} + + )} )} diff --git a/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx b/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx index 47040bd3014..4e74dda319f 100644 --- a/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx +++ b/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx @@ -14,8 +14,9 @@ const props: Omit = { disabled: false, onBack: () => undefined, onDelete: () => undefined, - onSubmit: () => undefined, + onImageDelete: () => undefined, onImageUpload: () => undefined, + onSubmit: () => undefined, permissions, saveButtonBarState: "default", staffMember From ebe6bcb6e83f6da3cbdd6977d8b3dd5f2caf2706 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Mon, 29 Apr 2019 13:57:12 +0200 Subject: [PATCH 06/14] Add avatar actions notify and dialog --- .../StaffDetailsPage/StaffDetailsPage.tsx | 2 +- .../static/dashboard-next/staff/mutations.ts | 2 +- .../staff/types/StaffAvatarDelete.ts | 6 -- saleor/static/dashboard-next/staff/urls.ts | 11 ++++ .../staff/views/StaffDetails.tsx | 63 +++++++++++++++++-- 5 files changed, 72 insertions(+), 12 deletions(-) diff --git a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx index 5d1eba79000..dfa98378747 100644 --- a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx @@ -38,8 +38,8 @@ export interface StaffDetailsPageProps { onBack: () => void; onDelete: () => void; onImageDelete: () => void; - onImageUpload(file: File); onSubmit: (data: FormData) => void; + onImageUpload(file: File); } const StaffDetailsPage: React.StatelessComponent = ({ diff --git a/saleor/static/dashboard-next/staff/mutations.ts b/saleor/static/dashboard-next/staff/mutations.ts index d3bd0379a2d..c66d0fee061 100644 --- a/saleor/static/dashboard-next/staff/mutations.ts +++ b/saleor/static/dashboard-next/staff/mutations.ts @@ -106,5 +106,5 @@ const staffAvatarDeleteMutation = gql` `; export const TypedStaffAvatarDeleteMutation = TypedMutation< StaffAvatarDelete, - {} + StaffMemberDeleteVariables >(staffAvatarDeleteMutation); diff --git a/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts b/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts index d37a1a84d40..c96ad58d9dc 100644 --- a/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts +++ b/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts @@ -12,15 +12,9 @@ export interface StaffAvatarDelete_userAvatarDelete_errors { message: string | null; } -export interface StaffAvatarDelete_userAvatarDelete_user { - __typename: "User"; - id: string; -} - export interface StaffAvatarDelete_userAvatarDelete { __typename: "UserAvatarDelete"; errors: StaffAvatarDelete_userAvatarDelete_errors[] | null; - user: StaffAvatarDelete_userAvatarDelete_user | null; } export interface StaffAvatarDelete { diff --git a/saleor/static/dashboard-next/staff/urls.ts b/saleor/static/dashboard-next/staff/urls.ts index 2bf8ad3c7d0..2ce2832fd9a 100644 --- a/saleor/static/dashboard-next/staff/urls.ts +++ b/saleor/static/dashboard-next/staff/urls.ts @@ -18,7 +18,18 @@ export type StaffMemberDetailsUrlDialog = "remove"; export type StaffMemberDetailsUrlQueryParams = Dialog< StaffMemberDetailsUrlDialog >; + export const staffMemberDetailsUrl = ( id: string, params?: StaffMemberDetailsUrlQueryParams ) => staffMemberDetailsPath(encodeURIComponent(id)) + "?" + stringifyQs(params); + +export type StaffMemberAvatarUrlDialog = "removeAvatar"; +export type StaffMemberAvatarUrlQueryParams = Dialog< + StaffMemberAvatarUrlDialog +>; + +export const staffMemberAvatarUrl = ( + id: string, + params?: StaffMemberAvatarUrlQueryParams +) => staffMemberDetailsPath(encodeURIComponent(id)) + "?" + stringifyQs(params); diff --git a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx index 3131a9e4ff5..43702415aee 100644 --- a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx +++ b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx @@ -22,6 +22,7 @@ import { StaffMemberDelete } from "../types/StaffMemberDelete"; import { StaffMemberUpdate } from "../types/StaffMemberUpdate"; import { staffListUrl, + staffMemberAvatarUrl, staffMemberDetailsUrl, StaffMemberDetailsUrlQueryParams } from "../urls"; @@ -61,6 +62,21 @@ export const StaffDetails: React.StatelessComponent = ({ navigate(staffListUrl()); } }; + const handleStaffMemberAvatarUpdate = (data: StaffAvatarUpdate) => { + if (!maybe(() => data.userAvatarUpdate.errors.length !== 0)) { + notify({ + text: i18n.t("Succesfully updated staff member avatar") + }); + } + }; + const handleStaffMemberAvatarDelete = (data: StaffAvatarDelete) => { + if (!maybe(() => data.userAvatarDelete.errors.length !== 0)) { + notify({ + text: i18n.t("Succesfully removed staff member avatar") + }); + navigate(staffMemberDetailsUrl(id)); + } + }; return ( {(updateStaffMember, updateResult) => ( @@ -69,10 +85,14 @@ export const StaffDetails: React.StatelessComponent = ({ onCompleted={handleStaffMemberDelete} > {(deleteStaffMember, deleteResult) => ( - + {updateStaffAvatar => ( - - {deleteStaffAvatar => { + + {(deleteStaffAvatar, deleteAvatarResult) => { const formTransitionState = getMutationState( updateResult.called, updateResult.loading, @@ -83,6 +103,14 @@ export const StaffDetails: React.StatelessComponent = ({ deleteResult.loading, maybe(() => deleteResult.data.staffDelete.errors) ); + const deleteAvatarTransitionState = getMutationState( + deleteAvatarResult.called, + deleteAvatarResult.loading, + maybe( + () => + deleteAvatarResult.data.userAvatarDelete.errors + ) + ); const isUserSameAsViewer = maybe( () => user.user.id === data.user.id, true @@ -126,7 +154,13 @@ export const StaffDetails: React.StatelessComponent = ({ } }) } - onImageDelete={() => deleteStaffAvatar()} + onImageDelete={() => + navigate( + staffMemberAvatarUrl(id, { + action: "removeAvatar" + }) + ) + } permissions={maybe(() => data.shop.permissions)} staffMember={maybe(() => data.user)} saveButtonBarState={formTransitionState} @@ -152,6 +186,27 @@ export const StaffDetails: React.StatelessComponent = ({ }} /> + + navigate(staffMemberDetailsUrl(id)) + } + onConfirm={deleteStaffAvatar} + > + {{ email }} avatar?", + { + email: maybe(() => data.user.email) + } + ) + }} + /> + ); }} From d26cc7609abcd9df0a2b50c2faff6e447a3c8861 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Mon, 29 Apr 2019 14:35:12 +0200 Subject: [PATCH 07/14] Add user deafult avatar --- .../StaffProperties/StaffProperties.tsx | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx index 7d46f3c54a4..af875871381 100644 --- a/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffProperties/StaffProperties.tsx @@ -13,7 +13,7 @@ import SVG from "react-inlinesvg"; import CardTitle from "../../../components/CardTitle"; import i18n from "../../../i18n"; -import { maybe } from "../../../misc"; +import { maybe, getUserInitials } from "../../../misc"; import { StaffMemberDetails_user } from "../../types/StaffMemberDetails"; import * as photoIcon from "../../../../images/photo-icon.svg"; @@ -36,6 +36,18 @@ const styles = (theme: Theme) => position: "relative", width: 120 }, + avatarDefault: { + "& p": { + color: "#fff", + fontSize: 35, + fontWeight: "bold", + lineHeight: "120px" + }, + background: theme.palette.primary.main, + height: 120, + textAlign: "center", + width: 120 + }, avatarHover: { "& p": { "&:hover": { @@ -116,10 +128,16 @@ const StaffProperties = withStyles(styles, { name: "StaffProperties" })(
- staffMember.avatar.url)} - /> + {maybe(() => staffMember.avatar.url) ? ( + staffMember.avatar.url)} + /> + ) : ( +
+ {getUserInitials(data)} +
+ )}
From a18266fda9d3552ee1f698c76a61ca378c453237 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Mon, 29 Apr 2019 15:05:07 +0200 Subject: [PATCH 08/14] Allow user to change only yours avatar --- .../StaffDetailsPage/StaffDetailsPage.tsx | 3 ++ .../StaffProperties/StaffProperties.tsx | 38 ++++++++++--------- .../staff/views/StaffDetails.tsx | 1 + .../stories/staff/StaffDetailsPage.tsx | 1 + 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx index dfa98378747..2c8be02f99e 100644 --- a/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffDetailsPage/StaffDetailsPage.tsx @@ -29,6 +29,7 @@ interface FormData { } export interface StaffDetailsPageProps { + canEditAvatar: boolean; canEditStatus: boolean; canRemove: boolean; disabled: boolean; @@ -43,6 +44,7 @@ export interface StaffDetailsPageProps { } const StaffDetailsPage: React.StatelessComponent = ({ + canEditAvatar, canEditStatus, canRemove, disabled, @@ -83,6 +85,7 @@ const StaffDetailsPage: React.StatelessComponent = ({ }); interface StaffPropertiesProps extends WithStyles { + canEditAvatar: boolean; className?: string; data: { email: string; @@ -111,6 +112,7 @@ interface StaffPropertiesProps extends WithStyles { const StaffProperties = withStyles(styles, { name: "StaffProperties" })( ({ + canEditAvatar, classes, className, data, @@ -138,22 +140,24 @@ const StaffProperties = withStyles(styles, { name: "StaffProperties" })( {getUserInitials(data)}
)} -
- - - {i18n.t("Change photo")} - - - {i18n.t("Delete photo")} - - onImageUpload(event.target.files[0])} - type="file" - ref={imgInputAnchor} - /> -
+ {canEditAvatar && ( +
+ + + {i18n.t("Change photo")} + + + {i18n.t("Delete photo")} + + onImageUpload(event.target.files[0])} + type="file" + ref={imgInputAnchor} + /> +
+ )}
diff --git a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx index 43702415aee..f90affe3e54 100644 --- a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx +++ b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx @@ -122,6 +122,7 @@ export const StaffDetails: React.StatelessComponent = ({ title={maybe(() => data.user.email)} /> = { + canEditAvatar: true, canEditStatus: true, canRemove: true, disabled: false, From e6020e35deca3a460dbe32edccbb1eec174a5b77 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Mon, 29 Apr 2019 15:14:35 +0200 Subject: [PATCH 09/14] Fix staff list styles --- .../staff/components/StaffList/StaffList.tsx | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/saleor/static/dashboard-next/staff/components/StaffList/StaffList.tsx b/saleor/static/dashboard-next/staff/components/StaffList/StaffList.tsx index e4658eaeaac..8cfc11b86ba 100644 --- a/saleor/static/dashboard-next/staff/components/StaffList/StaffList.tsx +++ b/saleor/static/dashboard-next/staff/components/StaffList/StaffList.tsx @@ -18,7 +18,12 @@ import * as React from "react"; import Skeleton from "../../../components/Skeleton"; import TablePagination from "../../../components/TablePagination"; import i18n from "../../../i18n"; -import { getUserName, maybe, renderCollection } from "../../../misc"; +import { + getUserInitials, + getUserName, + maybe, + renderCollection +} from "../../../misc"; import { ListProps } from "../../../types"; import { StaffList_staffUsers_edges_node } from "../../types/StaffList"; @@ -32,7 +37,18 @@ const styles = (theme: Theme) => height: 47, justifyContent: "center", marginRight: theme.spacing.unit * 1 + "px", - width: 37 + overflow: "hidden", + width: 47 + }, + avatarDefault: { + "& p": { + color: "#fff", + lineHeight: "47px" + }, + background: theme.palette.primary.main, + height: 47, + textAlign: "center", + width: 47 }, avatarImage: { pointerEvents: "none", @@ -104,10 +120,16 @@ const StaffList = withStyles(styles, { name: "StaffList" })( >
- staffMember.avatar.url)} - /> + {maybe(() => staffMember.avatar.url) ? ( + staffMember.avatar.url)} + /> + ) : ( +
+ {getUserInitials(staffMember)} +
+ )}
{getUserName(staffMember) || } From 9fbc07c87f5dc179cd1a03bbdb11fc7f4bf437bd Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Mon, 29 Apr 2019 15:22:34 +0200 Subject: [PATCH 10/14] Fix update avatar on delete --- saleor/static/dashboard-next/staff/mutations.ts | 6 ++++++ .../dashboard-next/staff/types/StaffAvatarDelete.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/saleor/static/dashboard-next/staff/mutations.ts b/saleor/static/dashboard-next/staff/mutations.ts index c66d0fee061..a3939ecc35d 100644 --- a/saleor/static/dashboard-next/staff/mutations.ts +++ b/saleor/static/dashboard-next/staff/mutations.ts @@ -101,6 +101,12 @@ const staffAvatarDeleteMutation = gql` field message } + user { + id + avatar { + url + } + } } } `; diff --git a/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts b/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts index c96ad58d9dc..763ee71e63d 100644 --- a/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts +++ b/saleor/static/dashboard-next/staff/types/StaffAvatarDelete.ts @@ -12,9 +12,21 @@ export interface StaffAvatarDelete_userAvatarDelete_errors { message: string | null; } +export interface StaffAvatarDelete_userAvatarDelete_user_avatar { + __typename: "Image"; + url: string; +} + +export interface StaffAvatarDelete_userAvatarDelete_user { + __typename: "User"; + id: string; + avatar: StaffAvatarDelete_userAvatarDelete_user_avatar | null; +} + export interface StaffAvatarDelete_userAvatarDelete { __typename: "UserAvatarDelete"; errors: StaffAvatarDelete_userAvatarDelete_errors[] | null; + user: StaffAvatarDelete_userAvatarDelete_user | null; } export interface StaffAvatarDelete { From 29dcbf614987b4b689f2c39f5085e5ead897451c Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Mon, 29 Apr 2019 16:37:53 +0200 Subject: [PATCH 11/14] Fix remove avatar urls --- saleor/static/dashboard-next/staff/urls.ts | 12 +----------- .../dashboard-next/staff/views/StaffDetails.tsx | 7 +++---- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/saleor/static/dashboard-next/staff/urls.ts b/saleor/static/dashboard-next/staff/urls.ts index 2ce2832fd9a..56c2211a69b 100644 --- a/saleor/static/dashboard-next/staff/urls.ts +++ b/saleor/static/dashboard-next/staff/urls.ts @@ -14,7 +14,7 @@ export const staffListUrl = (params?: StaffListUrlQueryParams) => staffListPath + "?" + stringifyQs(params); export const staffMemberDetailsPath = (id: string) => urlJoin(staffSection, id); -export type StaffMemberDetailsUrlDialog = "remove"; +export type StaffMemberDetailsUrlDialog = "remove" | "remove-avatar"; export type StaffMemberDetailsUrlQueryParams = Dialog< StaffMemberDetailsUrlDialog >; @@ -23,13 +23,3 @@ export const staffMemberDetailsUrl = ( id: string, params?: StaffMemberDetailsUrlQueryParams ) => staffMemberDetailsPath(encodeURIComponent(id)) + "?" + stringifyQs(params); - -export type StaffMemberAvatarUrlDialog = "removeAvatar"; -export type StaffMemberAvatarUrlQueryParams = Dialog< - StaffMemberAvatarUrlDialog ->; - -export const staffMemberAvatarUrl = ( - id: string, - params?: StaffMemberAvatarUrlQueryParams -) => staffMemberDetailsPath(encodeURIComponent(id)) + "?" + stringifyQs(params); diff --git a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx index f90affe3e54..f86ce92a810 100644 --- a/saleor/static/dashboard-next/staff/views/StaffDetails.tsx +++ b/saleor/static/dashboard-next/staff/views/StaffDetails.tsx @@ -22,7 +22,6 @@ import { StaffMemberDelete } from "../types/StaffMemberDelete"; import { StaffMemberUpdate } from "../types/StaffMemberUpdate"; import { staffListUrl, - staffMemberAvatarUrl, staffMemberDetailsUrl, StaffMemberDetailsUrlQueryParams } from "../urls"; @@ -157,8 +156,8 @@ export const StaffDetails: React.StatelessComponent = ({ } onImageDelete={() => navigate( - staffMemberAvatarUrl(id, { - action: "removeAvatar" + staffMemberDetailsUrl(id, { + action: "remove-avatar" }) ) } @@ -188,7 +187,7 @@ export const StaffDetails: React.StatelessComponent = ({ /> Date: Mon, 29 Apr 2019 22:14:07 +0200 Subject: [PATCH 12/14] Fix stories snap --- .../__snapshots__/Stories.test.ts.snap | 108 +++++++++++++++++- 1 file changed, 102 insertions(+), 6 deletions(-) diff --git a/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap b/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap index a51ca76dd32..2fa3a02c246 100644 --- a/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap +++ b/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap @@ -76709,6 +76709,28 @@ exports[`Storyshots Views / Staff / Staff member details default 1`] = ` class="StaffProperties-avatarImage-id" src="avatar1.png" /> +
+ +

+ Change photo +

+

+ Delete photo +

+ +
@@ -77002,6 +77024,28 @@ exports[`Storyshots Views / Staff / Staff member details himself 1`] = ` class="StaffProperties-avatarImage-id" src="avatar1.png" /> +
+ +

+ Change photo +

+

+ Delete photo +

+ +
@@ -77155,9 +77199,35 @@ exports[`Storyshots Views / Staff / Staff member details loading 1`] = `
- +
+

+

+
+ +

+ Change photo +

+

+ Delete photo +

+ +
@@ -77837,6 +77907,28 @@ exports[`Storyshots Views / Staff / Staff member details not admin 1`] = ` class="StaffProperties-avatarImage-id" src="avatar1.png" /> +
+ +

+ Change photo +

+

+ Delete photo +

+ +
@@ -79136,9 +79228,13 @@ exports[`Storyshots Views / Staff / Staff members when loading 1`] = `
- +
+

+

Date: Mon, 29 Apr 2019 22:15:35 +0200 Subject: [PATCH 13/14] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6db082696f..9666353487c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ All notable, unreleased changes to this project will be documented in this file. - Add bulk actions - #3955 by @dominik-zeglen - Update file field styles with materializecss template filter - #3998 by @zodiacfireworks - Add filtering interface for graphQL API - #3952 by @korycins - +- Add user avatar management - #4030 by @benekex2 ## 2.5.0 From fb0165398baed26f2dfb7dbc5ec3d71df7cfaa75 Mon Sep 17 00:00:00 2001 From: Krzysztof Bialoglowicz Date: Tue, 30 Apr 2019 16:06:35 +0200 Subject: [PATCH 14/14] Fix stories avatar edit state --- .../__snapshots__/Stories.test.ts.snap | 66 ------------------- .../stories/staff/StaffDetailsPage.tsx | 9 ++- 2 files changed, 7 insertions(+), 68 deletions(-) diff --git a/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap b/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap index 9e8bc915245..58620d51b7c 100644 --- a/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap +++ b/saleor/static/dashboard-next/storybook/__snapshots__/Stories.test.ts.snap @@ -77560,28 +77560,6 @@ exports[`Storyshots Views / Staff / Staff member details default 1`] = ` class="StaffProperties-avatarImage-id" src="avatar1.png" /> -

- -

- Change photo -

-

- Delete photo -

- -
@@ -78057,28 +78035,6 @@ exports[`Storyshots Views / Staff / Staff member details loading 1`] = ` class="MuiTypography-root-id MuiTypography-body1-id" />
-
- -

- Change photo -

-

- Delete photo -

- -
@@ -78758,28 +78714,6 @@ exports[`Storyshots Views / Staff / Staff member details not admin 1`] = ` class="StaffProperties-avatarImage-id" src="avatar1.png" /> -
- -

- Change photo -

-

- Delete photo -

- -
diff --git a/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx b/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx index 8de348dc9be..61bde9f12e7 100644 --- a/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx +++ b/saleor/static/dashboard-next/storybook/stories/staff/StaffDetailsPage.tsx @@ -9,7 +9,7 @@ import { permissions, staffMember } from "../../../staff/fixtures"; import Decorator from "../../Decorator"; const props: Omit = { - canEditAvatar: true, + canEditAvatar: false, canEditStatus: true, canRemove: true, disabled: false, @@ -39,5 +39,10 @@ storiesOf("Views / Staff / Staff member details", module) /> )) .add("himself", () => ( - + ));