|
|
|
@ -1,5 +1,8 @@ |
|
|
|
|
import React from 'react'; |
|
|
|
|
import React, { useEffect } from 'react'; |
|
|
|
|
import { WindowState } from './Windows'; |
|
|
|
|
import { Box, Typography, Chip } from '@material-ui/core'; |
|
|
|
|
import * as serverApi from '../../api'; |
|
|
|
|
import LoyaltyIcon from '@material-ui/icons/Loyalty'; |
|
|
|
|
var _ = require('lodash'); |
|
|
|
|
|
|
|
|
|
export interface ManageTagsWindowState extends WindowState { |
|
|
|
@ -15,6 +18,65 @@ export function ManageTagsWindowReducer(state: ManageTagsWindowState, action: an |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export function organiseTags(allTags: any[], fromId: number | null): any[] { |
|
|
|
|
const base = allTags.filter((tag: any) => |
|
|
|
|
(fromId === null && !tag.parentId) || |
|
|
|
|
(tag.parentId && tag.parentId === fromId) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return base.map((tag: any) => { |
|
|
|
|
return { |
|
|
|
|
...tag, |
|
|
|
|
children: organiseTags(allTags, tag.tagId), |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export async function getAllTags() { |
|
|
|
|
// Build a request to fetch all tags.
|
|
|
|
|
var q: serverApi.QueryRequest = { |
|
|
|
|
query: {}, |
|
|
|
|
offsetsLimits: { |
|
|
|
|
tagOffset: 0, |
|
|
|
|
tagLimit: 1000, |
|
|
|
|
}, |
|
|
|
|
ordering: { |
|
|
|
|
orderBy: { |
|
|
|
|
type: serverApi.OrderByType.Name, |
|
|
|
|
}, |
|
|
|
|
ascending: true, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const requestOpts = { |
|
|
|
|
method: 'POST', |
|
|
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
|
|
body: JSON.stringify(q), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
return (async () => { |
|
|
|
|
const response = await fetch((process.env.REACT_APP_BACKEND || "") + serverApi.QueryEndpoint, requestOpts) |
|
|
|
|
let json: any = await response.json(); |
|
|
|
|
return json.tags; |
|
|
|
|
})(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export function SingleTag(props: any) { |
|
|
|
|
const tag = props.tag; |
|
|
|
|
const thisTag = <Chip label={tag.name} />; |
|
|
|
|
|
|
|
|
|
return <> |
|
|
|
|
{thisTag} |
|
|
|
|
{tag.children && tag.children.map((tag: any) => { |
|
|
|
|
return <Box display="flex" alignItems="center" mt={1}> |
|
|
|
|
{thisTag} |
|
|
|
|
<Typography variant="h5">/</Typography> |
|
|
|
|
<SingleTag tag={tag} /> |
|
|
|
|
</Box> |
|
|
|
|
})} |
|
|
|
|
</> |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export interface IProps { |
|
|
|
|
state: ManageTagsWindowState, |
|
|
|
|
dispatch: (action: any) => void, |
|
|
|
@ -22,5 +84,41 @@ export interface IProps { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export default function ManageTagsWindow(props: IProps) { |
|
|
|
|
return <>Hi!</> |
|
|
|
|
const [tags, setTags] = React.useState<any[]>([]); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
(async () => { |
|
|
|
|
const allTags = await getAllTags(); |
|
|
|
|
// We have the tags in list form. Now, we want to organize
|
|
|
|
|
// them hierarchically by giving each tag a "children" prop.
|
|
|
|
|
setTags(organiseTags(allTags, null)); |
|
|
|
|
})(); |
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
return <Box width="100%" justifyContent="center" display="flex" flexWrap="wrap"> |
|
|
|
|
<Box |
|
|
|
|
m={1} |
|
|
|
|
mt={4} |
|
|
|
|
width="80%" |
|
|
|
|
> |
|
|
|
|
<LoyaltyIcon style={{ fontSize: 80 }} /> |
|
|
|
|
</Box> |
|
|
|
|
<Box |
|
|
|
|
m={1} |
|
|
|
|
mt={4} |
|
|
|
|
width="80%" |
|
|
|
|
> |
|
|
|
|
<Typography variant="h4">Manage Tags</Typography> |
|
|
|
|
</Box> |
|
|
|
|
<Box |
|
|
|
|
m={1} |
|
|
|
|
mt={4} |
|
|
|
|
width="80%" |
|
|
|
|
> |
|
|
|
|
{tags && tags.length && tags.map((tag: any) => { |
|
|
|
|
console.log("Tags:", tags); |
|
|
|
|
return <Box mt={1}><SingleTag tag={tag} /></Box>; |
|
|
|
|
})} |
|
|
|
|
</Box> |
|
|
|
|
</Box> |
|
|
|
|
} |