Added deletion.

pull/24/head
Sander Vocke 5 years ago
parent e19ebeffaa
commit 3d00b5b6ca
  1. 26
      client/src/components/windows/manage_tags/ManageTagMenu.tsx
  2. 57
      client/src/components/windows/manage_tags/ManageTagsWindow.tsx

@ -26,27 +26,34 @@ export function MenuEditText(props: {
} }
export interface IProps { export interface IProps {
anchorEl: null | HTMLElement, position: null | number[],
open: boolean,
onClose: () => void, onClose: () => void,
onRename: (s: string) => void, onRename: (s: string) => void,
onDelete: () => void,
tag: any, tag: any,
} }
export default function ManageTagMenu(props: IProps) { export default function ManageTagMenu(props: IProps) {
const anchorEl = props.anchorEl; const pos = props.open && props.position ?
{ left: props.position[0], top: props.position[1] }
const onRename = (name: string) => { : { left: 0, top: 0 }
}
return <Menu return <Menu
anchorEl={anchorEl} open={props.open}
anchorReference="anchorPosition"
anchorPosition={pos}
keepMounted keepMounted
open={Boolean(props.anchorEl)}
onClose={props.onClose} onClose={props.onClose}
> >
<MenuItem
onClick={() => {
props.onClose();
props.onDelete();
}}
>Delete</MenuItem>
<NestedMenuItem <NestedMenuItem
parentMenuOpen={Boolean(anchorEl)} parentMenuOpen={props.open}
label="Rename" label="Rename"
> >
<MenuEditText <MenuEditText
@ -57,5 +64,6 @@ export default function ManageTagMenu(props: IProps) {
}} }}
/> />
</NestedMenuItem> </NestedMenuItem>
</Menu> </Menu>
} }

@ -106,31 +106,35 @@ export function SingleTag(props: {
const tag = props.tag; const tag = props.tag;
const hasChildren = 'children' in tag && tag.children.length > 0; const hasChildren = 'children' in tag && tag.children.length > 0;
const [menuAnchorEl, setMenuAnchorEl] = React.useState<null | HTMLElement>(null); const [menuPos, setMenuPos] = React.useState<null | number[]>(null);
const [expanded, setExpanded] = useState<Boolean>(false); const [expanded, setExpanded] = useState<Boolean>(false);
const theme = useTheme(); const theme = useTheme();
const onOpenMenu = (event: any) => { const onOpenMenu = (e: any) => {
setMenuAnchorEl(event.currentTarget); setMenuPos([e.clientX, e.clientY])
}; };
const onCloseMenu = () => { const onCloseMenu = () => {
setMenuAnchorEl(null); setMenuPos(null);
}; };
const tagLabel = ("proposedName" in tag) ? var tagLabel: any = tag.name;
<><del style={{ color: theme.palette.text.secondary }}>{tag.name}</del>{tag.proposedName}</> : if ("proposedName" in tag) {
tag.name; tagLabel = <><del style={{ color: theme.palette.text.secondary }}>{tag.name}</del>{tag.proposedName}</>;
} else if ("proposeDelete" in tag && tag.proposeDelete) {
tagLabel = <><del style={{ color: theme.palette.text.secondary }}>{tag.name}</del></>;
}
const expandArrow = expanded ? const expandArrow = expanded ?
<IconButton size="small" onClick={() => setExpanded(false)}><ArrowDropDownIcon /></IconButton> : <IconButton size="small" onClick={() => setExpanded(false)}><ArrowDropDownIcon /></IconButton> :
<IconButton size="small" onClick={() => setExpanded(true)}><ArrowRightIcon /></IconButton>; <IconButton size="small" onClick={() => setExpanded(true)}><ArrowRightIcon /></IconButton>;
const GreyedTag = (props: any) => <Box const TagChip = (props: any) => <Box
style={{ opacity: 0.5 }} style={{ opacity: props.transparent ? 0.5 : 1.0 }}
> >
<Chip <Chip
size="small" size="small"
label={tagLabel} label={props.label}
onClick={onOpenMenu}
/> />
</Box>; </Box>;
@ -140,22 +144,19 @@ export function SingleTag(props: {
{expandArrow} {expandArrow}
</Box> </Box>
{props.prependElems} {props.prependElems}
<Chip <TagChip transparent={tag.proposeDelete} label={tagLabel} />
size="small"
label={tagLabel}
onClick={onOpenMenu}
/>
</Box> </Box>
{hasChildren && expanded && tag.children.map((child: any) => <SingleTag {hasChildren && expanded && tag.children.map((child: any) => <SingleTag
tag={child} tag={child}
prependElems={[...props.prependElems, prependElems={[...props.prependElems,
<GreyedTag tag={tag} />, <TagChip transparent={true} label={tagLabel} />,
<Typography variant="h5">/</Typography>]} <Typography variant="h5">/</Typography>]}
dispatch={props.dispatch} dispatch={props.dispatch}
state={props.state} state={props.state}
/>)} />)}
<ManageTagMenu <ManageTagMenu
anchorEl={menuAnchorEl} position={menuPos}
open={menuPos !== null}
onClose={onCloseMenu} onClose={onCloseMenu}
onRename={(s: string) => { onRename={(s: string) => {
props.dispatch({ props.dispatch({
@ -170,6 +171,18 @@ export function SingleTag(props: {
] ]
}) })
}} }}
onDelete={() => {
props.dispatch({
type: ManageTagsWindowActions.SetPendingChanges,
value: [
...props.state.pendingChanges,
{
type: TagChangeType.Delete,
id: tag.tagId,
}
]
})
}}
tag={tag} tag={tag}
/> />
</> </>
@ -177,11 +190,21 @@ export function SingleTag(props: {
function addTagChanges(tags: Record<number, any>, changes: TagChange[]) { function addTagChanges(tags: Record<number, any>, changes: TagChange[]) {
var retval = tags; var retval = tags;
const applyDelete = (id: number) => {
retval[id].proposeDelete = true;
Object.values(tags).filter((t: any) => t.parentId === id)
.forEach((child: any) => applyDelete(child.tagId));
}
changes.forEach((change: TagChange) => { changes.forEach((change: TagChange) => {
switch (change.type) { switch (change.type) {
case TagChangeType.Rename: case TagChangeType.Rename:
retval[change.id].proposedName = change.name; retval[change.id].proposedName = change.name;
break; break;
case TagChangeType.Delete:
applyDelete(change.id);
break;
default: default:
throw new Error("Unimplemented tag change") throw new Error("Unimplemented tag change")
} }

Loading…
Cancel
Save