Skip to content

Commit

Permalink
HierarchicalTags document structure
Browse files Browse the repository at this point in the history
  • Loading branch information
damianmoore committed May 14, 2019
1 parent 110ccfe commit e73be14
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 74 deletions.
30 changes: 15 additions & 15 deletions docker-compose.dev.yml
Expand Up @@ -24,8 +24,8 @@ services:
build:
context: .
ports:
- "8888:80"
- "8889:8000"
- "8888:80"
- "8889:8000"
environment:
ENV: dev
POSTGRES_HOST: postgres
Expand All @@ -34,17 +34,17 @@ services:
POSTGRES_PASSWORD: password
REDIS_HOST: redis
volumes:
- ./photonix:/srv/photonix
- ./tests:/srv/tests
- ./test.py:/srv/test.py
- ./ui/public:/srv/ui/public
- ./ui/src:/srv/ui/src
- ./ui/static:/srv/ui/static
- ./data/photos:/data/photos
- ./data/raw-photos-processed:/data/raw-photos-processed
- ./data/cache:/data/cache
- ./data/models:/data/models
- ./system/supervisord.conf:/etc/supervisord.conf
- ./photonix:/srv/photonix
- ./tests:/srv/tests
- ./test.py:/srv/test.py
- ./ui/public:/srv/ui/public
- ./ui/src:/srv/ui/src
- ./ui/static:/srv/ui/static
- ./data/photos:/data/photos
- ./data/raw-photos-processed:/data/raw-photos-processed
- ./data/cache:/data/cache
- ./data/models:/data/models
- ./system/supervisord.conf:/etc/supervisord.conf
links:
- postgres
- redis
- postgres
- redis
14 changes: 7 additions & 7 deletions docker-compose.example.yml
Expand Up @@ -18,7 +18,7 @@ services:
container_name: photonix
image: damianmoore/photonix:latest
ports:
- "8888:80"
- "8888:80"
environment:
ENV: prd
POSTGRES_HOST: postgres
Expand All @@ -28,10 +28,10 @@ services:
REDIS_HOST: redis
ALLOWED_HOSTS: localhost,example.com
volumes:
- ./data/photos:/data/photos
- ./data/raw-photos-processed:/data/raw-photos-processed
- ./data/cache:/data/cache
- ./data/models:/data/models
- ./data/photos:/data/photos
- ./data/raw-photos-processed:/data/raw-photos-processed
- ./data/cache:/data/cache
- ./data/models:/data/models
links:
- postgres
- redis
- postgres
- redis
22 changes: 10 additions & 12 deletions ui/src/components/ColorTags.js
Expand Up @@ -3,17 +3,15 @@ import React from 'react'
import '../static/css/ColorTags.css'


const ColorTags = ({ tags }) => {
return (
<ul className="ColorTags">
{
tags.map((tag, index) => {
let className = `Color ${tag.name.replace(/ /g, '')}`
return <li key={index} className={className} title={tag.name} onClick={tag.onClick}>{tag.name}</li>
})
}
</ul>
)
}
const ColorTags = ({ tags }) => (
<ul className="ColorTags">
{
tags.map((tag, index) => {
let className = `Color ${tag.name.replace(/ /g, '')}`
return <li key={index} className={className} title={tag.name} onClick={tag.onClick}>{tag.name}</li>
})
}
</ul>
)

export default ColorTags
70 changes: 44 additions & 26 deletions ui/src/components/Filters.js
@@ -1,36 +1,54 @@
import React from 'react'

import ColorTags from './ColorTags'
import HierarchicalTagsContainer from '../containers/HierarchicalTagsContainer'

import '../static/css/Filters.css'


const Filters = ({ data, onToggle, onScroll, onMouseDown, onTouchStart, containerRef, scrollbarHandleRef, displayScrollbar }) => (
<section className="Filters" onScroll={onScroll} ref={containerRef}>
<div className="FiltersContent">
{
data.map((group) => (
<div className="FilterGroup" key={group.name}>
<h2>{group.name}</h2>
{
group.name === 'Colors'
?
<ColorTags tags={group.items.map((item) => {
item.onClick = () => onToggle(item.id, group.name, item.name)
return item
})} />
:
group.items.map((item) => (
<li key={item.id} onClick={() => onToggle(item.id, group.name, item.name)}>{item.name}</li>
))
const Filters = ({ data, onToggle, onScroll, onMouseDown, onTouchStart, containerRef, scrollbarHandleRef, displayScrollbar }) => {
return (
<section className="Filters" onScroll={onScroll} ref={containerRef}>
<div className="FiltersContent">
{
data.map((group) => {
let items = ''

if (group.name === 'Colors') {
items = <ColorTags tags={group.items.map((item) => {
item.onClick = () => onToggle(item.id, group.name, item.name)
return item
})} />
}

else if (group.name === 'Locations') {
items = <HierarchicalTagsContainer tags={group.items} />
}
</div>
))
}
<div className="filterGradient"></div>
</div>
<div className="scrollbar" ref={scrollbarHandleRef} style={{opacity: displayScrollbar ? 1 : null}} onMouseDown={onMouseDown} onTouchStart={onTouchStart}></div>
</section>
)

else {
items = group.items.map((item) => {
if (item.id) {
return <li key={item.id} onClick={() => onToggle(item.id, group.name, item.name)}>{item.name}</li>
}
else {
return <li key={item} onClick={() => onToggle(item, group.name, item)}>{item}</li>
}
})
}

return (
<div className="FilterGroup" key={group.name}>
<h2>{group.name}</h2>
{items}
</div>
)
})
}
<div className="filterGradient"></div>
</div>
<div className="scrollbar" ref={scrollbarHandleRef} style={{opacity: displayScrollbar ? 1 : null}} onMouseDown={onMouseDown} onTouchStart={onTouchStart}></div>
</section>
)
}

export default Filters
37 changes: 37 additions & 0 deletions ui/src/components/HierarchicalTags.js
@@ -0,0 +1,37 @@
import React from 'react'

import '../static/css/HierarchicalTags.css'


function displayChildren(items) {
return items.map((item) => {
let mainEl = <li key={item.id} title={item.name} onClick={item.onClick}>{item.name}</li>
let childrenEl = <ul></ul>

if (item.children) {
childrenEl = (
<ul>
{displayChildren(item.children)}
</ul>
)
}

return (
<>
{mainEl}
{childrenEl}
</>
)
})
}


const HierarchicalTags = ({ tags }) => {
return (
<ul className="HeirarchicalTags">
{displayChildren(tags)}
</ul>
)
}

export default HierarchicalTags
13 changes: 6 additions & 7 deletions ui/src/components/PhotoDetail.js
Expand Up @@ -4,6 +4,7 @@ import createHistory from 'history/createBrowserHistory'
import BoundingBoxes from './BoundingBoxes'
import MapViewContainer from '../containers/MapViewContainer'
import ColorTags from './ColorTags'
import HierarchicalTagsContainer from '../containers/HierarchicalTagsContainer'

import { ReactComponent as CloseIcon } from '../static/images/close.svg'
import { ReactComponent as ArrowDownIcon } from '../static/images/arrow_down.svg'
Expand Down Expand Up @@ -53,13 +54,11 @@ const PhotoDetail = ({ photoId, photo }) => {
?
<div className="box">
<h2>Locations</h2>
<ul>
{
photo.locationTags.map((photoTag, index) => (
<li key={index}>{photoTag.tag.name}</li>
))
}
</ul>
<HierarchicalTagsContainer tags={photo.locationTags.map((item) => {
let newItem = item.tag
newItem.parent = item.parent
return newItem
})} />
</div>
:
''
Expand Down
13 changes: 11 additions & 2 deletions ui/src/containers/FiltersContainer.js
Expand Up @@ -10,6 +10,9 @@ const GET_FILTERS = gql`
allLocationTags {
id
name
parent {
id
}
}
allObjectTags {
id
Expand Down Expand Up @@ -179,10 +182,16 @@ export default class FiltersContainer extends React.Component {
return {
name: sectionName,
items: data.map((tag) => {
let item = {
id: prefix + ':' + tag,
name: tag,
}
if (tag.toString() === '[object Object]') {
return {id: prefix + ':' + tag.id, name: tag.name}
item.name = tag.name
item.id = prefix + ':' + tag.id
item.parent = tag.parent ? prefix + ':' + tag.parent.id : null
}
return {id: prefix + ':' + tag, name: tag}
return item
}),
}
}
Expand Down
79 changes: 79 additions & 0 deletions ui/src/containers/HierarchicalTagsContainer.js
@@ -0,0 +1,79 @@
import React from 'react'

import HierarchicalTags from '../components/HierarchicalTags'


export default class HierarchicalTagsContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
hierarchicalTags: [],
}
}

onSelectParent = (e, id) => {
console.log(e, id)
this.selectedTagId = id
}

componentDidMount = () => {
this.generateTags()
}

componentDidUpdate = (prevProps) => {
if (this.props.tags !== prevProps.tags) {
this.generateTags()
}
}

buildTree = (tree, item) => {
if (item) {
// Current item has a parent
for (let i = 0; i < tree.length; i++) { // Traverse the entire tree in to find the parent
if (tree[i].id === item.parent) {
tree[i].children.push(item) // add the child to his parent
tree[i].onClick = () => this.onSelectParent(tree[i].id)
break
}
else {
// if item doesn't match but tree have children then parses children again to find item parent
this.buildTree(tree[i].children, item)
}
}
}
else {
// We're at a root item
let i = 0
while (i < tree.length) {
if (tree[i].parent) {
// if have parent then remove it from the array and move it to the right place
this.buildTree(tree, tree.splice(i, 1)[0])
}
else {
i++
}
}
}
}

generateTags = () => {
let hierarchicalTags = this.props.tags
for (var i = 0; i < hierarchicalTags.length; i++) {
hierarchicalTags[i].children = []
}

this.buildTree(hierarchicalTags)
console.log(hierarchicalTags)

this.setState({hierarchicalTags: hierarchicalTags})
}

render = () => {
return (
<>
<div>{this.selectedTagId}</div>
<HierarchicalTags tags={this.state.hierarchicalTags} onSelectParent={this.onSelectParent} expandAll={true} />
</>
)
}
}
4 changes: 4 additions & 0 deletions ui/src/containers/PhotoDetailContainer.js
Expand Up @@ -40,7 +40,11 @@ query Photo($id: UUID) {
locationTags {
id
tag {
id
name
parent {
id
}
}
}
objectTags {
Expand Down
2 changes: 2 additions & 0 deletions ui/src/static/css/App.css
Expand Up @@ -12,6 +12,8 @@ body {
background: #1d1d1d;
color: #ddd;
height: 100%;
font-size: 14px;
line-height: 1.4;
}

a {
Expand Down
9 changes: 9 additions & 0 deletions ui/src/static/css/HierarchicalTags.css
@@ -0,0 +1,9 @@
.HeirarchicalTags li {
background: #383838;
display: inline-block;
margin: 0 10px 10px 0;
padding: 6px 10px 4px;
font-size: 12px;
border-radius: 4px;
cursor: pointer;
}

0 comments on commit e73be14

Please sign in to comment.