@webbio/strapi-plugin-page-builder 0.2.2 → 0.3.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.
Files changed (43) hide show
  1. package/README.md +6 -18
  2. package/admin/src/api/collection-type.ts +7 -1
  3. package/admin/src/api/platform.ts +34 -0
  4. package/admin/src/components/Combobox/react-select-custom-styles.tsx +12 -3
  5. package/admin/src/components/EditView/CollectionTypeSearch/index.tsx +17 -14
  6. package/admin/src/components/EditView/CollectionTypeSettings/CreatePageButton/index.tsx +5 -1
  7. package/admin/src/components/EditView/CollectionTypeSettings/index.tsx +5 -15
  8. package/admin/src/components/EditView/PageSettings/index.tsx +57 -6
  9. package/admin/src/components/EditView/Platform/platform-select.tsx +30 -0
  10. package/admin/src/components/EditView/Template/TemplateSelect/index.tsx +2 -2
  11. package/admin/src/components/EditView/index.tsx +1 -1
  12. package/admin/src/components/EditView/page-type-select.tsx +1 -1
  13. package/admin/src/components/PageFilters/PageTypeFilter/index.tsx +39 -0
  14. package/admin/src/components/PageFilters/PlatformFilter/index.tsx +28 -0
  15. package/admin/src/components/PageFilters/filters.tsx +180 -0
  16. package/admin/src/components/PageFilters/index.tsx +30 -0
  17. package/admin/src/index.tsx +2 -2
  18. package/admin/src/utils/hooks/useGetLocaleFromUrl.ts +1 -1
  19. package/dist/package.json +5 -6
  20. package/dist/server/bootstrap.js +15 -5
  21. package/dist/server/controllers/index.js +3 -1
  22. package/dist/server/graphql/pages-by-uid.js +1 -2
  23. package/dist/server/routes/index.js +21 -0
  24. package/dist/server/schema/page-end.json +5 -0
  25. package/dist/server/services/builder.js +20 -7
  26. package/dist/server/services/index.js +3 -1
  27. package/dist/shared/utils/constants.js +3 -1
  28. package/dist/tsconfig.server.tsbuildinfo +1 -1
  29. package/package.json +5 -6
  30. package/server/bootstrap/collection-type-lifecycles.ts +1 -1
  31. package/server/bootstrap.ts +18 -3
  32. package/server/controllers/index.ts +3 -1
  33. package/server/controllers/platform.ts +21 -0
  34. package/server/graphql/pages-by-uid.ts +1 -2
  35. package/server/routes/index.ts +21 -0
  36. package/server/schema/page-end.json +5 -0
  37. package/server/schema/platform-start.json +31 -0
  38. package/server/services/builder.ts +23 -8
  39. package/server/services/index.ts +3 -1
  40. package/server/services/platform.ts +36 -0
  41. package/shared/utils/constants.ts +2 -0
  42. package/admin/src/components/PageTypeFilter/index.tsx +0 -17
  43. package/admin/src/components/PageTypeFilter/page-type-filter.tsx +0 -130
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webbio/strapi-plugin-page-builder",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "This is the description of the plugin.",
5
5
  "scripts": {
6
6
  "develop": "tsc -p tsconfig.server.json -w",
@@ -21,14 +21,13 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@strapi/design-system": "^1.11.0",
24
- "@strapi/helper-plugin": "^4.13.6",
24
+ "@strapi/helper-plugin": "^4.15.0",
25
25
  "@strapi/icons": "^1.11.0",
26
- "@strapi/typescript-utils": "^4.13.6",
27
- "@strapi/utils": "^4.13.6",
26
+ "@strapi/typescript-utils": "^4.15.0",
27
+ "@strapi/utils": "^4.15.0",
28
28
  "react-select": "^5.7.4"
29
29
  },
30
30
  "devDependencies": {
31
- "@strapi/typescript-utils": "^4.13.6",
32
31
  "@types/react": "^18.2.21",
33
32
  "@types/react-dom": "^18.2.7",
34
33
  "@types/react-router-dom": "^5.3.3",
@@ -40,7 +39,7 @@
40
39
  "typescript": "5.1.6"
41
40
  },
42
41
  "peerDependencies": {
43
- "@strapi/strapi": "^4.13.6",
42
+ "@strapi/strapi": "^4.15.0",
44
43
  "@webbio/strapi-plugin-slug": "^2.0.2",
45
44
  "react": "^17.0.0 || ^18.0.0",
46
45
  "react-dom": "^17.0.0 || ^18.0.0",
@@ -37,7 +37,7 @@ export default async ({ strapi }: { strapi: Strapi }) => {
37
37
  data: {
38
38
  updatedAt: data.updatedAt
39
39
  }
40
- } as any);
40
+ } as Record<string, any>);
41
41
  }
42
42
  } catch (error) {
43
43
  console.log('[PAGEBUILDER PLUGIN] collection type lifecycle error: ', error);
@@ -1,6 +1,6 @@
1
1
  import { Common, Strapi } from '@strapi/strapi';
2
2
  import { errors } from '@strapi/utils';
3
- import { PAGE_TYPE_UID, PAGE_UID } from '../shared/utils/constants';
3
+ import { PAGE_TYPE_UID, PAGE_UID, PLATFORM_UID } from '../shared/utils/constants';
4
4
  import permissions from './bootstrap/permissions';
5
5
  import collectionTypeLifecycles from './bootstrap/collection-type-lifecycles';
6
6
 
@@ -27,6 +27,7 @@ export default async ({ strapi }: { strapi: Strapi }) => {
27
27
  let { data } = event.params;
28
28
  const collectionTypeId = data?.collectionTypeId;
29
29
  const pageTypeId = data?.pageType.connect?.[0]?.id || data.initialPageType;
30
+ const platformId = data?.platform.connect?.[0]?.id;
30
31
 
31
32
  if (collectionTypeId && pageTypeId) {
32
33
  const pageType: Record<string, any> | undefined | null = await strapi.entityService?.findOne(
@@ -39,10 +40,26 @@ export default async ({ strapi }: { strapi: Strapi }) => {
39
40
 
40
41
  const page: Record<string, any>[] = collectionToConnect?.page as any;
41
42
 
43
+ const foundPlatforms: Record<string, any> | undefined | null = await strapi.entityService?.findMany(
44
+ PLATFORM_UID,
45
+ {
46
+ populate: '*',
47
+ filters: {
48
+ pagetype: {
49
+ uid: pageType?.uid
50
+ }
51
+ }
52
+ }
53
+ );
54
+
42
55
  if (page && page.length > 0) {
43
56
  throw new errors.ValidationError('You can only link one CollectionType to one page');
44
57
  }
45
58
 
59
+ if (platformId && !foundPlatforms?.some((platform) => platform.id === platformId)) {
60
+ throw new errors.ValidationError('Platform not found');
61
+ }
62
+
46
63
  data = updateCollectionTypeData(data, collectionTypeId, pageType?.uid);
47
64
  }
48
65
  },
@@ -98,8 +115,6 @@ export default async ({ strapi }: { strapi: Strapi }) => {
98
115
  data = updateCollectionTypeData(data, collectionTypeId, pageType?.uid);
99
116
  }
100
117
 
101
- // needs to check if the collectionTypeData is already connected to another page
102
- // if so, remove the hasPage for filtering
103
118
  if (
104
119
  data.collectionTypeData &&
105
120
  originalEntity?.collectionTypeData?.[0]?.__type &&
@@ -2,10 +2,12 @@ import page from './page';
2
2
  import pageType from './page-type';
3
3
  import collectionTypes from './collection-types';
4
4
  import template from './template';
5
+ import platform from './platform';
5
6
 
6
7
  export default {
7
8
  page,
8
9
  'page-type': pageType,
9
10
  'collection-types': collectionTypes,
10
- template
11
+ template,
12
+ platform
11
13
  };
@@ -0,0 +1,21 @@
1
+ import { Strapi } from '@strapi/strapi';
2
+
3
+ export default {
4
+ async findAll() {
5
+ return await (strapi as Strapi).service('plugin::page-builder.platform').findAll();
6
+ },
7
+
8
+ async findOneByUid(ctx: any) {
9
+ const uid = ctx?.params?.uid;
10
+
11
+ if (!uid) {
12
+ return ctx.badRequest('uid is missing.');
13
+ }
14
+
15
+ return await strapi.service('plugin::page-builder.platform').findOneByUid(uid);
16
+ },
17
+ async findPageTypesByPlatform(ctx: any) {
18
+ const platform = ctx?.params?.platform;
19
+ return await (strapi as Strapi).services['plugin::page-builder.platform'].findPageTypesByPlatform(platform);
20
+ }
21
+ };
@@ -22,7 +22,7 @@ const getPageInfoFromUID = (strapi: Strapi) => {
22
22
  }
23
23
 
24
24
  type Query {
25
- get${collectionType.type}Pages(filters: ${collectionType.type}FiltersInput,pagination: PaginationArg, sort:[String], pageFilters: PageFiltersInput): ${collectionType.type}EntityResponseCollection
25
+ get${collectionType.type}Pages(filters: ${collectionType.type}FiltersInput,pagination: PaginationArg, pageFilters: PageFiltersInput): ${collectionType.type}EntityResponseCollection
26
26
  }
27
27
 
28
28
  `;
@@ -67,7 +67,6 @@ const getPageInfoFromUID = (strapi: Strapi) => {
67
67
  hasPage: { $eq: true },
68
68
  page: { ...transformedpageArgs.filters }
69
69
  },
70
- sort: transformedArgs.sort,
71
70
  start: start,
72
71
  limit: limit
73
72
  });
@@ -52,6 +52,27 @@ const routes = {
52
52
  handler: 'template.findOneById'
53
53
  }
54
54
  ]
55
+ },
56
+ platform: {
57
+ type: 'admin',
58
+ prefix: undefined,
59
+ routes: [
60
+ {
61
+ method: 'GET',
62
+ path: '/platform',
63
+ handler: 'platform.findAll'
64
+ },
65
+ {
66
+ method: 'GET',
67
+ path: '/platform/:uid',
68
+ handler: 'platform.findOneByUid'
69
+ },
70
+ {
71
+ method: 'GET',
72
+ path: '/platform/:platform/page-types',
73
+ handler: 'platform.findPageTypesByPlatform'
74
+ }
75
+ ]
55
76
  }
56
77
  };
57
78
 
@@ -86,6 +86,11 @@
86
86
  "type": "relation",
87
87
  "relation": "oneToOne",
88
88
  "target": "api::page-type.page-type"
89
+ },
90
+ "platform": {
91
+ "type": "relation",
92
+ "relation": "oneToOne",
93
+ "target": "api::platform.platform"
89
94
  }
90
95
  }
91
96
  }
@@ -0,0 +1,31 @@
1
+ {
2
+ "draftAndPublish": false,
3
+ "displayName": "Platforms",
4
+ "singularName": "platform",
5
+ "pluralName": "platforms",
6
+ "description": "",
7
+ "plugin": "page-builder",
8
+ "pluginOptions": {},
9
+ "kind": "collectionType",
10
+ "collectionName": "platforms",
11
+ "attributes": {
12
+ "title": {
13
+ "type": "string",
14
+ "required": true,
15
+ "unique": true
16
+ },
17
+ "domain": {
18
+ "type": "string"
19
+ },
20
+ "template": {
21
+ "type": "relation",
22
+ "relation": "oneToMany",
23
+ "target": "api::template.template"
24
+ },
25
+ "pageTypes": {
26
+ "type": "relation",
27
+ "relation": "oneToMany",
28
+ "target": "api::page-type.page-type"
29
+ }
30
+ }
31
+ }
@@ -4,13 +4,14 @@ import { Common } from '@strapi/strapi';
4
4
  import pageStart from '../schema/page-start.json';
5
5
  import pageEnd from '../schema/page-end.json';
6
6
  import pluginId from '../../admin/src/pluginId';
7
- import { PAGE_UID, TEMPLATE_UID, PAGE_TYPE_UID } from '../../shared/utils/constants';
7
+ import { PAGE_UID, TEMPLATE_UID, PAGE_TYPE_UID, PLATFORM_UID } from '../../shared/utils/constants';
8
8
  import { reloadStrapiOnLoad } from '../utils/reload-strapi-on-load';
9
9
  import pageTypeStart from '../schema/page-type-start.json';
10
10
  import pageTypeEnd from '../schema/page-type-end.json';
11
11
  import templateStart from '../schema/template-start.json';
12
+ import platformStart from '../schema/platform-start.json';
12
13
 
13
- const UIDS: Common.UID.ContentType[] = [TEMPLATE_UID, PAGE_TYPE_UID, PAGE_UID];
14
+ const UIDS: Common.UID.ContentType[] = [TEMPLATE_UID, PAGE_TYPE_UID, PLATFORM_UID, PAGE_UID];
14
15
 
15
16
  export default {
16
17
  async buildContentTypes() {
@@ -87,6 +88,10 @@ export default {
87
88
  [TEMPLATE_UID]: {
88
89
  create: this.getTemplateContentType(),
89
90
  update: this.getTemplateContentType()
91
+ },
92
+ [PLATFORM_UID]: {
93
+ create: this.getPlatformContentType(),
94
+ update: this.getPlatformContentType()
90
95
  }
91
96
  };
92
97
 
@@ -94,25 +99,32 @@ export default {
94
99
  },
95
100
  getPageContentType(create?: boolean) {
96
101
  const page = create ? pageStart : pageEnd;
97
- const contentType = this.mergeCollectionTypeWithModules(page, PAGE_UID);
102
+ const contentType = this.mergeCollectionTypeWithOld(page, PAGE_UID);
98
103
 
99
104
  return { uid: PAGE_UID, contentType };
100
105
  },
101
106
  getPageTypeContentType(create?: boolean) {
102
107
  const pageType = create ? pageTypeStart : pageTypeEnd;
103
- const contentType = this.mergeCollectionTypeWithModules(pageType, PAGE_TYPE_UID);
108
+ const contentType = this.mergeCollectionTypeWithOld(pageType, PAGE_TYPE_UID);
104
109
 
105
110
  return { uid: PAGE_TYPE_UID, contentType };
106
111
  },
107
112
  getTemplateContentType() {
108
113
  const template = templateStart;
109
- const contentType = this.mergeCollectionTypeWithModules(template, TEMPLATE_UID);
114
+ const contentType = this.mergeCollectionTypeWithOld(template, TEMPLATE_UID);
110
115
 
111
116
  return { uid: TEMPLATE_UID, contentType };
112
117
  },
113
- mergeCollectionTypeWithModules(collectionType: Record<string, any>, uid: Common.UID.ContentType) {
118
+ getPlatformContentType() {
119
+ const platform = platformStart;
120
+
121
+ const contentType = this.mergeCollectionTypeWithOld(platform, PLATFORM_UID);
122
+
123
+ return { uid: PLATFORM_UID, contentType };
124
+ },
125
+ mergeCollectionTypeWithOld(collectionType: Record<string, any>, uid: Common.UID.ContentType) {
114
126
  const { pluginOptions: oldPluginOptions, __schema__: oldSchema } = (strapi.contentType(uid) as any) || {};
115
- const components = this.getConfigModuleComponents();
127
+ const modulesFromConfig = oldSchema.attributes.modules ? this.getConfigModuleComponents() : undefined;
116
128
 
117
129
  return {
118
130
  ...collectionType,
@@ -124,7 +136,10 @@ export default {
124
136
  attributes: {
125
137
  ...oldSchema?.attributes,
126
138
  ...collectionType.attributes,
127
- modules: { ...collectionType.attributes.modules, components }
139
+ ...(((collectionType.attributes.modules && collectionType.attributes.modules.length > 0) ||
140
+ modulesFromConfig) && {
141
+ modules: { ...collectionType.attributes.modules, components: modulesFromConfig }
142
+ })
128
143
  }
129
144
  };
130
145
  },
@@ -3,11 +3,13 @@ import builder from './builder';
3
3
  import pageType from './page-type';
4
4
  import collectionTypes from './collection-types';
5
5
  import template from './template';
6
+ import platform from './platform';
6
7
 
7
8
  export default {
8
9
  page,
9
10
  builder,
10
11
  'page-type': pageType,
11
12
  'collection-types': collectionTypes,
12
- template
13
+ template,
14
+ platform
13
15
  };
@@ -0,0 +1,36 @@
1
+ import { Common } from '@strapi/strapi';
2
+ import { PLATFORM_UID } from '../../shared/utils/constants';
3
+
4
+ export default {
5
+ async findAll() {
6
+ return await strapi.entityService.findMany(PLATFORM_UID, { populate: '*' });
7
+ },
8
+ async findOneByUid(uid: Common.UID.ContentType) {
9
+ return await strapi.entityService.findMany(PLATFORM_UID, {
10
+ populate: '*',
11
+ filters: {
12
+ pagetype: {
13
+ uid
14
+ }
15
+ }
16
+ });
17
+ },
18
+ async findPageTypesByPlatform(platform: string) {
19
+ const results = await strapi.entityService.findMany(PLATFORM_UID, {
20
+ populate: {
21
+ pagetype: true
22
+ },
23
+ filters: {
24
+ title: {
25
+ $eq: platform
26
+ }
27
+ }
28
+ });
29
+
30
+ if ((results as any[]).length > 0) {
31
+ return results;
32
+ } else {
33
+ return null;
34
+ }
35
+ }
36
+ };
@@ -1,4 +1,6 @@
1
1
  export const PAGE_UID = 'api::page.page';
2
2
  export const TEMPLATE_UID = 'api::template.template';
3
3
  export const PAGE_TYPE_UID = 'api::page-type.page-type';
4
+ export const PLATFORM_UID = 'api::platform.platform';
4
5
  export const PAGE_TYPE_PAGE = 'page';
6
+ export const PLATFORM = 'platform';
@@ -1,17 +0,0 @@
1
- import React from 'react';
2
- import { useLocation } from 'react-router-dom';
3
-
4
- import { PageTypeFilter } from './page-type-filter';
5
- import { PAGE_UID } from '../../../../shared/utils/constants';
6
-
7
- const PageTypeFilterContainer = () => {
8
- const { pathname } = useLocation();
9
-
10
- if (pathname === `/content-manager/collectionType/${PAGE_UID}`) {
11
- return <PageTypeFilter />;
12
- }
13
-
14
- return null;
15
- };
16
-
17
- export default PageTypeFilterContainer;
@@ -1,130 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import set from 'lodash/set';
3
-
4
- import { SingleSelectOption, SingleSelect } from '@strapi/design-system';
5
- import { useQueryParams } from '@strapi/helper-plugin';
6
-
7
- import { useGetPageTypes } from '../../api/page-type';
8
- import { PAGE_TYPE_NO_FILTER } from '../../constants';
9
- import { PAGE_TYPE_PAGE } from '../../../../shared/utils/constants';
10
-
11
- const PageTypeFilter = () => {
12
- const [{ query }, setQuery] = useQueryParams();
13
- const { data: pageTypes } = useGetPageTypes({});
14
- const initialPageTypeUid = getInitialPageType(query, pageTypes);
15
- const [selectedPageTypeUid, setSelectedPageTypeUid] = useState(initialPageTypeUid);
16
-
17
- const removeFilters = () => {
18
- const newAndFilters = query.filters?.$and?.filter(
19
- (x?: Record<string, any>) => Object.keys(x || {})?.[0] !== 'pageType'
20
- );
21
- const filters = { ...query.filters, $and: newAndFilters };
22
-
23
- if (newAndFilters && newAndFilters.length === 0) {
24
- delete filters.$and;
25
- }
26
-
27
- setQuery({
28
- page: 1,
29
- filters
30
- });
31
- };
32
-
33
- const handleFilterChange = (filters: Record<string, any>) => {
34
- const currentFilters = query.filters?.$and ? query.filters : { ...query.filters, $and: [] }; // Make sure $and exists.
35
- const pageTypeFilterIndex = currentFilters.$and.findIndex(
36
- (x?: Record<string, any>) => Object.keys(x || {})?.[0] === 'pageType'
37
- );
38
-
39
- if (pageTypeFilterIndex > -1) {
40
- set(currentFilters, `$and[${pageTypeFilterIndex}]`, filters); // If the pageType filter already exists, replace it
41
- } else {
42
- currentFilters.$and.push(filters);
43
- }
44
-
45
- setQuery({
46
- page: 1,
47
- filters: currentFilters
48
- });
49
- };
50
-
51
- const handleSelect = (value: string) => {
52
- setSelectedPageTypeUid(value);
53
-
54
- if (value === 'all') {
55
- removeFilters();
56
- return;
57
- }
58
-
59
- if (value === PAGE_TYPE_PAGE) {
60
- handleFilterChange(nullPageTypeQueryFilter);
61
- return;
62
- }
63
-
64
- handleFilterChange(getPageTypeQueryFilter(value));
65
- };
66
-
67
- useEffect(() => {
68
- setSelectedPageTypeUid(getInitialPageType(query, pageTypes));
69
- }, [pageTypes]);
70
-
71
- useEffect(() => {
72
- if (!query?.filters) {
73
- setSelectedPageTypeUid(null);
74
- }
75
- }, [query]);
76
-
77
- return (
78
- <SingleSelect placeholder="Select page type" onChange={handleSelect} size="S" value={selectedPageTypeUid}>
79
- <SingleSelectOption key={PAGE_TYPE_NO_FILTER} value={PAGE_TYPE_NO_FILTER}>
80
- All Pagetypes
81
- </SingleSelectOption>
82
- <SingleSelectOption key={PAGE_TYPE_PAGE} value={PAGE_TYPE_PAGE}>
83
- Page
84
- </SingleSelectOption>
85
- {pageTypes?.map((pageType) => (
86
- <SingleSelectOption key={pageType.uid} value={pageType.uid}>
87
- {pageType.title || pageType.uid}
88
- </SingleSelectOption>
89
- ))}
90
- </SingleSelect>
91
- );
92
- };
93
-
94
- export { PageTypeFilter };
95
-
96
- const getPageTypeQueryFilter = (pageType: string) => ({
97
- pageType: {
98
- uid: {
99
- $eq: pageType
100
- }
101
- }
102
- });
103
-
104
- const nullPageTypeQueryFilter = {
105
- pageType: {
106
- uid: {
107
- $null: true
108
- }
109
- }
110
- };
111
-
112
- const getInitialPageType = (query: any, pageTypes: any) => {
113
- const pageTypeFromQuery = query?.filters?.$and?.find(
114
- (x?: Record<string, any>) => Object.keys(x || {})?.[0] === 'pageType'
115
- )?.pageType;
116
-
117
- if (pageTypeFromQuery?.uid?.$null === 'true') {
118
- return PAGE_TYPE_PAGE;
119
- }
120
-
121
- if (pageTypeFromQuery?.uid?.$eq) {
122
- const matchingPageType = pageTypes?.find((pageType: any) => pageType?.uid === pageTypeFromQuery.uid.$eq);
123
-
124
- if (matchingPageType) {
125
- return matchingPageType.uid;
126
- }
127
- }
128
-
129
- return PAGE_TYPE_NO_FILTER;
130
- };