@wordpress/editor 14.33.3 → 14.33.5
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/bindings/post-data.js +47 -63
- package/build/bindings/post-data.js.map +3 -3
- package/build/bindings/post-meta.js +45 -39
- package/build/bindings/post-meta.js.map +2 -2
- package/build/components/collab-sidebar/add-comment.js +9 -5
- package/build/components/collab-sidebar/add-comment.js.map +2 -2
- package/build/components/collab-sidebar/comment-author-info.js +27 -15
- package/build/components/collab-sidebar/comment-author-info.js.map +2 -2
- package/build/components/collab-sidebar/comment-indicator-toolbar.js +9 -23
- package/build/components/collab-sidebar/comment-indicator-toolbar.js.map +3 -3
- package/build/components/collab-sidebar/comment-menu-item.js +36 -6
- package/build/components/collab-sidebar/comment-menu-item.js.map +3 -3
- package/build/components/collab-sidebar/comments.js +317 -301
- package/build/components/collab-sidebar/comments.js.map +3 -3
- package/build/components/collab-sidebar/hooks.js +5 -3
- package/build/components/collab-sidebar/hooks.js.map +2 -2
- package/build/components/collab-sidebar/index.js +35 -11
- package/build/components/collab-sidebar/index.js.map +3 -3
- package/build/components/collab-sidebar/utils.js +6 -3
- package/build/components/collab-sidebar/utils.js.map +2 -2
- package/build/components/editor/index.js +2 -2
- package/build/components/editor/index.js.map +3 -3
- package/build/components/more-menu/index.js +1 -1
- package/build/components/more-menu/index.js.map +2 -2
- package/build/components/visual-editor/index.js +20 -9
- package/build/components/visual-editor/index.js.map +2 -2
- package/build/store/private-actions.js +8 -0
- package/build/store/private-actions.js.map +2 -2
- package/build/store/private-selectors.js +5 -0
- package/build/store/private-selectors.js.map +2 -2
- package/build/store/reducer.js +10 -0
- package/build/store/reducer.js.map +2 -2
- package/build-module/bindings/post-data.js +47 -63
- package/build-module/bindings/post-data.js.map +2 -2
- package/build-module/bindings/post-meta.js +45 -39
- package/build-module/bindings/post-meta.js.map +2 -2
- package/build-module/components/collab-sidebar/add-comment.js +10 -6
- package/build-module/components/collab-sidebar/add-comment.js.map +2 -2
- package/build-module/components/collab-sidebar/comment-author-info.js +27 -15
- package/build-module/components/collab-sidebar/comment-author-info.js.map +2 -2
- package/build-module/components/collab-sidebar/comment-indicator-toolbar.js +15 -25
- package/build-module/components/collab-sidebar/comment-indicator-toolbar.js.map +2 -2
- package/build-module/components/collab-sidebar/comment-menu-item.js +40 -7
- package/build-module/components/collab-sidebar/comment-menu-item.js.map +2 -2
- package/build-module/components/collab-sidebar/comments.js +319 -302
- package/build-module/components/collab-sidebar/comments.js.map +2 -2
- package/build-module/components/collab-sidebar/hooks.js +5 -3
- package/build-module/components/collab-sidebar/hooks.js.map +2 -2
- package/build-module/components/collab-sidebar/index.js +35 -11
- package/build-module/components/collab-sidebar/index.js.map +2 -2
- package/build-module/components/collab-sidebar/utils.js +6 -3
- package/build-module/components/collab-sidebar/utils.js.map +2 -2
- package/build-module/components/editor/index.js +2 -2
- package/build-module/components/editor/index.js.map +2 -2
- package/build-module/components/more-menu/index.js +1 -1
- package/build-module/components/more-menu/index.js.map +2 -2
- package/build-module/components/visual-editor/index.js +20 -9
- package/build-module/components/visual-editor/index.js.map +2 -2
- package/build-module/store/private-actions.js +7 -0
- package/build-module/store/private-actions.js.map +2 -2
- package/build-module/store/private-selectors.js +4 -0
- package/build-module/store/private-selectors.js.map +2 -2
- package/build-module/store/reducer.js +9 -0
- package/build-module/store/reducer.js.map +2 -2
- package/build-style/style-rtl.css +6 -43
- package/build-style/style.css +6 -43
- package/build-types/bindings/post-data.d.ts +18 -8
- package/build-types/bindings/post-meta.d.ts +1 -7
- package/build-types/components/collab-sidebar/add-comment.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/comment-author-info.d.ts +5 -16
- package/build-types/components/collab-sidebar/comment-author-info.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/comment-menu-item.d.ts +3 -2
- package/build-types/components/collab-sidebar/comment-menu-item.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/collab-sidebar/hooks.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/utils.d.ts +2 -2
- package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
- package/build-types/components/visual-editor/index.d.ts.map +1 -1
- package/build-types/store/private-actions.d.ts +7 -0
- package/build-types/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-selectors.d.ts +7 -0
- package/build-types/store/private-selectors.d.ts.map +1 -1
- package/build-types/store/reducer.d.ts +10 -0
- package/build-types/store/reducer.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/bindings/post-data.js +63 -111
- package/src/bindings/post-meta.js +55 -46
- package/src/bindings/test/post-meta.js +211 -0
- package/src/components/collab-sidebar/add-comment.js +11 -6
- package/src/components/collab-sidebar/comment-author-info.js +33 -26
- package/src/components/collab-sidebar/comment-indicator-toolbar.js +19 -29
- package/src/components/collab-sidebar/comment-menu-item.js +51 -11
- package/src/components/collab-sidebar/comments.js +47 -27
- package/src/components/collab-sidebar/hooks.js +6 -4
- package/src/components/collab-sidebar/index.js +63 -27
- package/src/components/collab-sidebar/style.scss +6 -46
- package/src/components/collab-sidebar/utils.js +15 -5
- package/src/components/editor/index.js +1 -1
- package/src/components/more-menu/index.js +1 -1
- package/src/components/visual-editor/index.js +27 -6
- package/src/store/private-actions.js +13 -0
- package/src/store/private-selectors.js +10 -0
- package/src/store/reducer.js +16 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -11,90 +11,23 @@ const NAVIGATION_BLOCK_TYPES = [
|
|
|
11
11
|
'core/navigation-submenu',
|
|
12
12
|
];
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
* },
|
|
32
|
-
* field_2_key: {
|
|
33
|
-
* label: 'Field 2 Label',
|
|
34
|
-
* value: 'Field 2 Value',
|
|
35
|
-
* },
|
|
36
|
-
* ...
|
|
37
|
-
* }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
function getPostDataFields( select, context, clientId ) {
|
|
41
|
-
const { getEditedEntityRecord } = select( coreDataStore );
|
|
42
|
-
const { getBlockAttributes, getBlockName } = select( blockEditorStore );
|
|
43
|
-
|
|
44
|
-
let entityDataValues, dataFields;
|
|
45
|
-
|
|
46
|
-
/*
|
|
47
|
-
* BACKWARDS COMPATIBILITY: Hardcoded exception for navigation blocks.
|
|
48
|
-
* Required for WordPress 6.9+ navigation blocks. DO NOT REMOVE.
|
|
49
|
-
*/
|
|
50
|
-
const blockName = getBlockName?.( clientId );
|
|
51
|
-
const isNavigationBlock = NAVIGATION_BLOCK_TYPES.includes( blockName );
|
|
52
|
-
|
|
53
|
-
let postId, postType;
|
|
54
|
-
|
|
55
|
-
if ( isNavigationBlock ) {
|
|
56
|
-
// Navigation blocks: read from block attributes
|
|
57
|
-
const blockAttributes = getBlockAttributes?.( clientId );
|
|
58
|
-
postId = blockAttributes?.id;
|
|
59
|
-
postType = blockAttributes?.type;
|
|
60
|
-
} else {
|
|
61
|
-
// All other blocks: use context
|
|
62
|
-
postId = context?.postId;
|
|
63
|
-
postType = context?.postType;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Try to get the current entity data values using resolved identifiers.
|
|
67
|
-
if ( postType && postId ) {
|
|
68
|
-
entityDataValues = getEditedEntityRecord(
|
|
69
|
-
'postType',
|
|
70
|
-
postType,
|
|
71
|
-
postId
|
|
72
|
-
);
|
|
73
|
-
dataFields = {
|
|
74
|
-
date: {
|
|
75
|
-
label: __( 'Post Date' ),
|
|
76
|
-
value: entityDataValues?.date,
|
|
77
|
-
type: 'string',
|
|
78
|
-
},
|
|
79
|
-
modified: {
|
|
80
|
-
label: __( 'Post Modified Date' ),
|
|
81
|
-
value: entityDataValues?.modified,
|
|
82
|
-
type: 'string',
|
|
83
|
-
},
|
|
84
|
-
link: {
|
|
85
|
-
label: __( 'Post Link' ),
|
|
86
|
-
value: entityDataValues?.link,
|
|
87
|
-
type: 'string',
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if ( ! Object.keys( dataFields || {} ).length ) {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return dataFields;
|
|
97
|
-
}
|
|
14
|
+
const postDataFields = [
|
|
15
|
+
{
|
|
16
|
+
label: __( 'Post Date' ),
|
|
17
|
+
args: { field: 'date' },
|
|
18
|
+
type: 'string',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
label: __( 'Post Modified Date' ),
|
|
22
|
+
args: { field: 'modified' },
|
|
23
|
+
type: 'string',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: __( 'Post Link' ),
|
|
27
|
+
args: { field: 'link' },
|
|
28
|
+
type: 'string',
|
|
29
|
+
},
|
|
30
|
+
];
|
|
98
31
|
|
|
99
32
|
/**
|
|
100
33
|
* @type {WPBlockBindingsSource}
|
|
@@ -102,15 +35,50 @@ function getPostDataFields( select, context, clientId ) {
|
|
|
102
35
|
export default {
|
|
103
36
|
name: 'core/post-data',
|
|
104
37
|
getValues( { select, context, bindings, clientId } ) {
|
|
105
|
-
const
|
|
38
|
+
const allowedFields = postDataFields.map(
|
|
39
|
+
( field ) => field.args.field
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* BACKWARDS COMPATIBILITY: Hardcoded exception for navigation blocks.
|
|
44
|
+
* Required for WordPress 6.9+ navigation blocks. DO NOT REMOVE.
|
|
45
|
+
*/
|
|
46
|
+
const { getBlockAttributes, getBlockName } = select( blockEditorStore );
|
|
47
|
+
const blockName = getBlockName?.( clientId );
|
|
48
|
+
const isNavigationBlock = NAVIGATION_BLOCK_TYPES.includes( blockName );
|
|
49
|
+
|
|
50
|
+
let postId, postType;
|
|
51
|
+
|
|
52
|
+
if ( isNavigationBlock ) {
|
|
53
|
+
// Navigation blocks: read from block attributes
|
|
54
|
+
const blockAttributes = getBlockAttributes?.( clientId );
|
|
55
|
+
postId = blockAttributes?.id;
|
|
56
|
+
postType = blockAttributes?.type;
|
|
57
|
+
} else {
|
|
58
|
+
// All other blocks: use context
|
|
59
|
+
postId = context?.postId;
|
|
60
|
+
postType = context?.postType;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { getEditedEntityRecord } = select( coreDataStore );
|
|
64
|
+
const entityDataValues = getEditedEntityRecord(
|
|
65
|
+
'postType',
|
|
66
|
+
postType,
|
|
67
|
+
postId
|
|
68
|
+
);
|
|
106
69
|
|
|
107
70
|
const newValues = {};
|
|
108
|
-
for ( const [ attributeName,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
71
|
+
for ( const [ attributeName, binding ] of Object.entries( bindings ) ) {
|
|
72
|
+
if ( ! allowedFields.includes( binding.args.field ) ) {
|
|
73
|
+
newValues[ attributeName ] = {};
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
newValues[ attributeName ] =
|
|
78
|
+
entityDataValues?.[ binding.args.field ] ??
|
|
79
|
+
postDataFields.find(
|
|
80
|
+
( field ) => field.args.field === binding.args.field
|
|
81
|
+
).label;
|
|
114
82
|
}
|
|
115
83
|
return newValues;
|
|
116
84
|
},
|
|
@@ -136,7 +104,7 @@ export default {
|
|
|
136
104
|
newData
|
|
137
105
|
);
|
|
138
106
|
},
|
|
139
|
-
canUserEditValue( { select, context
|
|
107
|
+
canUserEditValue( { select, context } ) {
|
|
140
108
|
const { getBlockName, getSelectedBlockClientId } =
|
|
141
109
|
select( blockEditorStore );
|
|
142
110
|
const clientId = getSelectedBlockClientId();
|
|
@@ -158,14 +126,6 @@ export default {
|
|
|
158
126
|
return false;
|
|
159
127
|
}
|
|
160
128
|
|
|
161
|
-
const fieldValue = getPostDataFields( select, context, undefined )?.[
|
|
162
|
-
args.field
|
|
163
|
-
]?.value;
|
|
164
|
-
// Empty string or `false` could be a valid value, so we need to check if the field value is undefined.
|
|
165
|
-
if ( fieldValue === undefined ) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
129
|
// Check that the user has the capability to edit post data.
|
|
170
130
|
const canUserEdit = select( coreDataStore ).canUser( 'update', {
|
|
171
131
|
kind: 'postType',
|
|
@@ -178,7 +138,7 @@ export default {
|
|
|
178
138
|
|
|
179
139
|
return true;
|
|
180
140
|
},
|
|
181
|
-
getFieldsList( { select
|
|
141
|
+
getFieldsList( { select } ) {
|
|
182
142
|
const selectedBlock = select( blockEditorStore ).getSelectedBlock();
|
|
183
143
|
if ( selectedBlock?.name !== 'core/post-date' ) {
|
|
184
144
|
return [];
|
|
@@ -187,15 +147,7 @@ export default {
|
|
|
187
147
|
if ( NAVIGATION_BLOCK_TYPES.includes( selectedBlock?.name ) ) {
|
|
188
148
|
return [];
|
|
189
149
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if ( ! postDataFields ) {
|
|
193
|
-
return [];
|
|
194
|
-
}
|
|
195
|
-
return Object.entries( postDataFields ).map( ( [ key, field ] ) => ( {
|
|
196
|
-
label: field.label,
|
|
197
|
-
type: field.type,
|
|
198
|
-
args: { field: key },
|
|
199
|
-
} ) );
|
|
150
|
+
|
|
151
|
+
return postDataFields;
|
|
200
152
|
},
|
|
201
153
|
};
|
|
@@ -35,41 +35,52 @@ import { unlock } from '../lock-unlock';
|
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
37
|
function getPostMetaFields( select, context ) {
|
|
38
|
-
const { getEditedEntityRecord } = select( coreDataStore );
|
|
39
38
|
const { getRegisteredPostMeta } = unlock( select( coreDataStore ) );
|
|
40
39
|
|
|
41
|
-
let entityMetaValues;
|
|
42
|
-
// Try to get the current entity meta values.
|
|
43
|
-
if ( context?.postType && context?.postId ) {
|
|
44
|
-
entityMetaValues = getEditedEntityRecord(
|
|
45
|
-
'postType',
|
|
46
|
-
context?.postType,
|
|
47
|
-
context?.postId
|
|
48
|
-
).meta;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
40
|
const registeredFields = getRegisteredPostMeta( context?.postType );
|
|
52
|
-
const metaFields =
|
|
53
|
-
Object.entries( registeredFields
|
|
41
|
+
const metaFields = [];
|
|
42
|
+
Object.entries( registeredFields ).forEach( ( [ key, props ] ) => {
|
|
54
43
|
// Don't include footnotes or private fields.
|
|
55
|
-
if ( key
|
|
56
|
-
|
|
57
|
-
label: props.title || key,
|
|
58
|
-
value:
|
|
59
|
-
// When using the entity value, an empty string IS a valid value.
|
|
60
|
-
entityMetaValues?.[ key ] ??
|
|
61
|
-
// When using the default, an empty string IS NOT a valid value.
|
|
62
|
-
( props.default || undefined ),
|
|
63
|
-
type: props.type,
|
|
64
|
-
};
|
|
44
|
+
if ( key === 'footnotes' || key.charAt( 0 ) === '_' ) {
|
|
45
|
+
return;
|
|
65
46
|
}
|
|
47
|
+
|
|
48
|
+
metaFields.push( {
|
|
49
|
+
label: props.title || key,
|
|
50
|
+
args: { key },
|
|
51
|
+
default: props.default,
|
|
52
|
+
type: props.type,
|
|
53
|
+
} );
|
|
66
54
|
} );
|
|
67
55
|
|
|
68
|
-
|
|
69
|
-
|
|
56
|
+
return metaFields;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getValue( { select, context, args } ) {
|
|
60
|
+
const metaFields = getPostMetaFields( select, context );
|
|
61
|
+
const metaField = metaFields.find(
|
|
62
|
+
( field ) => field.args.key === args.key
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// If the meta field was not found, it's either protected, inaccessible, or simply doesn't exist.
|
|
66
|
+
if ( ! metaField ) {
|
|
67
|
+
return args.key;
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
// Without a postId, we cannot look up a meta value.
|
|
71
|
+
if ( ! context?.postId ) {
|
|
72
|
+
// Return the default value for the meta field if available.
|
|
73
|
+
return metaField.default || metaField.label || args.key;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const { getEditedEntityRecord } = select( coreDataStore );
|
|
77
|
+
const entityMetaValues = getEditedEntityRecord(
|
|
78
|
+
'postType',
|
|
79
|
+
context?.postType,
|
|
80
|
+
context?.postId
|
|
81
|
+
).meta;
|
|
82
|
+
|
|
83
|
+
return entityMetaValues?.[ args.key ] ?? metaField?.label ?? args.key;
|
|
73
84
|
}
|
|
74
85
|
|
|
75
86
|
/**
|
|
@@ -78,15 +89,13 @@ function getPostMetaFields( select, context ) {
|
|
|
78
89
|
export default {
|
|
79
90
|
name: 'core/post-meta',
|
|
80
91
|
getValues( { select, context, bindings } ) {
|
|
81
|
-
const metaFields = getPostMetaFields( select, context );
|
|
82
|
-
|
|
83
92
|
const newValues = {};
|
|
84
|
-
for ( const [ attributeName,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
for ( const [ attributeName, binding ] of Object.entries( bindings ) ) {
|
|
94
|
+
newValues[ attributeName ] = getValue( {
|
|
95
|
+
select,
|
|
96
|
+
context,
|
|
97
|
+
args: binding.args,
|
|
98
|
+
} );
|
|
90
99
|
}
|
|
91
100
|
return newValues;
|
|
92
101
|
},
|
|
@@ -116,12 +125,14 @@ export default {
|
|
|
116
125
|
return false;
|
|
117
126
|
}
|
|
118
127
|
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
const metaFields = getPostMetaFields( select, context );
|
|
129
|
+
const hasMatchingMetaField = metaFields.some(
|
|
130
|
+
( field ) => field.args.key === args.key
|
|
131
|
+
);
|
|
132
|
+
if ( ! hasMatchingMetaField ) {
|
|
123
133
|
return false;
|
|
124
134
|
}
|
|
135
|
+
|
|
125
136
|
// Check that custom fields metabox is not enabled.
|
|
126
137
|
const areCustomFieldsEnabled =
|
|
127
138
|
select( editorStore ).getEditorSettings().enableCustomFields;
|
|
@@ -143,13 +154,11 @@ export default {
|
|
|
143
154
|
},
|
|
144
155
|
getFieldsList( { select, context } ) {
|
|
145
156
|
const metaFields = getPostMetaFields( select, context );
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
args: { key },
|
|
153
|
-
} ) );
|
|
157
|
+
// Remove 'default' property from meta fields.
|
|
158
|
+
return metaFields.map(
|
|
159
|
+
( { default: defaultProp, ...otherProps } ) => ( {
|
|
160
|
+
...otherProps,
|
|
161
|
+
} )
|
|
162
|
+
);
|
|
154
163
|
},
|
|
155
164
|
};
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { lock } from '../../lock-unlock';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import postMetaBindings from '../post-meta';
|
|
10
|
+
|
|
11
|
+
describe( 'post-meta bindings', () => {
|
|
12
|
+
let context, select, selectReturn;
|
|
13
|
+
|
|
14
|
+
beforeAll( () => {
|
|
15
|
+
const getEditedEntityRecord = ( kind, type, id ) => ( {
|
|
16
|
+
meta:
|
|
17
|
+
id === 123
|
|
18
|
+
? {
|
|
19
|
+
movie_field: 'Test Movie Value',
|
|
20
|
+
_protected_field: 'Protected field value',
|
|
21
|
+
}
|
|
22
|
+
: {},
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
const getEditorSettings = () => ( {
|
|
26
|
+
enableCustomFields: false,
|
|
27
|
+
} );
|
|
28
|
+
|
|
29
|
+
selectReturn = {
|
|
30
|
+
getEditedEntityRecord,
|
|
31
|
+
getEditorSettings,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const getRegisteredPostMeta = () => ( {
|
|
35
|
+
field_without_label_or_default: { type: 'string' },
|
|
36
|
+
field_with_label_only: {
|
|
37
|
+
title: 'Field With Label Only',
|
|
38
|
+
default: '', // If there's no default set, getRegisteredPostMeta() will return an empty string.
|
|
39
|
+
type: 'string',
|
|
40
|
+
},
|
|
41
|
+
movie_field: {
|
|
42
|
+
title: 'Movie Field Label',
|
|
43
|
+
default: 'Movie field default value',
|
|
44
|
+
type: 'string',
|
|
45
|
+
},
|
|
46
|
+
_protected_field: {
|
|
47
|
+
default: 'Protected field default value',
|
|
48
|
+
type: 'string',
|
|
49
|
+
},
|
|
50
|
+
} );
|
|
51
|
+
|
|
52
|
+
lock( selectReturn, { getRegisteredPostMeta } );
|
|
53
|
+
|
|
54
|
+
select = () => selectReturn;
|
|
55
|
+
} );
|
|
56
|
+
|
|
57
|
+
describe( 'when no postId is provided in context', () => {
|
|
58
|
+
beforeAll( () => {
|
|
59
|
+
context = { postType: 'movie' };
|
|
60
|
+
} );
|
|
61
|
+
|
|
62
|
+
describe( 'getValues', () => {
|
|
63
|
+
it( 'should return the meta default value if it is defined', () => {
|
|
64
|
+
const values = postMetaBindings.getValues( {
|
|
65
|
+
select,
|
|
66
|
+
context,
|
|
67
|
+
bindings: {
|
|
68
|
+
content: {
|
|
69
|
+
args: { key: 'movie_field' },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
} );
|
|
73
|
+
|
|
74
|
+
expect( values.content ).toBe( 'Movie field default value' );
|
|
75
|
+
} );
|
|
76
|
+
|
|
77
|
+
it( 'should fall back to the field label if the meta default value is not defined', () => {
|
|
78
|
+
const values = postMetaBindings.getValues( {
|
|
79
|
+
select,
|
|
80
|
+
context,
|
|
81
|
+
bindings: {
|
|
82
|
+
content: {
|
|
83
|
+
args: { key: 'field_with_label_only' },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
} );
|
|
87
|
+
|
|
88
|
+
expect( values.content ).toBe( 'Field With Label Only' );
|
|
89
|
+
} );
|
|
90
|
+
|
|
91
|
+
it( 'should fall back to the field key if the field label is not defined', () => {
|
|
92
|
+
const values = postMetaBindings.getValues( {
|
|
93
|
+
select,
|
|
94
|
+
context,
|
|
95
|
+
bindings: {
|
|
96
|
+
content: {
|
|
97
|
+
args: { key: 'field_without_label_or_default' },
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
} );
|
|
101
|
+
|
|
102
|
+
expect( values.content ).toBe(
|
|
103
|
+
'field_without_label_or_default'
|
|
104
|
+
);
|
|
105
|
+
} );
|
|
106
|
+
} );
|
|
107
|
+
|
|
108
|
+
describe( 'getFieldsList', () => {
|
|
109
|
+
it( 'should return the list of available meta fields, with correct fallbacks for labels, and exclude protected fields', () => {
|
|
110
|
+
const fields = postMetaBindings.getFieldsList( {
|
|
111
|
+
select,
|
|
112
|
+
context,
|
|
113
|
+
} );
|
|
114
|
+
|
|
115
|
+
expect( fields ).toEqual( [
|
|
116
|
+
{
|
|
117
|
+
label: 'field_without_label_or_default',
|
|
118
|
+
type: 'string',
|
|
119
|
+
args: { key: 'field_without_label_or_default' },
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
label: 'Field With Label Only',
|
|
123
|
+
type: 'string',
|
|
124
|
+
args: { key: 'field_with_label_only' },
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
label: 'Movie Field Label',
|
|
128
|
+
type: 'string',
|
|
129
|
+
args: { key: 'movie_field' },
|
|
130
|
+
},
|
|
131
|
+
] );
|
|
132
|
+
} );
|
|
133
|
+
} );
|
|
134
|
+
} );
|
|
135
|
+
|
|
136
|
+
describe( 'when postId is provided in context', () => {
|
|
137
|
+
beforeAll( () => {
|
|
138
|
+
context = { postType: 'movie', postId: 123 };
|
|
139
|
+
} );
|
|
140
|
+
|
|
141
|
+
describe( 'getValues', () => {
|
|
142
|
+
it( 'should return the meta value if it is defined', () => {
|
|
143
|
+
const values = postMetaBindings.getValues( {
|
|
144
|
+
select,
|
|
145
|
+
context,
|
|
146
|
+
bindings: {
|
|
147
|
+
content: {
|
|
148
|
+
args: { key: 'movie_field' },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
} );
|
|
152
|
+
|
|
153
|
+
expect( values.content ).toBe( 'Test Movie Value' );
|
|
154
|
+
} );
|
|
155
|
+
|
|
156
|
+
it( 'should fall back to the key when meta field is not accessible', () => {
|
|
157
|
+
const values = postMetaBindings.getValues( {
|
|
158
|
+
select,
|
|
159
|
+
context,
|
|
160
|
+
bindings: {
|
|
161
|
+
content: {
|
|
162
|
+
args: { key: 'inaccessible_field' },
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
} );
|
|
166
|
+
|
|
167
|
+
expect( values.content ).toBe( 'inaccessible_field' );
|
|
168
|
+
} );
|
|
169
|
+
|
|
170
|
+
it( 'should fall back to the key when meta field is protected', () => {
|
|
171
|
+
const values = postMetaBindings.getValues( {
|
|
172
|
+
select,
|
|
173
|
+
context,
|
|
174
|
+
bindings: {
|
|
175
|
+
content: {
|
|
176
|
+
args: { key: '_protected_field' },
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
} );
|
|
180
|
+
|
|
181
|
+
expect( values.content ).toBe( '_protected_field' );
|
|
182
|
+
} );
|
|
183
|
+
} );
|
|
184
|
+
|
|
185
|
+
describe( 'canUserEditValue', () => {
|
|
186
|
+
beforeAll( () => {
|
|
187
|
+
select = () => ( { ...selectReturn, canUser: () => true } );
|
|
188
|
+
} );
|
|
189
|
+
|
|
190
|
+
it( 'should return false when meta field is not accessible', () => {
|
|
191
|
+
const canUser = postMetaBindings.canUserEditValue( {
|
|
192
|
+
select,
|
|
193
|
+
context,
|
|
194
|
+
args: { key: 'inaccessible_field' },
|
|
195
|
+
} );
|
|
196
|
+
|
|
197
|
+
expect( canUser ).toBe( false );
|
|
198
|
+
} );
|
|
199
|
+
|
|
200
|
+
it( 'should return false when meta field is protected', () => {
|
|
201
|
+
const canUser = postMetaBindings.canUserEditValue( {
|
|
202
|
+
select,
|
|
203
|
+
context,
|
|
204
|
+
args: { key: '_protected_field' },
|
|
205
|
+
} );
|
|
206
|
+
|
|
207
|
+
expect( canUser ).toBe( false );
|
|
208
|
+
} );
|
|
209
|
+
} );
|
|
210
|
+
} );
|
|
211
|
+
} );
|
|
@@ -6,7 +6,7 @@ import clsx from 'clsx';
|
|
|
6
6
|
* WordPress dependencies
|
|
7
7
|
*/
|
|
8
8
|
import { __ } from '@wordpress/i18n';
|
|
9
|
-
import { useSelect } from '@wordpress/data';
|
|
9
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
10
10
|
import {
|
|
11
11
|
__experimentalHStack as HStack,
|
|
12
12
|
__experimentalVStack as VStack,
|
|
@@ -45,6 +45,13 @@ export function AddComment( {
|
|
|
45
45
|
};
|
|
46
46
|
}, [] );
|
|
47
47
|
const blockElement = useBlockElement( clientId );
|
|
48
|
+
const { toggleBlockSpotlight } = unlock( useDispatch( blockEditorStore ) );
|
|
49
|
+
|
|
50
|
+
const unselectThread = () => {
|
|
51
|
+
setShowCommentBoard( false );
|
|
52
|
+
blockElement?.focus();
|
|
53
|
+
toggleBlockSpotlight( clientId, false );
|
|
54
|
+
};
|
|
48
55
|
|
|
49
56
|
if ( ! showCommentBoard || ! clientId || undefined !== blockCommentId ) {
|
|
50
57
|
return null;
|
|
@@ -61,7 +68,7 @@ export function AddComment( {
|
|
|
61
68
|
spacing="3"
|
|
62
69
|
tabIndex={ 0 }
|
|
63
70
|
aria-label={ __( 'New note' ) }
|
|
64
|
-
role="
|
|
71
|
+
role="treeitem"
|
|
65
72
|
ref={ isFloating ? refs.setFloating : undefined }
|
|
66
73
|
style={
|
|
67
74
|
isFloating
|
|
@@ -73,6 +80,7 @@ export function AddComment( {
|
|
|
73
80
|
if ( event.currentTarget.contains( event.relatedTarget ) ) {
|
|
74
81
|
return;
|
|
75
82
|
}
|
|
83
|
+
toggleBlockSpotlight( clientId, false );
|
|
76
84
|
setShowCommentBoard( false );
|
|
77
85
|
} }
|
|
78
86
|
>
|
|
@@ -85,10 +93,7 @@ export function AddComment( {
|
|
|
85
93
|
focusCommentThread( id, commentSidebarRef.current );
|
|
86
94
|
setShowCommentBoard( false );
|
|
87
95
|
} }
|
|
88
|
-
onCancel={
|
|
89
|
-
setShowCommentBoard( false );
|
|
90
|
-
blockElement?.focus();
|
|
91
|
-
} }
|
|
96
|
+
onCancel={ unselectThread }
|
|
92
97
|
reflowComments={ reflowComments }
|
|
93
98
|
submitButtonText={ __( 'Add note' ) }
|
|
94
99
|
labelText={ __( 'New note' ) }
|
|
@@ -18,38 +18,45 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
|
18
18
|
*/
|
|
19
19
|
import { getAvatarBorderColor } from './utils';
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
* Render author information for a comment.
|
|
23
|
-
*
|
|
24
|
-
* @param {Object} props - Component properties.
|
|
25
|
-
* @param {string} props.avatar - URL of the author's avatar.
|
|
26
|
-
* @param {string} props.name - Name of the author.
|
|
27
|
-
* @param {string} props.date - Date of the comment.
|
|
28
|
-
* @param {string} props.userId - User ID of the author.
|
|
29
|
-
*
|
|
30
|
-
* @return {React.ReactNode} The JSX element representing the author's information.
|
|
31
|
-
*/
|
|
32
21
|
function CommentAuthorInfo( { avatar, name, date, userId } ) {
|
|
22
|
+
const hasAvatar = !! avatar;
|
|
33
23
|
const dateSettings = getDateSettings();
|
|
34
24
|
const {
|
|
35
25
|
currentUserAvatar,
|
|
36
26
|
currentUserName,
|
|
37
27
|
currentUserId,
|
|
38
28
|
dateFormat = dateSettings.formats.date,
|
|
39
|
-
} = useSelect(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
29
|
+
} = useSelect(
|
|
30
|
+
( select ) => {
|
|
31
|
+
const { canUser, getCurrentUser, getEntityRecord } =
|
|
32
|
+
select( coreStore );
|
|
33
|
+
const siteSettings = canUser( 'read', {
|
|
34
|
+
kind: 'root',
|
|
35
|
+
name: 'site',
|
|
36
|
+
} )
|
|
37
|
+
? getEntityRecord( 'root', 'site' )
|
|
38
|
+
: undefined;
|
|
39
|
+
|
|
40
|
+
if ( hasAvatar ) {
|
|
41
|
+
return {
|
|
42
|
+
dateFormat: siteSettings?.date_format,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { getSettings } = select( blockEditorStore );
|
|
47
|
+
const { __experimentalDiscussionSettings } = getSettings();
|
|
48
|
+
const defaultAvatar = __experimentalDiscussionSettings?.avatarURL;
|
|
49
|
+
const userData = getCurrentUser();
|
|
50
|
+
return {
|
|
51
|
+
currentUserAvatar:
|
|
52
|
+
userData?.avatar_urls?.[ 48 ] ?? defaultAvatar,
|
|
53
|
+
currentUserName: userData?.name,
|
|
54
|
+
currentUserId: userData?.id,
|
|
55
|
+
dateFormat: siteSettings?.date_format,
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
[ hasAvatar ]
|
|
59
|
+
);
|
|
53
60
|
|
|
54
61
|
const commentDate = getDate( date );
|
|
55
62
|
const commentDateTime = dateI18n( 'c', commentDate );
|
|
@@ -87,7 +94,7 @@ function CommentAuthorInfo( { avatar, name, date, userId } ) {
|
|
|
87
94
|
{ name ?? currentUserName }
|
|
88
95
|
</span>
|
|
89
96
|
{ date && (
|
|
90
|
-
<Tooltip
|
|
97
|
+
<Tooltip text={ tooltipText }>
|
|
91
98
|
<time
|
|
92
99
|
dateTime={ commentDateTime }
|
|
93
100
|
className="editor-collab-sidebar-panel__user-time"
|