Stopped creating Project and Task with blank name
This commit is contained in:
19
README.md
19
README.md
@@ -2,7 +2,7 @@ The CLI Task Manager for Geeks :technologist:
|
|||||||
=========
|
=========
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://goreportcard.com/report/github.com/ajaxray/geek-life)
|
[](https://goreportcard.com/report/github.com/ajaxray/geek-life)
|
||||||
|
|
||||||
|
|
||||||
:superhero: Developer / DevOps / Sysadmin? A command line hero?
|
:superhero: Developer / DevOps / Sysadmin? A command line hero?
|
||||||
@@ -19,7 +19,7 @@ Click to see it moving (GIF)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### :zap: Highlights
|
### :crystal_ball: Highlights
|
||||||
|
|
||||||
- For ninjas - do things faster with keyboard shortcuts
|
- For ninjas - do things faster with keyboard shortcuts
|
||||||
- Markdown lovers, feel at :house:! You'll see markdown everywhere.
|
- Markdown lovers, feel at :house:! You'll see markdown everywhere.
|
||||||
@@ -28,7 +28,7 @@ Click to see it moving (GIF)
|
|||||||
- Task note editor with markdown syntax highlighting<sup>2</sup>
|
- Task note editor with markdown syntax highlighting<sup>2</sup>
|
||||||
- Full mouse support
|
- Full mouse support
|
||||||
|
|
||||||
### :compass: Roadmap
|
### :dart: Roadmap
|
||||||
- [x] Create Project
|
- [x] Create Project
|
||||||
- [x] Delete Project
|
- [x] Delete Project
|
||||||
- [ ] Edit Project
|
- [ ] Edit Project
|
||||||
@@ -50,11 +50,12 @@ Click to see it moving (GIF)
|
|||||||
- [ ] [Havitica](https://habitica.com/)<sup>3</sup> integration - Use it as Habitica client or use Habitica for cloud backup
|
- [ ] [Havitica](https://habitica.com/)<sup>3</sup> integration - Use it as Habitica client or use Habitica for cloud backup
|
||||||
- [ ] Time tracking
|
- [ ] Time tracking
|
||||||
|
|
||||||
### :arrow_down: Ready for action (installing and running)
|
### :rocket: Ready for action (installing and running)
|
||||||
|
|
||||||
It's just a single binary file, **no external dependencies**.
|
It's just a single binary file, **no external dependencies**.
|
||||||
Just download the appropriate version of [executable from latest release](https://github.com/ajaxray/geek-life/releases) for your OS.
|
Just download the appropriate version of [executable from latest release](https://github.com/ajaxray/geek-life/releases) for your OS.
|
||||||
Then rename and give it permission to execute. For example
|
Then rename and give it permission to execute.
|
||||||
|
For example:
|
||||||
```bash
|
```bash
|
||||||
mv geek-life_linux-amd64 geek-life
|
mv geek-life_linux-amd64 geek-life
|
||||||
sudo chmod +x geek-life
|
sudo chmod +x geek-life
|
||||||
@@ -67,7 +68,7 @@ sudo mv geek-life /usr/local/bin/geek-life
|
|||||||
geek-life
|
geek-life
|
||||||
```
|
```
|
||||||
|
|
||||||
Done! Manage your tasks your way!
|
Done! *Manage your tasks your way!*
|
||||||
|
|
||||||
## :keyboard: Keyboard shortcuts
|
## :keyboard: Keyboard shortcuts
|
||||||
|
|
||||||
@@ -113,9 +114,9 @@ If you fix a bug or want to add/improve a feature,
|
|||||||
and it's aligned with the focus (merging with ease) of this app,
|
and it's aligned with the focus (merging with ease) of this app,
|
||||||
I will be glad to accept your PR. :)
|
I will be glad to accept your PR. :)
|
||||||
|
|
||||||
## :question: You may ask...
|
## :bulb: You may ask...
|
||||||
|
|
||||||
#### Where is the data stored? Can I change the location?
|
#### :question: Where is the data stored? Can I change the location?
|
||||||
|
|
||||||
By default, it will try to create a db file in you home directory.
|
By default, it will try to create a db file in you home directory.
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ In that case, just mention `DB_FILE` as an environment variable.
|
|||||||
DB_FILE=~/dropbox/geek-life/default.db geek-life
|
DB_FILE=~/dropbox/geek-life/default.db geek-life
|
||||||
```
|
```
|
||||||
|
|
||||||
#### How can I suggest a feature?
|
#### :question: How can I suggest a feature?
|
||||||
|
|
||||||
Just [post an issue](https://github.com/ajaxray/geek-life/issues/new) describing your desired feature/enhancement
|
Just [post an issue](https://github.com/ajaxray/geek-life/issues/new) describing your desired feature/enhancement
|
||||||
and select `feature` label.
|
and select `feature` label.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func main() {
|
|||||||
taskRepo = repo.NewTaskRepository(db)
|
taskRepo = repo.NewTaskRepository(db)
|
||||||
|
|
||||||
titleText := tview.NewTextView().SetText("[lime::b]Geek-life [::-]- Task Manager for geeks!").SetDynamicColors(true)
|
titleText := tview.NewTextView().SetText("[lime::b]Geek-life [::-]- Task Manager for geeks!").SetDynamicColors(true)
|
||||||
cloudStatus := tview.NewTextView().SetText("[::d]Version: 0.0.1").SetTextAlign(tview.AlignRight).SetDynamicColors(true)
|
cloudStatus := tview.NewTextView().SetText("[::d]Version: 0.0.3").SetTextAlign(tview.AlignRight).SetDynamicColors(true)
|
||||||
|
|
||||||
titleBar := tview.NewFlex().
|
titleBar := tview.NewFlex().
|
||||||
AddItem(titleText, 0, 2, false).
|
AddItem(titleText, 0, 2, false).
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ func prepareProjectDetail() {
|
|||||||
|
|
||||||
func deleteCurrentProject() {
|
func deleteCurrentProject() {
|
||||||
if currentProject != nil && projectRepo.Delete(currentProject) == nil {
|
if currentProject != nil && projectRepo.Delete(currentProject) == nil {
|
||||||
for i, _ := range tasks {
|
for i := range tasks {
|
||||||
taskRepo.Delete(&tasks[i])
|
_ = taskRepo.Delete(&tasks[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
showMessage("Removed Project: " + currentProject.Title)
|
showMessage("Removed Project: " + currentProject.Title)
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ func prepareProjectPane() {
|
|||||||
SetDoneFunc(func(key tcell.Key) {
|
SetDoneFunc(func(key tcell.Key) {
|
||||||
switch key {
|
switch key {
|
||||||
case tcell.KeyEnter:
|
case tcell.KeyEnter:
|
||||||
|
if len(newProject.GetText()) < 3 {
|
||||||
|
showMessage("[red::]Project name should be at least 3 character")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
project, err := projectRepo.Create(newProject.GetText(), "")
|
project, err := projectRepo.Create(newProject.GetText(), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
showMessage("[red::]Failed to create Project:" + err.Error())
|
showMessage("[red::]Failed to create Project:" + err.Error())
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ func prepareTaskPane() {
|
|||||||
SetDoneFunc(func(key tcell.Key) {
|
SetDoneFunc(func(key tcell.Key) {
|
||||||
switch key {
|
switch key {
|
||||||
case tcell.KeyEnter:
|
case tcell.KeyEnter:
|
||||||
|
if len(newTask.GetText()) < 3 {
|
||||||
|
showMessage("[red::]Task title should be at least 3 character")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
task, err := taskRepo.Create(*currentProject, newTask.GetText(), "", "", 0)
|
task, err := taskRepo.Create(*currentProject, newTask.GetText(), "", "", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
showMessage("[red::]Could not create Task:" + err.Error())
|
showMessage("[red::]Could not create Task:" + err.Error())
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ func makeLightTextInput(placeholder string) *tview.InputField {
|
|||||||
func parseDateInputOrCurrent(inputText string) time.Time {
|
func parseDateInputOrCurrent(inputText string) time.Time {
|
||||||
if date, err := time.Parse(dateLayoutISO, inputText); err == nil {
|
if date, err := time.Parse(dateLayoutISO, inputText); err == nil {
|
||||||
return date
|
return date
|
||||||
} else {
|
|
||||||
return time.Now()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
func showMessage(text string) {
|
func showMessage(text string) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
// Project represent a collection of related tasks (tags of Habitica)
|
||||||
type Project struct {
|
type Project struct {
|
||||||
ID int64 `storm:"id,increment",json:"id"`
|
ID int64 `storm:"id,increment",json:"id"`
|
||||||
Title string `storm:"index",json:"title"`
|
Title string `storm:"index",json:"title"`
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
// Task represent a task - the building block of the TaskManager app
|
||||||
type Task struct {
|
type Task struct {
|
||||||
ID int64 `storm:"id,increment",json:"id"`
|
ID int64 `storm:"id,increment",json:"id"`
|
||||||
ProjectID int64 `storm:"index",json:"project_id"`
|
ProjectID int64 `storm:"index",json:"project_id"`
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package repository
|
|||||||
|
|
||||||
import "github.com/ajaxray/geek-life/model"
|
import "github.com/ajaxray/geek-life/model"
|
||||||
|
|
||||||
|
// ProjectRepository interface defines methods of project data accessor
|
||||||
type ProjectRepository interface {
|
type ProjectRepository interface {
|
||||||
GetAll() ([]model.Project, error)
|
GetAll() ([]model.Project, error)
|
||||||
GetByID(id int64) (model.Project, error)
|
GetByID(id int64) (model.Project, error)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/ajaxray/geek-life/model"
|
"github.com/ajaxray/geek-life/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TaskRepository interface defines methods of task data accessor
|
||||||
type TaskRepository interface {
|
type TaskRepository interface {
|
||||||
GetAll() ([]model.Task, error)
|
GetAll() ([]model.Task, error)
|
||||||
GetAllByProject(project model.Project) ([]model.Task, error)
|
GetAllByProject(project model.Project) ([]model.Task, error)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
// gotenv.Load()
|
// gotenv.Load()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// GetEnvInt finds an ENV variable and converts to int, otherwise return default value
|
||||||
func GetEnvInt(key string, defaultVal int) int {
|
func GetEnvInt(key string, defaultVal int) int {
|
||||||
if v, ok := os.LookupEnv(key); ok {
|
if v, ok := os.LookupEnv(key); ok {
|
||||||
if i, err := strconv.Atoi(v); err == nil {
|
if i, err := strconv.Atoi(v); err == nil {
|
||||||
@@ -25,6 +26,7 @@ func GetEnvInt(key string, defaultVal int) int {
|
|||||||
return defaultVal
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEnvStr finds an ENV variable, otherwise return default value
|
||||||
func GetEnvStr(key, defaultVal string) string {
|
func GetEnvStr(key, defaultVal string) string {
|
||||||
if v, ok := os.LookupEnv(key); ok {
|
if v, ok := os.LookupEnv(key); ok {
|
||||||
return v
|
return v
|
||||||
|
|||||||
Reference in New Issue
Block a user