gatsby-theme-q3 4.5.16 → 4.5.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.eslintrc.js +12 -12
  2. package/CHANGELOG.md +1181 -1164
  3. package/LICENSE +21 -21
  4. package/__fixtures__/en/titles.json +2 -2
  5. package/__fixtures__/fr/titles.json +2 -2
  6. package/gatsby-browser.js +38 -38
  7. package/gatsby-config.js +62 -62
  8. package/gatsby-node.js +77 -77
  9. package/gatsby-ssr.js +11 -20
  10. package/index.js +1 -1
  11. package/lib/components/AccountPublicGateway.js +2 -3
  12. package/lib/components/AdminLoader.js +2 -3
  13. package/lib/components/AdminPrivateGateway.js +3 -4
  14. package/lib/components/AdminPublicGateway.js +3 -4
  15. package/lib/components/AdminRouter.js +3 -4
  16. package/lib/components/BlogArchiveTemplate.js +2 -3
  17. package/lib/components/BlogTemplate.js +2 -3
  18. package/lib/components/FormBox.js +2 -3
  19. package/lib/components/FormBoxContent.js +2 -3
  20. package/lib/components/FormBoxNotice.js +2 -3
  21. package/lib/components/IsBrowserReady.js +2 -3
  22. package/lib/components/PageWrapper.js +2 -3
  23. package/lib/components/PublicTemplate.js +2 -3
  24. package/lib/components/Redirect.js +2 -3
  25. package/lib/components/RedirectToIndex.js +2 -3
  26. package/lib/components/RichText.js +2 -3
  27. package/lib/components/SearchEngine.js +4 -7
  28. package/lib/components/ShareButton.js +2 -3
  29. package/lib/components/Wrapper.js +2 -3
  30. package/lib/components/__tests__/useSiteMetaData.test.js +44 -44
  31. package/lib/components/__tests__/withAuthenticate.test.js +2 -2
  32. package/lib/components/__tests__/withSuccessOp.test.js +4 -4
  33. package/lib/components/index.js +2 -3
  34. package/lib/components/useSiteMetaData.js +1 -1
  35. package/lib/components/utils.js +2 -3
  36. package/lib/components/withAuthenticate.js +2 -2
  37. package/lib/components/withPublicTemplate.js +2 -3
  38. package/lib/components/withSuccessOp.js +3 -4
  39. package/lib/pages/404.js +2 -3
  40. package/lib/pages/login.js +2 -3
  41. package/lib/pages/password-change.js +2 -3
  42. package/lib/pages/password-reset.js +2 -3
  43. package/lib/pages/reverify.js +2 -3
  44. package/lib/pages/verify.js +2 -3
  45. package/package.json +5 -5
  46. package/src/components/AccountPublicGateway.jsx +18 -18
  47. package/src/components/AdminLoader.jsx +16 -16
  48. package/src/components/AdminPrivateGateway.jsx +37 -37
  49. package/src/components/AdminPublicGateway.jsx +34 -34
  50. package/src/components/AdminRouter.jsx +44 -44
  51. package/src/components/BlogArchiveTemplate.jsx +55 -55
  52. package/src/components/BlogTemplate.jsx +104 -104
  53. package/src/components/FormBox.jsx +22 -22
  54. package/src/components/FormBoxContent.jsx +26 -26
  55. package/src/components/FormBoxNotice.jsx +21 -21
  56. package/src/components/IsBrowserReady.jsx +13 -13
  57. package/src/components/PageWrapper.jsx +20 -20
  58. package/src/components/PublicTemplate.jsx +198 -198
  59. package/src/components/Redirect.jsx +13 -13
  60. package/src/components/RedirectToIndex.jsx +9 -9
  61. package/src/components/RichText.jsx +196 -196
  62. package/src/components/SearchEngine.jsx +124 -124
  63. package/src/components/ShareButton.jsx +80 -80
  64. package/src/components/Wrapper.jsx +14 -14
  65. package/src/components/__tests__/SearchEngine.test.jsx +58 -58
  66. package/src/components/__tests__/useSiteMetaData.test.js +44 -44
  67. package/src/components/__tests__/withAuthenticate.test.jsx +52 -52
  68. package/src/components/__tests__/withSuccessOp.test.jsx +57 -57
  69. package/src/components/index.js +16 -16
  70. package/src/components/useSiteMetaData.js +35 -35
  71. package/src/components/utils.js +23 -23
  72. package/src/components/withAuthenticate.jsx +20 -20
  73. package/src/components/withPublicTemplate.jsx +11 -11
  74. package/src/components/withSuccessOp.jsx +43 -43
  75. package/src/pages/404.jsx +31 -31
  76. package/src/pages/login.jsx +71 -71
  77. package/src/pages/password-change.jsx +72 -72
  78. package/src/pages/password-reset.jsx +47 -47
  79. package/src/pages/reverify.jsx +72 -72
  80. package/src/pages/verify.jsx +70 -70
@@ -1,80 +1,80 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import Grid from '@material-ui/core/Grid';
4
- import { browser } from 'q3-ui-helpers';
5
- import {
6
- FacebookShareButton,
7
- LinkedinShareButton,
8
- TwitterShareButton,
9
- EmailShareButton,
10
- FacebookIcon,
11
- TwitterIcon,
12
- LinkedinIcon,
13
- EmailIcon,
14
- } from 'react-share';
15
-
16
- const EMAIL = 'Email';
17
- const FACEBOOK = 'Facebook';
18
- const LINKEDIN = 'LinkedIn';
19
- const TWITTER = 'Twitter';
20
-
21
- const { isBrowserReady } = browser;
22
-
23
- const getPlatformByName = (name) => {
24
- switch (name) {
25
- case FACEBOOK:
26
- return {
27
- Button: FacebookShareButton,
28
- Icon: FacebookIcon,
29
- };
30
- case EMAIL:
31
- return {
32
- Button: EmailShareButton,
33
- Icon: EmailIcon,
34
- };
35
- case TWITTER:
36
- return {
37
- Button: TwitterShareButton,
38
- Icon: TwitterIcon,
39
- };
40
- case LINKEDIN:
41
- return {
42
- Button: LinkedinShareButton,
43
- Icon: LinkedinIcon,
44
- };
45
- default:
46
- return {
47
- Button: () => null,
48
- Icon: () => null,
49
- };
50
- }
51
- };
52
-
53
- const ShareButton = ({ platform }) => {
54
- const [url, setUrl] = React.useState();
55
-
56
- React.useEffect(() => {
57
- if (isBrowserReady()) setUrl(window.location.href);
58
- }, []);
59
-
60
- const { Button, Icon } = getPlatformByName(platform);
61
-
62
- return url ? (
63
- <Grid item>
64
- <Button url={url} style={{ cursor: 'pointer' }}>
65
- <Icon size={32} round />
66
- </Button>
67
- </Grid>
68
- ) : null;
69
- };
70
-
71
- ShareButton.propTypes = {
72
- platform: PropTypes.oneOf([
73
- FACEBOOK,
74
- TWITTER,
75
- LINKEDIN,
76
- EMAIL,
77
- ]).isRequired,
78
- };
79
-
80
- export default ShareButton;
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import Grid from '@material-ui/core/Grid';
4
+ import { browser } from 'q3-ui-helpers';
5
+ import {
6
+ FacebookShareButton,
7
+ LinkedinShareButton,
8
+ TwitterShareButton,
9
+ EmailShareButton,
10
+ FacebookIcon,
11
+ TwitterIcon,
12
+ LinkedinIcon,
13
+ EmailIcon,
14
+ } from 'react-share';
15
+
16
+ const EMAIL = 'Email';
17
+ const FACEBOOK = 'Facebook';
18
+ const LINKEDIN = 'LinkedIn';
19
+ const TWITTER = 'Twitter';
20
+
21
+ const { isBrowserReady } = browser;
22
+
23
+ const getPlatformByName = (name) => {
24
+ switch (name) {
25
+ case FACEBOOK:
26
+ return {
27
+ Button: FacebookShareButton,
28
+ Icon: FacebookIcon,
29
+ };
30
+ case EMAIL:
31
+ return {
32
+ Button: EmailShareButton,
33
+ Icon: EmailIcon,
34
+ };
35
+ case TWITTER:
36
+ return {
37
+ Button: TwitterShareButton,
38
+ Icon: TwitterIcon,
39
+ };
40
+ case LINKEDIN:
41
+ return {
42
+ Button: LinkedinShareButton,
43
+ Icon: LinkedinIcon,
44
+ };
45
+ default:
46
+ return {
47
+ Button: () => null,
48
+ Icon: () => null,
49
+ };
50
+ }
51
+ };
52
+
53
+ const ShareButton = ({ platform }) => {
54
+ const [url, setUrl] = React.useState();
55
+
56
+ React.useEffect(() => {
57
+ if (isBrowserReady()) setUrl(window.location.href);
58
+ }, []);
59
+
60
+ const { Button, Icon } = getPlatformByName(platform);
61
+
62
+ return url ? (
63
+ <Grid item>
64
+ <Button url={url} style={{ cursor: 'pointer' }}>
65
+ <Icon size={32} round />
66
+ </Button>
67
+ </Grid>
68
+ ) : null;
69
+ };
70
+
71
+ ShareButton.propTypes = {
72
+ platform: PropTypes.oneOf([
73
+ FACEBOOK,
74
+ TWITTER,
75
+ LINKEDIN,
76
+ EMAIL,
77
+ ]).isRequired,
78
+ };
79
+
80
+ export default ShareButton;
@@ -1,14 +1,14 @@
1
- /* eslint-disable import/no-extraneous-dependencies */
2
- import React from 'react';
3
- import PropTypes from 'prop-types';
4
- import AuthProvider from 'q3-ui-permissions';
5
-
6
- const Wrapper = ({ children }) => (
7
- <AuthProvider>{children}</AuthProvider>
8
- );
9
-
10
- Wrapper.propTypes = {
11
- children: PropTypes.node.isRequired,
12
- };
13
-
14
- export default Wrapper;
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import AuthProvider from 'q3-ui-permissions';
5
+
6
+ const Wrapper = ({ children }) => (
7
+ <AuthProvider>{children}</AuthProvider>
8
+ );
9
+
10
+ Wrapper.propTypes = {
11
+ children: PropTypes.node.isRequired,
12
+ };
13
+
14
+ export default Wrapper;
@@ -1,58 +1,58 @@
1
- import {
2
- generateMetaDescriptionOptions,
3
- getStartUrl,
4
- generateIcons,
5
- generateBrand,
6
- } from '../SearchEngine';
7
-
8
- jest.mock('q3-ui-locale', () => ({
9
- browser: {
10
- isBrowserReady: jest.fn(),
11
- },
12
- }));
13
-
14
- const host = 'https://google.ca';
15
-
16
- beforeEach(() => {
17
- Object.defineProperty(window, 'location', {
18
- value: {
19
- host,
20
- },
21
- });
22
- });
23
-
24
- describe('SearchEngine', () => {
25
- it('should not render descriptions without content', () => {
26
- expect(generateMetaDescriptionOptions().length).toBe(0);
27
- });
28
-
29
- it('should render descriptions with content', () => {
30
- expect(
31
- generateMetaDescriptionOptions('foo').length,
32
- ).toBeGreaterThanOrEqual(1);
33
- });
34
-
35
- it('should return host', () => {
36
- expect(getStartUrl()).toMatch(host);
37
- });
38
-
39
- it('should render favicon', () => {
40
- expect(
41
- generateIcons({
42
- favicon: host,
43
- }),
44
- ).toHaveLength(1);
45
- });
46
-
47
- it('should not render favicon', () => {
48
- expect(
49
- generateIcons({
50
- favicon: undefined,
51
- }),
52
- ).toHaveLength(0);
53
- });
54
-
55
- it('should include template literals', () => {
56
- expect(generateBrand('3merge')).toMatch('%s | 3merge');
57
- });
58
- });
1
+ import {
2
+ generateMetaDescriptionOptions,
3
+ getStartUrl,
4
+ generateIcons,
5
+ generateBrand,
6
+ } from '../SearchEngine';
7
+
8
+ jest.mock('q3-ui-locale', () => ({
9
+ browser: {
10
+ isBrowserReady: jest.fn(),
11
+ },
12
+ }));
13
+
14
+ const host = 'https://google.ca';
15
+
16
+ beforeEach(() => {
17
+ Object.defineProperty(window, 'location', {
18
+ value: {
19
+ host,
20
+ },
21
+ });
22
+ });
23
+
24
+ describe('SearchEngine', () => {
25
+ it('should not render descriptions without content', () => {
26
+ expect(generateMetaDescriptionOptions().length).toBe(0);
27
+ });
28
+
29
+ it('should render descriptions with content', () => {
30
+ expect(
31
+ generateMetaDescriptionOptions('foo').length,
32
+ ).toBeGreaterThanOrEqual(1);
33
+ });
34
+
35
+ it('should return host', () => {
36
+ expect(getStartUrl()).toMatch(host);
37
+ });
38
+
39
+ it('should render favicon', () => {
40
+ expect(
41
+ generateIcons({
42
+ favicon: host,
43
+ }),
44
+ ).toHaveLength(1);
45
+ });
46
+
47
+ it('should not render favicon', () => {
48
+ expect(
49
+ generateIcons({
50
+ favicon: undefined,
51
+ }),
52
+ ).toHaveLength(0);
53
+ });
54
+
55
+ it('should include template literals', () => {
56
+ expect(generateBrand('3merge')).toMatch('%s | 3merge');
57
+ });
58
+ });
@@ -1,44 +1,44 @@
1
- import useSiteMetaData from '../useSiteMetaData';
2
-
3
- jest.mock('gatsby', () => ({
4
- graphql: jest.fn(),
5
- useStaticQuery: jest.fn(),
6
- }));
7
-
8
- jest.mock(
9
- 'gatsby-theme-q3-mui/src/components/useRunTime',
10
- () =>
11
- jest.fn().mockReturnValue({
12
- foo: 1,
13
- bar: null,
14
- quuz: 'string',
15
- thunk: undefined,
16
- }),
17
- );
18
-
19
- describe('useSiteMetaData', () => {
20
- it('should overwrite only the nullish and undefined', () => {
21
- expect(
22
- useSiteMetaData({
23
- foo: 2,
24
- bar: 2,
25
- quuz: 2,
26
- thunk: 2,
27
- }),
28
- ).toEqual({
29
- foo: 1,
30
- bar: 2,
31
- quuz: 'string',
32
- thunk: 2,
33
- });
34
- });
35
-
36
- it('should return without defaults', () => {
37
- expect(useSiteMetaData()).toEqual({
38
- foo: 1,
39
- bar: null,
40
- quuz: 'string',
41
- thunk: undefined,
42
- });
43
- });
44
- });
1
+ import useSiteMetaData from '../useSiteMetaData';
2
+
3
+ jest.mock('gatsby', () => ({
4
+ graphql: jest.fn(),
5
+ useStaticQuery: jest.fn(),
6
+ }));
7
+
8
+ jest.mock(
9
+ 'gatsby-theme-q3-mui/src/components/useRunTime',
10
+ () =>
11
+ jest.fn().mockReturnValue({
12
+ foo: 1,
13
+ bar: null,
14
+ quuz: 'string',
15
+ thunk: undefined,
16
+ }),
17
+ );
18
+
19
+ describe('useSiteMetaData', () => {
20
+ it('should overwrite only the nullish and undefined', () => {
21
+ expect(
22
+ useSiteMetaData({
23
+ foo: 2,
24
+ bar: 2,
25
+ quuz: 2,
26
+ thunk: 2,
27
+ }),
28
+ ).toEqual({
29
+ foo: 1,
30
+ bar: 2,
31
+ quuz: 'string',
32
+ thunk: 2,
33
+ });
34
+ });
35
+
36
+ it('should return without defaults', () => {
37
+ expect(useSiteMetaData()).toEqual({
38
+ foo: 1,
39
+ bar: null,
40
+ quuz: 'string',
41
+ thunk: undefined,
42
+ });
43
+ });
44
+ });
@@ -1,52 +1,52 @@
1
- import React from 'react';
2
- import { useLocation } from '@reach/router';
3
- import withAuthenticate from '../withAuthenticate';
4
- import { authenticate } from '../utils';
5
- import useSiteMetaData from '../useSiteMetaData';
6
-
7
- jest.mock('@reach/router', () => ({
8
- useLocation: jest.fn(),
9
- }));
10
-
11
- jest.mock('../useSiteMetaData');
12
- jest.mock('../utils', () => ({
13
- authenticate: jest.fn(),
14
- }));
15
-
16
- const runAuthenticate = () => {
17
- const Component = () => <div />;
18
- const Instance = withAuthenticate(Component);
19
-
20
- global
21
- .shallow(<Instance />)
22
- .props()
23
- .authenticate();
24
- };
25
-
26
- describe('withAuthenticate', () => {
27
- it('should redirect to default directory', () => {
28
- useSiteMetaData.mockReturnValue({
29
- appDirectory: '/app',
30
- });
31
-
32
- runAuthenticate();
33
- expect(authenticate).toHaveBeenCalledWith(
34
- undefined,
35
- '/app',
36
- );
37
- });
38
-
39
- it('should redirect to gatekeeper', () => {
40
- useLocation.mockReturnValue({
41
- state: {
42
- gatekeeper: '/app/users',
43
- },
44
- });
45
-
46
- runAuthenticate();
47
- expect(authenticate).toHaveBeenCalledWith(
48
- undefined,
49
- '/app/users',
50
- );
51
- });
52
- });
1
+ import React from 'react';
2
+ import { useLocation } from '@reach/router';
3
+ import withAuthenticate from '../withAuthenticate';
4
+ import { authenticate } from '../utils';
5
+ import useSiteMetaData from '../useSiteMetaData';
6
+
7
+ jest.mock('@reach/router', () => ({
8
+ useLocation: jest.fn(),
9
+ }));
10
+
11
+ jest.mock('../useSiteMetaData');
12
+ jest.mock('../utils', () => ({
13
+ authenticate: jest.fn(),
14
+ }));
15
+
16
+ const runAuthenticate = () => {
17
+ const Component = () => <div />;
18
+ const Instance = withAuthenticate(Component);
19
+
20
+ global
21
+ .shallow(<Instance />)
22
+ .props()
23
+ .authenticate();
24
+ };
25
+
26
+ describe('withAuthenticate', () => {
27
+ it('should redirect to default directory', () => {
28
+ useSiteMetaData.mockReturnValue({
29
+ appDirectory: '/app',
30
+ });
31
+
32
+ runAuthenticate();
33
+ expect(authenticate).toHaveBeenCalledWith(
34
+ undefined,
35
+ '/app',
36
+ );
37
+ });
38
+
39
+ it('should redirect to gatekeeper', () => {
40
+ useLocation.mockReturnValue({
41
+ state: {
42
+ gatekeeper: '/app/users',
43
+ },
44
+ });
45
+
46
+ runAuthenticate();
47
+ expect(authenticate).toHaveBeenCalledWith(
48
+ undefined,
49
+ '/app/users',
50
+ );
51
+ });
52
+ });
@@ -1,57 +1,57 @@
1
- import React from 'react';
2
- import { navigate } from 'gatsby';
3
- import FormBoxNotice from '../FormBoxNotice';
4
- import withSuccessOp from '../withSuccessOp';
5
-
6
- jest.mock('gatsby', () => ({
7
- navigate: jest.fn(),
8
- Link: () => <div />,
9
- }));
10
-
11
- const Box = () => <div />;
12
- const Component = withSuccessOp(Box, 'testing');
13
-
14
- describe('withSuccessOp', () => {
15
- it('should not render notice', () => {
16
- const el = global.shallow(
17
- <Component
18
- location={{
19
- search: '?foo=bar',
20
- }}
21
- />,
22
- );
23
-
24
- expect(el.find(FormBoxNotice).exists()).toBeFalsy();
25
- });
26
-
27
- it('should render notice with message', () => {
28
- const notice = global
29
- .shallow(
30
- <Component
31
- location={{
32
- search: '?op=success',
33
- }}
34
- />,
35
- )
36
- .find(FormBoxNotice);
37
-
38
- expect(notice.exists()).toBeTruthy();
39
- expect(notice.prop('title')).toMatch('testing');
40
- });
41
-
42
- it('should navigate', () => {
43
- global
44
- .shallow(
45
- <Component
46
- location={{
47
- pathname: 'foo',
48
- }}
49
- />,
50
- )
51
- .find(Box)
52
- .props()
53
- .onSuccess();
54
-
55
- expect(navigate).toHaveBeenCalledWith('foo?op=success');
56
- });
57
- });
1
+ import React from 'react';
2
+ import { navigate } from 'gatsby';
3
+ import FormBoxNotice from '../FormBoxNotice';
4
+ import withSuccessOp from '../withSuccessOp';
5
+
6
+ jest.mock('gatsby', () => ({
7
+ navigate: jest.fn(),
8
+ Link: () => <div />,
9
+ }));
10
+
11
+ const Box = () => <div />;
12
+ const Component = withSuccessOp(Box, 'testing');
13
+
14
+ describe('withSuccessOp', () => {
15
+ it('should not render notice', () => {
16
+ const el = global.shallow(
17
+ <Component
18
+ location={{
19
+ search: '?foo=bar',
20
+ }}
21
+ />,
22
+ );
23
+
24
+ expect(el.find(FormBoxNotice).exists()).toBeFalsy();
25
+ });
26
+
27
+ it('should render notice with message', () => {
28
+ const notice = global
29
+ .shallow(
30
+ <Component
31
+ location={{
32
+ search: '?op=success',
33
+ }}
34
+ />,
35
+ )
36
+ .find(FormBoxNotice);
37
+
38
+ expect(notice.exists()).toBeTruthy();
39
+ expect(notice.prop('title')).toMatch('testing');
40
+ });
41
+
42
+ it('should navigate', () => {
43
+ global
44
+ .shallow(
45
+ <Component
46
+ location={{
47
+ pathname: 'foo',
48
+ }}
49
+ />,
50
+ )
51
+ .find(Box)
52
+ .props()
53
+ .onSuccess();
54
+
55
+ expect(navigate).toHaveBeenCalledWith('foo?op=success');
56
+ });
57
+ });
@@ -1,16 +1,16 @@
1
- export { default as AdminLoader } from './AdminLoader';
2
- export { default as AdminPrivateGateway } from './AdminPrivateGateway';
3
- export { default as AdminPublicGateway } from './AdminPublicGateway';
4
- export { default as AdminRouter } from './AdminRouter';
5
- export { default as BlogTemplate } from './BlogTemplate';
6
- export { default as FormBox } from './FormBox';
7
- export { default as PageWrapper } from './PageWrapper';
8
- export { default as PublicTemplate } from './PublicTemplate';
9
- export { default as Redirect } from './Redirect';
10
- export { default as RedirectToIndex } from './RedirectToIndex';
11
- export {
12
- default as RichText,
13
- renderRichText,
14
- } from './RichText';
15
- export { default as SearchEngine } from './SearchEngine';
16
- export { default as Wrapper } from './Wrapper';
1
+ export { default as AdminLoader } from './AdminLoader';
2
+ export { default as AdminPrivateGateway } from './AdminPrivateGateway';
3
+ export { default as AdminPublicGateway } from './AdminPublicGateway';
4
+ export { default as AdminRouter } from './AdminRouter';
5
+ export { default as BlogTemplate } from './BlogTemplate';
6
+ export { default as FormBox } from './FormBox';
7
+ export { default as PageWrapper } from './PageWrapper';
8
+ export { default as PublicTemplate } from './PublicTemplate';
9
+ export { default as Redirect } from './Redirect';
10
+ export { default as RedirectToIndex } from './RedirectToIndex';
11
+ export {
12
+ default as RichText,
13
+ renderRichText,
14
+ } from './RichText';
15
+ export { default as SearchEngine } from './SearchEngine';
16
+ export { default as Wrapper } from './Wrapper';