diff --git a/packages/dataviews/src/components/dataform-combined-edit/style.scss b/packages/dataviews/src/components/dataform-combined-edit/style.scss index 0b59cbc9a4776..97e052ed89798 100644 --- a/packages/dataviews/src/components/dataform-combined-edit/style.scss +++ b/packages/dataviews/src/components/dataform-combined-edit/style.scss @@ -9,4 +9,8 @@ &__field { flex: 1 1 auto; } + + p.components-base-control__help:has(.components-checkbox-control__help) { + margin-top: $grid-unit-05; + } } diff --git a/packages/edit-site/src/components/post-edit/index.js b/packages/edit-site/src/components/post-edit/index.js index a2b3007757e42..fbff29ed67afa 100644 --- a/packages/edit-site/src/components/post-edit/index.js +++ b/packages/edit-site/src/components/post-edit/index.js @@ -23,6 +23,14 @@ import { unlock } from '../../lock-unlock'; const { PostCardPanel } = unlock( editorPrivateApis ); +const fieldsWithBulkEditSupport = [ + 'title', + 'status', + 'date', + 'author', + 'comment_status', +]; + function PostEditForm( { postType, postId } ) { const ids = useMemo( () => postId.split( ',' ), [ postId ] ); const { record } = useSelect( @@ -58,27 +66,36 @@ function PostEditForm( { postType, postId } ) { } ), [ _fields ] ); - const form = { - type: 'panel', - fields: [ - 'featured_media', - 'title', - 'author', - 'date', - 'slug', - 'parent', - 'comment_status', - ], - }; - - const fieldsWithBulkEditSupport = [ - 'title', - 'status', - 'date', - 'author', - 'comment_status', - ]; + const form = useMemo( + () => ( { + type: 'panel', + fields: [ + 'featured_media', + 'title', + 'status_and_visibility', + 'author', + 'date', + 'slug', + 'parent', + 'comment_status', + ].filter( + ( field ) => + ids.length === 1 || + fieldsWithBulkEditSupport.includes( field ) + ), + combinedFields: [ + { + id: 'status_and_visibility', + label: __( 'Status & Visibility' ), + children: [ 'status', 'password' ], + direction: 'vertical', + render: ( { item } ) => item.status, + }, + ], + } ), + [ ids ] + ); const onChange = ( edits ) => { for ( const id of ids ) { if ( @@ -117,16 +134,7 @@ function PostEditForm( { postType, postId } ) { - fieldsWithBulkEditSupport.includes( field ) - ), - } - } + form={ form } onChange={ onChange } /> diff --git a/packages/edit-site/src/components/post-edit/style.scss b/packages/edit-site/src/components/post-edit/style.scss index 4eaa41b2e8ed7..5688d83df00c5 100644 --- a/packages/edit-site/src/components/post-edit/style.scss +++ b/packages/edit-site/src/components/post-edit/style.scss @@ -7,3 +7,10 @@ justify-content: center; } } + +.dataforms-layouts-panel__field-dropdown { + .fields-controls__password { + border-top: $border-width solid $gray-200; + padding-top: $grid-unit-20; + } +} diff --git a/packages/edit-site/src/components/post-fields/index.js b/packages/edit-site/src/components/post-fields/index.js index 7a52b05321794..e659a4f96f23f 100644 --- a/packages/edit-site/src/components/post-fields/index.js +++ b/packages/edit-site/src/components/post-fields/index.js @@ -8,7 +8,12 @@ import clsx from 'clsx'; */ import { __, sprintf } from '@wordpress/i18n'; import { decodeEntities } from '@wordpress/html-entities'; -import { featuredImageField, slugField, parentField } from '@wordpress/fields'; +import { + featuredImageField, + slugField, + parentField, + passwordField, +} from '@wordpress/fields'; import { createInterpolateElement, useMemo, @@ -348,6 +353,7 @@ function usePostFields( viewType ) { }, ], }, + passwordField, ], [ authors, viewType, frontPageId, postsPageId ] ); diff --git a/packages/fields/README.md b/packages/fields/README.md index 5fd1031b50fe2..214f3d6ee3a50 100644 --- a/packages/fields/README.md +++ b/packages/fields/README.md @@ -50,6 +50,10 @@ Undocumented declaration. This field is used to display the post parent. +### passwordField + +This field is used to display the post password. + ### permanentlyDeletePost Undocumented declaration. diff --git a/packages/fields/src/fields/index.ts b/packages/fields/src/fields/index.ts index 9f1abef0417f4..29cbdeb2a4ba6 100644 --- a/packages/fields/src/fields/index.ts +++ b/packages/fields/src/fields/index.ts @@ -3,3 +3,4 @@ export { default as titleField } from './title'; export { default as orderField } from './order'; export { default as featuredImageField } from './featured-image'; export { default as parentField } from './parent'; +export { default as passwordField } from './password'; diff --git a/packages/fields/src/fields/password/edit.tsx b/packages/fields/src/fields/password/edit.tsx new file mode 100644 index 0000000000000..75226c1f93f15 --- /dev/null +++ b/packages/fields/src/fields/password/edit.tsx @@ -0,0 +1,68 @@ +/** + * WordPress dependencies + */ +import { + CheckboxControl, + __experimentalVStack as VStack, + TextControl, +} from '@wordpress/components'; +import type { DataFormControlProps } from '@wordpress/dataviews'; +import { useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import type { BasePost } from '../../types'; + +function PasswordEdit( { + data, + onChange, + field, +}: DataFormControlProps< BasePost > ) { + const [ showPassword, setShowPassword ] = useState( + !! field.getValue( { item: data } ) + ); + + const handleTogglePassword = ( value: boolean ) => { + setShowPassword( value ); + if ( ! value ) { + onChange( { password: '' } ); + } + }; + + return ( + + + { showPassword && ( +
+ + onChange( { + password: value, + } ) + } + value={ field.getValue( { item: data } ) || '' } + placeholder={ __( 'Use a secure password' ) } + type="text" + __next40pxDefaultSize + __nextHasNoMarginBottom + maxLength={ 255 } + /> +
+ ) } +
+ ); +} +export default PasswordEdit; diff --git a/packages/fields/src/fields/password/index.tsx b/packages/fields/src/fields/password/index.tsx new file mode 100644 index 0000000000000..aa7bc57e3f7ca --- /dev/null +++ b/packages/fields/src/fields/password/index.tsx @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import type { Field } from '@wordpress/dataviews'; + +/** + * Internal dependencies + */ +import type { BasePost } from '../../types'; +import PasswordEdit from './edit'; + +const passwordField: Field< BasePost > = { + id: 'password', + type: 'text', + getValue: ( { item } ) => item.password, + Edit: PasswordEdit, + enableSorting: false, + enableHiding: false, + isVisible: ( item ) => item.status !== 'private', +}; + +/** + * This field is used to display the post password. + */ +export default passwordField;