Welcome to the Trollo! Manage your tasks and collaborate with your team with cute little trolls. Reach new productivity peaks with cheerful and colorful trolls who will keep track of your work! Inspired by both Trello and the movie Trolls (I encourage you to checkout both if you don't know about them!)
live site HERE!
Similar to Trello, user can create boards for their projects, invite team to be on board, and add lists of todos and other tasks. Under the list, you may add card and assign work to whoever is on board, and add due dates and comments on the card.
- React & Redux
- Ruby on Rails
- Javascript
- SCSS
drag and drop is a common feature you see on all kinds of sites, but I didn't realize it's actually not easy to implement it. The frontend challenges are to precisely know which card/list is dragged and dropped to where, and send the updated order to backend so the state persist even after users refresh the page. In order to keep track of the movements, I made each card index in a list structure like a node tree, each card contains a predecessor id, so it knows who to go after.
def assign_order
list = self.list
cards_in_list = list.cards
if cards_in_list == []
self.update(predecessor_id: 0)
else
self.update(predecessor_id: list.cards.last.id)
end
return self.predecessor_id
end
Everytime a card switches position in the list, it will update its predecessor id. I also use sorting algorithm to order the cards based on their predecessor id so it will render the right order on page.
Using the technique of debounce, the search will only fire a HTTP request after the user finish typing. Thus reduces the number of API calls sent to server and is optimized for growth of user size.
handleSearch(e) {
this.setState({
search: e.target.value,
});
this.debounce();
}
debounce() {
let { timerId, search } = this.state;
const { matchedUsers } = this.props;
clearTimeout(timerId);
timerId = setTimeout(() => matchedUsers(search), 200);
this.setState({ timerId });
}
As user can either share a board or a card, creating a polymorphic tables make senses and will be easier to manage associations going further.
class Share < ApplicationRecord
validates :user_id, exclusion: { in: -> (share) {[share.shareable.author.id]}, message: "can't invite themselves"}
belongs_to :shareable, polymorphic: true
belongs_to :user
end
Still in process to make the site better with notification features and teamwork data visualization. Stay tuned with my Github and Linkedin for progress!
Thank You!