@treely/strapi-slices 7.11.0 → 7.13.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/dist/__mocks__/mapbox-gl.d.ts +11 -2
- package/dist/integrations/strapi/getPortfolioProjectsByBbox.d.ts +3 -0
- package/dist/models/PageMetadata.d.ts +1 -0
- package/dist/models/fpm/FPMProject.d.ts +3 -0
- package/dist/models/strapi/StrapiMetadata.d.ts +1 -0
- package/dist/slices/ProjectsMap/ProjectsMap.d.ts +1 -2
- package/dist/strapi-slices.cjs.development.js +509 -190
- package/dist/strapi-slices.cjs.development.js.map +1 -1
- package/dist/strapi-slices.cjs.production.min.js +1 -1
- package/dist/strapi-slices.cjs.production.min.js.map +1 -1
- package/dist/strapi-slices.esm.js +571 -253
- package/dist/strapi-slices.esm.js.map +1 -1
- package/package.json +2 -1
- package/src/components/SliceRenderer/SliceRenderer.tsx +0 -1
- package/src/integrations/strapi/getPortfolioProjectsByBbox.test.ts +82 -0
- package/src/integrations/strapi/getPortfolioProjectsByBbox.ts +86 -0
- package/src/models/PageMetadata.ts +1 -0
- package/src/models/fpm/FPMProject.ts +3 -0
- package/src/models/strapi/StrapiMetadata.ts +1 -0
- package/src/slices/ProjectsMap/ProjectsMap.stories.tsx +0 -48
- package/src/slices/ProjectsMap/ProjectsMap.test.tsx +111 -39
- package/src/slices/ProjectsMap/ProjectsMap.tsx +477 -91
- package/src/slices/TextWithCard/TextWithCard.stories.tsx +1 -0
- package/src/test/integrationMocks/fpmProjectMock.ts +1 -0
- package/src/test/strapiMocks/strapiMetadata.ts +1 -0
- package/src/utils/mergeGlobalAndStrapiBlogPostData.test.ts +81 -0
- package/src/utils/mergeGlobalAndStrapiBlogPostData.ts +6 -0
- package/src/utils/mergeGlobalAndStrapiCustomerStoryData.test.ts +78 -0
- package/src/utils/mergeGlobalAndStrapiCustomerStoryData.ts +6 -0
- package/src/utils/mergeGlobalAndStrapiPageData.test.ts +84 -0
- package/src/utils/mergeGlobalAndStrapiPageData.ts +6 -0
- package/src/utils/mergeGlobalAndStrapiProjectData.test.ts +81 -0
- package/src/utils/mergeGlobalAndStrapiProjectData.ts +6 -0
- package/dist/slices/ProjectsMap/MapMarker.d.ts +0 -12
- package/src/slices/ProjectsMap/MapMarker.test.tsx +0 -101
- package/src/slices/ProjectsMap/MapMarker.tsx +0 -102
|
@@ -219,4 +219,85 @@ describe('The mergeGlobalAndStrapiBlogPostData util', () => {
|
|
|
219
219
|
|
|
220
220
|
expect(result.isFallbackLocale).toBeTruthy();
|
|
221
221
|
});
|
|
222
|
+
|
|
223
|
+
it('handles schema markup types correctly', () => {
|
|
224
|
+
const globalDataWithSchemaMarkup = {
|
|
225
|
+
...minimalGlobalData,
|
|
226
|
+
attributes: {
|
|
227
|
+
...minimalGlobalData.attributes,
|
|
228
|
+
metadata: {
|
|
229
|
+
...minimalGlobalData.attributes.metadata,
|
|
230
|
+
schemaMarkupTypes: ['Organization'],
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const blogPostDataWithSchemaMarkup = {
|
|
236
|
+
...strapiBlogPostMock,
|
|
237
|
+
attributes: {
|
|
238
|
+
...strapiBlogPostMock.attributes,
|
|
239
|
+
metadata: {
|
|
240
|
+
...strapiMetadataMock,
|
|
241
|
+
schemaMarkupTypes: ['Article', 'BlogPosting'],
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// Test blog post-level schema markup
|
|
247
|
+
const resultWithBlogPostSchema = mergeGlobalAndStrapiBlogPostData(
|
|
248
|
+
getStaticPropsContextMock,
|
|
249
|
+
globalDataWithSchemaMarkup,
|
|
250
|
+
blogPostDataWithSchemaMarkup,
|
|
251
|
+
[],
|
|
252
|
+
[]
|
|
253
|
+
);
|
|
254
|
+
expect(resultWithBlogPostSchema.metadata.schemaMarkupTypes).toEqual([
|
|
255
|
+
'Article',
|
|
256
|
+
'BlogPosting',
|
|
257
|
+
]);
|
|
258
|
+
|
|
259
|
+
// Test global fallback
|
|
260
|
+
const blogPostDataWithoutSchema = {
|
|
261
|
+
...strapiBlogPostMock,
|
|
262
|
+
attributes: {
|
|
263
|
+
...strapiBlogPostMock.attributes,
|
|
264
|
+
metadata: {
|
|
265
|
+
...strapiMetadataMock,
|
|
266
|
+
schemaMarkupTypes: undefined,
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const resultWithGlobalSchema = mergeGlobalAndStrapiBlogPostData(
|
|
272
|
+
getStaticPropsContextMock,
|
|
273
|
+
globalDataWithSchemaMarkup,
|
|
274
|
+
blogPostDataWithoutSchema,
|
|
275
|
+
[],
|
|
276
|
+
[]
|
|
277
|
+
);
|
|
278
|
+
expect(resultWithGlobalSchema.metadata.schemaMarkupTypes).toEqual([
|
|
279
|
+
'Organization',
|
|
280
|
+
]);
|
|
281
|
+
|
|
282
|
+
// Test empty array fallback
|
|
283
|
+
const globalDataWithoutSchema = {
|
|
284
|
+
...minimalGlobalData,
|
|
285
|
+
attributes: {
|
|
286
|
+
...minimalGlobalData.attributes,
|
|
287
|
+
metadata: {
|
|
288
|
+
...minimalGlobalData.attributes.metadata,
|
|
289
|
+
schemaMarkupTypes: undefined,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
const resultWithNoSchema = mergeGlobalAndStrapiBlogPostData(
|
|
295
|
+
getStaticPropsContextMock,
|
|
296
|
+
globalDataWithoutSchema,
|
|
297
|
+
blogPostDataWithoutSchema,
|
|
298
|
+
[],
|
|
299
|
+
[]
|
|
300
|
+
);
|
|
301
|
+
expect(resultWithNoSchema.metadata.schemaMarkupTypes).toEqual([]);
|
|
302
|
+
});
|
|
222
303
|
});
|
|
@@ -28,6 +28,11 @@ const mergeGlobalAndStrapiBlogPostData = (
|
|
|
28
28
|
)
|
|
29
29
|
: DEFAULT_SHARE_IMAGE;
|
|
30
30
|
|
|
31
|
+
const schemaMarkupTypes =
|
|
32
|
+
post.attributes.metadata?.schemaMarkupTypes ??
|
|
33
|
+
global.attributes.metadata?.schemaMarkupTypes ??
|
|
34
|
+
[];
|
|
35
|
+
|
|
31
36
|
const returnBlog = post.attributes.slices.some((slice) =>
|
|
32
37
|
SLICES_WITH_BLOG_POSTS.includes(slice.__component)
|
|
33
38
|
);
|
|
@@ -67,6 +72,7 @@ const mergeGlobalAndStrapiBlogPostData = (
|
|
|
67
72
|
},
|
|
68
73
|
metaTitleSuffix: global.attributes.metaTitleSuffix,
|
|
69
74
|
favicon: strapiMediaUrl(global.attributes.favicon, 'thumbnail'),
|
|
75
|
+
schemaMarkupTypes,
|
|
70
76
|
},
|
|
71
77
|
slices: post?.attributes.slices,
|
|
72
78
|
blogPosts: returnBlog ? blog : [],
|
|
@@ -187,4 +187,82 @@ describe('The mergeGlobalAndStrapiCustomerStoryData util', () => {
|
|
|
187
187
|
|
|
188
188
|
expect(result.isFallbackLocale).toBeTruthy();
|
|
189
189
|
});
|
|
190
|
+
|
|
191
|
+
it('handles schema markup types correctly', () => {
|
|
192
|
+
const globalDataWithSchemaMarkup = {
|
|
193
|
+
...minimalGlobalData,
|
|
194
|
+
attributes: {
|
|
195
|
+
...minimalGlobalData.attributes,
|
|
196
|
+
metadata: {
|
|
197
|
+
...minimalGlobalData.attributes.metadata,
|
|
198
|
+
schemaMarkupTypes: ['Organization'],
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const customerStoryDataWithSchemaMarkup = {
|
|
204
|
+
...strapiCustomerStoryMock,
|
|
205
|
+
attributes: {
|
|
206
|
+
...strapiCustomerStoryMock.attributes,
|
|
207
|
+
metadata: {
|
|
208
|
+
...strapiMetadataMock,
|
|
209
|
+
schemaMarkupTypes: ['Article', 'BlogPosting'],
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// Test customer story-level schema markup
|
|
215
|
+
const resultWithCustomerStorySchema = mergeGlobalAndStrapiCustomerStoryData(
|
|
216
|
+
getStaticPropsContextMock,
|
|
217
|
+
globalDataWithSchemaMarkup,
|
|
218
|
+
customerStoryDataWithSchemaMarkup,
|
|
219
|
+
[]
|
|
220
|
+
);
|
|
221
|
+
expect(resultWithCustomerStorySchema.metadata.schemaMarkupTypes).toEqual([
|
|
222
|
+
'Article',
|
|
223
|
+
'BlogPosting',
|
|
224
|
+
]);
|
|
225
|
+
|
|
226
|
+
// Test global fallback
|
|
227
|
+
const customerStoryDataWithoutSchema = {
|
|
228
|
+
...strapiCustomerStoryMock,
|
|
229
|
+
attributes: {
|
|
230
|
+
...strapiCustomerStoryMock.attributes,
|
|
231
|
+
metadata: {
|
|
232
|
+
...strapiMetadataMock,
|
|
233
|
+
schemaMarkupTypes: undefined,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const resultWithGlobalSchema = mergeGlobalAndStrapiCustomerStoryData(
|
|
239
|
+
getStaticPropsContextMock,
|
|
240
|
+
globalDataWithSchemaMarkup,
|
|
241
|
+
customerStoryDataWithoutSchema,
|
|
242
|
+
[]
|
|
243
|
+
);
|
|
244
|
+
expect(resultWithGlobalSchema.metadata.schemaMarkupTypes).toEqual([
|
|
245
|
+
'Organization',
|
|
246
|
+
]);
|
|
247
|
+
|
|
248
|
+
// Test empty array fallback
|
|
249
|
+
const globalDataWithoutSchema = {
|
|
250
|
+
...minimalGlobalData,
|
|
251
|
+
attributes: {
|
|
252
|
+
...minimalGlobalData.attributes,
|
|
253
|
+
metadata: {
|
|
254
|
+
...minimalGlobalData.attributes.metadata,
|
|
255
|
+
schemaMarkupTypes: undefined,
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const resultWithNoSchema = mergeGlobalAndStrapiCustomerStoryData(
|
|
261
|
+
getStaticPropsContextMock,
|
|
262
|
+
globalDataWithoutSchema,
|
|
263
|
+
customerStoryDataWithoutSchema,
|
|
264
|
+
[]
|
|
265
|
+
);
|
|
266
|
+
expect(resultWithNoSchema.metadata.schemaMarkupTypes).toEqual([]);
|
|
267
|
+
});
|
|
190
268
|
});
|
|
@@ -23,6 +23,11 @@ const mergeGlobalAndStrapiCustomerStoryData = (
|
|
|
23
23
|
)
|
|
24
24
|
: DEFAULT_SHARE_IMAGE;
|
|
25
25
|
|
|
26
|
+
const schemaMarkupTypes =
|
|
27
|
+
customerStory.attributes.metadata?.schemaMarkupTypes ??
|
|
28
|
+
global.attributes.metadata?.schemaMarkupTypes ??
|
|
29
|
+
[];
|
|
30
|
+
|
|
26
31
|
const returnCustomerStories = customerStory.attributes.slices.some((slice) =>
|
|
27
32
|
SLICES_WITH_CUSTOMER_STORIES.includes(slice.__component)
|
|
28
33
|
);
|
|
@@ -60,6 +65,7 @@ const mergeGlobalAndStrapiCustomerStoryData = (
|
|
|
60
65
|
},
|
|
61
66
|
metaTitleSuffix: global.attributes.metaTitleSuffix,
|
|
62
67
|
favicon: strapiMediaUrl(global.attributes.favicon, 'thumbnail'),
|
|
68
|
+
schemaMarkupTypes,
|
|
63
69
|
},
|
|
64
70
|
slices: customerStory?.attributes.slices,
|
|
65
71
|
customerStories: returnCustomerStories ? customerStories : [],
|
|
@@ -339,4 +339,88 @@ describe('The mergeGlobalAndStrapiPageData util', () => {
|
|
|
339
339
|
|
|
340
340
|
expect(result.isFallbackLocale).toBeTruthy();
|
|
341
341
|
});
|
|
342
|
+
|
|
343
|
+
it('handles schema markup types correctly', () => {
|
|
344
|
+
const globalDataWithSchemaMarkup = {
|
|
345
|
+
...minimalGlobalData,
|
|
346
|
+
attributes: {
|
|
347
|
+
...minimalGlobalData.attributes,
|
|
348
|
+
metadata: {
|
|
349
|
+
...minimalGlobalData.attributes.metadata,
|
|
350
|
+
schemaMarkupTypes: ['Organization'],
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const pageDataWithSchemaMarkup = {
|
|
356
|
+
...strapiPageMock,
|
|
357
|
+
attributes: {
|
|
358
|
+
...strapiPageMock.attributes,
|
|
359
|
+
metadata: {
|
|
360
|
+
...strapiMetadataMock,
|
|
361
|
+
schemaMarkupTypes: ['Article', 'BlogPosting'],
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// Test page-level schema markup
|
|
367
|
+
const resultWithPageSchema = mergeGlobalAndStrapiPageData(
|
|
368
|
+
getStaticPropsContextMock,
|
|
369
|
+
globalDataWithSchemaMarkup,
|
|
370
|
+
pageDataWithSchemaMarkup,
|
|
371
|
+
[],
|
|
372
|
+
[],
|
|
373
|
+
[]
|
|
374
|
+
);
|
|
375
|
+
expect(resultWithPageSchema.metadata.schemaMarkupTypes).toEqual([
|
|
376
|
+
'Article',
|
|
377
|
+
'BlogPosting',
|
|
378
|
+
]);
|
|
379
|
+
|
|
380
|
+
// Test global fallback
|
|
381
|
+
const pageDataWithoutSchema = {
|
|
382
|
+
...strapiPageMock,
|
|
383
|
+
attributes: {
|
|
384
|
+
...strapiPageMock.attributes,
|
|
385
|
+
metadata: {
|
|
386
|
+
...strapiMetadataMock,
|
|
387
|
+
schemaMarkupTypes: undefined,
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
const resultWithGlobalSchema = mergeGlobalAndStrapiPageData(
|
|
393
|
+
getStaticPropsContextMock,
|
|
394
|
+
globalDataWithSchemaMarkup,
|
|
395
|
+
pageDataWithoutSchema,
|
|
396
|
+
[],
|
|
397
|
+
[],
|
|
398
|
+
[]
|
|
399
|
+
);
|
|
400
|
+
expect(resultWithGlobalSchema.metadata.schemaMarkupTypes).toEqual([
|
|
401
|
+
'Organization',
|
|
402
|
+
]);
|
|
403
|
+
|
|
404
|
+
// Test empty array fallback
|
|
405
|
+
const globalDataWithoutSchema = {
|
|
406
|
+
...minimalGlobalData,
|
|
407
|
+
attributes: {
|
|
408
|
+
...minimalGlobalData.attributes,
|
|
409
|
+
metadata: {
|
|
410
|
+
...minimalGlobalData.attributes.metadata,
|
|
411
|
+
schemaMarkupTypes: undefined,
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
const resultWithNoSchema = mergeGlobalAndStrapiPageData(
|
|
417
|
+
getStaticPropsContextMock,
|
|
418
|
+
globalDataWithoutSchema,
|
|
419
|
+
pageDataWithoutSchema,
|
|
420
|
+
[],
|
|
421
|
+
[],
|
|
422
|
+
[]
|
|
423
|
+
);
|
|
424
|
+
expect(resultWithNoSchema.metadata.schemaMarkupTypes).toEqual([]);
|
|
425
|
+
});
|
|
342
426
|
});
|
|
@@ -34,6 +34,11 @@ const mergeGlobalAndStrapiPageData = (
|
|
|
34
34
|
)
|
|
35
35
|
: DEFAULT_SHARE_IMAGE;
|
|
36
36
|
|
|
37
|
+
const schemaMarkupTypes =
|
|
38
|
+
page.attributes.metadata?.schemaMarkupTypes ??
|
|
39
|
+
global.attributes.metadata?.schemaMarkupTypes ??
|
|
40
|
+
[];
|
|
41
|
+
|
|
37
42
|
const returnBlogPosts = page.attributes.slices.some((slice) =>
|
|
38
43
|
SLICES_WITH_BLOG_POSTS.includes(slice.__component)
|
|
39
44
|
);
|
|
@@ -82,6 +87,7 @@ const mergeGlobalAndStrapiPageData = (
|
|
|
82
87
|
},
|
|
83
88
|
metaTitleSuffix: global.attributes.metaTitleSuffix,
|
|
84
89
|
favicon: strapiMediaUrl(global.attributes.favicon, 'thumbnail'),
|
|
90
|
+
schemaMarkupTypes,
|
|
85
91
|
},
|
|
86
92
|
slices: page?.attributes.slices,
|
|
87
93
|
blogPosts: returnBlogPosts ? blogPosts : [],
|
|
@@ -301,4 +301,85 @@ describe('The mergeGlobalAndStrapiProjectData util', () => {
|
|
|
301
301
|
|
|
302
302
|
expect(result.isFallbackLocale).toBeTruthy();
|
|
303
303
|
});
|
|
304
|
+
|
|
305
|
+
it('handles schema markup types correctly', () => {
|
|
306
|
+
const globalDataWithSchemaMarkup = {
|
|
307
|
+
...minimalGlobalData,
|
|
308
|
+
attributes: {
|
|
309
|
+
...minimalGlobalData.attributes,
|
|
310
|
+
metadata: {
|
|
311
|
+
...minimalGlobalData.attributes.metadata,
|
|
312
|
+
schemaMarkupTypes: ['Organization'],
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const projectDataWithSchemaMarkup = {
|
|
318
|
+
...strapiProjectMock,
|
|
319
|
+
attributes: {
|
|
320
|
+
...strapiProjectMock.attributes,
|
|
321
|
+
metadata: {
|
|
322
|
+
...strapiMetadataMock,
|
|
323
|
+
schemaMarkupTypes: ['Article', 'BlogPosting'],
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// Test project-level schema markup
|
|
329
|
+
const resultWithProjectSchema = mergeGlobalAndStrapiProjectData(
|
|
330
|
+
getStaticPropsContextMock,
|
|
331
|
+
globalDataWithSchemaMarkup,
|
|
332
|
+
projectDataWithSchemaMarkup,
|
|
333
|
+
[],
|
|
334
|
+
[]
|
|
335
|
+
);
|
|
336
|
+
expect(resultWithProjectSchema.metadata.schemaMarkupTypes).toEqual([
|
|
337
|
+
'Article',
|
|
338
|
+
'BlogPosting',
|
|
339
|
+
]);
|
|
340
|
+
|
|
341
|
+
// Test global fallback
|
|
342
|
+
const projectDataWithoutSchema = {
|
|
343
|
+
...strapiProjectMock,
|
|
344
|
+
attributes: {
|
|
345
|
+
...strapiProjectMock.attributes,
|
|
346
|
+
metadata: {
|
|
347
|
+
...strapiMetadataMock,
|
|
348
|
+
schemaMarkupTypes: undefined,
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const resultWithGlobalSchema = mergeGlobalAndStrapiProjectData(
|
|
354
|
+
getStaticPropsContextMock,
|
|
355
|
+
globalDataWithSchemaMarkup,
|
|
356
|
+
projectDataWithoutSchema,
|
|
357
|
+
[],
|
|
358
|
+
[]
|
|
359
|
+
);
|
|
360
|
+
expect(resultWithGlobalSchema.metadata.schemaMarkupTypes).toEqual([
|
|
361
|
+
'Organization',
|
|
362
|
+
]);
|
|
363
|
+
|
|
364
|
+
// Test empty array fallback
|
|
365
|
+
const globalDataWithoutSchema = {
|
|
366
|
+
...minimalGlobalData,
|
|
367
|
+
attributes: {
|
|
368
|
+
...minimalGlobalData.attributes,
|
|
369
|
+
metadata: {
|
|
370
|
+
...minimalGlobalData.attributes.metadata,
|
|
371
|
+
schemaMarkupTypes: undefined,
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const resultWithNoSchema = mergeGlobalAndStrapiProjectData(
|
|
377
|
+
getStaticPropsContextMock,
|
|
378
|
+
globalDataWithoutSchema,
|
|
379
|
+
projectDataWithoutSchema,
|
|
380
|
+
[],
|
|
381
|
+
[]
|
|
382
|
+
);
|
|
383
|
+
expect(resultWithNoSchema.metadata.schemaMarkupTypes).toEqual([]);
|
|
384
|
+
});
|
|
304
385
|
});
|
|
@@ -31,6 +31,11 @@ const mergeGlobalAndStrapiProject = (
|
|
|
31
31
|
)
|
|
32
32
|
: DEFAULT_SHARE_IMAGE;
|
|
33
33
|
|
|
34
|
+
const schemaMarkupTypes =
|
|
35
|
+
project.attributes.metadata?.schemaMarkupTypes ??
|
|
36
|
+
global.attributes.metadata?.schemaMarkupTypes ??
|
|
37
|
+
[];
|
|
38
|
+
|
|
34
39
|
const returnBlogPosts = project.attributes.slices.some((slice) =>
|
|
35
40
|
SLICES_WITH_BLOG_POSTS.includes(slice.__component)
|
|
36
41
|
);
|
|
@@ -76,6 +81,7 @@ const mergeGlobalAndStrapiProject = (
|
|
|
76
81
|
},
|
|
77
82
|
metaTitleSuffix: global.attributes.metaTitleSuffix,
|
|
78
83
|
favicon: strapiMediaUrl(global.attributes.favicon, 'thumbnail'),
|
|
84
|
+
schemaMarkupTypes,
|
|
79
85
|
},
|
|
80
86
|
slices: project.attributes.slices,
|
|
81
87
|
blogPosts: returnBlogPosts ? blogPosts : [],
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { CreditAvailability } from '../../models/fpm/FPMProject';
|
|
3
|
-
export interface MapMarkerProps {
|
|
4
|
-
title: string;
|
|
5
|
-
isPublic?: boolean;
|
|
6
|
-
projectDeveloper?: string;
|
|
7
|
-
slug?: string;
|
|
8
|
-
portfolioHost?: string;
|
|
9
|
-
creditAvailability: CreditAvailability;
|
|
10
|
-
}
|
|
11
|
-
declare const MapMarker: ({ title, projectDeveloper, slug, creditAvailability, portfolioHost, isPublic, }: MapMarkerProps) => React.JSX.Element;
|
|
12
|
-
export default MapMarker;
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { fireEvent, render, screen, waitFor } from '../../test/testUtils';
|
|
3
|
-
import MapMarker, { MapMarkerProps } from './MapMarker';
|
|
4
|
-
import messagesEn from './messages.en';
|
|
5
|
-
import { CreditAvailability } from '../../models/fpm/FPMProject';
|
|
6
|
-
|
|
7
|
-
const defaultProps: MapMarkerProps = {
|
|
8
|
-
title: 'Project title',
|
|
9
|
-
portfolioHost: '',
|
|
10
|
-
isPublic: true,
|
|
11
|
-
creditAvailability: CreditAvailability.CREDITS_AVAILABLE,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const setup = (props: Partial<MapMarkerProps> = {}) => {
|
|
15
|
-
const combinedProps = { ...defaultProps, ...props };
|
|
16
|
-
render(<MapMarker {...combinedProps} />);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
describe('The MapMarker component', () => {
|
|
20
|
-
it('renders successfully with minimal props', () => {
|
|
21
|
-
setup({});
|
|
22
|
-
|
|
23
|
-
expect(screen.queryByText('Project title')).not.toBeInTheDocument();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('renders successfully with minimal props', () => {
|
|
27
|
-
setup({});
|
|
28
|
-
|
|
29
|
-
fireEvent.mouseEnter(screen.getByTestId('mapmarker-pin'));
|
|
30
|
-
|
|
31
|
-
waitFor(() => {
|
|
32
|
-
expect(screen.findByText('Project title')).toBeInTheDocument();
|
|
33
|
-
expect(screen.findByRole('button')).not.toBeInTheDocument();
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('renders a button if slug is defined', () => {
|
|
38
|
-
setup({ slug: 'slug' });
|
|
39
|
-
|
|
40
|
-
expect(screen.getByTestId('mapmarker-pin').parentElement).toHaveProperty(
|
|
41
|
-
'href',
|
|
42
|
-
'http://localhost/portfolio/slug'
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
fireEvent.mouseEnter(screen.getByTestId('mapmarker-pin'));
|
|
46
|
-
|
|
47
|
-
waitFor(() => {
|
|
48
|
-
const button = screen.getByText(
|
|
49
|
-
messagesEn['sections.projectsMap.link.text']
|
|
50
|
-
);
|
|
51
|
-
expect(button).toBeInTheDocument();
|
|
52
|
-
expect(button).toHaveProperty('href', '/portfolio/slug');
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('prefixes the url with the portfolio host', () => {
|
|
57
|
-
setup({ slug: 'slug', portfolioHost: 'https://example.com' });
|
|
58
|
-
|
|
59
|
-
expect(screen.getByTestId('mapmarker-pin').parentElement).toHaveProperty(
|
|
60
|
-
'href',
|
|
61
|
-
'https://example.com/portfolio/slug'
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
fireEvent.mouseEnter(screen.getByTestId('mapmarker-pin'));
|
|
65
|
-
|
|
66
|
-
waitFor(() => {
|
|
67
|
-
const button = screen.getByText(
|
|
68
|
-
messagesEn['sections.projectsMap.link.text']
|
|
69
|
-
);
|
|
70
|
-
expect(button).toBeInTheDocument();
|
|
71
|
-
expect(button).toHaveProperty(
|
|
72
|
-
'href',
|
|
73
|
-
'https://example.com/portfolio/slug'
|
|
74
|
-
);
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('renders the project developer if it is defined', () => {
|
|
79
|
-
setup({
|
|
80
|
-
projectDeveloper: 'Project developer',
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
fireEvent.mouseEnter(screen.getByTestId('mapmarker-pin'));
|
|
84
|
-
|
|
85
|
-
waitFor(() => {
|
|
86
|
-
expect(screen.getByText('Project developer')).toBeInTheDocument();
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('renders the credit availability if it is defined', () => {
|
|
91
|
-
setup({
|
|
92
|
-
creditAvailability: CreditAvailability.CREDITS_AVAILABLE,
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
fireEvent.mouseEnter(screen.getByTestId('mapmarker-pin'));
|
|
96
|
-
|
|
97
|
-
waitFor(() => {
|
|
98
|
-
expect(screen.getByText('CREDITS AVAILABLE')).toBeInTheDocument();
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
});
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import React, { useContext } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Box,
|
|
4
|
-
Button,
|
|
5
|
-
Container,
|
|
6
|
-
Flex,
|
|
7
|
-
Heading,
|
|
8
|
-
Text,
|
|
9
|
-
useDisclosure,
|
|
10
|
-
useToken,
|
|
11
|
-
} from 'boemly';
|
|
12
|
-
import { MapPin } from '@phosphor-icons/react';
|
|
13
|
-
import NextLink from 'next/link';
|
|
14
|
-
import CreditsAvailableBadge from '../../components/CreditsAvailableBadge';
|
|
15
|
-
import { IntlContext } from '../../components/ContextProvider';
|
|
16
|
-
import { CreditAvailability } from '../../models/fpm/FPMProject';
|
|
17
|
-
|
|
18
|
-
export interface MapMarkerProps {
|
|
19
|
-
title: string;
|
|
20
|
-
isPublic?: boolean;
|
|
21
|
-
projectDeveloper?: string;
|
|
22
|
-
slug?: string;
|
|
23
|
-
portfolioHost?: string;
|
|
24
|
-
creditAvailability: CreditAvailability;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const MapMarker = ({
|
|
28
|
-
title,
|
|
29
|
-
projectDeveloper,
|
|
30
|
-
slug,
|
|
31
|
-
creditAvailability,
|
|
32
|
-
portfolioHost = '',
|
|
33
|
-
isPublic = false,
|
|
34
|
-
}: MapMarkerProps) => {
|
|
35
|
-
const { formatMessage } = useContext(IntlContext);
|
|
36
|
-
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
37
|
-
const blue600 = useToken('colors', 'blue.600');
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<Flex
|
|
41
|
-
position="absolute"
|
|
42
|
-
gap="4"
|
|
43
|
-
onMouseEnter={onOpen}
|
|
44
|
-
onMouseLeave={onClose}
|
|
45
|
-
cursor="grab"
|
|
46
|
-
>
|
|
47
|
-
<Box
|
|
48
|
-
as={slug ? NextLink : undefined}
|
|
49
|
-
href={slug && `${portfolioHost}/portfolio/${slug}`}
|
|
50
|
-
>
|
|
51
|
-
<MapPin
|
|
52
|
-
size="40px"
|
|
53
|
-
color={blue600}
|
|
54
|
-
weight="fill"
|
|
55
|
-
data-testid="mapmarker-pin"
|
|
56
|
-
filter="drop-shadow(0px 0px 2px #FFF)"
|
|
57
|
-
/>
|
|
58
|
-
</Box>
|
|
59
|
-
|
|
60
|
-
{isPublic && isOpen && (
|
|
61
|
-
<Container
|
|
62
|
-
shadow="md"
|
|
63
|
-
width="max-content"
|
|
64
|
-
minWidth="3xs"
|
|
65
|
-
maxWidth={['3xs', null, null, 'sm']}
|
|
66
|
-
>
|
|
67
|
-
<Flex direction="column">
|
|
68
|
-
<CreditsAvailableBadge
|
|
69
|
-
status={creditAvailability}
|
|
70
|
-
href={slug && `${portfolioHost}/portfolio/${slug}`}
|
|
71
|
-
/>
|
|
72
|
-
<Heading mt="3" size="md">
|
|
73
|
-
{title}
|
|
74
|
-
</Heading>
|
|
75
|
-
|
|
76
|
-
{projectDeveloper && (
|
|
77
|
-
<Text size="smLowNormal" mt="1">
|
|
78
|
-
{projectDeveloper}
|
|
79
|
-
</Text>
|
|
80
|
-
)}
|
|
81
|
-
|
|
82
|
-
{slug && (
|
|
83
|
-
<Button
|
|
84
|
-
width="fit-content"
|
|
85
|
-
variant="outline"
|
|
86
|
-
size="sm"
|
|
87
|
-
as={NextLink}
|
|
88
|
-
href={`${portfolioHost}/portfolio/${slug}`}
|
|
89
|
-
mt="4"
|
|
90
|
-
whiteSpace="nowrap"
|
|
91
|
-
>
|
|
92
|
-
{formatMessage({ id: 'sections.projectsMap.link.text' })}
|
|
93
|
-
</Button>
|
|
94
|
-
)}
|
|
95
|
-
</Flex>
|
|
96
|
-
</Container>
|
|
97
|
-
)}
|
|
98
|
-
</Flex>
|
|
99
|
-
);
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export default MapMarker;
|