@defra/lis-infra-ui-services 0.22.0 → 0.23.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/package.json +1 -2
- package/src/components/autocomplete.scss +3 -3
- package/src/components/search-form.scss +11 -9
- package/src/components/sortable-paginated-table.scss +9 -9
- package/src/components/sub-navigation.scss +14 -14
- package/src/nunjucks/context.js +3 -3
- package/src/nunjucks/context.test.js +0 -22
- package/src/nunjucks/plugin.js +0 -11
- package/src/nunjucks/plugin.test.js +1 -24
- package/src/navigation.js +0 -1
- package/src/nunjucks/build-navigation.js +0 -61
- package/src/nunjucks/build-navigation.test.js +0 -62
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra/lis-infra-ui-services",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "UI-Services shared definitions for the livestock taxonomy topology.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"./duration": "./src/duration.js",
|
|
20
20
|
"./errors": "./src/errors/index.js",
|
|
21
21
|
"./maintenance": "./src/maintenance.js",
|
|
22
|
-
"./navigation": "./src/navigation.js",
|
|
23
22
|
"./nunjucks/build-navigation": "./src/nunjucks/build-navigation.js",
|
|
24
23
|
"./nunjucks/context": "./src/nunjucks/context.js",
|
|
25
24
|
"./nunjucks/filters": "./src/nunjucks/filters.js",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
@use
|
|
2
|
-
@use
|
|
1
|
+
@use 'accessible-autocomplete/dist/accessible-autocomplete.min.css';
|
|
2
|
+
@use 'govuk-frontend' as *;
|
|
3
3
|
|
|
4
4
|
.app-autocomplete .autocomplete__input.govuk-input--error,
|
|
5
5
|
.app-autocomplete .autocomplete__hint.govuk-input--error {
|
|
6
|
-
border-color: govuk-functional-colour(
|
|
6
|
+
border-color: govuk-functional-colour('error');
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Modelled on govuk_publishing_components' gem-c-search (large, on-white
|
|
2
2
|
// variant): https://github.com/alphagov/govuk_publishing_components
|
|
3
|
-
@use
|
|
3
|
+
@use 'govuk-frontend' as *;
|
|
4
4
|
|
|
5
5
|
$lis-search-form-input-size: 50px;
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ $lis-search-form-input-size: 50px;
|
|
|
11
11
|
.lis-search-form__wrapper {
|
|
12
12
|
display: table;
|
|
13
13
|
width: 100%;
|
|
14
|
-
background: govuk-colour(
|
|
14
|
+
background: govuk-colour('white');
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.lis-search-form__input {
|
|
@@ -22,12 +22,13 @@ $lis-search-form-input-size: 50px;
|
|
|
22
22
|
height: $lis-search-form-input-size;
|
|
23
23
|
margin: 0;
|
|
24
24
|
padding: govuk-em(6, 19);
|
|
25
|
-
border: $govuk-border-width-form-element solid
|
|
25
|
+
border: $govuk-border-width-form-element solid
|
|
26
|
+
govuk-functional-colour('input-border');
|
|
26
27
|
border-right-width: 0;
|
|
27
28
|
@include govuk-font($size: 19);
|
|
28
29
|
|
|
29
30
|
&:focus {
|
|
30
|
-
outline: $govuk-focus-width solid govuk-functional-colour(
|
|
31
|
+
outline: $govuk-focus-width solid govuk-functional-colour('focus');
|
|
31
32
|
outline-offset: 0;
|
|
32
33
|
box-shadow: inset 0 0 0 $govuk-border-width-form-element;
|
|
33
34
|
border-right-width: $govuk-border-width-form-element;
|
|
@@ -48,20 +49,21 @@ $lis-search-form-input-size: 50px;
|
|
|
48
49
|
padding: 0;
|
|
49
50
|
border: 0;
|
|
50
51
|
border-radius: 0;
|
|
51
|
-
background-color: govuk-colour(
|
|
52
|
-
color: govuk-colour(
|
|
52
|
+
background-color: govuk-colour('blue');
|
|
53
|
+
color: govuk-colour('white');
|
|
53
54
|
text-indent: -5000px;
|
|
54
55
|
overflow: hidden;
|
|
55
56
|
cursor: pointer;
|
|
56
57
|
|
|
57
58
|
&:hover {
|
|
58
|
-
background-color: govuk-colour(
|
|
59
|
+
background-color: govuk-colour('blue', $variant: 'shade-25');
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
&:focus {
|
|
62
|
-
outline: $govuk-focus-width solid govuk-functional-colour(
|
|
63
|
+
outline: $govuk-focus-width solid govuk-functional-colour('focus');
|
|
63
64
|
outline-offset: 0;
|
|
64
|
-
box-shadow: inset 0 0 0 ($govuk-border-width-form-element * 2)
|
|
65
|
+
box-shadow: inset 0 0 0 ($govuk-border-width-form-element * 2)
|
|
66
|
+
govuk-colour('black');
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
@use
|
|
1
|
+
@use 'govuk-frontend' as *;
|
|
2
2
|
|
|
3
3
|
.lis-sortable-table__link {
|
|
4
4
|
display: inline-flex;
|
|
5
5
|
align-items: center;
|
|
6
|
-
color: govuk-functional-colour(
|
|
6
|
+
color: govuk-functional-colour('brand');
|
|
7
7
|
text-decoration: none;
|
|
8
8
|
|
|
9
9
|
&:visited,
|
|
10
10
|
&:hover {
|
|
11
|
-
color: govuk-functional-colour(
|
|
11
|
+
color: govuk-functional-colour('brand');
|
|
12
12
|
text-decoration: none;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
&:focus {
|
|
16
16
|
outline: none;
|
|
17
|
-
color: govuk-functional-colour(
|
|
18
|
-
background-color: govuk-functional-colour(
|
|
17
|
+
color: govuk-functional-colour('focus-text');
|
|
18
|
+
background-color: govuk-functional-colour('focus');
|
|
19
19
|
box-shadow:
|
|
20
|
-
0 -2px govuk-functional-colour(
|
|
21
|
-
0 4px govuk-functional-colour(
|
|
20
|
+
0 -2px govuk-functional-colour('focus'),
|
|
21
|
+
0 4px govuk-functional-colour('focus-text');
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
// The GOV.UK non-text focus state - yellow alone has too little contrast
|
|
38
38
|
// against a white page. Both rings sit outside the box, clear of the text.
|
|
39
39
|
&:focus {
|
|
40
|
-
outline: $govuk-focus-width solid govuk-functional-colour(
|
|
40
|
+
outline: $govuk-focus-width solid govuk-functional-colour('focus');
|
|
41
41
|
outline-offset: $govuk-focus-width;
|
|
42
|
-
box-shadow: 0 0 0 $govuk-focus-width govuk-functional-colour(
|
|
42
|
+
box-shadow: 0 0 0 $govuk-focus-width govuk-functional-colour('focus-text');
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// A header never wraps - on a narrow screen the table scrolls inside the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@use
|
|
1
|
+
@use 'govuk-frontend' as *;
|
|
2
2
|
|
|
3
3
|
.lis-sub-navigation {
|
|
4
4
|
margin-bottom: govuk-spacing(6);
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
@include govuk-media-query($from: tablet) {
|
|
14
14
|
width: 100%;
|
|
15
|
-
box-shadow: inset 0 -1px 0 govuk-functional-colour(
|
|
15
|
+
box-shadow: inset 0 -1px 0 govuk-functional-colour('border');
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.lis-sub-navigation__item {
|
|
20
20
|
display: block;
|
|
21
21
|
margin-top: -1px;
|
|
22
|
-
box-shadow: inset 0 -1px 0 govuk-functional-colour(
|
|
22
|
+
box-shadow: inset 0 -1px 0 govuk-functional-colour('border');
|
|
23
23
|
@include govuk-font-size(19);
|
|
24
24
|
|
|
25
25
|
&:last-child {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
display: block;
|
|
39
39
|
position: relative;
|
|
40
40
|
padding: 12px 0 12px govuk-spacing(3);
|
|
41
|
-
color: govuk-functional-colour(
|
|
41
|
+
color: govuk-functional-colour('link');
|
|
42
42
|
text-decoration: none;
|
|
43
43
|
|
|
44
44
|
@include govuk-media-query($from: tablet) {
|
|
@@ -46,37 +46,37 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
&:visited {
|
|
49
|
-
color: govuk-functional-colour(
|
|
49
|
+
color: govuk-functional-colour('link');
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
&:hover {
|
|
53
|
-
color: govuk-functional-colour(
|
|
53
|
+
color: govuk-functional-colour('link-hover');
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
&:focus {
|
|
57
|
-
color: govuk-functional-colour(
|
|
58
|
-
background-color: govuk-functional-colour(
|
|
57
|
+
color: govuk-functional-colour('focus-text');
|
|
58
|
+
background-color: govuk-functional-colour('focus');
|
|
59
59
|
box-shadow:
|
|
60
|
-
0 -2px govuk-functional-colour(
|
|
61
|
-
0 4px govuk-functional-colour(
|
|
60
|
+
0 -2px govuk-functional-colour('focus'),
|
|
61
|
+
0 4px govuk-functional-colour('focus-text');
|
|
62
62
|
text-decoration: none;
|
|
63
63
|
outline: none;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
&[aria-current=
|
|
66
|
+
&[aria-current='page'] {
|
|
67
67
|
position: relative;
|
|
68
|
-
color: govuk-functional-colour(
|
|
68
|
+
color: govuk-functional-colour('link-active');
|
|
69
69
|
text-decoration: none;
|
|
70
70
|
|
|
71
71
|
&::before {
|
|
72
|
-
content:
|
|
72
|
+
content: '';
|
|
73
73
|
display: block;
|
|
74
74
|
position: absolute;
|
|
75
75
|
bottom: 0;
|
|
76
76
|
left: 0;
|
|
77
77
|
width: 5px;
|
|
78
78
|
height: 100%;
|
|
79
|
-
background-color: govuk-functional-colour(
|
|
79
|
+
background-color: govuk-functional-colour('link');
|
|
80
80
|
|
|
81
81
|
@include govuk-media-query($from: tablet) {
|
|
82
82
|
width: 100%;
|
package/src/nunjucks/context.js
CHANGED
|
@@ -57,12 +57,11 @@ function createPermissionCheck(request) {
|
|
|
57
57
|
*/
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
|
-
* @param {{ config: object,
|
|
60
|
+
* @param {{ config: object, getRequestBasePath: Function, logger: object, readFileSync: Function, moduleId?: string, errorPages?: ErrorPageLinks }} options
|
|
61
61
|
* @returns {Function}
|
|
62
62
|
*/
|
|
63
63
|
export function createNunjucksContextBuilder({
|
|
64
64
|
config,
|
|
65
|
-
buildNavigation,
|
|
66
65
|
getRequestBasePath,
|
|
67
66
|
logger,
|
|
68
67
|
readFileSync,
|
|
@@ -106,7 +105,8 @@ export function createNunjucksContextBuilder({
|
|
|
106
105
|
sectionName,
|
|
107
106
|
serviceUrl: '/',
|
|
108
107
|
breadcrumbs: [],
|
|
109
|
-
navigation:
|
|
108
|
+
// No primary navigation links for now: only the service name and Sign out.
|
|
109
|
+
navigation: [],
|
|
110
110
|
isSignedIn: Boolean(request?.auth?.credentials?.user),
|
|
111
111
|
isFrontOffice: requestHubId === 'front-office',
|
|
112
112
|
isBackOffice: requestHubId === 'back-office',
|
|
@@ -23,7 +23,6 @@ test('createNunjucksContextBuilder resolves built asset paths from the Vite mani
|
|
|
23
23
|
const loggerMessages = []
|
|
24
24
|
const contextBuilder = createNunjucksContextBuilder({
|
|
25
25
|
config: createConfig(),
|
|
26
|
-
buildNavigation: () => [],
|
|
27
26
|
getRequestBasePath: () => '',
|
|
28
27
|
logger: {
|
|
29
28
|
error(loggedError, message) {
|
|
@@ -52,7 +51,6 @@ test('createNunjucksContextBuilder falls back to the source asset path without l
|
|
|
52
51
|
const loggerMessages = []
|
|
53
52
|
const contextBuilder = createNunjucksContextBuilder({
|
|
54
53
|
config: createConfig(),
|
|
55
|
-
buildNavigation: () => [],
|
|
56
54
|
getRequestBasePath: () => '',
|
|
57
55
|
logger: {
|
|
58
56
|
error(loggedError, message) {
|
|
@@ -77,7 +75,6 @@ test('createNunjucksContextBuilder resolves sectionName from the module registry
|
|
|
77
75
|
const loggerMessages = []
|
|
78
76
|
const contextBuilder = createNunjucksContextBuilder({
|
|
79
77
|
config: createConfig(),
|
|
80
|
-
buildNavigation: () => [],
|
|
81
78
|
getRequestBasePath: () => '',
|
|
82
79
|
logger: {
|
|
83
80
|
error(loggedError, message) {
|
|
@@ -98,7 +95,6 @@ test('createNunjucksContextBuilder leaves sectionName null when no moduleId is g
|
|
|
98
95
|
const loggerMessages = []
|
|
99
96
|
const contextBuilder = createNunjucksContextBuilder({
|
|
100
97
|
config: createConfig(),
|
|
101
|
-
buildNavigation: () => [],
|
|
102
98
|
getRequestBasePath: () => '',
|
|
103
99
|
logger: {
|
|
104
100
|
error(loggedError, message) {
|
|
@@ -118,7 +114,6 @@ test('createNunjucksContextBuilder logs once when the Vite manifest is unavailab
|
|
|
118
114
|
const loggerMessages = []
|
|
119
115
|
const contextBuilder = createNunjucksContextBuilder({
|
|
120
116
|
config: createConfig({ isProduction: true }),
|
|
121
|
-
buildNavigation: () => [],
|
|
122
117
|
getRequestBasePath: () => '',
|
|
123
118
|
logger: {
|
|
124
119
|
error(loggedError, message) {
|
|
@@ -143,7 +138,6 @@ test('createNunjucksContextBuilder always sets serviceUrl to the hub root even w
|
|
|
143
138
|
const loggerMessages = []
|
|
144
139
|
const contextBuilder = createNunjucksContextBuilder({
|
|
145
140
|
config: createConfig(),
|
|
146
|
-
buildNavigation: () => [],
|
|
147
141
|
getRequestBasePath: () => '/cattle/register',
|
|
148
142
|
logger: {
|
|
149
143
|
error(loggedError, message) {
|
|
@@ -169,7 +163,6 @@ test('createNunjucksContextBuilder always sets serviceUrl to the hub root even w
|
|
|
169
163
|
function createSignedInContextBuilder() {
|
|
170
164
|
return createNunjucksContextBuilder({
|
|
171
165
|
config: createConfig(),
|
|
172
|
-
buildNavigation: () => [],
|
|
173
166
|
getRequestBasePath: () => '',
|
|
174
167
|
logger: { error: () => undefined },
|
|
175
168
|
readFileSync: () => '{}'
|
|
@@ -213,7 +206,6 @@ describe('createNunjucksContextBuilder() hub flags', () => {
|
|
|
213
206
|
// Arrange
|
|
214
207
|
const contextBuilder = createNunjucksContextBuilder({
|
|
215
208
|
config: createConfig(),
|
|
216
|
-
buildNavigation: () => [],
|
|
217
209
|
getRequestBasePath: () => '',
|
|
218
210
|
logger: {},
|
|
219
211
|
readFileSync: () => '{}',
|
|
@@ -237,7 +229,6 @@ describe('createNunjucksContextBuilder() hub flags', () => {
|
|
|
237
229
|
// Arrange
|
|
238
230
|
const contextBuilder = createNunjucksContextBuilder({
|
|
239
231
|
config: createConfig(),
|
|
240
|
-
buildNavigation: () => [],
|
|
241
232
|
getRequestBasePath: () => '',
|
|
242
233
|
logger: {},
|
|
243
234
|
readFileSync: () => '{}',
|
|
@@ -261,7 +252,6 @@ describe('createNunjucksContextBuilder() hub flags', () => {
|
|
|
261
252
|
// Arrange
|
|
262
253
|
const contextBuilder = createNunjucksContextBuilder({
|
|
263
254
|
config: createConfig(),
|
|
264
|
-
buildNavigation: () => [],
|
|
265
255
|
getRequestBasePath: () => '',
|
|
266
256
|
logger: {},
|
|
267
257
|
readFileSync: () => '{}',
|
|
@@ -281,7 +271,6 @@ describe('createNunjucksContextBuilder() hub flags', () => {
|
|
|
281
271
|
// Arrange
|
|
282
272
|
const contextBuilder = createNunjucksContextBuilder({
|
|
283
273
|
config: createConfig(),
|
|
284
|
-
buildNavigation: () => [],
|
|
285
274
|
getRequestBasePath: () => '',
|
|
286
275
|
logger: {},
|
|
287
276
|
readFileSync: () => '{}',
|
|
@@ -307,7 +296,6 @@ describe('createNunjucksContextBuilder() errorPages', () => {
|
|
|
307
296
|
// Arrange
|
|
308
297
|
const contextBuilder = createNunjucksContextBuilder({
|
|
309
298
|
config: createConfig(),
|
|
310
|
-
buildNavigation: () => [],
|
|
311
299
|
getRequestBasePath: () => '',
|
|
312
300
|
logger: {},
|
|
313
301
|
readFileSync: () => '{}'
|
|
@@ -330,7 +318,6 @@ describe('createNunjucksContextBuilder() errorPages', () => {
|
|
|
330
318
|
// Arrange
|
|
331
319
|
const contextBuilder = createNunjucksContextBuilder({
|
|
332
320
|
config: createConfig(),
|
|
333
|
-
buildNavigation: () => [],
|
|
334
321
|
getRequestBasePath: () => '',
|
|
335
322
|
logger: {},
|
|
336
323
|
readFileSync: () => '{}',
|
|
@@ -357,7 +344,6 @@ describe('createNunjucksContextBuilder() errorPages', () => {
|
|
|
357
344
|
// Arrange
|
|
358
345
|
const contextBuilder = createNunjucksContextBuilder({
|
|
359
346
|
config: createConfig(),
|
|
360
|
-
buildNavigation: () => [],
|
|
361
347
|
getRequestBasePath: () => '',
|
|
362
348
|
logger: {},
|
|
363
349
|
readFileSync: () => '{}',
|
|
@@ -383,7 +369,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
383
369
|
// Arrange
|
|
384
370
|
const contextBuilder = createNunjucksContextBuilder({
|
|
385
371
|
config: createConfig(),
|
|
386
|
-
buildNavigation: () => [],
|
|
387
372
|
getRequestBasePath: () => '',
|
|
388
373
|
logger: {},
|
|
389
374
|
readFileSync: () => '{}'
|
|
@@ -413,7 +398,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
413
398
|
// Arrange
|
|
414
399
|
const contextBuilder = createNunjucksContextBuilder({
|
|
415
400
|
config: createConfig(),
|
|
416
|
-
buildNavigation: () => [],
|
|
417
401
|
getRequestBasePath: () => '',
|
|
418
402
|
logger: {},
|
|
419
403
|
readFileSync: () => '{}'
|
|
@@ -443,7 +427,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
443
427
|
// Arrange
|
|
444
428
|
const contextBuilder = createNunjucksContextBuilder({
|
|
445
429
|
config: createConfig(),
|
|
446
|
-
buildNavigation: () => [],
|
|
447
430
|
getRequestBasePath: () => '',
|
|
448
431
|
logger: {},
|
|
449
432
|
readFileSync: () => '{}'
|
|
@@ -473,7 +456,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
473
456
|
// Arrange
|
|
474
457
|
const contextBuilder = createNunjucksContextBuilder({
|
|
475
458
|
config: createConfig(),
|
|
476
|
-
buildNavigation: () => [],
|
|
477
459
|
getRequestBasePath: () => '',
|
|
478
460
|
logger: {},
|
|
479
461
|
readFileSync: () => '{}'
|
|
@@ -503,7 +485,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
503
485
|
// Arrange
|
|
504
486
|
const contextBuilder = createNunjucksContextBuilder({
|
|
505
487
|
config: createConfig(),
|
|
506
|
-
buildNavigation: () => [],
|
|
507
488
|
getRequestBasePath: () => '',
|
|
508
489
|
logger: {},
|
|
509
490
|
readFileSync: () => '{}'
|
|
@@ -524,7 +505,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
524
505
|
// Arrange
|
|
525
506
|
const contextBuilder = createNunjucksContextBuilder({
|
|
526
507
|
config: createConfig(),
|
|
527
|
-
buildNavigation: () => [],
|
|
528
508
|
getRequestBasePath: () => '',
|
|
529
509
|
logger: {},
|
|
530
510
|
readFileSync: () => '{}'
|
|
@@ -553,7 +533,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
553
533
|
// Arrange
|
|
554
534
|
const contextBuilder = createNunjucksContextBuilder({
|
|
555
535
|
config: createConfig(),
|
|
556
|
-
buildNavigation: () => [],
|
|
557
536
|
getRequestBasePath: () => '',
|
|
558
537
|
logger: {},
|
|
559
538
|
readFileSync: () => '{}'
|
|
@@ -580,7 +559,6 @@ describe('createNunjucksContextBuilder() hasPermission()', () => {
|
|
|
580
559
|
// Arrange
|
|
581
560
|
const contextBuilder = createNunjucksContextBuilder({
|
|
582
561
|
config: createConfig(),
|
|
583
|
-
buildNavigation: () => [],
|
|
584
562
|
getRequestBasePath: () => '',
|
|
585
563
|
logger: {},
|
|
586
564
|
readFileSync: () => '{}'
|
package/src/nunjucks/plugin.js
CHANGED
|
@@ -5,10 +5,7 @@ import hapiVision from '@hapi/vision'
|
|
|
5
5
|
import { createRequire } from 'node:module'
|
|
6
6
|
import { fileURLToPath } from 'node:url'
|
|
7
7
|
|
|
8
|
-
import { getBasePathForModule } from '@defra/lis-hubs-infra-registry'
|
|
9
|
-
|
|
10
8
|
import { createNunjucksContextBuilder } from './context.js'
|
|
11
|
-
import { buildPrimaryNavigation } from './build-navigation.js'
|
|
12
9
|
import * as filters from './filters.js'
|
|
13
10
|
import * as globals from './globals.js'
|
|
14
11
|
|
|
@@ -168,7 +165,6 @@ export function createNunjucksConfig({
|
|
|
168
165
|
moduleId,
|
|
169
166
|
errorPages
|
|
170
167
|
}) {
|
|
171
|
-
const basePath = moduleId ? getBasePathForModule(moduleId) : ''
|
|
172
168
|
const projectRoot = config.get('root')
|
|
173
169
|
const infrastructureRoot = path.resolve(
|
|
174
170
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
@@ -185,15 +181,8 @@ export function createNunjucksConfig({
|
|
|
185
181
|
govukFrontendRoot
|
|
186
182
|
})
|
|
187
183
|
|
|
188
|
-
const buildNavigation = (request) =>
|
|
189
|
-
buildPrimaryNavigation({
|
|
190
|
-
request,
|
|
191
|
-
basePath
|
|
192
|
-
})
|
|
193
|
-
|
|
194
184
|
const context = createNunjucksContextBuilder({
|
|
195
185
|
config,
|
|
196
|
-
buildNavigation,
|
|
197
186
|
getRequestBasePath,
|
|
198
187
|
logger,
|
|
199
188
|
readFileSync,
|
|
@@ -4,15 +4,12 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
|
4
4
|
import { tmpdir } from 'node:os'
|
|
5
5
|
import path from 'node:path'
|
|
6
6
|
import nunjucks from 'nunjucks'
|
|
7
|
-
import { getBasePathForModule } from '@defra/lis-hubs-infra-registry'
|
|
8
7
|
import { createNunjucksConfig } from './plugin.js'
|
|
9
8
|
|
|
10
9
|
vi.mock('nunjucks')
|
|
11
|
-
vi.mock('@defra/lis-hubs-infra-registry')
|
|
12
10
|
|
|
13
11
|
const mocks = {
|
|
14
|
-
nunjucksConfigure: vi.mocked(nunjucks.configure)
|
|
15
|
-
getBasePathForModule: vi.mocked(getBasePathForModule)
|
|
12
|
+
nunjucksConfigure: vi.mocked(nunjucks.configure)
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
function createProjectRoot() {
|
|
@@ -49,25 +46,6 @@ describe('createNunjucksConfig()', () => {
|
|
|
49
46
|
rmSync(projectRoot, { recursive: true, force: true })
|
|
50
47
|
})
|
|
51
48
|
|
|
52
|
-
test('resolves the base path from the module registry when moduleId is given', () => {
|
|
53
|
-
// Arrange
|
|
54
|
-
mocks.getBasePathForModule.mockReturnValue('/cattle/register')
|
|
55
|
-
const config = {
|
|
56
|
-
get: vi.fn((key) => (key === 'root' ? projectRoot : false))
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Act
|
|
60
|
-
createNunjucksConfig({
|
|
61
|
-
config,
|
|
62
|
-
logger: {},
|
|
63
|
-
getRequestBasePath: vi.fn(),
|
|
64
|
-
moduleId: 'cattle-register'
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
// Assert
|
|
68
|
-
expect(mocks.getBasePathForModule).toHaveBeenCalledWith('cattle-register')
|
|
69
|
-
})
|
|
70
|
-
|
|
71
49
|
test('defaults to an empty base path when no moduleId is given', () => {
|
|
72
50
|
// Arrange
|
|
73
51
|
const config = {
|
|
@@ -82,7 +60,6 @@ describe('createNunjucksConfig()', () => {
|
|
|
82
60
|
})
|
|
83
61
|
|
|
84
62
|
// Assert
|
|
85
|
-
expect(mocks.getBasePathForModule).not.toHaveBeenCalled()
|
|
86
63
|
expect(nunjucksConfig.plugin).toBeDefined()
|
|
87
64
|
})
|
|
88
65
|
|
package/src/navigation.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { buildPrimaryNavigation } from './nunjucks/build-navigation.js'
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { MODULES } from '@defra/lis-hubs-infra-registry'
|
|
2
|
-
import { SUPPORTED_SPECIES, SUPPORTED_TAXONOMIES } from '../index.js'
|
|
3
|
-
|
|
4
|
-
/** @import { Request } from '@hapi/hapi' */
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param {{ request: Request, basePath?: string }} options
|
|
8
|
-
* @returns {object[]}
|
|
9
|
-
*/
|
|
10
|
-
export function buildPrimaryNavigation({ request, basePath = '' }) {
|
|
11
|
-
const currentSpecies = getCurrentSpecies({ request, basePath })
|
|
12
|
-
const profileItem = {
|
|
13
|
-
text: 'Profile',
|
|
14
|
-
href: '/profile',
|
|
15
|
-
current: request?.path === '/profile' && !currentSpecies?.id
|
|
16
|
-
}
|
|
17
|
-
const permittedSpecies = request?.auth?.credentials?.authorizedSpecies
|
|
18
|
-
|
|
19
|
-
if (!Array.isArray(permittedSpecies) || permittedSpecies.length === 0) {
|
|
20
|
-
return []
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return [
|
|
24
|
-
...permittedSpecies.map((species) => ({
|
|
25
|
-
text: species.label,
|
|
26
|
-
href: getSpeciesHomePath(species),
|
|
27
|
-
current: species.id === currentSpecies?.id
|
|
28
|
-
})),
|
|
29
|
-
profileItem
|
|
30
|
-
]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function getSpeciesHomePath(species) {
|
|
34
|
-
const homeModule = MODULES.find(
|
|
35
|
-
(module) => module.id === `${species.id}-home`
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
return homeModule?.path ?? `/${species.id}`
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getCurrentSpecies({ request, basePath }) {
|
|
42
|
-
for (const path of [request?.path, basePath]) {
|
|
43
|
-
if (typeof path !== 'string' || path.length === 0) {
|
|
44
|
-
continue
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const [speciesSlug, taxonomySlug] = path.split('/').filter(Boolean)
|
|
48
|
-
|
|
49
|
-
const matchingTaxonomy = SUPPORTED_TAXONOMIES.find(
|
|
50
|
-
(taxonomy) => taxonomy.slug === taxonomySlug
|
|
51
|
-
)
|
|
52
|
-
const matchingSpecies = SUPPORTED_SPECIES.find(
|
|
53
|
-
(species) => species.slug === speciesSlug
|
|
54
|
-
)
|
|
55
|
-
if (matchingTaxonomy && matchingSpecies) {
|
|
56
|
-
return matchingSpecies
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return null
|
|
61
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict'
|
|
2
|
-
import { test } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import { buildPrimaryNavigation } from './build-navigation.js'
|
|
5
|
-
|
|
6
|
-
test('buildPrimaryNavigation renders species already authorized by the host', () => {
|
|
7
|
-
const navigation = buildPrimaryNavigation({
|
|
8
|
-
request: {
|
|
9
|
-
path: '/',
|
|
10
|
-
auth: {
|
|
11
|
-
credentials: {
|
|
12
|
-
authorizedSpecies: [
|
|
13
|
-
{ id: 'cattle', label: 'Cattle' },
|
|
14
|
-
{ id: 'sheep', label: 'Sheep' }
|
|
15
|
-
]
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
assert.deepEqual(
|
|
22
|
-
navigation.map((item) => item.text),
|
|
23
|
-
['Cattle', 'Sheep', 'Profile']
|
|
24
|
-
)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
test('buildPrimaryNavigation renders no items when the user has no authorized species', () => {
|
|
28
|
-
const navigation = buildPrimaryNavigation({
|
|
29
|
-
request: { path: '/', app: {} }
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
assert.deepEqual(navigation, [])
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('buildPrimaryNavigation marks the profile item as current on the profile route', () => {
|
|
36
|
-
const navigation = buildPrimaryNavigation({
|
|
37
|
-
request: {
|
|
38
|
-
path: '/profile',
|
|
39
|
-
auth: {
|
|
40
|
-
credentials: {
|
|
41
|
-
authorizedSpecies: [{ id: 'cattle', label: 'Cattle' }]
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
assert.equal(navigation.at(-1)?.text, 'Profile')
|
|
48
|
-
assert.equal(navigation.at(-1)?.current, true)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
test('buildPrimaryNavigation ignores the legacy request.app.authorizedSpecies', () => {
|
|
52
|
-
const navigation = buildPrimaryNavigation({
|
|
53
|
-
request: {
|
|
54
|
-
path: '/',
|
|
55
|
-
app: {
|
|
56
|
-
authorizedSpecies: [{ id: 'cattle', label: 'Cattle' }]
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
assert.deepEqual(navigation, [])
|
|
62
|
-
})
|