Commit e056c464 authored by ransome1's avatar ransome1
Browse files

WIP: Filters can be bulk changed/deleted, empty filters won't disappear any longer

parent ed867889
......@@ -126,3 +126,4 @@ A prioritized backlog of new features and known issues can be found <a href="htt
- vanillajs-datepicker: https://github.com/mymth/vanillajs-datepicker
- i18next: https://github.com/i18next/i18next
- Matomo: https://github.com/matomo-org/matomo
- chokidar: https://github.com/paulmillr/chokidar
{
"name": "sleek",
"productName": "sleek",
"version": "1.0.4-1",
"version": "1.0.5-1",
"description": "Todo app based on todo.txt for Linux, Windows and MacOS, free and open-source",
"synopsis": "Todo app based on todo.txt for Linux, Windows and MacOS, free and open-source",
"category": "ProjectManagement",
......
......@@ -265,6 +265,17 @@ nav ul li.is-highlighted a {
background: #212224 !important;
}
#filterMenu .card {
background: #3B3B3B;
}
#filterMenu .card #filterMenuSave {
background-color: transparent !important;
border-right: 1px solid #212224 !important;
}
#filterMenu .card-footer {
border-top: 1px solid #212224 !important;
}
.contexts .button {
color: #c5ede3;
background: #247561;
......
{"version":3,"sourceRoot":"","sources":["../scss/dark.scss","../scss/variables.scss"],"names":[],"mappings":"AAGA;EACE,kBCOa;EDNb;;;AAEF;EACE;;;AAEF;AAAA;EAEE;;;AAEF;AAAA;AAAA;EAGE,OCZa;;;ADcf;AAAA;AAAA;EAGE;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;EACA;;;AAEF;EACE;;;AAEF;AAAA;EAEE;EACA;;;AAEF;EACE;;;AAEF;AAAA;EAEE;;AACA;AAAA;EACE;;;AAGJ;AAAA;EAEE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE,kBC3EY;;AD4EZ;EACE,OCjFW;;ADoFX;EACE;;AAGA;EACE,OCzFO;ED0FP;;AAEF;AAAA;EAEE,OC9FO;ED+FP;EACA,kBC3FW;;AD8Ff;EACE,OCpGS;EDqGT;EACA,kBCjGa;;;ADuGf;EACE;;AAEF;EACE;;;AAIN;EACE,kBC/Ga;;ADgHb;EACE;;;AAIF;EACE;EACA;;;AAIF;EACE,kBC7He;;AD+HjB;EACE,OCrIW;;ADuIb;EACE;;AAGA;EACE,OC7IS;;ADgJb;EACE,cC3Ie;;AD4If;EACE,OClJS;;ADoJX;EACE;;AAEF;EACE,OCxJS;;AD0JX;EACE;;AACA;EACE,OCxJW;;AD2Jf;AAAA;EAEE,OC1JY;;AD2JZ;AAAA;EACE;;AAIF;EACE;;AAIF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE,OCtLO;EDuLP;;AAGJ;EACE,OC3LS;;AD6LX;EACE,YCzLa;ED0Lb;;AAEF;EACE,YC9LQ;;;ADmMZ;EACE;EACA;EACA;;AAEF;EACE;;AAGA;AAAA;AAAA;AAAA;EAIE;;AAEF;EACE,YClNa;;;ADuNjB;AAAA;EAEE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE,YCrOU;;ADsOV;EACE,cCrOS;;;ADyOf;EACE,YC3OiB;;AD4OjB;EACE,OClPW;;;ADsPb;EACE;;AACA;EACE;;AAIJ;EACE;;AAEF;EACE;;AAEF;EACE;;;AAKF;EACE,OC7PoB;ED8PpB;;AACA;EACE;EACA;;AAGJ;EACE;EACA;;;AAIF;EACE,OC1QoB;ED2QpB;;AACA;EACE;EACA;;AAGJ;EACE;EACA;;;AAIF;EACE;;;AAKA;EACE,kBCzSM;;AD2SR;EACE;;AAEF;EACE;;AAEF;EACE;;;AAMF;EACE,YCvTa;EDwTb,OC7TS;;AD8TT;EACE;;AAEF;AACE;AAAA;AAAA;;AAIF;AAAA;EAEE,cCpUM;;;ADyUd;EACE;;AACA;EACE;;AAEF;EACE;;AAEF;AAAA;AAAA;EAGE;EACA;;AAEF;EACE;;AAEF;AAAA;EAEE;EACA;;AAEF;AAAA;EAEE,YChWe;EDiWf;;AAEF;AAAA;EAEE;;AAEF;AAAA;AAAA;EAGE;;AAEF;EACE;;AAEF;EACE;EACA,cCnXQ;;ADqXV;EACE,cCzXW;;AD2Xb;EACE;EACA,cC7XW;;;ADgYf;EACE;;AACA;EACE,OCnYW;EDoYX;;AACA;EACE;;;AAKJ;AAAA;AAAA;EAGE;EACA;EACA;;;AAGJ;EACE;;AACA;EACE;;AAEF;AAAA;EAEE;;AAEF;AAAA;EAEE;;AAEF;EACE,YC7ZU;ED8ZV;;AACA;AAAA;AAAA;EAGE;EACA;;AAEF;EACE;;AAEF;AAAA;EAEE,OC1aQ;ED2aR;;AAEF;AAAA;EAEE,OC/aQ;EDgbR,YCpbS;;;ADybb;EACE;;AAEF;AAAA;EAEE,OC9bW","file":"dark.css"}
\ No newline at end of file
{"version":3,"sourceRoot":"","sources":["../scss/dark.scss","../scss/variables.scss"],"names":[],"mappings":"AAGA;EACE,kBCOa;EDNb;;;AAEF;EACE;;;AAEF;AAAA;EAEE;;;AAEF;AAAA;AAAA;EAGE,OCZa;;;ADcf;AAAA;AAAA;EAGE;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;EACA;;;AAEF;EACE;;;AAEF;AAAA;EAEE;EACA;;;AAEF;EACE;;;AAEF;AAAA;EAEE;;AACA;AAAA;EACE;;;AAGJ;AAAA;EAEE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE,kBC3EY;;AD4EZ;EACE,OCjFW;;ADoFX;EACE;;AAGA;EACE,OCzFO;ED0FP;;AAEF;AAAA;EAEE,OC9FO;ED+FP;EACA,kBC3FW;;AD8Ff;EACE,OCpGS;EDqGT;EACA,kBCjGa;;;ADuGf;EACE;;AAEF;EACE;;;AAIN;EACE,kBC/Ga;;ADgHb;EACE;;;AAIF;EACE;EACA;;;AAIF;EACE,kBC7He;;AD+HjB;EACE,OCrIW;;ADuIb;EACE;;AAGA;EACE,OC7IS;;ADgJb;EACE,cC3Ie;;AD4If;EACE,OClJS;;ADoJX;EACE;;AAEF;EACE,OCxJS;;AD0JX;EACE;;AACA;EACE,OCxJW;;AD2Jf;AAAA;EAEE,OC1JY;;AD2JZ;AAAA;EACE;;AAIF;EACE;;AAIF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE,OCtLO;EDuLP;;AAGJ;EACE,OC3LS;;AD6LX;EACE,YCzLa;ED0Lb;;AAEF;EACE,YC9LQ;;;ADmMZ;EACE;EACA;EACA;;AAEF;EACE;;AAGA;AAAA;AAAA;AAAA;EAIE;;AAEF;EACE,YClNa;;;ADuNjB;AAAA;EAEE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE,YCrOU;;ADsOV;EACE,cCrOS;;;ADyOf;EACE,YC3OiB;;AD4OjB;EACE,OClPW;;;ADsPb;EACE;;AACA;EACE;;AAIJ;EACE;;AAEF;EACE;;AAEF;EACE;;;AAIF;EACE,YCpQe;;ADqQf;EACE;EACA;;AAGJ;EACE;;;AAIF;EACE,OCxQoB;EDyQpB;;AACA;EACE;EACA;;AAGJ;EACE;EACA;;;AAIF;EACE,OCrRoB;EDsRpB;;AACA;EACE;EACA;;AAGJ;EACE;EACA;;;AAIF;EACE;;;AAKA;EACE,kBCpTM;;ADsTR;EACE;;AAEF;EACE;;AAEF;EACE;;;AAMF;EACE,YClUa;EDmUb,OCxUS;;ADyUT;EACE;;AAEF;AACE;AAAA;AAAA;;AAIF;AAAA;EAEE,cC/UM;;;ADoVd;EACE;;AACA;EACE;;AAEF;EACE;;AAEF;AAAA;AAAA;EAGE;EACA;;AAEF;EACE;;AAEF;AAAA;EAEE;EACA;;AAEF;AAAA;EAEE,YC3We;ED4Wf;;AAEF;AAAA;EAEE;;AAEF;AAAA;AAAA;EAGE;;AAEF;EACE;;AAEF;EACE;EACA,cC9XQ;;ADgYV;EACE,cCpYW;;ADsYb;EACE;EACA,cCxYW;;;AD2Yf;EACE;;AACA;EACE,OC9YW;ED+YX;;AACA;EACE;;;AAKJ;AAAA;AAAA;EAGE;EACA;EACA;;;AAGJ;EACE;;AACA;EACE;;AAEF;AAAA;EAEE;;AAEF;AAAA;EAEE;;AAEF;EACE,YCxaU;EDyaV;;AACA;AAAA;AAAA;EAGE;EACA;;AAEF;EACE;;AAEF;AAAA;EAEE,OCrbQ;EDsbR;;AAEF;AAAA;EAEE,OC1bQ;ED2bR,YC/bS;;;ADocb;EACE;;AAEF;AAAA;EAEE,OCzcW","file":"dark.css"}
\ No newline at end of file
......@@ -348,6 +348,10 @@ nav ul:nth-child(2) {
overflow-x: hidden;
padding: 2em;
background: #ebebeb;
/*.dropdown-item.is-greyed-out {
opacity: .75;
-webkit-filter: grayscale(100%);
}*/
/*#btnResetAllFilters {
display: none;
}
......@@ -373,6 +377,13 @@ nav ul:nth-child(2) {
top: -0.75em;
z-index: 35;
}
#drawerContainer .drawer .is-greyed-out {
opacity: 0.75;
-webkit-filter: grayscale(100%);
}
#drawerContainer .drawer .button.is-greyed-out {
cursor: default;
}
#drawerContainer .drawer h4.is-4 {
font-size: 1.35em;
color: #4a4a4a;
......@@ -385,10 +396,6 @@ nav ul:nth-child(2) {
padding: 0;
margin: 0 0 1.5em 0;
}
#drawerContainer .drawer .dropdown-item.is-greyed-out {
opacity: 0.75;
-webkit-filter: grayscale(100%);
}
#drawerContainer .drawer table tr td:nth-child(odd) {
width: auto;
vertical-align: middle;
......@@ -769,6 +776,24 @@ nav ul:nth-child(2) {
display: block;
}
#filterMenu {
display: none;
position: fixed;
z-index: 60;
}
#filterMenu #filterMenuSave {
cursor: pointer;
border: none;
border-right: 1px solid #f5f5f5;
}
#filterMenu #filterMenuDelete {
color: #ff3860;
}
#filterMenu.is-active {
display: block;
}
.contentContainer {
width: 100%;
height: 90%;
......
This diff is collapsed.
......@@ -479,7 +479,7 @@
</tr>
<tr>
<td><a href="https://github.com/matomo-org/matomo" target="_blank">Matomo</a></td>
<td></td>
<td><a href="https://github.com/paulmillr/chokidar" target="_blank">chokidar</a></td>
<td></td>
<td></td>
</tr>
......@@ -637,6 +637,22 @@
</div>
</div>
<div id="autoCompleteContainer" class="drawer card"></div>
<div id="filterMenu" class="flex-row ">
<form class="card">
<div class="card-content">
<input id="filterMenuInput" class="input" type="text">
</div>
<footer class="card-footer">
<input type="submit" id="filterMenuSave" class="card-footer-item">
<a href="#" id="filterMenuDelete" class="card-footer-item"></a>
</footer>
</form>
</div>
<div id="modalChangeFile" class="modal" tabindex="0">
<div class="modal-background"></div>
<div class="modal-content">
......
......@@ -6,7 +6,43 @@ const modalFormInput = document.getElementById("modalFormInput");
const todoTableSearch = document.getElementById("todoTableSearch");
const autoCompleteContainer = document.getElementById("autoCompleteContainer");
const todoFilters = document.getElementById("todoFilters");
let categories, filtersCounted, selectedFilters, container, headline;
const filterMenu = document.getElementById("filterMenu");
const filterMenuInput = document.getElementById("filterMenuInput");
const filterMenuSave = document.getElementById("filterMenuSave");
const filterMenuDelete = document.getElementById("filterMenuDelete");
filterMenuSave.value = translations.save;
filterMenuDelete.innerHTML = translations.delete;
let categories, filtersCounted, filtersCountedReduced, selectedFilters, container, headline;
function saveFilter(newFilter, oldFilter, category) {
items.objects.forEach((item) => {
if(category!=="priority" && item[category]) {
const index = item[category].findIndex((el) => el === oldFilter);
item[category][index] = newFilter;
} else if(category==="priority" && item[category]===oldFilter) {
item[category] = newFilter.toUpperCase();
}
});
// persisted filters will be removed
setUserData("selectedFilters", []);
//write the data to the file
// a newline character is added to prevent other todo.txt apps to append new todos to the last line
window.api.send("writeToFile", [items.objects.join("\n").toString() + "\n", userData.file]);
}
function deleteFilter(filter, category) {
items.objects.forEach((item) => {
if(item[category]) {
const index = item[category].indexOf(filter);
if(index!==-1) item[category].splice(index, 1);
if(item[category].length===0) item[category] = null;
}
});
// persisted filters will be removed
setUserData("selectedFilters", []);
//write the data to the file
// a newline character is added to prevent other todo.txt apps to append new todos to the last line
window.api.send("writeToFile", [items.objects.join("\n").toString() + "\n", userData.file]);
}
function filterItems(items, searchString) {
try {
// selected filters are empty, unless they were persisted
......@@ -80,7 +116,7 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
// array to collect all the available filters in the data
let filters = new Array();
// run the array and collect all possible filters, duplicates included
items.filtered.forEach((item) => {
items.objects.forEach((item) => {
// check if the object has values in either the project or contexts field
if(item[category]) {
// push all filters found so far into an array
......@@ -126,7 +162,7 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
// https://wsvincent.com/javascript-remove-duplicates-array/
filters = [...new Set(filters.join(",").split(","))];
// filter persisted filters
if(userData.selectedFilters && userData.selectedFilters.length>0) {
/*if(userData.selectedFilters && userData.selectedFilters.length>0) {
selectedFilters = JSON.parse(userData.selectedFilters);
// check if selected filters is still part of all available filters
selectedFilters.forEach(function(selectedFilter,index){
......@@ -140,7 +176,45 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
}
}
});
}
}*/
// TODO: basically a duplicate
// count reduced filter when persisted filters are present
let filtersReduced = new Array();
items.filtered.forEach((item) => {
// check if the object has values in either the project or contexts field
if(item[category]) {
// push all filters found so far into an array
for (let filter in item[category]) {
// if user has not opted for showComplete we skip the filter of this particular item
if(userData.showCompleted==false && item.complete==true) {
continue;
// if task is hidden the filter will be marked
} else if(item.h) {
filtersReduced.push([item[category][filter],0]);
} else {
filtersReduced.push([item[category][filter],1]);
}
}
}
});
filtersCountedReduced = filtersReduced.reduce(function(filters, filter) {
// if filter is already in object and should be counted
if (filter[1] && (filter[0] in filters)) {
filters[filter[0]]++;
// new filter in object and should be counted
} else if(filter[1]) {
filters[filter[0]] = 1;
// do not count if filter is suppose to be hidden
// only overwrite value with 0 if the filter doesn't already exist in object
} else if(!filter[1] && !(filter[0] in filters)) {
filters[filter[0]] = 0;
}
if(filters!=null) {
return filters;
}
}, {});
// build the filter buttons
if(filters[0]!="" && filters.length>0) {
generateFilterButtons(category, autoCompleteValue, autoCompletePrefix, caretPosition).then(response => {
......@@ -253,13 +327,39 @@ function generateFilterButtons(category, autoCompleteValue, autoCompletePrefix,
selectedFilters.forEach(function(item) {
if(JSON.stringify(item) === '["'+filter+'","'+category+'"]') todoFiltersItem.classList.toggle("is-dark")
});
todoFiltersItem.innerHTML += " <span class=\"tag is-rounded\">" + filtersCounted[filter] + "</span>";
// create the event listener for filter selection by user
todoFiltersItem.addEventListener("click", () => {
selectFilter(todoFiltersItem.getAttribute('data-filter'), todoFiltersItem.getAttribute('data-category'))
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Filter-Drawer", "Click on filter tag", category]);
// context menu
todoFiltersItem.addEventListener("contextmenu", event => {
filterMenu.style.left = event.x + "px";
filterMenu.style.top = event.y + "px";
filterMenu.classList.add("is-active");
filterMenuInput.value = filter;
filterMenuInput.focus();
filterMenuSave.onclick = function() {
if(filterMenuInput.value!==filter) {
saveFilter(filterMenuInput.value, filter, category);
} else {
filterMenu.classList.remove("is-active");
}
}
filterMenuDelete.onclick = function() {
deleteFilter(filter, category);
}
});
if(filtersCountedReduced[filter]) {
todoFiltersItem.innerHTML += " <span class=\"tag is-rounded\">" + filtersCountedReduced[filter] + "</span>";
// create the event listener for filter selection by user
todoFiltersItem.addEventListener("click", () => {
selectFilter(todoFiltersItem.getAttribute('data-filter'), todoFiltersItem.getAttribute('data-category'))
// trigger matomo event
if(userData.matomoEvents) _paq.push(["trackEvent", "Filter-Drawer", "Click on filter tag", category]);
});
} else {
todoFiltersItem.classList.add("is-greyed-out");
todoFiltersItem.innerHTML += " <span class=\"tag is-rounded\">0</span>";
}
// autocomplete container
} else {
// add filter to input
......
......@@ -246,19 +246,19 @@ function generateTableRow(todo) {
if(userData.matomoEvents) _paq.push(["trackEvent", "Todo-Table", "Click on Todo item"]);
}
}
// cell for the categories
categories.forEach(category => {
if(todo[category] && category!="priority") {
todo[category].forEach(el => {
let todoTableBodyCellCategory = document.createElement("span");
todoTableBodyCellCategory.setAttribute("class", "tag " + category);
todoTableBodyCellCategory.innerHTML = el;
tableContainerCategories.appendChild(todoTableBodyCellCategory);
});
}
});
// only add the categories to text cell if it has child nodes
if(tableContainerCategories.hasChildNodes()) todoTableBodyCellText.appendChild(tableContainerCategories);
// cell for the categories
categories.forEach(category => {
if(todo[category] && category!="priority") {
todo[category].forEach(el => {
let todoTableBodyCellCategory = document.createElement("span");
todoTableBodyCellCategory.setAttribute("class", "tag " + category);
todoTableBodyCellCategory.innerHTML = el;
tableContainerCategories.appendChild(todoTableBodyCellCategory);
});
}
});
// only add the categories to text cell if it has child nodes
if(tableContainerCategories.hasChildNodes()) todoTableBodyCellText.appendChild(tableContainerCategories);
// check for and add a given due date
if(todo.due) {
var tag = convertDate(todo.due);
......
......@@ -147,7 +147,7 @@ const createWindow = async function() {
break;
}
}
const startFileWatcher = async function(file) {
const startFileWatcher = function(file) {
try {
if(!fs.existsSync(file)) throw("File not found on disk")
// use the loop to check if the new path is already in the user data
......@@ -171,7 +171,8 @@ const createWindow = async function() {
userData.set("files", userData.data.files);
userData.data.file = file;
userData.set("file", file);
fileWatcher = await chokidar.watch(file);
if(fileWatcher) fileWatcher.close();
fileWatcher = chokidar.watch(file);
fileWatcher
.on("add", function() {
getContent(file).then(content => {
......
......@@ -133,6 +133,8 @@ function configureMatomo() {
}
function configureMainView() {
try {
// close filterMenu if open
if(filterMenu.classList.contains("is-active")) filterMenu.classList.remove("is-active");
// set scaling factor if default font size has changed
if(userData.zoom) {
html.style.zoom = userData.zoom + "%";
......@@ -159,7 +161,6 @@ function configureMainView() {
// check if archive button should be enabled
setButtonState("btnArchiveTodos");
// file is defined, but content is empty
console.log(userData.file);
if(userData.file && todos.items.objects.length===0) {
addTodoContainer.classList.add("is-active");
todoTableSearchContainer.classList.remove("is-active");
......@@ -294,6 +295,13 @@ function registerEvents() {
// ########################################################################################################################
// ONCLICK DEFINITIONS, FILE AND EVENT LISTENERS
// ########################################################################################################################
body.onclick = function(event) {
if(filterMenu.classList.contains("is-active")) {
if(!filterMenu.contains(event.target)) {
filterMenu.classList.remove("is-active");
}
}
}
a.forEach(el => el.addEventListener("click", function(el) {
if(el.target.href && el.target.href === "#") el.preventDefault();
}));
......@@ -446,17 +454,17 @@ function registerKeyboardShortcuts() {
// CMD/metaKey only works on keydown
window.addEventListener("keydown", function(event) {
// open file
if((event.ctrlKey || event.metaKey) && event.key === "o") {
if((event.ctrlKey || event.metaKey) && event.key === "o" && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
window.api.send("openOrCreateFile", "open");
}
// create file
if((event.ctrlKey || event.metaKey) && event.key === "c") {
if((event.ctrlKey || event.metaKey) && event.key === "c" && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
window.api.send("openOrCreateFile", "create");
}
}, true)
window.addEventListener("keyup", function(event) {
// open settings
if(event.key === "," && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key === "," && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
content.showContent(document.getElementById("modalSettings")).then(function(response) {
console.info(response);
}).catch(function(error) {
......@@ -464,7 +472,7 @@ function registerKeyboardShortcuts() {
});
}
// open help
if(event.key === "?" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key === "?" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
content.showContent(document.getElementById("modalHelp")).then(function(response) {
console.info(response);
}).catch(function(error) {
......@@ -472,7 +480,7 @@ function registerKeyboardShortcuts() {
});
}
// create new todo
if(event.key==="n" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key==="n" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
form.show().then(function(response) {
console.info(response);
}).catch(function(error) {
......@@ -480,11 +488,11 @@ function registerKeyboardShortcuts() {
});
}
// find todo
if(event.key==="f" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key==="f" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
todoTableSearch.focus();
}
// reset filters
if(event.key==="0" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key==="0" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
resetFilters().then(function(response) {
console.info(response);
}).catch(function(error) {
......@@ -492,7 +500,7 @@ function registerKeyboardShortcuts() {
});
}
// toggle completed todos
if(event.key==="h" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key==="h" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
view.toggle("showCompleted").then(function(response) {
console.info(response);
}).catch(function(error) {
......@@ -500,7 +508,7 @@ function registerKeyboardShortcuts() {
});
}
// archive todos
if(event.key==="a" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key==="a" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
todos.archiveTodos().then(function(response) {
console.info(response);
}).catch(function(error) {
......@@ -508,7 +516,7 @@ function registerKeyboardShortcuts() {
});
}
// toggle dark mode
if(event.key==="d" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key==="d" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
setTheme(true).then(function(response) {
console.info(response);
}).catch(function(error) {
......@@ -516,7 +524,7 @@ function registerKeyboardShortcuts() {
});
}
// show filter drawer
if(event.key==="b" && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if(event.key==="b" && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
drawer.showDrawer("toggle", "navBtnFilter", "filterDrawer").then(function(result) {
console.log(result);
}).catch(function(error) {
......@@ -524,10 +532,18 @@ function registerKeyboardShortcuts() {
});
}
// reload window
if((event.key === "." || event.key === "F5") && !modalForm.classList.contains("is-active") && document.activeElement.id!="todoTableSearch") {
if((event.key === "." || event.key === "F5") && !modalForm.classList.contains("is-active") && (document.activeElement.id!="todoTableSearch" && document.activeElement.id!="filterMenuInput" && document.activeElement.id!="modalFormInput")) {
location.reload(true);
}
}, true)
// shortcuts for search input field
todoTableSearch.addEventListener("keydown", function () {
if(event.key === "Escape") todoTableSearch.blur();
});
// shortcuts for filter menu input field
filterMenuInput.addEventListener("keydown", function () {
if(event.key === "Escape") filterMenu.classList.remove("is-active");
});
// shortcuts for modal form
modalForm.addEventListener ("keydown", function(event) {
// priority up
......
......@@ -266,7 +266,18 @@ nav {
background: $almost-black!important;
}
}
#filterMenu {
.card {
background: $even-darker-grey;
#filterMenuSave {
background-color: transparent!important;
border-right: 1px solid $almost-black!important;
}
}
.card-footer {
border-top: 1px solid $almost-black!important;
}
}
.contexts {
.button {
color: $sleek-contexts-button;
......
......@@ -333,6 +333,13 @@ nav {
z-index: 35;
}
}
.is-greyed-out {
opacity: .75;
-webkit-filter: grayscale(100%);
}
.button.is-greyed-out {
cursor: default;
}
h4.is-4 {
font-size: 1.35em;
color: $dark-grey;
......@@ -345,10 +352,10 @@ nav {
padding: 0;
margin: 0 0 1.5em 0;
}
.dropdown-item.is-greyed-out {
/*.dropdown-item.is-greyed-out {
opacity: .75;
-webkit-filter: grayscale(100%);
}
}*/
/*#btnResetAllFilters {
display: none;
}
......@@ -745,6 +752,22 @@ nav {
#autoCompleteContainer.is-active {
display: block;
}
#filterMenu {
display: none;
position: fixed;
z-index: 60;
#filterMenuSave {
cursor: pointer;
border: none;
border-right: 1px solid $almost-white;
}
#filterMenuDelete {
color: $has-text-danger;
}
}
#filterMenu.is-active {
display: block;
}
.contentContainer {
width: 100%;
height: 90%;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment