Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Task Input Buttons #128

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
23 changes: 23 additions & 0 deletions MMM-Todoist.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,26 @@
width: 400px;
overflow: hidden;
}

.add-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}

.add-list-item-add {
display: flex;
flex-direction: column;
width: 50px;
height: 50px;
margin: 10px;
font-size: 40px;
font-weight: bold;
color: white;
text-align: center;
padding: 20px 10px 10px 10px;
border: 1px solid black;
border-radius: 10px;
background-color: grey;
}
126 changes: 99 additions & 27 deletions MMM-Todoist.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
*/

/*
* Update by dirtylimerix 24/11/2024
* - Added support for adding to lists and new tasks
* Update by mabahj 24/11/2019
* - Added support for labels in addtion to projects
* Update by AgP42 the 18/07/2018
Expand Down Expand Up @@ -58,7 +60,7 @@ Module.register("MMM-Todoist", {
// "#ffcc00", "#74e8d3", "#3bd5fb", "#dc4fad", "#ac193d", "#d24726", "#82ba00", "#03b3b2", "#008299",
// "#5db2ff", "#0072c6", "#000000", "#777777"
// ], //These colors come from Todoist and their order matters if you want the colors to match your Todoist project colors.

//TODOIST Change how they are doing Project Colors, so now I'm changing it.
projectColors: {
30:'#b8256f',
Expand All @@ -83,11 +85,13 @@ Module.register("MMM-Todoist", {
49:'#ccac93'
},

//This has been designed to use the Todoist Sync API.
// list input parameters
inputTasks: [],

// Non-configurable parameters
apiVersion: "v9",
apiBase: "https://todoist.com/API",
todoistEndpoint: "sync",

todoistResourceType: "[\"items\", \"projects\", \"collaborators\", \"user\", \"labels\"]",

debug: false
Expand Down Expand Up @@ -158,6 +162,12 @@ Module.register("MMM-Todoist", {
UserPresence = payload;
this.GestionUpdateIntervalToDoIst();
}

if (notification == "KEYBOARD_INPUT" && payload.key === "MMM-Todoist") {
//this.addItemToList(payload.data, payload.message);
var ndata = {"config" : this.config, "addData" : payload};
this.sendSocketNotification("ADDITEM_TODOIST", ndata);
}
},

GestionUpdateIntervalToDoIst: function () {
Expand Down Expand Up @@ -237,6 +247,9 @@ Module.register("MMM-Todoist", {
Log.log("ToDoIst update OK, project : " + this.config.projects + " at : " + moment.unix(this.lastUpdate).format(this.config.displayLastUpdateFormat)); //AgP
}

this.loaded = true;
this.updateDom(1000);
} else if (notification === "ADDITEM") {
this.loaded = true;
this.updateDom(1000);
} else if (notification === "FETCH_ERROR") {
Expand Down Expand Up @@ -597,33 +610,14 @@ Module.register("MMM-Todoist", {

return cell;
},
getDom: function () {

if (this.config.hideWhenEmpty && this.tasks.items.length===0) {
return null;
}

//Add a new div to be able to display the update time alone after all the task
var wrapper = document.createElement("div");

//display "loading..." if not loaded
if (!this.loaded) {
wrapper.innerHTML = "Loading...";
wrapper.className = "dimmed light small";
return wrapper;
}


buildTaskTable: function () {
//New CSS based Table
var divTable = document.createElement("div");
divTable.className = "divTable normal small light";

var divBody = document.createElement("div");
divBody.className = "divTableBody";

if (this.tasks === undefined) {
return wrapper;
}

// create mapping from user id to collaborator index
var collaboratorsMap = new Map();
Expand All @@ -637,7 +631,6 @@ Module.register("MMM-Todoist", {
var divRow = document.createElement("div");
//Add the Row
divRow.className = "divTableRow";


//Columns
divRow.appendChild(this.addPriorityIndicatorCell(item));
Expand All @@ -653,10 +646,89 @@ Module.register("MMM-Todoist", {
}

divBody.appendChild(divRow);
});

});
divTable.appendChild(divBody);
wrapper.appendChild(divTable);

return divTable;
},

buildInputList: function() {
const addList = document.createElement("div");
addList.className = "add-list";
if (this.config.inputTasks.length > 0) {
// For each "inputTask", add a button according to the config parameters
for (var idx = 0; idx < this.config.inputTasks.length; idx++) {
var item = this.config.inputTasks[idx];
var addListBtn = document.createElement("div");
var symbol = "plus"
if (item["symbol"]) {
symbol = item["symbol"];
}
addListBtn.className = "add-list-item-add fas fa-" + symbol;
addListBtn.id = item["project"] + "-" + item["task"];
if (item["color"]) {
addListBtn.style.color = item["color"];
}
if (item["bg-color"]) {
addListBtn.style.backgroundColor = item["bg-color"];
}
addListBtn.addEventListener("click", event => {
this.sendNotification("KEYBOARD", {
key: "MMM-Todoist",
style: "default",
data: {"id" : event.target.id }
});
});
addList.appendChild(addListBtn);
}

// If using input tasks, create a button for new inbox items
if (this.config.inputTasks.length > 0) {
var addNewBtn = document.createElement("div");
addNewBtn.className = "add-list-item-add fas fa-square-plus";
//addNewBtn.id = "inbox-NEW";
addNewBtn.id = "2334830530-NEW";
addNewBtn.style.color = "white";
addNewBtn.style.backgroundColor = "darkgrey";
addNewBtn.addEventListener("click", event => {
this.sendNotification("KEYBOARD", {
key: "MMM-Todoist",
style: "default",
data: {"id" : event.target.id }
});
});
addList.appendChild(addNewBtn);
}
}
return addList;
},

getDom: function () {

if (this.config.hideWhenEmpty && this.tasks.items.length===0) {
return null;
}

//Add a new div to be able to display the update time alone after all the task
var wrapper = document.createElement("div");

//display "loading..." if not loaded
if (!this.loaded) {
wrapper.innerHTML = "Loading...";
wrapper.className = "dimmed light small";
return wrapper;
}

if (this.tasks === undefined) {
return wrapper;
}

// Build the Todoist task table and add it
taskTable = this.buildTaskTable();
wrapper.appendChild(taskTable);
// Build the input task button list (if enabled) and add it
addList = this.buildInputList();
wrapper.appendChild(addList);

// create the gradient
if (this.config.fade && this.config.fadePoint < 1) divTable.querySelectorAll('.divTableRow').forEach((row, i, rows) => row.style.opacity = Math.max(0, Math.min(1 - ((((i + 1) * (1 / (rows.length))) - this.config.fadePoint) / (1 - this.config.fadePoint)) * (1 - this.config.fadeMinimumOpacity), 1)));
Expand Down
105 changes: 101 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ modules: [
fade: false,
// projects and/or labels is mandatory:
projects: [ 166564794 ],
labels: [ "MagicMirror", "Important" ] // Tasks for any projects with these labels will be shown.
}
labels: [ "MagicMirror", "Important" ], // Tasks for any projects with these labels will be shown.
inputTasks: [
{"project" : 166564794, "task" : "Groceries", "symbol" : "cart-shopping"},
{"project" : 166564794, "task" : "Hardware Store", "symbol" : "screwdriver-wrench", "color" : "white", "bg-color" : "darkorange"}
]
}
}
]
````
Expand All @@ -37,7 +41,6 @@ modules: [

The following properties can be configured:


<table width="100%">
<!-- why, markdown... -->
<thead>
Expand Down Expand Up @@ -222,10 +225,102 @@ The following properties can be configured:
<br><b>Default value:</b> <code>false</code>
</td>
</tr>

<tr>
<td><code>inputTasks</code></td>
<td>Add buttons for adding tasks and subtasks to lists below task list. Depends on MMM-Keyboard module being installed.<br>
<br><b>Possible values:</b> <code>An array, see inputTask configuration below.</code>
<br><b>Default value:</b> <code>[]</code>
</td>
</tr>
</tbody>
</table>


## InputTask Configuration options

InputTasks are buttons that will appear below the task list, enabling user input to add tasks to projects, or add sub-tasks to tasks. If any inputTask is specified, an additional [+] button be automatically added that allows tasks to be added to the inbox. For each specified inputTask, a *project_id* and *task* name is required. The *project_id* specifies the project under which a task will be added. The *task* specifies the parent task under which new tasks will be created (like a list). If the parent task does not exist (as a task under the *project_id* and due "today"), it will be created.

### Example usage

For a given config that includes the following:

````javascript
modules: [
{
...
inputTasks: [
{"project" : 166564794, "task" : "Groceries", "symbol" : "cart-shopping"},
{"project" : 166564794, "task" : "Hardware Store", "symbol" : "screwdriver-wrench", "color" : "white", "bg-color" : "darkorange"}
]
}
}
]
````

Three buttons will appear (as in the screenshot below), one for a *Groceries* with a shopping cart icon, one for *Hardware Store* with a tools icon, and one for new inbox items with a [+] icon. When you click on any button (i.e. *Groceries*) the visual keyboard (MMM-Keyboard) will show up on the screen. After you input text and hit send, that text will be the name of a new sub-task under *Groceries* in the *project_id* project. If *Groceries* did not already exist, it will be created. Everything is created with a due date of *today* by default.


The following properties can be configured for each inputTask:

<table width="100%">
<thead>
<tr>
<th width="15%">Option</th>
<th width="100%">Description</th>
</tr>
<thead>
<tbody>
<tr>
<td><code>project</code></td>
<td>(required) Project to which this task will belong.<br>
<br><b>Possible values:</b> <code>any project id</code>
<br><b>Default value:</b> <code>none</code>
<br><b>Example:</b> <code>166564792</code>
<br>
<b>Getting the Todoist ProjectID:</b><br>
1) Go to Todoist (Log in if you aren't)<br>
2) Click on a Project in the left menu<br>
3) Your browser URL will change to something like<br> <code>"https://todoist.com/app?lang=en&v=818#project%2F166564897"</code><br><br>
Everything after %2F is the Project ID. In this case "166564792"<br><br>
<hr />
Alternatively, if you add <b>debug=true</b> in your config.js the Projects and ProjectsIDs will be displayed on MagicMirror as well as in the Browser console.<br><br>
<b>This value and/or the labels entry must be specified</b>. If both projects and labels are specified, then tasks from both will be shown.
</td>
</tr>
<tr>
<td><code>task</code></td>
<td>(required) Name of the task under which new subtasks will be placed<br>
<br><b>Possible values:</b> <code>string</code>
<br><b>Default value:</b> <code>none</code>
<br><b>Note:</b> You can use one of three values here.
</td>
</tr>
<tr>
<td><code>symbol</code></td>
<td>(optional) Name of the FontAwesome icon to use for an icon on the button.<br>
<br><b>Possible values:</b> <code>string</code>
<br><b>Default value:</b> <code>"plus"</code>
<br><b>Note:</b> You can use any of the free Font Awesome icon values found here https://fontawesome.com/v6/search?o=r&m=free.
</td>
</tr>
<tr>
<td><code>color</code></td>
<td>(optional) CSS color to use for the foreground button icon.<br>
<br><b>Possible values:</b> <code>string</code>
<br><b>Default value:</b> <code>"grey"</code>
</td>
</tr>
<tr>
<td><code>bg-color</code></td>
<td>(optional) CSS color to use for the background of the button.<br>
<br><b>Possible values:</b> <code>string</code>
<br><b>Default value:</b> <code>"white"</code>
</td>
</tr>
</tbody>
</table>


## Dependencies
- [request](https://www.npmjs.com/package/request) (installed via `npm install`)

Expand Down Expand Up @@ -260,6 +355,8 @@ Options enabled: orderBy:dueDateAsc, showProjects: true
Options enabled: orderBy:dueDateAsc, showProjects: false
![My image](http://cbrooker.github.io/MMM-Todoist/Screenshots/7.png)

Options enabled: inputTasks
![My image](todoist_btns.png)

## Attribution

Expand Down
Loading