@elementor/editor-site-navigation 0.6.2 → 0.7.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/CHANGELOG.md +11 -0
- package/README.md +48 -0
- package/package.json +4 -4
- package/src/hooks/types/interfaces.ts +13 -0
- package/src/hooks/use-post-types.ts +64 -0
- package/src/hooks/use-posts.ts +123 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.7.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.6.2...@elementor/editor-site-navigation@0.7.0) (2023-06-25)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **api:** add PostsData class for managing post data and API interactions [ED-11021] ([#57](https://github.com/elementor/elementor-packages/issues/57)) ([a7b93ac](https://github.com/elementor/elementor-packages/commit/a7b93acfc00076f9452cf86f04670412c42b5773))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [0.6.2](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.6.1...@elementor/editor-site-navigation@0.6.2) (2023-06-13)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @elementor/editor-site-navigation
|
package/README.md
CHANGED
|
@@ -3,3 +3,51 @@
|
|
|
3
3
|
> **Warning**
|
|
4
4
|
>
|
|
5
5
|
> This package is under development and not ready for production use.
|
|
6
|
+
|
|
7
|
+
## Code examples
|
|
8
|
+
|
|
9
|
+
**Get all pages and create a new one:**
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
import * as React from 'react';
|
|
13
|
+
import { useEffect } from 'react';
|
|
14
|
+
import { usePosts } from './use-posts';
|
|
15
|
+
|
|
16
|
+
const PageList = () => {
|
|
17
|
+
const { getPosts: getPages, createPost: createPage, isLoading, posts } = usePosts( 'page' );
|
|
18
|
+
|
|
19
|
+
useEffect( () => {
|
|
20
|
+
getPages();
|
|
21
|
+
}, [ getPages ] );
|
|
22
|
+
|
|
23
|
+
const createNewPage = () => {
|
|
24
|
+
const newPage = {
|
|
25
|
+
title: 'New Page',
|
|
26
|
+
content: 'This is a demo page',
|
|
27
|
+
status: 'publish',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
createPage( newPage );
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if ( isLoading ) {
|
|
34
|
+
return <div>Loading...</div>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div>
|
|
39
|
+
<h1>Pages</h1>
|
|
40
|
+
<button onClick={ createNewPage }>Create New Page</button>
|
|
41
|
+
<ul>
|
|
42
|
+
{
|
|
43
|
+
posts.map( ( page ) => (
|
|
44
|
+
<li key={ page.id }>{ page.title }</li>
|
|
45
|
+
) )
|
|
46
|
+
}
|
|
47
|
+
</ul>
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default PageList;
|
|
53
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-site-navigation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@elementor/editor-app-bar": "^0.6.
|
|
36
|
-
"@elementor/editor-documents": "^0.8.
|
|
35
|
+
"@elementor/editor-app-bar": "^0.6.2",
|
|
36
|
+
"@elementor/editor-documents": "^0.8.2",
|
|
37
37
|
"@elementor/icons": "^0.4.0",
|
|
38
38
|
"@elementor/ui": "^1.4.50",
|
|
39
39
|
"@wordpress/api-fetch": "^6.27.0",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"elementor": {
|
|
47
47
|
"type": "extension"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "ad9032e095915dbef0f8543d83f73b9288adc8ad"
|
|
50
50
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
2
|
+
import { PostType } from './types/interfaces';
|
|
3
|
+
import apiFetch from '@wordpress/api-fetch';
|
|
4
|
+
|
|
5
|
+
type PostTypesResponse = Record<string, PostType>;
|
|
6
|
+
|
|
7
|
+
// allowedPostTypes is only used to filter irrelevant types when fetching all post types.
|
|
8
|
+
// You can still use a specific post type name to fetch a post type not present in allowedPostTypes.
|
|
9
|
+
const allowedPostTypes = [ 'page' ];
|
|
10
|
+
|
|
11
|
+
const useFetchPostTypes = (
|
|
12
|
+
postTypeName?: string
|
|
13
|
+
): ( PostType | null )[] => {
|
|
14
|
+
const [ postTypes, setPostTypes ] = useState<( PostType | null )[]>( [] );
|
|
15
|
+
|
|
16
|
+
useEffect( () => {
|
|
17
|
+
const fetchPostTypes = async () => {
|
|
18
|
+
try {
|
|
19
|
+
const response: PostTypesResponse = await apiFetch( {
|
|
20
|
+
path: '/wp/v2/types',
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
if ( postTypeName ) {
|
|
24
|
+
const specificPostType = response[ postTypeName ];
|
|
25
|
+
|
|
26
|
+
setPostTypes( [
|
|
27
|
+
specificPostType
|
|
28
|
+
? { ...specificPostType }
|
|
29
|
+
: null,
|
|
30
|
+
] );
|
|
31
|
+
} else {
|
|
32
|
+
const filteredResponse: PostTypesResponse = {};
|
|
33
|
+
|
|
34
|
+
allowedPostTypes.forEach( ( type ) => {
|
|
35
|
+
if ( response[ type ] ) {
|
|
36
|
+
filteredResponse[ type ] = response[ type ];
|
|
37
|
+
}
|
|
38
|
+
} );
|
|
39
|
+
|
|
40
|
+
const filteredPostTypes: ( PostType | null )[] = Object.keys( filteredResponse ).map(
|
|
41
|
+
( key ) => ( { ...filteredResponse[ key ] } )
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
setPostTypes( filteredPostTypes );
|
|
45
|
+
}
|
|
46
|
+
} catch ( error ) {
|
|
47
|
+
// eslint-disable-next-line no-console
|
|
48
|
+
console.error( 'Error fetching post types:', error );
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
fetchPostTypes();
|
|
53
|
+
}, [ postTypeName ] );
|
|
54
|
+
|
|
55
|
+
return postTypes;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const usePostTypes = (
|
|
59
|
+
postTypeName?: string
|
|
60
|
+
): ( PostType | null )[] => {
|
|
61
|
+
const postTypes = useFetchPostTypes( postTypeName );
|
|
62
|
+
|
|
63
|
+
return useMemo( () => postTypes, [ postTypes ] );
|
|
64
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState, useCallback } from 'react';
|
|
2
|
+
import { usePostTypes } from './use-post-types';
|
|
3
|
+
import { Post, PostType } from './types/interfaces';
|
|
4
|
+
import apiFetch from '@wordpress/api-fetch';
|
|
5
|
+
|
|
6
|
+
const defaultRestNamespace = 'wp/v2';
|
|
7
|
+
|
|
8
|
+
const useFetchPosts = ( postType: PostType | null | undefined ): [ Post[], () => void, boolean ] => {
|
|
9
|
+
const [ posts, setPosts ] = useState<Post[]>( [] );
|
|
10
|
+
const [ isLoading, setIsLoading ] = useState( false );
|
|
11
|
+
|
|
12
|
+
const fetchPosts = useCallback( () => {
|
|
13
|
+
setIsLoading( true );
|
|
14
|
+
|
|
15
|
+
const path = postType
|
|
16
|
+
? `/${ postType.rest_namespace }/${ postType.rest_base }`
|
|
17
|
+
: `/${ defaultRestNamespace }/posts`;
|
|
18
|
+
|
|
19
|
+
apiFetch( { path } )
|
|
20
|
+
.then( ( response ) => {
|
|
21
|
+
if ( Array.isArray( response ) ) {
|
|
22
|
+
setPosts( response );
|
|
23
|
+
}
|
|
24
|
+
} )
|
|
25
|
+
.catch( ( error ) => {
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
27
|
+
console.error( 'Error fetching posts:', error );
|
|
28
|
+
} )
|
|
29
|
+
.finally( () => {
|
|
30
|
+
setIsLoading( false );
|
|
31
|
+
} );
|
|
32
|
+
}, [ postType ] );
|
|
33
|
+
|
|
34
|
+
useEffect( () => {
|
|
35
|
+
fetchPosts();
|
|
36
|
+
}, [ fetchPosts ] );
|
|
37
|
+
|
|
38
|
+
return [ posts, fetchPosts, isLoading ];
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const useUpdatePost = ( postType: PostType | null | undefined ): ( ( postId: number, updatedPost: Partial<Post> ) => void ) => {
|
|
42
|
+
return ( postId: number, updatedPost: Partial<Post> ) => {
|
|
43
|
+
const path = postType
|
|
44
|
+
? `/${ postType.rest_namespace }/${ postType.rest_base }`
|
|
45
|
+
: `/${ defaultRestNamespace }/posts`;
|
|
46
|
+
|
|
47
|
+
apiFetch( {
|
|
48
|
+
path: `/${ path }/${ postId }`,
|
|
49
|
+
method: 'POST',
|
|
50
|
+
data: updatedPost,
|
|
51
|
+
} )
|
|
52
|
+
.catch( ( error ) => {
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.error( 'Error updating post:', error );
|
|
55
|
+
} );
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const useCreatePost = ( postType: PostType | null | undefined ): ( ( newPost: Partial<Post> ) => void ) => {
|
|
60
|
+
return ( newPost: Partial<Post> ) => {
|
|
61
|
+
const path = postType
|
|
62
|
+
? `/${ postType.rest_namespace }/${ postType.rest_base }`
|
|
63
|
+
: `/${ defaultRestNamespace }/posts`;
|
|
64
|
+
|
|
65
|
+
apiFetch( {
|
|
66
|
+
path,
|
|
67
|
+
method: 'POST',
|
|
68
|
+
data: newPost,
|
|
69
|
+
} )
|
|
70
|
+
.catch( ( error ) => {
|
|
71
|
+
// eslint-disable-next-line no-console
|
|
72
|
+
console.error( 'Error creating post:', error );
|
|
73
|
+
} );
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const useDeletePost = ( postType: PostType | null | undefined ): ( ( postId: number ) => void ) => {
|
|
78
|
+
return ( postId: number ) => {
|
|
79
|
+
const path = postType
|
|
80
|
+
? `/${ postType.rest_namespace }/${ postType.rest_base }`
|
|
81
|
+
: `/${ defaultRestNamespace }/posts`;
|
|
82
|
+
|
|
83
|
+
apiFetch( {
|
|
84
|
+
path: `/${ path }/${ postId }`,
|
|
85
|
+
method: 'DELETE',
|
|
86
|
+
} )
|
|
87
|
+
.catch( ( error ) => {
|
|
88
|
+
// eslint-disable-next-line no-console
|
|
89
|
+
console.error( 'Error deleting post:', error );
|
|
90
|
+
} );
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const usePosts = ( postType?: string | null ): {
|
|
95
|
+
posts: Post[];
|
|
96
|
+
getPosts: () => void;
|
|
97
|
+
updatePost: ( postId: number, updatedPost: Partial<Post> ) => void;
|
|
98
|
+
createPost: ( newPost: Partial<Post> ) => void;
|
|
99
|
+
deletePost: ( postId: number ) => void;
|
|
100
|
+
isLoading: boolean;
|
|
101
|
+
} => {
|
|
102
|
+
const postTypes = usePostTypes();
|
|
103
|
+
const postTypeData = postTypes.find( ( type ) => type?.name === postType );
|
|
104
|
+
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
106
|
+
const [ posts, fetchPosts, isLoading ] = useFetchPosts( postTypeData );
|
|
107
|
+
const updatePost = useUpdatePost( postTypeData );
|
|
108
|
+
const createPost = useCreatePost( postTypeData );
|
|
109
|
+
const deletePost = useDeletePost( postTypeData );
|
|
110
|
+
|
|
111
|
+
const getPosts = useMemo( () => {
|
|
112
|
+
return () => posts;
|
|
113
|
+
}, [ posts ] );
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
posts,
|
|
117
|
+
getPosts,
|
|
118
|
+
updatePost,
|
|
119
|
+
createPost,
|
|
120
|
+
deletePost,
|
|
121
|
+
isLoading,
|
|
122
|
+
};
|
|
123
|
+
};
|