builds Add Upload modal
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
&__toggle-columns,
|
||||
&__toggle-where {
|
||||
margin: 0 0 0 $baseline;
|
||||
min-width: 150px;
|
||||
min-width: 140px;
|
||||
|
||||
&.btn--style-primary {
|
||||
svg {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
@import '../../../scss/styles.scss';
|
||||
|
||||
.status-list {
|
||||
position: relative;
|
||||
z-index: $z-status;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
img, svg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ const UploadCard = (props) => {
|
||||
onClick={typeof onClick === 'function' ? onClick : undefined}
|
||||
>
|
||||
<Thumbnail
|
||||
size="large"
|
||||
size="expand"
|
||||
{...{
|
||||
mimeType, adminThumbnail, sizes, staticURL, filename,
|
||||
}}
|
||||
|
||||
@@ -3,10 +3,30 @@
|
||||
.upload-gallery {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: base(2) 0;
|
||||
margin: base(2) -#{base(.5)};
|
||||
width: calc(100% + #{$baseline});
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
min-width: 0;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.upload-card {
|
||||
margin-right: base(.5);
|
||||
margin: base(.5);
|
||||
max-width: initial;
|
||||
}
|
||||
|
||||
@include large-break {
|
||||
li {
|
||||
width: 33.33%;
|
||||
}
|
||||
}
|
||||
|
||||
@include mid-break {
|
||||
li {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ const Form = (props) => {
|
||||
}, [fields]);
|
||||
|
||||
const submit = useCallback((e) => {
|
||||
e.stopPropagation();
|
||||
setSubmitted(true);
|
||||
|
||||
const isValid = validateForm();
|
||||
|
||||
@@ -26,7 +26,6 @@ const HiddenInput = (props) => {
|
||||
type="hidden"
|
||||
value={value || ''}
|
||||
onChange={setValue}
|
||||
id={path}
|
||||
name={path}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,44 +1,93 @@
|
||||
import React from 'react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Modal, useModal } from '@trbl/react-modal';
|
||||
import config from '../../../../../config';
|
||||
import MinimalTemplate from '../../../../templates/Minimal';
|
||||
import Form from '../../../Form';
|
||||
import Button from '../../../../elements/Button';
|
||||
import formatFields from '../../../../views/collections/Edit/formatFields';
|
||||
import RenderFields from '../../../RenderFields';
|
||||
import FormSubmit from '../../../Submit';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const { serverURL, routes: { api } } = config;
|
||||
|
||||
const baseClass = 'add-upload-modal';
|
||||
|
||||
const AddExistingUploadModal = (props) => {
|
||||
const { closeAll, toggle } = useModal();
|
||||
|
||||
const AddUploadModal = (props) => {
|
||||
const {
|
||||
collection,
|
||||
slug,
|
||||
fieldTypes,
|
||||
setValue,
|
||||
} = props;
|
||||
|
||||
const { closeAll } = useModal();
|
||||
const [fields, setFields] = useState([]);
|
||||
|
||||
const onSuccess = useCallback((json) => {
|
||||
closeAll();
|
||||
setValue(json.doc);
|
||||
}, [closeAll, setValue]);
|
||||
|
||||
const classes = [
|
||||
baseClass,
|
||||
].filter(Boolean).join(' ');
|
||||
|
||||
useEffect(() => {
|
||||
setFields(formatFields(collection, false));
|
||||
}, [collection]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className={classes}
|
||||
slug={slug}
|
||||
>
|
||||
<div>
|
||||
Upload new
|
||||
{' '}
|
||||
{collection.labels.singular}
|
||||
</div>
|
||||
<MinimalTemplate width="wide">
|
||||
<Form
|
||||
method="post"
|
||||
action={`${serverURL}${api}/${collection.slug}`}
|
||||
onSuccess={onSuccess}
|
||||
disableSuccessStatus
|
||||
>
|
||||
<header className={`${baseClass}__header`}>
|
||||
<h1>
|
||||
New
|
||||
{' '}
|
||||
{collection.labels.singular}
|
||||
</h1>
|
||||
<FormSubmit>Save</FormSubmit>
|
||||
<Button
|
||||
icon="x"
|
||||
round
|
||||
buttonStyle="icon-label"
|
||||
iconStyle="with-border"
|
||||
onClick={closeAll}
|
||||
/>
|
||||
</header>
|
||||
<RenderFields
|
||||
filter={field => (!field.position || (field.position && field.position !== 'sidebar'))}
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={fields}
|
||||
customComponentsPath={`${collection.slug}.fields.`}
|
||||
/>
|
||||
</Form>
|
||||
</MinimalTemplate>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
AddExistingUploadModal.propTypes = {
|
||||
AddUploadModal.propTypes = {
|
||||
setValue: PropTypes.func.isRequired,
|
||||
collection: PropTypes.shape({
|
||||
labels: PropTypes.shape({
|
||||
singular: PropTypes.string,
|
||||
}),
|
||||
slug: PropTypes.string,
|
||||
}).isRequired,
|
||||
slug: PropTypes.string.isRequired,
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
};
|
||||
|
||||
export default AddExistingUploadModal;
|
||||
export default AddUploadModal;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
@import '../../../../../scss/styles.scss';
|
||||
|
||||
.add-upload-modal {
|
||||
@include blur-bg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
.template-minimal {
|
||||
padding-top: base(6);
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
margin-bottom: $baseline;
|
||||
|
||||
h1 {
|
||||
margin: 0 auto 0 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin: 0 0 0 $baseline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
|
||||
import { Modal, useModal } from '@trbl/react-modal';
|
||||
import config from '../../../../../config';
|
||||
import MinimalTemplate from '../../../../templates/Minimal';
|
||||
import Form from '../../../Form';
|
||||
import Button from '../../../../elements/Button';
|
||||
import formatFields from '../../../../views/collections/List/formatFields';
|
||||
import usePayloadAPI from '../../../../../hooks/usePayloadAPI';
|
||||
@@ -59,63 +58,61 @@ const SelectExistingUploadModal = (props) => {
|
||||
slug={modalSlug}
|
||||
>
|
||||
<MinimalTemplate width="wide">
|
||||
<Form>
|
||||
<header className={`${baseClass}__header`}>
|
||||
<h1>
|
||||
{' '}
|
||||
Select existing
|
||||
{' '}
|
||||
{collection.labels.singular}
|
||||
</h1>
|
||||
<Button
|
||||
icon="x"
|
||||
round
|
||||
buttonStyle="icon-label"
|
||||
iconStyle="with-border"
|
||||
onClick={closeAll}
|
||||
/>
|
||||
</header>
|
||||
<ListControls
|
||||
handleChange={setListControls}
|
||||
collection={{
|
||||
...collection,
|
||||
fields,
|
||||
}}
|
||||
<header className={`${baseClass}__header`}>
|
||||
<h1>
|
||||
{' '}
|
||||
Select existing
|
||||
{' '}
|
||||
{collection.labels.singular}
|
||||
</h1>
|
||||
<Button
|
||||
icon="x"
|
||||
round
|
||||
buttonStyle="icon-label"
|
||||
iconStyle="with-border"
|
||||
onClick={closeAll}
|
||||
/>
|
||||
<UploadGallery
|
||||
docs={data?.docs}
|
||||
collection={collection}
|
||||
onCardClick={(doc) => {
|
||||
setValue(doc);
|
||||
closeAll();
|
||||
}}
|
||||
</header>
|
||||
<ListControls
|
||||
handleChange={setListControls}
|
||||
collection={{
|
||||
...collection,
|
||||
fields,
|
||||
}}
|
||||
/>
|
||||
<UploadGallery
|
||||
docs={data?.docs}
|
||||
collection={collection}
|
||||
onCardClick={(doc) => {
|
||||
setValue(doc);
|
||||
closeAll();
|
||||
}}
|
||||
/>
|
||||
<div className={`${baseClass}__page-controls`}>
|
||||
<Paginator
|
||||
limit={data.limit}
|
||||
totalPages={data.totalPages}
|
||||
page={data.page}
|
||||
hasPrevPage={data.hasPrevPage}
|
||||
hasNextPage={data.hasNextPage}
|
||||
prevPage={data.prevPage}
|
||||
nextPage={data.nextPage}
|
||||
numberOfNeighbors={1}
|
||||
onChange={setPage}
|
||||
disableHistoryChange
|
||||
/>
|
||||
<div className={`${baseClass}__page-controls`}>
|
||||
<Paginator
|
||||
limit={data.limit}
|
||||
totalPages={data.totalPages}
|
||||
page={data.page}
|
||||
hasPrevPage={data.hasPrevPage}
|
||||
hasNextPage={data.hasNextPage}
|
||||
prevPage={data.prevPage}
|
||||
nextPage={data.nextPage}
|
||||
numberOfNeighbors={1}
|
||||
onChange={setPage}
|
||||
disableHistoryChange
|
||||
/>
|
||||
{data?.totalDocs > 0 && (
|
||||
<div className={`${baseClass}__page-info`}>
|
||||
{data.page}
|
||||
-
|
||||
{data.totalPages > 1 ? data.limit : data.totalDocs}
|
||||
{' '}
|
||||
of
|
||||
{' '}
|
||||
{data.totalDocs}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
{data?.totalDocs > 0 && (
|
||||
<div className={`${baseClass}__page-info`}>
|
||||
{data.page}
|
||||
-
|
||||
{data.totalPages > 1 ? data.limit : data.totalDocs}
|
||||
{' '}
|
||||
of
|
||||
{' '}
|
||||
{data.totalDocs}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</MinimalTemplate>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -34,6 +34,7 @@ const Upload = (props) => {
|
||||
readOnly,
|
||||
validate,
|
||||
relationTo,
|
||||
fieldTypes,
|
||||
} = props;
|
||||
|
||||
const collection = collections.find(coll => coll.slug === relationTo);
|
||||
@@ -124,6 +125,7 @@ const Upload = (props) => {
|
||||
<AddModal {...{
|
||||
collection,
|
||||
slug: addModalSlug,
|
||||
fieldTypes,
|
||||
setValue: (val) => {
|
||||
setValue(val.id);
|
||||
setInternalValue(val);
|
||||
@@ -169,6 +171,7 @@ Upload.propTypes = {
|
||||
width: PropTypes.string,
|
||||
style: PropTypes.shape({}),
|
||||
relationTo: PropTypes.string.isRequired,
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
label: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.node,
|
||||
|
||||
@@ -27,7 +27,10 @@ const Index = () => {
|
||||
<WindowInfoProvider {...windowInfoProps}>
|
||||
<ScrollInfoProvider>
|
||||
<Router>
|
||||
<ModalProvider classPrefix="payload">
|
||||
<ModalProvider
|
||||
classPrefix="payload"
|
||||
zIndex={parseInt(getCSSVariable('z-modal'), 10)}
|
||||
>
|
||||
<UserProvider>
|
||||
<StatusListProvider>
|
||||
<SearchParamsProvider>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link, useRouteMatch, useLocation } from 'react-router-dom';
|
||||
import { Link, useRouteMatch } from 'react-router-dom';
|
||||
import format from 'date-fns/format';
|
||||
import config from 'payload/config';
|
||||
import Eyebrow from '../../../elements/Eyebrow';
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
@import 'styles';
|
||||
|
||||
:root {
|
||||
--breakpoint-xs-width : $breakpoint-xs-width;
|
||||
--breakpoint-s-width : $breakpoint-s-width;
|
||||
--breakpoint-m-width : $breakpoint-m-width;
|
||||
--breakpoint-l-width : $breakpoint-l-width;
|
||||
--breakpoint-xs-width : #{$breakpoint-xs-width};
|
||||
--breakpoint-s-width : #{$breakpoint-s-width};
|
||||
--breakpoint-m-width : #{$breakpoint-m-width};
|
||||
--breakpoint-l-width : #{$breakpoint-l-width};
|
||||
--z-modal: #{$z-modal};
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
@@ -35,6 +36,7 @@ html, body, #app {
|
||||
#app {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: $z-modal;
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
@@ -5,3 +5,4 @@
|
||||
$z-page: 20;
|
||||
$z-nav: 40;
|
||||
$z-modal: 50;
|
||||
$z-status: 60;
|
||||
|
||||
Reference in New Issue
Block a user