Card Based Project Manager
This project is intended for you to learn the basics of the JavaScript framework Vue to create a reactive, data-oriented, web page.
Submitting Your Work
This project will be added to your portfolio_NETID
repository so there is one single place we can go to find your work during the semester. To submit this project:
- create one separate folder for the all parts of the assignment given below
- within that folder put
index.html
, the main page used to interact with the user- CSS style file(s), if necessary (i.e., it contains different rules from your primary set already defined in the top-level style file)
- JavaScript file(s) you write to implement the specifications
- any JSON data or images used to make your page
- a README file (in plain text or Markdown format) describing your work on the assignment as well as your JavaScript data structure
- then add a very obvious link on your Portfolio web site to each page you have made
Your page must
- display the way you expect in the latest version of Google's Chrome browser on the course Gitlab server
- be written following standard Coding Conventions that is validated using ESLint (JavaScript) or online (Accessibility)
- not produce any warnings (within your control) or errors in the DevTools Console
Specification
Most task list apps are too linear and structured to go beyond the "done" and "not done" status for your tasks — say, to show things that are in progress or have several steps before they get completed. Trello is arguably the most popular project management web app today, used by millions of people and companies including Google, Pixar, National Geographic, and Kickstarter. It gives you a digital workspace whose basic layout is minimalist and yet very flexible: boards organized into lists of cards that can be easily moved around. Each card, when expanded, provides more details and options about the specific task. In this way it helps visualize the state of a project by letting you see the big picture and also drill down to see relevant details. There may be no limit to what people use Trello to organize including managing code projects.
Here is the official Trello guide and a short example of using Trello in action to give you a sense of how the app should work. Your app will definitely be much simplified from the full Trello app, but you should create a similar interface of a project (board in Trello) that contains any number of task lists (columns in Trello), each of which contains any number of cards (cards in Trello :). There are many alternatives to Trello (a few with their pros and cons analyzed, open source only, or a comprehensive list) that have a variety of looks and features that you can use for inspiration.
Functionally, your page should allow users to:
- Work with any number of task lists (columns in Trello):
- Create a list with a name (that can be edited later)
- Show the current number of tasks in the list's title bar
- Duplicate an entire list at once (with a different name) or remove it
- Change the order in which the lists are displayed
- Work with any number of cards within a task list:
- Create a card with a name (that can be edited later)
- Show the current number of comments in the card's title bar
- Duplicate an entire card at once (with a different name) or remove it
- Change the order in which the cards are displayed or move cards to another list
- Work with data within a card:
- Add a description or deadline (such that there is a clear or, perhaps progressive, "highlight" for when a card is past its deadline)
- Select a background color
- Add or remove any number of tags
- Add, edit, remove, or change the order of "comments", sub-tasks, or ideas regarding the task (basically any kind of text a user wants to add)
- Customize the overall project page:
- Edit the name for the project
- Choose a color or upload an image for the page's background
- Create tags that can be used on cards and select colors for those tags
- Search/filter visible cards by any text in the card, tags, deadline, or almost any criteria
- Optional Challenges:
- Allow users to collapse any list or card (showing just its name and count) and then expand them again
- Allow users to use an image or audio file for a card's description in addition to just text
- Support working with multiple projects (boards in Trello) when no project is currently selected and displayed:
- Create a project with a name (that can be edited later) that shows its current number of tasks
- Add a description, deadline, or priority (keep project list in sorted order based on priority first, then by deadline, and then by name)
- Mark projects as done (order them at the bottom of the project selection list by deadline and then by name)
- Duplicate an entire project at once (with a different name)
- Allow users to close a project to take them back to the list of available projects
Implement this page using the JavaScript framework Vue (integrated into your page using the unpkg CDN). We strongly suggest develop your iteratively: making a few small changes at a time and using the Developer Tools: the Console to try JavaScript statements out interactively and Breakpoints to see what is happening in your code; as well as installing the Vue Developer Tool Chrome extension to help clarify where issues are in your code.
Part 1: Non-Interactive Display
Likely the most important way to guarantee success in this project will be figuring out a JavaScript data structure to support easily displaying all of this information using Vue. So this first part requires no new concepts, focusing just on organizing and displaying data, by creating JSON data examples that demonstrate you can display as many different kinds of data "situations" as you can think of (e.g., an empty list, a list with one card, a list with multiple cards, cards with differing number of tags, cards with differing number of comments, etc.). Also create JSON example data for the overall page, including its title, background, tags and their colors, and search text (you do not actually need to implement filtering for this part, but do not forget that it needs to be included). While the page itself does not need to be interactive yet, it should clearly be reactive (e.g., lists and cards should display their counts, cards and tags should display their colors, cards should show they are past their deadline, etc.).
Since the final version of this page will start with no tasks and users will add them interactively, the example data for this part should be declared as one or more variables in a separate JavaScript file that is loaded from your HTML page before your code (as in the Word Game project) and referenced in your Vue data
field rather than fetched dynamically (as in the Quiz project).
Since nothing about the data to be displayed should be hardcoded in the HTML, CSS, or JavaScript, your data structure will need to include nested arrays of objects (like the Quiz project) that support:
- multiple task lists, each with at least a name
- multiple cards per task list, each with at least a name and optionally a description, color, and deadline
- multiple tags per card, each with at least a name and color
- multiple comments per card, each with at least the text to display
Note that it is very likely you will need to add some new fields to your data structure to manage the interactive details in the next part (e.g., when an item is being edited, what the current value is (in case the user cancels), placeholder values, etc.) so be wary of choosing to make arrays composed only of simple values like Strings or numbers. We will go over strategies for this and discuss the details in class this week.
This may look complex but, if you take some time to plan out your entire data structure first to make sure it includes everything you need, you should find it manageable (and maybe even fun). In any case, we strongly recommend that you code interactively, starting as simply as possible and displaying each step as you go to make sure each works separately and also nests as intended using tools such as
- Vue Playground
- Vue DevTools
- BootstrapVue Components for styling and layout (not required but recommended)
Part 2: Complete Interactivity
Using typical HTML input elements as well as icons as buttons (as shown in the ToDo List example) or double clicking (as shown in the interactive URL list example), allow users to edit most, if not all, aspects of the project. In addition to these standard "inline" options, BootstrapVue also makes it easy to provide "higher level" input forms with a variety of configurable options (note, the linked documentation includes interactive areas to experiment with their example code):
With these interaction elements, you will call functions on your Vue app that make changes to your data structure — and that (typically) is it, Vue should handle updating the HTML displayed on your page automatically! As a reminder, to manage these interactive details, you will likely need to add new data fields to your Vue app (global edit state for the entire page) and within your data structure (local edit state for the specific item being created/modified).
Here are some specific kinds of interactions you will need to implement to support the project's required functional features:
- Create new items, either from an empty collection or adding to an existing collection
- Add/remove any item on the page, such as task lists, cards, comments, tags, optional fields, etc.
- Moving/duplicating an existing complex item, such as task lists, cards, etc.
- Edit any text on the page, such as titles, names, descriptions, comments, tags, etc.
- Edit non-text on the page, such as colors and dates
- Enter text for search/filter criteria
In the process of implementing interactivity, you will likely discover omissions or bugs in your data structure's design and implementation — this is completely normal! A sure sign of problems is that changes you make interactively do not trigger updates in your data structure that become visible on the page — remember that, with reactivity, Vue (not you) should take on the majority of the effort/complexity in updating the HTML visible on the page in response to changes made to the data structure (that you have already tested can display all the necessary data). It will likely help to follow the guidance on Vue reactivity idiosyncrasies and best practices.
Before submitting your final version, make sure to test that it works correctly for empty data (e.g., no task lists, no cards, no tags, no comments, no optional fields, etc.) and that it is possible create any of that data from an empty state (e.g., add the first task list, then the first card, then the first tag or comment, etc.).
When submitting, make sure to include your example JSON/JavaScript data structure(s) so we do not have to start from scratch when grading your project (you can just comment the script
line(s) out of your HTML page).
Part 3: Components
Reorganize your single Vue app into as many components as you can both by creating your own and using existing Vue components. Vue components combine JavaScript with HTML templates (and eventually CSS styling) that are instantiated using HTML tags (so if you have been using BootstrapVue, you have already been using components when you use an HTML element like b-card
) and passed parameters using attributes (like setting a title on a b-card
). Components are a standard feature across many frameworks (and, soon, even common within standard HTML) that provide another layer of abstraction above a framework to, again, help support writing less, more readable, code that is much better organized with much less duplication.
However, components that are easy to use, easy to debug, and correctly update your data structure while maintaining reactivity can be tricky to design well. So, as usual, we strongly recommend that you code interactively, making your changes in as clear and structured was as possible and making each step as small as possible to ensure a component works in a single instance before replacing everything. We also recommend that you focus on writing two different kinds of components:
- Input element replacements: provide some enhancement already implemented in your code and allow using a
v-model
on a copy of the simple data oremit
events to communicate a change but do not modify your primary data structure - Data structure accessors: provide some organization or structure to your code (usually around groups of objects) and respond to events from child components to modify your primary data structure by calling methods on it rather than doing it directly
We also strongly recommend putting each component in a separate JavaScript file (as in the examples for this module, but not using a .vue
file as shown in many tutorials using Vue's CLI tool that we will learn later).
In addition to creating your own components, you must use at least these components as well (this example shows how to access and use them):
Managing your primary data structure (or data store) can get complex, error prone, and even make it non-reactive if you simply let every component modify it directly. Instead, we will use a common convention where components never directly change state that belongs to part of the data store and instead call methods on the data store to perform the necessary changes. This allows you to write a small set of methods that control how the data store is changed and correctly maintain the data's reactivity. Moreover, this more closely mirrors how we will access data when it is in a database on a remote server instead of available locally within our app.
Here are some examples that provide good details about the thinking and design of Vue Components, rather than the direct implementation because they use the single file syntax and JavaScript modules that we will learn about in later modules. Also note that you will be managing your data structure yourself (like the examples for this module) and later using a database, rather than learning an additional framework for this part like Flux or Vuex (which are shown in some of the examples below and are overly complex for this project).
- About building an input element replacement component from Building Component Examples by Jay Roberts
- About building data structure accessor components (using Vuex) from A Complete Vue.js Application by Matthias Hager
Your goal should be to not change the logic of you current code very much (just to move it around to different components/files).