@elementor/editor-site-navigation 0.12.0 → 0.14.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 CHANGED
@@ -3,6 +3,28 @@
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.14.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.13.0...@elementor/editor-site-navigation@0.14.0) (2023-07-27)
7
+
8
+
9
+ ### Features
10
+
11
+ * **site-navigation:** add duplicate action to pages panel [ED-10867] ([#95](https://github.com/elementor/elementor-packages/issues/95)) ([2fd8b3c](https://github.com/elementor/elementor-packages/commit/2fd8b3cc88feb525adc4dfebe75ea14189876075))
12
+
13
+
14
+
15
+
16
+
17
+ # [0.13.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.12.0...@elementor/editor-site-navigation@0.13.0) (2023-07-26)
18
+
19
+
20
+ ### Features
21
+
22
+ * added view page action to pages panel [ED-10869] ([#66](https://github.com/elementor/elementor-packages/issues/66)) ([dfefd2f](https://github.com/elementor/elementor-packages/commit/dfefd2f90435c8ecf45c897c4329bd9c5a262a6c))
23
+
24
+
25
+
26
+
27
+
6
28
  # [0.12.0](https://github.com/elementor/elementor-packages/compare/@elementor/editor-site-navigation@0.11.0...@elementor/editor-site-navigation@0.12.0) (2023-07-24)
7
29
 
8
30
 
package/dist/index.js CHANGED
@@ -249,7 +249,7 @@ function RecentlyEdited() {
249
249
  // src/init.ts
250
250
  var import_editor_app_bar = require("@elementor/editor-app-bar");
251
251
 
252
- // src/hooks/useToggleButtonProps.ts
252
+ // src/hooks/use-toggle-button-props.ts
253
253
  var import_i18n14 = require("@wordpress/i18n");
254
254
  var import_icons15 = require("@elementor/icons");
255
255
 
@@ -318,6 +318,17 @@ var deleteRequest = (postTypeSlug, postId) => {
318
318
  method: "DELETE"
319
319
  });
320
320
  };
321
+ var duplicateRequest = (originalPost) => {
322
+ const path = `/elementor/v1/site-navigation/duplicate-post`;
323
+ return (0, import_api_fetch3.default)({
324
+ path,
325
+ method: "POST",
326
+ data: {
327
+ post_id: originalPost.id,
328
+ title: originalPost.title
329
+ }
330
+ });
331
+ };
321
332
 
322
333
  // src/hooks/use-posts.ts
323
334
  var postsQueryKey = (postTypeSlug) => ["site-navigation", "posts", postTypeSlug];
@@ -423,10 +434,15 @@ function usePostActions(postTypeSlug) {
423
434
  (postId) => deleteRequest(postTypeSlug, postId),
424
435
  { onSuccess }
425
436
  );
437
+ const duplicatePost = (0, import_query2.useMutation)(
438
+ (originalPost) => duplicateRequest(originalPost),
439
+ { onSuccess }
440
+ );
426
441
  return {
427
442
  createPost,
428
443
  updatePost,
429
- deletePost
444
+ deletePost,
445
+ duplicatePost
430
446
  };
431
447
  }
432
448
  function useInvalidatePosts(postTypeSlug) {
@@ -550,23 +566,23 @@ function ListItemCreate() {
550
566
  // src/components/panel/posts-list/list-items/list-item-duplicate.tsx
551
567
  var React11 = __toESM(require("react"));
552
568
  var import_i18n6 = require("@wordpress/i18n");
553
- function ListItemDuplicate() {
569
+ function ListItemDuplicate({ post }) {
554
570
  const { type, editMode, resetEditMode } = usePostListContext();
555
- const { createPost } = usePostActions(type);
571
+ const { duplicatePost } = usePostActions(type);
556
572
  if ("duplicate" !== editMode.mode) {
557
573
  return null;
558
574
  }
559
575
  const duplicatePostCallback = (inputValue) => {
560
- createPost.mutateAsync({
561
- title: inputValue,
562
- status: "draft"
576
+ duplicatePost.mutateAsync({
577
+ id: post.id,
578
+ title: inputValue
563
579
  }, {
564
580
  onSuccess: () => {
565
581
  resetEditMode();
566
582
  }
567
583
  });
568
584
  };
569
- return /* @__PURE__ */ React11.createElement(EditModeTemplate, { postTitle: `${editMode.details.title} ${(0, import_i18n6.__)("copy", "elementor")}`, isLoading: createPost.isLoading, callback: duplicatePostCallback });
585
+ return /* @__PURE__ */ React11.createElement(EditModeTemplate, { postTitle: `${editMode.details.title} ${(0, import_i18n6.__)("copy", "elementor")}`, isLoading: duplicatePost.isLoading, callback: duplicatePostCallback });
570
586
  }
571
587
 
572
588
  // src/components/panel/posts-list/list-items/list-item-view.tsx
@@ -724,7 +740,7 @@ function View({ post }) {
724
740
  title,
725
741
  icon: import_icons10.EyeIcon,
726
742
  onClick: () => {
727
- console.log(post);
743
+ window.open(post.link, "_blank");
728
744
  }
729
745
  }
730
746
  );
@@ -817,8 +833,8 @@ function PostListItem2({ post }) {
817
833
  if ("create" === editMode.mode && !post) {
818
834
  return /* @__PURE__ */ React21.createElement(ListItemCreate, null);
819
835
  }
820
- if ("duplicate" === editMode.mode && !post) {
821
- return /* @__PURE__ */ React21.createElement(ListItemDuplicate, null);
836
+ if ("duplicate" === editMode.mode && post?.id && post?.id === editMode.details.postId) {
837
+ return /* @__PURE__ */ React21.createElement(ListItemDuplicate, { post });
822
838
  }
823
839
  if (!post) {
824
840
  return null;
@@ -891,7 +907,7 @@ var {
891
907
  component: shell_default
892
908
  });
893
909
 
894
- // src/hooks/useToggleButtonProps.ts
910
+ // src/hooks/use-toggle-button-props.ts
895
911
  function useToggleButtonProps() {
896
912
  const { isOpen, isBlocked } = usePanelStatus();
897
913
  const { open, close } = usePanelActions();
package/dist/index.mjs CHANGED
@@ -231,7 +231,7 @@ function RecentlyEdited() {
231
231
  // src/init.ts
232
232
  import { injectIntoPageIndication, toolsMenu } from "@elementor/editor-app-bar";
233
233
 
234
- // src/hooks/useToggleButtonProps.ts
234
+ // src/hooks/use-toggle-button-props.ts
235
235
  import { __ as __14 } from "@wordpress/i18n";
236
236
  import { PagesIcon } from "@elementor/icons";
237
237
 
@@ -300,6 +300,17 @@ var deleteRequest = (postTypeSlug, postId) => {
300
300
  method: "DELETE"
301
301
  });
302
302
  };
303
+ var duplicateRequest = (originalPost) => {
304
+ const path = `/elementor/v1/site-navigation/duplicate-post`;
305
+ return apiFetch3({
306
+ path,
307
+ method: "POST",
308
+ data: {
309
+ post_id: originalPost.id,
310
+ title: originalPost.title
311
+ }
312
+ });
313
+ };
303
314
 
304
315
  // src/hooks/use-posts.ts
305
316
  var postsQueryKey = (postTypeSlug) => ["site-navigation", "posts", postTypeSlug];
@@ -405,10 +416,15 @@ function usePostActions(postTypeSlug) {
405
416
  (postId) => deleteRequest(postTypeSlug, postId),
406
417
  { onSuccess }
407
418
  );
419
+ const duplicatePost = useMutation(
420
+ (originalPost) => duplicateRequest(originalPost),
421
+ { onSuccess }
422
+ );
408
423
  return {
409
424
  createPost,
410
425
  updatePost,
411
- deletePost
426
+ deletePost,
427
+ duplicatePost
412
428
  };
413
429
  }
414
430
  function useInvalidatePosts(postTypeSlug) {
@@ -539,23 +555,23 @@ function ListItemCreate() {
539
555
  // src/components/panel/posts-list/list-items/list-item-duplicate.tsx
540
556
  import * as React11 from "react";
541
557
  import { __ as __6 } from "@wordpress/i18n";
542
- function ListItemDuplicate() {
558
+ function ListItemDuplicate({ post }) {
543
559
  const { type, editMode, resetEditMode } = usePostListContext();
544
- const { createPost } = usePostActions(type);
560
+ const { duplicatePost } = usePostActions(type);
545
561
  if ("duplicate" !== editMode.mode) {
546
562
  return null;
547
563
  }
548
564
  const duplicatePostCallback = (inputValue) => {
549
- createPost.mutateAsync({
550
- title: inputValue,
551
- status: "draft"
565
+ duplicatePost.mutateAsync({
566
+ id: post.id,
567
+ title: inputValue
552
568
  }, {
553
569
  onSuccess: () => {
554
570
  resetEditMode();
555
571
  }
556
572
  });
557
573
  };
558
- return /* @__PURE__ */ React11.createElement(EditModeTemplate, { postTitle: `${editMode.details.title} ${__6("copy", "elementor")}`, isLoading: createPost.isLoading, callback: duplicatePostCallback });
574
+ return /* @__PURE__ */ React11.createElement(EditModeTemplate, { postTitle: `${editMode.details.title} ${__6("copy", "elementor")}`, isLoading: duplicatePost.isLoading, callback: duplicatePostCallback });
559
575
  }
560
576
 
561
577
  // src/components/panel/posts-list/list-items/list-item-view.tsx
@@ -724,7 +740,7 @@ function View({ post }) {
724
740
  title,
725
741
  icon: EyeIcon,
726
742
  onClick: () => {
727
- console.log(post);
743
+ window.open(post.link, "_blank");
728
744
  }
729
745
  }
730
746
  );
@@ -817,8 +833,8 @@ function PostListItem2({ post }) {
817
833
  if ("create" === editMode.mode && !post) {
818
834
  return /* @__PURE__ */ React21.createElement(ListItemCreate, null);
819
835
  }
820
- if ("duplicate" === editMode.mode && !post) {
821
- return /* @__PURE__ */ React21.createElement(ListItemDuplicate, null);
836
+ if ("duplicate" === editMode.mode && post?.id && post?.id === editMode.details.postId) {
837
+ return /* @__PURE__ */ React21.createElement(ListItemDuplicate, { post });
822
838
  }
823
839
  if (!post) {
824
840
  return null;
@@ -891,7 +907,7 @@ var {
891
907
  component: shell_default
892
908
  });
893
909
 
894
- // src/hooks/useToggleButtonProps.ts
910
+ // src/hooks/use-toggle-button-props.ts
895
911
  function useToggleButtonProps() {
896
912
  const { isOpen, isBlocked } = usePanelStatus();
897
913
  const { open, close } = usePanelActions();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-site-navigation",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -49,5 +49,5 @@
49
49
  "elementor": {
50
50
  "type": "extension"
51
51
  },
52
- "gitHead": "e8add4d4645e1c8f62a11ddac8d26d50341b6ed2"
52
+ "gitHead": "025f7ec0942da99205377c41e713afe1e8f7898d"
53
53
  }
package/src/api/post.ts CHANGED
@@ -70,3 +70,16 @@ export const deleteRequest = ( postTypeSlug: Slug, postId: number ) => {
70
70
  method: 'DELETE',
71
71
  } );
72
72
  };
73
+
74
+ export const duplicateRequest = ( originalPost: UpdatePost ) => {
75
+ const path = `/elementor/v1/site-navigation/duplicate-post`;
76
+
77
+ return apiFetch( {
78
+ path,
79
+ method: 'POST',
80
+ data: {
81
+ post_id: originalPost.id,
82
+ title: originalPost.title,
83
+ },
84
+ } );
85
+ };
@@ -0,0 +1,36 @@
1
+ import * as React from 'react';
2
+ import { act, render, screen } from '@testing-library/react';
3
+ import View from '../view';
4
+ import { Post } from '../../../../../types';
5
+
6
+ describe( '@elementor/editor-site-navigation - View', () => {
7
+ afterAll( () => {
8
+ jest.clearAllMocks();
9
+ } );
10
+
11
+ it( 'should open page in a different tab', () => {
12
+ // Arrange.
13
+ const spy = jest.spyOn( window, 'open' );
14
+ spy.mockImplementation( () => null );
15
+ const page: Post = {
16
+ id: 1,
17
+ title: { rendered: 'Page Title' },
18
+ link: 'mocklink',
19
+ status: 'publish',
20
+ type: 'page',
21
+ };
22
+
23
+ // Act.
24
+ render( <View post={ page } /> );
25
+ const button = screen.getByRole( 'button' );
26
+
27
+ act( () => {
28
+ // Open menu
29
+ button.click();
30
+ } );
31
+
32
+ // Assert.
33
+ expect( spy ).toHaveBeenCalledTimes( 1 );
34
+ expect( spy ).toHaveBeenCalledWith( 'mocklink', '_blank' );
35
+ } );
36
+ } );
@@ -17,8 +17,7 @@ export default function View( { post }: { post: Post } ) {
17
17
  title={ title }
18
18
  icon={ EyeIcon }
19
19
  onClick={ () => {
20
- // eslint-disable-next-line no-console
21
- console.log( post );
20
+ window.open( post.link, '_blank' );
22
21
  } }
23
22
  />
24
23
  );
@@ -3,19 +3,24 @@ import { __ } from '@wordpress/i18n';
3
3
  import { usePostListContext } from '../../../../contexts/post-list-context';
4
4
  import { usePostActions } from '../../../../hooks/use-posts-actions';
5
5
  import EditModeTemplate from './edit-mode-template';
6
+ import { Post } from '../../../../types';
6
7
 
7
- export default function ListItemDuplicate() {
8
+ type Props = {
9
+ post: Post,
10
+ }
11
+
12
+ export default function ListItemDuplicate( { post }: Props ) {
8
13
  const { type, editMode, resetEditMode } = usePostListContext();
9
- const { createPost } = usePostActions( type );
14
+ const { duplicatePost } = usePostActions( type );
10
15
 
11
16
  if ( 'duplicate' !== editMode.mode ) {
12
17
  return null;
13
18
  }
14
19
 
15
20
  const duplicatePostCallback = ( inputValue: string ) => {
16
- createPost.mutateAsync( {
21
+ duplicatePost.mutateAsync( {
22
+ id: post.id,
17
23
  title: inputValue,
18
- status: 'draft',
19
24
  }, {
20
25
  onSuccess: () => {
21
26
  resetEditMode();
@@ -24,6 +29,6 @@ export default function ListItemDuplicate() {
24
29
  };
25
30
 
26
31
  return (
27
- <EditModeTemplate postTitle={ `${ editMode.details.title } ${ __( 'copy', 'elementor' ) }` } isLoading={ createPost.isLoading } callback={ duplicatePostCallback } />
32
+ <EditModeTemplate postTitle={ `${ editMode.details.title } ${ __( 'copy', 'elementor' ) }` } isLoading={ duplicatePost.isLoading } callback={ duplicatePostCallback } />
28
33
  );
29
34
  }
@@ -17,8 +17,8 @@ export default function PostListItem( { post }: { post?: Post } ) {
17
17
  return <ListItemCreate />;
18
18
  }
19
19
 
20
- if ( 'duplicate' === editMode.mode && ! post ) {
21
- return <ListItemDuplicate />;
20
+ if ( 'duplicate' === editMode.mode && post?.id && post?.id === editMode.details.postId ) {
21
+ return <ListItemDuplicate post={ post } />;
22
22
  }
23
23
 
24
24
  if ( ! post ) {
@@ -1,5 +1,5 @@
1
1
  import { useQueryClient, useMutation } from '@elementor/query';
2
- import { createRequest, deleteRequest, updateRequest, NewPost, Slug, UpdatePost } from '../api/post';
2
+ import { createRequest, deleteRequest, updateRequest, duplicateRequest, NewPost, Slug, UpdatePost } from '../api/post';
3
3
  import { postsQueryKey } from './use-posts';
4
4
 
5
5
  export function usePostActions( postTypeSlug: Slug ) {
@@ -22,10 +22,16 @@ export function usePostActions( postTypeSlug: Slug ) {
22
22
  { onSuccess }
23
23
  );
24
24
 
25
+ const duplicatePost = useMutation(
26
+ ( originalPost: UpdatePost ) => duplicateRequest( originalPost ),
27
+ { onSuccess }
28
+ );
29
+
25
30
  return {
26
31
  createPost,
27
32
  updatePost,
28
33
  deletePost,
34
+ duplicatePost,
29
35
  };
30
36
  }
31
37
 
package/src/init.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import RecentlyEdited from './components/top-bar/recently-edited';
2
2
  import { injectIntoPageIndication, toolsMenu } from '@elementor/editor-app-bar';
3
- import { useToggleButtonProps } from './hooks/useToggleButtonProps';
3
+ import { useToggleButtonProps } from './hooks/use-toggle-button-props';
4
4
  import { registerPanel } from '@elementor/editor-panels';
5
5
  import { panel } from './components/panel/panel';
6
6
  import { env } from './env';
package/src/types.ts CHANGED
@@ -7,7 +7,7 @@ export type Post = {
7
7
  title: {
8
8
  rendered: string;
9
9
  }
10
- }
10
+ };
11
11
 
12
12
  export type PostType = {
13
13
  name: string;