Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial refactor of todo-mvc-kitchensink #190

Merged
merged 39 commits into from
Feb 23, 2017
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ac961f2
Starting to move over to classes
rorticus Feb 9, 2017
fd3ffb3
More updates
rorticus Feb 10, 2017
a4452f5
Getting it all together
rorticus Feb 10, 2017
b5c52d0
Setting the right widget-core version
rorticus Feb 10, 2017
fbb3c6f
Misc fixes
rorticus Feb 10, 2017
8d1579c
Updating package classes
rorticus Feb 15, 2017
99360a2
Updating to latest widget-core, converting to use class based routes
rorticus Feb 15, 2017
32f9c79
Adding conditional to not error during tests
rorticus Feb 15, 2017
a505222
Converting to CSS
rorticus Feb 16, 2017
df7560d
More CSS styles
rorticus Feb 16, 2017
bbb8762
More CSS
rorticus Feb 16, 2017
00377f7
Removing css.d.ts
rorticus Feb 16, 2017
16bd2f4
Removing more unused styles
rorticus Feb 16, 2017
bcee354
WIP
rorticus Feb 16, 2017
ed0d7d7
WIP
rorticus Feb 16, 2017
1cd2bbc
WIP
rorticus Feb 16, 2017
369a5c2
More class conversions
rorticus Feb 16, 2017
b60c950
Adding i18n
rorticus Feb 17, 2017
1feb945
More i18n
rorticus Feb 20, 2017
bdabc7d
Enough i18n for now..
rorticus Feb 20, 2017
9366148
Adding a widget that using dojo/core/request
rorticus Feb 20, 2017
f9fe3ef
Making github issues a custom element
rorticus Feb 20, 2017
eb31ada
Starting to add theme
rorticus Feb 21, 2017
5f3132c
Adding theming
rorticus Feb 21, 2017
666391b
Adding pirate theme
rorticus Feb 21, 2017
ab63a9b
Fixing style errors
rorticus Feb 22, 2017
27e290f
Updating css
rorticus Feb 22, 2017
7f896ca
Updating tests
rorticus Feb 22, 2017
d5eb64a
Fixing infinite github bug
rorticus Feb 22, 2017
41b30a8
Updating styles
rorticus Feb 22, 2017
508567f
Renaming file
rorticus Feb 22, 2017
7819297
Removing to rename files
rorticus Feb 22, 2017
b63cb74
More renaming files..
rorticus Feb 22, 2017
9f40127
Code review feedback
rorticus Feb 22, 2017
07c64c2
Removing wrong cased file
rorticus Feb 22, 2017
f8d7cf6
Renaming file for proper casing
rorticus Feb 22, 2017
81ad8f1
Making custom elements shims external
rorticus Feb 22, 2017
7c85feb
Removing custom element
rorticus Feb 22, 2017
ddaa025
Conditionally loading custom element, fixing FF tests
rorticus Feb 23, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions todo-mvc-kitchensink/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,31 @@
"npm": ">=3"
},
"devDependencies": {
"@dojo/cli-build-webpack": "2.0.0-alpha.8",
"@dojo/cli-test-intern": "^2.0.0-alpha.1",
"@dojo/cli-build-webpack": "2.0.0-alpha.13",
"@dojo/cli-test-intern": "^2.0.0-alpha.3",
"@dojo/interfaces": "^2.0.0-alpha.11",
"@types/chai": "^3.4.34",
"@types/es6-shim": "~0.31.0",
"@types/glob": "~5.0.0",
"@types/grunt": "~0.4.0",
"@types/node": "^6.0.46",
"chai": "^3.5.0",
"grunt": "^1.0.1",
"grunt-dojo2": "^2.0.0-beta.16",
"grunt-dojo2": "^2.0.0-beta.28",
"grunt-tslint": "^3.0.0",
"intern": "~3.4.1",
"tslint": "^3.15.1",
"typescript": "~2.1.4"
"typescript": "^2.2.0"
},
"dependencies": {
"@dojo/compose": "^2.0.0-beta.21",
"@dojo/core": "^2.0.0-alpha.20",
"@dojo/core": "2.0.0-alpha.24",
"@dojo/has": "^2.0.0-alpha.7",
"@dojo/loader": "^2.0.0-beta.9",
"@dojo/routing": "^2.0.0-alpha.8",
"@dojo/shim": "^2.0.0-beta.8",
"@dojo/routing": "^2.0.0-alpha.9",
"@dojo/shim": "2.0.0-beta.9",
"@dojo/stores": "^2.0.0-alpha.9",
"@dojo/widgets": "^2.0.0-alpha.19",
"@dojo/widget-core": "2.0.0-alpha.25",
"@dojo/i18n": "2.0.0-alpha.6",
"@webcomponents/custom-elements": "^1.0.0-alpha.3",
"maquette": ">=2.3.7 <=2.4.1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you bump this to 2.4.3 please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumped!

"todomvc-app-css": "^2.0.6",
"todomvc-common": "^1.0.2"
Expand Down
96 changes: 96 additions & 0 deletions todo-mvc-kitchensink/src/App.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { deepAssign } from '@dojo/core/lang';
import { v, w } from '@dojo/widget-core/d';
import { DNode } from '@dojo/widget-core/interfaces';
import { I18nProperties, I18nMixin } from '@dojo/widget-core/mixins/I18n';
import { theme, ThemeableMixin, ThemeableProperties } from '@dojo/widget-core/mixins/Themeable';
import { WidgetBase } from '@dojo/widget-core/WidgetBase';
import * as styles from './widgets/styles/App.css';
import pirateThemeStyles from './themes/pirate';
import { AppFooter } from './widgets/AppFooter';
import Home from './widgets/Home';
import { ThemeSwitcher } from './widgets/ThemeSwitcher';
import TodoDetails from './widgets/TodoDetails';

interface AppProperties extends ThemeableProperties, I18nProperties {
widgets?: any;
todos?: Item[];
todo?: string;
activeFilter?: string;
activeView?: string;
search?: string;
todoDetails?: Item;
pirateTheme?: boolean;
}

export interface Item {
id: string;
label?: string;
completed?: boolean;
createdOn?: Date;
editing: boolean;
}

function createWidget(widgetName: string, widgetProperties: any): DNode {
switch (widgetName) {
case 'main':
return w(Home, widgetProperties);
case 'todo-details':
return w(TodoDetails, widgetProperties);
}

return null;
}

let app: App = <any> null;

@theme(styles)
export class App extends I18nMixin(ThemeableMixin(WidgetBase))<AppProperties> {
constructor() {
super();

app = this;
this.applyTheme();
}

applyTheme() {
this.setProperties(deepAssign({}, this.properties, {
theme: this.properties.pirateTheme ? pirateThemeStyles : undefined
}));
}

changeTheme(wantsPirate: boolean) {
this.setProperties(deepAssign({}, this.properties, {
pirateTheme: wantsPirate
}));

this.applyTheme();
}

render() {
const { widgets = [ [ 'main', {} ] ], pirateTheme = false } = this.properties;

return v('div', {}, [
v('section', {
classes: this.classes(styles.todoapp).get()
}, [
w(ThemeSwitcher, {
theme: this.properties.theme,
wantsPirate: pirateTheme,
onChange: this.changeTheme
})
].concat(widgets.map((widget: any) => {
return createWidget(widget[ 0 ], <any> {
...this.properties, ...widget[ 1 ],
id: <string> widget[ 0 ]
});
}))),
w(AppFooter, {
theme: this.properties.theme
})
]);
}
}

export default function () {
return app;
};
63 changes: 43 additions & 20 deletions todo-mvc-kitchensink/src/actions/todoStoreActions.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,56 @@
import todoStore, { Item } from '../stores/todoStore';
import createFilter from '@dojo/stores/query/createFilter';
import { assign } from '@dojo/core/lang';
import { deepAssign } from '@dojo/core/lang';
import app, { Item } from '../App';

let id = 0;

export const addTodo = function({ label, completed }: { label: string, completed: boolean }) {
return todoStore.add({ id: `${id++}`, label, completed, createdOn: new Date(), editing: false });
export const addTodo = function ({ label, completed }: { label: string, completed: boolean }) {
const { todos = [] } = app().properties;

todos.push({ id: `${id++}`, label, completed, createdOn: new Date(), editing: false });

app().setProperties(deepAssign({}, app().properties, { todos }));
};

export const deleteTodo = function({ id }: { id: string }) {
return todoStore.delete(id);
export const deleteTodo = function ({ id }: { id: string }) {
const { todos = [] } = app().properties;

app().setProperties(deepAssign({}, app().properties, {
todos: todos.filter((todo: Item) => {
return todo.id !== id;
})
}));
};

export const deleteCompleted = function() {
return todoStore.fetch(createFilter<Item>().equalTo('completed', true))
.then((items: Item[]) => todoStore.identify(items))
.then((ids: string[]) => todoStore.delete(ids));
export const deleteCompleted = function () {
const { todos = [] } = app().properties;

app().setProperties(deepAssign({}, app().properties, {
todos: todos.filter((todo: Item) => {
return todo.completed !== true;
})
}));
};

export const toggleAll = function({ checked: completed }: { checked: boolean }) {
return todoStore.fetch()
.then((items: Item[]) => {
return items.map((item) => {
return assign({}, item, <any> { completed });
});
export const toggleAll = function ({ checked: completed }: { checked: boolean }) {
const { todos = [] } = app().properties;

app().setProperties(deepAssign({}, app().properties, {
todos: todos.map((item: Item) => {
return deepAssign({}, item, <any> { completed });
})
.then((items) => todoStore.patch(items));
}));
};

export const updateTodo = function(item: Item) {
return todoStore.patch(item);
export const updateTodo = function (item: Item) {
const { todos = [] } = app().properties;

app().setProperties(deepAssign({}, app().properties, {
todos: todos.map((todo: Item) => {
if (todo.id === item.id) {
return deepAssign({}, todo, item);
}

return todo;
})
}));
};
63 changes: 33 additions & 30 deletions todo-mvc-kitchensink/src/actions/userActions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { assign } from '@dojo/core/lang';
import widgetStore from '../stores/widgetStore';
import { addTodo, deleteCompleted, deleteTodo, toggleAll, updateTodo } from './todoStoreActions';
import { deepAssign } from '@dojo/core/lang';
import app, { Item } from '../App';
import router, { todoViewRoute } from '../routes';
import { Item } from '../stores/todoStore';
import { addTodo, deleteCompleted, deleteTodo, toggleAll, updateTodo } from './todoStoreActions';

interface FormEvent extends Event {
target: HTMLInputElement;
Expand All @@ -12,11 +11,19 @@ interface FormInputEvent extends KeyboardEvent {
target: HTMLInputElement;
}

/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented out code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted

const completedCount = afterAll.filter(({ completed }) => completed).length;
const activeCount = afterAll.length - completedCount;
const allCompleted = afterAll.length === completedCount;
*/

export const todoInput = function (this: any, { which, target: { value: label } }: FormInputEvent) {
if (which === 13 && label) {
addTodo({ label, completed: false });
widgetStore.patch({ id: 'todo-app', todo: '' });
this.invalidate();

app().setProperties(deepAssign({}, app().properties, {
todo: ''
}));
}
};

Expand All @@ -30,47 +37,45 @@ function toggleEditing(todos: Item[], todoId: string, editing: boolean): Item[]
}

export const todoEdit = function (this: any, event: KeyboardEvent) {
const { state: { id } } = this;
const { properties: { todoId } } = this;
if (event.type === 'keypress' && event.which !== 13 && event.which !== 32) {
return;
}
widgetStore.get('todo-app').then((todoListState: any) => {
const link = router.link(todoViewRoute, {
filter: todoListState.activeFilter,
view: todoListState.activeView,
todoId: id
});
document.location.href = link;

const link = router.link(todoViewRoute, {
filter: app().properties.activeFilter,
view: app().properties.activeView,
todoId
});

document.location.href = link;
};

export const todoEditInput = function (this: any, event: FormInputEvent) {
const { state } = this;
const { properties } = this;
if (event.which === 13) {
todoSave.call(this, event);
}
else if (event.which === 27) {
widgetStore.get('todo-app').then((todoListState: any) => {
const { todos } = todoListState;
todoListState.todos = toggleEditing(todos, state.id, false);
widgetStore.patch({ id: 'todo-app', todoListState });
});
app().setProperties(deepAssign({}, app().properties, {
todos: toggleEditing(app().properties.todos || [], properties.id, false)
}));
}
};

export const todoSave = function (this: any, event: FormInputEvent) {
const { state } = this;
const { properties } = this;
if (!event.target.value) {
deleteTodo(state);
deleteTodo(properties);
}
else {
updateTodo(assign(state, { label: event.target.value, editing: false }));
updateTodo(deepAssign({}, properties, { label: event.target.value, editing: false }));
}
};

export const todoRemove = function (this: any) {
const { state } = this;
deleteTodo({ id: state.id });
const { properties } = this;
deleteTodo({ id: properties.todoId });
};

export const todoToggleComplete = function (this: any) {
Expand All @@ -87,9 +92,7 @@ export const clearCompleted = function () {
};

export const updateSearch = function (this: any, searchQuery: string) {
widgetStore.get('todo-app').then((todoListState: any) => {
todoListState.search = searchQuery;

widgetStore.patch({ id: 'todo-app', todoListState });
});
app().setProperties(deepAssign({}, app().properties, {
search: searchQuery
}));
};
45 changes: 25 additions & 20 deletions todo-mvc-kitchensink/src/actions/widgetStoreActions.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import { StoreDelta } from '@dojo/stores/store/mixins/createObservableStoreMixin';
import widgetStore from '../stores/widgetStore';
import todoStore from '../stores/todoStore';
import { Item } from '../stores/todoStore';

export const putTodo = function({ afterAll = [] }: StoreDelta<any>) {
const completedCount = afterAll.filter(({ completed }) => completed).length;
const activeCount = afterAll.length - completedCount;
const allCompleted = afterAll.length === completedCount;

return widgetStore.patch({ id: 'todo-app', todos: afterAll, activeCount, completedCount, allCompleted });
};
import { deepAssign } from '@dojo/core/lang';
import app, { Item } from '../App';

export const setHierarchy = function (this: any, widgets: [ string, any ][]) {
widgetStore.patch({ id: 'todo-app', widgets });
app().setProperties(deepAssign({}, app().properties, {
widgets
}));
};

export const filterAndView = function (this: any, filter: 'active' | 'all' | 'completed', view: 'list' | 'cards') {
const { state: { activeView = view, activeFilter = filter } = { } } = this;
widgetStore.patch({ id: 'todo-app', activeView, activeFilter });
const { state: { activeView = view, activeFilter = filter } = {} } = this;

app().setProperties(deepAssign({}, app().properties, {
activeView, activeFilter
}));
};

export const showTodoDetails = function(todoId: string) {
return todoStore.get(todoId).then(( todo: Item) => {
widgetStore.patch({ id: 'todo-details', todoDetails: todo }).then(() => {
setHierarchy([ [ 'main', {} ], [ 'todo-details', { id: 'todo-details', externalState: widgetStore } ] ]);
});
export const showTodoDetails = function (todoId: string) {
let details: Item | null = null;

(app().properties.todos || []).forEach((todo) => {
if (todo.id === todoId) {
details = todo;
}
});

if (details !== null) {
app().setProperties(deepAssign({}, app().properties, {
todoDetails: details
}));

setHierarchy([ [ 'main', {} ], [ 'todo-details', { id: 'todo-details' } ] ]);
}
};
Loading