Skip to content
Asana Clone
JavaScript Ruby CSS Other
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
app fixed most edit task modal bugs, deleting task still causes bugs Nov 6, 2018
basana_wireframe added user search images Aug 9, 2018
bin initial commit May 2, 2018
config fixed task like routes, back is completed. unliketask action.task com… Oct 27, 2018
db created tasklike model, will work on like_create and delete function … Oct 26, 2018
frontend fixed sorting feature Nov 6, 2018
lib initial commit May 2, 2018
log initial commit May 2, 2018
public initial commit May 2, 2018
test created endpoints for new comment features Jul 31, 2018
tmp initial commit May 2, 2018
vendor initial commit May 2, 2018
.gitignore created set up for aws s3 and paperclip, will migrate for attachment … May 14, 2018
.jshintrc frontend auth is setup, needs close buttons on the forms and styling May 8, 2018
= implemented comments infinite scroll Oct 8, 2018
Gemfile modified webpack.config.js, Gemfile, package.json to make basana prod… May 21, 2018
Gemfile.lock Update Aug 9, 2018
Rakefile initial commit May 2, 2018 initial commit May 2, 2018
package.json included pure from recompose to create pure functional component Oct 16, 2018
webpack.config.js modified webpack.config.js, Gemfile, package.json to make basana prod… May 21, 2018


Basana splash


Basana is a single-page project management web application inspired by Asana built with JavaScript, React.js, Redux, PostgreSQL and Ruby on Rails.


Basana allows users to:

  • Create an account
  • Log in / Log out
  • Update profile information
  • Create, edit and delete Teams and Projects
  • Create, edit, complete and assign Tasks to a member or assign a deadline
  • Search for and invite team members

Languages and Libraries

  • JavaScript
  • React.js
  • Redux
  • Ruby
  • Ruby on Rails
  • PostgreSQL
  • HTML5 + CSS3

Implementation in Detail

  • Debounce function

Task title and description are dynamically updated every 1 sec after user stops making changes.

Dynamic update

The TaskForm component is initialized with a timeout instance set as Null. An update function is passed to input field event listener as a callback. Every time when the user changes input, an action is dispatched to mutate the Redux state; the timeout instance is cleared if present and is reset to a new setTimeout object. After 1000 ms, an AJAX request is sent to update the database.

Debounce1 Debounce2

  • User Search

Team member form searches for existing users and completes email addresses upon click.

User search

Debounce function is also implemented here so that an AJAX request to search users is sent whenever user stops typing. Additionally component state controls the visibility of dropdown containing search results. Visibility is toggled through onFocus and onBlur installed on the input field of search bar.

User Search1

setState function of TeamMemberForm component is passed down to its child component UserSearchItem. The child component invokes this callback to mutate the parent component's state. One challenge here was that onBlur(closes the dropdown) and onClick(completes the input field) listens to the same event and event handlers are prioritized in a certain order that the dropdown always closes before the input field is completed. I initially solved this with setTimeout but found out that using onMouseDown instead can fix this issue.

User Search3 User Search4

Future Plans

  • Complete comment feature (edit/delete)
  • Log user's activities on tasks (user1 updated on 06/17/2019)
  • Implement infinite scroll to comment index (display 3 latest comment, scroll to see more)
  • Create report feature ...
You can’t perform that action at this time.