npm install
npm run serve
npm run build
npm run test
npm run lint
firebase deploy
Simple task management, attain your dreams.
License: MIT License
Right now tasks are ordered as they exist in firebase, but we probably want to have a better default sort for the different screens. we'd probably want starred tasks at the top for project task listing. For task list we probably want a LIFO sort so that newest tasks are always up at the top.
We currently have a concept of different states a task can be in. We have "today" and "now" which are currently handled as lists that we add/remove tasks to as needed. However, we'd like to have some more states (such as backlog and week) and it becomes difficult to keep these all in sync. We don't want something in the backlog also appearing in today.
Let's move do a defined state field on tasks which we can use to select and filter on our views. By default we'll put all tasks into the "inbox" state where we can triage accordingly.
After #35 is done, take the time to convert the existing completed tasks over. We'll need to write an action in Vuex that filters by completed tasks and then makes the call to updateTask
. We can expose this as a link on the settings page, hit it once, and then delete.
We have notification ui elements already built into attainment:
https://attainment.io/notifications
Let's take advantage of them when we change a task's state in a view that isn't obvious that the change has happened. For example, in the tasks view, we could move something directly into "today" state, but we aren't in the planning view, so we wouldn't see that it's changed state. in these cases, we should get a little brief popup that says that we've changed to the new state.
There are two problems with VimMovement right now:
We should fix this by jumping to the task that is being focused on. Will need to see how we can do this across browsers.
Long-term, I'd like a bit of a Kanban approach where we have a Weekly column, followed by Today, followed by Now. Below the kanban we'd have a list of all backlogged tasks. We can easily move tasks around with keyboard shortcuts.
Much like the work we're doing for #32, we also need a complementary view for the backlog. This will match all tasks that have the state of "backlog" but will filter the following tasks:
You'll notice we filter the exact tasks that we explicitly include in the weekly view.
Sorting will also be very important for the backlog, here's the proposal:
After implementing #28 we broke the ability to move around the task lists with the keyboard. Take a look at how the plugin works and see how we can retrofit to work with the tabbed interface.
We have several views which render multiple arrays on the same page, for example on the Dashboard view we have Now/Today/Starred/Due all in separate sections. Right now, VimMovement can only traverse one of the arrays.
Let's improve this so it can accept multiple sections. I'd imaging we we could take an array of lengths (we don't actually care about the underlying items in the array, we just want to understand its bounds). When we "move" we can return which section we are in and what index within the section is selected.
For example, in the Dashboard if we had no Task in Now, 3 tasks in Today, 0 in Starred, and 5 in Due, we could pass [0, 3, 0, 5]
to VimMovement. The first time we hit j
to move down, VimMovement would return [1,0]
. We'd skip Today because it is zero length and give the first element in the second position. We'd also need to update Dashboard to correctly interpret/focus on the correct element.
We don't have a focus set when we change the view. We should. Let's make focus default to the form field (for views like inbox
) and to the first task in the list (for views like plan
/tasks
).
I'm not able to jump between categories of "Now", "Today", "Week" via VimMovement on the planning page.
We have code in place to show completed tasks on projects that have them, but it isn't working. There is no dropdown shown when I complete tasks in projects.
The current interface for showing project information on a task card looks like this:
<task-card
:id="id"
:projectId="task.projectId">
</task-card>
But, we now automatically lookup the task details in the card component, so we should just pass a boolean to let the card know if we should show it or not:
<task-card
:id="id"
showProject>
</task-card>
Currently keyboard shortcuts are directly defined on the TaskDetail component. Find a good way to move this into its own component (or components) so we can reuse these and have them available for anything that would like to take care of some keyboard powers.
Right now we are just using the default logo/favicon, make something a little more customized to attainment and switch it over globally.
The dashboard should be the place for doing. Right now it just lists starred tasks and due tasks, which means the user is still trying to figure out what to do in the view. Reorganize the Dashboard (potential name change? Action? Doing? Not sure) so that we have two sections:
Now is the task that we are focusing on right now, it will only display the task and should expand so we can see notes, etc. This might be broken out into its own dedicated section in the future. I could see a lot of fun features like starting/stopping pomodoro timers, distraction-free mode, etc.
Below Now is the list of tasks we plan to accomplish today. It will just be a simple list of TaskCards but I'd also like a little section that totals the number of pomodoros across all of the tasks so users have a good sense of if their today list is manageable.
I think the best way to do this is by having dedicated datastructures in vuex. Now will just hold one task object and Today will be an array. This way we can easily reorder the Today list in order of importance in the future. We'll need to do a little bit of work to hook this up to when a task is completed in another view, so we'll want to detect that case and automatically remove from from Today.
In status quo, we have a boolean field completed
and a date field completedAt
to indicate if a task is completed or not. Once #30 is finished, we'll now have an actual state called complete. Refactor tasks to remove the completed
field and use the state entry in order to determine if a task is done. We can keep the completedAt
as is.
I'd like to be able to use vim keybindings to move up/down the task list anywhere and use "o" key to open it up.
right now we have tasks in the now
state set as a property on Vuex. we do this to make it easy to enforce that there is one and only one task that gets the now
distinction, and also make it easy to lookup which task that is for display purposes.
However, it's confusing when we move tasks into now
and they remain in their respective today
or week
buckets. We can have the best of both worlds and keep track of the current now
task as well as set an explicit state on the task.
When a project is completed it shouldn't show up in the general project list. We'll want to filter those out. However, we'll probably want to have an "archived projects" list somewhere so we can go back and bring projects out of an archived state if we need to.
We have a lot of packages in our dependency tree that are several versions behind. Let's go thru and get these current:
$ npm outdated
Package Current Wanted Latest Location
autoprefixer 6.7.7 6.7.7 7.2.5 vue-admin-paper-dashboard
babel-loader 6.4.1 6.4.1 7.1.2 vue-admin-paper-dashboard
babel-plugin-istanbul 3.1.2 3.1.2 4.1.5 vue-admin-paper-dashboard
bootstrap 3.3.7 3.3.7 4.0.0 vue-admin-paper-dashboard
chalk 1.1.3 1.1.3 2.3.0 vue-admin-paper-dashboard
chartist 0.10.1 0.10.1 0.11.0 vue-admin-paper-dashboard
cross-env 3.2.4 3.2.4 5.1.3 vue-admin-paper-dashboard
cross-spawn 5.1.0 5.1.0 6.0.4 vue-admin-paper-dashboard
css-loader 0.26.4 0.26.4 0.28.9 vue-admin-paper-dashboard
eslint 3.19.0 3.19.0 4.16.0 vue-admin-paper-dashboard
eslint-config-standard 10.2.1 10.2.1 11.0.0-beta.0 vue-admin-paper-dashboard
eslint-plugin-html 2.0.3 2.0.3 4.0.2 vue-admin-paper-dashboard
eslint-plugin-node 4.2.3 4.2.3 5.2.1 vue-admin-paper-dashboard
extract-text-webpack-plugin 2.1.2 2.1.2 3.0.2 vue-admin-paper-dashboard
file-loader 0.10.1 0.10.1 1.1.6 vue-admin-paper-dashboard
firebase 4.6.2 4.9.0 4.9.0 vue-admin-paper-dashboard
inject-loader 2.0.1 2.0.1 3.0.1 vue-admin-paper-dashboard
moment 2.19.2 2.20.1 2.20.1 vue-admin-paper-dashboard
node-sass 4.6.1 4.7.2 4.7.2 vue-admin-paper-dashboard
opn 4.0.2 4.0.2 5.2.0 vue-admin-paper-dashboard
sass-loader 5.0.1 5.0.1 6.0.6 vue-admin-paper-dashboard
semver 5.4.1 5.5.0 5.5.0 vue-admin-paper-dashboard
shelljs 0.7.8 0.7.8 0.8.1 vue-admin-paper-dashboard
url-loader 0.5.9 0.5.9 0.6.2 vue-admin-paper-dashboard
vue 2.5.4 2.5.13 2.5.13 vue-admin-paper-dashboard
vue-datetime 0.7.0 0.7.1 1.0.0-beta.2 vue-admin-paper-dashboard
vue-fuse 1.2.1 1.4.0 1.4.0 vue-admin-paper-dashboard
vue-loader 10.3.0 10.3.0 14.0.1 vue-admin-paper-dashboard
vue-moment 3.0.0 3.1.0 3.1.0 vue-admin-paper-dashboard
vue-router 2.8.1 2.8.1 3.0.1 vue-admin-paper-dashboard
vue-style-loader 2.0.5 2.0.5 3.1.2 vue-admin-paper-dashboard
vue-template-compiler 2.5.4 2.5.13 2.5.13 vue-admin-paper-dashboard
webpack 2.7.0 2.7.0 3.10.0 vue-admin-paper-dashboard
webpack-bundle-analyzer 2.9.1 2.9.2 2.9.2 vue-admin-paper-dashboard
webpack-dev-middleware 1.12.0 1.12.2 2.0.4 vue-admin-paper-dashboard
webpack-hot-middleware 2.20.0 2.21.0 2.21.0 vue-admin-paper-dashboard
webpack-merge 2.6.1 2.6.1 4.1.1 vue-admin-paper-dashboard
Should function similarly to the gmail overlay modal which appears when you hit "?".
This should display all keyboard shortcuts to the user with a brief description of what it does.
We standardized on the TaskShortcuts
component for interacting with TaskCards, etc. but it hasn't been carried over to TaskDetail
so we are inconsistent between what keys trigger what action and we have duplicated code. Look into reusing TaskShortcuts
and simplifying.
When the user navigates to the Task view they just currently see a listing of all non-completed tasks. Let's organize this a little better and have a top "menu" much like what is defined in Semantic UI:
https://semantic-ui.com/collections/menu.html
For the following categories:
Bonus points if we can give some easy keyboard shortcut to each.
Most tasks are short and require 30 mins or less to complete. Right now an "action" is more or less equivalent to a pomodoro, which means it gets a budget of 25 mins...too long for a lot of these quick tasks.
I'd like to rethink how actions work in Attainment. We should probably have a bounded scale (e.g. don't allow any task that would take longer than 4-5 hours (it should really be broken down further to smaller subtasks instead) and we should figure out if we should have a linear scale (e.g. 15min, 30min, 45min, 1hr) have some kind of increasing delta between the levels (e.g. 10min, 30min, 1hr, 2hr, 4hr). I like the latter option better but could noodle on it more.
We also should think about display options for this, might be nice to use a series of dots instead of just showing the direct numeric value as we currently are doing.
We have the attainment-chrome-ext repository that can push messages from gmail in to tasks in attainment but it hasn't been updated for the new makeover. Dust it off and get it to work with the current version of attainment.
As the first step in moving vim movements into a component that can be shared, we basically reproduced the same behavior we had in the Tasks component:
Object.keys
to convert that into an array representing every taskId in the ObjectcurrFocusIndex
We then use that id to match on the individual item to set it's focus and put a blue outline around the card. It looks like this:
<div class="flex-col" v-for="(task, id) in projectTasksActive">
<task-card
:id="id"
:task="task"
:isFocused="id === currFocusId" <---- this is where the check takes place
@click.native="toTask(id)">
</task-card>
</div>
But this is problematic, because there are some places where we have the same task listed multiple times on the same page (e.g. starred & due) so we'll show the same row in focus.
We should switch this to just be based on the index on an array. However, I'm not sure how well this will work with the reactive nature of Vue/firebase.
The Tasks component has been cleaned up to have:
Let's do the same for the ProjectDetail component. First step is update the state getters for projectTasksActive
and projectTasksCompleted
to behave like the tasksActive
function.
See if we can update attainment to pick up the new styles in paper-kit. I'm especially interested in the "Nav Tabs" which could be a lot better for our menu tabs on the Tasks view:
http://demos.creative-tim.com/paper-kit/components?_ga=2.80802199.149756553.1522115724-1616025964.1522115724
https://www.creative-tim.com/product/paper-kit
We did the work for tasksActive
, let's do the same for tasksSnoozed
:
tasksSnoozed () {
return this.$store.getters.tasksSnoozed
}
Update the Vuex getter to return this as an array and provide default ordering (snoozedUntil
in ascending order, so we see the next task that will be unsnoozed at the top of the list).
Alongside work for #12, I'd also like to create a new space to triage tasks. The dashboard view currently shows the starred and due tasks, we'll move this over to a new page (name TBD) which has these categories as well as the new "Week" category, for tasks I plan to finish by the end of the week.
This will be the primary place to move things into an actionable state. I'd like to have keyboard shortcuts as well as something that works on mobile (drag & drop would probably be best, but maybe a good chunk of work? maybe some pop-up modal will suffice for now.)
As the task list grows, it becomes harder and harder to select the next thing to be working on. Paradox of choice sets in and you're trying to decide from many options what should be worked on. Most of the time, a random choice would be just fine.
Create a button along the lines of "I'm Feeling Lucky" that will pseudo-randomly select the next task. It can take an optional "time" into consideration which defaults to just 1 action. This will be put into "now" automatically.
Right now the checkbox for projects results in a noop. Let's update to properly archive a project, steps required:
We might want to get a little fancier and actually have a system-wide undo. If we have this, no need to modal and get user okay. If they want to revert, they can just go to the log view and click the revert to get back to prior state.
Right now package.json is a mess. The name/description/etc. are all holdovers from the the original fork of the paper-dashboard project. Let's update to reflect the attainment project and also remove/cleanup packages that aren't in use and update the ones that are to their latest versions.
Attainment has a concept of "Due Dates" for things that have a hard deadline, but sometimes you just want to have a reminder and have something pop back up at a later day. It's not strictly due, just that you don't want to deal with it right now and should pop back into visibility at a later time.
Add a new "snoozedUntil" field on the Task object. When it is set, hide any tasks from the task list/dashboard until the date arrived (or is in the past).
We'll also want a new section in the dashboard for these snoozed tasks when they are ready to appear.
Right now for views like planning we use updatedAt
as the default comparator for sorting, but this is really problematic when you are updating things like # of actions and then the task card moves on you. Let's use createdAt
instead, which will be a more stable ordering in views.
Right now a
increments the number of completed actions and A
increments the total actions required. I'd like to swap this as it's a faster workflow to hit "aaw" to give two actions and then move into weekly status.
Much like #14, we have all of the logic for the vim-style movement held on Tasks.vue. Let's move this into a separate component that can be reused on any list to provide common behavior for moving around in Attainment.
This will be the default spot for all new tasks that get created and will be the place where the user is able to triage and set initial details like duedate, bolts, etc.
We'll move the TaskAdder form to only reside here and simplify the other views around their actual intent (e.g. Planning should be solely for the purpose of figuring out what to do this week/today, not about new tasks to be added).
We now have a way to add VimMovement
to multiple sections on a page with 65c3a6b. Let's enable this functionality where we could use it most, on the Dashboard page. We can use the commit as a good reference for how to get this integrated with the page.
This is what the addTask
func looks like on the Tasks
component:
addTask (e) {
const taskName = e.trim()
if (taskName.length === 0) {
console.log('ERROR! Please specify a task name')
} else {
const newTask = {
name: taskName,
projectId: '',
notes: '',
starred: false,
poms_completed: 0,
poms_total: 0,
dueAt: '',
snoozedUntil: '',
completed: false,
completedAt: ''
}
this.$store.dispatch('addTask', newTask)
}
},
Let's take all that default property setting and move it where it belongs: into the Vuex actions
. This code is repeated in a couple of places (e.g. in ProjectDetail
).
Move this code and delete the repetition.
Commit 477a8f4 broke VimMovement
because it expects to get an actual task object passed into its props, but in order to implement #8, we are moving towards views that use arrays with taskids as the backing store. Components need to pull out the actual task object from the Vuex store directly. We need to do that for VimMovement
.
First step, change the prop from an Object to an Array:
props: {
'items': Object
},
Right now when we snooze tasks, it still appears in places like weekly/backlog views. Snooze means "I don't want to see you until some later date". Let's update view code so that it always filters snoozed tasks that haven't yet been tripped.
Currently a task is considered to be in today's focus if it is part of the list in the Vuex store. Let's switch this to properly use state instaed. This requires us to remove today
from store's index.js
. We'll then update the getters code to use a filter set for any tasks that have state
equal to today
.
Right now we have a lot of duplicated code that looks like this:
<task-card :id="id" showProject @click.native="toTask(id)"></task-card>
Every instance that we use a task-card
requires us to register a click handler and a function to jump to the task, let's move this into the task-card
directly. We already have a toTask
function, so we can just reuse that.
Right now we have two ways to show that a task is selected, either we hover over with the mouse, or we use VimMovement to set the focus and move around the task list. This can cause confusion because there is a possibility we show two tasks with focus, the one that's hovered and the one we are moving with VimMovement.
One solution is to intercept the mouseover event and determine which task the hover refers to, if we have that we can feed it into VimMovement's id
prop and then these would be linked. If we change focus because of hover, VimMovement will reflect that in its state.
However, this will mean that when we leave the hover state (by moving the mouse away) we will be left with that task still highlighted, not sure if this is a good user experience or not.
Once #30 is finished, we'll have a new state that identifies tasks that should be focused on during the week. We should update the planning view to incorporate the weekly tasks. This view should include tasks that match the following criteria:
We'll have a new "w" shortcut that moves tasks into weekly view.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.