gatsby-theme-q3 3.0.4 → 3.2.0

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.
package/CHANGELOG.md CHANGED
@@ -3,50 +3,86 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ## [3.0.4](https://github.com/3merge/q/compare/v3.0.3...v3.0.4) (2022-01-29)
7
-
8
- **Note:** Version bump only for package gatsby-theme-q3
9
-
10
-
11
-
12
-
13
-
14
- ## [3.0.3](https://github.com/3merge/q/compare/v3.0.2...v3.0.3) (2022-01-29)
15
-
16
-
17
- ### Bug Fixes
18
-
19
- * major release bugs ([#372](https://github.com/3merge/q/issues/372)) ([d3e0681](https://github.com/3merge/q/commit/d3e0681a8d9ce61558b3aeaabe94ce8bc326dfa7))
20
-
21
-
22
-
23
-
24
-
25
- ## [3.0.2](https://github.com/3merge/q/compare/v3.0.1...v3.0.2) (2022-01-28)
26
-
27
- **Note:** Version bump only for package gatsby-theme-q3
28
-
29
-
30
-
31
-
32
-
33
- ## [3.0.1](https://github.com/3merge/q/compare/v3.0.0...v3.0.1) (2022-01-28)
34
-
35
- **Note:** Version bump only for package gatsby-theme-q3
36
-
6
+ # [3.2.0](https://github.com/3merge/q/compare/v3.1.5...v3.2.0) (2022-02-09)
37
7
 
38
8
 
9
+ ### Features
39
10
 
40
-
41
- # [3.0.0](https://github.com/3merge/q/compare/v2.3.13...v3.0.0) (2022-01-28)
42
-
43
- **Note:** Version bump only for package gatsby-theme-q3
11
+ * text locale editor ([#377](https://github.com/3merge/q/issues/377)) ([e827875](https://github.com/3merge/q/commit/e8278757be7505554376c1d1d78d9b8900fdf35e))
44
12
 
45
13
 
46
14
 
47
15
 
48
16
 
49
17
 
18
+ ## [3.1.5](https://github.com/3merge/q/compare/v3.1.4...v3.1.5) (2022-02-01)
19
+
20
+ **Note:** Version bump only for package gatsby-theme-q3
21
+
22
+
23
+
24
+
25
+
26
+ ## [3.1.4](https://github.com/3merge/q/compare/v3.1.3...v3.1.4) (2022-02-01)
27
+
28
+ **Note:** Version bump only for package gatsby-theme-q3
29
+
30
+
31
+
32
+
33
+
34
+ # [3.1.0](https://github.com/3merge/q/compare/v3.0.4...v3.1.0) (2022-01-31)
35
+
36
+ **Note:** Version bump only for package gatsby-theme-q3
37
+
38
+
39
+
40
+
41
+
42
+ ## [3.0.4](https://github.com/3merge/q/compare/v3.0.3...v3.0.4) (2022-01-29)
43
+
44
+ **Note:** Version bump only for package gatsby-theme-q3
45
+
46
+
47
+
48
+
49
+
50
+ ## [3.0.3](https://github.com/3merge/q/compare/v3.0.2...v3.0.3) (2022-01-29)
51
+
52
+
53
+ ### Bug Fixes
54
+
55
+ * major release bugs ([#372](https://github.com/3merge/q/issues/372)) ([d3e0681](https://github.com/3merge/q/commit/d3e0681a8d9ce61558b3aeaabe94ce8bc326dfa7))
56
+
57
+
58
+
59
+
60
+
61
+ ## [3.0.2](https://github.com/3merge/q/compare/v3.0.1...v3.0.2) (2022-01-28)
62
+
63
+ **Note:** Version bump only for package gatsby-theme-q3
64
+
65
+
66
+
67
+
68
+
69
+ ## [3.0.1](https://github.com/3merge/q/compare/v3.0.0...v3.0.1) (2022-01-28)
70
+
71
+ **Note:** Version bump only for package gatsby-theme-q3
72
+
73
+
74
+
75
+
76
+
77
+ # [3.0.0](https://github.com/3merge/q/compare/v2.3.13...v3.0.0) (2022-01-28)
78
+
79
+ **Note:** Version bump only for package gatsby-theme-q3
80
+
81
+
82
+
83
+
84
+
85
+
50
86
  ## [2.3.11](https://github.com/3merge/q/compare/v2.3.10...v2.3.11) (2022-01-18)
51
87
 
52
88
  **Note:** Version bump only for package gatsby-theme-q3
@@ -2,7 +2,6 @@ import { get } from 'lodash';
2
2
  import config from '../gatsby-config';
3
3
 
4
4
  const CANONICAL = 'gatsby-plugin-canonical-urls';
5
- const MANIFEST = 'gatsby-plugin-manifest';
6
5
  const ROBOTS = 'gatsby-plugin-robots-txt';
7
6
 
8
7
  const ENV = {
@@ -29,18 +28,8 @@ const checkPlugins = (args = {}, plugin) => {
29
28
 
30
29
  describe('gatsby-config', () => {
31
30
  describe('plugins', () => {
32
- it('should error without contentful access token', () => {
33
- process.env.URL =
34
- 'https://development.netlify.3merge.com';
35
- expect(() =>
36
- config({
37
- contentfulSpaceID: '1',
38
- }),
39
- ).toThrowError();
40
- });
41
-
42
31
  it('should include conditional plugins', () =>
43
- [CANONICAL, MANIFEST].forEach((name) =>
32
+ [CANONICAL].forEach((name) =>
44
33
  checkPlugins(
45
34
  {
46
35
  brandingColor: '#FFF',
@@ -52,7 +41,7 @@ describe('gatsby-config', () => {
52
41
  ));
53
42
 
54
43
  it('should exclude conditional plugins', () =>
55
- [CANONICAL, MANIFEST].forEach((name) =>
44
+ [CANONICAL].forEach((name) =>
56
45
  checkPlugins({}, name).hasNot(),
57
46
  ));
58
47
 
package/gatsby-browser.js CHANGED
@@ -1,4 +1,28 @@
1
+ import axios from 'axios';
2
+ import { last, size } from 'lodash';
3
+ import { getDomain } from 'q3-admin';
4
+ import { browser } from 'q3-ui-helpers';
5
+
1
6
  export {
2
7
  wrapPageElement,
3
8
  wrapRootElement,
4
9
  } from './gatsby-ssr';
10
+
11
+ export const onClientEntry = async () => {
12
+ if (!browser.isBrowserReady()) return;
13
+
14
+ // set language default
15
+ axios.defaults.headers['Content-Language'] =
16
+ window.localStorage.getItem('q3-locale') || 'en';
17
+
18
+ // set tenant default
19
+ const { host } = window.location;
20
+ const parts = String(host).split('.').reverse();
21
+
22
+ if (size(parts) > 1)
23
+ axios.defaults.headers['X-Session-Tenant'] =
24
+ last(parts);
25
+
26
+ // calls Q3 API
27
+ await getDomain();
28
+ };
package/gatsby-config.js CHANGED
@@ -5,8 +5,6 @@ const genKey = (url) =>
5
5
  String(url).includes('netlify') ? 'disallow' : 'allow';
6
6
 
7
7
  module.exports = ({
8
- contentfulSpaceID,
9
- contentfulAccessToken,
10
8
  siteUrl,
11
9
  title,
12
10
  brandingColor,
@@ -52,19 +50,6 @@ module.exports = ({
52
50
  },
53
51
  ];
54
52
 
55
- if (contentfulSpaceID) {
56
- if (!contentfulAccessToken)
57
- throw new Error('Contentful access token missing');
58
-
59
- plugins.push({
60
- resolve: 'gatsby-source-contentful',
61
- options: {
62
- spaceId: contentfulSpaceID,
63
- accessToken: contentfulAccessToken,
64
- },
65
- });
66
- }
67
-
68
53
  if (netlify)
69
54
  plugins.push({
70
55
  resolve: 'gatsby-plugin-netlify',
@@ -73,20 +58,6 @@ module.exports = ({
73
58
  },
74
59
  });
75
60
 
76
- if (title && brandingColor)
77
- plugins.push({
78
- resolve: 'gatsby-plugin-manifest',
79
- options: {
80
- short_name: title,
81
- start_url: '/',
82
- background_color: '#FFF',
83
- theme_color: brandingColor,
84
- display: 'standalone',
85
- name: title,
86
- icon,
87
- },
88
- });
89
-
90
61
  if (siteUrl)
91
62
  plugins.push({
92
63
  resolve: 'gatsby-plugin-canonical-urls',
@@ -13,21 +13,13 @@ var _components = require("q3-admin/lib/components");
13
13
 
14
14
  var _SearchEngine = _interopRequireDefault(require("./SearchEngine"));
15
15
 
16
- var _useLocale = _interopRequireDefault(require("./useLocale"));
17
-
18
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
17
 
20
- // cannot conditionally call hooks otherwise
21
- const Locale = () => {
22
- (0, _useLocale.default)();
23
- return null;
24
- };
25
-
26
18
  const PageWrapper = ({
27
19
  children,
28
20
  includeLoader,
29
21
  includeLocale
30
- }) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_SearchEngine.default, null), includeLoader && /*#__PURE__*/_react.default.createElement(_components.Loader, null), includeLocale && /*#__PURE__*/_react.default.createElement(Locale, null), children);
22
+ }) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_SearchEngine.default, null), includeLoader && /*#__PURE__*/_react.default.createElement(_components.Loader, null), children);
31
23
 
32
24
  PageWrapper.defaultProps = {
33
25
  children: null,
@@ -3,18 +3,79 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.getStartUrl = exports.generateMetaTitleOptions = exports.generateMetaDescriptionOptions = exports.generateManifest = exports.generateIcons = exports.generateBrand = exports.default = exports.Manifest = void 0;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
10
+ var _lodash = require("lodash");
11
+
10
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
13
 
12
14
  var _reactHelmet = require("react-helmet");
13
15
 
16
+ var _q3UiHelpers = require("q3-ui-helpers");
17
+
14
18
  var _useSiteMetaData = _interopRequireDefault(require("./useSiteMetaData"));
15
19
 
16
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
21
 
22
+ const withContent = output => content => content && (0, _lodash.isFunction)(output) ? output(content) : [];
23
+
24
+ const getStartUrl = () => _q3UiHelpers.browser.isBrowserReady() ? (0, _lodash.get)(window, 'location.host') : '';
25
+
26
+ exports.getStartUrl = getStartUrl;
27
+ const generateMetaDescriptionOptions = withContent(content => [{
28
+ name: 'description',
29
+ content
30
+ }, {
31
+ property: 'og:description',
32
+ content
33
+ }, {
34
+ name: 'twitter:description',
35
+ content
36
+ }]);
37
+ exports.generateMetaDescriptionOptions = generateMetaDescriptionOptions;
38
+ const generateMetaTitleOptions = withContent(content => [{
39
+ property: 'og:title',
40
+ content
41
+ }, {
42
+ name: 'twitter:title',
43
+ content
44
+ }]);
45
+ exports.generateMetaTitleOptions = generateMetaTitleOptions;
46
+
47
+ const generateBrand = xs => xs ? `%s | ${xs}` : undefined;
48
+
49
+ exports.generateBrand = generateBrand;
50
+
51
+ const generateIcons = (site = {}) => site !== null && site !== void 0 && site.favicon ? [{
52
+ src: site.favicon,
53
+ sizes: '512x512',
54
+ type: 'image/png'
55
+ }] : [];
56
+
57
+ exports.generateIcons = generateIcons;
58
+
59
+ const generateManifest = (site = {}) => ({
60
+ background_color: site.color,
61
+ description: site.description,
62
+ display: 'fullscreen',
63
+ icons: generateIcons(site),
64
+ name: site.title,
65
+ start_url: getStartUrl(),
66
+ short_name: site.brand,
67
+ theme_color: site.color
68
+ });
69
+
70
+ exports.generateManifest = generateManifest;
71
+
72
+ const Manifest = props => (0, _lodash.isObject)(props) ? /*#__PURE__*/_react.default.createElement("link", {
73
+ rel: "manifest",
74
+ href: `data:application/manifest+json,${encodeURIComponent(JSON.stringify(props))}`
75
+ }) : null;
76
+
77
+ exports.Manifest = Manifest;
78
+
18
79
  const SEO = ({
19
80
  description,
20
81
  lang,
@@ -23,35 +84,24 @@ const SEO = ({
23
84
  }) => {
24
85
  const site = (0, _useSiteMetaData.default)();
25
86
  const metaDescription = description || site.description;
87
+ const metaTitle = title || site.title;
26
88
  return /*#__PURE__*/_react.default.createElement(_reactHelmet.Helmet, {
27
89
  htmlAttributes: {
28
90
  lang
29
91
  },
30
- title: title || site.title,
31
- titleTemplate: `%s | ${site.brand}`,
32
- meta: [{
33
- name: 'description',
34
- content: metaDescription
35
- }, {
36
- property: 'og:title',
37
- content: title
38
- }, {
39
- property: 'og:description',
40
- content: metaDescription
41
- }, {
92
+ title: metaTitle,
93
+ titleTemplate: generateBrand((0, _lodash.get)(site, 'brand', 'Q3')),
94
+ meta: [...generateMetaTitleOptions(metaTitle), ...generateMetaDescriptionOptions(metaDescription), {
42
95
  property: 'og:type',
43
96
  content: 'website'
44
97
  }, {
45
98
  name: 'twitter:card',
46
99
  content: 'summary'
47
- }, {
48
- name: 'twitter:title',
49
- content: title
50
- }, {
51
- name: 'twitter:description',
52
- content: metaDescription
53
100
  }].concat(meta)
54
- });
101
+ }, /*#__PURE__*/_react.default.createElement(Manifest, generateManifest(site)), /*#__PURE__*/_react.default.createElement("link", {
102
+ rel: "icon",
103
+ href: site.favicon
104
+ }));
55
105
  };
56
106
 
57
107
  SEO.defaultProps = {
@@ -13,8 +13,6 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
14
  var _q3UiPermissions = _interopRequireDefault(require("q3-ui-permissions"));
15
15
 
16
- var _LocaleBundles = _interopRequireDefault(require("./LocaleBundles"));
17
-
18
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
17
 
20
18
  /* eslint-disable import/no-extraneous-dependencies */
@@ -25,13 +23,10 @@ const setBaseUrlForRest = (baseURL = process.env.GATSBY_APP_BASE_URL || 'http://
25
23
 
26
24
  const Wrapper = ({
27
25
  baseURL,
28
- children,
29
- locale
26
+ children
30
27
  }) => {
31
28
  setBaseUrlForRest(baseURL);
32
- return /*#__PURE__*/_react.default.createElement(_LocaleBundles.default, {
33
- locale: locale
34
- }, /*#__PURE__*/_react.default.createElement(_q3UiPermissions.default, null, children));
29
+ return /*#__PURE__*/_react.default.createElement(_q3UiPermissions.default, null, children);
35
30
  };
36
31
 
37
32
  Wrapper.defaultProps = {
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ var _SearchEngine = require("../SearchEngine");
4
+
5
+ jest.mock('q3-ui-locale', () => ({
6
+ browser: {
7
+ isBrowserReady: jest.fn()
8
+ }
9
+ }));
10
+ const host = 'https://google.ca';
11
+ beforeEach(() => {
12
+ Object.defineProperty(window, 'location', {
13
+ value: {
14
+ host
15
+ }
16
+ });
17
+ });
18
+ describe('SearchEngine', () => {
19
+ it('should not render descriptions without content', () => {
20
+ expect((0, _SearchEngine.generateMetaDescriptionOptions)().length).toBe(0);
21
+ });
22
+ it('should render descriptions with content', () => {
23
+ expect((0, _SearchEngine.generateMetaDescriptionOptions)('foo').length).toBeGreaterThanOrEqual(1);
24
+ });
25
+ it('should return host', () => {
26
+ expect((0, _SearchEngine.getStartUrl)()).toMatch(host);
27
+ });
28
+ it('should render favicon', () => {
29
+ expect((0, _SearchEngine.generateIcons)({
30
+ favicon: host
31
+ })).toHaveLength(1);
32
+ });
33
+ it('should not render favicon', () => {
34
+ expect((0, _SearchEngine.generateIcons)({
35
+ favicon: undefined
36
+ })).toHaveLength(0);
37
+ });
38
+ it('should include template literals', () => {
39
+ expect((0, _SearchEngine.generateBrand)('3merge')).toMatch('%s | 3merge');
40
+ });
41
+ });
@@ -9,19 +9,20 @@ var _lodash = require("lodash");
9
9
 
10
10
  var _gatsby = require("gatsby");
11
11
 
12
- var _default = () => (0, _lodash.get)((0, _gatsby.useStaticQuery)((0, _gatsby.graphql)`
13
- query {
14
- site {
15
- siteMetadata {
16
- appDirectory
17
- brand
18
- description
19
- favicon
20
- logo
21
- title
12
+ var _useRunTime = _interopRequireDefault(require("gatsby-theme-q3-mui/src/components/useRunTime"));
13
+
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+
16
+ var _default = () => (0, _lodash.merge)((0, _lodash.get)((0, _gatsby.useStaticQuery)((0, _gatsby.graphql)`
17
+ query {
18
+ site {
19
+ siteMetadata {
20
+ appDirectory
21
+ description
22
+ title
23
+ }
22
24
  }
23
25
  }
24
- }
25
- `), 'site.siteMetadata', {});
26
+ `), 'site.siteMetadata', {}), (0, _useRunTime.default)());
26
27
 
27
28
  exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-theme-q3",
3
- "version": "3.0.4",
3
+ "version": "3.2.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {
@@ -23,24 +23,24 @@
23
23
  "gatsby-image": "^3.11.0",
24
24
  "gatsby-plugin-canonical-urls": "^4.2.0",
25
25
  "gatsby-plugin-force-trailing-slashes": "^1.0.5",
26
- "gatsby-plugin-manifest": "^4.2.0",
27
26
  "gatsby-plugin-material-ui": "^3.0.1",
28
27
  "gatsby-plugin-netlify": "^3.14.0",
29
28
  "gatsby-plugin-robots-txt": "^1.6.14",
30
29
  "gatsby-plugin-sharp": "^4.2.0",
31
30
  "gatsby-plugin-sitemap": "^5.2.0",
32
- "gatsby-source-contentful": "^7.0.0",
33
- "gatsby-theme-q3-mui": "^3.0.4",
31
+ "gatsby-theme-q3-mui": "^3.2.0",
34
32
  "gatsby-transformer-sharp": "^4.2.0",
35
33
  "lodash": "^4.17.20",
36
34
  "process": "^0.11.10",
37
35
  "prop-types": "^15.7.2",
38
- "q3-ui-locale": "^3.0.4",
36
+ "q3-ui-helpers": "^3.2.0",
37
+ "q3-ui-locale": "^3.2.0",
39
38
  "query-string": "^7.0.1",
39
+ "react-helmet": "^6.1.0",
40
40
  "react-share": "^4.3.1",
41
41
  "slugify": "^1.6.3",
42
42
  "transform-loader": "^0.2.4",
43
43
  "yarn": "^1.22.17"
44
44
  },
45
- "gitHead": "4b3ae22a26743bd8f1aae62b45d7c0823cc68ef2"
45
+ "gitHead": "e7b26a194d8779024212ba64ca440222c28d82c7"
46
46
  }
@@ -2,13 +2,6 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Loader } from 'q3-admin/lib/components';
4
4
  import SearchEngine from './SearchEngine';
5
- import useLocale from './useLocale';
6
-
7
- // cannot conditionally call hooks otherwise
8
- const Locale = () => {
9
- useLocale();
10
- return null;
11
- };
12
5
 
13
6
  const PageWrapper = ({
14
7
  children,
@@ -18,7 +11,6 @@ const PageWrapper = ({
18
11
  <>
19
12
  <SearchEngine />
20
13
  {includeLoader && <Loader />}
21
- {includeLocale && <Locale />}
22
14
  {children}
23
15
  </>
24
16
  );
@@ -1,32 +1,100 @@
1
1
  import React from 'react';
2
+ import { get, isFunction, isObject } from 'lodash';
2
3
  import PropTypes from 'prop-types';
3
4
  import { Helmet } from 'react-helmet';
5
+ import { browser } from 'q3-ui-helpers';
4
6
  import useSiteMetaData from './useSiteMetaData';
5
7
 
8
+ const withContent = (output) => (content) =>
9
+ content && isFunction(output) ? output(content) : [];
10
+
11
+ export const getStartUrl = () =>
12
+ browser.isBrowserReady()
13
+ ? get(window, 'location.host')
14
+ : '';
15
+
16
+ export const generateMetaDescriptionOptions = withContent(
17
+ (content) => [
18
+ {
19
+ name: 'description',
20
+ content,
21
+ },
22
+ {
23
+ property: 'og:description',
24
+ content,
25
+ },
26
+ {
27
+ name: 'twitter:description',
28
+ content,
29
+ },
30
+ ],
31
+ );
32
+
33
+ export const generateMetaTitleOptions = withContent(
34
+ (content) => [
35
+ {
36
+ property: 'og:title',
37
+ content,
38
+ },
39
+ {
40
+ name: 'twitter:title',
41
+ content,
42
+ },
43
+ ],
44
+ );
45
+
46
+ export const generateBrand = (xs) =>
47
+ xs ? `%s | ${xs}` : undefined;
48
+
49
+ export const generateIcons = (site = {}) =>
50
+ site?.favicon
51
+ ? [
52
+ {
53
+ src: site.favicon,
54
+ sizes: '512x512',
55
+ type: 'image/png',
56
+ },
57
+ ]
58
+ : [];
59
+
60
+ export const generateManifest = (site = {}) => ({
61
+ background_color: site.color,
62
+ description: site.description,
63
+ display: 'fullscreen',
64
+ icons: generateIcons(site),
65
+ name: site.title,
66
+ start_url: getStartUrl(),
67
+ short_name: site.brand,
68
+ theme_color: site.color,
69
+ });
70
+
71
+ export const Manifest = (props) =>
72
+ isObject(props) ? (
73
+ <link
74
+ rel="manifest"
75
+ href={`data:application/manifest+json,${encodeURIComponent(
76
+ JSON.stringify(props),
77
+ )}`}
78
+ />
79
+ ) : null;
80
+
6
81
  const SEO = ({ description, lang, meta, title }) => {
7
82
  const site = useSiteMetaData();
8
83
  const metaDescription = description || site.description;
84
+ const metaTitle = title || site.title;
9
85
 
10
86
  return (
11
87
  <Helmet
12
88
  htmlAttributes={{
13
89
  lang,
14
90
  }}
15
- title={title || site.title}
16
- titleTemplate={`%s | ${site.brand}`}
91
+ title={metaTitle}
92
+ titleTemplate={generateBrand(
93
+ get(site, 'brand', 'Q3'),
94
+ )}
17
95
  meta={[
18
- {
19
- name: 'description',
20
- content: metaDescription,
21
- },
22
- {
23
- property: 'og:title',
24
- content: title,
25
- },
26
- {
27
- property: 'og:description',
28
- content: metaDescription,
29
- },
96
+ ...generateMetaTitleOptions(metaTitle),
97
+ ...generateMetaDescriptionOptions(metaDescription),
30
98
  {
31
99
  property: 'og:type',
32
100
  content: 'website',
@@ -35,16 +103,11 @@ const SEO = ({ description, lang, meta, title }) => {
35
103
  name: 'twitter:card',
36
104
  content: 'summary',
37
105
  },
38
- {
39
- name: 'twitter:title',
40
- content: title,
41
- },
42
- {
43
- name: 'twitter:description',
44
- content: metaDescription,
45
- },
46
106
  ].concat(meta)}
47
- />
107
+ >
108
+ <Manifest {...generateManifest(site)} />
109
+ <link rel="icon" href={site.favicon} />
110
+ </Helmet>
48
111
  );
49
112
  };
50
113
 
@@ -3,7 +3,6 @@ import React from 'react';
3
3
  import axios from 'axios';
4
4
  import PropTypes from 'prop-types';
5
5
  import AuthProvider from 'q3-ui-permissions';
6
- import LocaleBundles from './LocaleBundles';
7
6
 
8
7
  const setBaseUrlForRest = (
9
8
  baseURL = process.env.GATSBY_APP_BASE_URL ||
@@ -13,14 +12,9 @@ const setBaseUrlForRest = (
13
12
  return axios.defaults;
14
13
  };
15
14
 
16
- const Wrapper = ({ baseURL, children, locale }) => {
15
+ const Wrapper = ({ baseURL, children }) => {
17
16
  setBaseUrlForRest(baseURL);
18
-
19
- return (
20
- <LocaleBundles locale={locale}>
21
- <AuthProvider>{children}</AuthProvider>
22
- </LocaleBundles>
23
- );
17
+ return <AuthProvider>{children}</AuthProvider>;
24
18
  };
25
19
 
26
20
  Wrapper.defaultProps = {
@@ -0,0 +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,22 +1,23 @@
1
- import { get } from 'lodash';
1
+ import { get, merge } from 'lodash';
2
2
  import { useStaticQuery, graphql } from 'gatsby';
3
+ import useRunTime from 'gatsby-theme-q3-mui/src/components/useRunTime';
3
4
 
4
5
  export default () =>
5
- get(
6
- useStaticQuery(graphql`
7
- query {
8
- site {
9
- siteMetadata {
10
- appDirectory
11
- brand
12
- description
13
- favicon
14
- logo
15
- title
6
+ merge(
7
+ get(
8
+ useStaticQuery(graphql`
9
+ query {
10
+ site {
11
+ siteMetadata {
12
+ appDirectory
13
+ description
14
+ title
15
+ }
16
16
  }
17
17
  }
18
- }
19
- `),
20
- 'site.siteMetadata',
21
- {},
18
+ `),
19
+ 'site.siteMetadata',
20
+ {},
21
+ ),
22
+ useRunTime(),
22
23
  );
@@ -1,42 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _q3UiLocale = require("q3-ui-locale");
9
-
10
- var _propTypes = _interopRequireDefault(require("prop-types"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
- const registeri18ResourceBundles = contentData => {
15
- if (!contentData || !('en' in contentData)) return;
16
- Object.entries(contentData).forEach(([key, bundle]) => {
17
- Object.entries(bundle).forEach(([namespace, data]) => {
18
- _q3UiLocale.i18n.addResourceBundle(key, namespace, data, true, true);
19
- });
20
- });
21
- };
22
-
23
- const LocaleBundles = ({
24
- children,
25
- locale
26
- }) => {
27
- registeri18ResourceBundles(locale);
28
- return children;
29
- };
30
-
31
- LocaleBundles.defaultProps = {
32
- children: null,
33
- locale: {}
34
- };
35
- LocaleBundles.propTypes = {
36
- // eslint-disable-next-line
37
- children: _propTypes.default.any,
38
- // eslint-disable-next-line
39
- locale: _propTypes.default.object
40
- };
41
- var _default = LocaleBundles;
42
- exports.default = _default;
@@ -1,31 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _react = _interopRequireDefault(require("react"));
9
-
10
- var _q3UiLocale = require("q3-ui-locale");
11
-
12
- var _q3UiPermissions = require("q3-ui-permissions");
13
-
14
- var _q3UiRest = require("q3-ui-rest");
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- const useLocale = () => {
19
- var _React$useContext, _React$useContext$sta;
20
-
21
- const profile = (_React$useContext = _react.default.useContext(_q3UiPermissions.AuthContext)) === null || _React$useContext === void 0 ? void 0 : (_React$useContext$sta = _React$useContext.state) === null || _React$useContext$sta === void 0 ? void 0 : _React$useContext$sta.profile;
22
- const lng = profile === null || profile === void 0 ? void 0 : profile.lang;
23
- (0, _q3UiRest.useTimezoneInterceptor)(profile === null || profile === void 0 ? void 0 : profile.timezone);
24
-
25
- _react.default.useEffect(() => {
26
- if (lng && _q3UiLocale.i18n.resolvedLanguage) _q3UiLocale.i18n.changeLanguage(lng);
27
- }, [lng]);
28
- };
29
-
30
- var _default = useLocale;
31
- exports.default = _default;
@@ -1,37 +0,0 @@
1
- import { i18n } from 'q3-ui-locale';
2
- import PropTypes from 'prop-types';
3
-
4
- const registeri18ResourceBundles = (contentData) => {
5
- if (!contentData || !('en' in contentData)) return;
6
-
7
- Object.entries(contentData).forEach(([key, bundle]) => {
8
- Object.entries(bundle).forEach(([namespace, data]) => {
9
- i18n.addResourceBundle(
10
- key,
11
- namespace,
12
- data,
13
- true,
14
- true,
15
- );
16
- });
17
- });
18
- };
19
-
20
- const LocaleBundles = ({ children, locale }) => {
21
- registeri18ResourceBundles(locale);
22
- return children;
23
- };
24
-
25
- LocaleBundles.defaultProps = {
26
- children: null,
27
- locale: {},
28
- };
29
-
30
- LocaleBundles.propTypes = {
31
- // eslint-disable-next-line
32
- children: PropTypes.any,
33
- // eslint-disable-next-line
34
- locale: PropTypes.object,
35
- };
36
-
37
- export default LocaleBundles;
@@ -1,20 +0,0 @@
1
- import React from 'react';
2
- import { i18n } from 'q3-ui-locale';
3
- import { AuthContext } from 'q3-ui-permissions';
4
- import { useTimezoneInterceptor } from 'q3-ui-rest';
5
-
6
- const useLocale = () => {
7
- const profile =
8
- React.useContext(AuthContext)?.state?.profile;
9
-
10
- const lng = profile?.lang;
11
-
12
- useTimezoneInterceptor(profile?.timezone);
13
-
14
- React.useEffect(() => {
15
- if (lng && i18n.resolvedLanguage)
16
- i18n.changeLanguage(lng);
17
- }, [lng]);
18
- };
19
-
20
- export default useLocale;