mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 18:08:11 +00:00 
			
		
		
		
	Delete old table
Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
		
							parent
							
								
									5a7dbe742a
								
							
						
					
					
						commit
						5611a8b0f8
					
				| @ -1,14 +0,0 @@ | |||||||
| import styled from 'styled-components'; |  | ||||||
| 
 |  | ||||||
| const Delete = styled.span` |  | ||||||
|   font-weight: 600; |  | ||||||
|   -webkit-font-smoothing: antialiased; |  | ||||||
|   &:after { |  | ||||||
|     content: '—'; |  | ||||||
|     margin: 0 7px; |  | ||||||
|     font-size: 13px; |  | ||||||
|     font-weight: 600; |  | ||||||
|   } |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| export default Delete; |  | ||||||
| @ -1,18 +0,0 @@ | |||||||
| import styled from 'styled-components'; |  | ||||||
| 
 |  | ||||||
| const DeleteAll = styled.span` |  | ||||||
|   position: absolute; |  | ||||||
|   color: #f64d0a; |  | ||||||
|   font-weight: 500; |  | ||||||
|   cursor: pointer; |  | ||||||
|   &:after { |  | ||||||
|     position: relative; |  | ||||||
|     top: -1px; |  | ||||||
|     content: '\f2ed'; |  | ||||||
|     margin-left: 7px; |  | ||||||
|     font-size: 10px; |  | ||||||
|     font-family: FontAwesome; |  | ||||||
|     -webkit-font-smoothing: antialiased; |  | ||||||
|   } |  | ||||||
| `;
 |  | ||||||
| export default DeleteAll; |  | ||||||
| @ -1,20 +0,0 @@ | |||||||
| import styled from 'styled-components'; |  | ||||||
| 
 |  | ||||||
| const Wrapper = styled.tr` |  | ||||||
|   width: 100%; |  | ||||||
|   height: 36px; |  | ||||||
|   background: #f7f8f8; |  | ||||||
| 
 |  | ||||||
|   td { |  | ||||||
|     height: 36px; |  | ||||||
|     line-height: 36px; |  | ||||||
|     font-size: 1.3rem; |  | ||||||
|     font-weight: 400; |  | ||||||
|     color: #333740; |  | ||||||
|     text-align: left; |  | ||||||
|     border-collapse: collapse; |  | ||||||
|     border-top: 1px solid #f1f1f2 !important; |  | ||||||
|   } |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| export default Wrapper; |  | ||||||
| @ -1,38 +0,0 @@ | |||||||
| import React, { memo } from 'react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { FormattedMessage } from 'react-intl'; |  | ||||||
| import { getTrad } from '../../../utils'; |  | ||||||
| import useListView from '../../../hooks/useListView'; |  | ||||||
| import DeleteAll from './DeleteAll'; |  | ||||||
| import Delete from './Delete'; |  | ||||||
| import Wrapper from './Wrapper'; |  | ||||||
| 
 |  | ||||||
| function ActionCollapse({ colSpan }) { |  | ||||||
|   const { data, entriesToDelete, toggleModalDeleteAll } = useListView(); |  | ||||||
| 
 |  | ||||||
|   const number = entriesToDelete.length; |  | ||||||
|   const suffix = number > 1 ? 'plural' : 'singular'; |  | ||||||
|   const deleteMessageId = number === data.length ? 'delete' : 'deleteSelected'; |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <Wrapper colSpan={colSpan}> |  | ||||||
|       <td colSpan={colSpan}> |  | ||||||
|         <FormattedMessage |  | ||||||
|           id={getTrad(`components.TableDelete.entries.${suffix}`)} |  | ||||||
|           values={{ number }} |  | ||||||
|         > |  | ||||||
|           {message => <Delete>{message}</Delete>} |  | ||||||
|         </FormattedMessage> |  | ||||||
|         <FormattedMessage id={getTrad(`components.TableDelete.${deleteMessageId}`)}> |  | ||||||
|           {message => <DeleteAll onClick={toggleModalDeleteAll}>{message}</DeleteAll>} |  | ||||||
|         </FormattedMessage> |  | ||||||
|       </td> |  | ||||||
|     </Wrapper> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ActionCollapse.propTypes = { |  | ||||||
|   colSpan: PropTypes.number.isRequired, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default memo(ActionCollapse); |  | ||||||
| @ -1,59 +0,0 @@ | |||||||
| import React, { memo } from 'react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { Carret, useTracking } from '@strapi/helper-plugin'; |  | ||||||
| import { useListView } from '../../../hooks'; |  | ||||||
| 
 |  | ||||||
| const Header = ({ fieldSchema: { type }, metadatas: { label, sortable, mainField }, name }) => { |  | ||||||
|   const { sort, firstSortableHeader, setQuery } = useListView(); |  | ||||||
|   const { trackUsage } = useTracking(); |  | ||||||
|   const [sortBy, sortOrder] = sort.split(':'); |  | ||||||
| 
 |  | ||||||
|   let sortField = name; |  | ||||||
|   let useRelation = false; |  | ||||||
| 
 |  | ||||||
|   if (type === 'relation') { |  | ||||||
|     useRelation = true; |  | ||||||
|     sortField = `${name}.${mainField.name}`; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   const handleClick = () => { |  | ||||||
|     if (sortable) { |  | ||||||
|       trackUsage('didSortEntries', { useRelation }); |  | ||||||
| 
 |  | ||||||
|       const isCurrentSort = sortField === sortBy; |  | ||||||
|       const nextOrder = isCurrentSort && sortOrder === 'ASC' ? 'DESC' : 'ASC'; |  | ||||||
|       let value = `${sortField}:${nextOrder}`; |  | ||||||
| 
 |  | ||||||
|       if (isCurrentSort && sortOrder === 'DESC') { |  | ||||||
|         value = `${firstSortableHeader}:ASC`; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       setQuery({ |  | ||||||
|         sort: value, |  | ||||||
|       }); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <th onClick={handleClick}> |  | ||||||
|       <span className={sortable ? 'sortable' : ''}> |  | ||||||
|         {label} |  | ||||||
|         {sortBy === sortField && <Carret fill="#212529" isUp={sortOrder === 'ASC' && 'isAsc'} />} |  | ||||||
|       </span> |  | ||||||
|     </th> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| Header.propTypes = { |  | ||||||
|   fieldSchema: PropTypes.shape({ |  | ||||||
|     type: PropTypes.string.isRequired, |  | ||||||
|   }).isRequired, |  | ||||||
|   metadatas: PropTypes.shape({ |  | ||||||
|     label: PropTypes.string.isRequired, |  | ||||||
|     sortable: PropTypes.bool.isRequired, |  | ||||||
|     mainField: PropTypes.object, |  | ||||||
|   }).isRequired, |  | ||||||
|   name: PropTypes.string.isRequired, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default memo(Header); |  | ||||||
| @ -1,35 +0,0 @@ | |||||||
| import styled, { css } from 'styled-components'; |  | ||||||
| 
 |  | ||||||
| /* eslint-disable consistent-return */ |  | ||||||
| 
 |  | ||||||
| const Thead = styled.thead` |  | ||||||
|   background: #f3f3f3; |  | ||||||
|   height: 43px; |  | ||||||
|   overflow: hidden; |  | ||||||
| 
 |  | ||||||
|   th { |  | ||||||
|     height: 43px; |  | ||||||
|     border: none !important; |  | ||||||
|     font-size: 1.3rem; |  | ||||||
|     vertical-align: middle !important; |  | ||||||
|     > span { |  | ||||||
|       position: relative; |  | ||||||
|       &.sortable { |  | ||||||
|         cursor: pointer; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   ${({ isBulkable }) => { |  | ||||||
|     if (isBulkable) { |  | ||||||
|       return css` |  | ||||||
|         > tr { |  | ||||||
|           th:first-child { |  | ||||||
|             width: 50px; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       `;
 |  | ||||||
|     } |  | ||||||
|   }} |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| export default Thead; |  | ||||||
| @ -1,46 +0,0 @@ | |||||||
| /* eslint-disable jsx-a11y/control-has-associated-label */ |  | ||||||
| import React, { memo } from 'react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { useListView } from '../../../hooks'; |  | ||||||
| import CustomInputCheckbox from '../../CustomInputCheckbox'; |  | ||||||
| import Thead from './Thead'; |  | ||||||
| import Header from './Header'; |  | ||||||
| 
 |  | ||||||
| function Headers({ headers, isBulkable }) { |  | ||||||
|   const { data, entriesToDelete, onChangeBulkSelectall } = useListView(); |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <Thead isBulkable={isBulkable}> |  | ||||||
|       <tr> |  | ||||||
|         {isBulkable && ( |  | ||||||
|           <th> |  | ||||||
|             <CustomInputCheckbox |  | ||||||
|               entriesToDelete={entriesToDelete} |  | ||||||
|               isAll |  | ||||||
|               name="all" |  | ||||||
|               onChange={onChangeBulkSelectall} |  | ||||||
|               value={data.length === entriesToDelete.length && entriesToDelete.length > 0} |  | ||||||
|             /> |  | ||||||
|           </th> |  | ||||||
|         )} |  | ||||||
|         {headers.map(({ key, name, fieldSchema, metadatas }) => { |  | ||||||
|           return <Header key={key} name={name} fieldSchema={fieldSchema} metadatas={metadatas} />; |  | ||||||
|         })} |  | ||||||
| 
 |  | ||||||
|         <th /> |  | ||||||
|       </tr> |  | ||||||
|     </Thead> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Headers.defaultProps = { |  | ||||||
|   isBulkable: true, |  | ||||||
|   headers: [], |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| Headers.propTypes = { |  | ||||||
|   headers: PropTypes.array, |  | ||||||
|   isBulkable: PropTypes.bool, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default memo(Headers); |  | ||||||
| @ -1,19 +0,0 @@ | |||||||
| import styled from 'styled-components'; |  | ||||||
| 
 |  | ||||||
| const ActionContainer = styled.td` |  | ||||||
|   text-align: right; |  | ||||||
| 
 |  | ||||||
|   i, |  | ||||||
|   svg { |  | ||||||
|     margin-left: 15px; |  | ||||||
|     font-size: 1rem; |  | ||||||
| 
 |  | ||||||
|     color: #333740; |  | ||||||
| 
 |  | ||||||
|     &:first-of-type { |  | ||||||
|       margin-left: 0px; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| export default ActionContainer; |  | ||||||
| @ -1,55 +0,0 @@ | |||||||
| import React, { memo, useState } from 'react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { Tooltip } from '@buffetjs/styles'; |  | ||||||
| import MediaPreviewList from '../../MediaPreviewList'; |  | ||||||
| import RelationPreviewList from '../../RelationPreviewList'; |  | ||||||
| import Truncate from '../../Truncate'; |  | ||||||
| import Truncated from '../../Truncated'; |  | ||||||
| 
 |  | ||||||
| const Cell = ({ options }) => { |  | ||||||
|   const [tooltipIsDisplayed, setDisplayTooltip] = useState(false); |  | ||||||
| 
 |  | ||||||
|   const handleTooltipToggle = () => { |  | ||||||
|     setDisplayTooltip(prev => !prev); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const { type, cellId, value } = options; |  | ||||||
| 
 |  | ||||||
|   if (type === 'media') { |  | ||||||
|     return <MediaPreviewList files={value} />; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if (type === 'relation') { |  | ||||||
|     return <RelationPreviewList options={options} />; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <Truncate onMouseEnter={handleTooltipToggle} onMouseLeave={handleTooltipToggle}> |  | ||||||
|       <Truncated> |  | ||||||
|         <span data-for={cellId} data-tip={value}> |  | ||||||
|           {value} |  | ||||||
|         </span> |  | ||||||
|       </Truncated> |  | ||||||
|       {tooltipIsDisplayed && <Tooltip id={cellId} />} |  | ||||||
|     </Truncate> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| Cell.propTypes = { |  | ||||||
|   options: PropTypes.shape({ |  | ||||||
|     cellId: PropTypes.string.isRequired, |  | ||||||
|     metadatas: PropTypes.shape({ |  | ||||||
|       mainField: PropTypes.object, |  | ||||||
|     }).isRequired, |  | ||||||
|     name: PropTypes.string.isRequired, |  | ||||||
|     relationType: PropTypes.string, |  | ||||||
|     rowId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, |  | ||||||
|     type: PropTypes.string, |  | ||||||
|     queryInfos: PropTypes.shape({ |  | ||||||
|       endPoint: PropTypes.string.isRequired, |  | ||||||
|     }), |  | ||||||
|     value: PropTypes.any, |  | ||||||
|   }).isRequired, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default memo(Cell); |  | ||||||
| @ -1,111 +0,0 @@ | |||||||
| import React, { memo, useCallback } from 'react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { toString } from 'lodash'; |  | ||||||
| import { useTracking } from '@strapi/helper-plugin'; |  | ||||||
| import { IconLinks } from '@buffetjs/core'; |  | ||||||
| import { Duplicate } from '@buffetjs/icons'; |  | ||||||
| import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |  | ||||||
| import { useListView } from '../../../hooks'; |  | ||||||
| import { getDisplayedValue } from '../../../utils'; |  | ||||||
| import CustomInputCheckbox from '../../CustomInputCheckbox'; |  | ||||||
| import ActionContainer from './ActionContainer'; |  | ||||||
| import Cell from './Cell'; |  | ||||||
| 
 |  | ||||||
| /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ |  | ||||||
| 
 |  | ||||||
| function Row({ canCreate, canDelete, canUpdate, isBulkable, row, headers, goTo }) { |  | ||||||
|   const { entriesToDelete, onChangeBulk, onClickDelete } = useListView(); |  | ||||||
|   const { trackUsage } = useTracking(); |  | ||||||
| 
 |  | ||||||
|   const memoizedDisplayedValue = useCallback( |  | ||||||
|     (name, type) => { |  | ||||||
|       return getDisplayedValue(type, row[name], name); |  | ||||||
|     }, |  | ||||||
|     [row] |  | ||||||
|   ); |  | ||||||
| 
 |  | ||||||
|   const links = [ |  | ||||||
|     { |  | ||||||
|       icon: canCreate ? <Duplicate fill="black" /> : null, |  | ||||||
|       onClick: e => { |  | ||||||
|         e.stopPropagation(); |  | ||||||
|         goTo(`create/clone/${row.id}`); |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       icon: canUpdate ? <FontAwesomeIcon icon="pencil-alt" /> : null, |  | ||||||
|       onClick: e => { |  | ||||||
|         e.stopPropagation(); |  | ||||||
|         trackUsage('willEditEntryFromList'); |  | ||||||
|         goTo(row.id); |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       icon: canDelete ? <FontAwesomeIcon icon="trash-alt" /> : null, |  | ||||||
|       onClick: e => { |  | ||||||
|         e.stopPropagation(); |  | ||||||
|         trackUsage('willDeleteEntryFromList'); |  | ||||||
|         onClickDelete(row.id); |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|   ].filter(icon => icon); |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <> |  | ||||||
|       {isBulkable && ( |  | ||||||
|         // eslint-disable-next-line jsx-a11y/click-events-have-key-events
 |  | ||||||
|         <td key="i" onClick={e => e.stopPropagation()}> |  | ||||||
|           <CustomInputCheckbox |  | ||||||
|             name={row.id} |  | ||||||
|             onChange={onChangeBulk} |  | ||||||
|             value={entriesToDelete.filter(id => toString(id) === toString(row.id)).length > 0} |  | ||||||
|           /> |  | ||||||
|         </td> |  | ||||||
|       )} |  | ||||||
|       {headers.map( |  | ||||||
|         ({ |  | ||||||
|           key, |  | ||||||
|           name, |  | ||||||
|           fieldSchema: { type, relationType }, |  | ||||||
|           cellFormatter, |  | ||||||
|           metadatas, |  | ||||||
|           queryInfos, |  | ||||||
|         }) => ( |  | ||||||
|           <td key={key}> |  | ||||||
|             {cellFormatter ? ( |  | ||||||
|               cellFormatter(row) |  | ||||||
|             ) : ( |  | ||||||
|               <Cell |  | ||||||
|                 options={{ |  | ||||||
|                   rowId: row.id, |  | ||||||
|                   relationType, |  | ||||||
|                   type, |  | ||||||
|                   name, |  | ||||||
|                   value: memoizedDisplayedValue(name, type), |  | ||||||
|                   cellId: key, |  | ||||||
|                   metadatas, |  | ||||||
|                   queryInfos, |  | ||||||
|                 }} |  | ||||||
|               /> |  | ||||||
|             )} |  | ||||||
|           </td> |  | ||||||
|         ) |  | ||||||
|       )} |  | ||||||
|       <ActionContainer> |  | ||||||
|         <IconLinks links={links} /> |  | ||||||
|       </ActionContainer> |  | ||||||
|     </> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Row.propTypes = { |  | ||||||
|   canCreate: PropTypes.bool.isRequired, |  | ||||||
|   canDelete: PropTypes.bool.isRequired, |  | ||||||
|   canUpdate: PropTypes.bool.isRequired, |  | ||||||
|   headers: PropTypes.array.isRequired, |  | ||||||
|   isBulkable: PropTypes.bool.isRequired, |  | ||||||
|   row: PropTypes.object.isRequired, |  | ||||||
|   goTo: PropTypes.func.isRequired, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default memo(Row); |  | ||||||
| @ -1,159 +0,0 @@ | |||||||
| import React, { memo, useMemo } from 'react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { useLocation, useHistory } from 'react-router-dom'; |  | ||||||
| import { FormattedMessage, useIntl } from 'react-intl'; |  | ||||||
| import { upperFirst, isEmpty } from 'lodash'; |  | ||||||
| import { LoadingIndicator, useTracking } from '@strapi/helper-plugin'; |  | ||||||
| import useListView from '../../hooks/useListView'; |  | ||||||
| import { getTrad } from '../../utils'; |  | ||||||
| import State from '../State'; |  | ||||||
| import { LoadingContainer, LoadingWrapper, Table, TableEmpty, TableRow } from './styledComponents'; |  | ||||||
| import ActionCollapse from './ActionCollapse'; |  | ||||||
| import Headers from './Headers'; |  | ||||||
| import Row from './Row'; |  | ||||||
| import { usePluginsQueryParams } from '../../hooks'; |  | ||||||
| 
 |  | ||||||
| const CustomTable = ({ |  | ||||||
|   canCreate, |  | ||||||
|   canUpdate, |  | ||||||
|   canDelete, |  | ||||||
|   data, |  | ||||||
|   displayedHeaders, |  | ||||||
|   hasDraftAndPublish, |  | ||||||
|   isBulkable, |  | ||||||
|   showLoader, |  | ||||||
| }) => { |  | ||||||
|   const { formatMessage } = useIntl(); |  | ||||||
|   const { entriesToDelete, label, filters, _q } = useListView(); |  | ||||||
|   const { trackUsage } = useTracking(); |  | ||||||
|   const { pathname } = useLocation(); |  | ||||||
|   const { push } = useHistory(); |  | ||||||
|   const pluginsQueryParams = usePluginsQueryParams(); |  | ||||||
| 
 |  | ||||||
|   const headers = useMemo(() => { |  | ||||||
|     if (hasDraftAndPublish) { |  | ||||||
|       return [ |  | ||||||
|         ...displayedHeaders, |  | ||||||
|         { |  | ||||||
|           key: '__published_at_temp_key__', |  | ||||||
|           name: 'published_at', |  | ||||||
|           fieldSchema: { |  | ||||||
|             type: 'custom', |  | ||||||
|           }, |  | ||||||
|           metadatas: { |  | ||||||
|             label: formatMessage({ id: getTrad('containers.ListPage.table-headers.published_at') }), |  | ||||||
|             searchable: false, |  | ||||||
|             sortable: true, |  | ||||||
|           }, |  | ||||||
|           cellFormatter: cellData => { |  | ||||||
|             const isPublished = !isEmpty(cellData.published_at); |  | ||||||
| 
 |  | ||||||
|             return <State isPublished={isPublished} />; |  | ||||||
|           }, |  | ||||||
|         }, |  | ||||||
|       ]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return displayedHeaders; |  | ||||||
|   }, [formatMessage, hasDraftAndPublish, displayedHeaders]); |  | ||||||
| 
 |  | ||||||
|   const colSpanLength = isBulkable && canDelete ? headers.length + 2 : headers.length + 1; |  | ||||||
| 
 |  | ||||||
|   const handleRowGoTo = id => { |  | ||||||
|     trackUsage('willEditEntryFromList'); |  | ||||||
|     push({ |  | ||||||
|       pathname: `${pathname}/${id}`, |  | ||||||
|       state: { from: pathname }, |  | ||||||
|       search: pluginsQueryParams, |  | ||||||
|     }); |  | ||||||
|   }; |  | ||||||
|   const handleEditGoTo = id => { |  | ||||||
|     trackUsage('willEditEntryFromButton'); |  | ||||||
|     push({ |  | ||||||
|       pathname: `${pathname}/${id}`, |  | ||||||
|       state: { from: pathname }, |  | ||||||
|       search: pluginsQueryParams, |  | ||||||
|     }); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   const values = { contentType: upperFirst(label), search: _q }; |  | ||||||
|   let tableEmptyMsgId = filters.length > 0 ? 'withFilters' : 'withoutFilter'; |  | ||||||
| 
 |  | ||||||
|   if (_q !== '') { |  | ||||||
|     tableEmptyMsgId = 'withSearch'; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   const content = |  | ||||||
|     data.length === 0 ? ( |  | ||||||
|       <TableEmpty> |  | ||||||
|         <td colSpan={colSpanLength}> |  | ||||||
|           <FormattedMessage |  | ||||||
|             id={`content-manager.components.TableEmpty.${tableEmptyMsgId}`} |  | ||||||
|             values={values} |  | ||||||
|           /> |  | ||||||
|         </td> |  | ||||||
|       </TableEmpty> |  | ||||||
|     ) : ( |  | ||||||
|       data.map(row => { |  | ||||||
|         return ( |  | ||||||
|           <TableRow |  | ||||||
|             key={row.id} |  | ||||||
|             onClick={e => { |  | ||||||
|               e.preventDefault(); |  | ||||||
|               e.stopPropagation(); |  | ||||||
| 
 |  | ||||||
|               handleRowGoTo(row.id); |  | ||||||
|             }} |  | ||||||
|           > |  | ||||||
|             <Row |  | ||||||
|               canCreate={canCreate} |  | ||||||
|               canDelete={canDelete} |  | ||||||
|               canUpdate={canUpdate} |  | ||||||
|               isBulkable={isBulkable && canDelete} |  | ||||||
|               headers={headers} |  | ||||||
|               row={row} |  | ||||||
|               goTo={handleEditGoTo} |  | ||||||
|             /> |  | ||||||
|           </TableRow> |  | ||||||
|         ); |  | ||||||
|       }) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|   if (showLoader) { |  | ||||||
|     return ( |  | ||||||
|       <> |  | ||||||
|         <Table className="table"> |  | ||||||
|           <Headers headers={headers} isBulkable={isBulkable && canDelete} /> |  | ||||||
|         </Table> |  | ||||||
|         <LoadingWrapper> |  | ||||||
|           <LoadingContainer> |  | ||||||
|             <LoadingIndicator /> |  | ||||||
|           </LoadingContainer> |  | ||||||
|         </LoadingWrapper> |  | ||||||
|       </> |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   return ( |  | ||||||
|     <Table className="table"> |  | ||||||
|       <Headers headers={headers} isBulkable={isBulkable && canDelete} /> |  | ||||||
|       <tbody> |  | ||||||
|         {entriesToDelete.length > 0 && <ActionCollapse colSpan={colSpanLength} />} |  | ||||||
|         {content} |  | ||||||
|       </tbody> |  | ||||||
|     </Table> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| CustomTable.propTypes = { |  | ||||||
|   canCreate: PropTypes.bool.isRequired, |  | ||||||
|   canDelete: PropTypes.bool.isRequired, |  | ||||||
|   canUpdate: PropTypes.bool.isRequired, |  | ||||||
|   data: PropTypes.array.isRequired, |  | ||||||
|   displayedHeaders: PropTypes.array.isRequired, |  | ||||||
|   hasDraftAndPublish: PropTypes.bool.isRequired, |  | ||||||
|   isBulkable: PropTypes.bool.isRequired, |  | ||||||
|   showLoader: PropTypes.bool.isRequired, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default memo(CustomTable); |  | ||||||
| @ -1,85 +0,0 @@ | |||||||
| import styled from 'styled-components'; |  | ||||||
| import { themePropTypes } from '@strapi/helper-plugin'; |  | ||||||
| 
 |  | ||||||
| const Table = styled.table` |  | ||||||
|   border-radius: 3px; |  | ||||||
|   border-collapse: initial; |  | ||||||
|   box-shadow: 0 2px 4px #e3e9f3; |  | ||||||
|   table-layout: fixed; |  | ||||||
|   margin-bottom: 0; |  | ||||||
| 
 |  | ||||||
|   tr, |  | ||||||
|   th, |  | ||||||
|   td { |  | ||||||
|     border: none; |  | ||||||
|     padding: 0; |  | ||||||
|     white-space: nowrap; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   th, |  | ||||||
|   td { |  | ||||||
|     padding: 0 25px; |  | ||||||
| 
 |  | ||||||
|     label { |  | ||||||
|       display: inline; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| const TableEmpty = styled.tr` |  | ||||||
|   width: 100%; |  | ||||||
|   height: 108px; |  | ||||||
|   background: #ffffff; |  | ||||||
| 
 |  | ||||||
|   td { |  | ||||||
|     height: 106px; |  | ||||||
|     line-height: 90px; |  | ||||||
|     font-size: 1.3rem; |  | ||||||
|     font-weight: 400; |  | ||||||
|     color: #333740; |  | ||||||
|     text-align: center; |  | ||||||
|     border-collapse: collapse; |  | ||||||
|     border-top: 1px solid #f1f1f2 !important; |  | ||||||
|   } |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| const TableRow = styled.tr` |  | ||||||
|   height: 54px; |  | ||||||
|   background: #ffffff; |  | ||||||
| 
 |  | ||||||
|   &:hover { |  | ||||||
|     cursor: pointer; |  | ||||||
|     background: #f7f8f8; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   td { |  | ||||||
|     height: 53px; |  | ||||||
|     font-size: 1.3rem; |  | ||||||
|     line-height: 1.8rem; |  | ||||||
|     font-weight: 400; |  | ||||||
|     color: #333740; |  | ||||||
|     vertical-align: middle; |  | ||||||
|     border-collapse: collapse; |  | ||||||
|     border-top: 1px solid #f1f1f2 !important; |  | ||||||
|   } |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| const LoadingContainer = styled.div` |  | ||||||
|   display: block; |  | ||||||
|   margin: auto; |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| const LoadingWrapper = styled.div` |  | ||||||
|   width: 100%; |  | ||||||
|   height: 108px; |  | ||||||
|   display: flex; |  | ||||||
|   background: ${props => props.theme.main.colors.white}; |  | ||||||
|   box-shadow: 0 2px 4px ${props => props.theme.main.colors.darkGrey}; |  | ||||||
|   clip-path: inset(0px -5px -5px -5px); |  | ||||||
| `;
 |  | ||||||
| 
 |  | ||||||
| LoadingWrapper.propTypes = { |  | ||||||
|   ...themePropTypes, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export { LoadingContainer, LoadingWrapper, Table, TableEmpty, TableRow }; |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 soupette
						soupette