@wordpress/editor 14.33.7 → 14.33.9
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/build/components/collab-sidebar/comment-form.js +14 -5
- package/build/components/collab-sidebar/comment-form.js.map +2 -2
- package/build/components/collab-sidebar/comments.js +109 -30
- package/build/components/collab-sidebar/comments.js.map +2 -2
- package/build/components/post-template/panel.js +9 -6
- package/build/components/post-template/panel.js.map +2 -2
- package/build-module/components/collab-sidebar/comment-form.js +14 -5
- package/build-module/components/collab-sidebar/comment-form.js.map +2 -2
- package/build-module/components/collab-sidebar/comments.js +109 -30
- package/build-module/components/collab-sidebar/comments.js.map +2 -2
- package/build-module/components/post-template/panel.js +9 -6
- package/build-module/components/post-template/panel.js.map +2 -2
- package/build-types/components/collab-sidebar/comment-form.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/comments.d.ts +1 -1
- package/build-types/components/collab-sidebar/comments.d.ts.map +1 -1
- package/build-types/components/post-template/panel.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/bindings/test/post-data.js +199 -0
- package/src/components/collab-sidebar/comment-form.js +16 -4
- package/src/components/collab-sidebar/comments.js +151 -28
- package/src/components/post-template/panel.js +11 -8
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import postDataBindings from '../post-data';
|
|
10
|
+
|
|
11
|
+
describe( 'post-data bindings', () => {
|
|
12
|
+
describe( 'getValues', () => {
|
|
13
|
+
describe( 'for regular blocks using block context', () => {
|
|
14
|
+
let select;
|
|
15
|
+
beforeAll( () => {
|
|
16
|
+
select = ( store ) => {
|
|
17
|
+
if ( store === blockEditorStore ) {
|
|
18
|
+
return {
|
|
19
|
+
getBlockName: ( clientId ) =>
|
|
20
|
+
clientId === '123abc456'
|
|
21
|
+
? 'core/post-date'
|
|
22
|
+
: undefined,
|
|
23
|
+
getBlockAttributes: () => ( {} ),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
getEditedEntityRecord: ( kind, name, recordId ) =>
|
|
28
|
+
name === 'post' && recordId === 123
|
|
29
|
+
? {
|
|
30
|
+
date: '2024-03-02 00:00:00',
|
|
31
|
+
modified: '2025-06-07 00:00:00',
|
|
32
|
+
link: 'https://example.com/post',
|
|
33
|
+
unknown: 'Unknown field value',
|
|
34
|
+
}
|
|
35
|
+
: {},
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
} );
|
|
39
|
+
|
|
40
|
+
it( 'should return entity field values when they exist', () => {
|
|
41
|
+
const values = postDataBindings.getValues( {
|
|
42
|
+
select,
|
|
43
|
+
context: { postId: 123, postType: 'post' },
|
|
44
|
+
bindings: {
|
|
45
|
+
datetime: {
|
|
46
|
+
source: 'core/post-date',
|
|
47
|
+
args: { field: 'date' },
|
|
48
|
+
},
|
|
49
|
+
modified: {
|
|
50
|
+
source: 'core/post-date',
|
|
51
|
+
args: { field: 'modified' },
|
|
52
|
+
},
|
|
53
|
+
url: {
|
|
54
|
+
source: 'core/post-date',
|
|
55
|
+
args: { field: 'link' },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
clientId: '123abc456',
|
|
59
|
+
} );
|
|
60
|
+
|
|
61
|
+
expect( values ).toStrictEqual( {
|
|
62
|
+
datetime: '2024-03-02 00:00:00',
|
|
63
|
+
modified: '2025-06-07 00:00:00',
|
|
64
|
+
url: 'https://example.com/post',
|
|
65
|
+
} );
|
|
66
|
+
} );
|
|
67
|
+
|
|
68
|
+
it( 'should fall back to field labels when entity value does not exist', () => {
|
|
69
|
+
const values = postDataBindings.getValues( {
|
|
70
|
+
select,
|
|
71
|
+
context: { postId: 456, postType: 'post' },
|
|
72
|
+
bindings: {
|
|
73
|
+
datetime: {
|
|
74
|
+
source: 'core/post-date',
|
|
75
|
+
args: { field: 'date' },
|
|
76
|
+
},
|
|
77
|
+
modified: {
|
|
78
|
+
source: 'core/post-date',
|
|
79
|
+
args: { field: 'modified' },
|
|
80
|
+
},
|
|
81
|
+
url: {
|
|
82
|
+
source: 'core/post-date',
|
|
83
|
+
args: { field: 'link' },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
clientId: '123abc456',
|
|
87
|
+
} );
|
|
88
|
+
|
|
89
|
+
expect( values ).toStrictEqual( {
|
|
90
|
+
datetime: 'Post Date',
|
|
91
|
+
modified: 'Post Modified Date',
|
|
92
|
+
url: 'Post Link',
|
|
93
|
+
} );
|
|
94
|
+
} );
|
|
95
|
+
|
|
96
|
+
it( 'should return empty object for unknown fields', () => {
|
|
97
|
+
const values = postDataBindings.getValues( {
|
|
98
|
+
select,
|
|
99
|
+
context: { postId: 123, postType: 'post' },
|
|
100
|
+
bindings: {
|
|
101
|
+
content: {
|
|
102
|
+
source: 'core/post-date',
|
|
103
|
+
args: { field: 'unknown' },
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
clientId: '123abc456',
|
|
107
|
+
} );
|
|
108
|
+
|
|
109
|
+
expect( values.content ).toEqual( {} );
|
|
110
|
+
} );
|
|
111
|
+
} );
|
|
112
|
+
|
|
113
|
+
describe( 'for navigation blocks using block attributes', () => {
|
|
114
|
+
it( 'should use block attributes instead of context', () => {
|
|
115
|
+
const select = ( store ) => {
|
|
116
|
+
if ( store === blockEditorStore ) {
|
|
117
|
+
return {
|
|
118
|
+
getBlockName: () => 'core/navigation-link',
|
|
119
|
+
getBlockAttributes: () => ( {
|
|
120
|
+
id: 456,
|
|
121
|
+
type: 'page',
|
|
122
|
+
} ),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
getEditedEntityRecord: ( _kind, type, id ) => {
|
|
127
|
+
if ( type !== 'page' || id !== 456 ) {
|
|
128
|
+
return {};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
link: 'https://example.com/page',
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const values = postDataBindings.getValues( {
|
|
138
|
+
select,
|
|
139
|
+
context: { postId: 123, postType: 'post' },
|
|
140
|
+
bindings: {
|
|
141
|
+
url: {
|
|
142
|
+
source: 'core/post-date',
|
|
143
|
+
args: { field: 'link' },
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
clientId: '123abc456',
|
|
147
|
+
} );
|
|
148
|
+
|
|
149
|
+
expect( values.url ).toBe( 'https://example.com/page' );
|
|
150
|
+
} );
|
|
151
|
+
} );
|
|
152
|
+
} );
|
|
153
|
+
|
|
154
|
+
describe( 'getFieldsList', () => {
|
|
155
|
+
it( 'should return the list of available post data fields when the Date block is selected', () => {
|
|
156
|
+
const select = () => ( {
|
|
157
|
+
getSelectedBlock: () => ( {
|
|
158
|
+
name: 'core/post-date',
|
|
159
|
+
} ),
|
|
160
|
+
} );
|
|
161
|
+
|
|
162
|
+
const fields = postDataBindings.getFieldsList( {
|
|
163
|
+
select,
|
|
164
|
+
} );
|
|
165
|
+
|
|
166
|
+
expect( fields ).toEqual( [
|
|
167
|
+
{
|
|
168
|
+
label: 'Post Date',
|
|
169
|
+
args: { field: 'date' },
|
|
170
|
+
type: 'string',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
label: 'Post Modified Date',
|
|
174
|
+
args: { field: 'modified' },
|
|
175
|
+
type: 'string',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
label: 'Post Link',
|
|
179
|
+
args: { field: 'link' },
|
|
180
|
+
type: 'string',
|
|
181
|
+
},
|
|
182
|
+
] );
|
|
183
|
+
} );
|
|
184
|
+
|
|
185
|
+
it( 'should return an empty array when any other block than the Date block is selected', () => {
|
|
186
|
+
const select = () => ( {
|
|
187
|
+
getSelectedBlock: () => ( {
|
|
188
|
+
name: 'core/paragraph',
|
|
189
|
+
} ),
|
|
190
|
+
} );
|
|
191
|
+
|
|
192
|
+
const fields = postDataBindings.getFieldsList( {
|
|
193
|
+
select,
|
|
194
|
+
} );
|
|
195
|
+
|
|
196
|
+
expect( fields ).toEqual( [] );
|
|
197
|
+
} );
|
|
198
|
+
} );
|
|
199
|
+
} );
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from '@wordpress/components';
|
|
17
17
|
import { __ } from '@wordpress/i18n';
|
|
18
18
|
import { useInstanceId, useDebounce } from '@wordpress/compose';
|
|
19
|
+
import { isKeyboardEvent } from '@wordpress/keycodes';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Internal dependencies
|
|
@@ -50,6 +51,12 @@ function CommentForm( {
|
|
|
50
51
|
<VStack
|
|
51
52
|
className="editor-collab-sidebar-panel__comment-form"
|
|
52
53
|
spacing="4"
|
|
54
|
+
as="form"
|
|
55
|
+
onSubmit={ ( event ) => {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
onSubmit( inputComment );
|
|
58
|
+
setInputComment( '' );
|
|
59
|
+
} }
|
|
53
60
|
>
|
|
54
61
|
<VisuallyHidden as="label" htmlFor={ inputId }>
|
|
55
62
|
{ labelText ?? __( 'Note' ) }
|
|
@@ -63,6 +70,14 @@ function CommentForm( {
|
|
|
63
70
|
} }
|
|
64
71
|
rows={ 1 }
|
|
65
72
|
maxRows={ 20 }
|
|
73
|
+
onKeyDown={ ( event ) => {
|
|
74
|
+
if (
|
|
75
|
+
isKeyboardEvent.primary( event, 'Enter' ) &&
|
|
76
|
+
! isDisabled
|
|
77
|
+
) {
|
|
78
|
+
event.target.parentNode.requestSubmit();
|
|
79
|
+
}
|
|
80
|
+
} }
|
|
66
81
|
/>
|
|
67
82
|
<HStack spacing="2" justify="flex-end" wrap>
|
|
68
83
|
<Button size="compact" variant="tertiary" onClick={ onCancel }>
|
|
@@ -72,10 +87,7 @@ function CommentForm( {
|
|
|
72
87
|
size="compact"
|
|
73
88
|
accessibleWhenDisabled
|
|
74
89
|
variant="primary"
|
|
75
|
-
|
|
76
|
-
onSubmit( inputComment );
|
|
77
|
-
setInputComment( '' );
|
|
78
|
-
} }
|
|
90
|
+
type="submit"
|
|
79
91
|
disabled={ isDisabled }
|
|
80
92
|
>
|
|
81
93
|
<Truncate>{ submitButtonText }</Truncate>
|
|
@@ -66,6 +66,9 @@ export function Comments( {
|
|
|
66
66
|
const [ blockRefs, setBlockRefs ] = useState( {} );
|
|
67
67
|
|
|
68
68
|
const { setCanvasMinHeight } = unlock( useDispatch( editorStore ) );
|
|
69
|
+
const { selectBlock, toggleBlockSpotlight } = unlock(
|
|
70
|
+
useDispatch( blockEditorStore )
|
|
71
|
+
);
|
|
69
72
|
const { blockCommentId, selectedBlockClientId, orderedBlockIds } =
|
|
70
73
|
useSelect( ( select ) => {
|
|
71
74
|
const {
|
|
@@ -310,10 +313,84 @@ export function Comments( {
|
|
|
310
313
|
setCanvasMinHeight,
|
|
311
314
|
] );
|
|
312
315
|
|
|
316
|
+
const handleThreadNavigation = ( event, thread, isSelected ) => {
|
|
317
|
+
if ( event.defaultPrevented ) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const currentIndex = threads.findIndex( ( t ) => t.id === thread.id );
|
|
322
|
+
|
|
323
|
+
if (
|
|
324
|
+
( event.key === 'Enter' || event.key === 'ArrowRight' ) &&
|
|
325
|
+
event.currentTarget === event.target &&
|
|
326
|
+
! isSelected
|
|
327
|
+
) {
|
|
328
|
+
// Expand thread.
|
|
329
|
+
setNewNoteFormState( 'closed' );
|
|
330
|
+
setSelectedThread( thread.id );
|
|
331
|
+
if ( !! thread.blockClientId ) {
|
|
332
|
+
// Pass `null` as the second parameter to prevent focusing the block.
|
|
333
|
+
selectBlock( thread.blockClientId, null );
|
|
334
|
+
toggleBlockSpotlight( thread.blockClientId, true );
|
|
335
|
+
}
|
|
336
|
+
} else if (
|
|
337
|
+
( ( event.key === 'Enter' || event.key === 'ArrowLeft' ) &&
|
|
338
|
+
event.currentTarget === event.target &&
|
|
339
|
+
isSelected ) ||
|
|
340
|
+
event.key === 'Escape'
|
|
341
|
+
) {
|
|
342
|
+
// Collapse thread.
|
|
343
|
+
setSelectedThread( null );
|
|
344
|
+
setNewNoteFormState( 'closed' );
|
|
345
|
+
if ( thread.blockClientId ) {
|
|
346
|
+
toggleBlockSpotlight( thread.blockClientId, false );
|
|
347
|
+
}
|
|
348
|
+
focusCommentThread( thread.id, commentSidebarRef.current );
|
|
349
|
+
} else if (
|
|
350
|
+
event.key === 'ArrowDown' &&
|
|
351
|
+
currentIndex < threads.length - 1 &&
|
|
352
|
+
event.currentTarget === event.target
|
|
353
|
+
) {
|
|
354
|
+
// Move to the next thread.
|
|
355
|
+
const nextThread = threads[ currentIndex + 1 ];
|
|
356
|
+
focusCommentThread( nextThread.id, commentSidebarRef.current );
|
|
357
|
+
} else if (
|
|
358
|
+
event.key === 'ArrowUp' &&
|
|
359
|
+
currentIndex > 0 &&
|
|
360
|
+
event.currentTarget === event.target
|
|
361
|
+
) {
|
|
362
|
+
// Move to the previous thread.
|
|
363
|
+
const prevThread = threads[ currentIndex - 1 ];
|
|
364
|
+
focusCommentThread( prevThread.id, commentSidebarRef.current );
|
|
365
|
+
} else if (
|
|
366
|
+
event.key === 'Home' &&
|
|
367
|
+
event.currentTarget === event.target
|
|
368
|
+
) {
|
|
369
|
+
// Move to the first thread.
|
|
370
|
+
focusCommentThread( threads[ 0 ].id, commentSidebarRef.current );
|
|
371
|
+
} else if (
|
|
372
|
+
event.key === 'End' &&
|
|
373
|
+
event.currentTarget === event.target
|
|
374
|
+
) {
|
|
375
|
+
// Move to the last thread.
|
|
376
|
+
focusCommentThread(
|
|
377
|
+
threads[ threads.length - 1 ].id,
|
|
378
|
+
commentSidebarRef.current
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
|
|
313
383
|
const hasThreads = Array.isArray( threads ) && threads.length > 0;
|
|
314
|
-
//
|
|
384
|
+
// A special case for `template-locked` mode - https://github.com/WordPress/gutenberg/pull/72646.
|
|
315
385
|
if ( ! hasThreads && ! isFloating ) {
|
|
316
|
-
return
|
|
386
|
+
return (
|
|
387
|
+
<AddComment
|
|
388
|
+
onSubmit={ onAddReply }
|
|
389
|
+
newNoteFormState={ newNoteFormState }
|
|
390
|
+
setNewNoteFormState={ setNewNoteFormState }
|
|
391
|
+
commentSidebarRef={ commentSidebarRef }
|
|
392
|
+
/>
|
|
393
|
+
);
|
|
317
394
|
}
|
|
318
395
|
|
|
319
396
|
return (
|
|
@@ -345,6 +422,13 @@ export function Comments( {
|
|
|
345
422
|
selectedThread={ selectedThread }
|
|
346
423
|
commentLastUpdated={ commentLastUpdated }
|
|
347
424
|
newNoteFormState={ newNoteFormState }
|
|
425
|
+
onKeyDown={ ( event ) =>
|
|
426
|
+
handleThreadNavigation(
|
|
427
|
+
event,
|
|
428
|
+
thread,
|
|
429
|
+
selectedThread === thread.id
|
|
430
|
+
)
|
|
431
|
+
}
|
|
348
432
|
/>
|
|
349
433
|
) ) }
|
|
350
434
|
</>
|
|
@@ -368,6 +452,7 @@ function Thread( {
|
|
|
368
452
|
selectedThread,
|
|
369
453
|
commentLastUpdated,
|
|
370
454
|
newNoteFormState,
|
|
455
|
+
onKeyDown,
|
|
371
456
|
} ) {
|
|
372
457
|
const { toggleBlockHighlight, selectBlock, toggleBlockSpotlight } = unlock(
|
|
373
458
|
useDispatch( blockEditorStore )
|
|
@@ -385,6 +470,7 @@ function Thread( {
|
|
|
385
470
|
selectedThread,
|
|
386
471
|
commentLastUpdated,
|
|
387
472
|
} );
|
|
473
|
+
const isKeyboardTabbingRef = useRef( false );
|
|
388
474
|
|
|
389
475
|
const onMouseEnter = () => {
|
|
390
476
|
debouncedToggleBlockHighlight( thread.blockClientId, true );
|
|
@@ -394,13 +480,48 @@ function Thread( {
|
|
|
394
480
|
debouncedToggleBlockHighlight( thread.blockClientId, false );
|
|
395
481
|
};
|
|
396
482
|
|
|
483
|
+
const onFocus = () => {
|
|
484
|
+
toggleBlockHighlight( thread.blockClientId, true );
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
const onBlur = ( event ) => {
|
|
488
|
+
const isNoteFocused = event.relatedTarget?.closest(
|
|
489
|
+
'.editor-collab-sidebar-panel__thread'
|
|
490
|
+
);
|
|
491
|
+
const isDialogFocused =
|
|
492
|
+
event.relatedTarget?.closest( '[role="dialog"]' );
|
|
493
|
+
const isTabbing = isKeyboardTabbingRef.current;
|
|
494
|
+
|
|
495
|
+
// When another note is clicked, do nothing because the current note is automatically closed.
|
|
496
|
+
if ( isNoteFocused && ! isTabbing ) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
// When deleting a note, a dialog appears, but the note should not be collapsed.
|
|
500
|
+
if ( isDialogFocused ) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
// When tabbing, do nothing if the focus is within the current note.
|
|
504
|
+
if (
|
|
505
|
+
isTabbing &&
|
|
506
|
+
event.currentTarget.contains( event.relatedTarget )
|
|
507
|
+
) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Closes a note that has lost focus when any of the following conditions are met:
|
|
512
|
+
// - An element other than a note is clicked.
|
|
513
|
+
// - Focus was lost by tabbing.
|
|
514
|
+
toggleBlockHighlight( thread.blockClientId, false );
|
|
515
|
+
unselectThread();
|
|
516
|
+
};
|
|
517
|
+
|
|
397
518
|
const handleCommentSelect = () => {
|
|
398
519
|
setNewNoteFormState( 'closed' );
|
|
399
520
|
setSelectedThread( thread.id );
|
|
521
|
+
toggleBlockSpotlight( thread.blockClientId, true );
|
|
400
522
|
if ( !! thread.blockClientId ) {
|
|
401
523
|
// Pass `null` as the second parameter to prevent focusing the block.
|
|
402
524
|
selectBlock( thread.blockClientId, null );
|
|
403
|
-
toggleBlockSpotlight( thread.blockClientId, true );
|
|
404
525
|
}
|
|
405
526
|
};
|
|
406
527
|
|
|
@@ -462,27 +583,18 @@ function Thread( {
|
|
|
462
583
|
onClick={ handleCommentSelect }
|
|
463
584
|
onMouseEnter={ onMouseEnter }
|
|
464
585
|
onMouseLeave={ onMouseLeave }
|
|
465
|
-
onFocus={
|
|
466
|
-
onBlur={
|
|
467
|
-
|
|
468
|
-
if ( event.
|
|
469
|
-
|
|
470
|
-
}
|
|
471
|
-
// Expand or Collapse thread.
|
|
472
|
-
if (
|
|
473
|
-
event.key === 'Enter' &&
|
|
474
|
-
event.currentTarget === event.target
|
|
475
|
-
) {
|
|
476
|
-
if ( isSelected ) {
|
|
477
|
-
unselectThread();
|
|
478
|
-
} else {
|
|
479
|
-
handleCommentSelect();
|
|
480
|
-
}
|
|
586
|
+
onFocus={ onFocus }
|
|
587
|
+
onBlur={ onBlur }
|
|
588
|
+
onKeyUp={ ( event ) => {
|
|
589
|
+
if ( event.key === 'Tab' ) {
|
|
590
|
+
isKeyboardTabbingRef.current = false;
|
|
481
591
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
592
|
+
} }
|
|
593
|
+
onKeyDown={ ( event ) => {
|
|
594
|
+
if ( event.key === 'Tab' ) {
|
|
595
|
+
isKeyboardTabbingRef.current = true;
|
|
596
|
+
} else {
|
|
597
|
+
onKeyDown( event );
|
|
486
598
|
}
|
|
487
599
|
} }
|
|
488
600
|
tabIndex={ 0 }
|
|
@@ -504,7 +616,7 @@ function Thread( {
|
|
|
504
616
|
);
|
|
505
617
|
} }
|
|
506
618
|
>
|
|
507
|
-
{ __( 'Add new
|
|
619
|
+
{ __( 'Add new reply' ) }
|
|
508
620
|
</Button>
|
|
509
621
|
{ ! thread.blockClientId && (
|
|
510
622
|
<Text as="p" weight={ 500 } variant="muted">
|
|
@@ -709,6 +821,14 @@ const CommentBoard = ( {
|
|
|
709
821
|
? actions.filter( ( item ) => item.isEligible( thread ) )
|
|
710
822
|
: [];
|
|
711
823
|
|
|
824
|
+
const deleteConfirmMessage =
|
|
825
|
+
// When deleting a top level note, descendants will also be deleted.
|
|
826
|
+
thread.parent === 0
|
|
827
|
+
? __(
|
|
828
|
+
"Are you sure you want to delete this note? This will also delete all of this note's replies."
|
|
829
|
+
)
|
|
830
|
+
: __( 'Are you sure you want to delete this reply?' );
|
|
831
|
+
|
|
712
832
|
return (
|
|
713
833
|
<VStack
|
|
714
834
|
spacing="2"
|
|
@@ -763,7 +883,12 @@ const CommentBoard = ( {
|
|
|
763
883
|
/>
|
|
764
884
|
}
|
|
765
885
|
/>
|
|
766
|
-
<Menu.Popover
|
|
886
|
+
<Menu.Popover
|
|
887
|
+
// The menu popover is rendered in a portal, which causes focus to be
|
|
888
|
+
// lost and the note to be collapsed unintentionally. To prevent this,
|
|
889
|
+
// the popover should be rendered as an inline.
|
|
890
|
+
modal={ false }
|
|
891
|
+
>
|
|
767
892
|
{ moreActions.map( ( action ) => (
|
|
768
893
|
<Menu.Item
|
|
769
894
|
key={ action.id }
|
|
@@ -844,9 +969,7 @@ const CommentBoard = ( {
|
|
|
844
969
|
onCancel={ handleCancel }
|
|
845
970
|
confirmButtonText={ __( 'Delete' ) }
|
|
846
971
|
>
|
|
847
|
-
{
|
|
848
|
-
"Are you sure you want to delete this note? This will also delete all of this note's replies."
|
|
849
|
-
) }
|
|
972
|
+
{ deleteConfirmMessage }
|
|
850
973
|
</ConfirmDialog>
|
|
851
974
|
) }
|
|
852
975
|
</VStack>
|
|
@@ -53,14 +53,17 @@ export default function PostTemplatePanel() {
|
|
|
53
53
|
return canCreateTemplates;
|
|
54
54
|
}, [] );
|
|
55
55
|
|
|
56
|
-
const canViewTemplates = useSelect(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
const canViewTemplates = useSelect(
|
|
57
|
+
( select ) => {
|
|
58
|
+
return isVisible
|
|
59
|
+
? select( coreStore ).canUser( 'read', {
|
|
60
|
+
kind: 'postType',
|
|
61
|
+
name: 'wp_template',
|
|
62
|
+
} )
|
|
63
|
+
: false;
|
|
64
|
+
},
|
|
65
|
+
[ isVisible ]
|
|
66
|
+
);
|
|
64
67
|
|
|
65
68
|
if ( ( ! isBlockTheme || ! canViewTemplates ) && isVisible ) {
|
|
66
69
|
return <ClassicThemeControl />;
|