mirror of
https://github.com/strapi/strapi.git
synced 2025-09-08 16:16:21 +00:00
WIP Desgin rows
This commit is contained in:
parent
fab2a6f46b
commit
fbd22b8c33
@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Box } from '@strapi/parts';
|
||||
import {
|
||||
Component,
|
||||
CT,
|
||||
Date,
|
||||
Bool,
|
||||
DynamicZone,
|
||||
Email,
|
||||
Enumeration,
|
||||
Json,
|
||||
LongDescription,
|
||||
Media,
|
||||
Numbers,
|
||||
Password,
|
||||
Relation,
|
||||
St,
|
||||
Text,
|
||||
Uid,
|
||||
} from '@strapi/icons';
|
||||
import { pxToRem } from '@strapi/helper-plugin';
|
||||
|
||||
const types = {
|
||||
biginteger: Numbers,
|
||||
boolean: Bool,
|
||||
component: Component,
|
||||
contentType: CT,
|
||||
date: Date,
|
||||
datetime: Date,
|
||||
decimal: Numbers,
|
||||
dynamiczone: DynamicZone,
|
||||
email: Email,
|
||||
enum: Enumeration,
|
||||
enumeration: Enumeration,
|
||||
file: Media,
|
||||
files: Media,
|
||||
float: Numbers,
|
||||
integer: Numbers,
|
||||
json: Json,
|
||||
JSON: Json,
|
||||
media: Media,
|
||||
number: Numbers,
|
||||
password: Password,
|
||||
relation: Relation,
|
||||
richtext: LongDescription,
|
||||
singleType: St,
|
||||
string: Text,
|
||||
text: Text,
|
||||
time: Date,
|
||||
timestamp: Date,
|
||||
uid: Uid,
|
||||
};
|
||||
|
||||
const StyledCompo = styled(Box)`
|
||||
width: ${pxToRem(32)};
|
||||
height: ${pxToRem(24)};
|
||||
box-sizing: content-box;
|
||||
`;
|
||||
|
||||
const AttributeIcon = ({ type, ...rest }) => {
|
||||
const Compo = types[type];
|
||||
|
||||
if (!types[type]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <StyledCompo as={Compo} {...rest} />;
|
||||
};
|
||||
|
||||
AttributeIcon.propTypes = {
|
||||
type: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default AttributeIcon;
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
* Wrapper
|
||||
*
|
||||
*/
|
||||
import { Box } from '@strapi/parts';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const BoxWrapper = styled(Box)`
|
||||
overflow-x: auto;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
thead {
|
||||
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
|
||||
|
||||
& td,
|
||||
& th {
|
||||
padding: ${({ theme }) => theme.spaces[4]};
|
||||
}
|
||||
|
||||
& td:first-of-type,
|
||||
& th:first-of-type {
|
||||
padding: 0 ${({ theme }) => theme.spaces[1]};
|
||||
}
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
vertical-align: middle;
|
||||
text-align: left;
|
||||
color: ${({ theme }) => theme.colors.neutral600};
|
||||
outline-offset: -4px;
|
||||
}
|
||||
`;
|
||||
|
||||
BoxWrapper.defaultProps = {
|
||||
isFromDynamicZone: false,
|
||||
};
|
||||
|
||||
export default BoxWrapper;
|
@ -1,131 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Wrapper
|
||||
*
|
||||
*/
|
||||
|
||||
import styled from 'styled-components';
|
||||
import { List } from '@buffetjs/styles';
|
||||
|
||||
const Wrapper = styled(List)`
|
||||
table-layout: fixed;
|
||||
|
||||
tbody {
|
||||
td:first-of-type:not(:last-of-type) {
|
||||
width: 73px;
|
||||
padding-left: 30px;
|
||||
> svg {
|
||||
width: auto;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: 16px;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
td[colspan='12'] {
|
||||
position: relative;
|
||||
padding: 0 0 0 50px;
|
||||
> div {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
tr.component-row {
|
||||
&:not(:first-of-type) {
|
||||
&::before {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
table tr td:first-of-type:not(:last-of-type) {
|
||||
width: 79px;
|
||||
padding-left: 36px;
|
||||
svg {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
table + div button {
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
text-transform: initial;
|
||||
color: #9ea7b8;
|
||||
text-align: left;
|
||||
padding-left: 35px;
|
||||
border-color: transparent;
|
||||
svg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
tr.dynamiczone-row {
|
||||
&:not(:first-of-type) {
|
||||
&::before {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
> td[colspan='12'] {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.tabs-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
padding-top: 18px;
|
||||
padding-left: 86px;
|
||||
padding-right: 30px;
|
||||
.nav-tabs {
|
||||
border-bottom: 0;
|
||||
}
|
||||
ul.nav {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
li {
|
||||
margin-right: 9px;
|
||||
}
|
||||
}
|
||||
& + .tab-content {
|
||||
padding-top: 126px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
& + .plus-icon {
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
border-radius: 18px;
|
||||
position: absolute;
|
||||
bottom: 14px;
|
||||
left: 34px;
|
||||
background-color: ${({ isFromDynamicZone }) => (isFromDynamicZone ? '#AED4FB' : '#f3f4f4')};
|
||||
|
||||
color: transparent;
|
||||
text-align: center;
|
||||
line-height: 27px;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
svg {
|
||||
margin: auto;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
Wrapper.defaultProps = {
|
||||
isFromDynamicZone: false,
|
||||
};
|
||||
|
||||
export default Wrapper;
|
@ -9,6 +9,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get } from 'lodash';
|
||||
import { ListButton, useTracking } from '@strapi/helper-plugin';
|
||||
import { TableLabel } from '@strapi/parts';
|
||||
import { Button } from '@buffetjs/core';
|
||||
import { Plus } from '@buffetjs/icons';
|
||||
import { useIntl } from 'react-intl';
|
||||
@ -17,13 +18,12 @@ import useListView from '../../hooks/useListView';
|
||||
import useDataManager from '../../hooks/useDataManager';
|
||||
import DynamicZoneList from '../DynamicZoneList';
|
||||
import ComponentList from '../ComponentList';
|
||||
import Wrapper from './List';
|
||||
import BoxWrapper from './BoxWrapper';
|
||||
|
||||
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||
|
||||
function List({
|
||||
className,
|
||||
customRowComponent,
|
||||
items,
|
||||
addComponentToDZ,
|
||||
@ -186,8 +186,25 @@ function List({
|
||||
|
||||
return (
|
||||
<>
|
||||
<Wrapper className={className} isFromDynamicZone={isFromDynamicZone}>
|
||||
<BoxWrapper
|
||||
isFromDynamicZone={isFromDynamicZone}
|
||||
background="neutral0"
|
||||
shadow="filterShadow"
|
||||
hasRadius
|
||||
paddingLeft={6}
|
||||
paddingRight={6}
|
||||
>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colSpan="2">
|
||||
<TableLabel textColor="neutral600">Name</TableLabel>
|
||||
</th>
|
||||
<th colSpan="2">
|
||||
<TableLabel textColor="neutral600">Type</TableLabel>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map(item => {
|
||||
const { type } = item;
|
||||
@ -247,7 +264,7 @@ function List({
|
||||
<Button {...addButtonProps} />
|
||||
</ListButton>
|
||||
)}
|
||||
</Wrapper>
|
||||
</BoxWrapper>
|
||||
{isSub && (
|
||||
<div className="plus-icon" onClick={onClickAddField}>
|
||||
{isInDevelopmentMode && <Plus fill={isFromDynamicZone ? '#007EFF' : '#b4b6ba'} />}
|
||||
@ -259,7 +276,6 @@ function List({
|
||||
|
||||
List.defaultProps = {
|
||||
addComponentToDZ: () => {},
|
||||
className: null,
|
||||
customRowComponent: null,
|
||||
dzName: null,
|
||||
firstLoopComponentName: null,
|
||||
@ -276,7 +292,6 @@ List.defaultProps = {
|
||||
|
||||
List.propTypes = {
|
||||
addComponentToDZ: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
customRowComponent: PropTypes.func,
|
||||
dzName: PropTypes.string,
|
||||
editTarget: PropTypes.string.isRequired,
|
||||
|
@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
* Wrapper
|
||||
*
|
||||
*/
|
||||
|
||||
import styled from 'styled-components';
|
||||
import { Box } from '@strapi/parts';
|
||||
|
||||
const BoxWrapper = styled(Box)``;
|
||||
|
||||
export default BoxWrapper;
|
@ -1,76 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Wrapper
|
||||
*
|
||||
*/
|
||||
|
||||
import styled from 'styled-components';
|
||||
import { colors } from '@strapi/helper-plugin';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
const Wrapper = styled.tr`
|
||||
background-color: transparent;
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
img {
|
||||
width: 35px;
|
||||
}
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
td:first-of-type {
|
||||
padding-left: 3rem;
|
||||
position: relative;
|
||||
img {
|
||||
width: 35px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
top: calc(50% - 10px);
|
||||
left: 3rem;
|
||||
}
|
||||
img + p {
|
||||
width: 237px;
|
||||
padding-left: calc(3rem + 35px);
|
||||
}
|
||||
}
|
||||
td:nth-child(2) {
|
||||
${({ loopNumber }) => {
|
||||
return `
|
||||
width: calc(25rem - ${5 * loopNumber}rem);
|
||||
`;
|
||||
}}
|
||||
p {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
td:last-child {
|
||||
text-align: right;
|
||||
&:not(:first-of-type) {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
&.relation-row {
|
||||
background: linear-gradient(135deg, rgba(28, 93, 231, 0.05), rgba(239, 243, 253, 0));
|
||||
}
|
||||
&.clickable {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: ${colors.grey};
|
||||
& + tr {
|
||||
&::before {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.button-container {
|
||||
svg {
|
||||
color: #333740;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
@ -2,15 +2,16 @@ import React, { memo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { AttributeIcon, IconLinks } from '@buffetjs/core';
|
||||
import { IconLinks } from '@buffetjs/core';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import pluginId from '../../pluginId';
|
||||
import useDataManager from '../../hooks/useDataManager';
|
||||
import getAttributeDisplayedType from '../../utils/getAttributeDisplayedType';
|
||||
import getTrad from '../../utils/getTrad';
|
||||
import Curve from '../../icons/Curve';
|
||||
// import Curve from '../../icons/Curve';
|
||||
import UpperFist from '../UpperFirst';
|
||||
import Wrapper from './Wrapper';
|
||||
import BoxWrapper from './BoxWrapper';
|
||||
import AttributeIcon from '../AttributeIcon';
|
||||
|
||||
function ListRow({
|
||||
configurable,
|
||||
@ -198,14 +199,15 @@ function ListRow({
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
<BoxWrapper
|
||||
as="tr"
|
||||
onClick={handleClick}
|
||||
className={[target ? 'relation-row' : '', configurable ? 'clickable' : '']}
|
||||
loopNumber={loopNumber}
|
||||
>
|
||||
<td>
|
||||
<AttributeIcon key={src} type={src} />
|
||||
<Curve fill={isFromDynamicZone ? '#AED4FB' : '#f3f4f4'} />
|
||||
<AttributeIcon paddingLeft={2} key={src} type={src} />
|
||||
{/* <Curve fill={isFromDynamicZone ? '#AED4FB' : '#f3f4f4'} /> */}
|
||||
</td>
|
||||
<td style={{ fontWeight: 600 }}>
|
||||
<p>{name}</p>
|
||||
@ -288,7 +290,7 @@ function ListRow({
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
</Wrapper>
|
||||
</BoxWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTracking } from '@strapi/helper-plugin';
|
||||
import { AddIcon, BackIcon, CheckIcon, EditIcon } from '@strapi/icons';
|
||||
import { Box, Button, ContentLayout, HeaderLayout, Link, Row, Stack } from '@strapi/parts';
|
||||
import { Button, ContentLayout, HeaderLayout, Link, Row, Stack } from '@strapi/parts';
|
||||
import { get, has, isEqual, upperFirst } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Prompt, useHistory, useLocation } from 'react-router-dom';
|
||||
import List from '../../components/List';
|
||||
@ -202,20 +201,6 @@ const ListView = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const CustomRow = props => {
|
||||
const { name } = props;
|
||||
|
||||
return <ListRow {...props} attributeName={name} name={name} onClick={handleClickEditField} />;
|
||||
};
|
||||
|
||||
CustomRow.defaultProps = {
|
||||
name: null,
|
||||
};
|
||||
|
||||
CustomRow.propTypes = {
|
||||
name: PropTypes.string,
|
||||
};
|
||||
|
||||
return (
|
||||
<ListViewContext.Provider value={{ openModalAddField: handleClickAddField }}>
|
||||
<>
|
||||
@ -302,19 +287,17 @@ const ListView = () => {
|
||||
</Button>
|
||||
</Stack>
|
||||
</Row>
|
||||
<Box background="neutral0" padding={6} shadow="filterShadow" hasRadius>
|
||||
<List
|
||||
items={attributes}
|
||||
customRowComponent={props => <CustomRow {...props} />}
|
||||
addComponentToDZ={handleClickAddComponentToDZ}
|
||||
targetUid={targetUid}
|
||||
dataType={forTarget}
|
||||
dataTypeName={currentDataName}
|
||||
mainTypeName={currentDataName}
|
||||
editTarget={forTarget}
|
||||
isMain
|
||||
/>
|
||||
</Box>
|
||||
<List
|
||||
items={attributes}
|
||||
customRowComponent={props => <ListRow {...props} onClick={handleClickEditField} />}
|
||||
addComponentToDZ={handleClickAddComponentToDZ}
|
||||
targetUid={targetUid}
|
||||
dataType={forTarget}
|
||||
dataTypeName={currentDataName}
|
||||
mainTypeName={currentDataName}
|
||||
editTarget={forTarget}
|
||||
isMain
|
||||
/>
|
||||
</Stack>
|
||||
</ContentLayout>
|
||||
</>
|
||||
|
Loading…
x
Reference in New Issue
Block a user