├── .meteor
├── .gitignore
├── release
└── packages
├── collections
├── cards.js
└── lists.js
├── server
├── publications.js
└── main.js
├── client
├── views
│ ├── card.html
│ ├── board.html
│ ├── list.html
│ └── main.html
└── main.js
├── README.md
├── LICENSE
└── trallo.css
/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/.meteor/release:
--------------------------------------------------------------------------------
1 | 0.6.4.1
2 |
--------------------------------------------------------------------------------
/collections/cards.js:
--------------------------------------------------------------------------------
1 | Cards = new Meteor.Collection('cards');
2 |
--------------------------------------------------------------------------------
/collections/lists.js:
--------------------------------------------------------------------------------
1 | Lists = new Meteor.Collection('lists');
2 |
--------------------------------------------------------------------------------
/server/publications.js:
--------------------------------------------------------------------------------
1 | Meteor.publish('cards', function() {
2 | return Cards.find();
3 | });
4 |
5 | Meteor.publish('lists', function() {
6 | return Lists.find();
7 | });
8 |
--------------------------------------------------------------------------------
/client/views/card.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ task }} edit
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | #
3 | # 'meteor add' and 'meteor remove' will edit this file for you,
4 | # but you can also edit it by hand.
5 |
6 | preserve-inputs
7 | bootstrap
8 | insecure
9 |
--------------------------------------------------------------------------------
/client/views/board.html:
--------------------------------------------------------------------------------
1 |
2 | {{#each lists }}
3 | {{> list}}
4 | {{/each }}
5 |
8 |
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | trallo
2 | ======
3 |
4 | Trello Clone using meteor. Live instance on [http://trallo.meteor.com](http://trallo.meteor.com)
5 |
6 | ## Usage:
7 | You need to have [Meteor](http://www.meteor.com/) installed.
8 |
9 | Clone the repository
10 |
11 | git clone https://github.com/daikeren/trallo.git
12 |
13 | Run the project
14 |
15 | cd trallo
16 | meteor
17 |
--------------------------------------------------------------------------------
/server/main.js:
--------------------------------------------------------------------------------
1 | Meteor.startup(function () {
2 | if ( Lists.find().count() === 0 ) {
3 | Lists.insert({
4 | name: 'TODO',
5 | order: 1
6 | });
7 | Lists.insert({
8 | name: 'DOING',
9 | order: 2
10 | });
11 | Lists.insert({
12 | name: 'DONE',
13 | order: 3
14 | });
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/client/views/list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ name }}
4 |
5 | {{#each cards _id }}
6 | {{> card }}
7 | {{/each }}
8 | - Add a card
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/client/views/main.html:
--------------------------------------------------------------------------------
1 |
2 | Trallo
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{> board }}
12 |
13 |
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Andy Dai
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/trallo.css:
--------------------------------------------------------------------------------
1 | li {
2 | list-style: none;
3 | font-size: 16px;
4 | }
5 |
6 | li a {
7 | float: right;
8 | margin: 3px ;
9 | font-size: 12px;
10 | }
11 |
12 | ul {
13 | padding: 10px ;
14 | }
15 |
16 | h2 {
17 | font-size: 18px ;
18 | }
19 |
20 | .list {
21 | width: 300px ;
22 | float: left;
23 | padding: 2px 8px ;
24 | background-color: #ddd ;
25 | margin: 10px ;
26 | border: 1px solid #666 ;
27 | border-radius: 7px ;
28 | }
29 |
30 | .card {
31 | cursor: move;
32 | border-radius: 3px ;
33 | border: 1px solid #666 ;
34 | margin: 5px ;
35 | padding: 4px ;
36 | word-wrap: break-word;
37 | background-color: white;
38 | }
39 |
40 | .card:hover {
41 | -webkit-transform:rotate(2deg);
42 | -o-transform:rotate(2deg);
43 | -ms-transform:rotate(2deg);
44 | -moz-transform:rotate(2deg);
45 | transform:rotate(2deg);
46 | }
47 |
48 | .ui-state-highlight {
49 | width: 300px ;
50 | height: 300px ;
51 | float: left;
52 | padding: 2px 8px ;
53 | background-color: #999 ;
54 | margin: 10px ;
55 | border: 1px solid #666 ;
56 | border-radius: 7px ;
57 | }
58 |
--------------------------------------------------------------------------------
/client/main.js:
--------------------------------------------------------------------------------
1 | Meteor.subscribe('cards');
2 | Meteor.subscribe('lists');
3 |
4 | function initialSortable() {
5 | $('.board').sortable({
6 | placeholder: 'ui-state-highlight',
7 | helper: 'clone',
8 | update: function(event, ui) {
9 | console.log('.board update');
10 | var $this = $(this);
11 | var lists = $this.sortable('toArray');
12 |
13 | _.each(lists, function(list, index){
14 | Lists.update(
15 | {_id: list.substring(1)},
16 | {$set: {order: index+1}}
17 | );
18 | });
19 | },
20 | stop: function(event, ui) {
21 | initialSortable();
22 | }
23 | }).disableSelection();
24 |
25 | $('ul').sortable({
26 | connectWith: 'ul',
27 | dropOnEmpty: true,
28 | update: function(event, ui) {
29 | var $this = $(this);
30 | var cards = $this.sortable('toArray');
31 | var _status = $this.attr('id');
32 | _.each(cards, function(card, index){
33 | Cards.update(
34 | {_id: card},
35 | {$set: {status: _status, position: index + 1}}
36 | );
37 | });
38 | },
39 | stop: function(event, ui) {
40 | var parent = ui.item.parent();
41 | var id = parent.attr('id');
42 | $("#"+id).find("li[data-status!="+id+"]").remove();
43 | initialSortable();
44 | }
45 | }).disableSelection();
46 | }
47 |
48 | Template.board.helpers({
49 | lists: Lists.find({}, {sort: {order: 1}})
50 | });
51 |
52 | Template.list.cards = function(status) {
53 | console.log(status);
54 | return Cards.find(
55 | {status: status},
56 | {sort: {position: 1, task: 1}}
57 | );
58 | };
59 |
60 | Template.board.events = {
61 | "click .edit": function() {
62 | if ( $('button').length > 0 ) {
63 | return false ;
64 | }
65 | var _id = this._id;
66 | $('#'+_id).html('');
67 | $('button').on('click', function(){
68 | var _task = $('#'+_id +' textarea').val();
69 | console.log(_id);
70 | console.log(_task);
71 | Cards.update({_id: _id}, { $set: {task: _task}});
72 | $('#'+_id).html(_task+"edit");
73 | return false;
74 | });
75 | return false;
76 | },
77 | "click .add": function(event, template) {
78 | if ( $('button').length > 0 ) {
79 | return false ;
80 | }
81 | var status = $(event.target).parent().parent().attr('id') ;
82 | var li_wrapper = $(event.target).parent();
83 | console.log(status);
84 | console.log(li_wrapper);
85 | li_wrapper.addClass('card ui-state-default');
86 | li_wrapper.html('');
87 | $('button').on('click', function(){
88 | var taskName = $('textarea').val();
89 | var _status = status;
90 | console.log(taskName);
91 | var length = Cards.find({status: _status }).count();
92 | if ( $.trim(taskName).length !== 0) {
93 | Cards.insert({
94 | task: taskName,
95 | status: _status,
96 | position: length + 1
97 | });
98 | }
99 | li_wrapper.removeClass('card ui-state-default');
100 | li_wrapper.html('Add a card');
101 | return false;
102 | });
103 | },
104 | "click .add_list": function(event, template) {
105 | if ( $('button').length > 0 ) {
106 | return false ;
107 | }
108 |
109 | var list_wrapper = $(event.target).parent();
110 | console.log(list_wrapper);
111 | list_wrapper.addClass('ui-state-default');
112 | list_wrapper.html('');
113 | $('button').on('click', function(){
114 | var listName = $('textarea').val();
115 | var length = Lists.find().count();
116 | if ( $.trim(listName).length !== 0) {
117 | Lists.insert({
118 | name: listName,
119 | order: length + 1
120 | });
121 | }
122 | list_wrapper.removeClass('ui-state-default');
123 | list_wrapper.html('');
124 | return false;
125 | });
126 | }
127 | };
128 |
129 | Meteor.startup(function () {
130 | initialSortable();
131 | });
132 |
--------------------------------------------------------------------------------