Skip to content

Commit b077911

Browse files
Pollepsjoepio
authored andcommitted
#228 Add folder with listview
1 parent 7a1f03b commit b077911

File tree

15 files changed

+404
-26
lines changed

15 files changed

+404
-26
lines changed

data-browser/src/components/NewInstanceButton/NewBookmarkButton.tsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { classes, properties, useResource, useTitle } from '@tomic/react';
2-
import React, { useCallback, useState } from 'react';
2+
import React, { FormEvent, useCallback, useState } from 'react';
33
import { Button } from '../Button';
44
import {
55
Dialog,
@@ -39,15 +39,20 @@ export function NewBookmarkButton({
3939

4040
const createResourceAndNavigate = useCreateAndNavigate(klass, parent);
4141

42-
const onDone = useCallback(() => {
43-
const normalizedUrl = normalizeWebAddress(url);
42+
const onDone = useCallback(
43+
(e: FormEvent) => {
44+
e.preventDefault();
4445

45-
createResourceAndNavigate('bookmark', {
46-
[properties.name]: 'New Bookmark',
47-
[properties.bookmark.url]: normalizedUrl,
48-
[properties.isA]: [classes.bookmark],
49-
});
50-
}, [url]);
46+
const normalizedUrl = normalizeWebAddress(url);
47+
48+
createResourceAndNavigate('bookmark', {
49+
[properties.name]: 'New Bookmark',
50+
[properties.bookmark.url]: normalizedUrl,
51+
[properties.isA]: [classes.bookmark],
52+
});
53+
},
54+
[url],
55+
);
5156

5257
return (
5358
<>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { classes, properties, useResource, useTitle } from '@tomic/react';
2+
import React, { FormEvent, useCallback, useState } from 'react';
3+
import { Button } from '../Button';
4+
import {
5+
Dialog,
6+
DialogActions,
7+
DialogContent,
8+
DialogTitle,
9+
useDialog,
10+
} from '../Dialog';
11+
import Field from '../forms/Field';
12+
import { InputStyled, InputWrapper } from '../forms/InputStyles';
13+
import { Base } from './Base';
14+
import { useCreateAndNavigate } from './useCreateAndNavigate';
15+
import { NewInstanceButtonProps } from './NewInstanceButtonProps';
16+
17+
export function NewFolderButton({
18+
klass,
19+
subtle,
20+
icon,
21+
parent,
22+
children,
23+
label,
24+
}: NewInstanceButtonProps): JSX.Element {
25+
const resource = useResource(klass);
26+
const [title] = useTitle(resource);
27+
const [name, setName] = useState('');
28+
29+
const [dialogProps, show, hide] = useDialog();
30+
31+
const createResourceAndNavigate = useCreateAndNavigate(klass, parent);
32+
33+
const onDone = useCallback(
34+
(e: FormEvent) => {
35+
e.preventDefault();
36+
37+
createResourceAndNavigate('Folder', {
38+
[properties.name]: name,
39+
[properties.displayStyle]: 'list',
40+
[properties.isA]: [classes.folder],
41+
});
42+
},
43+
[name],
44+
);
45+
46+
return (
47+
<>
48+
<Base
49+
onClick={show}
50+
title={title}
51+
icon={icon}
52+
subtle={subtle}
53+
label={label}
54+
>
55+
{children}
56+
</Base>
57+
<Dialog {...dialogProps}>
58+
<DialogTitle>
59+
<h1>New Folder</h1>
60+
</DialogTitle>
61+
<DialogContent>
62+
<form onSubmit={onDone}>
63+
<Field required label='url'>
64+
<InputWrapper>
65+
<InputStyled
66+
placeholder='New Folder'
67+
value={name}
68+
autoFocus={true}
69+
onChange={e => setName(e.target.value)}
70+
/>
71+
</InputWrapper>
72+
</Field>
73+
</form>
74+
</DialogContent>
75+
<DialogActions>
76+
<Button onClick={hide} subtle>
77+
Cancel
78+
</Button>
79+
<Button onClick={onDone} disabled={name.trim() === ''}>
80+
Ok
81+
</Button>
82+
</DialogActions>
83+
</Dialog>
84+
</>
85+
);
86+
}

data-browser/src/components/NewInstanceButton/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { NewBookmarkButton } from './NewBookmarkButton';
44
import { NewInstanceButtonProps } from './NewInstanceButtonProps';
55
import { NewInstanceButtonDefault } from './NewInstanceButtonDefault';
66
import { useSettings } from '../../helpers/AppSettings';
7+
import { NewFolderButton } from './NewFolderButton';
78

89
type InstanceButton = (props: NewInstanceButtonProps) => JSX.Element;
910

1011
/** If your New Instance button requires custom logic, such as a custom dialog */
1112
const classMap = new Map<string, InstanceButton>([
1213
[classes.bookmark, NewBookmarkButton],
14+
[classes.folder, NewFolderButton],
1315
]);
1416

1517
/** A button for creating a new instance of some thing */

data-browser/src/components/Parent.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ function Parent({ resource }: ParentProps): JSX.Element {
4343
}
4444

4545
const ParentWrapper = styled.nav`
46+
height: ${p => p.theme.heights.breadCrumbBar};
4647
padding: 0.2rem;
4748
padding-left: 0.5rem;
4849
color: ${props => props.theme.colors.textLight2};

data-browser/src/components/SideBar/ResourceSideBar/FloatingActions.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { useResource, useTitle } from '@tomic/react';
2-
import React, { useCallback } from 'react';
2+
import React from 'react';
33
import { FaEllipsisV, FaPlus } from 'react-icons/fa';
4-
import { useNavigate } from 'react-router-dom';
54
import styled, { css } from 'styled-components';
6-
import { paths } from '../../../routes/paths';
5+
import { useNewRoute } from '../../../helpers/useNewRoute';
76
import { Button } from '../../Button';
87
import { buildDefaultTrigger } from '../../Dropdown/DefaultTrigger';
98
import ResourceContextMenu from '../../ResourceContextMenu';
@@ -13,27 +12,15 @@ export interface FloatingActionsProps {
1312
className?: string;
1413
}
1514

16-
function buildURL(subject: string) {
17-
const params = new URLSearchParams({
18-
parentSubject: subject,
19-
});
20-
21-
return `${paths.new}?${params.toString()}`;
22-
}
23-
2415
/** Contains actions for a SideBarResource, such as a context menu and a new item button */
2516
export function FloatingActions({
2617
subject,
2718
className,
2819
}: FloatingActionsProps): JSX.Element {
29-
const navigate = useNavigate();
3020
const parentResource = useResource(subject);
3121
const [parentName] = useTitle(parentResource);
3222

33-
const handleAddClick = useCallback(() => {
34-
const url = buildURL(subject);
35-
navigate(url);
36-
}, [subject]);
23+
const handleAddClick = useNewRoute(subject);
3724

3825
return (
3926
<Wrapper className={className}>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { useCallback } from 'react';
2+
import { useNavigate } from 'react-router';
3+
import { paths } from '../routes/paths';
4+
5+
function buildURL(parent?: string) {
6+
const params = new URLSearchParams({
7+
...(parent ? { parentSubject: parent } : {}),
8+
});
9+
10+
return `${paths.new}?${params.toString()}`;
11+
}
12+
13+
export function useNewRoute(parent?: string) {
14+
const navigate = useNavigate();
15+
16+
const navigateToNewRoute = useCallback(() => {
17+
const url = buildURL(parent);
18+
navigate(url);
19+
}, [parent]);
20+
21+
return navigateToNewRoute;
22+
}

data-browser/src/routes/NewRoute.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ function New(): JSX.Element {
6969
)}
7070
{!classInput && (
7171
<>
72+
<NewIntanceButton
73+
klass={urls.classes.folder}
74+
subtle
75+
parent={calculatedParent}
76+
/>
7277
<NewIntanceButton
7378
klass={urls.classes.document}
7479
subtle

data-browser/src/styling.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export const zIndex = {
4545
/** Default animation duration in ms */
4646
export const animationDuration = 100;
4747

48+
const breadCrumbBarHeight = '2.2rem';
49+
4850
/** Construct a StyledComponents theme object */
4951
export const buildTheme = (darkMode: boolean, mainIn: string): DefaultTheme => {
5052
const main = darkMode ? lighten(0.2, mainIn) : mainIn;
@@ -74,6 +76,10 @@ export const buildTheme = (darkMode: boolean, mainIn: string): DefaultTheme => {
7476
sideBarWidth: 15,
7577
margin: 1,
7678
radius: '9px',
79+
heights: {
80+
breadCrumbBar: breadCrumbBarHeight,
81+
fullPage: `calc(100% - ${breadCrumbBarHeight})`,
82+
},
7783
colors: {
7884
main,
7985
mainLight: darkMode ? lighten(0.08)(main) : lighten(0.08)(main),
@@ -121,6 +127,10 @@ declare module 'styled-components' {
121127
/** Roundness of some elements / Border radius */
122128
radius: string;
123129
/** All theme colors */
130+
heights: {
131+
breadCrumbBar: string;
132+
fullPage: string;
133+
};
124134
colors: {
125135
/** Main accent color, used for links */
126136
main: string;

data-browser/src/views/DocumentPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ const FullPageWrapper = styled.div`
449449
display: flex;
450450
flex: 1;
451451
flex-direction: column;
452-
min-height: 100%;
452+
min-height: ${p => p.theme.heights.fullPage};
453453
box-sizing: border-box;
454454
`;
455455

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Resource } from '@tomic/react';
2+
3+
export enum FolderDisplayStyle {
4+
List = 'list',
5+
Grid = 'grid',
6+
}
7+
8+
export interface ViewProps {
9+
subResources: Map<string, Resource>;
10+
onNewClick: () => void;
11+
}

0 commit comments

Comments
 (0)