Implemented entry exclusions in UI.
* Resolved D0020: Add exclusion filter for entries. * Refactored ``timeline`` fields of several objects in ``ts.js`` to be ``timelineModel`` to be explicit. * Added support for exclusions in ``EntryListView.renderOne`` and ``EntryListView.render``.
This commit is contained in:
parent
602bdca7e3
commit
1fff94b622
143
.ide/vim-views/ts.js.view
Normal file
143
.ide/vim-views/ts.js.view
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
let s:so_save = &so | let s:siso_save = &siso | set so=0 siso=0
|
||||||
|
argglobal
|
||||||
|
edit /mnt/secure/projects/jdb-labs/timestamper/web-app/www/js/ts.js
|
||||||
|
setlocal keymap=
|
||||||
|
setlocal noarabic
|
||||||
|
setlocal autoindent
|
||||||
|
setlocal balloonexpr=
|
||||||
|
setlocal nobinary
|
||||||
|
setlocal bufhidden=
|
||||||
|
setlocal buflisted
|
||||||
|
setlocal buftype=
|
||||||
|
setlocal nocindent
|
||||||
|
setlocal cinkeys=0{,0},0),:,0#,!^F,o,O,e
|
||||||
|
setlocal cinoptions=
|
||||||
|
setlocal cinwords=if,else,while,do,for,switch
|
||||||
|
setlocal comments=s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-
|
||||||
|
setlocal commentstring=/*%s*/
|
||||||
|
setlocal complete=.,w,b,u,t,i
|
||||||
|
setlocal completefunc=
|
||||||
|
setlocal nocopyindent
|
||||||
|
setlocal nocursorcolumn
|
||||||
|
setlocal nocursorline
|
||||||
|
setlocal define=
|
||||||
|
setlocal dictionary=
|
||||||
|
setlocal nodiff
|
||||||
|
setlocal equalprg=
|
||||||
|
setlocal errorformat=
|
||||||
|
setlocal expandtab
|
||||||
|
if &filetype != 'javascript'
|
||||||
|
setlocal filetype=javascript
|
||||||
|
endif
|
||||||
|
setlocal foldcolumn=0
|
||||||
|
setlocal foldenable
|
||||||
|
setlocal foldexpr=0
|
||||||
|
setlocal foldignore=#
|
||||||
|
setlocal foldlevel=0
|
||||||
|
setlocal foldmarker={{{,}}}
|
||||||
|
setlocal foldmethod=manual
|
||||||
|
setlocal foldminlines=1
|
||||||
|
setlocal foldnestmax=20
|
||||||
|
setlocal foldtext=foldtext()
|
||||||
|
setlocal formatexpr=
|
||||||
|
setlocal formatoptions=tcq
|
||||||
|
setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s*
|
||||||
|
setlocal grepprg=
|
||||||
|
setlocal iminsert=2
|
||||||
|
setlocal imsearch=2
|
||||||
|
setlocal include=
|
||||||
|
setlocal includeexpr=
|
||||||
|
setlocal indentexpr=
|
||||||
|
setlocal indentkeys=0{,0},:,0#,!^F,o,O,e
|
||||||
|
setlocal noinfercase
|
||||||
|
setlocal iskeyword=@,48-57,_,192-255
|
||||||
|
setlocal keywordprg=
|
||||||
|
setlocal nolinebreak
|
||||||
|
setlocal nolisp
|
||||||
|
setlocal nolist
|
||||||
|
setlocal makeprg=
|
||||||
|
setlocal matchpairs=(:),{:},[:]
|
||||||
|
setlocal nomodeline
|
||||||
|
setlocal modifiable
|
||||||
|
setlocal nrformats=octal,hex
|
||||||
|
setlocal number
|
||||||
|
setlocal numberwidth=4
|
||||||
|
setlocal omnifunc=
|
||||||
|
setlocal path=
|
||||||
|
setlocal nopreserveindent
|
||||||
|
setlocal nopreviewwindow
|
||||||
|
setlocal quoteescape=\\
|
||||||
|
setlocal noreadonly
|
||||||
|
setlocal norightleft
|
||||||
|
setlocal rightleftcmd=search
|
||||||
|
setlocal noscrollbind
|
||||||
|
setlocal shiftwidth=4
|
||||||
|
setlocal noshortname
|
||||||
|
setlocal nosmartindent
|
||||||
|
setlocal softtabstop=0
|
||||||
|
setlocal nospell
|
||||||
|
setlocal spellcapcheck=[.?!]\\_[\\])'\"\ \ ]\\+
|
||||||
|
setlocal spellfile=
|
||||||
|
setlocal spelllang=en
|
||||||
|
setlocal statusline=
|
||||||
|
setlocal suffixesadd=
|
||||||
|
setlocal swapfile
|
||||||
|
setlocal synmaxcol=3000
|
||||||
|
if &syntax != 'javascript'
|
||||||
|
setlocal syntax=javascript
|
||||||
|
endif
|
||||||
|
setlocal tabstop=4
|
||||||
|
setlocal tags=
|
||||||
|
setlocal textwidth=80
|
||||||
|
setlocal thesaurus=
|
||||||
|
setlocal nowinfixheight
|
||||||
|
setlocal nowinfixwidth
|
||||||
|
setlocal wrap
|
||||||
|
setlocal wrapmargin=0
|
||||||
|
silent! normal! zE
|
||||||
|
9,18fold
|
||||||
|
20,28fold
|
||||||
|
30,43fold
|
||||||
|
45,62fold
|
||||||
|
64,82fold
|
||||||
|
87,289fold
|
||||||
|
291,378fold
|
||||||
|
380,448fold
|
||||||
|
450,487fold
|
||||||
|
489,603fold
|
||||||
|
605,664fold
|
||||||
|
666,702fold
|
||||||
|
9
|
||||||
|
normal zc
|
||||||
|
20
|
||||||
|
normal zc
|
||||||
|
30
|
||||||
|
normal zc
|
||||||
|
45
|
||||||
|
normal zo
|
||||||
|
64
|
||||||
|
normal zc
|
||||||
|
87
|
||||||
|
normal zc
|
||||||
|
291
|
||||||
|
normal zo
|
||||||
|
380
|
||||||
|
normal zc
|
||||||
|
450
|
||||||
|
normal zc
|
||||||
|
489
|
||||||
|
normal zo
|
||||||
|
605
|
||||||
|
normal zc
|
||||||
|
666
|
||||||
|
normal zc
|
||||||
|
let s:l = 334 - ((273 * winheight(0) + 35) / 71)
|
||||||
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
|
exe s:l
|
||||||
|
normal! zt
|
||||||
|
334
|
||||||
|
normal! 042l
|
||||||
|
let &so = s:so_save | let &siso = s:siso_save
|
||||||
|
doautoall SessionLoadPost
|
||||||
|
" vim: set ft=vim :
|
||||||
|
syntax on
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
db/test/ts_ext_data.DCL
Normal file
BIN
db/test/ts_ext_data.DCL
Normal file
Binary file not shown.
Binary file not shown.
BIN
db/test/ts_user.DCL
Normal file
BIN
db/test/ts_user.DCL
Normal file
Binary file not shown.
@ -1,10 +0,0 @@
|
|||||||
Add exclusion filter for entries.
|
|
||||||
=================================
|
|
||||||
|
|
||||||
Add a way for users to add regexes for entries to be ignored in the
|
|
||||||
display. Exclusions may be per-timeline or per-user.
|
|
||||||
|
|
||||||
========= ==========
|
|
||||||
Created: 2011-06-10
|
|
||||||
Resolved: YYYY-MM-DD
|
|
||||||
========= ==========
|
|
22
doc/issues/desktop/0020fs5.rst
Normal file
22
doc/issues/desktop/0020fs5.rst
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Add exclusion filter for entries.
|
||||||
|
=================================
|
||||||
|
|
||||||
|
Add a way for users to add regexes for entries to be ignored in the
|
||||||
|
display. Exclusions may be per-timeline or per-user.
|
||||||
|
|
||||||
|
Resolution
|
||||||
|
----------
|
||||||
|
|
||||||
|
``ts_user`` and ``ts_timeline`` both support an exnteded data property called
|
||||||
|
``entry_exclusions`` which accepts a list of regular expression strings. Any entries
|
||||||
|
whose marks match any of the regular expressions should be excluded from view.
|
||||||
|
|
||||||
|
EntryListView.render filters out any matching entries from its display. It still
|
||||||
|
takes them into account when calculating the duration of other entries.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
========= ==========
|
||||||
|
Created: 2011-06-10
|
||||||
|
Resolved: 2011-06-15
|
||||||
|
========= ==========
|
12
doc/issues/desktop/0023bn7.rst
Normal file
12
doc/issues/desktop/0023bn7.rst
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Check for exclusion after mark update.
|
||||||
|
======================================
|
||||||
|
|
||||||
|
If a user rewrites the mark of an entry, we should check to see if it now
|
||||||
|
matches one of the defined entry exclusions.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
========= ==========
|
||||||
|
Created: YYYY-MM-DD
|
||||||
|
Resolved: YYYY-MM-DD
|
||||||
|
========= ==========
|
@ -36,7 +36,7 @@ update(ER = #ts_entry{}, ExtData) when is_list(ExtData) ->
|
|||||||
write(ER = #ts_entry{}) -> mnesia:dirty_write(ER).
|
write(ER = #ts_entry{}) -> mnesia:dirty_write(ER).
|
||||||
|
|
||||||
write(ER = #ts_entry{}, ExtData) ->
|
write(ER = #ts_entry{}, ExtData) ->
|
||||||
{atomic, Result} = mnesia:transcation(fun() ->
|
{atomic, Result} = mnesia:transaction(fun() ->
|
||||||
ok = mnesia:write(ER),
|
ok = mnesia:write(ER),
|
||||||
ok = ts_common:do_set_ext_data(ER, ExtData)
|
ok = ts_common:do_set_ext_data(ER, ExtData)
|
||||||
end),
|
end),
|
||||||
|
52
www/js/ts.js
52
www/js/ts.js
@ -48,15 +48,16 @@ $(document).ready(function(){
|
|||||||
comparator: function(entry) { return entry.get('timestamp'); },
|
comparator: function(entry) { return entry.get('timestamp'); },
|
||||||
|
|
||||||
initialize: function(model, options) {
|
initialize: function(model, options) {
|
||||||
if (options.timeline == undefined) {
|
if (options.timelineModel == undefined) {
|
||||||
throw "Cannot create an EntryList without a TimelineModel reference."
|
throw "Cannot create an EntryList without a TimelineModel reference."
|
||||||
} else { this.timeline = options.timeline; }
|
} else { this.timelineModel = options.timelineModel; }
|
||||||
|
|
||||||
_.bindAll(this, "url");
|
_.bindAll(this, "url");
|
||||||
},
|
},
|
||||||
|
|
||||||
url: function() {
|
url: function() {
|
||||||
return "/ts_api/entries/" + this.timeline.get('user_id') + "/" + this.timeline.get('id');
|
return "/ts_api/entries/" + this.timelineModel.get('user_id') + "/"
|
||||||
|
+ this.timelineModel.get('id');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -312,10 +313,26 @@ $(document).ready(function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderOne: function(entry, nextEntry) {
|
renderOne: function(entry, nextEntry) {
|
||||||
|
// exclude if any exclusion RegExps match
|
||||||
|
var excluded = _.any(this.entryExclusions,
|
||||||
|
function(exclusion) { return exclusion.test(entry.get("mark"))});
|
||||||
|
|
||||||
|
// create the view if it does not exist
|
||||||
if (!entry.view) { new TS.EntryView(
|
if (!entry.view) { new TS.EntryView(
|
||||||
{model: entry, markdownConverter: this.markdownConverter}); }
|
{model: entry, markdownConverter: this.markdownConverter}); }
|
||||||
entry.view.nextModel = nextEntry
|
entry.view.nextModel = nextEntry
|
||||||
this.entryContainer.prepend(entry.view.render().el);
|
|
||||||
|
// render the element
|
||||||
|
var el = entry.view.render().el;
|
||||||
|
|
||||||
|
// add it to the container
|
||||||
|
this.entryContainer.prepend(el);
|
||||||
|
|
||||||
|
// hide it if excluded
|
||||||
|
if (excluded) {
|
||||||
|
$(el).fadeOut('slow');
|
||||||
|
$(el).addClass('excluded');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
createNewEntryOnEnter: function(e) {
|
createNewEntryOnEnter: function(e) {
|
||||||
@ -337,6 +354,19 @@ $(document).ready(function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
|
// get our user exclusions
|
||||||
|
var userExclusions = TS.app.user.model.get("entry_exclusions") || [];
|
||||||
|
|
||||||
|
// get the current timeline exclusions
|
||||||
|
var timelineExclusions =
|
||||||
|
this.collection.timelineModel.get("entry_exclusions") || [];
|
||||||
|
|
||||||
|
// turn them into RegExps and store them
|
||||||
|
this.entryExclusions = _.map(
|
||||||
|
userExclusions.concat(timelineExclusions),
|
||||||
|
function(exclusion) { return new RegExp(exclusion)} );
|
||||||
|
|
||||||
this.entryContainer.empty();
|
this.entryContainer.empty();
|
||||||
for (var i = 0, len = this.collection.length; i < len; i++) {
|
for (var i = 0, len = this.collection.length; i < len; i++) {
|
||||||
var entry = this.collection.at(i);
|
var entry = this.collection.at(i);
|
||||||
@ -367,7 +397,7 @@ $(document).ready(function(){
|
|||||||
if (options.initialTimelineId == undefined) {
|
if (options.initialTimelineId == undefined) {
|
||||||
throw "Can not create a TimelineListView without an initial timeline."
|
throw "Can not create a TimelineListView without an initial timeline."
|
||||||
} else {
|
} else {
|
||||||
this.selected = this.collection.get(options.initialTimelineId);
|
this.selectedModel = this.collection.get(options.initialTimelineId);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.collection.bind('add', this.renderOne);
|
this.collection.bind('add', this.renderOne);
|
||||||
@ -381,10 +411,10 @@ $(document).ready(function(){
|
|||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
// render the basic template
|
// render the basic template
|
||||||
$(this.el).html(ich.timelineTemplate(this.selected.toJSON()));
|
$(this.el).html(ich.timelineTemplate(this.selectedModel.toJSON()));
|
||||||
|
|
||||||
// render the selection list
|
// render the selection list
|
||||||
_.each(this.collection.without([this.selected]), this.renderOne);
|
_.each(this.collection.without([this.selectedModel]), this.renderOne);
|
||||||
},
|
},
|
||||||
|
|
||||||
editId: function() {
|
editId: function() {
|
||||||
@ -400,7 +430,7 @@ $(document).ready(function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
close: function() {
|
close: function() {
|
||||||
this.selected.save({
|
this.selectedModel.save({
|
||||||
id: this.$('.timeline-id-input').val(),
|
id: this.$('.timeline-id-input').val(),
|
||||||
description: this.$('.timeline-desc-input').val()});
|
description: this.$('.timeline-desc-input').val()});
|
||||||
$(this.el).removeClass('edit-id edit-desc');
|
$(this.el).removeClass('edit-id edit-desc');
|
||||||
@ -515,7 +545,7 @@ $(document).ready(function(){
|
|||||||
// create the entry collection
|
// create the entry collection
|
||||||
this.entries = {};
|
this.entries = {};
|
||||||
this.entries.collection = new TS.EntryList(entryModels,
|
this.entries.collection = new TS.EntryList(entryModels,
|
||||||
{timeline: this.timelines.view.selected});
|
{timelineModel: this.timelines.view.selectedModel});
|
||||||
this.entries.view = new TS.EntryListView(
|
this.entries.view = new TS.EntryListView(
|
||||||
{collection: this.entries.collection});
|
{collection: this.entries.collection});
|
||||||
|
|
||||||
@ -553,10 +583,10 @@ $(document).ready(function(){
|
|||||||
var tl = this.timelines.collection.get(e.srcElement.text);
|
var tl = this.timelines.collection.get(e.srcElement.text);
|
||||||
|
|
||||||
// set the on the timeline view
|
// set the on the timeline view
|
||||||
this.timelines.view.selected = tl;
|
this.timelines.view.selectedModel = tl;
|
||||||
|
|
||||||
// set the timeline on the EntryList
|
// set the timeline on the EntryList
|
||||||
this.entries.collection.timeline = tl;
|
this.entries.collection.timelineModel = tl;
|
||||||
|
|
||||||
// update the last_timeline field of the user model
|
// update the last_timeline field of the user model
|
||||||
this.user.model.set({last_timeline: tl.get('id')});
|
this.user.model.set({last_timeline: tl.get('id')});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user