@webbio/strapi-plugin-page-builder 0.0.12 → 0.0.13

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 (75) hide show
  1. package/.prettierignore +17 -0
  2. package/admin/src/api/collection-type.ts +110 -0
  3. package/admin/src/api/has-page-relation.ts +34 -0
  4. package/admin/src/api/page-type.ts +31 -0
  5. package/admin/src/api/template.ts +25 -0
  6. package/admin/src/components/Combobox/index.tsx +77 -0
  7. package/admin/src/components/Combobox/react-select-custom-styles.tsx +111 -0
  8. package/admin/src/components/Combobox/styles.ts +22 -0
  9. package/admin/src/components/ConfirmModal/index.tsx +90 -0
  10. package/admin/src/components/EditView/CollectionTypeSearch/index.tsx +118 -0
  11. package/admin/src/components/EditView/CollectionTypeSettings/CreatePageButton/index.tsx +95 -0
  12. package/admin/src/components/EditView/CollectionTypeSettings/CreatePageButton/styles.ts +26 -0
  13. package/admin/src/components/EditView/CollectionTypeSettings/index.tsx +53 -0
  14. package/admin/src/components/EditView/Details/index.tsx +47 -0
  15. package/admin/src/components/EditView/Details/styles.ts +51 -0
  16. package/admin/src/components/EditView/PageSettings/index.tsx +104 -0
  17. package/admin/src/components/EditView/Template/TemplateConfirmModal/index.tsx +36 -0
  18. package/admin/src/components/EditView/Template/TemplateSelect/index.tsx +64 -0
  19. package/admin/src/components/EditView/Template/TemplateSelect/use-template-modules.ts +30 -0
  20. package/admin/src/components/EditView/index.tsx +27 -0
  21. package/admin/src/components/EditView/page-type-select.tsx +30 -0
  22. package/admin/src/components/EditView/wrapper.tsx +35 -0
  23. package/admin/src/components/Initializer/index.tsx +24 -0
  24. package/admin/src/components/PageTypeFilter/index.tsx +17 -0
  25. package/admin/src/components/PageTypeFilter/page-type-filter.tsx +130 -0
  26. package/admin/src/components/PluginIcon/index.tsx +12 -0
  27. package/admin/src/constants.ts +1 -0
  28. package/admin/src/index.tsx +115 -0
  29. package/admin/src/pages/App/index.tsx +25 -0
  30. package/admin/src/pages/HomePage/index.tsx +19 -0
  31. package/admin/src/pluginId.ts +5 -0
  32. package/admin/src/redux/initialData.reducer.ts +0 -0
  33. package/admin/src/translations/en.json +6 -0
  34. package/admin/src/translations/nl.json +6 -0
  35. package/admin/src/utils/getRequestUrl.ts +11 -0
  36. package/admin/src/utils/getTrad.ts +5 -0
  37. package/admin/src/utils/hooks/useDebounce.ts +17 -0
  38. package/admin/src/utils/hooks/useGetLocaleFromUrl.ts +9 -0
  39. package/admin/src/utils/hooks/usePrevious.ts +12 -0
  40. package/admin/src/utils/sanitizeModules.ts +10 -0
  41. package/custom.d.ts +5 -0
  42. package/dist/package.json +1 -1
  43. package/dist/tsconfig.server.tsbuildinfo +1 -1
  44. package/package.json +1 -5
  45. package/server/bootstrap.ts +106 -0
  46. package/server/config/index.ts +4 -0
  47. package/server/content-types/index.ts +1 -0
  48. package/server/controllers/collection-types.ts +27 -0
  49. package/server/controllers/index.ts +9 -0
  50. package/server/controllers/page-type.ts +12 -0
  51. package/server/controllers/page.ts +20 -0
  52. package/server/destroy.ts +5 -0
  53. package/server/index.ts +23 -0
  54. package/server/middlewares/index.ts +1 -0
  55. package/server/policies/index.ts +1 -0
  56. package/server/register.ts +5 -0
  57. package/server/routes/index.ts +42 -0
  58. package/server/schema/page-end.json +97 -0
  59. package/server/schema/page-start.json +87 -0
  60. package/server/schema/page-type-end.json +49 -0
  61. package/server/schema/page-type-start.json +44 -0
  62. package/server/schema/template.json +35 -0
  63. package/server/services/builder.ts +121 -0
  64. package/server/services/collection-types.ts +49 -0
  65. package/server/services/index.ts +11 -0
  66. package/server/services/page-type.ts +22 -0
  67. package/server/services/page.ts +24 -0
  68. package/server/utils/graphql.ts +110 -0
  69. package/server/utils/reload-strapi-on-load.ts +13 -0
  70. package/shared/utils/constants.ts +4 -0
  71. package/shared/utils/sleep.ts +1 -0
  72. package/strapi-admin.js +3 -0
  73. package/strapi-server.js +3 -0
  74. package/tsconfig.json +20 -0
  75. package/tsconfig.server.json +25 -0
@@ -0,0 +1,106 @@
1
+ import { Strapi } from '@strapi/strapi';
2
+ import { errors } from '@strapi/utils';
3
+
4
+ import { PAGE_UID } from '../shared/utils/constants';
5
+
6
+ export default async ({ strapi }: { strapi: Strapi }) => {
7
+ // TODO: refactor to own function
8
+ try {
9
+ const pageTypes = await strapi.entityService.findMany('api::page-type.page-type', {
10
+ limit: -1
11
+ });
12
+ const pagePermissions = pageTypes.map((pageType) => {
13
+ const name = `page-type-is-${pageType.uid}`;
14
+ const displayName = pageType.title;
15
+
16
+ return {
17
+ plugin: 'page-builder',
18
+ name,
19
+ displayName,
20
+ category: 'Page type',
21
+ handler: async () => {
22
+ return {
23
+ $or: [
24
+ {
25
+ 'pageType.uid': {
26
+ $eq: pageType.uid
27
+ }
28
+ },
29
+ {
30
+ uid: {
31
+ $eq: pageType.uid
32
+ }
33
+ }
34
+ ]
35
+ };
36
+ }
37
+ };
38
+ });
39
+ // @ts-ignore shitty types
40
+ await strapi.admin.services.permission.conditionProvider.registerMany(pagePermissions);
41
+ } catch {
42
+ console.log('Cannot set page permissions');
43
+ }
44
+
45
+ const updateCollectionTypeData = (data: any, collectionTypeId: number, uid: string) => {
46
+ data.collectionTypeData = {
47
+ id: collectionTypeId,
48
+ __type: uid,
49
+ __pivot: {
50
+ field: 'page'
51
+ }
52
+ };
53
+
54
+ return data;
55
+ };
56
+
57
+ strapi.db.lifecycles.subscribe({
58
+ // @ts-ignore
59
+ models: [PAGE_UID],
60
+ async beforeCreate(event) {
61
+ let { data } = event.params;
62
+ const collectionTypeId = data?.collectionTypeId;
63
+ const pageTypeId = data?.pageType.connect?.[0]?.id || data.initialPageType;
64
+
65
+ if (collectionTypeId && pageTypeId) {
66
+ const { uid } = await strapi.entityService.findOne('api::page-type.page-type', pageTypeId);
67
+ const collectionToConnect = await strapi.entityService.findOne(uid, collectionTypeId, {
68
+ populate: { page: true }
69
+ });
70
+
71
+ if (collectionToConnect.page && collectionToConnect.page.length > 0) {
72
+ throw new errors.ValidationError('You can only link one CollectionType to one page');
73
+ }
74
+
75
+ data = updateCollectionTypeData(data, collectionTypeId, uid);
76
+ }
77
+ },
78
+ async beforeUpdate(event) {
79
+ let data = event?.params?.data;
80
+ const collectionTypeId = data?.collectionTypeId;
81
+ const pageTypeId = data?.pageType?.connect?.[0]?.id || data?.initialPageType;
82
+ const removedPageType = data?.pageType?.disconnect?.[0]?.id;
83
+
84
+ if (removedPageType || collectionTypeId === null) {
85
+ data.collectionTypeData = undefined;
86
+ }
87
+
88
+ if (collectionTypeId && pageTypeId && !removedPageType) {
89
+ const { uid } = await strapi.entityService.findOne('api::page-type.page-type', pageTypeId);
90
+ const collectionToConnect = await strapi.entityService.findOne(uid, collectionTypeId, {
91
+ populate: { page: true }
92
+ });
93
+
94
+ if (
95
+ collectionToConnect.page &&
96
+ collectionToConnect.page.length > 0 &&
97
+ !collectionToConnect?.page.some((p) => p.id === data.id)
98
+ ) {
99
+ throw new errors.ValidationError('You can only link one CollectionType to one page');
100
+ }
101
+
102
+ data = updateCollectionTypeData(data, collectionTypeId, uid);
103
+ }
104
+ }
105
+ });
106
+ };
@@ -0,0 +1,4 @@
1
+ export default {
2
+ default: {},
3
+ validator() {}
4
+ };
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1,27 @@
1
+ export default {
2
+ async hasPageRelation(ctx: any) {
3
+ const uid = ctx.params?.uid;
4
+
5
+ // @ts-ignore
6
+ return strapi.service('plugin::page-builder.collection-types').hasPageRelation(uid);
7
+ },
8
+ async getTranslationPageLinks(ctx: any): Promise<IGetTranslationPageLinks[] | undefined> {
9
+ const { uid, ids } = ctx.params || {};
10
+ const idsArr = (ids as string)
11
+ ?.split(',')
12
+ .map(Number)
13
+ .filter((x) => !isNaN(x));
14
+
15
+ if (!uid || idsArr?.length === 0) {
16
+ return undefined;
17
+ }
18
+
19
+ // @ts-ignore
20
+ return strapi.service('plugin::page-builder.collection-types').getTranslationPageLinks(uid, idsArr);
21
+ }
22
+ };
23
+
24
+ export interface IGetTranslationPageLinks {
25
+ id: number;
26
+ locale: string;
27
+ }
@@ -0,0 +1,9 @@
1
+ import page from './page';
2
+ import pageType from './page-type';
3
+ import collectionTypes from './collection-types';
4
+
5
+ export default {
6
+ page,
7
+ 'page-type': pageType,
8
+ 'collection-types': collectionTypes
9
+ };
@@ -0,0 +1,12 @@
1
+ export default {
2
+ async findOneByUid(ctx: any) {
3
+ const uid = ctx?.params?.uid;
4
+
5
+ if (!uid) {
6
+ return ctx.badRequest('uid is missing.');
7
+ }
8
+
9
+ // @ts-ignore strapi typings
10
+ return await strapi.service('plugin::page-builder.page-type').findOneByUid(uid);
11
+ }
12
+ };
@@ -0,0 +1,20 @@
1
+ import { Strapi } from '@strapi/strapi';
2
+
3
+ import { PAGE_UID } from '../../shared/utils/constants';
4
+
5
+ export default {
6
+ async getPage(ctx) {
7
+ const id = ctx.params?.id;
8
+
9
+ return (strapi as Strapi).service('plugin::page-builder.page')?.getPage(id);
10
+ },
11
+
12
+ async findOneBySlug(ctx) {
13
+ const { slug = '' } = ctx.params;
14
+
15
+ const entity = await (strapi as Strapi).service(PAGE_UID)?.find({ filters: { slug } });
16
+ const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
17
+
18
+ return this.transformResponse(sanitizedEntity);
19
+ }
20
+ };
@@ -0,0 +1,5 @@
1
+ import { Strapi } from '@strapi/strapi';
2
+
3
+ export default ({ strapi }: { strapi: Strapi }) => {
4
+ // destroy phase
5
+ };
@@ -0,0 +1,23 @@
1
+ import register from './register';
2
+ import bootstrap from './bootstrap';
3
+ import destroy from './destroy';
4
+ import config from './config';
5
+ import contentTypes from './content-types';
6
+ import controllers from './controllers';
7
+ import routes from './routes';
8
+ import middlewares from './middlewares';
9
+ import policies from './policies';
10
+ import services from './services';
11
+
12
+ export default {
13
+ register,
14
+ bootstrap,
15
+ destroy,
16
+ config,
17
+ controllers,
18
+ routes,
19
+ services,
20
+ contentTypes,
21
+ policies,
22
+ middlewares
23
+ };
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1 @@
1
+ export default {};
@@ -0,0 +1,5 @@
1
+ import { Strapi } from '@strapi/strapi';
2
+
3
+ export default async ({ strapi }: { strapi: Strapi }) => {
4
+ await strapi.services?.['plugin::page-builder.builder']?.buildContentTypes();
5
+ };
@@ -0,0 +1,42 @@
1
+ const routes = {
2
+ 'page-type': {
3
+ type: 'admin',
4
+ prefix: undefined,
5
+ routes: [
6
+ {
7
+ method: 'GET',
8
+ path: '/page-types/:uid',
9
+ handler: 'page-type.findOneByUid'
10
+ }
11
+ ]
12
+ },
13
+ page: {
14
+ type: 'admin',
15
+ prefix: undefined,
16
+ routes: [
17
+ {
18
+ method: 'GET',
19
+ path: '/page/:id',
20
+ handler: 'page.getPage'
21
+ }
22
+ ]
23
+ },
24
+ 'collection-types': {
25
+ type: 'admin',
26
+ prefix: undefined,
27
+ routes: [
28
+ {
29
+ method: 'GET',
30
+ path: '/collection-types/:uid',
31
+ handler: 'collection-types.hasPageRelation'
32
+ },
33
+ {
34
+ method: 'GET',
35
+ path: '/collection-types-page-links/:uid/:ids?',
36
+ handler: 'collection-types.getTranslationPageLinks'
37
+ }
38
+ ]
39
+ }
40
+ };
41
+
42
+ export default routes;
@@ -0,0 +1,97 @@
1
+ {
2
+ "draftAndPublish": true,
3
+ "displayName": "Pagina's",
4
+ "singularName": "page",
5
+ "pluralName": "pages",
6
+ "description": "",
7
+ "plugin": "page-builder",
8
+ "pluginOptions": {
9
+ "i18n": {
10
+ "localized": true
11
+ }
12
+ },
13
+ "kind": "collectionType",
14
+ "collectionName": "pages",
15
+ "attributes": {
16
+ "collectionTypeData": {
17
+ "type": "relation",
18
+ "relation": "morphToMany",
19
+ "configurable": false
20
+ },
21
+ "title": {
22
+ "pluginOptions": {
23
+ "i18n": {
24
+ "localized": true
25
+ }
26
+ },
27
+ "type": "string",
28
+ "required": true
29
+ },
30
+ "slug": {
31
+ "pluginOptions": {
32
+ "i18n": {
33
+ "localized": true
34
+ },
35
+ "slug": {
36
+ "field": "slug",
37
+ "targetField": "title"
38
+ }
39
+ },
40
+ "type": "customField",
41
+ "customField": "plugin::slug.slug",
42
+ "required": true
43
+ },
44
+ "path": {
45
+ "pluginOptions": {
46
+ "i18n": {
47
+ "localized": true
48
+ }
49
+ },
50
+ "type": "string",
51
+ "required": false
52
+ },
53
+ "parent": {
54
+ "type": "relation",
55
+ "relation": "oneToOne",
56
+ "target": "api::page.page",
57
+ "private": false
58
+ },
59
+ "excerpt": {
60
+ "pluginOptions": {
61
+ "i18n": {
62
+ "localized": true
63
+ }
64
+ },
65
+ "type": "text"
66
+ },
67
+ "modules": {
68
+ "pluginOptions": {
69
+ "i18n": {
70
+ "localized": true
71
+ }
72
+ },
73
+ "type": "dynamiczone",
74
+ "components": []
75
+ },
76
+ "seo": {
77
+ "type": "component",
78
+ "pluginOptions": {
79
+ "i18n": {
80
+ "localized": true
81
+ }
82
+ },
83
+ "component": "shared.seo"
84
+ },
85
+ "template": {
86
+ "relation": "manyToOne",
87
+ "target": "api::template.template",
88
+ "targetAttribute": "pages",
89
+ "type": "relation"
90
+ },
91
+ "pageType": {
92
+ "type": "relation",
93
+ "relation": "oneToOne",
94
+ "target": "api::page-type.page-type"
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "draftAndPublish": true,
3
+ "displayName": "Pagina's",
4
+ "singularName": "page",
5
+ "pluralName": "pages",
6
+ "description": "",
7
+ "plugin": "page-builder",
8
+ "pluginOptions": {
9
+ "i18n": {
10
+ "localized": true
11
+ }
12
+ },
13
+ "kind": "collectionType",
14
+ "collectionName": "pages",
15
+ "attributes": {
16
+ "collectionTypeData": {
17
+ "type": "relation",
18
+ "relation": "morphToMany",
19
+ "configurable": false,
20
+ "private": false
21
+ },
22
+ "title": {
23
+ "pluginOptions": {
24
+ "i18n": {
25
+ "localized": true
26
+ }
27
+ },
28
+ "type": "string",
29
+ "required": true
30
+ },
31
+ "slug": {
32
+ "pluginOptions": {
33
+ "i18n": {
34
+ "localized": true
35
+ },
36
+ "slug": {
37
+ "field": "slug",
38
+ "targetField": "title"
39
+ }
40
+ },
41
+ "type": "customField",
42
+ "customField": "plugin::slug.slug",
43
+ "required": true
44
+ },
45
+ "path": {
46
+ "pluginOptions": {
47
+ "i18n": {
48
+ "localized": true
49
+ }
50
+ },
51
+ "type": "string",
52
+ "required": false
53
+ },
54
+ "parent": {
55
+ "type": "relation",
56
+ "relation": "oneToOne",
57
+ "target": "api::page.page",
58
+ "private": false
59
+ },
60
+ "excerpt": {
61
+ "pluginOptions": {
62
+ "i18n": {
63
+ "localized": true
64
+ }
65
+ },
66
+ "type": "text"
67
+ },
68
+ "modules": {
69
+ "pluginOptions": {
70
+ "i18n": {
71
+ "localized": true
72
+ }
73
+ },
74
+ "type": "dynamiczone",
75
+ "components": []
76
+ },
77
+ "seo": {
78
+ "type": "component",
79
+ "pluginOptions": {
80
+ "i18n": {
81
+ "localized": true
82
+ }
83
+ },
84
+ "component": "shared.seo"
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "draftAndPublish": false,
3
+ "displayName": "Pagina Types",
4
+ "singularName": "page-type",
5
+ "pluralName": "page-types",
6
+ "description": "",
7
+ "plugin": "page-builder",
8
+ "pluginOptions": {
9
+ "i18n": {
10
+ "localized": true
11
+ }
12
+ },
13
+ "kind": "collectionType",
14
+ "collectionName": "page_types",
15
+ "attributes": {
16
+ "uid": {
17
+ "type": "string",
18
+ "required": true,
19
+ "unique": true,
20
+ "pluginOptions": {
21
+ "i18n": {
22
+ "localized": true
23
+ }
24
+ }
25
+ },
26
+ "title": {
27
+ "type": "string",
28
+ "pluginOptions": {
29
+ "i18n": {
30
+ "localized": true
31
+ }
32
+ }
33
+ },
34
+ "modules": {
35
+ "type": "dynamiczone",
36
+ "components": [],
37
+ "pluginOptions": {
38
+ "i18n": {
39
+ "localized": true
40
+ }
41
+ }
42
+ },
43
+ "template": {
44
+ "type": "relation",
45
+ "relation": "oneToOne",
46
+ "target": "api::template.template"
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "draftAndPublish": false,
3
+ "displayName": "Pagina Types",
4
+ "singularName": "page-type",
5
+ "pluralName": "page-types",
6
+ "description": "",
7
+ "plugin": "page-builder",
8
+ "pluginOptions": {
9
+ "i18n": {
10
+ "localized": true
11
+ }
12
+ },
13
+ "kind": "collectionType",
14
+ "collectionName": "page_types",
15
+ "attributes": {
16
+ "uid": {
17
+ "type": "string",
18
+ "required": true,
19
+ "unique": true,
20
+ "pluginOptions": {
21
+ "i18n": {
22
+ "localized": true
23
+ }
24
+ }
25
+ },
26
+ "title": {
27
+ "type": "string",
28
+ "pluginOptions": {
29
+ "i18n": {
30
+ "localized": true
31
+ }
32
+ }
33
+ },
34
+ "modules": {
35
+ "type": "dynamiczone",
36
+ "components": [],
37
+ "pluginOptions": {
38
+ "i18n": {
39
+ "localized": true
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "draftAndPublish": false,
3
+ "displayName": "Templates",
4
+ "singularName": "template",
5
+ "pluralName": "templates",
6
+ "description": "",
7
+ "plugin": "page-builder",
8
+ "pluginOptions": {
9
+ "i18n": {
10
+ "localized": true
11
+ }
12
+ },
13
+ "kind": "collectionType",
14
+ "collectionName": "templates",
15
+ "attributes": {
16
+ "title": {
17
+ "type": "string",
18
+ "required": true,
19
+ "pluginOptions": {
20
+ "i18n": {
21
+ "localized": true
22
+ }
23
+ }
24
+ },
25
+ "modules": {
26
+ "type": "dynamiczone",
27
+ "components": [],
28
+ "pluginOptions": {
29
+ "i18n": {
30
+ "localized": true
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }