├── .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 | 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 | 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 | 12 | -------------------------------------------------------------------------------- /client/views/main.html: -------------------------------------------------------------------------------- 1 | 2 | Trallo 3 | 4 | 5 | 6 | 7 | 8 | 9 | Fork me on GitHub 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('

Add a list

'); 124 | return false; 125 | }); 126 | } 127 | }; 128 | 129 | Meteor.startup(function () { 130 | initialSortable(); 131 | }); 132 | --------------------------------------------------------------------------------