@newskit-render/core 1.77.0 → 1.79.0-alpha.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,6 +3,22 @@
|
|
|
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
|
+
# [1.78.0](https://github.com/newscorp-ghfb/ncu-newskit-render/compare/@newskit-render/core@1.78.0-alpha.0...@newskit-render/core@1.78.0) (2022-07-22)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @newskit-render/core
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [1.77.0](https://github.com/newscorp-ghfb/ncu-newskit-render/compare/@newskit-render/core@1.77.0-alpha.0...@newskit-render/core@1.77.0) (2022-07-22)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @newskit-render/core
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [1.76.4](https://github.com/newscorp-ghfb/ncu-newskit-render/compare/@newskit-render/core@1.76.4-alpha.0...@newskit-render/core@1.76.4) (2022-07-22)
|
|
7
23
|
|
|
8
24
|
**Note:** Version bump only for package @newskit-render/core
|
package/README.md
CHANGED
|
@@ -105,3 +105,157 @@ In order to publish the contracts you need to execute:
|
|
|
105
105
|
```sh
|
|
106
106
|
npm run pact:publish
|
|
107
107
|
```
|
|
108
|
+
|
|
109
|
+
## Multi-tenant application
|
|
110
|
+
|
|
111
|
+
A multi-tenant application allows you to run an application from various (sub-)domains and show different content depending on the domain that is used.
|
|
112
|
+
|
|
113
|
+
This means that the titles would be able to load different brands' content and themes, while running the same application. The codebase will be the same across all brands.
|
|
114
|
+
|
|
115
|
+
### Getting started
|
|
116
|
+
|
|
117
|
+
How to configure your application for multitenancy
|
|
118
|
+
|
|
119
|
+
1. If you want to build a project from scratch, that will have everything from newskit-render, you need to run `create-render-app` (See [Newskit-Render Getting started](https://github.com/newscorp-ghfb/ncu-newskit-render#getting-started)).
|
|
120
|
+
|
|
121
|
+
When creating a new project a question whether you'd like your application to be multi tenant will prompt in the terminal.
|
|
122
|
+
|
|
123
|
+
2. If you already have a Next application and you want to make it multi-tenant you need to add the following files:
|
|
124
|
+
|
|
125
|
+
In config folder: `config/multiTenancy.ts`:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
import { sharedTheme, timesTheme } from '@newskit-render/shared-components'
|
|
129
|
+
import { Publisher } from '@newskit-render/api'
|
|
130
|
+
import { demoStrings, timesStrings } from '../theme/strings'
|
|
131
|
+
|
|
132
|
+
export const translationsMap = {
|
|
133
|
+
[Publisher.DEMO]: demoStrings,
|
|
134
|
+
[Publisher.TIMES]: timesStrings,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const themesMap = {
|
|
138
|
+
[Publisher.DEMO]: sharedTheme,
|
|
139
|
+
[Publisher.TIMES]: timesTheme,
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
- `translationsMap` is used for re-mapping variables like site title, or any other string for each brand. Example:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
export const demoStrings = {
|
|
149
|
+
title: 'Demo Site'
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const timesStrings = {
|
|
153
|
+
title: 'Times Site'
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
- `themesMap` is used for mapping the theme for each brand.
|
|
160
|
+
Brand names live in the `PUBLISHER` object
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
In context folder `context/multi-tenancy`
|
|
164
|
+
Add a multi-tenancy context that will keep the current tenant:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
import React, { createContext, useContext } from 'react'
|
|
168
|
+
import get from 'lodash.get'
|
|
169
|
+
import { Publisher } from '@newskit-render/api'
|
|
170
|
+
import { translationsMap } from '../../config'
|
|
171
|
+
|
|
172
|
+
export interface MultiTenancyContextProps {
|
|
173
|
+
tenant?: Publisher
|
|
174
|
+
getTenantString?: (key: string, defaultValue?: string) => string
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const MultiTenancyContext = createContext<MultiTenancyContextProps>({})
|
|
178
|
+
|
|
179
|
+
const MultiTenancyProvider: React.FC<MultiTenancyContextProps> = ({
|
|
180
|
+
tenant,
|
|
181
|
+
children,
|
|
182
|
+
}) => (
|
|
183
|
+
<MultiTenancyContext.Provider
|
|
184
|
+
value={{
|
|
185
|
+
tenant,
|
|
186
|
+
getTenantString: (key: string, defaultValue: string = ''): string => {
|
|
187
|
+
const data = translationsMap[tenant]
|
|
188
|
+
return get(data, key, defaultValue)
|
|
189
|
+
},
|
|
190
|
+
}}
|
|
191
|
+
>
|
|
192
|
+
{children}
|
|
193
|
+
</MultiTenancyContext.Provider>
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
export const useMultiTenancy = () => useContext(MultiTenancyContext)
|
|
197
|
+
export default MultiTenancyProvider
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
Now you need to update `_app.js`. To pass the tenant to the app, you need to wrap it in `MultitenancyProvide`:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
interface MyAppProps extends AppProps {
|
|
205
|
+
tenant: Publisher
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function MyApp({ Component, pageProps, tenant }: MyAppProps) {
|
|
209
|
+
return (
|
|
210
|
+
<MultiTenancyProvider tenant={tenant}>
|
|
211
|
+
<AppContextProvider>
|
|
212
|
+
………
|
|
213
|
+
</AppContextProvider>
|
|
214
|
+
</MultiTenancyProvider>
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export default MyApp
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
Then call the `getTenant()` helper function in `getInitialProps()`. This function extracts the brands' hostname ( domain name ) from the request headers and then we save the tenant in the context provider:
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
MyApp.getInitialProps = async ({ Component, ctx }: AppContextType) => {
|
|
226
|
+
let pageProps = {}
|
|
227
|
+
const tenant = getTenant(ctx.req?.headers?.host as string)
|
|
228
|
+
|
|
229
|
+
if (Component.getInitialProps) {
|
|
230
|
+
pageProps = await Component.getInitialProps(ctx)
|
|
231
|
+
}
|
|
232
|
+
return { pageProps, tenant }
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
### How to set the theme for each tenant
|
|
238
|
+
|
|
239
|
+
You can use the `useMultiTenancy` hook anywhere in the code to get the current tenant
|
|
240
|
+
|
|
241
|
+
In `context/app-context.js`:
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
const AppContext = React.createContext({
|
|
245
|
+
theme: sharedTheme,
|
|
246
|
+
} as AppContextType)
|
|
247
|
+
|
|
248
|
+
const AppContextProvider = ({ children }: { children: JSX.Element }) => {
|
|
249
|
+
const { tenant } = useMultiTenancy()
|
|
250
|
+
const tenantTheme = themesMap[tenant]
|
|
251
|
+
const [theme, setTheme] = useState(tenantTheme)
|
|
252
|
+
|
|
253
|
+
return (
|
|
254
|
+
<AppContext.Provider value={{ theme, setTheme }}>
|
|
255
|
+
{children}
|
|
256
|
+
</AppContext.Provider>
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { AppContextProvider, AppContext }
|
|
261
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const terminalLog = (violations) => {
|
|
2
|
+
cy.task(
|
|
3
|
+
'log',
|
|
4
|
+
`${violations.length} accessibility violation${
|
|
5
|
+
violations.length === 1 ? '' : 's'
|
|
6
|
+
} ${violations.length === 1 ? 'was' : 'were'} detected`
|
|
7
|
+
)
|
|
8
|
+
// pluck specific keys to keep the table readable
|
|
9
|
+
const violationData = violations.map(
|
|
10
|
+
({ id, impact, description, nodes }) => ({
|
|
11
|
+
id,
|
|
12
|
+
impact,
|
|
13
|
+
description,
|
|
14
|
+
nodes: nodes.length,
|
|
15
|
+
})
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
cy.task('table', violationData)
|
|
19
|
+
}
|
|
@@ -1,28 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
cy.task(
|
|
3
|
-
'log',
|
|
4
|
-
`${violations.length} accessibility violation${
|
|
5
|
-
violations.length === 1 ? '' : 's'
|
|
6
|
-
} ${violations.length === 1 ? 'was' : 'were'} detected`
|
|
7
|
-
)
|
|
8
|
-
// pluck specific keys to keep the table readable
|
|
9
|
-
const violationData = violations.map(
|
|
10
|
-
({ id, impact, description, nodes }) => ({
|
|
11
|
-
id,
|
|
12
|
-
impact,
|
|
13
|
-
description,
|
|
14
|
-
nodes: nodes.length,
|
|
15
|
-
})
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
cy.task('table', violationData)
|
|
19
|
-
}
|
|
1
|
+
import { terminalLog } from '../../axe/terminal-log'
|
|
20
2
|
|
|
21
3
|
const pages = [
|
|
22
|
-
{
|
|
23
|
-
url: '/account',
|
|
24
|
-
name: 'Personal Details',
|
|
25
|
-
},
|
|
4
|
+
{ url: '/account', name: 'Personal Details' },
|
|
26
5
|
{ url: '/account/edit/name', name: 'Name form' },
|
|
27
6
|
{ url: '/account/edit/displayName', name: 'Display Name form' },
|
|
28
7
|
{ url: '/account/edit/email', name: 'Email form' },
|
|
@@ -43,7 +22,8 @@ const pages = [
|
|
|
43
22
|
// {
|
|
44
23
|
// url: '/account/payment',
|
|
45
24
|
// name: 'Payment form',
|
|
46
|
-
// skip: { skipFailures: true },
|
|
25
|
+
// skip: { skipFailures: true },
|
|
26
|
+
// error being caused by Stripe, ignore at this time
|
|
47
27
|
// },
|
|
48
28
|
{
|
|
49
29
|
url: '/account/newsletters-and-alerts',
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { terminalLog } from '../../axe/terminal-log'
|
|
2
|
+
|
|
3
|
+
const pages = [
|
|
4
|
+
{ url: '/help-hub', name: 'Landing Page' },
|
|
5
|
+
{ url: '/help-hub/results?q=google', name: 'Search Page' },
|
|
6
|
+
{ url: '/help-hub/article/sign-with-google', name: 'Article Page' },
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
describe('Page accessibility', () => {
|
|
10
|
+
pages.forEach(({ url, name, skip }) => {
|
|
11
|
+
it(`Should pass a11y tests: ${name}`, () => {
|
|
12
|
+
cy.mockConsentAndVisit(url)
|
|
13
|
+
cy.injectAxe()
|
|
14
|
+
cy.checkA11y(null, null, terminalLog, skip)
|
|
15
|
+
|
|
16
|
+
cy.get('[data-testid="autocomplete-input"]').type('Google')
|
|
17
|
+
|
|
18
|
+
cy.checkA11y(null, null, terminalLog, false)
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newskit-render/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.79.0-alpha.0",
|
|
4
4
|
"description": "Newskit Render - Core package",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"@apollo/client": "3.4.16",
|
|
36
36
|
"@newskit-render/api": "^0.36.0",
|
|
37
37
|
"@newskit-render/auth": "^0.44.0",
|
|
38
|
-
"@newskit-render/checkout": "^0.51.
|
|
38
|
+
"@newskit-render/checkout": "^0.51.4-alpha.0",
|
|
39
39
|
"@newskit-render/feature-flags": "^0.24.0",
|
|
40
40
|
"@newskit-render/feed": "^0.24.0",
|
|
41
41
|
"@newskit-render/my-account": "^0.184.0",
|
|
42
42
|
"@newskit-render/shared-components": "^0.68.0",
|
|
43
|
-
"@newskit-render/standalone-components": "^0.
|
|
43
|
+
"@newskit-render/standalone-components": "^0.32.0-alpha.0",
|
|
44
44
|
"@newskit-render/validation": "^0.50.0",
|
|
45
45
|
"cross-fetch": "3.1.5",
|
|
46
46
|
"graphql": "15.6.0",
|
|
@@ -11,12 +11,12 @@ import { AppContext } from '../../context'
|
|
|
11
11
|
import { addCacheHeaders } from '../../helpers/addCacheHeaders'
|
|
12
12
|
|
|
13
13
|
const ResultsPage: React.FC<{
|
|
14
|
-
|
|
14
|
+
credentials: AlgoliaCredentials
|
|
15
15
|
hits: Hit[]
|
|
16
16
|
}> = (props) => {
|
|
17
17
|
const { theme, setTheme } = useContext(AppContext)
|
|
18
18
|
const themeDropdownObject = createThemeDropdownObject(setTheme)
|
|
19
|
-
const credentials =
|
|
19
|
+
const { credentials } = props
|
|
20
20
|
return (
|
|
21
21
|
<HelpHubResultsPage
|
|
22
22
|
{...props}
|