@webbio/strapi-plugin-page-builder 0.9.0-platform → 0.9.2-platform
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/admin/src/components/PlatformFilteredSelectField/Multi/index.tsx +1 -0
- package/admin/src/components/PlatformFilteredSelectField/hooks/useRelationLoad.tsx +4 -2
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/components/Relations/RelationInput.tsx +1 -2
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/components/Relations/useRelation.ts +170 -0
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/components/Relations/utils/getRelationLink.ts +5 -0
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/components/Relations/utils/normalizeRelations.ts +52 -0
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/hooks/useDragAndDrop.ts +2 -2
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/hooks/useKeyboardDragAndDrop.ts +69 -69
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/hooks/usePrev.ts +5 -5
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/utils/dragAndDrop.ts +6 -6
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/utils/paths.ts +14 -21
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/utils/refs.ts +6 -6
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/collection-types.ts +207 -207
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/components.ts +42 -42
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/content-types.ts +74 -74
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/init.ts +12 -12
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/relations.ts +57 -57
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/review-workflows.ts +52 -52
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/single-types.ts +65 -65
- package/admin/src/components/StrapiCore/content-manager/shared/contracts/uid.ts +31 -31
- package/dist/package.json +1 -1
- package/dist/server/bootstrap/permissions.js +97 -69
- package/dist/server/middlewares/mikkel.js +35 -0
- package/dist/server/policies/platformSelector.js +18 -0
- package/dist/server/utils/graphql.js +100 -0
- package/dist/server/utils/paginationValidation.js +31 -0
- package/dist/tsconfig.server.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/server/bootstrap/permissions.ts +103 -72
- package/admin/src/components/StrapiCore/admin/admin/src/content-manager/utils/normalizeRelations.ts +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { useRelation } from '
|
|
4
|
-
import { getInitialDataPathUsingTempKeys } from '
|
|
3
|
+
import { useRelation } from '../../StrapiCore/admin/admin/src/content-manager/components/Relations/useRelation';
|
|
4
|
+
import { getInitialDataPathUsingTempKeys } from '../../StrapiCore/admin/admin/src/content-manager/utils/paths';
|
|
5
5
|
import RelationHelper, { IPlatformFilteredSelectFieldProps } from '../utils/relation-helper';
|
|
6
6
|
import { useCMEditViewDataManager } from '@strapi/helper-plugin';
|
|
7
7
|
import { useRouteMatch } from 'react-router-dom';
|
|
@@ -73,8 +73,10 @@ const useRelationLoad = ({ name, attribute }: IPlatformFilteredSelectFieldProps)
|
|
|
73
73
|
});
|
|
74
74
|
},
|
|
75
75
|
normalizeArguments: {
|
|
76
|
+
// @ts-expect-error
|
|
76
77
|
mainFieldName: relationMainFieldName,
|
|
77
78
|
shouldAddLink: true,
|
|
79
|
+
// @ts-expect-error
|
|
78
80
|
targetModel: targetAttributes?.targetModel
|
|
79
81
|
}
|
|
80
82
|
},
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
import * as React from 'react';
|
|
4
2
|
|
|
5
3
|
import {
|
|
@@ -549,6 +547,7 @@ const LinkEllipsis = styled(Link)`
|
|
|
549
547
|
|
|
550
548
|
interface RelationItemProps
|
|
551
549
|
extends Pick<UseDragAndDropOptions, 'onCancel' | 'onDropItem' | 'onGrabItem'>,
|
|
550
|
+
// @ts-ignore
|
|
552
551
|
Omit<FlexProps, 'id' | 'style'>,
|
|
553
552
|
Pick<ListChildComponentProps, 'style' | 'index'> {
|
|
554
553
|
ariaDescribedBy: string;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// @ts-nocheck build compiler thinks differently than runtime compiler
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useCallbackRef, useFetchClient } from '@strapi/helper-plugin';
|
|
5
|
+
import { useInfiniteQuery } from 'react-query';
|
|
6
|
+
|
|
7
|
+
import { NormalizeRelationArgs, NormalizedRelation, normalizeRelations } from './utils/normalizeRelations';
|
|
8
|
+
|
|
9
|
+
import type { Contracts } from '../../../../../../content-manager/shared';
|
|
10
|
+
|
|
11
|
+
interface UseRelationArgs {
|
|
12
|
+
relation: {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
endpoint: string;
|
|
15
|
+
normalizeArguments: NormalizeRelationArgs;
|
|
16
|
+
onLoad: (data: NormalizedRelation[]) => void;
|
|
17
|
+
pageParams?: Record<string, any>;
|
|
18
|
+
pageGoal?: number;
|
|
19
|
+
};
|
|
20
|
+
search: {
|
|
21
|
+
endpoint: string;
|
|
22
|
+
pageParams?: Record<string, any>;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const useRelation = (cacheKey: any[] = [], { relation, search }: UseRelationArgs) => {
|
|
27
|
+
const [searchParams, setSearchParams] = useState({});
|
|
28
|
+
const [currentPage, setCurrentPage] = useState(0);
|
|
29
|
+
const { get } = useFetchClient();
|
|
30
|
+
|
|
31
|
+
const { onLoad: onLoadRelations, normalizeArguments } = relation;
|
|
32
|
+
|
|
33
|
+
const relationsRes = useInfiniteQuery(
|
|
34
|
+
['relation', ...cacheKey],
|
|
35
|
+
async ({ pageParam = 1 }) => {
|
|
36
|
+
try {
|
|
37
|
+
const { data } = await get<Contracts.Relations.FindExisting.Response>(relation?.endpoint, {
|
|
38
|
+
params: {
|
|
39
|
+
...(relation.pageParams ?? {}),
|
|
40
|
+
page: pageParam
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
setCurrentPage(pageParam);
|
|
45
|
+
|
|
46
|
+
return data;
|
|
47
|
+
} catch (err) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
cacheTime: 0,
|
|
53
|
+
enabled: relation.enabled,
|
|
54
|
+
getNextPageParam(lastPage) {
|
|
55
|
+
const isXToOneRelation = lastPage && !('pagination' in lastPage);
|
|
56
|
+
|
|
57
|
+
if (
|
|
58
|
+
!lastPage || // the API may send an empty 204 response
|
|
59
|
+
isXToOneRelation || // xToOne relations do not have a pagination
|
|
60
|
+
lastPage?.pagination.page >= lastPage?.pagination.pageCount
|
|
61
|
+
) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// eslint-disable-next-line consistent-return
|
|
66
|
+
return lastPage.pagination.page + 1;
|
|
67
|
+
},
|
|
68
|
+
select: (data) => ({
|
|
69
|
+
...data,
|
|
70
|
+
pages: data.pages.map((page) => {
|
|
71
|
+
if (!page) {
|
|
72
|
+
return page;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let normalizedResults: Contracts.Relations.RelationResult[] = [];
|
|
76
|
+
|
|
77
|
+
// xToOne relations return an object, which we normalize so that relations
|
|
78
|
+
// always have the same shape
|
|
79
|
+
if ('data' in page && page.data) {
|
|
80
|
+
normalizedResults = [page.data];
|
|
81
|
+
} else if ('results' in page && page.results) {
|
|
82
|
+
normalizedResults = [...page.results].reverse();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
pagination: 'pagination' in page ? page.pagination : undefined,
|
|
87
|
+
results: normalizedResults
|
|
88
|
+
};
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const { pageGoal } = relation;
|
|
95
|
+
|
|
96
|
+
const { status, data, fetchNextPage, hasNextPage } = relationsRes;
|
|
97
|
+
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
/**
|
|
100
|
+
* This ensures the infiniteQuery hook fetching has caught-up with the modifiedData
|
|
101
|
+
* state i.e. in circumstances where you add 10 relations, the browserState knows this,
|
|
102
|
+
* but the hook would think it could fetch more, when in reality, it can't.
|
|
103
|
+
*/
|
|
104
|
+
if (pageGoal && pageGoal > currentPage && hasNextPage && status === 'success') {
|
|
105
|
+
fetchNextPage({
|
|
106
|
+
pageParam: currentPage + 1
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}, [pageGoal, currentPage, fetchNextPage, hasNextPage, status]);
|
|
110
|
+
|
|
111
|
+
const onLoadRelationsCallback = useCallbackRef(onLoadRelations);
|
|
112
|
+
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (status === 'success' && data && data.pages?.at(-1)?.results && onLoadRelationsCallback) {
|
|
115
|
+
// everytime we fetch, we normalize prior to adding to redux
|
|
116
|
+
const normalizedResults = normalizeRelations(data.pages.at(-1)?.results ?? [], normalizeArguments);
|
|
117
|
+
|
|
118
|
+
// this is loadRelation from EditViewDataManagerProvider
|
|
119
|
+
onLoadRelationsCallback(normalizedResults);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
123
|
+
}, [status, onLoadRelationsCallback, data]);
|
|
124
|
+
|
|
125
|
+
const searchRes = useInfiniteQuery(
|
|
126
|
+
['relation', ...cacheKey, 'search', JSON.stringify(searchParams)],
|
|
127
|
+
async ({ pageParam = 1 }) => {
|
|
128
|
+
try {
|
|
129
|
+
const { data } = await get<Contracts.Relations.FindAvailable.Response>(search.endpoint, {
|
|
130
|
+
params: {
|
|
131
|
+
...(search.pageParams ?? {}),
|
|
132
|
+
...searchParams,
|
|
133
|
+
page: pageParam
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return data;
|
|
138
|
+
} catch (err) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
enabled: Object.keys(searchParams).length > 0,
|
|
144
|
+
getNextPageParam(lastPage) {
|
|
145
|
+
if (
|
|
146
|
+
!lastPage?.pagination ||
|
|
147
|
+
(lastPage.pagination && lastPage.pagination.page >= lastPage.pagination.pageCount)
|
|
148
|
+
) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// eslint-disable-next-line consistent-return
|
|
153
|
+
return lastPage.pagination.page + 1;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const searchFor = (term: string, options: object = {}) => {
|
|
159
|
+
setSearchParams({
|
|
160
|
+
...options,
|
|
161
|
+
_q: term,
|
|
162
|
+
_filter: '$containsi'
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
return { relations: relationsRes, search: searchRes, searchFor };
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export { useRelation };
|
|
170
|
+
export type { UseRelationArgs };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// @ts-nocheck build compiler thinks differently than runtime compiler
|
|
2
|
+
import type { Contracts } from '../../../../../../../content-manager/shared';
|
|
3
|
+
|
|
4
|
+
import { PUBLICATION_STATES } from '../RelationInputDataManager';
|
|
5
|
+
|
|
6
|
+
import { getRelationLink } from './getRelationLink';
|
|
7
|
+
|
|
8
|
+
export interface NormalizeRelationArgs {
|
|
9
|
+
shouldAddLink: boolean;
|
|
10
|
+
mainFieldName: string;
|
|
11
|
+
targetModel: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type NormalizedRelation = Contracts.Relations.RelationResult & {
|
|
15
|
+
href?: string;
|
|
16
|
+
mainField: string;
|
|
17
|
+
publicationState?: false | 'published' | 'draft';
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const normalizeRelation = (
|
|
21
|
+
relation: Contracts.Relations.RelationResult,
|
|
22
|
+
{ shouldAddLink, mainFieldName, targetModel }: NormalizeRelationArgs
|
|
23
|
+
) => {
|
|
24
|
+
const nextRelation: NormalizedRelation = {
|
|
25
|
+
...relation,
|
|
26
|
+
mainField: relation[mainFieldName]
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
if (shouldAddLink) {
|
|
30
|
+
nextRelation.href = getRelationLink(targetModel, nextRelation.id);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
nextRelation.publicationState = false;
|
|
34
|
+
|
|
35
|
+
if (nextRelation?.publishedAt !== undefined) {
|
|
36
|
+
nextRelation.publicationState = nextRelation.publishedAt ? PUBLICATION_STATES.PUBLISHED : PUBLICATION_STATES.DRAFT;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return nextRelation;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* Applies some transformations to existing and new relations in order to display them correctly
|
|
44
|
+
* relations: raw relations data coming from useRelations
|
|
45
|
+
* shouldAddLink: comes from generateRelationQueryInfos, if true we display a link to the relation (TO FIX: explanation)
|
|
46
|
+
* mainFieldName: name of the main field inside the relation (e.g. text field), if no displayable main field exists (e.g. date field) we use the id of the entry
|
|
47
|
+
* targetModel: the model on which the relation is based on, used to create an URL link
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
export const normalizeRelations = (relations: Contracts.Relations.RelationResult[], args: NormalizeRelationArgs) => {
|
|
51
|
+
return [...relations].map((relation) => normalizeRelation(relation, args));
|
|
52
|
+
};
|
package/admin/src/components/StrapiCore/admin/admin/src/content-manager/hooks/useDragAndDrop.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
|
|
4
3
|
import {
|
|
@@ -250,4 +249,5 @@ const useDragAndDrop = <
|
|
|
250
249
|
];
|
|
251
250
|
};
|
|
252
251
|
|
|
253
|
-
export {
|
|
252
|
+
export type { UseDragAndDropReturn, UseDragAndDropOptions };
|
|
253
|
+
export { useDragAndDrop, DIRECTIONS, DROP_SENSITIVITY };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
export type UseKeyboardDragAndDropCallbacks<TIndex extends number | Array<number> = number> = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
onCancel?: (index: TIndex) => void;
|
|
5
|
+
onDropItem?: (currentIndex: TIndex, newIndex?: TIndex) => void;
|
|
6
|
+
onGrabItem?: (index: TIndex) => void;
|
|
7
|
+
onMoveItem?: (newIndex: TIndex, currentIndex: TIndex) => void;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -14,83 +14,83 @@ export type UseKeyboardDragAndDropCallbacks<TIndex extends number | Array<number
|
|
|
14
14
|
* @internal - You should use `useDragAndDrop` instead.
|
|
15
15
|
*/
|
|
16
16
|
export const useKeyboardDragAndDrop = <TIndex extends number | Array<number> = number>(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
active: boolean,
|
|
18
|
+
index: TIndex,
|
|
19
|
+
{ onCancel, onDropItem, onGrabItem, onMoveItem }: UseKeyboardDragAndDropCallbacks<TIndex>
|
|
20
20
|
) => {
|
|
21
|
-
|
|
21
|
+
const [isSelected, setIsSelected] = React.useState(false);
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
const handleMove = (movement: 'UP' | 'DOWN') => {
|
|
24
|
+
if (!isSelected) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (typeof index === 'number' && onMoveItem) {
|
|
28
|
+
if (movement === 'UP') {
|
|
29
|
+
onMoveItem((index - 1) as TIndex, index);
|
|
30
|
+
} else if (movement === 'DOWN') {
|
|
31
|
+
onMoveItem((index + 1) as TIndex, index);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
const handleDragClick = () => {
|
|
37
|
+
if (isSelected) {
|
|
38
|
+
if (onDropItem) {
|
|
39
|
+
onDropItem(index);
|
|
40
|
+
}
|
|
41
|
+
setIsSelected(false);
|
|
42
|
+
} else {
|
|
43
|
+
if (onGrabItem) {
|
|
44
|
+
onGrabItem(index);
|
|
45
|
+
}
|
|
46
|
+
setIsSelected(true);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const handleCancel = () => {
|
|
51
|
+
if (isSelected) {
|
|
52
|
+
setIsSelected(false);
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
if (onCancel) {
|
|
55
|
+
onCancel(index);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
const handleKeyDown: React.KeyboardEventHandler<HTMLButtonElement> = (e) => {
|
|
61
|
+
if (!active) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
if (e.key === 'Tab' && !isSelected) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
e.preventDefault();
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
switch (e.key) {
|
|
72
|
+
case ' ':
|
|
73
|
+
case 'Enter':
|
|
74
|
+
handleDragClick();
|
|
75
|
+
break;
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
case 'Escape':
|
|
78
|
+
handleCancel();
|
|
79
|
+
break;
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
case 'ArrowDown':
|
|
82
|
+
case 'ArrowRight':
|
|
83
|
+
handleMove('DOWN');
|
|
84
|
+
break;
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
case 'ArrowUp':
|
|
87
|
+
case 'ArrowLeft':
|
|
88
|
+
handleMove('UP');
|
|
89
|
+
break;
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
default:
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
return handleKeyDown;
|
|
96
96
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
|
|
3
3
|
export const usePrev = <T>(value: T): T | undefined => {
|
|
4
|
-
|
|
4
|
+
const ref = useRef<T>();
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
ref.current = value;
|
|
8
|
+
}, [value]);
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
return ref.current;
|
|
11
11
|
};
|
package/admin/src/components/StrapiCore/admin/admin/src/content-manager/utils/dragAndDrop.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const ItemTypes = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
COMPONENT: 'component',
|
|
3
|
+
EDIT_FIELD: 'editField',
|
|
4
|
+
FIELD: 'field',
|
|
5
|
+
DYNAMIC_ZONE: 'dynamicZone',
|
|
6
|
+
RELATION: 'relation',
|
|
7
|
+
BLOCKS: 'blocks'
|
|
8
8
|
} as const;
|
|
@@ -7,30 +7,23 @@ import get from 'lodash/get';
|
|
|
7
7
|
* a new item they wont have a server ID).
|
|
8
8
|
*/
|
|
9
9
|
export const getInitialDataPathUsingTempKeys =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const splitPath = currentPath.split('.');
|
|
10
|
+
(initialData: Record<string, any>, modifiedData: Record<string, any>) => (currentPath: string) => {
|
|
11
|
+
const splitPath = currentPath.split('.');
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
...splitPath.slice(0, index),
|
|
18
|
-
currentValue,
|
|
19
|
-
'__temp_key__',
|
|
20
|
-
]);
|
|
13
|
+
return splitPath.reduce<string[]>((acc, currentValue, index) => {
|
|
14
|
+
const initialDataParent = get(initialData, acc);
|
|
15
|
+
const modifiedDataTempKey = get(modifiedData, [...splitPath.slice(0, index), currentValue, '__temp_key__']);
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
(entry) => entry.__temp_key__ === modifiedDataTempKey
|
|
25
|
-
);
|
|
17
|
+
if (Array.isArray(initialDataParent) && typeof modifiedDataTempKey === 'number') {
|
|
18
|
+
const initialDataIndex = initialDataParent.findIndex((entry) => entry.__temp_key__ === modifiedDataTempKey);
|
|
26
19
|
|
|
27
|
-
|
|
20
|
+
acc.push(initialDataIndex.toString());
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
return acc;
|
|
23
|
+
}
|
|
31
24
|
|
|
32
|
-
|
|
25
|
+
acc.push(currentValue);
|
|
33
26
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
return acc;
|
|
28
|
+
}, []);
|
|
29
|
+
};
|
|
@@ -3,11 +3,11 @@ import { MutableRefObject, Ref } from 'react';
|
|
|
3
3
|
type PossibleRef<T> = Ref<T> | undefined;
|
|
4
4
|
|
|
5
5
|
const setRef = <T>(ref: PossibleRef<T>, value: T) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
if (typeof ref === 'function') {
|
|
7
|
+
ref(value);
|
|
8
|
+
} else if (ref !== null && ref !== undefined) {
|
|
9
|
+
(ref as MutableRefObject<T>).current = value;
|
|
10
|
+
}
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -15,5 +15,5 @@ const setRef = <T>(ref: PossibleRef<T>, value: T) => {
|
|
|
15
15
|
* Accepts callback refs and RefObject(s)
|
|
16
16
|
*/
|
|
17
17
|
export const composeRefs = <T>(...refs: PossibleRef<T>[]) => {
|
|
18
|
-
|
|
18
|
+
return (node: T) => refs.forEach((ref) => setRef(ref, node));
|
|
19
19
|
};
|