Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ransome
sleek
Commits
623441bd
Commit
623441bd
authored
Jul 08, 2021
by
ransome1
Browse files
Added empty state for filter categories in drawer, added updated br-pt translations
parent
2523137f
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
package.json
View file @
623441bd
{
"name"
:
"sleek"
,
"productName"
:
"sleek"
,
"version"
:
"1.0.9-rc.
1
"
,
"version"
:
"1.0.9-rc.
2
"
,
"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"
,
...
...
src/css/style.css
View file @
623441bd
...
...
@@ -1418,28 +1418,31 @@ body.compact #autoCompleteContainer h4 {
#drawerContainer
.drawer
button
.is-greyed-out
.tag
{
display
:
none
;
}
#drawerContainer
.drawer
h4
.is-4
{
#drawerContainer
.drawer
section
{
width
:
100%
;
padding
:
0
;
margin
:
0
0
1.5em
0
;
}
#drawerContainer
.drawer
section
h4
.is-4
{
font-size
:
1.25em
;
font-family
:
FreeSansBold
;
margin
-bottom
:
0em
;
margin
:
0
0
0.75em
0
;
}
#drawerContainer
.drawer
h4
.is-4.clickable
{
#drawerContainer
.drawer
section
h4
.is-4.clickable
{
cursor
:
pointer
;
display
:
inline
;
}
#drawerContainer
.drawer
h4
.is-4.clickable
i
{
#drawerContainer
.drawer
section
h4
.is-4.clickable
i
{
color
:
#3273dc
;
}
#drawerContainer
.drawer
h4
.is-4.clickable
::after
{
#drawerContainer
.drawer
section
h4
.is-4.clickable
::after
{
height
:
1em
;
display
:
block
;
content
:
"\a"
;
white-space
:
pre
;
}
#drawerContainer
.drawer
section
{
width
:
100%
;
padding
:
0
;
margin
:
0
0
1.5em
0
;
#drawerContainer
.drawer
section
.todoFilterHint
{
cursor
:
pointer
;
}
#drawerContainer
.drawer
table
tr
td
:nth-child
(
odd
)
{
width
:
auto
;
...
...
src/css/style.css.map
View file @
623441bd
This diff is collapsed.
Click to expand it.
src/js/filters.mjs
View file @
623441bd
...
...
@@ -3,6 +3,7 @@ import { userData, handleError, translations, setUserData, startBuilding, getCon
import
{
createModalJail
}
from
"
../configs/modal.config.mjs
"
;
import
{
_paq
}
from
"
./matomo.mjs
"
;
import
{
items
}
from
"
./todos.mjs
"
;
import
{
showContent
}
from
"
./content.mjs
"
;
import
{
isToday
,
isPast
,
isFuture
}
from
"
./date.mjs
"
;
import
*
as
filterlang
from
"
./filterlang.mjs
"
;
import
{
runQuery
}
from
"
./filterquery.mjs
"
;
...
...
@@ -169,6 +170,83 @@ function filterItems(items) {
return
Promise
.
reject
(
error
);
}
}
function
generateCategoryContainer
(
category
,
autoCompletePrefix
,
filterFragment
)
{
try
{
let
hideFilterCategories
=
userData
.
hideFilterCategories
;
selectedFilters
=
new
Array
;
if
(
userData
.
selectedFilters
&&
userData
.
selectedFilters
.
length
>
0
)
selectedFilters
=
JSON
.
parse
(
userData
.
selectedFilters
);
// creates a div for the specific filter section
let
todoFiltersContainer
=
document
.
createElement
(
"
section
"
);
todoFiltersContainer
.
setAttribute
(
"
class
"
,
category
);
// translate headline
if
(
category
==
"
contexts
"
)
{
headline
=
translations
.
contexts
;
}
else
if
(
category
==
"
projects
"
){
headline
=
translations
.
projects
;
}
else
if
(
category
==
"
priority
"
){
headline
=
translations
.
priority
;
}
// if filters are available and if container is not the autocomplete one
let
todoFilterHeadline
=
document
.
createElement
(
"
h4
"
);
// show suggestion box when prefix is present
if
(
autoCompletePrefix
!==
undefined
)
{
autoCompleteContainer
.
classList
.
add
(
"
is-active
"
);
autoCompleteContainer
.
focus
();
todoFilterHeadline
.
innerHTML
=
headline
;
}
else
{
todoFilterHeadline
.
setAttribute
(
"
class
"
,
"
is-4 clickable
"
);
// setup greyed out state
if
(
hideFilterCategories
.
includes
(
category
))
{
todoFilterHeadline
.
innerHTML
=
"
<i class=
\"
far fa-eye
\"
tabindex=
\"
-1
\"
></i>
"
+
headline
;
todoFilterHeadline
.
classList
.
add
(
"
is-greyed-out
"
);
}
else
{
todoFilterHeadline
.
innerHTML
=
"
<i class=
\"
far fa-eye-slash
\"
tabindex=
\"
-1
\"
></i>
"
+
headline
;
todoFilterHeadline
.
classList
.
remove
(
"
is-greyed-out
"
);
}
// add click event
todoFilterHeadline
.
onclick
=
function
()
{
document
.
getElementById
(
"
todoTableWrapper
"
).
scrollTo
(
0
,
0
);
if
(
hideFilterCategories
.
includes
(
category
))
{
hideFilterCategories
.
splice
(
hideFilterCategories
.
indexOf
(
category
),
1
)
}
else
{
hideFilterCategories
.
push
(
category
);
hideFilterCategories
=
[...
new
Set
(
hideFilterCategories
.
join
(
"
,
"
).
split
(
"
,
"
))];
}
setUserData
(
"
hideFilterCategories
"
,
hideFilterCategories
)
startBuilding
();
}
}
// add the headline before category container
todoFiltersContainer
.
appendChild
(
todoFilterHeadline
);
// add filter fragment
if
(
filterFragment
.
childElementCount
>
0
)
{
todoFiltersContainer
.
appendChild
(
filterFragment
);
// if no filter fragment is available a empty filter container will be shown
}
else
{
let
todoFilterHint
=
document
.
createElement
(
"
div
"
);
todoFilterHint
.
setAttribute
(
"
class
"
,
"
todoFilterHint
"
);
todoFilterHint
.
innerHTML
=
"
<i class=
\"
fas fa-question-circle
\"
></i> No
"
+
category
+
"
available. Learn how to add one.
"
;
todoFilterHint
.
onclick
=
function
()
{
showContent
(
"
modalHelp
"
);
// trigger matomo event
if
(
userData
.
matomoEvents
)
_paq
.
push
([
"
trackEvent
"
,
"
Drawer
"
,
"
Click on Help
"
]);
}
todoFiltersContainer
.
appendChild
(
todoFilterHint
);
}
// add filter fragment if it is available
if
(
filterFragment
)
{
todoFiltersContainer
.
appendChild
(
filterFragment
);
}
// return the container
return
Promise
.
resolve
(
todoFiltersContainer
);
}
catch
(
error
)
{
error
.
functionName
=
generateCategoryContainer
.
name
;
return
Promise
.
reject
(
error
);
}
}
function
generateFilterData
(
autoCompleteCategory
,
autoCompleteValue
,
autoCompletePrefix
,
caretPosition
)
{
try
{
// reset filter counter
...
...
@@ -191,11 +269,10 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
// needs to be reset every run, because it can be overwritten by previous autocomplete
categories
=
[
"
priority
"
,
"
contexts
"
,
"
projects
"
];
}
categories
.
forEach
((
category
)
=>
{
// TODO build empty container shells here
//console.log(category);
let
todoFiltersContainer
;
categories
.
forEach
(
async
(
category
)
=>
{
// array to collect all the available filters in the data
let
filters
=
new
Array
();
let
filterArray
;
...
...
@@ -281,26 +358,29 @@ function generateFilterData(autoCompleteCategory, autoCompleteValue, autoComplet
}
else
if
(
!
filter
[
1
]
&&
!
(
filter
[
0
]
in
filters
))
{
filters
[
filter
[
0
]]
=
0
;
}
if
(
filters
!=
null
)
{
if
(
filters
!=
=
null
)
{
return
filters
;
}
},
{});
// build the filter buttons
if
(
filters
[
0
]
!=
""
&&
filters
.
length
>
0
)
{
// add category length to total filter count
generateFilterButtons
(
category
,
autoCompleteValue
,
autoCompletePrefix
,
caretPosition
).
then
(
response
=>
{
if
(
userData
.
hideFilterCategories
.
includes
(
category
))
{
response
.
classList
.
add
(
"
is-greyed-out
"
);
}
container
.
appendChild
(
response
);
}).
catch
(
error
=>
{
handleError
(
error
);
});
}
else
{
autoCompleteContainer
.
classList
.
remove
(
"
is-active
"
);
autoCompleteContainer
.
blur
();
console
.
log
(
"
Info: No
"
+
category
+
"
found in todo.txt data, so no filters will be generated
"
);
}
// TODO can this be done above already?
// remove empty filter entries
filters
=
filters
.
filter
(
function
(
filter
)
{
//console.log(filter[0]);
if
(
filter
[
0
])
return
filter
;
});
// build filter buttons and add them to a fragment
let
filterFragment
=
await
generateFilterButtons
(
category
,
autoCompleteValue
,
autoCompletePrefix
,
caretPosition
).
then
(
response
=>
{
return
response
;
}).
catch
(
error
=>
{
handleError
(
error
);
});
// build and configure the category container and finally append the fragments
todoFiltersContainer
=
await
generateCategoryContainer
(
category
,
autoCompletePrefix
,
filterFragment
).
then
(
response
=>
{
return
response
;
}).
catch
(
error
=>
{
handleError
(
error
);
});
container
.
appendChild
(
todoFiltersContainer
);
});
return
Promise
.
resolve
(
"
Success: Filter data generated
"
);
}
catch
(
error
)
{
...
...
@@ -330,63 +410,8 @@ function selectFilter(filter, category) {
}
function
generateFilterButtons
(
category
,
autoCompleteValue
,
autoCompletePrefix
,
caretPosition
)
{
try
{
let
hideFilterCategories
=
userData
.
hideFilterCategories
;
selectedFilters
=
new
Array
;
if
(
userData
.
selectedFilters
&&
userData
.
selectedFilters
.
length
>
0
)
selectedFilters
=
JSON
.
parse
(
userData
.
selectedFilters
);
// creates a div for the specific filter section
let
todoFiltersContainer
=
document
.
createElement
(
"
section
"
);
todoFiltersContainer
.
setAttribute
(
"
class
"
,
category
);
// translate headline
if
(
category
==
"
contexts
"
)
{
headline
=
translations
.
contexts
;
}
else
if
(
category
==
"
projects
"
){
headline
=
translations
.
projects
;
}
else
if
(
category
==
"
priority
"
){
headline
=
translations
.
priority
;
}
if
(
autoCompletePrefix
===
undefined
&&
userData
.
showEmptyFilters
)
{
// create a sub headline element
let
todoFilterHeadline
=
document
.
createElement
(
"
h4
"
);
todoFilterHeadline
.
setAttribute
(
"
class
"
,
"
is-4 clickable
"
);
// setup greyed out state
if
(
hideFilterCategories
.
includes
(
category
))
{
todoFilterHeadline
.
innerHTML
=
"
<i class=
\"
far fa-eye
\"
tabindex=
\"
-1
\"
></i>
"
+
headline
;
todoFilterHeadline
.
classList
.
add
(
"
is-greyed-out
"
);
}
else
{
todoFilterHeadline
.
innerHTML
=
"
<i class=
\"
far fa-eye-slash
\"
tabindex=
\"
-1
\"
></i>
"
+
headline
;
todoFilterHeadline
.
classList
.
remove
(
"
is-greyed-out
"
);
}
// add click event
todoFilterHeadline
.
onclick
=
function
()
{
document
.
getElementById
(
"
todoTableWrapper
"
).
scrollTo
(
0
,
0
);
if
(
hideFilterCategories
.
includes
(
category
))
{
hideFilterCategories
.
splice
(
hideFilterCategories
.
indexOf
(
category
),
1
)
}
else
{
hideFilterCategories
.
push
(
category
);
hideFilterCategories
=
[...
new
Set
(
hideFilterCategories
.
join
(
"
,
"
).
split
(
"
,
"
))];
}
setUserData
(
"
hideFilterCategories
"
,
hideFilterCategories
)
startBuilding
();
}
// add the headline before category container
todoFiltersContainer
.
appendChild
(
todoFilterHeadline
);
}
else
{
let
todoFilterHeadline
=
document
.
createElement
(
"
h4
"
);
// show suggestion box when prefix is present
if
(
autoCompletePrefix
!==
undefined
)
{
autoCompleteContainer
.
classList
.
add
(
"
is-active
"
);
autoCompleteContainer
.
focus
();
}
todoFilterHeadline
.
setAttribute
(
"
tabindex
"
,
-
1
);
// create a sub headline element
todoFilterHeadline
.
setAttribute
(
"
class
"
,
"
is-4
"
);
// no need for tab index if the headline is in suggestion box
//if(autoCompletePrefix==undefined)
todoFilterHeadline
.
innerHTML
=
headline
;
// add the headline before category container
todoFiltersContainer
.
appendChild
(
todoFilterHeadline
);
}
// to figure out how many buttons with filters behind them have been build in the end
// create a fragment to collect the filters in
let
filterFragment
=
document
.
createDocumentFragment
();
// build one button each
for
(
let
filter
in
filtersCounted
)
{
// skip this loop if no filters are present
...
...
@@ -406,7 +431,6 @@ function generateFilterButtons(category, autoCompleteValue, autoCompletePrefix,
todoFiltersItem
.
addEventListener
(
"
contextmenu
"
,
event
=>
{
// jail the modal
createModalJail
(
filterContext
);
filterContext
.
style
.
left
=
event
.
x
+
"
px
"
;
filterContext
.
style
.
top
=
event
.
y
+
"
px
"
;
filterContext
.
classList
.
add
(
"
is-active
"
);
...
...
@@ -485,9 +509,9 @@ function generateFilterButtons(category, autoCompleteValue, autoCompletePrefix,
});
}
filterCounter
++
;
todoFiltersContainer
.
appendChild
(
todoFiltersItem
);
filterFragment
.
appendChild
(
todoFiltersItem
);
}
return
Promise
.
resolve
(
todoFiltersContainer
);
return
Promise
.
resolve
(
filterFragment
);
}
catch
(
error
)
{
error
.
functionName
=
generateFilterButtons
.
name
;
return
Promise
.
reject
(
error
);
...
...
src/render.js
View file @
623441bd
...
...
@@ -143,18 +143,18 @@ function configureMainView() {
// check if archive button should be enabled
//setButtonState("btnArchiveTodos");
// configure navigation
if
(
filters
.
filterCounter
===
0
)
{
// hide filter nav button
navBtnFilter
.
classList
.
add
(
"
is-hidden
"
);
// close filter drawer
drawer
.
show
(
navBtnFilter
,
document
.
getElementById
(
navBtnFilter
.
getAttribute
(
"
data-drawer
"
)),
true
).
then
(
function
(
result
)
{
console
.
log
(
result
);
}).
catch
(
function
(
error
)
{
handleError
(
error
);
});
}
else
{
navBtnFilter
.
classList
.
remove
(
"
is-hidden
"
);
}
//
if(filters.filterCounter===0) {
//
// hide filter nav button
//
navBtnFilter.classList.add("is-hidden");
//
// close filter drawer
//
drawer.show(navBtnFilter, document.getElementById(navBtnFilter.getAttribute("data-drawer")), true).then(function(result) {
//
console.log(result);
//
}).catch(function(error) {
//
handleError(error);
//
});
//
} else {
//
navBtnFilter.classList.remove("is-hidden");
//
}
// configure table view
if
(
userData
.
file
&&
todos
.
items
.
objects
.
length
===
0
)
{
addTodoContainer
.
classList
.
add
(
"
is-active
"
);
...
...
src/scss/drawer.scss
View file @
623441bd
...
...
@@ -120,28 +120,31 @@
display
:
none
;
}
}
h4
.is-4
{
font-size
:
1
.25em
;
font-family
:
FreeSansBold
;
margin-bottom
:
0em
;
}
h4
.is-4.clickable
{
cursor
:
pointer
;
display
:
inline
;
i
{
color
:
$has-text-link
;
}
}
h4
.
is-4
.
clickable
:
:
after
{
height
:
1em
;
display
:
block
;
content
:
'\A'
;
white-space
:
pre
;
}
section
{
width
:
100%
;
padding
:
0
;
margin
:
0
0
1
.5em
0
;
h4
.is-4
{
font-size
:
1
.25em
;
font-family
:
FreeSansBold
;
margin
:
0
0
0
.75em
0
;
}
h4
.is-4.clickable
{
cursor
:
pointer
;
display
:
inline
;
i
{
color
:
$has-text-link
;
}
}
h4
.
is-4
.
clickable
:
:
after
{
height
:
1em
;
display
:
block
;
content
:
'\A'
;
white-space
:
pre
;
}
.todoFilterHint
{
cursor
:
pointer
;
}
}
table
tr
td
:nth-child
(
odd
)
{
width
:
auto
;
...
...
src/scss/modal.scss
View file @
623441bd
...
...
@@ -194,9 +194,6 @@
button
{
margin
:
0
.5rem
.5rem
0
;
}
// button:focus-visible {
// background: white!important;
// }
}
section
:
:-
webkit-scrollbar
{
background-color
:
transparent
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment