Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
feat: replace project dropdown with page tile overview (fixes #176)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mauricio Palma authored and TheReincarnator committed Apr 10, 2018
1 parent de87bb5 commit 1c568ca
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 153 deletions.
10 changes: 3 additions & 7 deletions src/component/container/app.tsx
Expand Up @@ -14,14 +14,13 @@ import Link from '../../lsg/patterns/link';
import { createMenu } from '../../electron/menu';
import * as MobX from 'mobx';
import { observer } from 'mobx-react';
import { PageList } from '../../component/container/page-list';
import * as PathUtils from 'path';
import { PatternListContainer } from '../../component/container/pattern-list';
import PatternsPane from '../../lsg/patterns/panes/patterns-pane';
import { PreviewPaneWrapper } from '../../component/container/preview-pane-wrapper';
import * as ProcessUtils from 'process';
import { ProjectList } from '../../component/container/project-list';
import { PropertyList } from '../../component/container/property-list';
import { ProjectList } from './project-list';
import { PropertyList } from './property-list';
import PropertyPane from '../../lsg/patterns/panes/property-pane';
import * as React from 'react';
import Space, { Size as SpaceSize } from '../../lsg/patterns/space';
Expand Down Expand Up @@ -65,6 +64,7 @@ export class App extends React.Component {
}
}

@MobX.action
protected handleChromeToggle(evt: React.MouseEvent<HTMLElement>): void {
this.projectListVisible = !this.projectListVisible;
}
Expand Down Expand Up @@ -144,7 +144,6 @@ export class App extends React.Component {
}

public render(): JSX.Element {
// Todo: project and page don't update on page change
const project = store.getCurrentProject();
const title = `${project && project.getName()}`;
const styleguide = store.getStyleguide();
Expand All @@ -167,9 +166,6 @@ export class App extends React.Component {
{project && [
<SideBar key="left" directionVertical hasPaddings>
<ElementPane>
<Space sizeBottom={SpaceSize.L}>
<PageList />
</Space>
<ElementList />
</ElementPane>
<PatternsPane>
Expand Down
144 changes: 0 additions & 144 deletions src/component/container/page-list.tsx

This file was deleted.

26 changes: 26 additions & 0 deletions src/component/page-list/page-list-composite.tsx
@@ -0,0 +1,26 @@
import Layout from '../../lsg/patterns/layout';
import { observer } from 'mobx-react';
import { PageRef } from '../../store/page/page-ref';
import { PageTileContainer } from './page-tile-container';
import * as React from 'react';

export interface PageListProps {
focusStates: boolean[];
pages: PageRef[];
onClick(event: React.MouseEvent<HTMLElement>, index: number): void;
}

export const PageListComposite: React.StatelessComponent<PageListProps> = observer(
(props): JSX.Element => (
<Layout>
{props.pages.map((page: PageRef, i: number) => (
<PageTileContainer
focused={props.focusStates[i]}
key={page.getId()}
onClick={e => props.onClick(e, i)}
page={page}
/>
))}
</Layout>
)
);
47 changes: 47 additions & 0 deletions src/component/page-list/page-list-container.tsx
@@ -0,0 +1,47 @@
import * as MobX from 'mobx';
import { observer } from 'mobx-react';
import { PageListComposite } from './page-list-composite';
import { PageRef } from '../../store/page/page-ref';
import { Project } from '../../store/project';
import * as React from 'react';
import { Store } from '../../store/store';

@observer
export class PageListContainer extends React.Component {
@MobX.observable public focusStates: boolean[] = this.generateInitialFocusList(false);

@MobX.action
protected generateInitialFocusList(bool: boolean): boolean[] {
const pages = this.getPages();
const states: boolean[] = [];
pages.forEach((page: PageRef) => {
states.push(bool);
});
return states;
}
protected getPages(): PageRef[] {
const project: Project | undefined = Store.getInstance().getCurrentProject();
return project ? project.getPages() : [];
}

@MobX.action
protected handleClick(e: React.MouseEvent<HTMLElement>, i: number): void {
if (this.focusStates[i]) {
return;
}
this.focusStates.forEach((state, index) => {
this.focusStates[index] = false;
});
this.focusStates[i] = !this.focusStates[i];
}

public render(): JSX.Element {
return (
<PageListComposite
focusStates={this.focusStates}
pages={this.getPages()}
onClick={this.handleClick}
/>
);
}
}
28 changes: 28 additions & 0 deletions src/component/page-list/page-list-preview.tsx
@@ -0,0 +1,28 @@
import * as React from 'react';

import { colors } from '../../lsg/patterns/colors';
import Copy from '../../lsg/patterns/copy';
import { Headline } from '../../lsg/patterns/headline';
import Space, { Size } from '../../lsg/patterns/space';
import { Store } from '../../store/store';

export const PageListPreview: React.StatelessComponent = props => {
const project = Store.getInstance().getCurrentProject();
if (!project) {
return <>props.children</>;
}
const dateString = new Intl.DateTimeFormat().format(project.getLastChangedDate());
return (
<Space size={[Size.XXXL, Size.XL, Size.XS, Size.XL]}>
<Space size={[Size.S, Size.S, Size.XXXL]}>
<Headline order={3} tagName="h1">
{project.getName()}
</Headline>
<Copy textColor={colors.grey60}>
Last change: {dateString} by {project.getLastChangedAuthor()}
</Copy>
</Space>
{props.children}
</Space>
);
};
101 changes: 101 additions & 0 deletions src/component/page-list/page-tile-container.tsx
@@ -0,0 +1,101 @@
import { PreviewTile } from '../../lsg/patterns/preview-tile/index';
import Space, { Size } from '../../lsg/patterns/space/index';
import * as MobX from 'mobx';
import { observer } from 'mobx-react';
import { PageRef } from '../../store/page/page-ref';
import * as React from 'react';
import { Store } from '../../store/store';

export interface PageTileContainerProps {
focused: boolean;
onClick: React.MouseEventHandler<HTMLElement>;
page: PageRef;
}

@observer
export class PageTileContainer extends React.Component<PageTileContainerProps> {
@MobX.observable public editable: boolean = false;
@MobX.observable public inputValue: string = '';

public constructor(props: PageTileContainerProps) {
super(props);
this.inputValue = this.inputValue || this.props.page.getName();

this.handleBlur = this.handleBlur.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
this.handleDoubleClick = this.handleDoubleClick.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.renamePage = this.renamePage.bind(this);
}

@MobX.action
protected handleBlur(): void {
this.renamePage();
}

@MobX.action
protected handleChange(e: React.ChangeEvent<HTMLInputElement>): void {
this.inputValue = e.target.value;
}

@MobX.action
protected handleClick(e: React.MouseEvent<HTMLElement>): void {
this.props.onClick(e);
if (this.props.focused) {
this.editable = true;
}
}

protected handleDoubleClick(e: React.MouseEvent<HTMLElement>): void {
Store.getInstance().openPage(this.props.page.getId());
}

@MobX.action
protected handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>): void {
switch (e.key) {
case 'Escape':
this.inputValue = this.props.page.getName();
this.editable = false;
break;

case 'Enter':
this.renamePage();
break;

default:
return;
}
}
@MobX.action
protected renamePage(): void {
if (!this.inputValue) {
this.inputValue = this.props.page.getName();
this.editable = false;
return;
}

this.props.page.setName(this.inputValue);
Store.getInstance().save();
this.editable = false;
}

public render(): JSX.Element {
return (
<Space size={Size.S}>
<PreviewTile
editable={this.editable}
focused={this.props.focused}
id={this.props.page.getId()}
name={this.inputValue}
onBlur={this.handleBlur}
onChange={this.handleChange}
onClick={this.handleClick}
onDoubleClick={this.handleDoubleClick}
onKeyDown={this.handleKeyDown}
value={this.inputValue}
/>
</Space>
);
}
}

0 comments on commit 1c568ca

Please sign in to comment.