commit
831bde8311
10 changed files with 102 additions and 32 deletions
|
@ -1675,6 +1675,10 @@
|
||||||
"context": "button",
|
"context": "button",
|
||||||
"string": "Delete"
|
"string": "Delete"
|
||||||
},
|
},
|
||||||
|
"src_dot_demo": {
|
||||||
|
"context": "notification message after log in",
|
||||||
|
"string": "Just to let you know... You're in demo mode. You can play around with the dashboard but can't save changes."
|
||||||
|
},
|
||||||
"src_dot_description": {
|
"src_dot_description": {
|
||||||
"string": "Description"
|
"string": "Description"
|
||||||
},
|
},
|
||||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -17951,6 +17951,11 @@
|
||||||
"react-clientside-effect": "^1.2.0"
|
"react-clientside-effect": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-gtm-module": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-gtm-module/-/react-gtm-module-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-OU5FwAHC3gWnnxJ+MLwBMLZO1Pmn1DiVCGHqptwDnNojE3QRrNxjqozkW5cNS4Zp+C6HZ8a4ZIt0QPNlpzua4Q=="
|
||||||
|
},
|
||||||
"react-helmet": {
|
"react-helmet": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.1.tgz",
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.9.0",
|
||||||
"react-dropzone": "^8.2.0",
|
"react-dropzone": "^8.2.0",
|
||||||
"react-error-boundary": "^1.2.5",
|
"react-error-boundary": "^1.2.5",
|
||||||
|
"react-gtm-module": "^2.0.8",
|
||||||
"react-helmet": "^5.2.1",
|
"react-helmet": "^5.2.1",
|
||||||
"react-infinite-scroller": "^1.2.4",
|
"react-infinite-scroller": "^1.2.4",
|
||||||
"react-inlinesvg": "^0.8.4",
|
"react-inlinesvg": "^0.8.4",
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { DEMO_MODE } from "@saleor/config";
|
||||||
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import {
|
import {
|
||||||
isSupported as isCredentialsManagementAPISupported,
|
isSupported as isCredentialsManagementAPISupported,
|
||||||
|
@ -6,6 +8,7 @@ import {
|
||||||
} from "@saleor/utils/credentialsManagement";
|
} from "@saleor/utils/credentialsManagement";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { MutationFunction, MutationResult } from "react-apollo";
|
import { MutationFunction, MutationResult } from "react-apollo";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { UserContext } from "./";
|
import { UserContext } from "./";
|
||||||
import {
|
import {
|
||||||
|
@ -17,7 +20,12 @@ import { RefreshToken, RefreshTokenVariables } from "./types/RefreshToken";
|
||||||
import { TokenAuth, TokenAuthVariables } from "./types/TokenAuth";
|
import { TokenAuth, TokenAuthVariables } from "./types/TokenAuth";
|
||||||
import { User } from "./types/User";
|
import { User } from "./types/User";
|
||||||
import { VerifyToken, VerifyTokenVariables } from "./types/VerifyToken";
|
import { VerifyToken, VerifyTokenVariables } from "./types/VerifyToken";
|
||||||
import { getAuthToken, removeAuthToken, setAuthToken } from "./utils";
|
import {
|
||||||
|
displayDemoMessage,
|
||||||
|
getAuthToken,
|
||||||
|
removeAuthToken,
|
||||||
|
setAuthToken
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
interface AuthProviderOperationsProps {
|
interface AuthProviderOperationsProps {
|
||||||
children: (props: {
|
children: (props: {
|
||||||
|
@ -30,7 +38,17 @@ interface AuthProviderOperationsProps {
|
||||||
}
|
}
|
||||||
const AuthProviderOperations: React.FC<AuthProviderOperationsProps> = ({
|
const AuthProviderOperations: React.FC<AuthProviderOperationsProps> = ({
|
||||||
children
|
children
|
||||||
}) => (
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const notify = useNotifier();
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
if (DEMO_MODE) {
|
||||||
|
displayDemoMessage(intl, notify);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
<TypedTokenAuthMutation>
|
<TypedTokenAuthMutation>
|
||||||
{(...tokenAuth) => (
|
{(...tokenAuth) => (
|
||||||
<TypedVerifyTokenMutation>
|
<TypedVerifyTokenMutation>
|
||||||
|
@ -41,6 +59,7 @@ const AuthProviderOperations: React.FC<AuthProviderOperationsProps> = ({
|
||||||
tokenAuth={tokenAuth}
|
tokenAuth={tokenAuth}
|
||||||
tokenVerify={tokenVerify}
|
tokenVerify={tokenVerify}
|
||||||
tokenRefresh={tokenRefresh}
|
tokenRefresh={tokenRefresh}
|
||||||
|
onLogin={handleLogin}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
|
@ -51,6 +70,7 @@ const AuthProviderOperations: React.FC<AuthProviderOperationsProps> = ({
|
||||||
)}
|
)}
|
||||||
</TypedTokenAuthMutation>
|
</TypedTokenAuthMutation>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
interface AuthProviderProps {
|
interface AuthProviderProps {
|
||||||
children: (props: {
|
children: (props: {
|
||||||
|
@ -72,6 +92,7 @@ interface AuthProviderProps {
|
||||||
MutationFunction<RefreshToken, RefreshTokenVariables>,
|
MutationFunction<RefreshToken, RefreshTokenVariables>,
|
||||||
MutationResult<RefreshToken>
|
MutationResult<RefreshToken>
|
||||||
];
|
];
|
||||||
|
onLogin?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AuthProviderState {
|
interface AuthProviderState {
|
||||||
|
@ -130,11 +151,14 @@ class AuthProvider extends React.Component<
|
||||||
}
|
}
|
||||||
|
|
||||||
login = async (email: string, password: string) => {
|
login = async (email: string, password: string) => {
|
||||||
const { tokenAuth } = this.props;
|
const { tokenAuth, onLogin } = this.props;
|
||||||
const [tokenAuthFn] = tokenAuth;
|
const [tokenAuthFn] = tokenAuth;
|
||||||
|
|
||||||
tokenAuthFn({ variables: { email, password } }).then(result => {
|
tokenAuthFn({ variables: { email, password } }).then(result => {
|
||||||
if (result && !result.data.tokenCreate.errors.length) {
|
if (result && !result.data.tokenCreate.errors.length) {
|
||||||
|
if (!!onLogin) {
|
||||||
|
onLogin();
|
||||||
|
}
|
||||||
saveCredentials(result.data.tokenCreate.user, password);
|
saveCredentials(result.data.tokenCreate.user, password);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,6 +4,7 @@ import TextField from "@material-ui/core/TextField";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import Form from "@saleor/components/Form";
|
import Form from "@saleor/components/Form";
|
||||||
import { FormSpacer } from "@saleor/components/FormSpacer";
|
import { FormSpacer } from "@saleor/components/FormSpacer";
|
||||||
|
import { DEMO_MODE } from "@saleor/config";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
@ -53,8 +54,16 @@ const LoginCard: React.FC<LoginCardProps> = props => {
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
let initialFormData = { email: "", password: "" };
|
||||||
|
if (DEMO_MODE) {
|
||||||
|
initialFormData = {
|
||||||
|
email: "admin@example.com",
|
||||||
|
password: "admin"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form initial={{ email: "", password: "" }} onSubmit={onSubmit}>
|
<Form initial={initialFormData} onSubmit={onSubmit}>
|
||||||
{({ change: handleChange, data, submit: handleSubmit }) => (
|
{({ change: handleChange, data, submit: handleSubmit }) => (
|
||||||
<>
|
<>
|
||||||
{error && (
|
{error && (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import { UseNotifierResult } from "@saleor/hooks/useNotifier";
|
||||||
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
import { IntlShape } from "react-intl";
|
||||||
|
|
||||||
const TOKEN_STORAGE_KEY = "dashboardAuth";
|
const TOKEN_STORAGE_KEY = "dashboardAuth";
|
||||||
|
|
||||||
export const getAuthToken = () =>
|
export const getAuthToken = () =>
|
||||||
|
@ -13,3 +17,12 @@ export const removeAuthToken = () => {
|
||||||
localStorage.removeItem(TOKEN_STORAGE_KEY);
|
localStorage.removeItem(TOKEN_STORAGE_KEY);
|
||||||
sessionStorage.removeItem(TOKEN_STORAGE_KEY);
|
sessionStorage.removeItem(TOKEN_STORAGE_KEY);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const displayDemoMessage = (
|
||||||
|
intl: IntlShape,
|
||||||
|
notify: UseNotifierResult
|
||||||
|
) => {
|
||||||
|
notify({
|
||||||
|
text: intl.formatMessage(commonMessages.demo)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ import packageInfo from "../package.json";
|
||||||
import { SearchVariables } from "./hooks/makeSearch";
|
import { SearchVariables } from "./hooks/makeSearch";
|
||||||
import { ListSettings, ListViews, Pagination } from "./types";
|
import { ListSettings, ListViews, Pagination } from "./types";
|
||||||
|
|
||||||
export const APP_MOUNT_URI = process.env.APP_MOUNT_URI || "/";
|
export const APP_MOUNT_URI = process.env.APP_MOUNT_URI;
|
||||||
export const API_URI = process.env.API_URI;
|
export const API_URI = process.env.API_URI;
|
||||||
|
|
||||||
export const DEFAULT_INITIAL_SEARCH_DATA: SearchVariables = {
|
export const DEFAULT_INITIAL_SEARCH_DATA: SearchVariables = {
|
||||||
|
@ -90,3 +90,5 @@ export const defaultListSettings: AppListViewSettings = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const APP_VERSION = packageInfo.version;
|
export const APP_VERSION = packageInfo.version;
|
||||||
|
export const DEMO_MODE = process.env.DEMO_MODE === "true";
|
||||||
|
export const GTM_ID = process.env.GTM_ID;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import React from "react";
|
||||||
import { ApolloProvider } from "react-apollo";
|
import { ApolloProvider } from "react-apollo";
|
||||||
import { render } from "react-dom";
|
import { render } from "react-dom";
|
||||||
import ErrorBoundary from "react-error-boundary";
|
import ErrorBoundary from "react-error-boundary";
|
||||||
|
import TagManager from "react-gtm-module";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { BrowserRouter, Route, Switch } from "react-router-dom";
|
import { BrowserRouter, Route, Switch } from "react-router-dom";
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ import { MessageManager } from "./components/messages";
|
||||||
import { ShopProvider } from "./components/Shop";
|
import { ShopProvider } from "./components/Shop";
|
||||||
import ThemeProvider from "./components/Theme";
|
import ThemeProvider from "./components/Theme";
|
||||||
import { WindowTitle } from "./components/WindowTitle";
|
import { WindowTitle } from "./components/WindowTitle";
|
||||||
import { API_URI, APP_MOUNT_URI } from "./config";
|
import { API_URI, APP_MOUNT_URI, GTM_ID } from "./config";
|
||||||
import ConfigurationSection, { createConfigurationMenu } from "./configuration";
|
import ConfigurationSection, { createConfigurationMenu } from "./configuration";
|
||||||
import AppStateProvider from "./containers/AppState";
|
import AppStateProvider from "./containers/AppState";
|
||||||
import { CustomerSection } from "./customers";
|
import { CustomerSection } from "./customers";
|
||||||
|
@ -66,6 +67,10 @@ interface ResponseError extends ErrorResponse {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.env.GTM_ID !== undefined) {
|
||||||
|
TagManager.initialize({ gtmId: GTM_ID });
|
||||||
|
}
|
||||||
|
|
||||||
const invalidTokenLink = onError((error: ResponseError) => {
|
const invalidTokenLink = onError((error: ResponseError) => {
|
||||||
if (
|
if (
|
||||||
(error.networkError && error.networkError.statusCode === 401) ||
|
(error.networkError && error.networkError.statusCode === 401) ||
|
||||||
|
|
|
@ -10,6 +10,11 @@ export const commonMessages = defineMessages({
|
||||||
dashboard: {
|
dashboard: {
|
||||||
defaultMessage: "Dashboard"
|
defaultMessage: "Dashboard"
|
||||||
},
|
},
|
||||||
|
demo: {
|
||||||
|
defaultMessage:
|
||||||
|
"Just to let you know... You're in demo mode. You can play around with the dashboard but can't save changes.",
|
||||||
|
description: "notification message after log in"
|
||||||
|
},
|
||||||
description: {
|
description: {
|
||||||
defaultMessage: "Description"
|
defaultMessage: "Description"
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,10 +22,12 @@ const htmlWebpackPlugin = new HtmlWebpackPlugin({
|
||||||
hash: true,
|
hash: true,
|
||||||
template: "./src/index.html"
|
template: "./src/index.html"
|
||||||
});
|
});
|
||||||
const environmentPlugin = new webpack.EnvironmentPlugin([
|
const environmentPlugin = new webpack.EnvironmentPlugin({
|
||||||
"APP_MOUNT_URI",
|
API_URI: "",
|
||||||
"API_URI"
|
APP_MOUNT_URI: "/",
|
||||||
]);
|
DEMO_MODE: false,
|
||||||
|
GTM_ID: ""
|
||||||
|
});
|
||||||
|
|
||||||
const dashboardBuildPath = "build/dashboard/";
|
const dashboardBuildPath = "build/dashboard/";
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ module.exports = (env, argv) => {
|
||||||
let output;
|
let output;
|
||||||
|
|
||||||
if (!process.env.API_URI) {
|
if (!process.env.API_URI) {
|
||||||
throw new Error("Environment variable API_URI not set")
|
throw new Error("Environment variable API_URI not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!devMode) {
|
if (!devMode) {
|
||||||
|
|
Loading…
Reference in a new issue