Skip to content

Commit

Permalink
Merge branch 'release/0.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
oliveryh committed Aug 15, 2020
2 parents d122c7e + e7a4593 commit c583a51
Show file tree
Hide file tree
Showing 18 changed files with 3,499 additions and 3,747 deletions.
10 changes: 10 additions & 0 deletions .grenrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"dataSource": "issues",
"prefix": "",
"onlyMilestones": false,
"groupBy": "label",
"changelogFilename": "CHANGELOG.md",
"template": {
"issue": "- [{{text}}]({{url}}) {{name}}"
}
}
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@ The motivation of this project is to take the components from the best task mana

The application has the following basic features:

- Create a task
- Update a task
- Delete a task
- CRUD operations on a task
- Track time spent on a task
- Categorise tasks by date
- Focus on a particular date (for mobile)

### Future Features

Future features will include the ability to:

- Assign a task to a particular date
- Get statistics on number of tasks complete per date, time spent on tasks
- Ability to categorise tasks
- Stopwatch timer for tasks
- Recurring tasks
- Set expected time taken
- Drag and drop tasks across dates

## Inspiration

Expand Down
1,640 changes: 1,202 additions & 438 deletions client/package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-axios": "^2.1.5",
"vue-router": "^3.3.4",
"vuetify": "^2.2.11",
"vue-router": "^3.4.3",
"vuetify": "^2.3.8",
"vuex": "^3.5.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-service": "~4.4.0",
"@vue/cli-plugin-babel": "~4.5.3",
"@vue/cli-plugin-eslint": "~4.5.3",
"@vue/cli-service": "~4.5.3",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint": "^7.7.0",
"eslint-plugin-vue": "^6.2.2",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-vuetify": "~2.0.6",
"sass": "^1.26.10",
"sass-loader": "^9.0.3",
"vue-cli-plugin-vuetify": "^2.0.7",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.3.0"
"vuetify-loader": "^1.6.0"
},
"eslintConfig": {
"root": true,
Expand Down
2 changes: 1 addition & 1 deletion client/src/common/config.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const API_URL = 'http://127.0.0.1:3000/api'
export const API_URL = process.env.VUE_APP_API_URL
export default API_URL
269 changes: 269 additions & 0 deletions client/src/components/Task.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
<template>
<div>
<v-card outlined class="rounded-card">
<v-card-title :class="task.complete && 'grey--text' || 'primary--text'">
<div class="card-title">{{ task.description }}</div>
</v-card-title>

<v-card-actions style="height: 55px">
<v-btn
outlined
rounded
class="timer-button"
v-if="task.timerActive"
color="orange"
@click="taskTimerStop(task)"
>
<v-icon left>mdi-stop</v-icon>
{{ secondsToString }}
</v-btn>
<v-btn
outlined
rounded
class="timer-button"
v-else
color="green"
@click="taskTimerStart(task)"
>
<v-icon left>mdi-play</v-icon>
{{ secondsToString }}
</v-btn>
<v-spacer></v-spacer>
<v-checkbox
v-model="task.complete"
@change="taskUpdate(task)"
:color="task.complete && 'grey' || 'primary'"
></v-checkbox>
<v-btn icon rounded color="red" @click="taskDelete(task)">
<v-icon>mdi-close</v-icon>
</v-btn>
<v-btn icon rounded @click="editorOpen()">
<v-icon>mdi-pencil</v-icon>
</v-btn>
</v-card-actions>
</v-card>
<v-dialog v-if="editedTask != null" v-model="editorDialog" max-width="392">
<v-card>
<v-card-title class="headline">Edit Card</v-card-title>

<v-card-text>
<v-form ref="form" @submit.prevent>
<v-container>
<v-row>
<v-col cols="12">
<v-menu
v-model="dateDialog"
:close-on-content-click="false"
:nudge-right="40"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="editedTask.date"
label="Date"
prepend-icon="mdi-calendar"
readonly
v-bind="attrs"
v-on="on"
></v-text-field>
</template>
<v-date-picker v-model="editedTask.date" @input="dateDialog = false"></v-date-picker>
</v-menu>
</v-col>
<v-col cols="12">
<v-text-field
:rules="taskRules"
label="Description"
prepend-icon="mdi-pencil"
v-model="editedTask.description"
></v-text-field>
</v-col>
<v-col cols="12">
<v-menu
ref="timeDialog"
v-model="timeDialog"
:close-on-content-click="false"
:nudge-right="40"
:return-value.sync="time"
transition="scale-transition"
offset-y
max-width="290px"
min-width="290px"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="editedTaskTime"
label="Time taken"
prepend-icon="mdi-clock"
readonly
v-bind="attrs"
v-on="on"
></v-text-field>
</template>
<v-time-picker
v-if="timeDialog"
v-model="editedTaskTime"
label="Time Taken"
full-width
format="24hr"
@click:minute="$refs.timeDialog.save(time)"
></v-time-picker>
</v-menu>
</v-col>
</v-row>
</v-container>
</v-form>
</v-card-text>

<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="green darken-1" text @click="editorDialog = false; timerSet()">Cancel</v-btn>
<v-btn color="green darken-1" text @click="editorSave()">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

<script>
import {
A_TASK_UPDATE,
A_TASK_DELETE,
A_TASK_TIMER_START,
A_TASK_TIMER_STOP,
} from '@/store/actions.type'
export default {
name: 'Task',
props: {
task: {
type: Object,
},
},
data: () => ({
taskRules: [v => !!v || 'Description required'],
timerTrackedTime: null,
timerInterval: null,
editorDialog: false,
editedTask: null,
dateDialog: null,
timeDialog: null,
}),
created() {
this.timerSet()
},
filters: {
zeroPad: function(value, num) {
num = typeof num !== 'undefined' ? num : 2
return value.toString().padStart(num, '0')
},
},
watch: {
$props: {
deep: true,
handler() {
this.timerSet()
},
},
},
computed: {
editedTaskTime: {
get() {
var tt = this.editedTask.timerTrackedTime
var hours = this.$options.filters.zeroPad(parseInt(tt / 3600))
var minutes = this.$options.filters.zeroPad(parseInt((tt % 3600) / 60))
return `${hours}:${minutes}`
},
set(val) {
var parts = val.split(':')
var hours = parseInt(parts[0])
var minutes = parseInt(parts[1])
this.editedTask.timerTrackedTime = hours * 3600 + minutes * 60
},
},
secondsToString: {
get() {
var tt = this.timerTrackedTime
var hours = this.$options.filters.zeroPad(parseInt(tt / 3600))
var minutes = this.$options.filters.zeroPad(parseInt((tt % 3600) / 60))
var seconds = this.$options.filters.zeroPad(parseInt(tt % 60))
return `${hours}:${minutes}:${seconds}`
},
set(val) {
var parts = val.split(':')
var hours = parseInt(parts[0])
var minutes = parseInt(parts[1])
var seconds = parseInt(parts[2])
this.timerTrackedTime = hours * 3600 + minutes * 60 + seconds
},
},
},
methods: {
// timer
timerSet() {
this.timerTrackedTime = this.task.timerTrackedTime
if (this.task.timerActive) {
this.timerTrackedTime += parseInt(
(Date.now() - new Date(this.task.timerStartedAt).getTime()) / 1000,
)
}
if (this.task.timerActive) {
this.timerStart()
} else {
this.timerStop()
}
},
timerStart() {
clearInterval(this.timerInterval)
this.timerInterval = setInterval(() => (this.timerTrackedTime += 1), 1000)
},
timerStop() {
clearInterval(this.timerInterval)
},
// task
taskUpdate(task) {
this.$store.dispatch(A_TASK_UPDATE, task)
},
taskDelete(task) {
this.$store.dispatch(A_TASK_DELETE, task)
},
taskTimerStart(task) {
this.$store.dispatch(A_TASK_TIMER_START, task)
},
taskTimerStop(task) {
this.$store.dispatch(A_TASK_TIMER_STOP, task)
},
// editor
editorOpen() {
this.editedTask = Object.assign({}, this.task)
if (this.task.timerActive) this.taskTimerStop(this.task)
this.editorDialog = true
},
editorSave() {
if (this.editorValidate()) {
this.taskUpdate(this.editedTask)
this.editorDialog = false
}
},
editorValidate() {
if (this.$refs.form.validate()) {
return true
} else {
return false
}
},
},
}
</script>

<style scoped>
.rounded-card {
border-radius: 25px;
}
.timer-button {
padding: 0px 12px !important;
}
</style>
Loading

0 comments on commit c583a51

Please sign in to comment.