File manager cleanup for mobile devices

This commit is contained in:
Dane Everitt 2020-09-13 10:33:12 -07:00
parent 6ec2ae9df8
commit 47283700a8
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
9 changed files with 53 additions and 40 deletions

View file

@ -155,7 +155,6 @@ export default ({ server, className }: { server: Server; className?: string }) =
</div> </div>
<p css={tw`text-xs text-neutral-600 text-center mt-1`}>of {disklimit}</p> <p css={tw`text-xs text-neutral-600 text-center mt-1`}>of {disklimit}</p>
</div> </div>
<div css={tw`flex-1 flex justify-end sm:hidden`}> <div css={tw`flex-1 flex justify-end sm:hidden`}>
<div css={tw`flex items-end text-right`}> <div css={tw`flex items-end text-right`}>
<div <div

View file

@ -19,11 +19,11 @@ const ConfirmationModal = ({ title, children, buttonText, onConfirmed }: Props)
<> <>
<h2 css={tw`text-2xl mb-6`}>{title}</h2> <h2 css={tw`text-2xl mb-6`}>{title}</h2>
<p css={tw`text-sm`}>{children}</p> <p css={tw`text-sm`}>{children}</p>
<div css={tw`flex items-center justify-end mt-8`}> <div css={tw`flex flex-wrap items-center justify-end mt-8`}>
<Button isSecondary onClick={() => dismiss()}> <Button isSecondary onClick={() => dismiss()} css={tw`w-full sm:w-auto`}>
Cancel Cancel
</Button> </Button>
<Button color={'red'} css={tw`ml-4`} onClick={() => onConfirmed()}> <Button color={'red'} css={tw`w-full sm:w-auto mt-4 sm:mt-0 sm:ml-4`} onClick={() => onConfirmed()}>
{buttonText} {buttonText}
</Button> </Button>
</div> </div>

View file

@ -1,9 +1,7 @@
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
import Spinner from '@/components/elements/Spinner'; import Spinner from '@/components/elements/Spinner';
import tw from 'twin.macro'; import tw from 'twin.macro';
import styled from 'styled-components/macro'; import styled, { css } from 'styled-components/macro';
import { breakpoint } from '@/theme'; import { breakpoint } from '@/theme';
import Fade from '@/components/elements/Fade'; import Fade from '@/components/elements/Fade';
@ -26,25 +24,27 @@ export const ModalMask = styled.div`
background: rgba(0, 0, 0, 0.70); background: rgba(0, 0, 0, 0.70);
`; `;
const ModalContainer = styled.div<{ alignTop?: boolean }>` const ModalContainer = styled.div<{ alignTop?: boolean }>`
${breakpoint('xs')` max-width: 95%;
max-width: 95%; max-height: calc(100vh - 8rem);
`}; ${breakpoint('md')`max-width: 75%`};
${breakpoint('lg')`max-width: 50%`};
${breakpoint('md')`
max-width: 50%;
`};
${tw`relative flex flex-col w-full m-auto`}; ${tw`relative flex flex-col w-full m-auto`};
max-height: calc(100vh - 8rem); ${props => props.alignTop && css`
// @todo max-w-screen-lg perhaps? margin-top: 20%;
${props => props.alignTop && 'margin-top: 10%'}; ${breakpoint('md')`margin-top: 10%`};
`};
& > .close-icon { & > .close-icon {
${tw`absolute right-0 p-2 text-white cursor-pointer opacity-50 transition-all duration-150 ease-linear hover:opacity-100`}; ${tw`absolute right-0 p-2 text-white cursor-pointer opacity-50 transition-all duration-150 ease-linear hover:opacity-100`};
top: -2rem; top: -2.5rem;
&:hover {${tw`transform rotate-90`}} &:hover {${tw`transform rotate-90`}}
& > svg {
${tw`w-6 h-6`};
}
} }
`; `;
@ -80,6 +80,7 @@ const Modal: React.FC<ModalProps> = ({ visible, appear, dismissable, showSpinner
> >
<ModalMask <ModalMask
onClick={e => e.stopPropagation()} onClick={e => e.stopPropagation()}
onContextMenu={e => e.stopPropagation()}
onMouseDown={e => { onMouseDown={e => {
if (isDismissable && closeOnBackground) { if (isDismissable && closeOnBackground) {
e.stopPropagation(); e.stopPropagation();
@ -92,7 +93,14 @@ const Modal: React.FC<ModalProps> = ({ visible, appear, dismissable, showSpinner
<ModalContainer alignTop={top}> <ModalContainer alignTop={top}>
{isDismissable && {isDismissable &&
<div className={'close-icon'} onClick={() => setRender(false)}> <div className={'close-icon'} onClick={() => setRender(false)}>
<FontAwesomeIcon icon={faTimes}/> <svg xmlns={'http://www.w3.org/2000/svg'} fill={'none'} viewBox={'0 0 24 24'} stroke={'currentColor'}>
<path
strokeLinecap={'round'}
strokeLinejoin={'round'}
strokeWidth={'2'}
d={'M6 18L18 6M6 6l12 12'}
/>
</svg>
</div> </div>
} }
{showSpinnerOverlay && {showSpinnerOverlay &&

View file

@ -120,7 +120,7 @@ export default () => {
/> />
</div> </div>
<div css={tw`flex justify-end mt-4`}> <div css={tw`flex justify-end mt-4`}>
<div css={tw`rounded bg-neutral-900 mr-4`}> <div css={tw`flex-1 sm:flex-none rounded bg-neutral-900 mr-4`}>
<Select value={mode} onChange={e => setMode(e.currentTarget.value)}> <Select value={mode} onChange={e => setMode(e.currentTarget.value)}>
{Object.keys(modes).map(key => ( {Object.keys(modes).map(key => (
<option key={key} value={key}>{modes[key]}</option> <option key={key} value={key}>{modes[key]}</option>
@ -129,13 +129,13 @@ export default () => {
</div> </div>
{action === 'edit' ? {action === 'edit' ?
<Can action={'file.update'}> <Can action={'file.update'}>
<Button onClick={() => save()}> <Button css={tw`flex-1 sm:flex-none`} onClick={() => save()}>
Save Content Save Content
</Button> </Button>
</Can> </Can>
: :
<Can action={'file.create'}> <Can action={'file.create'}>
<Button onClick={() => setModalVisible(true)}> <Button css={tw`flex-1 sm:flex-none`} onClick={() => setModalVisible(true)}>
Create File Create File
</Button> </Button>
</Can> </Can>

View file

@ -6,7 +6,7 @@ import FileObjectRow from '@/components/server/files/FileObjectRow';
import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcrumbs'; import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcrumbs';
import { FileObject } from '@/api/server/files/loadDirectory'; import { FileObject } from '@/api/server/files/loadDirectory';
import NewDirectoryButton from '@/components/server/files/NewDirectoryButton'; import NewDirectoryButton from '@/components/server/files/NewDirectoryButton';
import { Link, useLocation } from 'react-router-dom'; import { NavLink, useLocation } from 'react-router-dom';
import Can from '@/components/elements/Can'; import Can from '@/components/elements/Can';
import ServerError from '@/components/screens/ServerError'; import ServerError from '@/components/screens/ServerError';
import tw from 'twin.macro'; import tw from 'twin.macro';
@ -81,16 +81,17 @@ export default () => {
</CSSTransition> </CSSTransition>
} }
<Can action={'file.create'}> <Can action={'file.create'}>
<div css={tw`flex justify-end mt-8`}> <div css={tw`flex flex-wrap-reverse justify-end mt-4`}>
<NewDirectoryButton/> <NewDirectoryButton css={tw`w-full flex-none mt-4 sm:mt-0 sm:w-auto sm:mr-4`}/>
<UploadButton/> <UploadButton css={tw`flex-1 mr-4 sm:flex-none sm:mt-0`}/>
<Button <NavLink
// @ts-ignore
as={Link}
to={`/server/${id}/files/new${window.location.hash}`} to={`/server/${id}/files/new${window.location.hash}`}
css={tw`flex-1 sm:flex-none sm:mt-0`}
> >
New File <Button css={tw`w-full`}>
</Button> New File
</Button>
</NavLink>
</div> </div>
</Can> </Can>
</> </>

View file

@ -11,6 +11,7 @@ import Button from '@/components/elements/Button';
import { FileObject } from '@/api/server/files/loadDirectory'; import { FileObject } from '@/api/server/files/loadDirectory';
import useFlash from '@/plugins/useFlash'; import useFlash from '@/plugins/useFlash';
import useFileManagerSwr from '@/plugins/useFileManagerSwr'; import useFileManagerSwr from '@/plugins/useFileManagerSwr';
import { WithClassname } from '@/components/types';
interface Values { interface Values {
directoryName: string; directoryName: string;
@ -34,7 +35,7 @@ const generateDirectoryData = (name: string): FileObject => ({
isEditable: () => false, isEditable: () => false,
}); });
export default () => { export default ({ className }: WithClassname) => {
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
const { clearAndAddHttpError } = useFlash(); const { clearAndAddHttpError } = useFlash();
const [ visible, setVisible ] = useState(false); const [ visible, setVisible ] = useState(false);
@ -95,7 +96,7 @@ export default () => {
</Modal> </Modal>
)} )}
</Formik> </Formik>
<Button isSecondary css={tw`mr-2`} onClick={() => setVisible(true)}> <Button isSecondary onClick={() => setVisible(true)} className={className}>
Create Directory Create Directory
</Button> </Button>
</> </>

View file

@ -62,11 +62,11 @@ const RenameFileModal = ({ files, useMoveTerminology, ...props }: OwnProps) => {
<Form css={tw`m-0`}> <Form css={tw`m-0`}>
<div <div
css={[ css={[
tw`flex`, tw`flex flex-wrap`,
useMoveTerminology ? tw`items-center` : tw`items-end`, useMoveTerminology ? tw`items-center` : tw`items-end`,
]} ]}
> >
<div css={tw`flex-1 mr-6`}> <div css={tw`w-full sm:flex-1 sm:mr-4`}>
<Field <Field
type={'string'} type={'string'}
id={'file_name'} id={'file_name'}
@ -79,8 +79,8 @@ const RenameFileModal = ({ files, useMoveTerminology, ...props }: OwnProps) => {
autoFocus autoFocus
/> />
</div> </div>
<div> <div css={tw`w-full sm:w-auto mt-4 sm:mt-0`}>
<Button>{useMoveTerminology ? 'Move' : 'Rename'}</Button> <Button css={tw`w-full`}>{useMoveTerminology ? 'Move' : 'Rename'}</Button>
</div> </div>
</div> </div>
{useMoveTerminology && {useMoveTerminology &&

View file

@ -11,13 +11,14 @@ import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import useFlash from '@/plugins/useFlash'; import useFlash from '@/plugins/useFlash';
import useFileManagerSwr from '@/plugins/useFileManagerSwr'; import useFileManagerSwr from '@/plugins/useFileManagerSwr';
import { ServerContext } from '@/state/server'; import { ServerContext } from '@/state/server';
import { WithClassname } from '@/components/types';
const InnerContainer = styled.div` const InnerContainer = styled.div`
max-width: 600px; max-width: 600px;
${tw`bg-black w-full border-4 border-primary-500 border-dashed rounded p-10 mx-10`} ${tw`bg-black w-full border-4 border-primary-500 border-dashed rounded p-10 mx-10`}
`; `;
export default () => { export default ({ className }: WithClassname) => {
const fileUploadInput = useRef<HTMLInputElement>(null); const fileUploadInput = useRef<HTMLInputElement>(null);
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
const [ visible, setVisible ] = useState(false); const [ visible, setVisible ] = useState(false);
@ -114,7 +115,7 @@ export default () => {
}} }}
/> />
<Button <Button
css={tw`mr-2`} className={className}
onClick={() => { onClick={() => {
fileUploadInput.current fileUploadInput.current
? fileUploadInput.current.click() ? fileUploadInput.current.click()

View file

@ -0,0 +1,3 @@
export interface WithClassname {
className?: string;
}