Skip to content

Commit

Permalink
Merge pull request #3071 from mirumee/tsx/implement-site-settings
Browse files Browse the repository at this point in the history
Implement site settings
  • Loading branch information
maarcingebala committed Oct 12, 2018
2 parents 6aa57d7 + 258362e commit cbc72d3
Show file tree
Hide file tree
Showing 31 changed files with 1,998 additions and 24 deletions.
2 changes: 1 addition & 1 deletion saleor/graphql/core/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def clean_instance(cls, instance, errors):
except ValidationError as validation_errors:
message_dict = validation_errors.message_dict
for field in message_dict:
if field in cls._meta.exclude:
if hasattr(cls._meta, 'exclude') and field in cls._meta.exclude:
continue
for message in message_dict[field]:
field = snake_to_camel_case(field)
Expand Down
6 changes: 4 additions & 2 deletions saleor/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,18 @@ type AuthorizationKey {
type AuthorizationKeyAdd {
errors: [Error]
authorizationKey: AuthorizationKey
shop: Shop
}

type AuthorizationKeyDelete {
errors: [Error]
authorizationKey: AuthorizationKey
shop: Shop
}

input AuthorizationKeyInput {
key: String
password: String
key: String!
password: String!
}

enum AuthorizationKeyType {
Expand Down
30 changes: 16 additions & 14 deletions saleor/graphql/shop/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class SiteDomainInput(graphene.InputObjectType):


class ShopSettingsUpdate(BaseMutation):
shop = graphene.Field(Shop, description='Updated Shop')

class Arguments:
input = ShopSettingsInput(
description='Fields required to update shop settings.',
Expand All @@ -34,9 +36,6 @@ class Arguments:
class Meta:
description = 'Updates shop settings'

shop = graphene.Field(
Shop, description='Updated Shop')

@classmethod
@permission_required('site.manage_settings')
def mutate(cls, root, info, input):
Expand All @@ -56,24 +55,24 @@ def mutate(cls, root, info, input):


class ShopDomainUpdate(BaseMutation):
shop = graphene.Field(Shop, description='Updated Shop')

class Arguments:
input = SiteDomainInput(description='Fields required to update site')

class Meta:
description = 'Updates site domain of the shop'

shop = graphene.Field(Shop, description='Updated Shop')

@classmethod
@permission_required('site.manage_settings')
def mutate(cls, root, info, input):
errors = []
site = info.context.site
domain = input.get('domain')
name = input.get('name')
if domain:
if domain is not None:
site.domain = domain
if name:
if name is not None:
site.name = name
cls.clean_instance(site, errors)
if errors:
Expand All @@ -83,16 +82,15 @@ def mutate(cls, root, info, input):


class HomepageCollectionUpdate(BaseMutation):
shop = graphene.Field(Shop, description='Updated Shop')

class Arguments:
collection = graphene.ID(
description='Collection displayed on homepage')

class Meta:
description = 'Updates homepage collection of the shop'

shop = graphene.Field(
Shop, description='Updated Shop')

@classmethod
@permission_required('site.manage_settings')
def mutate(cls, root, info, collection):
Expand All @@ -111,13 +109,16 @@ def mutate(cls, root, info, collection):


class AuthorizationKeyInput(graphene.InputObjectType):
key = graphene.String(description='Client authorization key (client ID).')
password = graphene.String(description='Client secret.')
key = graphene.String(
required=True, description='Client authorization key (client ID).')
password = graphene.String(
required=True, description='Client secret.')


class AuthorizationKeyAdd(BaseMutation):
authorization_key = graphene.Field(
AuthorizationKey, description='Newly added authorization key.')
shop = graphene.Field(Shop, description='Updated Shop')

class Meta:
description = 'Adds an authorization key.'
Expand Down Expand Up @@ -146,12 +147,13 @@ def mutate(cls, root, info, key_type, input):
return AuthorizationKeyAdd(errors=errors)

instance.save()
return AuthorizationKeyAdd(authorization_key=instance)
return AuthorizationKeyAdd(authorization_key=instance, shop=Shop())


class AuthorizationKeyDelete(BaseMutation):
authorization_key = graphene.Field(
AuthorizationKey, description='Auhtorization key that was deleted.')
shop = graphene.Field(Shop, description='Updated Shop')

class Arguments:
key_type = AuthorizationKeyType(
Expand All @@ -174,4 +176,4 @@ def mutate(cls, root, info, key_type):
return AuthorizationKeyDelete(errors=errors)

instance.delete()
return AuthorizationKeyDelete(authorization_key=instance)
return AuthorizationKeyDelete(authorization_key=instance, shop=Shop())
4 changes: 3 additions & 1 deletion saleor/static/dashboard-next/configuration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Navigation from "../icons/Navigation";
import Pages from "../icons/Pages";
import StoreMall from "../icons/StoreMall";
import { productTypeListUrl } from "../productTypes";
import { siteSettingsUrl } from "../siteSettings";
import { staffListUrl } from "../staff";
import { PermissionEnum } from "../types/globalTypes";
import ConfigurationPage, { MenuItem } from "./ConfigurationPage";
Expand Down Expand Up @@ -59,7 +60,8 @@ export const configurationMenu: MenuItem[] = [
description: i18n.t("View and update your site settings"),
icon: <StoreMall fontSize="inherit" />,
permission: PermissionEnum.MANAGE_SETTINGS,
title: i18n.t("Site Settings")
title: i18n.t("Site Settings"),
url: siteSettingsUrl
},
{
description: i18n.t("Manage and add additional pages"),
Expand Down
22 changes: 18 additions & 4 deletions saleor/static/dashboard-next/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import CssBaseline from "@material-ui/core/CssBaseline";
import MuiThemeProvider from "@material-ui/core/styles/MuiThemeProvider";
import { InMemoryCache } from "apollo-cache-inmemory";
import { defaultDataIdFromObject, InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient, ApolloError } from "apollo-client";
import { setContext } from "apollo-link-context";
import { ErrorResponse, onError } from "apollo-link-error";
Expand Down Expand Up @@ -28,10 +28,10 @@ import OrdersSection from "./orders";
import PageSection from "./pages";
import ProductSection from "./products";
import ProductTypesSection from "./productTypes";
import SiteSettingsSection from "./siteSettings";
import StaffSection from "./staff";
import theme from "./theme";
import { PermissionEnum } from './types/globalTypes';

import { PermissionEnum } from "./types/globalTypes";

const cookies = new Cookies();

Expand Down Expand Up @@ -68,7 +68,16 @@ const uploadLink = createUploadLink({
});

const apolloClient = new ApolloClient({
cache: new InMemoryCache(),
cache: new InMemoryCache({
dataIdFromObject: (obj: any) => {
// We need to set manually shop's ID, since it is singleton and
// API does not return its ID
if (obj.__typename === "Shop") {
return "shop";
}
return defaultDataIdFromObject(obj);
}
}),
link: invalidTokenLink.concat(authLink.concat(uploadLink))
});

Expand Down Expand Up @@ -125,6 +134,11 @@ render(
path="/staff"
component={StaffSection}
/>
<SectionRoute
permissions={[PermissionEnum.MANAGE_SETTINGS]}
path="/siteSettings"
component={SiteSettingsSection}
/>
{configurationMenu.filter(menuItem =>
hasPermission(menuItem.permission, user)
).length > 0 && (
Expand Down
7 changes: 6 additions & 1 deletion saleor/static/dashboard-next/misc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { stringify } from "qs";
import i18n from "./i18n";
import { TaxRateType } from "./types/globalTypes";
import { AuthorizationKeyType, TaxRateType } from "./types/globalTypes";

export interface PageInfo {
endCursor: string;
Expand Down Expand Up @@ -145,6 +145,11 @@ export const translatedTaxRates = () => ({
[TaxRateType.WATER]: i18n.t("Water")
});

export const translatedAuthorizationKeyTypes = () => ({
[AuthorizationKeyType.FACEBOOK]: i18n.t("Facebook"),
[AuthorizationKeyType.GOOGLE_OAUTH2]: i18n.t("Google OAuth2")
});

export function maybe<T>(exp: () => T, d?: T) {
try {
const result = exp();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import TextField from "@material-ui/core/TextField";
import * as React from "react";

import CardTitle from "../../../components/CardTitle";
import FormSpacer from "../../../components/FormSpacer";
import i18n from "../../../i18n";
import { SiteSettingsPageFormData } from "../SiteSettingsPage";

interface SiteSettingsDetailsProps {
data: SiteSettingsPageFormData;
errors: Partial<{
description: string;
domain: string;
name: string;
}>;
disabled: boolean;
onChange: (event: React.ChangeEvent<any>) => void;
}

const SiteSettingsDetails: React.StatelessComponent<
SiteSettingsDetailsProps
> = ({ data, disabled, errors, onChange }) => (
<Card>
<CardTitle
title={i18n.t("General Information", {
context: "store configuration"
})}
/>
<CardContent>
<TextField
disabled={disabled}
error={!!errors.name}
fullWidth
name="name"
label={i18n.t("Name of your store")}
helperText={
errors.name ||
i18n.t("Name of your store is shown on tab in web browser")
}
value={data.name}
onChange={onChange}
/>
<FormSpacer />
<TextField
disabled={disabled}
error={!!errors.domain}
fullWidth
name="domain"
label={i18n.t("URL of your online store")}
helperText={errors.domain}
value={data.domain}
onChange={onChange}
/>
<FormSpacer />
<TextField
disabled={disabled}
error={!!errors.domain}
fullWidth
name="description"
label={i18n.t("Store Description", {
context: "field label"
})}
helperText={
errors.description ||
i18n.t(
"Store description is shown on taskbar after your store name",
{
context: "help text"
}
)
}
value={data.description}
onChange={onChange}
/>
</CardContent>
</Card>
);
SiteSettingsDetails.displayName = "SiteSettingsDetails";
export default SiteSettingsDetails;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from "./SiteSettingsDetails";
export * from "./SiteSettingsDetails";

0 comments on commit cbc72d3

Please sign in to comment.