link: sidebar redesign with grouped collections

This commit is contained in:
Matilde Park 2020-03-26 16:45:48 -04:00
parent e7a29dc628
commit 744dc47be9
6 changed files with 150 additions and 46 deletions

View File

@ -214,4 +214,7 @@ a {
a {
color: #fff;
}
.hover-bg-gray1-d:hover {
background-color: #4d4d4d;
}
}

View File

@ -1,9 +1,10 @@
import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';
import { ChannelsItem } from '/components/lib/channels-item';
import { GroupItem } from './group-item';
import { SidebarInvite } from '/components/lib/sidebar-invite';
import { Welcome } from '/components/lib/welcome';
import { alphabetiseAssociations } from '../../lib/util';
export class ChannelsSidebar extends Component {
// drawer to the left
@ -21,34 +22,75 @@ export class ChannelsSidebar extends Component {
);
});
const channelItems =
[...props.listening].map((path) => {
const meta = props.associations[path];
if (!meta) return null;
const selected = (props.selected === path);
const linkCount = !!props.links[path] ? props.links[path].totalItems : 0;
const unseenCount = !!props.links[path]
? props.links[path].unseenCount
: linkCount
let associations = !!props.associations.contacts ? alphabetiseAssociations(props.associations.contacts) : {};
return (
<ChannelsItem
key={path}
link={path}
memberList={props.groups[meta["group-path"]]}
selected={selected}
linkCount={linkCount}
unseenCount={unseenCount}
name={meta.metadata.title}/>
);
});
let groupedChannels = {};
[...props.listening].map((path) => {
let groupPath = !!props.associations.link[path] ?
props.associations.link[path]["group-path"] : "";
console.log(path);
console.log(groupPath);
if (groupPath.startsWith("/~/")) {
if (groupedChannels["/~/"]) {
let array = groupedChannels["/~/"];
array.push(path);
groupedChannels["/~/"] = array;
} else {
groupedChannels["/~/"] = [path];
};
}
if (groupPath in associations) {
if (groupedChannels[groupPath]) {
let array = groupedChannels[groupPath];
array.push[path];
groupedChannels[groupPath] = array;
} else {
groupedChannels[groupPath] = [path];
}
}
});
let i = -1;
const groupedItems = Object.keys(associations).map((each) => {
let channels = groupedChannels[each];
if (!channels || channels.length === 0) return;
i++;
if (groupedChannels["/~/"] && groupedChannels["/~/"].length !== 0) {
i++;
}
return (
<GroupItem
key={i}
index={i}
association={associations[each]}
linkMetadata={props.associations["link"]}
channels={channels}
selected={props.selected}
links={props.links}
/>
)
});
if (groupedChannels["/~/"] && groupedChannels["/~/"].length !== 0) {
groupedItems.unshift(
<GroupItem
key={"/~/"}
index={0}
association={"/~/"}
linkMetadata={props.associations["link"]}
channels={groupedChannels["/~/"]}
selected={props.selected}
links={props.links}
/>
)
}
let activeClasses = (this.props.active === "collections") ? " " : "dn-s ";
let hiddenClasses = true;
// probably a more concise way to write this
if (this.props.popout) {
hiddenClasses = false;
} else {
@ -63,17 +105,16 @@ export class ChannelsSidebar extends Component {
: "dn")}>
<a className="db dn-m dn-l dn-xl f8 pb3 pl3" href="/"> Landscape</a>
<div className="overflow-y-scroll h-100">
<div className="w-100 bg-transparent pa4 bb b--gray4 b--gray2-d"
style={{paddingBottom: 10, paddingTop: 10}}>
<div className="w-100 bg-transparent">
<Link
className="dib f9 pointer green2 gray4-d mr4"
className="dib f9 pointer green2 gray4-d pa4"
to={"/~link/new"}>
New Collection
</Link>
</div>
<Welcome associations={props.associations}/>
{sidebarInvites}
{channelItems}
{groupedItems}
</div>
</div>
);

View File

@ -7,25 +7,18 @@ export class ChannelsItem extends Component {
const { props } = this;
let selectedClass = (props.selected)
? "bg-gray5 bg-gray1-d b--gray4 b--gray2-d"
: "b--gray4 b--gray2-d";
? "bg-gray5 bg-gray1-d"
: "pointer hover-bg-gray5 hover-bg-gray1-d";
let memberCount = props.memberList
? props.memberList.size
: 0;
const unseenCount = props.unseenCount > 0
? <span className="green2">{" " + props.unseenCount + " unread"}</span>
? <span className="dib white bg-gray3 bg-gray2-d fw6 br1" style={{padding: "1px 5px"}}>{props.unseenCount}</span>
: null;
return (
<Link to={makeRoutePath(props.link)}>
<div className={"w-100 v-mid f9 pl4 bb z1 pa3 pt4 pb4 b--gray4 b--gray1-d gray3-d pointer " + selectedClass}>
<p className="f9 pt1">{props.name}</p>
<p className="f9 gray2">
{memberCount + " contributor" + ((memberCount === 1) ? "" : "s")}
</p>
<p className="f9 pb1">
{props.linkCount + " link" + ((props.linkCount === 1) ? "" : "s")}
<div className={"w-100 v-mid f9 ph4 z1 pv1 " + selectedClass}>
<p className="f9 dib">{props.name}</p>
<p className="f9 dib fr">
{unseenCount}
</p>
</div>

View File

@ -0,0 +1,45 @@
import React, { Component } from 'react';
import { ChannelsItem } from './channels-item';
export class GroupItem extends Component {
render() {
const { props, state } = this;
let association = !!props.association ? props.association : {};
let title = association["app-path"] ? association["app-path"] : "Unmanaged Collections";
if (association.metadata && association.metadata.title) {
title = association.metadata.title !== ""
? association.metadata.title : title;
}
let channels = !!props.channels ? props.channels : [];
let first = (props.index === 0) ? "pt1" : "pt4";
let channelItems = channels.map((each, i) => {
const meta = props.linkMetadata[each];
if (!meta) return null;
const selected = (props.selected === each);
const unseenCount = !!props.links[each]
? props.links[each].unseenCount
: 0;
return (
<ChannelsItem
key={each}
link={each}
selected={selected}
unseenCount={unseenCount}
name={meta.metadata.title}
/>
)
})
return (
<div className={first}>
<p className="f9 ph4 fw6 gray3">{title}</p>
{channelItems}
</div>
)
}
}
export default GroupItem;

View File

@ -49,7 +49,7 @@ export class Root extends Component {
<Skeleton
active="collections"
spinner={state.spinner}
associations={associations.link}
associations={associations}
invites={invites}
groups={groups}
rightPanelHide={true}
@ -71,7 +71,7 @@ export class Root extends Component {
return (
<Skeleton
spinner={state.spinner}
associations={associations.link}
associations={associations}
invites={invites}
groups={groups}
rightPanelHide={true}
@ -108,7 +108,7 @@ export class Root extends Component {
return (
<Skeleton
spinner={state.spinner}
associations={associations.link}
associations={associations}
invites={invites}
groups={groups}
selected={resourcePath}
@ -145,7 +145,7 @@ export class Root extends Component {
return (
<Skeleton
spinner={state.spinner}
associations={associations.link}
associations={associations}
invites={invites}
groups={groups}
selected={resourcePath}
@ -198,7 +198,7 @@ export class Root extends Component {
return (
<Skeleton
spinner={state.spinner}
associations={associations.link}
associations={associations}
invites={invites}
groups={groups}
selected={resourcePath}
@ -253,7 +253,7 @@ export class Root extends Component {
return (
<Skeleton
spinner={state.spinner}
associations={associations.link}
associations={associations}
invites={invites}
groups={groups}
selected={resourcePath}

View File

@ -164,4 +164,26 @@ export function cite(ship) {
return shortened;
}
return `~${patp}`;
}
export function alphabetiseAssociations(associations) {
let result = {};
Object.keys(associations).sort((a, b) => {
let aName = a.substr(1);
let bName = b.substr(1);
if (a.metadata && a.metadata.title) {
aName = a.metadata.title !== ""
? a.metadata.title
: a.substr(1);
}
if (b.metadata && b.metadata.title) {
bName = b.metadata.title !== ""
? b.metadata.title
: b.substr(1);
}
return aName.toLowerCase().localeCompare(bName.toLowerCase());
}).map((each) => {
result[each] = associations[each];
})
return result;
}