From 6673c19442bb0ddfa9df1ec4e9570a13e99ff132 Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 11:34:10 +1200 Subject: [PATCH 01/73] Initial commit: - media sidebar item and main page - fetching attachment records --- .../src/components/page-main/index.js | 5 ++- .../src/components/page-media/index.js | 41 +++++++++++++++++++ .../sidebar-navigation-screen-main/index.js | 11 ++++- .../sidebar-navigation-screen-media/index.js | 25 +++++++++++ .../edit-site/src/components/sidebar/index.js | 4 ++ .../use-sync-path-with-url.js | 2 +- .../edit-site/src/utils/get-is-list-page.js | 1 + 7 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 packages/edit-site/src/components/page-media/index.js create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-media/index.js diff --git a/packages/edit-site/src/components/page-main/index.js b/packages/edit-site/src/components/page-main/index.js index af017a8db9700..aeb52569f5efe 100644 --- a/packages/edit-site/src/components/page-main/index.js +++ b/packages/edit-site/src/components/page-main/index.js @@ -7,6 +7,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; * Internal dependencies */ import PagePatterns from '../page-patterns'; +import PageMedia from '../page-media'; import PageTemplateParts from '../page-template-parts'; import PageTemplates from '../page-templates'; import { unlock } from '../../lock-unlock'; @@ -17,13 +18,15 @@ export default function PageMain() { const { params: { path }, } = useLocation(); - +console.log( 'path', path ); if ( path === '/wp_template/all' ) { return ; } else if ( path === '/wp_template_part/all' ) { return ; } else if ( path === '/patterns' ) { return ; + } else if ( path === '/media' ) { + return ; } return null; diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js new file mode 100644 index 0000000000000..a786c3cbcbbdc --- /dev/null +++ b/packages/edit-site/src/components/page-media/index.js @@ -0,0 +1,41 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; +/** + * Internal dependencies + */ +import Page from '../page'; + +const EMPTY_ARRAY = []; +export default function PageMedia() { + const { attachments } = useSelect( + ( select ) => { + const _attachments = select( coreStore ).getEntityRecords( + 'postType', + 'attachment', + { per_page: 50 } + ); + return { + attachments: _attachments || EMPTY_ARRAY, + }; + }, [] ); + + return ( + + { __( 'Media library list component stuff goes here' ) } + { attachments.map( ( attachment ) => ( +
+ { +
{ attachment.title.raw }
+
+ ) ) } +
+ ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js index 152139870fa59..063bebb3b75f9 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js @@ -7,9 +7,8 @@ import { __experimentalUseNavigator as useNavigator, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { layout, symbol, navigation, styles, page } from '@wordpress/icons'; +import { layout, media, navigation, page, styles, symbol } from '@wordpress/icons'; import { useDispatch } from '@wordpress/data'; - import { useEffect } from '@wordpress/element'; /** @@ -45,6 +44,14 @@ export default function SidebarNavigationScreenMain() { content={ <> + + { __( 'Media' ) } + + ); +} diff --git a/packages/edit-site/src/components/sidebar/index.js b/packages/edit-site/src/components/sidebar/index.js index 9e035759ea9ad..55aee6f65534e 100644 --- a/packages/edit-site/src/components/sidebar/index.js +++ b/packages/edit-site/src/components/sidebar/index.js @@ -27,6 +27,7 @@ import SaveHub from '../save-hub'; import { unlock } from '../../lock-unlock'; import SidebarNavigationScreenPages from '../sidebar-navigation-screen-pages'; import SidebarNavigationScreenPage from '../sidebar-navigation-screen-page'; +import SidebarNavigationScreenMedia from '../sidebar-navigation-screen-media'; const { useLocation } = unlock( routerPrivateApis ); @@ -68,6 +69,9 @@ function SidebarScreens() { + + + ); } diff --git a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js b/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js index 86928c1920a94..4eb3c3734a892 100644 --- a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js +++ b/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js @@ -87,7 +87,7 @@ export default function useSyncPathWithURL() { postId: navigatorParams?.postId, path: undefined, } ); - } else if ( navigatorLocation.path === '/patterns' ) { + } else if ( navigatorLocation.path === '/patterns' || navigatorLocation.path === '/media' ) { updateUrlParams( { postType: undefined, postId: undefined, diff --git a/packages/edit-site/src/utils/get-is-list-page.js b/packages/edit-site/src/utils/get-is-list-page.js index 600e686618bf9..47a4d9003512a 100644 --- a/packages/edit-site/src/utils/get-is-list-page.js +++ b/packages/edit-site/src/utils/get-is-list-page.js @@ -16,6 +16,7 @@ export default function getIsListPage( return ( path === '/wp_template/all' || path === '/wp_template_part/all' || + path === '/media' || ( path === '/patterns' && // Don't treat "/patterns" without categoryType and categoryId as a // list page in mobile because the sidebar covers the whole page. From 8af831f5e5a9305e8964bcd04c9603f9042663b6 Mon Sep 17 00:00:00 2001 From: Ramon Date: Fri, 18 Aug 2023 11:47:41 +1200 Subject: [PATCH 02/73] console.log( 'path', path ); --- packages/edit-site/src/components/page-main/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/page-main/index.js b/packages/edit-site/src/components/page-main/index.js index aeb52569f5efe..7029c60b59715 100644 --- a/packages/edit-site/src/components/page-main/index.js +++ b/packages/edit-site/src/components/page-main/index.js @@ -18,7 +18,7 @@ export default function PageMain() { const { params: { path }, } = useLocation(); -console.log( 'path', path ); + if ( path === '/wp_template/all' ) { return ; } else if ( path === '/wp_template_part/all' ) { From 25f782ed5dedcea3cbd5f692c39609fb5829e15e Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 18 Aug 2023 11:49:11 +1200 Subject: [PATCH 03/73] Add attachment_tags taxonomy --- lib/experimental/media-library.php | 28 ++++++++++++++++++++++++++++ lib/load.php | 1 + 2 files changed, 29 insertions(+) create mode 100644 lib/experimental/media-library.php diff --git a/lib/experimental/media-library.php b/lib/experimental/media-library.php new file mode 100644 index 0000000000000..d0f987b1e5c62 --- /dev/null +++ b/lib/experimental/media-library.php @@ -0,0 +1,28 @@ + false, + 'query_var' => 'tag', + 'rewrite' => false, // TODO: what is this? + 'public' => true, + 'show_ui' => true, + 'show_admin_column' => true, + '_builtin' => true, + 'capabilities' => array( // TODO: is this right? + 'manage_terms' => 'upload_files', + 'edit_terms' => 'upload_files', + 'delete_terms' => 'upload_files', + 'assign_terms' => 'upload_files', + ), + 'show_in_rest' => true, + 'rest_base' => 'attachment_tags', + 'rest_controller_class' => 'WP_REST_Terms_Controller', + ) + ); +} + +add_action( 'init', 'gutenberg_register_attachment_tag_taxonomy' ); diff --git a/lib/load.php b/lib/load.php index cfd5c4f38d0c5..5ed9b63b4c270 100644 --- a/lib/load.php +++ b/lib/load.php @@ -149,6 +149,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/experimental/interactivity-api/directives/wp-class.php'; require __DIR__ . '/experimental/interactivity-api/directives/wp-style.php'; require __DIR__ . '/experimental/interactivity-api/directives/wp-text.php'; +require __DIR__ . '/experimental/media-library.php'; // Fonts API / Font Face. remove_action( 'plugins_loaded', '_wp_theme_json_webfonts_handler' ); // Turns off WordPress 6.0's stopgap handler. From cc069c45f3f76f23241deabea3d6637728a98e90 Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 15:02:23 +1200 Subject: [PATCH 04/73] Media sidebar items --- .../sidebar-navigation-screen-media/index.js | 51 ++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js index 0645536f98aa1..7ccc717a22c79 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js @@ -1,25 +1,64 @@ -/** - * WordPress dependencies - */ import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; +import { + __experimentalItemGroup as ItemGroup, +} from '@wordpress/components'; +import { media, video, image, audio, pages } from '@wordpress/icons'; /** * Internal dependencies */ import SidebarNavigationItem from '../sidebar-navigation-item'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; +import { useLink } from '../routes/link'; + +const EMPTY_ARRAY = []; + +function MediaItem( { icon, type, isActive, children } ) { + const linkInfo = useLink( { + path: '/media', + mediaType: type, + } ); + return ( + + { children } + + ); +} export default function SidebarNavigationScreenMedia() { return ( + + { __( 'All media' ) } + + + { __( 'Images' ) } + + + { __( 'Videos' ) } + + + { __( 'Audio' ) } + + + { __( 'Documents' ) } + + + } /> ); } From a5825aeacf6b152f7e553cdc44e004ac19bb3ad1 Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 15:23:21 +1200 Subject: [PATCH 05/73] Blah --- .../src/components/page-media/index.js | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index a786c3cbcbbdc..c0388b4271a23 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -4,19 +4,46 @@ import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; +import { getQueryArgs } from '@wordpress/url'; +import { + Button, + SearchControl, + __experimentalVStack as VStack, + Flex, + FlexItem, + FlexBlock, + MenuGroup, MenuItem, + __experimentalInputControl as InputControl, + __experimentalToggleGroupControl as ToggleGroupControl, + __experimentalToggleGroupControlOption as ToggleGroupControlOption, + __experimentalHeading as Heading, + __experimentalText as Text, + __experimentalHStack as HStack, +} from '@wordpress/components'; + /** * Internal dependencies */ import Page from '../page'; +// @todo abstract for common usage. +import Pagination from '../page-patterns/pagination'; const EMPTY_ARRAY = []; + +// Getting headings, etc based on `mediaType` query type. +function getMediaDetails() {} + export default function PageMedia() { + const { mediaType } = getQueryArgs( window.location.href ); const { attachments } = useSelect( ( select ) => { const _attachments = select( coreStore ).getEntityRecords( 'postType', 'attachment', - { per_page: 50 } + { + per_page: 50, + mime_type: mediaType, + } ); return { attachments: _attachments || EMPTY_ARRAY, @@ -29,7 +56,25 @@ export default function PageMedia() { title={ __( 'Media' ) } hideTitleFromUI > - { __( 'Media library list component stuff goes here' ) } + + + { __( 'Images' ) } + + + + + + + + + + {/* or */} + + + + + + { attachments.map( ( attachment ) => (
{ From 8fadaad327fefda4c192e2bca75314215c7539e7 Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 15:24:58 +1200 Subject: [PATCH 06/73] blah --- packages/edit-site/src/components/page-media/index.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index c0388b4271a23..024c304d6546f 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -9,6 +9,7 @@ import { Button, SearchControl, __experimentalVStack as VStack, + DropdownMenu, Flex, FlexItem, FlexBlock, @@ -74,13 +75,6 @@ export default function PageMedia() { - - { attachments.map( ( attachment ) => ( -
- { -
{ attachment.title.raw }
-
- ) ) } ); } From 0a6164993b0bf35b7a82a51ac4abfc773c771cbd Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 15:34:28 +1200 Subject: [PATCH 07/73] blah --- packages/edit-site/src/components/page-media/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 024c304d6546f..e8581e58e38d8 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -50,7 +50,7 @@ export default function PageMedia() { attachments: _attachments || EMPTY_ARRAY, }; }, [] ); - +console.log( '_attachments', _attachments ); return ( Date: Fri, 18 Aug 2023 17:04:24 +1200 Subject: [PATCH 08/73] Use @tanstack/react-table for templates and template-parts --- package-lock.json | 46 +++++++ packages/edit-site/package.json | 1 + .../components/page-template-parts/index.js | 114 ++++++++++------- .../src/components/page-templates/index.js | 117 +++++++++++------- .../edit-site/src/components/table/index.js | 59 ++++++++- 5 files changed, 245 insertions(+), 92 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ceb0a0d5248c..4f1dfbf81b97e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13612,6 +13612,37 @@ "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.1.0.tgz", "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==" }, + "node_modules/@tanstack/react-table": { + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.9.3.tgz", + "integrity": "sha512-Ng9rdm3JPoSCi6cVZvANsYnF+UoGVRxflMb270tVj0+LjeT/ZtZ9ckxF6oLPLcKesza6VKBqtdF9mQ+vaz24Aw==", + "dependencies": { + "@tanstack/table-core": "8.9.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.9.3.tgz", + "integrity": "sha512-NpHZBoHTfqyJk0m/s/+CSuAiwtebhYK90mDuf5eylTvgViNOujiaOaxNDxJkQQAsVvHWZftUGAx1EfO1rkKtLg==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@testing-library/dom": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", @@ -55043,6 +55074,7 @@ "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", + "@tanstack/react-table": "^8.9.3", "@wordpress/a11y": "file:../a11y", "@wordpress/api-fetch": "file:../api-fetch", "@wordpress/block-editor": "file:../block-editor", @@ -65809,6 +65841,19 @@ "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.1.0.tgz", "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==" }, + "@tanstack/react-table": { + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.9.3.tgz", + "integrity": "sha512-Ng9rdm3JPoSCi6cVZvANsYnF+UoGVRxflMb270tVj0+LjeT/ZtZ9ckxF6oLPLcKesza6VKBqtdF9mQ+vaz24Aw==", + "requires": { + "@tanstack/table-core": "8.9.3" + } + }, + "@tanstack/table-core": { + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.9.3.tgz", + "integrity": "sha512-NpHZBoHTfqyJk0m/s/+CSuAiwtebhYK90mDuf5eylTvgViNOujiaOaxNDxJkQQAsVvHWZftUGAx1EfO1rkKtLg==" + }, "@testing-library/dom": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", @@ -67618,6 +67663,7 @@ "version": "file:packages/edit-site", "requires": { "@babel/runtime": "^7.16.0", + "@tanstack/react-table": "^8.9.3", "@wordpress/a11y": "file:../a11y", "@wordpress/api-fetch": "file:../api-fetch", "@wordpress/block-editor": "file:../block-editor", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index e0f9ac3dfcb5c..17a060fcd8d1b 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -27,6 +27,7 @@ "react-native": "src/index", "dependencies": { "@babel/runtime": "^7.16.0", + "@tanstack/react-table": "^8.9.3", "@wordpress/a11y": "file:../a11y", "@wordpress/api-fetch": "file:../api-fetch", "@wordpress/block-editor": "file:../block-editor", diff --git a/packages/edit-site/src/components/page-template-parts/index.js b/packages/edit-site/src/components/page-template-parts/index.js index e03d726a57525..68105f688510b 100644 --- a/packages/edit-site/src/components/page-template-parts/index.js +++ b/packages/edit-site/src/components/page-template-parts/index.js @@ -1,3 +1,7 @@ +/** + * External dependencies + */ +import { createColumnHelper } from '@tanstack/react-table'; /** * WordPress dependencies */ @@ -20,7 +24,74 @@ import AddedBy from '../list/added-by'; import TemplateActions from '../template-actions'; import AddNewTemplatePart from './add-new-template-part'; +/** + * @typedef {Object} RichContent + * @property {string} rendered The rendered content. + * @property {string} raw The raw content. + * + * @typedef {Object} TemplatePart + * @property {string} id The ID of the template. + * @property {'wp_template_part'} type The type of the template. + * @property {RichContent} title The name of the template. + * @property {string} description The description of the template. + * @property {string} slug The slug of the template. + */ + +/** @type {import('@tanstack/react-table').ColumnHelper} */ +const columnHelper = createColumnHelper(); + +const columns = [ + columnHelper.accessor( + ( row ) => decodeEntities( row.title?.rendered || row.slug ), + { + id: 'title', + header: __( 'Template Part' ), + cell: ( cell ) => { + const templatePart = cell.row.original; + return ( + + + + { cell.getValue() } + + + + ); + }, + maxWidth: 400, + } + ), + // TODO: Ideally this should be a accessor column, but the data is only fetched asynchronously. + columnHelper.display( { + id: 'added-by', + header: __( 'Added by' ), + cell: ( { row: { original: templatePart } } ) => ( + + ), + } ), + columnHelper.display( { + id: 'actions', + header: { __( 'Actions' ) }, + cell: ( { row: { original: templatePart } } ) => ( + + ), + } ), +]; + export default function PageTemplateParts() { + /** @type {{records: TemplatePart[] | null}} */ const { records: templateParts } = useEntityRecords( 'postType', 'wp_template_part', @@ -29,49 +100,6 @@ export default function PageTemplateParts() { } ); - const columns = [ - { - header: __( 'Template Part' ), - cell: ( templatePart ) => ( - - - - { decodeEntities( - templatePart.title?.rendered || - templatePart.slug - ) } - - - - ), - maxWidth: 400, - }, - { - header: __( 'Added by' ), - cell: ( templatePart ) => ( - - ), - }, - { - header: { __( 'Actions' ) }, - cell: ( templatePart ) => ( - - ), - }, - ]; - return ( } */ +const columnHelper = createColumnHelper(); + +const columns = [ + columnHelper.accessor( + ( row ) => decodeEntities( row.title?.rendered || row.slug ), + { + id: 'title', + header: __( 'Template' ), + cell: ( cell ) => { + const template = cell.row.original; + return ( + + + + { cell.getValue() } + + + { template.description && ( + + { decodeEntities( template.description ) } + + ) } + + ); + }, + maxWidth: 400, + } + ), + // TODO: Ideally this should be a accessor column, but the data is only fetched asynchronously. + columnHelper.display( { + id: 'added-by', + header: __( 'Added by' ), + cell: ( { row: { original: template } } ) => ( + + ), + } ), + columnHelper.display( { + id: 'actions', + header: { __( 'Actions' ) }, + cell: ( { row: { original: template } } ) => ( + + ), + } ), +]; + export default function PageTemplates() { + /** @type {{records: Template[] | null}} */ const { records: templates } = useEntityRecords( 'postType', 'wp_template', @@ -30,50 +103,6 @@ export default function PageTemplates() { } ); - const columns = [ - { - header: __( 'Template' ), - cell: ( template ) => ( - - - - { decodeEntities( - template.title?.rendered || template.slug - ) } - - - { template.description && ( - - { decodeEntities( template.description ) } - - ) } - - ), - maxWidth: 400, - }, - { - header: __( 'Added by' ), - cell: ( template ) => ( - - ), - }, - { - header: { __( 'Actions' ) }, - cell: ( template ) => ( - - ), - }, - ]; - return ( - + { table.getHeaderGroups().map( ( headerGroup ) => ( + + { headerGroup.headers.map( ( header ) => ( + + ) ) } + + ) ) } + { /* { columns.map( ( column ) => ( ) ) } - + */ } - { data.map( ( row, rowIndex ) => ( + { table.getRowModel().rows.map( ( row ) => ( + + { row.getVisibleCells().map( ( cell ) => ( + + ) ) } + + ) ) } + { /* { data.map( ( row, rowIndex ) => ( { columns.map( ( column, columnIndex ) => ( - ) ) } + ) ) } */ }
+ { header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + ) } +
{ column.header }
+ { flexRender( + cell.column.columnDef.cell, + cell.getContext() + ) } +
) ) }
From d788013fab5b012179c9141094acce878413f1e3 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 18 Aug 2023 17:12:31 +1200 Subject: [PATCH 09/73] Add FilterControl --- .../components/page-media/filter-control.js | 104 ++++++++++++++++++ .../src/components/page-media/index.js | 90 +++++++++++---- 2 files changed, 174 insertions(+), 20 deletions(-) create mode 100644 packages/edit-site/src/components/page-media/filter-control.js diff --git a/packages/edit-site/src/components/page-media/filter-control.js b/packages/edit-site/src/components/page-media/filter-control.js new file mode 100644 index 0000000000000..af97b39e1b518 --- /dev/null +++ b/packages/edit-site/src/components/page-media/filter-control.js @@ -0,0 +1,104 @@ +/** + * WordPress dependencies + */ +import { + Dropdown, + Button, + __experimentalInputControl as InputControl, + CheckboxControl, + __experimentalVStack as VStack, +} from '@wordpress/components'; +import { sprintf, __ } from '@wordpress/i18n'; +import { chevronDown } from '@wordpress/icons'; +import { useState } from '@wordpress/element'; + +const noop = () => {}; + +export default function FilterControl( { + label, + value = [], + options = [], + onChange = noop, +} ) { + const [ searchFilter, setSearchFilter ] = useState( '' ); + return ( + ( + + + ) } + /> + ); +} + +function getToggleText( label, value ) { + if ( value.length > 1 ) { + return sprintf( + /* translators: %1$s: label, %2$d: number of selected items */ + __( '%1$s: %2$d selected' ), + label, + value.length + ); + } else if ( value.length === 1 ) { + return sprintf( + /* translators: %1$s: label, %2$s: selected item */ + __( '%1$s: %2$s' ), + label, + value[ 0 ] + ); + } + return label; +} diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index e8581e58e38d8..29a33ef8f096a 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -13,14 +13,17 @@ import { Flex, FlexItem, FlexBlock, - MenuGroup, MenuItem, + MenuGroup, + MenuItem, __experimentalInputControl as InputControl, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, __experimentalHeading as Heading, __experimentalText as Text, __experimentalHStack as HStack, + __experimentalSpacer as Spacer, } from '@wordpress/components'; +import { useState } from '@wordpress/element'; /** * Internal dependencies @@ -28,6 +31,7 @@ import { import Page from '../page'; // @todo abstract for common usage. import Pagination from '../page-patterns/pagination'; +import FilterControl from './filter-control'; const EMPTY_ARRAY = []; @@ -36,21 +40,22 @@ function getMediaDetails() {} export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); - const { attachments } = useSelect( - ( select ) => { - const _attachments = select( coreStore ).getEntityRecords( - 'postType', - 'attachment', - { - per_page: 50, - mime_type: mediaType, - } - ); - return { - attachments: _attachments || EMPTY_ARRAY, - }; - }, [] ); -console.log( '_attachments', _attachments ); + const { attachments } = useSelect( ( select ) => { + const _attachments = select( coreStore ).getEntityRecords( + 'postType', + 'attachment', + { + per_page: 50, + mime_type: mediaType, + } + ); + return { + attachments: _attachments || EMPTY_ARRAY, + }; + }, [] ); + const [ tagsFilter, setTagsFilter ] = useState( [] ); + const [ authorFilter, setAuthorFilter ] = useState( [] ); + console.log( 'attachments', attachments ); return ( Upload + + + - - - + + + - {/* or */} + { /* or */ } From 62d037147dc83d0f7e34b1aa95503fba927e94b5 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 18 Aug 2023 17:33:19 +1200 Subject: [PATCH 10/73] Make filter toggle 40px high --- packages/edit-site/src/components/page-media/filter-control.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/edit-site/src/components/page-media/filter-control.js b/packages/edit-site/src/components/page-media/filter-control.js index af97b39e1b518..f452ad1c73f38 100644 --- a/packages/edit-site/src/components/page-media/filter-control.js +++ b/packages/edit-site/src/components/page-media/filter-control.js @@ -32,6 +32,7 @@ export default function FilterControl( { iconPosition="right" isPressed={ isOpen } onClick={ onToggle } + __next40pxDefaultSize /> ) } renderContent={ () => ( From 56e71e3bdd6026e2c4fd81bd975b6dc4f1b11ce8 Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 17:35:13 +1200 Subject: [PATCH 11/73] Fetching media entities based on type --- .../src/components/page-media/index.js | 77 +++++++++++++------ .../sidebar-navigation-screen-media/index.js | 18 ++--- 2 files changed, 59 insertions(+), 36 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index e8581e58e38d8..374dd5d1535b2 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -7,18 +7,11 @@ import { store as coreStore } from '@wordpress/core-data'; import { getQueryArgs } from '@wordpress/url'; import { Button, - SearchControl, __experimentalVStack as VStack, DropdownMenu, - Flex, - FlexItem, - FlexBlock, - MenuGroup, MenuItem, - __experimentalInputControl as InputControl, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, __experimentalHeading as Heading, - __experimentalText as Text, __experimentalHStack as HStack, } from '@wordpress/components'; @@ -31,26 +24,52 @@ import Pagination from '../page-patterns/pagination'; const EMPTY_ARRAY = []; -// Getting headings, etc based on `mediaType` query type. -function getMediaDetails() {} +// Getting headings, etc. based on `mediaType` query type. +function getMediaDetails( mediaType ) { + if ( 'document' === mediaType ) { + return { + heading: __( 'Documents' ), + }; + } + + if ( 'audio' === mediaType ) { + return { + heading: __( 'Audio' ), + }; + } + + if ( 'video' === mediaType ) { + return { + heading: __( 'Videos' ), + }; + } + + return { + heading: __( 'Images' ), + }; +} export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); const { attachments } = useSelect( ( select ) => { - const _attachments = select( coreStore ).getEntityRecords( - 'postType', - 'attachment', - { - per_page: 50, - mime_type: mediaType, - } - ); + const _attachments = select( coreStore ).getMediaItems( { + per_page: 50, + orderby: 'date', + order: 'desc', + // @todo `application` and `text` are valid media types, + // but we should maybe combine them into `documents`. + media_type: mediaType, + } ); return { attachments: _attachments || EMPTY_ARRAY, }; - }, [] ); -console.log( '_attachments', _attachments ); + }, + [ mediaType ] + ); + + const { heading } = getMediaDetails( mediaType ); + return ( - { __( 'Images' ) } + { heading } - - - + + + - {/* or */} + { /* or */ } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js index 7ccc717a22c79..a1c78594ea822 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js @@ -1,10 +1,8 @@ - +/** + * WordPress dependencies + */ import { __ } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; -import { - __experimentalItemGroup as ItemGroup, -} from '@wordpress/components'; +import { __experimentalItemGroup as ItemGroup } from '@wordpress/components'; import { media, video, image, audio, pages } from '@wordpress/icons'; /** @@ -14,8 +12,6 @@ import SidebarNavigationItem from '../sidebar-navigation-item'; import SidebarNavigationScreen from '../sidebar-navigation-screen'; import { useLink } from '../routes/link'; -const EMPTY_ARRAY = []; - function MediaItem( { icon, type, isActive, children } ) { const linkInfo = useLink( { path: '/media', @@ -36,9 +32,7 @@ export default function SidebarNavigationScreenMedia() { return ( @@ -54,7 +48,7 @@ export default function SidebarNavigationScreenMedia() { { __( 'Audio' ) } - + { __( 'Documents' ) } From 74df510f06b620a2ab762c6dec2a995e3f9ee9f9 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 18 Aug 2023 17:41:52 +1200 Subject: [PATCH 12/73] Neaten up top bar --- .../src/components/page-media/index.js | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 47cea1525364c..c184fcfb2d6cd 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -17,13 +17,15 @@ import { MenuItem, __experimentalInputControl as InputControl, __experimentalToggleGroupControl as ToggleGroupControl, - __experimentalToggleGroupControlOption as ToggleGroupControlOption, + __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon, __experimentalHeading as Heading, __experimentalText as Text, __experimentalHStack as HStack, __experimentalSpacer as Spacer, + SelectControl, } from '@wordpress/components'; import { useState } from '@wordpress/element'; +import { grid, list } from '@wordpress/icons'; /** * Internal dependencies @@ -129,19 +131,34 @@ export default function PageMedia() { ] } onChange={ setAuthorFilter } /> - + + - - From 869d56627d90e0b039d96c652f072a3ca0b8ac1c Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 17:46:26 +1200 Subject: [PATCH 13/73] Search control --- .../edit-site/src/components/page-media/index.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 47cea1525364c..bf43383c40509 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -10,18 +10,10 @@ import { SearchControl, __experimentalVStack as VStack, DropdownMenu, - Flex, - FlexItem, - FlexBlock, - MenuGroup, - MenuItem, - __experimentalInputControl as InputControl, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, __experimentalHeading as Heading, - __experimentalText as Text, __experimentalHStack as HStack, - __experimentalSpacer as Spacer, } from '@wordpress/components'; import { useState } from '@wordpress/element'; @@ -94,7 +86,8 @@ export default function PageMedia() { - {} } placeholder={ __( 'Search' ) } size="__unstable-large" /> @@ -146,6 +139,11 @@ export default function PageMedia() { { /* or */ } + { attachments.map( ( attachment ) => ( +

+ { attachment.title.raw } - { attachment.source_url } +

+ ) ) }
From 31872bb642bd8f0e58e472ecc2265f80c4c07e9f Mon Sep 17 00:00:00 2001 From: ramon Date: Fri, 18 Aug 2023 17:52:25 +1200 Subject: [PATCH 14/73] Highlight menu item --- .../src/components/page-media/index.js | 3 +- .../sidebar-navigation-screen-media/index.js | 32 ++++++++++++++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index e215fe7e149fe..aed968df9c4bc 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -58,13 +58,14 @@ export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); const { attachments } = useSelect( ( select ) => { + const _mediaType = 'all' === mediaType ? undefined : mediaType; const _attachments = select( coreStore ).getMediaItems( { per_page: 50, orderby: 'date', order: 'desc', // @todo `application` and `text` are valid media types, // but we should maybe combine them into `documents`. - media_type: mediaType, + media_type: _mediaType, } ); return { attachments: _attachments || EMPTY_ARRAY, diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js index a1c78594ea822..80e0a70a3fa25 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js @@ -4,6 +4,7 @@ import { __ } from '@wordpress/i18n'; import { __experimentalItemGroup as ItemGroup } from '@wordpress/components'; import { media, video, image, audio, pages } from '@wordpress/icons'; +import { getQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -29,6 +30,7 @@ function MediaItem( { icon, type, isActive, children } ) { } export default function SidebarNavigationScreenMedia() { + const { mediaType } = getQueryArgs( window.location.href ); return ( - + { __( 'All media' ) } - + { __( 'Images' ) } - + { __( 'Videos' ) } - + { __( 'Audio' ) } - + { __( 'Documents' ) } From 34374dd52be12fb821211c2d36b62c4e0e19d781 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 18 Aug 2023 17:42:47 +1200 Subject: [PATCH 15/73] Use Table in media page --- .../src/components/page-media/index.js | 269 +++++++++++++----- 1 file changed, 196 insertions(+), 73 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index aed968df9c4bc..96105547e604b 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -1,13 +1,18 @@ +/** + * External dependencies + */ +import { createColumnHelper } from '@tanstack/react-table'; /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; +import { store as coreStore, useEntityRecord } from '@wordpress/core-data'; import { getQueryArgs } from '@wordpress/url'; import { Button, SearchControl, + CheckboxControl, __experimentalVStack as VStack, __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon, @@ -23,10 +28,111 @@ import { grid, list } from '@wordpress/icons'; * Internal dependencies */ import Page from '../page'; +import Table from '../table'; // @todo abstract for common usage. import Pagination from '../page-patterns/pagination'; import FilterControl from './filter-control'; +/** + * @typedef {Object} Attachment + * @property {{raw: string, rendered: string}} title The name of the attachment. + */ + +/** @type {import('@tanstack/react-table').ColumnHelper} */ +const columnHelper = createColumnHelper(); + +const dateFormatter = new Intl.DateTimeFormat( + // TODO: Other locales? + 'en-US', + { + year: 'numeric', + month: 'long', + day: 'numeric', + } +); + +const columns = [ + columnHelper.display( { + id: 'select', + header: ( { table } ) => ( + + table.toggleAllPageRowsSelected( !! value ) + } + aria-label={ __( 'Select all' ) } + /> + ), + cell: ( { row } ) => ( + row.toggleSelected( !! value ) } + aria-label={ __( 'Select row' ) } + /> + ), + enableSorting: false, + enableHiding: false, + } ), + columnHelper.accessor( ( row ) => row.title.rendered, { + id: 'title', + header: () => __( 'Title' ), + cell: ( info ) => ( + + { +

{ info.getValue() }

+
+ ), + } ), + columnHelper.accessor( 'attachment_tags', { + header: () => __( 'Tags' ), + cell: ( info ) => ( + + { info.getValue().map( ( tagId ) => ( + + { + info.table.options.meta.tags.find( + ( tag ) => tag.id === tagId + )?.name + } + + ) ) } + + ), + } ), + columnHelper.accessor( 'post', { + header: () => __( 'Attached to' ), + cell: function AttachedToCell( info ) { + const { record } = useEntityRecord( + 'postType', + 'post', + info.getValue() + ); + const postTitle = record?.title?.rendered; + return postTitle ? { postTitle } : null; + }, + } ), + columnHelper.accessor( 'date_gmt', { + header: () => __( 'Date' ), + cell: ( info ) => ( + + ), + } ), +]; + const EMPTY_ARRAY = []; // Getting headings, etc. based on `mediaType` query type. @@ -56,7 +162,7 @@ function getMediaDetails( mediaType ) { export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); - const { attachments } = useSelect( + const { attachments, tags } = useSelect( ( select ) => { const _mediaType = 'all' === mediaType ? undefined : mediaType; const _attachments = select( coreStore ).getMediaItems( { @@ -67,8 +173,14 @@ export default function PageMedia() { // but we should maybe combine them into `documents`. media_type: _mediaType, } ); + const _tags = select( coreStore ).getEntityRecords( + 'taxonomy', + 'attachment_tag', + { per_page: -1 } + ); return { attachments: _attachments || EMPTY_ARRAY, + tags: _tags || EMPTY_ARRAY, }; }, [ mediaType ] @@ -88,81 +200,92 @@ export default function PageMedia() { { heading }
- - {} } - placeholder={ __( 'Search' ) } - size="__unstable-large" - /> - - - - - - + + {} } + placeholder={ __( 'Search' ) } + size="__unstable-large" + /> + - + + + + + + + + + { attachments && ( + - + ) } + - { /* or */ } - { attachments.map( ( attachment ) => ( -

- { attachment.title.raw } - { attachment.source_url } -

- ) ) } - From c355bd43a3e2ba26bd765f948bff4a90d357dc9b Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 18 Aug 2023 17:52:50 +1200 Subject: [PATCH 16/73] Saxon's stupid sort control --- .../components/page-media/filter-control.js | 28 ++++++++++++------- .../src/components/page-media/index.js | 18 ++++++------ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/packages/edit-site/src/components/page-media/filter-control.js b/packages/edit-site/src/components/page-media/filter-control.js index f452ad1c73f38..f7f9903a20677 100644 --- a/packages/edit-site/src/components/page-media/filter-control.js +++ b/packages/edit-site/src/components/page-media/filter-control.js @@ -18,6 +18,7 @@ export default function FilterControl( { label, value = [], options = [], + multiple = false, onChange = noop, } ) { const [ searchFilter, setSearchFilter ] = useState( '' ); @@ -27,7 +28,7 @@ export default function FilterControl( { renderToggle={ ( { onToggle, isOpen } ) => ( + From b1358ff09fe20464a4cfa524910d0d35bc83ba6d Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Sat, 19 Aug 2023 09:49:49 +1200 Subject: [PATCH 19/73] Wrap everything in a Spacer --- .../src/components/page-media/index.js | 192 +++++++++--------- 1 file changed, 101 insertions(+), 91 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 3a164923bf908..772aa048eec80 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -195,102 +195,112 @@ export default function PageMedia() { title={ __( 'Media' ) } hideTitleFromUI > - - - { heading } - - - - - {} } - placeholder={ __( 'Search' ) } - size="__unstable-large" - /> - - - - - - + + + { heading } + + + + + {} } + placeholder={ __( 'Search' ) } + size="__unstable-large" + /> + + + + - + + + + + + { attachments && ( +
- - + ) } + - { attachments && ( -
- ) } + + + - - - - - + ); } From a9c6eb44b8156c9485a1d0b11c3e4db1f943496a Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Sat, 19 Aug 2023 09:50:54 +1200 Subject: [PATCH 20/73] Refactor to accept the table prop directly --- .../src/components/page-media/index.js | 65 +++++++++++-------- .../components/page-template-parts/index.js | 16 +++-- .../src/components/page-templates/index.js | 14 +++- .../edit-site/src/components/table/index.js | 40 ++---------- 4 files changed, 67 insertions(+), 68 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 772aa048eec80..c1f5bc7da7575 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -1,7 +1,11 @@ /** * External dependencies */ -import { createColumnHelper } from '@tanstack/react-table'; +import { + useReactTable, + createColumnHelper, + getCoreRowModel, +} from '@tanstack/react-table'; /** * WordPress dependencies */ @@ -20,8 +24,9 @@ import { __experimentalHStack as HStack, __experimentalSpacer as Spacer, } from '@wordpress/components'; -import { useState } from '@wordpress/element'; +import { useState, useMemo } from '@wordpress/element'; import { grid, list } from '@wordpress/icons'; +import { store as blockEditorStore } from '@wordpress/block-editor'; /** * Internal dependencies @@ -40,16 +45,6 @@ import FilterControl from './filter-control'; /** @type {import('@tanstack/react-table').ColumnHelper} */ const columnHelper = createColumnHelper(); -const dateFormatter = new Intl.DateTimeFormat( - // TODO: Other locales? - 'en-US', - { - year: 'numeric', - month: 'long', - day: 'numeric', - } -); - const columns = [ columnHelper.display( { id: 'select', @@ -126,7 +121,9 @@ const columns = [ header: () => __( 'Date' ), cell: ( info ) => ( ), } ), @@ -161,7 +158,7 @@ function getMediaDetails( mediaType ) { export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); - const { attachments, tags } = useSelect( + const { attachments, tags, locale } = useSelect( ( select ) => { const _mediaType = 'all' === mediaType ? undefined : mediaType; const _attachments = select( coreStore ).getMediaItems( { @@ -177,14 +174,39 @@ export default function PageMedia() { 'attachment_tag', { per_page: -1 } ); + const settings = select( blockEditorStore ).getSettings(); return { attachments: _attachments || EMPTY_ARRAY, tags: _tags || EMPTY_ARRAY, + locale: settings.locale, }; }, [ mediaType ] ); + const dateFormatter = useMemo( + () => + new Intl.DateTimeFormat( locale || 'en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + } ), + [ locale ] + ); + + const table = useReactTable( { + data: attachments, + columns, + getCoreRowModel: getCoreRowModel(), + meta: { + tags, + dateFormatter, + }, + enableMultiRowSelection: true, + enableSorting: true, + enableHiding: true, + } ); + const { heading } = getMediaDetails( mediaType ); const [ tagsFilter, setTagsFilter ] = useState( [] ); const [ authorFilter, setAuthorFilter ] = useState( [] ); @@ -280,20 +302,7 @@ export default function PageMedia() { - { attachments && ( -
- ) } + { attachments &&
} diff --git a/packages/edit-site/src/components/page-template-parts/index.js b/packages/edit-site/src/components/page-template-parts/index.js index 68105f688510b..2519a0ffa7cc4 100644 --- a/packages/edit-site/src/components/page-template-parts/index.js +++ b/packages/edit-site/src/components/page-template-parts/index.js @@ -1,7 +1,11 @@ /** * External dependencies */ -import { createColumnHelper } from '@tanstack/react-table'; +import { + useReactTable, + getCoreRowModel, + createColumnHelper, +} from '@tanstack/react-table'; /** * WordPress dependencies */ @@ -100,14 +104,18 @@ export default function PageTemplateParts() { } ); + const table = useReactTable( { + data: templateParts, + columns, + getCoreRowModel: getCoreRowModel(), + } ); + return ( } > - { templateParts && ( -
- ) } + { templateParts &&
} ); } diff --git a/packages/edit-site/src/components/page-templates/index.js b/packages/edit-site/src/components/page-templates/index.js index 7d384fbb10348..056611a8c37d1 100644 --- a/packages/edit-site/src/components/page-templates/index.js +++ b/packages/edit-site/src/components/page-templates/index.js @@ -1,7 +1,11 @@ /** * External dependencies */ -import { createColumnHelper } from '@tanstack/react-table'; +import { + useReactTable, + getCoreRowModel, + createColumnHelper, +} from '@tanstack/react-table'; /** * WordPress dependencies */ @@ -103,6 +107,12 @@ export default function PageTemplates() { } ); + const table = useReactTable( { + data: templates, + columns, + getCoreRowModel: getCoreRowModel(), + } ); + return ( } > - { templates &&
} + { templates &&
} ); } diff --git a/packages/edit-site/src/components/table/index.js b/packages/edit-site/src/components/table/index.js index 0c9951a37829f..0dc5b6fc48fb8 100644 --- a/packages/edit-site/src/components/table/index.js +++ b/packages/edit-site/src/components/table/index.js @@ -1,20 +1,13 @@ /** * External dependencies */ -import { - useReactTable, - flexRender, - getCoreRowModel, -} from '@tanstack/react-table'; - -export default function Table( { data, columns, tableOptions } ) { - const table = useReactTable( { - data, - columns, - getCoreRowModel: getCoreRowModel(), - ...tableOptions, - } ); +import { flexRender } from '@tanstack/react-table'; +/** + * @param {Object} props The props. + * @param {import('@tanstack/react-table').Table} props.table The table created from `@tanstack/react-table`. + */ +export default function Table( { table } ) { return (
@@ -33,11 +26,6 @@ export default function Table( { data, columns, tableOptions } ) { ) ) } ) ) } - { /* - { columns.map( ( column ) => ( - - ) ) } - */ } { table.getRowModel().rows.map( ( row ) => ( @@ -59,22 +47,6 @@ export default function Table( { data, columns, tableOptions } ) { ) ) } ) ) } - { /* { data.map( ( row, rowIndex ) => ( - - { columns.map( ( column, columnIndex ) => ( - - ) ) } - - ) ) } */ }
{ column.header }
- { column.cell( row ) } -
From be6616c26554e2f8266556bacdf846b72d422348 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Sat, 19 Aug 2023 09:52:53 +1200 Subject: [PATCH 21/73] Tweak SearchInput appearance --- packages/edit-site/src/components/page-media/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index c1f5bc7da7575..748be1c57193d 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -228,9 +228,10 @@ export default function PageMedia() { {} } placeholder={ __( 'Search' ) } - size="__unstable-large" + __nextHasNoMarginBottom /> Date: Sat, 19 Aug 2023 10:13:18 +1200 Subject: [PATCH 22/73] Add grid support and hook up grid/table toggle. --- .../src/components/page-media/grid-item.js | 58 +++++++++++++++++++ .../src/components/page-media/grid.js | 18 ++++++ .../src/components/page-media/index.js | 13 ++++- 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 packages/edit-site/src/components/page-media/grid-item.js create mode 100644 packages/edit-site/src/components/page-media/grid.js diff --git a/packages/edit-site/src/components/page-media/grid-item.js b/packages/edit-site/src/components/page-media/grid-item.js new file mode 100644 index 0000000000000..6262f9aed6b91 --- /dev/null +++ b/packages/edit-site/src/components/page-media/grid-item.js @@ -0,0 +1,58 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + Button, + DropdownMenu, + MenuGroup, + MenuItem, + __experimentalHeading as Heading, + __experimentalHStack as HStack, + Flex, +} from '@wordpress/components'; +import { moreHorizontal } from '@wordpress/icons'; + +function GridItem( { item } ) { + return ( +
  • + { + + + + + + + + + + { ( { onClose } ) => ( + + TODO + + ) } + + +
  • + ); +} + +export default GridItem; diff --git a/packages/edit-site/src/components/page-media/grid.js b/packages/edit-site/src/components/page-media/grid.js new file mode 100644 index 0000000000000..52a55bfca947c --- /dev/null +++ b/packages/edit-site/src/components/page-media/grid.js @@ -0,0 +1,18 @@ +/** + * Internal dependencies + */ +import GridItem from './grid-item'; + +export default function GridView( { items, ...props } ) { + if ( ! items?.length ) { + return null; + } + + return ( +
      + { items.map( ( item ) => ( + + ) ) } +
    + ); +} diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 748be1c57193d..6f6ee1a224b1e 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -33,6 +33,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; */ import Page from '../page'; import Table from '../table'; +import Grid from './grid'; // @todo abstract for common usage. import Pagination from '../page-patterns/pagination'; import FilterControl from './filter-control'; @@ -211,6 +212,8 @@ export default function PageMedia() { const [ tagsFilter, setTagsFilter ] = useState( [] ); const [ authorFilter, setAuthorFilter ] = useState( [] ); const [ sortBy, setSortBy ] = useState( [ 'name' ] ); + const [ currentView, setCurrentView ] = useState( 'grid' ); + return (
    - { attachments && } + { attachments && 'table' === currentView && ( +
    + ) } + { attachments && 'grid' === currentView && ( + + ) } From 0620f92dbd8f71672b643e1b07b29bcd4e1cb6b4 Mon Sep 17 00:00:00 2001 From: ramon Date: Sat, 19 Aug 2023 10:18:19 +1200 Subject: [PATCH 23/73] Let's show icons! --- .../src/components/page-media/index.js | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 3a164923bf908..3b4c8f8e6761f 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -19,9 +19,10 @@ import { __experimentalHeading as Heading, __experimentalHStack as HStack, __experimentalSpacer as Spacer, + Icon, } from '@wordpress/components'; import { useState } from '@wordpress/element'; -import { grid, list } from '@wordpress/icons'; +import { grid, list, video, audio, page } from '@wordpress/icons'; /** * Internal dependencies @@ -49,7 +50,6 @@ const dateFormatter = new Intl.DateTimeFormat( day: 'numeric', } ); - const columns = [ columnHelper.display( { id: 'select', @@ -77,16 +77,7 @@ const columns = [ header: () => __( 'Title' ), cell: ( info ) => ( - { + { getMediaThumbnail( info.row.original ) }

    { info.getValue() }

    ), @@ -134,29 +125,38 @@ const columns = [ const EMPTY_ARRAY = []; +const headingText = { + media: __( 'Media' ), + document: __( 'Documents' ), + audio: __( 'Audio' ), + video: __( 'Videos' ), + image: __( 'Images' ), +}; + // Getting headings, etc. based on `mediaType` query type. -function getMediaDetails( mediaType ) { - if ( 'document' === mediaType ) { - return { - heading: __( 'Documents' ), - }; +function getMediaThumbnail( attachment ) { + if ( 'image' === attachment?.media_type ) { + return ( + { + ); } - if ( 'audio' === mediaType ) { - return { - heading: __( 'Audio' ), - }; + if ( attachment?.mime_type.startsWith( 'audio' ) ) { + return ; } - if ( 'video' === mediaType ) { - return { - heading: __( 'Videos' ), - }; + if ( attachment?.mime_type.startsWith( 'video' ) ) { + return ; } - return { - heading: __( 'Images' ), - }; + // Everything else is a file. + return ; } export default function PageMedia() { @@ -185,7 +185,6 @@ export default function PageMedia() { [ mediaType ] ); - const { heading } = getMediaDetails( mediaType ); const [ tagsFilter, setTagsFilter ] = useState( [] ); const [ authorFilter, setAuthorFilter ] = useState( [] ); const [ sortBy, setSortBy ] = useState( [ 'name' ] ); @@ -197,7 +196,7 @@ export default function PageMedia() { > - { heading } + { headingText[ mediaType ] } From 280b567efb10f460bc0f7935537b605114c356f3 Mon Sep 17 00:00:00 2001 From: apeatling Date: Sat, 19 Aug 2023 10:21:03 +1200 Subject: [PATCH 24/73] Add missing grid styles --- .../src/components/page-media/style.scss | 56 +++++++++++++++++++ packages/edit-site/src/style.scss | 1 + 2 files changed, 57 insertions(+) create mode 100644 packages/edit-site/src/components/page-media/style.scss diff --git a/packages/edit-site/src/components/page-media/style.scss b/packages/edit-site/src/components/page-media/style.scss new file mode 100644 index 0000000000000..87c2353859c3f --- /dev/null +++ b/packages/edit-site/src/components/page-media/style.scss @@ -0,0 +1,56 @@ +.edit-site-media__grid { + display: grid; + grid-template-columns: 1fr; + gap: $grid-unit-40; + margin-top: 0; + margin-bottom: 0; + + @include break-large { + grid-template-columns: 1fr 1fr; + } + + @include break-huge { + grid-template-columns: 1fr 1fr 1fr; + } + + @include break-xhuge { + grid-template-columns: 1fr 1fr 1fr 1fr; + } + + .edit-site-media__item-container { + break-inside: avoid-column; + display: flex; + flex-direction: column; + + .edit-site-media__item { + max-width: 100%; + } + + .edit-site-media__footer, + .edit-site-media__button { + color: $gray-600; + } + } +} + +.edit-site-media__load-more { + align-self: center; +} + +.edit-site-media__title { + color: $gray-200; + + .is-link { + text-decoration: none; + color: $gray-200; + + &:hover, + &:focus { + color: $white; + } + } +} + +.edit-site-media__no-results { + color: $gray-600; +} diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 1053aa6267bd7..17627cdd6c97e 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -45,6 +45,7 @@ @import "./components/editor-canvas-container/style.scss"; @import "./components/resizable-frame/style.scss"; @import "./hooks/push-changes-to-global-styles/style.scss"; +@import "./components/page-media/style.scss"; body.js #wpadminbar { display: none; From 25c8bdd4ce147f13f49995260ac9cf9ba8690f85 Mon Sep 17 00:00:00 2001 From: apeatling Date: Sat, 19 Aug 2023 10:22:15 +1200 Subject: [PATCH 25/73] Reverse toggle --- packages/edit-site/src/components/page-media/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 6f6ee1a224b1e..a91bf7fb4e7a1 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -297,12 +297,12 @@ export default function PageMedia() {
    From 396c4f31f61ba031db429af7127f34cfa55a020d Mon Sep 17 00:00:00 2001 From: ramon Date: Sat, 19 Aug 2023 10:26:18 +1200 Subject: [PATCH 26/73] getting thumbnail for grid --- .../edit-site/src/components/page-media/grid-item.js | 11 ++++++----- packages/edit-site/src/components/page-media/index.js | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/page-media/grid-item.js b/packages/edit-site/src/components/page-media/grid-item.js index 6262f9aed6b91..9264cb0a7e774 100644 --- a/packages/edit-site/src/components/page-media/grid-item.js +++ b/packages/edit-site/src/components/page-media/grid-item.js @@ -13,14 +13,15 @@ import { } from '@wordpress/components'; import { moreHorizontal } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import { getMediaThumbnail } from './'; + function GridItem( { item } ) { return (
  • - { + { getMediaThumbnail( item ) } Date: Sat, 19 Aug 2023 10:34:28 +1200 Subject: [PATCH 27/73] EL LINTO DEL DIABLO! --- .../components/sidebar-navigation-screen-main/index.js | 9 ++++++++- .../sync-state-with-url/use-sync-path-with-url.js | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js index 063bebb3b75f9..fc8e82b147017 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-main/index.js @@ -7,7 +7,14 @@ import { __experimentalUseNavigator as useNavigator, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { layout, media, navigation, page, styles, symbol } from '@wordpress/icons'; +import { + layout, + media, + navigation, + page, + styles, + symbol, +} from '@wordpress/icons'; import { useDispatch } from '@wordpress/data'; import { useEffect } from '@wordpress/element'; diff --git a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js b/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js index 4eb3c3734a892..b3e44f73576d2 100644 --- a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js +++ b/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js @@ -87,7 +87,10 @@ export default function useSyncPathWithURL() { postId: navigatorParams?.postId, path: undefined, } ); - } else if ( navigatorLocation.path === '/patterns' || navigatorLocation.path === '/media' ) { + } else if ( + navigatorLocation.path === '/patterns' || + navigatorLocation.path === '/media' + ) { updateUrlParams( { postType: undefined, postId: undefined, From 7a1dd8db11d44a482fbb5fe8c6305257fc10c651 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Sat, 19 Aug 2023 10:40:59 +1200 Subject: [PATCH 28/73] Default to table view --- .../edit-site/src/components/page-media/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 1f4d92be4f639..a84b3552eabfc 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -212,7 +212,7 @@ export default function PageMedia() { const [ tagsFilter, setTagsFilter ] = useState( [] ); const [ authorFilter, setAuthorFilter ] = useState( [] ); const [ sortBy, setSortBy ] = useState( [ 'name' ] ); - const [ currentView, setCurrentView ] = useState( 'grid' ); + const [ currentView, setCurrentView ] = useState( 'table' ); return ( - + From 532aae0b4862a331ebc60978a5ee48e573096160 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Sat, 19 Aug 2023 11:01:31 +1200 Subject: [PATCH 29/73] Hook up tags filtering --- .../src/components/page-media/index.js | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index a84b3552eabfc..5ed471a3851da 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -5,6 +5,7 @@ import { useReactTable, createColumnHelper, getCoreRowModel, + getFilteredRowModel, } from '@tanstack/react-table'; /** * WordPress dependencies @@ -80,6 +81,7 @@ const columns = [ ), } ), columnHelper.accessor( 'attachment_tags', { + id: 'tags', header: () => __( 'Tags' ), cell: ( info ) => ( @@ -97,6 +99,7 @@ const columns = [ ) ) } ), + filterFn: 'arrIncludesAll', } ), columnHelper.accessor( 'post', { header: () => __( 'Attached to' ), @@ -200,6 +203,7 @@ export default function PageMedia() { data: attachments, columns, getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), meta: { tags, dateFormatter, @@ -207,12 +211,21 @@ export default function PageMedia() { enableMultiRowSelection: true, enableSorting: true, enableHiding: true, + enableFilters: true, } ); + window.table = table; - const [ tagsFilter, setTagsFilter ] = useState( [] ); const [ authorFilter, setAuthorFilter ] = useState( [] ); const [ sortBy, setSortBy ] = useState( [ 'name' ] ); const [ currentView, setCurrentView ] = useState( 'table' ); + const tagOptions = useMemo( + () => + tags.map( ( tag ) => ( { + label: tag.name, + value: tag.id, + } ) ), + [ tags ] + ); return ( Date: Sat, 19 Aug 2023 11:22:43 +1200 Subject: [PATCH 30/73] Basic single item page and nav --- .../src/components/page-media/grid-item.js | 68 +++++++++++-------- .../src/components/page-media/grid.js | 2 +- .../src/components/page-media/index.js | 3 +- .../index.js | 55 +++++++++++++++ .../style.scss | 3 + .../sidebar-navigation-screen-media/index.js | 6 +- .../edit-site/src/components/sidebar/index.js | 4 ++ .../use-sync-path-with-url.js | 1 + packages/edit-site/src/style.scss | 1 + 9 files changed, 106 insertions(+), 37 deletions(-) create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss diff --git a/packages/edit-site/src/components/page-media/grid-item.js b/packages/edit-site/src/components/page-media/grid-item.js index 9264cb0a7e774..301495c694286 100644 --- a/packages/edit-site/src/components/page-media/grid-item.js +++ b/packages/edit-site/src/components/page-media/grid-item.js @@ -17,41 +17,51 @@ import { moreHorizontal } from '@wordpress/icons'; * Internal dependencies */ import { getMediaThumbnail } from './'; +import { useLink } from '../routes/link'; function GridItem( { item } ) { + const linkProps = useLink( { + postType: item.type, + postId: item.id, + } ); return ( -
  • - { getMediaThumbnail( item ) } - +
  • + - - + + + + { item.title.rendered } + + + + + { ( { onClose } ) => ( + + TODO + + ) } + - - { ( { onClose } ) => ( - - TODO - - ) } - - +
  • ); } diff --git a/packages/edit-site/src/components/page-media/grid.js b/packages/edit-site/src/components/page-media/grid.js index 52a55bfca947c..89bb335a398f2 100644 --- a/packages/edit-site/src/components/page-media/grid.js +++ b/packages/edit-site/src/components/page-media/grid.js @@ -11,7 +11,7 @@ export default function GridView( { items, ...props } ) { return (
      { items.map( ( item ) => ( - + ) ) }
    ); diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 1f4d92be4f639..7c0bb519d5d52 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -162,14 +162,13 @@ export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); const { attachments, tags, locale } = useSelect( ( select ) => { - const _mediaType = 'all' === mediaType ? undefined : mediaType; const _attachments = select( coreStore ).getMediaItems( { per_page: 50, orderby: 'date', order: 'desc', // @todo `application` and `text` are valid media types, // but we should maybe combine them into `documents`. - media_type: _mediaType, + media_type: mediaType, } ); const _tags = select( coreStore ).getEntityRecords( 'taxonomy', diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js new file mode 100644 index 0000000000000..5cd2a0d110000 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js @@ -0,0 +1,55 @@ +/** + * WordPress dependencies + */ +import { __experimentalUseNavigator as useNavigator } from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { pencil } from '@wordpress/icons'; +import { store as coreStore } from '@wordpress/core-data'; + +/** + * Internal dependencies + */ +import SidebarButton from '../sidebar-button'; +import SidebarNavigationScreen from '../sidebar-navigation-screen'; +import { store as editSiteStore } from '../../store'; +import { unlock } from '../../lock-unlock'; + +export default function SidebarNavigationScreenMediaItem() { + const { params } = useNavigator(); + const { postType, postId } = params; + const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); + const { record } = useSelect( + ( select ) => { + const { getMedia } = select( coreStore ); + return { + record: getMedia( postId ), + }; + }, + [ postId ] + ); + + // The absence of a media type in the query params for media + // indicates the user has arrived at the template part via the "media" main + // view and the back button should return them to that list page. + //const backPath = !! mediaType ? `/media/${ mediaType }` : '/media'; + + return ( + setCanvasMode( 'edit' ) } + label={ __( 'Edit' ) } + icon={ pencil } + /> + } + //backPath={ backPath } + content={ +
    + { record?.title.rendered } { postType } - { postId } +
    + } + footer={ __( 'Media Item Footer' ) } + /> + ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss new file mode 100644 index 0000000000000..35626f319c0ab --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss @@ -0,0 +1,3 @@ +.edit-site-sidebar-navigation-screen-media-item-content { + display: flex; +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js index 80e0a70a3fa25..9f0d70b664494 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media/index.js @@ -38,11 +38,7 @@ export default function SidebarNavigationScreenMedia() { actions={ null } content={ - + { __( 'All media' ) } + + + ); } diff --git a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js b/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js index b3e44f73576d2..378d8ecda13a0 100644 --- a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js +++ b/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js @@ -21,6 +21,7 @@ export function getPathFromURL( urlParams ) { case 'wp_block': case 'wp_template': case 'wp_template_part': + case 'attachment': case 'page': path = `/${ encodeURIComponent( urlParams.postType diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 17627cdd6c97e..c697794a852bf 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -46,6 +46,7 @@ @import "./components/resizable-frame/style.scss"; @import "./hooks/push-changes-to-global-styles/style.scss"; @import "./components/page-media/style.scss"; +@import "./components/sidebar-navigation-screen-media-item/style.scss"; body.js #wpadminbar { display: none; From 2221839c820f02d879c27b8f4cdbb097f40a4e36 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Sat, 19 Aug 2023 11:45:18 +1200 Subject: [PATCH 31/73] Add sorting --- .../src/components/page-media/index.js | 7 ++- .../components/page-template-parts/index.js | 1 + .../src/components/page-templates/index.js | 1 + .../edit-site/src/components/table/index.js | 54 ++++++++++++++++--- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 1185e07ea3ace..92a84ed8d491b 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -6,6 +6,7 @@ import { createColumnHelper, getCoreRowModel, getFilteredRowModel, + getSortedRowModel, } from '@tanstack/react-table'; /** * WordPress dependencies @@ -72,13 +73,14 @@ const columns = [ } ), columnHelper.accessor( ( row ) => row.title.rendered, { id: 'title', - header: () => __( 'Title' ), + header: __( 'Title' ), cell: ( info ) => ( { getMediaThumbnail( info.row.original ) }

    { info.getValue() }

    ), + sortingFn: 'alphanumeric', } ), columnHelper.accessor( 'attachment_tags', { id: 'tags', @@ -112,6 +114,7 @@ const columns = [ const postTitle = record?.title?.rendered; return postTitle ? { postTitle } : null; }, + sortingFn: 'alphanumeric', } ), columnHelper.accessor( 'date_gmt', { header: () => __( 'Date' ), @@ -122,6 +125,7 @@ const columns = [ ) } ), + sortingFn: 'datetime', } ), ]; @@ -203,6 +207,7 @@ export default function PageMedia() { columns, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), + getSortedRowModel: getSortedRowModel(), meta: { tags, dateFormatter, diff --git a/packages/edit-site/src/components/page-template-parts/index.js b/packages/edit-site/src/components/page-template-parts/index.js index 2519a0ffa7cc4..314b75e5f91fd 100644 --- a/packages/edit-site/src/components/page-template-parts/index.js +++ b/packages/edit-site/src/components/page-template-parts/index.js @@ -108,6 +108,7 @@ export default function PageTemplateParts() { data: templateParts, columns, getCoreRowModel: getCoreRowModel(), + enableSorting: false, } ); return ( diff --git a/packages/edit-site/src/components/page-templates/index.js b/packages/edit-site/src/components/page-templates/index.js index 056611a8c37d1..393fd03c1fcc1 100644 --- a/packages/edit-site/src/components/page-templates/index.js +++ b/packages/edit-site/src/components/page-templates/index.js @@ -111,6 +111,7 @@ export default function PageTemplates() { data: templates, columns, getCoreRowModel: getCoreRowModel(), + enableSorting: false, } ); return ( diff --git a/packages/edit-site/src/components/table/index.js b/packages/edit-site/src/components/table/index.js index 0dc5b6fc48fb8..ad48aa6b1850a 100644 --- a/packages/edit-site/src/components/table/index.js +++ b/packages/edit-site/src/components/table/index.js @@ -4,8 +4,51 @@ import { flexRender } from '@tanstack/react-table'; /** - * @param {Object} props The props. - * @param {import('@tanstack/react-table').Table} props.table The table created from `@tanstack/react-table`. + * WordPress dependencies + */ +import { Button, Icon } from '@wordpress/components'; +import { chevronUp, chevronDown } from '@wordpress/icons'; + +/** + * @typedef {import('@tanstack/react-table').Header} Header + * @typedef {import('@tanstack/react-table').Table} Table + */ + +/** + * @param {Object} props + * @param {Header} props.header + */ +function HeaderColumn( { header } ) { + if ( header.isPlaceholder ) return null; + + const rendered = flexRender( + header.column.columnDef.header, + header.getContext() + ); + + if ( ! header.column.getCanSort() ) { + return rendered; + } + + return ( + + ); +} + +/** + * @param {Object} props + * @param {Table} props.table */ export default function Table( { table } ) { return ( @@ -16,12 +59,7 @@ export default function Table( { table } ) {
    { headerGroup.headers.map( ( header ) => ( ) ) } From 38c4358e2eff4641a2b7f458275d90960f811684 Mon Sep 17 00:00:00 2001 From: apeatling Date: Sat, 19 Aug 2023 11:46:18 +1200 Subject: [PATCH 32/73] Get pagination working --- .../src/components/page-media/index.js | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 1185e07ea3ace..fd574146668c9 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -126,6 +126,7 @@ const columns = [ ]; const EMPTY_ARRAY = []; +const PAGE_SIZE = 20; const headingText = { media: __( 'Media' ), @@ -166,7 +167,7 @@ export default function PageMedia() { const { attachments, tags, locale } = useSelect( ( select ) => { const _attachments = select( coreStore ).getMediaItems( { - per_page: 50, + per_page: -1, orderby: 'date', order: 'desc', // @todo `application` and `text` are valid media types, @@ -187,6 +188,25 @@ export default function PageMedia() { }, [ mediaType ] ); + const totalItems = attachments.length; + const numPages = Math.ceil( attachments.length / PAGE_SIZE ); + const [ currentPage, setCurrentPage ] = useState( 1 ); + const pageIndex = currentPage - 1; + + const attachmentsOnPage = useMemo( () => { + return attachments.slice( + pageIndex * PAGE_SIZE, + pageIndex * PAGE_SIZE + PAGE_SIZE + ); + }, [ pageIndex, attachments ] ); + + const changePage = ( newPage ) => { + // @todo Not working yet, we don't have a scroll container. + // const scrollContainer = document.querySelector( '.edit-site-media' ); + // scrollContainer?.scrollTo( 0, 0 ); + + setCurrentPage( newPage ); + }; const dateFormatter = useMemo( () => @@ -199,7 +219,7 @@ export default function PageMedia() { ); const table = useReactTable( { - data: attachments, + data: attachmentsOnPage, columns, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), @@ -310,16 +330,23 @@ export default function PageMedia() { - { attachments && 'table' === currentView && ( + { attachmentsOnPage && 'table' === currentView && (
    - { header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - ) } +
    ) } - { attachments && 'grid' === currentView && ( - + { attachmentsOnPage && 'grid' === currentView && ( + ) } - + { numPages > 1 && ( + + ) } From 7476dd878cf06847dfdd39da01bcf35183db724a Mon Sep 17 00:00:00 2001 From: ramon Date: Sat, 19 Aug 2023 11:48:26 +1200 Subject: [PATCH 33/73] Adding link button to list item --- .../src/components/page-media/index.js | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 1185e07ea3ace..0ea12cc8087a5 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -39,6 +39,7 @@ import Grid from './grid'; // @todo abstract for common usage. import Pagination from '../page-patterns/pagination'; import FilterControl from './filter-control'; +import { useLink } from '../routes/link'; /** * @typedef {Object} Attachment @@ -48,6 +49,21 @@ import FilterControl from './filter-control'; /** @type {import('@tanstack/react-table').ColumnHelper} */ const columnHelper = createColumnHelper(); +function GridItemButton( { item } ) { + const linkProps = useLink( { + postType: item.type, + postId: item.id, + } ); + return ( + + ); +} + const columns = [ columnHelper.display( { id: 'select', @@ -73,12 +89,7 @@ const columns = [ columnHelper.accessor( ( row ) => row.title.rendered, { id: 'title', header: () => __( 'Title' ), - cell: ( info ) => ( - - { getMediaThumbnail( info.row.original ) } -

    { info.getValue() }

    -
    - ), + cell: ( info ) => , } ), columnHelper.accessor( 'attachment_tags', { id: 'tags', From b7766eb9da4e6ac00b966b8754bd7f67d5615fae Mon Sep 17 00:00:00 2001 From: ramon Date: Sat, 19 Aug 2023 12:06:49 +1200 Subject: [PATCH 34/73] Completely breaking nav - just trying --- .../src/components/page-media/grid-item.js | 2 ++ .../src/components/page-media/index.js | 19 +++++++++++++++++++ .../index.js | 6 +++--- .../use-sync-path-with-url.js | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/edit-site/src/components/page-media/grid-item.js b/packages/edit-site/src/components/page-media/grid-item.js index 301495c694286..0849f841fd323 100644 --- a/packages/edit-site/src/components/page-media/grid-item.js +++ b/packages/edit-site/src/components/page-media/grid-item.js @@ -18,11 +18,13 @@ import { moreHorizontal } from '@wordpress/icons'; */ import { getMediaThumbnail } from './'; import { useLink } from '../routes/link'; +import { getMediaTypeFromMimeType } from '../page-media'; function GridItem( { item } ) { const linkProps = useLink( { postType: item.type, postId: item.id, + mediaType: getMediaTypeFromMimeType( item.mime_type ), } ); return (
  • diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index d262f2fa56ddf..2b494d0cadb7d 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -54,6 +54,7 @@ function GridItemButton( { item } ) { const linkProps = useLink( { postType: item.type, postId: item.id, + mediaType: getMediaTypeFromMimeType( item.mime_type ), } ); return ( + diff --git a/packages/edit-site/src/components/table/index.js b/packages/edit-site/src/components/table/index.js index ad48aa6b1850a..8e8fd2ec7ffdc 100644 --- a/packages/edit-site/src/components/table/index.js +++ b/packages/edit-site/src/components/table/index.js @@ -67,7 +67,12 @@ export default function Table( { table } ) {
  • { table.getRowModel().rows.map( ( row ) => ( - + { row.getVisibleCells().map( ( cell ) => ( From dbe8c7beb653fa99a2f8ae5b10f21f7259e4e63c Mon Sep 17 00:00:00 2001 From: ramon Date: Sat, 19 Aug 2023 14:34:35 +1200 Subject: [PATCH 39/73] Media item page routes. Fooked and fixed --- .../src/components/page-main/index.js | 7 +++- .../src/components/page-media/grid-item.js | 4 +- .../src/components/page-media/index.js | 3 +- .../components/page-media/page-media-item.js | 42 +++++++++++++++++++ .../index.js | 19 ++------- .../index.js | 1 - .../edit-site/src/components/sidebar/index.js | 6 +-- .../use-sync-path-with-url.js | 2 +- .../edit-site/src/utils/get-is-list-page.js | 5 ++- 9 files changed, 60 insertions(+), 29 deletions(-) create mode 100644 packages/edit-site/src/components/page-media/page-media-item.js diff --git a/packages/edit-site/src/components/page-main/index.js b/packages/edit-site/src/components/page-main/index.js index 7029c60b59715..48239a91b4ca9 100644 --- a/packages/edit-site/src/components/page-main/index.js +++ b/packages/edit-site/src/components/page-main/index.js @@ -8,6 +8,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; */ import PagePatterns from '../page-patterns'; import PageMedia from '../page-media'; +import PageMediaItem from '../page-media/page-media-item'; import PageTemplateParts from '../page-template-parts'; import PageTemplates from '../page-templates'; import { unlock } from '../../lock-unlock'; @@ -16,7 +17,7 @@ const { useLocation } = unlock( routerPrivateApis ); export default function PageMain() { const { - params: { path }, + params: { path, postId, postType }, } = useLocation(); if ( path === '/wp_template/all' ) { @@ -25,8 +26,10 @@ export default function PageMain() { return ; } else if ( path === '/patterns' ) { return ; - } else if ( path === '/media' ) { + } else if ( path === '/media' && ! postId ) { return ; + } else if ( postType === 'attachment' && !! postId ) { + return ; } return null; diff --git a/packages/edit-site/src/components/page-media/grid-item.js b/packages/edit-site/src/components/page-media/grid-item.js index 0849f841fd323..c42edf6db9c45 100644 --- a/packages/edit-site/src/components/page-media/grid-item.js +++ b/packages/edit-site/src/components/page-media/grid-item.js @@ -18,13 +18,11 @@ import { moreHorizontal } from '@wordpress/icons'; */ import { getMediaThumbnail } from './'; import { useLink } from '../routes/link'; -import { getMediaTypeFromMimeType } from '../page-media'; function GridItem( { item } ) { const linkProps = useLink( { - postType: item.type, + postType: 'attachment', postId: item.id, - mediaType: getMediaTypeFromMimeType( item.mime_type ), } ); return (
  • diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 65a17f4cf5cdc..ffb2e93b79351 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -57,9 +57,8 @@ const columnHelper = createColumnHelper(); function GridItemButton( { item } ) { const linkProps = useLink( { - postType: item.type, + postType: 'attachment', postId: item.id, - mediaType: getMediaTypeFromMimeType( item.mime_type ), } ); return ( + { !! onCreate && searchFilter !== '' && ( + + ) } + { multiple && ! hideClear && ( + + ) } ) } /> @@ -106,7 +133,8 @@ function getToggleText( label, value, options ) { /* translators: %1$s: label, %2$s: selected item */ __( '%1$s: %2$s' ), label, - options.find( ( option ) => option.value === value[ 0 ] ).label + options.find( ( option ) => option.value === value[ 0 ] )?.label ?? + value[ 0 ] ); } return label; diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index b2a512400e952..f2d377e96f054 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -70,6 +70,62 @@ function GridItemButton( { item } ) { ); } +function TagsCellButton( { attachmentId, tagIds, tags } ) { + const { saveEntityRecord } = useDispatch( coreStore ); + return ( + ( { + value: tag.id, + label: tag.name, + } ) ) } + multiple + hideClear + onChange={ async ( newTagIds ) => { + await saveEntityRecord( 'root', 'media', { + id: attachmentId, + attachment_tags: newTagIds, + } ); + } } + onCreate={ async ( input ) => { + const { id: newTagId } = await saveEntityRecord( + 'taxonomy', + 'attachment_tag', + { + name: input, + } + ); + await saveEntityRecord( 'root', 'media', { + id: attachmentId, + attachment_tags: [ ...tagIds, newTagId ], + } ); + } } + > + { ( { onToggle } ) => ( + + ) } + + ); +} + const columns = [ columnHelper.display( { id: 'select', @@ -106,20 +162,11 @@ const columns = [ id: 'tags', header: () => __( 'Tags' ), cell: ( info ) => ( - - { info.getValue()?.map( ( tagId ) => ( - - { - info.table.options.meta.tags.find( - ( tag ) => tag.id === tagId - )?.name - } - - ) ) } - + ), filterFn: 'arrIncludesAll', } ), From 1c6b8fc8a8b740a2ef15d721067e4e50a4618308 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Sat, 19 Aug 2023 14:12:49 +1200 Subject: [PATCH 42/73] Add author filter --- .../src/components/page-media/index.js | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index f2d377e96f054..7fa83a77f20a8 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -183,6 +183,15 @@ const columns = [ }, sortingFn: 'alphanumeric', } ), + columnHelper.accessor( 'author', { + header: () => __( 'Author' ), + cell: ( info ) => { + const users = info.table.options.meta.users; + if ( ! users ) return null; + return users.find( ( user ) => user.id === info.getValue() )?.name; + }, + sortingFn: 'alphanumeric', + } ), columnHelper.accessor( 'date_gmt', { header: () => __( 'Date' ), cell: ( info ) => @@ -268,7 +277,7 @@ export function getMediaThumbnail( attachment ) { export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); - const { persistedAttachments, tags, locale } = useSelect( + const { persistedAttachments, tags, locale, users } = useSelect( ( select ) => { const _attachments = select( coreStore ).getMediaItems( { per_page: -1, @@ -288,6 +297,7 @@ export default function PageMedia() { persistedAttachments: _attachments || EMPTY_ARRAY, tags: _tags || EMPTY_ARRAY, locale: settings.locale, + users: select( coreStore ).getUsers(), }; }, [ mediaType ] @@ -338,6 +348,7 @@ export default function PageMedia() { meta: { tags, dateFormatter, + users, }, enableMultiRowSelection: true, enableSorting: true, @@ -346,7 +357,6 @@ export default function PageMedia() { } ); window.table = table; - const [ authorFilter, setAuthorFilter ] = useState( [] ); const [ sortBy, setSortBy ] = useState( [ 'name' ] ); const [ currentView, setCurrentView ] = useState( 'table' ); const tagOptions = useMemo( @@ -427,23 +437,25 @@ export default function PageMedia() { table.getColumn( 'tags' ).setFilterValue } /> - + { users && ( + ( { + label: user.name, + value: user.id, + } ) ) ?? [] + } + multiple + onChange={ + table.getColumn( 'author' ) + .setFilterValue + } + /> + ) } Date: Sat, 19 Aug 2023 15:05:03 +1200 Subject: [PATCH 43/73] Add global filter search box --- packages/edit-site/src/components/page-media/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 7fa83a77f20a8..5067e85f1c47c 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -337,6 +337,7 @@ export default function PageMedia() { } ), [ locale ] ); + const [ globalFilter, setGlobalFilter ] = useState( '' ); const table = useReactTable( { data: attachmentsOnPage, @@ -345,6 +346,9 @@ export default function PageMedia() { getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), + state: { + globalFilter, + }, meta: { tags, dateFormatter, @@ -422,7 +426,8 @@ export default function PageMedia() { {} } + value={ globalFilter } + onChange={ setGlobalFilter } placeholder={ __( 'Search' ) } __nextHasNoMarginBottom /> From 0961f217bb3618cf81962a324a1d2117af6503fd Mon Sep 17 00:00:00 2001 From: apeatling Date: Sat, 19 Aug 2023 15:10:39 +1200 Subject: [PATCH 44/73] Fix grid view design. --- .../src/components/page-media/get-media.js | 71 +++++++++++++++++++ .../src/components/page-media/grid-item.js | 4 +- .../src/components/page-media/index.js | 66 ++--------------- .../src/components/page-media/style.scss | 9 ++- 4 files changed, 84 insertions(+), 66 deletions(-) create mode 100644 packages/edit-site/src/components/page-media/get-media.js diff --git a/packages/edit-site/src/components/page-media/get-media.js b/packages/edit-site/src/components/page-media/get-media.js new file mode 100644 index 0000000000000..cc7705ecdb125 --- /dev/null +++ b/packages/edit-site/src/components/page-media/get-media.js @@ -0,0 +1,71 @@ +/** + * WordPress dependencies + */ +import { Icon } from '@wordpress/components'; +import { video, audio, page } from '@wordpress/icons'; +import { isBlobURL } from '@wordpress/blob'; + +// Getting headings, etc. based on `mediaType` query type. +export function getMediaItem( attachment, size = 'thumb' ) { + if ( isBlobURL( attachment.url ) ) { + return size === 'thumb' ? ( + + ) : ( + + ); + } + + const mediaType = getMediaTypeFromMimeType( attachment.mime_type ); + + if ( 'image' === mediaType ) { + return size === 'thumb' ? ( + { + ) : ( + { + ); + } + + if ( 'audio' === mediaType ) { + return ; + } + + if ( 'video' === mediaType ) { + return ; + } + + // Everything else is a file. + return ; +} + +export function getMediaTypeFromMimeType( mimeType ) { + // @todo this needs to be abstracted and the + // media types formalized somewhere. + if ( mimeType.startsWith( 'image/' ) ) { + return 'image'; + } + + if ( mimeType.startsWith( 'video/' ) ) { + return 'video'; + } + + if ( mimeType.startsWith( 'audio/' ) ) { + return 'audio'; + } + + return 'application'; +} diff --git a/packages/edit-site/src/components/page-media/grid-item.js b/packages/edit-site/src/components/page-media/grid-item.js index c42edf6db9c45..a6d9ff1aecaaa 100644 --- a/packages/edit-site/src/components/page-media/grid-item.js +++ b/packages/edit-site/src/components/page-media/grid-item.js @@ -16,7 +16,7 @@ import { moreHorizontal } from '@wordpress/icons'; /** * Internal dependencies */ -import { getMediaThumbnail } from './'; +import { getMediaItem } from './get-media'; import { useLink } from '../routes/link'; function GridItem( { item } ) { @@ -27,7 +27,7 @@ function GridItem( { item } ) { return (
  • @@ -97,7 +97,7 @@ const columns = [ header: () => __( 'Title' ), cell: ( info ) => isBlobURL( info.row.original.url ) ? ( - getMediaThumbnail( info.row.original ) + getMediaItem( info.row.original ) ) : ( ), @@ -161,64 +161,6 @@ const headingText = { image: __( 'Images' ), }; -export function getMediaTypeFromMimeType( mimeType ) { - // @todo this needs to be abstracted and the - // media types formalized somewhere. - if ( mimeType.startsWith( 'image/' ) ) { - return 'image'; - } - - if ( mimeType.startsWith( 'video/' ) ) { - return 'video'; - } - - if ( mimeType.startsWith( 'audio/' ) ) { - return 'audio'; - } - - return 'application'; -} - -// Getting headings, etc. based on `mediaType` query type. -export function getMediaThumbnail( attachment ) { - if ( isBlobURL( attachment.url ) ) { - return ( - - ); - } - - const mediaType = getMediaTypeFromMimeType( attachment.mime_type ); - - if ( 'image' === mediaType ) { - return ( - { - ); - } - - if ( 'audio' === mediaType ) { - return ; - } - - if ( 'video' === mediaType ) { - return ; - } - - // Everything else is a file. - return ; -} - export default function PageMedia() { const { mediaType } = getQueryArgs( window.location.href ); const { persistedAttachments, tags, locale } = useSelect( diff --git a/packages/edit-site/src/components/page-media/style.scss b/packages/edit-site/src/components/page-media/style.scss index d07959536ce55..5702c6b1f73fe 100644 --- a/packages/edit-site/src/components/page-media/style.scss +++ b/packages/edit-site/src/components/page-media/style.scss @@ -22,8 +22,13 @@ display: flex; flex-direction: column; - .edit-site-media__item { - max-width: 100%; + .components-button { + height: auto; + display: block; + + img { + max-width: 100%; + } } .edit-site-media__footer, From 86315018725336740a390225a1851255824e9a5e Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Sat, 19 Aug 2023 15:21:18 +1200 Subject: [PATCH 45/73] Alphabatically sort the title --- packages/edit-site/src/components/page-media/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index f9a1bbbcedf2a..0f648e1faf64e 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -157,6 +157,7 @@ const columns = [ ) : ( ), + sortingFn: 'alphanumeric', } ), columnHelper.accessor( 'attachment_tags', { id: 'tags', From 8c79ae7e6eed2d850cd5d04efead7198b7bcb144 Mon Sep 17 00:00:00 2001 From: Saxon Fletcher Date: Sat, 19 Aug 2023 13:48:55 +1000 Subject: [PATCH 46/73] make pretty --- .../components/page-media/filter-control.js | 2 +- .../src/components/page-media/index.js | 236 +++++++++--------- .../src/components/page-media/style.scss | 17 ++ .../edit-site/src/components/table/index.js | 5 +- .../edit-site/src/components/table/style.scss | 5 +- 5 files changed, 143 insertions(+), 122 deletions(-) diff --git a/packages/edit-site/src/components/page-media/filter-control.js b/packages/edit-site/src/components/page-media/filter-control.js index a821b7e7d5459..1539d086a005b 100644 --- a/packages/edit-site/src/components/page-media/filter-control.js +++ b/packages/edit-site/src/components/page-media/filter-control.js @@ -35,7 +35,7 @@ export default function FilterControl( { children( { onToggle, isOpen } ) ) : ( ); } @@ -127,27 +125,27 @@ function TagsCellButton( { attachmentId, tagIds, tags } ) { } const columns = [ - columnHelper.display( { - id: 'select', - header: ( { table } ) => ( - - table.toggleAllPageRowsSelected( !! value ) - } - aria-label={ __( 'Select all' ) } - /> - ), - cell: ( { row } ) => ( - row.toggleSelected( !! value ) } - aria-label={ __( 'Select row' ) } - /> - ), - enableSorting: false, - enableHiding: false, - } ), + // columnHelper.display( { + // id: 'select', + // header: ( { table } ) => ( + // + // table.toggleAllPageRowsSelected( !! value ) + // } + // aria-label={ __( 'Select all' ) } + // /> + // ), + // cell: ( { row } ) => ( + // row.toggleSelected( !! value ) } + // aria-label={ __( 'Select row' ) } + // /> + // ), + // enableSorting: false, + // enableHiding: false, + // } ), columnHelper.accessor( ( row ) => row.title?.rendered, { id: 'title', header: () => __( 'Title' ), @@ -231,11 +229,9 @@ export function getMediaThumbnail( attachment ) { if ( isBlobURL( attachment.url ) ) { return ( ); } @@ -245,9 +241,7 @@ export function getMediaThumbnail( attachment ) { if ( 'image' === mediaType ) { return ( { @@ -339,7 +333,7 @@ export default function PageMedia() { tags, dateFormatter, }, - enableMultiRowSelection: true, + enableMultiRowSelection: false, enableSorting: true, enableHiding: true, enableFilters: true, @@ -389,62 +383,68 @@ export default function PageMedia() { return ( uploadFiles( event.target.files ) } + > + { __( 'Upload new' ) } + + } > - - - - - { headingText[ mediaType ] } - - - uploadFiles( event.target.files ) - } - > - { __( 'Upload new' ) } - - - - - {} } - placeholder={ __( 'Search' ) } - __nextHasNoMarginBottom - /> - - - + + + + {} } + placeholder={ __( 'Search' ) } + __nextHasNoMarginBottom + /> + + + + + + + - - - - - - - { attachmentsOnPage && 'table' === currentView && ( -
  • Date: Sat, 19 Aug 2023 12:41:11 +1200 Subject: [PATCH 37/73] Get pagination styled --- .../src/components/page-media/index.js | 1 + .../src/components/page-media/style.scss | 23 +++++++++++++++++++ .../components/page-patterns/pagination.js | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index 6b48fce41f701..d8a156430525c 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -376,6 +376,7 @@ export default function PageMedia() { { numPages > 1 && ( { From 1e0317eb2f65525a5008fbbbf330bb3e1ae6356d Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Sat, 19 Aug 2023 13:59:52 +1200 Subject: [PATCH 38/73] Add TODO note for later --- packages/edit-site/src/components/table/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/edit-site/src/components/table/index.js b/packages/edit-site/src/components/table/index.js index 8e8fd2ec7ffdc..1886fa3f5b8fe 100644 --- a/packages/edit-site/src/components/table/index.js +++ b/packages/edit-site/src/components/table/index.js @@ -70,6 +70,7 @@ export default function Table( { table } ) {
    - ) } - { attachmentsOnPage && 'grid' === currentView && ( - - ) } - - + + + + + + + { attachmentsOnPage && 'table' === currentView && ( +
    + ) } + { attachmentsOnPage && 'grid' === currentView && ( + + ) } { numPages > 1 && ( +
    ) } - { attachmentsOnPage && 'grid' === currentView && ( - + { attachments && 'grid' === currentView && ( + row.original ) } + /> ) } - { numPages > 1 && ( + { table.getPageCount() > 1 && ( + table.setPageIndex( page - 1 ) + } + totalItems={ + table.getFilteredRowModel().rows.length + } /> ) } From 2a5462576f978449af15c823d6d927d11be0680a Mon Sep 17 00:00:00 2001 From: ramon Date: Sat, 19 Aug 2023 16:00:59 +1200 Subject: [PATCH 48/73] Using navigation routing for secondary level mediaTypes --- .../src/components/page-main/index.js | 2 +- .../src/components/page-media/grid-item.js | 10 +++++ .../src/components/page-media/index.js | 24 ++++++++++-- .../components/page-media/page-media-item.js | 34 ++++++++++++++++- .../sidebar-navigation-screen-main/index.js | 2 +- .../index.js | 5 ++- .../sidebar-navigation-screen-media/index.js | 38 ++++++++++++------- .../edit-site/src/components/sidebar/index.js | 4 +- .../use-sync-path-with-url.js | 23 ++++++++++- .../edit-site/src/utils/get-is-list-page.js | 1 + 10 files changed, 116 insertions(+), 27 deletions(-) diff --git a/packages/edit-site/src/components/page-main/index.js b/packages/edit-site/src/components/page-main/index.js index 48239a91b4ca9..5ed98015cda53 100644 --- a/packages/edit-site/src/components/page-main/index.js +++ b/packages/edit-site/src/components/page-main/index.js @@ -26,7 +26,7 @@ export default function PageMain() { return ; } else if ( path === '/patterns' ) { return ; - } else if ( path === '/media' && ! postId ) { + } else if ( path && path.startsWith( '/media' ) && ! postId ) { return ; } else if ( postType === 'attachment' && !! postId ) { return ; diff --git a/packages/edit-site/src/components/page-media/grid-item.js b/packages/edit-site/src/components/page-media/grid-item.js index c42edf6db9c45..ae260dd1a19ff 100644 --- a/packages/edit-site/src/components/page-media/grid-item.js +++ b/packages/edit-site/src/components/page-media/grid-item.js @@ -12,16 +12,26 @@ import { Flex, } from '@wordpress/components'; import { moreHorizontal } from '@wordpress/icons'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ import { getMediaThumbnail } from './'; import { useLink } from '../routes/link'; +import { unlock } from '../../lock-unlock'; + +const { useLocation } = unlock( routerPrivateApis ); function GridItem( { item } ) { + const { + params: { path }, + } = useLocation(); + + const mediaType = path.split( '/media/' )[ 1 ]; const linkProps = useLink( { postType: 'attachment', + mediaType, postId: item.id, } ); return ( diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index b2a512400e952..09c4acbeaed9a 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -15,7 +15,6 @@ import { import { __ } from '@wordpress/i18n'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore, useEntityRecord } from '@wordpress/core-data'; -import { getQueryArgs } from '@wordpress/url'; import { SearchControl, CheckboxControl, @@ -35,6 +34,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; import { uploadMedia } from '@wordpress/media-utils'; import { store as noticesStore } from '@wordpress/notices'; import { isBlobURL } from '@wordpress/blob'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies @@ -46,6 +46,9 @@ import Grid from './grid'; import Pagination from '../page-patterns/pagination'; import FilterControl from './filter-control'; import { useLink } from '../routes/link'; +import { unlock } from '../../lock-unlock'; + +const { useLocation } = unlock( routerPrivateApis ); /** * @typedef {Object} Attachment @@ -56,8 +59,14 @@ import { useLink } from '../routes/link'; const columnHelper = createColumnHelper(); function GridItemButton( { item } ) { + const { + params: { path }, + } = useLocation(); + + const mediaType = path.split( '/media/' )[ 1 ]; const linkProps = useLink( { postType: 'attachment', + mediaType, postId: item.id, } ); return ( @@ -176,7 +185,9 @@ export function getMediaTypeFromMimeType( mimeType ) { return 'audio'; } - return 'application'; + if ( mimeType.startsWith( 'application/' ) ) { + return 'application'; + } } // Getting headings, etc. based on `mediaType` query type. @@ -220,16 +231,21 @@ export function getMediaThumbnail( attachment ) { } export default function PageMedia() { - const { mediaType } = getQueryArgs( window.location.href ); + const { + params: { path }, + } = useLocation(); + + const mediaType = path.split( '/media/' )[ 1 ]; const { persistedAttachments, tags, locale } = useSelect( ( select ) => { + const _mediaType = mediaType === 'all' ? undefined : mediaType; const _attachments = select( coreStore ).getMediaItems( { per_page: -1, orderby: 'date', order: 'desc', // @todo `application` and `text` are valid media types, // but we should maybe combine them into `documents`. - media_type: mediaType, + media_type: _mediaType, } ); const _tags = select( coreStore ).getEntityRecords( 'taxonomy', diff --git a/packages/edit-site/src/components/page-media/page-media-item.js b/packages/edit-site/src/components/page-media/page-media-item.js index ce72665667d33..04929aa6c19ff 100644 --- a/packages/edit-site/src/components/page-media/page-media-item.js +++ b/packages/edit-site/src/components/page-media/page-media-item.js @@ -8,6 +8,7 @@ import { getQueryArgs } from '@wordpress/url'; import { __experimentalVStack as VStack, __experimentalSpacer as Spacer, + __experimentalHeading as Heading, } from '@wordpress/components'; /** @@ -15,8 +16,36 @@ import { */ import Page from '../page'; +function getMediaPreview( mediaType, record ) { + if ( mediaType === 'image' ) { + return {; + } + + if ( mediaType === 'audio' ) { + return ( +
    ) } - { attachments && 'grid' === currentView && ( + { attachments && 'grid' === view && ( Date: Sun, 20 Aug 2023 12:24:53 +1200 Subject: [PATCH 64/73] Add pagination to url --- .../src/components/page-media/index.js | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/edit-site/src/components/page-media/index.js b/packages/edit-site/src/components/page-media/index.js index ed9471097d4eb..81e2cf445e3bb 100644 --- a/packages/edit-site/src/components/page-media/index.js +++ b/packages/edit-site/src/components/page-media/index.js @@ -235,6 +235,7 @@ const columns = [ ]; const EMPTY_ARRAY = []; +const PAGE_SIZE = 20; const headingText = { media: __( 'Media' ), @@ -245,7 +246,7 @@ const headingText = { }; const parseQueryParamFilter = ( filter ) => - filter ? filter.split( ',' ).map( ( str ) => Number( str ) ) : []; + filter ? filter.split( ',' ).map( ( str ) => parseInt( str, 10 ) ) : []; export default function PageMedia() { const { params } = useLocation(); @@ -253,6 +254,7 @@ export default function PageMedia() { path, tags: tagsFilter = '', author: authorFilter = '', + p: pageIndex = 0, view = 'table', } = params; const history = useHistory(); @@ -307,6 +309,14 @@ export default function PageMedia() { ], [ tagsFilter, authorFilter ] ); + /** @type {import('@tanstack/react-table').PaginationState} */ + const pagination = useMemo( + () => ( { + pageIndex: parseInt( pageIndex, 10 ), + pageSize: PAGE_SIZE, + } ), + [ pageIndex ] + ); const [ globalFilter, setGlobalFilter ] = useState( '' ); const table = useReactTable( { @@ -317,12 +327,8 @@ export default function PageMedia() { getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), - initialState: { - pagination: { - pageSize: 20, - }, - }, state: { + pagination, columnFilters, globalFilter, }, @@ -338,6 +344,18 @@ export default function PageMedia() { } history.replace( newParams ); }, + onPaginationChange: ( paginationStateUpdater ) => { + const paginationState = paginationStateUpdater( pagination ); + if ( paginationState.pageIndex !== pagination.pageIndex ) { + history.push( { + ...params, + p: + paginationState.pageIndex > 0 + ? paginationState.pageIndex + : undefined, + } ); + } + }, meta: { tags, dateFormatter, From de0e4c68f84a28f6b7004b0586554c964e3cf747 Mon Sep 17 00:00:00 2001 From: ramon Date: Sun, 20 Aug 2023 17:40:27 +1200 Subject: [PATCH 65/73] Editing image. THis one is for Rob --- package-lock.json | 50 ++ package.json | 1 + packages/edit-site/package.json | 1 + .../src/components/page-media/get-media.js | 7 +- .../components/page-media/page-media-item.js | 210 ++++++- .../src/components/page-media/style.scss | 521 ++++++++++++++++++ .../index.js | 13 +- 7 files changed, 769 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f1dfbf81b97e..578cfb3e57a4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,6 +79,7 @@ "@wordpress/warning": "file:packages/warning", "@wordpress/widgets": "file:packages/widgets", "@wordpress/wordcount": "file:packages/wordcount", + "react-advanced-cropper": "0.19.3", "wicg-inert": "3.1.2" }, "devDependencies": { @@ -15614,6 +15615,18 @@ "node": ">=6.0" } }, + "node_modules/advanced-cropper": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/advanced-cropper/-/advanced-cropper-0.18.0.tgz", + "integrity": "sha512-Bo0fiW8F+kI4f8zEm8YXIDkGNi+aXaQPxqDijU7hY+1ETACbvFnNCxssspgAwHBy9RpFlcXMmjcq+LImUOhaqQ==", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -45730,6 +45743,23 @@ "node": ">=0.10.0" } }, + "node_modules/react-advanced-cropper": { + "version": "0.19.3", + "resolved": "https://registry.npmjs.org/react-advanced-cropper/-/react-advanced-cropper-0.19.3.tgz", + "integrity": "sha512-rC07DvUMidJgyD9sR1Clz9R3RtxgfrpjZN837awJFcnhlDjKs3arwUA6rfhJZ3jHuo9FmQfZ86xmDeNA1PBFKg==", + "dependencies": { + "advanced-cropper": "~0.18.0", + "classnames": "^2.2.6", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-autosize-textarea": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", @@ -55077,6 +55107,7 @@ "@tanstack/react-table": "^8.9.3", "@wordpress/a11y": "file:../a11y", "@wordpress/api-fetch": "file:../api-fetch", + "@wordpress/blob": "file:../blob", "@wordpress/block-editor": "file:../block-editor", "@wordpress/block-library": "file:../block-library", "@wordpress/blocks": "file:../blocks", @@ -67666,6 +67697,7 @@ "@tanstack/react-table": "^8.9.3", "@wordpress/a11y": "file:../a11y", "@wordpress/api-fetch": "file:../api-fetch", + "@wordpress/blob": "file:../blob", "@wordpress/block-editor": "file:../block-editor", "@wordpress/block-library": "file:../block-library", "@wordpress/blocks": "file:../blocks", @@ -68659,6 +68691,14 @@ "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", "dev": true }, + "advanced-cropper": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/advanced-cropper/-/advanced-cropper-0.18.0.tgz", + "integrity": "sha512-Bo0fiW8F+kI4f8zEm8YXIDkGNi+aXaQPxqDijU7hY+1ETACbvFnNCxssspgAwHBy9RpFlcXMmjcq+LImUOhaqQ==", + "requires": { + "tslib": "^2.4.0" + } + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -93363,6 +93403,16 @@ "loose-envify": "^1.1.0" } }, + "react-advanced-cropper": { + "version": "0.19.3", + "resolved": "https://registry.npmjs.org/react-advanced-cropper/-/react-advanced-cropper-0.19.3.tgz", + "integrity": "sha512-rC07DvUMidJgyD9sR1Clz9R3RtxgfrpjZN837awJFcnhlDjKs3arwUA6rfhJZ3jHuo9FmQfZ86xmDeNA1PBFKg==", + "requires": { + "advanced-cropper": "~0.18.0", + "classnames": "^2.2.6", + "tslib": "^2.4.0" + } + }, "react-autosize-textarea": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", diff --git a/package.json b/package.json index 4afc5e2d18ea3..7af3f14cf2d4c 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "@wordpress/warning": "file:packages/warning", "@wordpress/widgets": "file:packages/widgets", "@wordpress/wordcount": "file:packages/wordcount", + "react-advanced-cropper": "0.19.3", "wicg-inert": "3.1.2" }, "devDependencies": { diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index e4b1ed40390e8..6d3be0b1d7fe2 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -75,6 +75,7 @@ "fast-deep-equal": "^3.1.3", "is-plain-object": "^5.0.0", "memize": "^2.1.0", + "react-advanced-cropper": "0.19.3", "react-autosize-textarea": "^7.1.0", "rememo": "^4.0.2", "remove-accents": "^0.5.0" diff --git a/packages/edit-site/src/components/page-media/get-media.js b/packages/edit-site/src/components/page-media/get-media.js index 8e84d883f57e6..c64ba5edadede 100644 --- a/packages/edit-site/src/components/page-media/get-media.js +++ b/packages/edit-site/src/components/page-media/get-media.js @@ -24,7 +24,8 @@ export function getMediaItem( attachment, size = 'thumb' ) { const mediaType = getMediaTypeFromMimeType( attachment.mime_type ); if ( 'image' === mediaType ) { - return size === 'thumb' ? ( + return size === 'thumb' && + attachment.media_details?.sizes?.thumbnail?.source_url ? ( { diff --git a/packages/edit-site/src/components/page-media/page-media-item.js b/packages/edit-site/src/components/page-media/page-media-item.js index c9ede9b27dc48..e44422c40fc18 100644 --- a/packages/edit-site/src/components/page-media/page-media-item.js +++ b/packages/edit-site/src/components/page-media/page-media-item.js @@ -1,22 +1,203 @@ +/** + * External dependencies + */ +import { Cropper } from 'react-advanced-cropper'; + /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; -import { getQueryArgs } from '@wordpress/url'; +import { getQueryArgs, getFilename } from '@wordpress/url'; import { + __experimentalHStack as HStack, __experimentalVStack as VStack, __experimentalSpacer as Spacer, Icon, Tooltip, + Button, } from '@wordpress/components'; -import { page } from '@wordpress/icons'; +import { + page, + rotateLeft, + rotateRight, + flipHorizontal, + flipVertical, + lineSolid, + plus, +} from '@wordpress/icons'; +import { uploadMedia } from '@wordpress/media-utils'; +import { store as noticesStore } from '@wordpress/notices'; +import { useRef, useState } from '@wordpress/element'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ import Page from '../page'; +import { getMediaTypeFromMimeType } from '../page-media/get-media'; + +import { unlock } from '../../lock-unlock'; + +const { useLocation, useHistory } = unlock( routerPrivateApis ); + +function MediaEditor( { record } ) { + const { receiveEntityRecords } = useDispatch( coreStore ); + const { createErrorNotice } = useDispatch( noticesStore ); + const cropperRef = useRef( null ); + const [ flipValue, setFlipValue ] = useState( [ false, false ] ); + const [ image, setImage ] = useState( record ); + const [ isEditingImage, setIsEditingImage ] = useState( false ); + const history = useHistory(); + const { params: urlParams } = useLocation(); + + if ( ! isEditingImage ) { + return ( + <> + + { + + ); + } + + const flip = ( horizontal, vertical ) => { + if ( cropperRef.current ) { + cropperRef.current.flipImage( horizontal, vertical, { + transitions: true, + } ); + setFlipValue( [ horizontal, vertical ] ); + } + }; + + const rotate = ( angle ) => { + if ( cropperRef.current ) { + cropperRef.current.rotateImage( angle, { + transitions: true, + } ); + } + }; + + const zoom = ( value ) => { + if ( cropperRef.current ) { + cropperRef.current.zoomImage( value, { + transitions: true, + } ); + } + }; + + const reset = () => { + if ( cropperRef.current ) { + cropperRef.current.reset(); + setFlipValue( [ false, false ] ); + } + }; + + const uploadFiles = async ( files ) => { + await uploadMedia( { + filesList: files, + onFileChange: ( newFiles ) => { + const newMediaItems = newFiles.filter( ( file ) => !! file.id ); + if ( newMediaItems.length ) { + receiveEntityRecords( + 'root', + 'media', + newMediaItems, + undefined, + true + ); + setImage( newMediaItems[ 0 ] ); + const updatedParams = { + ...urlParams, + postId: newMediaItems[ 0 ].id, + }; + history.push( updatedParams ); + } + setIsEditingImage( false ); + }, + onError: ( error ) => { + createErrorNotice( error.message, { type: 'snackbar' } ); + }, + } ); + }; + + return ( + <> + + + + + + + ); +} function MediaPreview( { mediaType, record } ) { if ( mediaType === 'application' ) { @@ -34,7 +215,7 @@ function MediaPreview( { mediaType, record } ) { } if ( mediaType === 'image' ) { - return {; + return ; } if ( mediaType === 'audio' ) { @@ -59,27 +240,6 @@ function MediaPreview( { mediaType, record } ) { ); } } - -export function getMediaTypeFromMimeType( mimeType ) { - // @todo this needs to be abstracted and the - // media types formalized somewhere. - if ( mimeType.startsWith( 'image/' ) ) { - return 'image'; - } - - if ( mimeType.startsWith( 'video/' ) ) { - return 'video'; - } - - if ( mimeType.startsWith( 'audio/' ) ) { - return 'audio'; - } - - if ( mimeType.startsWith( 'application/' ) ) { - return 'application'; - } -} - export default function PageMediaItem() { const { postId } = getQueryArgs( window.location.href ); const { record } = useSelect( diff --git a/packages/edit-site/src/components/page-media/style.scss b/packages/edit-site/src/components/page-media/style.scss index 13b86d14cf854..9fd6b7069c3c8 100644 --- a/packages/edit-site/src/components/page-media/style.scss +++ b/packages/edit-site/src/components/page-media/style.scss @@ -106,3 +106,524 @@ align-items: center !important; height: 100%; } + +.advanced-cropper-line-wrapper--north, +.advanced-cropper-line-wrapper--south { + height: 12px; + width: 100%; +} + +.advanced-cropper-line-wrapper--north { + cursor: n-resize; +} + +.advanced-cropper-line-wrapper--south { + cursor: s-resize; +} + +.advanced-cropper-line-wrapper--east, +.advanced-cropper-line-wrapper--west { + width: 12px; + height: 100%; +} + +.advanced-cropper-line-wrapper--east { + cursor: e-resize; +} + +.advanced-cropper-line-wrapper--west { + cursor: w-resize; +} + +.advanced-cropper-line-wrapper--disabled { + cursor: auto; +} + +.advanced-cropper-line-wrapper__content { + position: absolute; +} +.advanced-cropper-line-wrapper__content--east, +.advanced-cropper-line-wrapper__content--west { + height: 100%; +} +.advanced-cropper-line-wrapper__content--north, +.advanced-cropper-line-wrapper__content--south { + width: 100%; +} +.advanced-cropper-line-wrapper__content--east { + left: 50%; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} +.advanced-cropper-line-wrapper__content--west { + right: 50%; + -webkit-transform: translateX(100%); + transform: translateX(100%); +} +.advanced-cropper-line-wrapper__content--north { + top: 50%; +} +.advanced-cropper-line-wrapper__content--south { + bottom: 50%; +} + +.advanced-cropper-handler-wrapper { + position: absolute; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + width: 30px; + height: 30px; +} +.advanced-cropper-handler-wrapper__draggable { + width: 100%; + height: 100%; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.advanced-cropper-handler-wrapper--west-north { + cursor: nw-resize; +} +.advanced-cropper-handler-wrapper--north { + cursor: n-resize; +} +.advanced-cropper-handler-wrapper--east-north { + cursor: ne-resize; +} +.advanced-cropper-handler-wrapper--east { + cursor: e-resize; +} +.advanced-cropper-handler-wrapper--east-south { + cursor: se-resize; +} +.advanced-cropper-handler-wrapper--south { + cursor: s-resize; +} +.advanced-cropper-handler-wrapper--west-south { + cursor: sw-resize; +} +.advanced-cropper-handler-wrapper--west { + cursor: w-resize; +} +.advanced-cropper-handler-wrapper--disabled { + cursor: auto; +} + +.advanced-cropper-bounding-box { + position: relative; + height: 100%; + width: 100%; +} +.advanced-cropper-bounding-box__handler-wrapper { + position: absolute; +} +.advanced-cropper-bounding-box__handler-wrapper--east, +.advanced-cropper-bounding-box__handler-wrapper--west { + top: 50%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + height: 100%; +} +.advanced-cropper-bounding-box__handler-wrapper--south, +.advanced-cropper-bounding-box__handler-wrapper--north { + left: 50%; + -webkit-transform: translateX(-50%); + transform: translateX(-50%); + width: 100%; +} +.advanced-cropper-bounding-box__handler-wrapper--west, +.advanced-cropper-bounding-box__handler-wrapper--west-north, +.advanced-cropper-bounding-box__handler-wrapper--west-south { + left: 0; +} +.advanced-cropper-bounding-box__handler-wrapper--east, +.advanced-cropper-bounding-box__handler-wrapper--east-north, +.advanced-cropper-bounding-box__handler-wrapper--east-south { + left: 100%; +} +.advanced-cropper-bounding-box__handler-wrapper--north, +.advanced-cropper-bounding-box__handler-wrapper--west-north, +.advanced-cropper-bounding-box__handler-wrapper--east-north { + top: 0; +} +.advanced-cropper-bounding-box__handler-wrapper--south, +.advanced-cropper-bounding-box__handler-wrapper--west-south, +.advanced-cropper-bounding-box__handler-wrapper--east-south { + top: 100%; +} +.advanced-cropper-bounding-box__handler { + position: absolute; +} +.advanced-cropper-bounding-box__handler--west-north { + left: 0; + top: 0; +} +.advanced-cropper-bounding-box__handler--north { + left: 50%; + top: 0; +} +.advanced-cropper-bounding-box__handler--east-north { + left: 100%; + top: 0; +} +.advanced-cropper-bounding-box__handler--east { + left: 100%; + top: 50%; +} +.advanced-cropper-bounding-box__handler--east-south { + left: 100%; + top: 100%; +} +.advanced-cropper-bounding-box__handler--south { + left: 50%; + top: 100%; +} +.advanced-cropper-bounding-box__handler--west-south { + left: 0; + top: 100%; +} +.advanced-cropper-bounding-box__handler--west { + left: 0; + top: 50%; +} +.advanced-cropper-bounding-box__line { + position: absolute; +} +.advanced-cropper-bounding-box__line--north, +.advanced-cropper-bounding-box__line--south { + left: 0; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.advanced-cropper-bounding-box__line--north { + top: 0; +} +.advanced-cropper-bounding-box__line--south { + top: 100%; +} +.advanced-cropper-bounding-box__line--west, +.advanced-cropper-bounding-box__line--east { + top: 0; + -webkit-transform: translateX(-50%); + transform: translateX(-50%); +} +.advanced-cropper-bounding-box__line--west { + left: 0; +} +.advanced-cropper-bounding-box__line--east { + left: 100%; +} + +.advanced-cropper-artificial-transition { + will-change: transform; +} + +.advanced-cropper-background-image { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + position: absolute; + -webkit-transform-origin: center; + transform-origin: center; + pointer-events: none; + max-width: none !important; +} + +.advanced-cropper-canvas { + display: none; +} + +.advanced-cropper-source { + width: 1px; + height: 1px; + visibility: hidden; + position: absolute; + opacity: 0; +} + +.advanced-cropper-fade { + visibility: hidden; + opacity: 0; + -webkit-transition: 0.5s; + transition: 0.5s; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.advanced-cropper-fade--visible { + opacity: 1; + visibility: visible; +} + +.advanced-cropper-wrapper__fade { + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + min-height: 0; +} + +.advanced-cropper-stencil-grid { + display: table; + border-collapse: collapse; + table-layout: fixed; + opacity: 0; + -webkit-transition: opacity 0.3s; + transition: opacity 0.3s; + color: rgba(255, 255, 255, 0.4); +} +.advanced-cropper-stencil-grid--visible { + opacity: 1; +} +.advanced-cropper-stencil-grid__row { + display: table-row; +} +.advanced-cropper-stencil-grid__cell { + display: table-cell; + width: 1%; + height: 1%; + border: currentColor solid 1px; +} +.advanced-cropper-stencil-grid__cell--top { + border-top-color: transparent; +} +.advanced-cropper-stencil-grid__cell--left { + border-left-color: transparent; +} +.advanced-cropper-stencil-grid__cell--right { + border-right-color: transparent; +} +.advanced-cropper-stencil-grid__cell--bottom { + border-bottom-color: transparent; +} + +.advanced-cropper-stencil-overlay { + -webkit-box-sizing: content-box; + box-sizing: content-box; + -webkit-box-shadow: 0 0 0 1000px currentColor; + box-shadow: 0 0 0 1000px currentColor; + pointer-events: none; + width: 100%; + height: 100%; + position: absolute; + -webkit-backface-visibility: hidden; + color: rgba(0, 0, 0, 0.5); +} + +.advanced-cropper-stencil-wrapper { + will-change: transform; +} + +.advanced-cropper-boundary { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + direction: ltr; + position: relative; +} +.advanced-cropper-boundary__content { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; +} +.advanced-cropper-boundary__stretcher { + pointer-events: none; + position: relative; + max-width: 100%; + max-height: 100%; +} + +.advanced-cropper-circle-stencil { + position: absolute; + height: 100%; + width: 100%; + -webkit-box-sizing: content-box; + box-sizing: content-box; + -webkit-backface-visibility: hidden; + -webkit-transform-style: preserve-3d; +} +.advanced-cropper-circle-stencil__overlay { + border-radius: 50%; + overflow: hidden; +} +.advanced-cropper-circle-stencil__preview { + border-radius: 50%; + border: solid 2px rgba(255, 255, 255, 0.2); +} +.advanced-cropper-circle-stencil__draggable-area, +.advanced-cropper-circle-stencil__overlay, +.advanced-cropper-circle-stencil__preview, +.advanced-cropper-circle-stencil__grid { + position: absolute; + height: 100%; + width: 100%; +} +.advanced-cropper-circle-stencil--movable { + cursor: move; +} + +.advanced-cropper-rectangle-stencil { + position: absolute; + height: 100%; + width: 100%; + -webkit-box-sizing: border-box; + box-sizing: border-box; + -webkit-backface-visibility: hidden; + -webkit-transform-style: preserve-3d; +} +.advanced-cropper-rectangle-stencil__draggable-area, +.advanced-cropper-rectangle-stencil__overlay, +.advanced-cropper-rectangle-stencil__preview, +.advanced-cropper-rectangle-stencil__grid { + position: absolute; + height: 100%; + width: 100%; +} +.advanced-cropper-rectangle-stencil--movable { + cursor: move; +} + +.advanced-cropper-simple-line { + background: none; + border-width: 0; + -webkit-transition: border 0.5s; + transition: border 0.5s; + border-color: rgba(255, 255, 255, 0.3); + border-style: solid; +} +.advanced-cropper-simple-line--south, +.advanced-cropper-simple-line--north { + height: 0; + width: 100%; +} +.advanced-cropper-simple-line--east, +.advanced-cropper-simple-line--west { + height: 100%; + width: 0; +} +.advanced-cropper-simple-line--east { + border-right-width: 1px; +} +.advanced-cropper-simple-line--west { + border-left-width: 1px; +} +.advanced-cropper-simple-line--south { + border-bottom-width: 1px; +} +.advanced-cropper-simple-line--north { + border-top-width: 1px; +} + +.advanced-cropper-simple-handler { + display: block; + background: currentColor; + height: 10px; + width: 10px; +} + +.advanced-cropper-preview { + overflow: hidden; + -webkit-box-sizing: border-box; + box-sizing: border-box; + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.advanced-cropper-preview__content { + overflow: hidden; + position: absolute; + left: 50%; + top: 50%; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} +.advanced-cropper-preview__image { + display: none; + pointer-events: none; + position: absolute; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-transform-origin: center; + transform-origin: center; + max-width: none !important; +} +.advanced-cropper-preview__image--visible { + display: block; +} +.advanced-cropper-preview__boundary { + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + min-height: 0; + min-width: 0; +} + +.cropper-preview-wrapper__fade { + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + min-height: 0; + width: 100%; +} + +.advanced-cropper { + overflow: hidden; + max-height: 100%; + background: $black; + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + color: $white; +} +.advanced-cropper__boundary { + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + min-height: 0; + min-width: 0; +} +.advanced-cropper__wrapper, +.advanced-cropper__background-wrapper { + left: 0; + top: 0; + right: 0; + bottom: 0; + position: absolute; +} +.advanced-cropper__stencil-wrapper { + position: absolute; +} +.advanced-cropper * { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.advanced-cropper-simple-line--hover { + border-color: $white; +} + diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js index 9b32267c9dbb2..95dc2b2194152 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js @@ -1,10 +1,7 @@ /** * WordPress dependencies */ -import { - Button, - __experimentalUseNavigator as useNavigator, -} from '@wordpress/components'; +import { Button } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { store as coreStore } from '@wordpress/core-data'; @@ -13,6 +10,7 @@ import { dateI18n, getDate, getSettings } from '@wordpress/date'; import { createInterpolateElement } from '@wordpress/element'; import { download, copy } from '@wordpress/icons'; import { useCopyToClipboard } from '@wordpress/compose'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies @@ -24,6 +22,10 @@ import { SidebarNavigationScreenDetailsPanelLabel, SidebarNavigationScreenDetailsPanelValue, } from '../sidebar-navigation-screen-details-panel'; +import { unlock } from '../../lock-unlock'; + +const { useLocation } = unlock( routerPrivateApis ); + function CopyButton( { text, onCopy = () => {}, children } ) { const ref = useCopyToClipboard( text, onCopy ); @@ -107,8 +109,7 @@ function getMediaDetails( record ) { } export default function SidebarNavigationScreenMediaItem() { - const { params } = useNavigator(); - const { postId, mediaType } = params; + const { params: { postId, mediaType } } = useLocation(); const { record } = useSelect( ( select ) => { const { getMedia } = select( coreStore ); From 0fa05f5a679c7885076e8ea57057930215533499 Mon Sep 17 00:00:00 2001 From: ramon Date: Tue, 22 Aug 2023 16:25:26 +1200 Subject: [PATCH 66/73] Tags in item view --- .../index.js | 90 +++++++++++++------ .../style.scss | 8 ++ 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js index 95dc2b2194152..3c36780142da0 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/index.js @@ -25,7 +25,8 @@ import { import { unlock } from '../../lock-unlock'; const { useLocation } = unlock( routerPrivateApis ); - +const EMPTY_ARRAY = []; +const EMPTY_OBJECT = {}; function CopyButton( { text, onCopy = () => {}, children } ) { const ref = useCopyToClipboard( text, onCopy ); @@ -41,8 +42,7 @@ function CopyButton( { text, onCopy = () => {}, children } ) { ); } - -function getMediaDetails( record ) { +function getMediaDetails( record, imageTags ) { if ( ! record ) { return []; } @@ -77,7 +77,7 @@ function getMediaDetails( record ) { } if ( record?.media_details ) { - const { width, height, filesize, file } = record.media_details; + const { width, height, filesize } = record.media_details; if ( width && height ) { details.push( { @@ -92,34 +92,64 @@ function getMediaDetails( record ) { value: `${ filesize / 1000 } kb`, } ); } - - if ( file ) { - details.push( { - label: __( 'Source' ), - value: ( - - { __( 'Copy source url' ) } - - ), - } ); - } + } + if ( imageTags && imageTags.length ) { + details.push( { + label: __( 'Tags' ), + value: ( + <> + { imageTags.map( ( tag ) => ( +
    + { tag?.name } +
    + ) ) } + + ), + } ); } + if ( record?.source_url ) { + details.push( { + label: __( 'Source' ), + value: ( + + { __( 'Copy source url' ) } + + ), + } ); + } return details; } export default function SidebarNavigationScreenMediaItem() { - const { params: { postId, mediaType } } = useLocation(); - const { record } = useSelect( + const { + params: { postId, mediaType }, + } = useLocation(); + const { record, tags } = useSelect( ( select ) => { const { getMedia } = select( coreStore ); + const _tags = select( coreStore ).getEntityRecords( + 'taxonomy', + 'attachment_tag', + { per_page: -1 } + ); return { - record: getMedia( postId ), + record: getMedia( postId ) || EMPTY_OBJECT, + tags: _tags || EMPTY_ARRAY, }; }, [ postId ] ); + const imageTags = record?.attachment_tags?.length + ? record?.attachment_tags.map( ( tagId ) => + tags.find( ( tag ) => tag.id === tagId ) + ) + : []; + // The absence of a media type in the query params for media // indicates the user has arrived at the template part via the "media" main // view and the back button should return them to that list page. @@ -136,16 +166,20 @@ export default function SidebarNavigationScreenMediaItem() { spacing={ 5 } title={ __( 'Details' ) } > - { getMediaDetails( record ).map( ( { label, value } ) => ( - - - { label } - - - { value } - - - ) ) } + { getMediaDetails( record, imageTags ).map( + ( { label, value } ) => ( + + + { label } + + + { value } + + + ) + ) } } footer={ diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss index 7352273dabac8..d1388580c4781 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss +++ b/packages/edit-site/src/components/sidebar-navigation-screen-media-item/style.scss @@ -7,3 +7,11 @@ box-shadow: none !important; padding: 0 !important; } + +.sidebar-navigation-screen-media-item__tag { + background: rgb(221, 221, 221); + padding: 0.1em 0.5em; + margin: 0.1em 0.1em 0; + color: $black; + display: inline-block; +} From b65f76c745926ac3f16fb8c4263ea6b4b72a32df Mon Sep 17 00:00:00 2001 From: ramon Date: Tue, 22 Aug 2023 16:28:50 +1200 Subject: [PATCH 67/73] mother flipper --- .../edit-site/src/components/page-media/page-media-item.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/edit-site/src/components/page-media/page-media-item.js b/packages/edit-site/src/components/page-media/page-media-item.js index e44422c40fc18..b35b249ddfd64 100644 --- a/packages/edit-site/src/components/page-media/page-media-item.js +++ b/packages/edit-site/src/components/page-media/page-media-item.js @@ -46,7 +46,6 @@ function MediaEditor( { record } ) { const { receiveEntityRecords } = useDispatch( coreStore ); const { createErrorNotice } = useDispatch( noticesStore ); const cropperRef = useRef( null ); - const [ flipValue, setFlipValue ] = useState( [ false, false ] ); const [ image, setImage ] = useState( record ); const [ isEditingImage, setIsEditingImage ] = useState( false ); const history = useHistory(); @@ -74,7 +73,6 @@ function MediaEditor( { record } ) { cropperRef.current.flipImage( horizontal, vertical, { transitions: true, } ); - setFlipValue( [ horizontal, vertical ] ); } }; @@ -97,7 +95,6 @@ function MediaEditor( { record } ) { const reset = () => { if ( cropperRef.current ) { cropperRef.current.reset(); - setFlipValue( [ false, false ] ); } }; @@ -148,13 +145,13 @@ function MediaEditor( { record } ) { icon={ flipVertical } variant="secondary" label={ __( 'Flip vertical' ) } - onClick={ () => flip( flipValue[ 0 ], ! flipValue[ 1 ] ) } + onClick={ () => flip( false, true ) } />
    +
    ) } { attachments && 'grid' === view && ( :is(td, th):first-child { +// width: 50%; +// } +// } +// } + .edit-site-media__grid { display: grid; grid-template-columns: 1fr; diff --git a/packages/edit-site/src/components/table/index.js b/packages/edit-site/src/components/table/index.js index 0959e3827b4a2..345a8f96ba51d 100644 --- a/packages/edit-site/src/components/table/index.js +++ b/packages/edit-site/src/components/table/index.js @@ -2,6 +2,7 @@ * External dependencies */ import { flexRender } from '@tanstack/react-table'; +import cx from 'classnames'; /** * WordPress dependencies @@ -51,17 +52,31 @@ function HeaderColumn( { header } ) { /** * @param {Object} props + * @param {string} props.className * @param {Table} props.table */ -export default function Table( { table } ) { +export default function Table( { table, className, ...props } ) { return ( -
    +
    { table.getHeaderGroups().map( ( headerGroup ) => ( { headerGroup.headers.map( ( header ) => ( - ) ) } @@ -80,6 +95,9 @@ export default function Table( { table } ) { { row.getVisibleCells().map( ( cell ) => (
    +