From b603fe7c198f78af7d41da5deb3006bae8c58f1e Mon Sep 17 00:00:00 2001 From: Felipe Carlos Date: Tue, 16 Apr 2024 08:45:22 -0300 Subject: [PATCH 1/5] fields: removing pricing field --- .../fields/MarketplacePricingPlansField.js | 125 ------------------ .../MarketplacePricingPlansField.stories.js | 35 ----- .../MarketplacePricingPlansField.test.js | 31 ----- src/lib/components/form/base/fields/index.js | 2 - 4 files changed, 193 deletions(-) delete mode 100644 src/lib/components/form/base/fields/MarketplacePricingPlansField.js delete mode 100644 src/lib/components/form/base/fields/MarketplacePricingPlansField.stories.js delete mode 100644 src/lib/components/form/base/fields/MarketplacePricingPlansField.test.js diff --git a/src/lib/components/form/base/fields/MarketplacePricingPlansField.js b/src/lib/components/form/base/fields/MarketplacePricingPlansField.js deleted file mode 100644 index 87eaa4c..0000000 --- a/src/lib/components/form/base/fields/MarketplacePricingPlansField.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022-2024 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -import React, { Component } from "react"; -import PropTypes from "prop-types"; - -import { - TextField, - GroupField, - ArrayField, - FieldLabel, -} from "react-invenio-forms"; -import { Button, Form, Icon } from "semantic-ui-react"; - -import { i18next } from '@translations/i18next'; - -/** - * Empty Pricing plan model - */ -const emptyMarketplacePricingPlans = { - "title": "", - "description": "", - "url": "", - "value": "" -} - -/** - * Pricing plan component - */ -export class MarketplacePricingPlansField extends Component { - render() { - const { fieldPath, label, labelIcon, required, showEmptyValue } = - this.props; - - return ( - <> - } - required={required} - showEmptyValue={showEmptyValue} - > - {({ arrayHelpers, indexPath }) => { - const fieldPathPrefix = `${fieldPath}.${indexPath}`; - - return ( -
- - - - - - - - - - - - - -
- ); - }} -
- - - ); - } -} - -MarketplacePricingPlansField.propTypes = { - fieldPath: PropTypes.string.isRequired, - label: PropTypes.string, - labelIcon: PropTypes.string, - required: PropTypes.bool, - showEmptyValue: PropTypes.bool, -}; - -MarketplacePricingPlansField.defaultProps = { - fieldPath: 'metadata.marketplace.pricing', - label: i18next.t('Pricing plans'), - labelIcon: 'money bill alternate outline', - required: false, - showEmptyValue: true, -}; diff --git a/src/lib/components/form/base/fields/MarketplacePricingPlansField.stories.js b/src/lib/components/form/base/fields/MarketplacePricingPlansField.stories.js deleted file mode 100644 index b0a653b..0000000 --- a/src/lib/components/form/base/fields/MarketplacePricingPlansField.stories.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -import React from 'react'; - -import { Formik } from 'formik'; - -import { MarketplacePricingPlansField as MarketplacePricingPlansComponent } from './MarketplacePricingPlansField'; - -export default { - title: 'Form/Fields/Marketplace Pricing Plans', - component: MarketplacePricingPlansComponent, -}; - -/** - * Component template - */ -const Template = (args) => ( - <> - - - - -); - -/** - * Component stories - */ -export const Base = Template.bind({}); -Base.args = {}; diff --git a/src/lib/components/form/base/fields/MarketplacePricingPlansField.test.js b/src/lib/components/form/base/fields/MarketplacePricingPlansField.test.js deleted file mode 100644 index 1974bc1..0000000 --- a/src/lib/components/form/base/fields/MarketplacePricingPlansField.test.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -import React from 'react'; - -import { MarketplacePricingPlansField } from './MarketplacePricingPlansField'; -import { renderWithFormikProvider } from '@tests/renders'; - -describe('MarketplacePricingPlansField tests', () => { - describe('Render tests', () => { - it('should render without crashing', () => { - renderWithFormikProvider(); - }); - it('renders without crashing with all props', () => { - renderWithFormikProvider( - - ); - }); - }); -}); diff --git a/src/lib/components/form/base/fields/index.js b/src/lib/components/form/base/fields/index.js index e0b57bc..23035ae 100644 --- a/src/lib/components/form/base/fields/index.js +++ b/src/lib/components/form/base/fields/index.js @@ -16,5 +16,3 @@ export { WorkProgrammeActivityField } from './WorkProgrammeActivityField'; export { ResourceTypeField } from './ResourceTypeField'; export { AuthorsField } from './AuthorsField'; - -export { MarketplacePricingPlansField } from './MarketplacePricingPlansField'; From bba49f8b674f42f505539a406e9e93cc904156f3 Mon Sep 17 00:00:00 2001 From: Felipe Carlos Date: Tue, 16 Apr 2024 08:45:36 -0300 Subject: [PATCH 2/5] table: removing pricing table --- .../PricingPlansTable/PricingPlansTable.css | 11 - .../PricingPlansTable/PricingPlansTable.js | 192 ------------------ .../PricingPlansTable.stories.js | 31 --- .../PricingPlansTable.test.js | 23 --- .../table/thematic/PricingPlansTable/index.js | 9 - 5 files changed, 266 deletions(-) delete mode 100644 src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.css delete mode 100644 src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.js delete mode 100644 src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.stories.js delete mode 100644 src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.test.js delete mode 100644 src/lib/components/table/thematic/PricingPlansTable/index.js diff --git a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.css b/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.css deleted file mode 100644 index 1c9bb81..0000000 --- a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.css +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022-2024 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -.table-marketplace-pricing-plans .ui.container .grid p { - overflow-wrap: break-word; -} diff --git a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.js b/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.js deleted file mode 100644 index 63a1667..0000000 --- a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.js +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022-2024 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -import React, { useMemo } from 'react'; -import { PaginableTable } from '../../moldure'; - -import _get from 'lodash/get'; -import _isNil from 'lodash/isNil'; -import _truncate from 'lodash/truncate'; - -import regeneratorRuntime from 'regenerator-runtime'; -import { useAsyncDebounce } from 'react-table'; - -import { Grid, Button, Icon, Input, Header, Label } from 'semantic-ui-react'; - -import './PricingPlansTable.css'; - - -/** - * Global filter component for the external resources table. - */ -function GlobalFilter({ - preGlobalFilteredRows, - globalFilter, - setGlobalFilter, -}) { - const count = preGlobalFilteredRows.length; - const [value, setValue] = React.useState(globalFilter); - const onChange = useAsyncDebounce((value) => { - setGlobalFilter(value || undefined); - }, 200); - - return ( - { - setValue(e.target.value); - onChange(e.target.value); - }} - > - - - - ); -} - -/** - * Pricing Plans table for marketplace. - */ -export const PricingPlansTable = ({ tableData, tableConfig }) => { - const tableColumnsDefinition = useMemo(() => { - return [ - // Defining invisible columns that are used as the index for the - // table filter - { - Header: () => null, - id: 'idx_title', - accessor: 'title', - }, - { - Header: () => null, - id: 'idx_description', - accessor: 'description', - }, - { - Header: () => null, - id: 'idx_url', - accessor: 'url', - }, - { - Header: () => null, - id: 'idx_value', - accessor: 'value', - }, - // Content column - { - Header: () => null, - id: 'external-resources-table', - Cell: ({ row }) => { - // Getting data - const { original: rowData } = row; - - // Preparing data - // Title - const rowTitle = _get(rowData, 'title'); - - // Description - const rowDescription = _get(rowData, 'description'); - - // URL - const rowUrl = _get(rowData, 'url'); - - // Value - const rowValue = _get(rowData, 'value'); - - return ( - - - - - - -
{rowTitle}
-
-
- - -

- {rowDescription} -

-
-
-
-
- - - -
-
- ); - }, - }, - ]; - }); - - const tableDataMemoized = useMemo(() => tableData); - - return ( -
- ( - - )} - showHeader={false} - {...tableConfig} - /> -
- ); -}; diff --git a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.stories.js b/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.stories.js deleted file mode 100644 index e533c39..0000000 --- a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.stories.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -import React from 'react'; - -import { PricingPlansTable as PricingPlansTableComponent } from './PricingPlansTable'; - -import tableDataPricingPlans from '../../../../../mocks/table/table-pricing-plans.json'; - -export default { - title: 'Table/Thematic/Pricing Plans Table', - component: PricingPlansTableComponent, -}; - -/** - * Component template - */ -const Template = (args) => ; - -/** - * Component stories - */ -export const Base = Template.bind({}); -Base.args = { - tableData: tableDataPricingPlans, -}; diff --git a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.test.js b/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.test.js deleted file mode 100644 index 15ca7ac..0000000 --- a/src/lib/components/table/thematic/PricingPlansTable/PricingPlansTable.test.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -import React from 'react'; - -import { PricingPlansTable } from './PricingPlansTable'; - -import { render } from '../../../../../setupTestRenders'; - -import tableDataPricingPlans from '../../../../../mocks/table/table-pricing-plans.json'; - -describe('PricingPlansTable tests', () => { - describe('Render tests', () => { - it('should render with the required props without crashing', () => { - render(); - }); - }); -}); diff --git a/src/lib/components/table/thematic/PricingPlansTable/index.js b/src/lib/components/table/thematic/PricingPlansTable/index.js deleted file mode 100644 index 30ad9af..0000000 --- a/src/lib/components/table/thematic/PricingPlansTable/index.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - * This file is part of GEO-Components-React. - * Copyright (C) 2022 GEO Secretariat. - * - * GEO-Components-React is free software; you can redistribute it and/or modify it - * under the terms of the MIT License; see LICENSE file for more details. - */ - -export { PricingPlansTable } from './PricingPlansTable'; From 40cfd46eb0fecc407cec3c7fc842822d4a9295c2 Mon Sep 17 00:00:00 2001 From: Felipe Carlos Date: Tue, 16 Apr 2024 08:46:02 -0300 Subject: [PATCH 3/5] table: improving mobile experience --- src/lib/components/table/base/BaseTable.js | 7 +- .../table/moldure/PaginableTable.js | 12 ++- .../ExternalResourceTable.css | 8 ++ .../ExternalResourceTable.js | 69 +++++++++------- .../thematic/ExternalResourceTable/youtube.js | 82 +++++++++++-------- .../ExternalResourceTable/youtube.test.js | 4 +- .../thematic/RecordsTable/RecordsTable.css | 4 + .../thematic/RecordsTable/RecordsTable.js | 32 +++++--- .../RelatedResourceTable.js | 4 +- .../results/RecordList/RecordListItem.js | 30 +++---- .../UserStoriesTable/UserStoriesTable.js | 2 +- src/lib/components/table/thematic/index.js | 2 - 12 files changed, 151 insertions(+), 105 deletions(-) diff --git a/src/lib/components/table/base/BaseTable.js b/src/lib/components/table/base/BaseTable.js index 3c0abae..513b6d3 100644 --- a/src/lib/components/table/base/BaseTable.js +++ b/src/lib/components/table/base/BaseTable.js @@ -28,7 +28,6 @@ export const BaseTable = ({ }) => { return ( - {showHeader && ( @@ -42,7 +41,9 @@ export const BaseTable = ({ : null } {...column.getHeaderProps( - column.getSortByToggleProps ? column.getSortByToggleProps() : {} + column.getSortByToggleProps + ? column.getSortByToggleProps() + : {} )} > {column.render('Header')} @@ -91,5 +92,5 @@ BaseTable.propTypes = { }; BaseTable.defaultProps = { - showHeader: true + showHeader: true, }; diff --git a/src/lib/components/table/moldure/PaginableTable.js b/src/lib/components/table/moldure/PaginableTable.js index d6be2af..656d88b 100644 --- a/src/lib/components/table/moldure/PaginableTable.js +++ b/src/lib/components/table/moldure/PaginableTable.js @@ -48,12 +48,16 @@ export const PaginableTable = ({ state: { pageSize, globalFilter }, preGlobalFilteredRows, setGlobalFilter, - visibleColumns + visibleColumns, } = useTable( { columns: columnsConfiguration, data: data, - initialState: { pageIndex: 0, pageSize: pageSizeSorted[0], ...initialState }, + initialState: { + pageIndex: 0, + pageSize: pageSizeSorted[0], + ...initialState, + }, }, useGlobalFilter, useSortBy, @@ -76,7 +80,7 @@ export const PaginableTable = ({ } return ( - + <> )} - + ); }; diff --git a/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.css b/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.css index 7b71514..a1c7387 100644 --- a/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.css +++ b/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.css @@ -9,3 +9,11 @@ .table-external-resources .ui.container .grid p { overflow-wrap: break-word; } + +.table-external-resources .ui.grid .row .column.pt-0 { + padding-top: 0 !important; +} + +.table-external-resources .ui.grid .row .column.pt-1 { + padding-top: 1px !important; +} diff --git a/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.js b/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.js index f738797..0c65152 100644 --- a/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.js +++ b/src/lib/components/table/thematic/ExternalResourceTable/ExternalResourceTable.js @@ -21,7 +21,6 @@ import { Grid, Button, Icon, Input, Header, Label } from 'semantic-ui-react'; import './ExternalResourceTable.css'; - /** * Global filter component for the external resources table. */ @@ -118,12 +117,18 @@ export const ExternalResourceTable = ({ tableData, tableConfig }) => { widescreen={13} largeScreen={13} computer={13} - tablet={13} - mobile={12} + tablet={16} + mobile={16} >
- {rowRelationType && } - {rowResourceType && } + {rowRelationType && ( + + )} + {rowResourceType && ( + + )}
@@ -145,13 +150,10 @@ export const ExternalResourceTable = ({ tableData, tableConfig }) => { widescreen={3} largeScreen={3} computer={3} - tablet={3} - only={'computer tablet'} + only={'computer'} > - {rowIsYoutubeVideo && ( - - )} + {rowIsYoutubeVideo && } - - + + + - - {rowIsYoutubeVideo && ( - - )} - - + {rowIsYoutubeVideo && ( + + + + )} + + icon={'external alternate'} + /> - + + icon={'copy outline'} + /> diff --git a/src/lib/components/table/thematic/ExternalResourceTable/youtube.js b/src/lib/components/table/thematic/ExternalResourceTable/youtube.js index ca2febc..0bce4b4 100644 --- a/src/lib/components/table/thematic/ExternalResourceTable/youtube.js +++ b/src/lib/components/table/thematic/ExternalResourceTable/youtube.js @@ -7,10 +7,18 @@ */ import React, { useState } from 'react'; -import { Modal, ModalHeader, Button, Icon, Embed, Container } from 'semantic-ui-react'; +import _isEmpty from 'lodash/isEmpty'; -import './youtube.css'; +import { + Modal, + ModalHeader, + Button, + Icon, + Embed, + Container, +} from 'semantic-ui-react'; +import './youtube.css'; /** * Get Video ID from a YouTube URL @@ -18,7 +26,8 @@ import './youtube.css'; * @returns {*|null} */ export const getYouTubeVideoIdFromUrl = (url) => { - const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; + const regExp = + /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; const match = url.match(regExp); if (match && match[2].length === 11) { @@ -26,20 +35,19 @@ export const getYouTubeVideoIdFromUrl = (url) => { } else { return null; } -} - +}; /** * Check if a given URL is from YouTube. * @param url {string} URL to be verified. * @returns {boolean} Flag indicating if the given link is from YouTube. */ -export const isUrlFromYouTube = (url) => { +export const isUrlFromYouTube = (url) => { // Regular expression to match YouTube URL patterns - const youtubePattern = /^(https?:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)/; + const youtubePattern = + /^(https?:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)/; return youtubePattern.test(url); -} - +}; /** * YouTube video viewer component. @@ -53,58 +61,64 @@ const YouTubeVideo = ({ videoId }) => { placeholder={`https://img.youtube.com/vi/${videoId}/0.jpg`} source="youtube" iframe={{ - "allowfullscreen": "allowfullscreen" + allowfullscreen: 'allowfullscreen', }} hd={true} - className={"youtube-embed"} + className={'youtube-embed'} /> - - ) -} - + ); +}; /** * YouTube viewer component. * @param url {string} YouTube video URL. + * @param buttonProps {object} Button UI properties. */ -export const YouTubeViewer = ({ url }) => { +export const YouTubeViewer = ({ url, ...buttonProps }) => { const [open, setOpen] = useState(false); // Extracting video id const videoId = getYouTubeVideoIdFromUrl(url); + // Define trigger button + const isUsingCustomProps = !_isEmpty(buttonProps); + + const triggerBasic = + ); + + const triggerButton = isUsingCustomProps + ? triggerBasic + : triggerWithAnimation; + return ( setOpen(false)} onOpen={() => setOpen(true)} open={open} - trigger={( - - )} - size={"large"} - dimmer={"blurring"} + trigger={triggerButton} + size={'large'} + dimmer={'blurring'} closeIcon closeOnEscape closeOnDimmerClick={false} > Youtube viewer - + {videoId ? ( - + ) : (

Invalid YouTube link

)}
- ) -} + ); +}; diff --git a/src/lib/components/table/thematic/ExternalResourceTable/youtube.test.js b/src/lib/components/table/thematic/ExternalResourceTable/youtube.test.js index 1aa02d4..9ea0e74 100644 --- a/src/lib/components/table/thematic/ExternalResourceTable/youtube.test.js +++ b/src/lib/components/table/thematic/ExternalResourceTable/youtube.test.js @@ -15,7 +15,9 @@ import { render } from '../../../../../setupTestRenders'; describe('YouTube Viewer tests', () => { describe('Render tests', () => { it('should render with the required props without crashing', () => { - render(); + render( + + ); }); }); }); diff --git a/src/lib/components/table/thematic/RecordsTable/RecordsTable.css b/src/lib/components/table/thematic/RecordsTable/RecordsTable.css index 96bc2c2..8e0c5a9 100644 --- a/src/lib/components/table/thematic/RecordsTable/RecordsTable.css +++ b/src/lib/components/table/thematic/RecordsTable/RecordsTable.css @@ -9,3 +9,7 @@ .table-records .ui.container .grid p { overflow-wrap: break-word; } + +.table-records .pt-0 { + padding-top: 0 !important; +} diff --git a/src/lib/components/table/thematic/RecordsTable/RecordsTable.js b/src/lib/components/table/thematic/RecordsTable/RecordsTable.js index 3edafea..327579d 100644 --- a/src/lib/components/table/thematic/RecordsTable/RecordsTable.js +++ b/src/lib/components/table/thematic/RecordsTable/RecordsTable.js @@ -19,7 +19,6 @@ import { Grid, Button, Icon, Input, Header, Label } from 'semantic-ui-react'; import './RecordsTable.css'; import { mutateRecordData } from '../../../list/base/mutations'; - /** * Table of Records component. */ @@ -74,8 +73,8 @@ export const RecordsTable = ({ tableData, tableConfig }) => { widescreen={13} largeScreen={13} computer={13} - tablet={13} - mobile={12} + tablet={16} + mobile={16} >