wuffle 0.72.0 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/apps/search/Search.js +14 -10
- package/lib/apps/store-filter.js +31 -0
- package/lib/index.js +2 -1
- package/lib/store.js +25 -1
- package/package.json +2 -2
- package/wuffle.config.example.js +41 -36
|
@@ -8,7 +8,11 @@ const CHILD_LINK_TYPES = {
|
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* @typedef { {
|
|
11
|
+
* @typedef { {
|
|
12
|
+
* defaultFilter?: string,
|
|
13
|
+
* treatBotsAsReviewers?: boolean
|
|
14
|
+
* } } SearchConfig
|
|
15
|
+
*
|
|
12
16
|
* @typedef { import('../../util/search.js').SearchTerm } SearchTerm
|
|
13
17
|
*
|
|
14
18
|
* @typedef { import('../../types.js').GitHubUser } GitHubUser
|
|
@@ -32,7 +36,8 @@ export default function Search(config, logger, store) {
|
|
|
32
36
|
});
|
|
33
37
|
|
|
34
38
|
const {
|
|
35
|
-
treatBotsAsReviewers = false
|
|
39
|
+
treatBotsAsReviewers = false,
|
|
40
|
+
defaultFilter
|
|
36
41
|
} = config;
|
|
37
42
|
|
|
38
43
|
function filterNoop(issue) {
|
|
@@ -446,9 +451,11 @@ export default function Search(config, logger, store) {
|
|
|
446
451
|
*/
|
|
447
452
|
function getSearchFilter(search, user) {
|
|
448
453
|
|
|
449
|
-
|
|
454
|
+
if (!search) {
|
|
455
|
+
search = defaultFilter;
|
|
456
|
+
}
|
|
450
457
|
|
|
451
|
-
const
|
|
458
|
+
const filterFn = buildFilterFn(search, user);
|
|
452
459
|
|
|
453
460
|
return function(issue) {
|
|
454
461
|
try {
|
|
@@ -456,12 +463,7 @@ export default function Search(config, logger, store) {
|
|
|
456
463
|
return filterFn(issue);
|
|
457
464
|
}
|
|
458
465
|
|
|
459
|
-
|
|
460
|
-
return ignoreFilterFn(issue);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// no user search, no ignore filter,
|
|
464
|
-
// show all issues
|
|
466
|
+
// no search, show all issues
|
|
465
467
|
return true;
|
|
466
468
|
} catch (err) {
|
|
467
469
|
log.warn({ issue: issueIdent(issue), err }, 'filter failed');
|
|
@@ -475,4 +477,6 @@ export default function Search(config, logger, store) {
|
|
|
475
477
|
// api ///////////////////////
|
|
476
478
|
|
|
477
479
|
this.getSearchFilter = getSearchFilter;
|
|
480
|
+
|
|
481
|
+
this.buildFilterFn = buildFilterFn;
|
|
478
482
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef { { ignoreFilter?: string } } StoreFilterConfig
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* An component that configures the store to filter certain elements,
|
|
7
|
+
* effectively making them invisible to the board and its users.
|
|
8
|
+
*
|
|
9
|
+
* @param { StoreFilterConfig } config
|
|
10
|
+
*
|
|
11
|
+
* @param { import('../store.js').default } store
|
|
12
|
+
* @param { import('./search/Search.js').default } search
|
|
13
|
+
* @param { import('../types.js').Logger } logger
|
|
14
|
+
*/
|
|
15
|
+
export default function StoreFilter(config, store, search, logger) {
|
|
16
|
+
|
|
17
|
+
const log = logger.child({
|
|
18
|
+
name: 'wuffle:store-filter'
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if ('ignoreFilter' in config) {
|
|
22
|
+
const ignoreFilterFn = search.buildFilterFn(config.ignoreFilter);
|
|
23
|
+
|
|
24
|
+
if (ignoreFilterFn) {
|
|
25
|
+
store.setIgnoreFilter(ignoreFilterFn);
|
|
26
|
+
} else {
|
|
27
|
+
log.warn('unparseable <ignoreFilter> - please correct your board configuration');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -27,7 +27,8 @@ const appModules = [
|
|
|
27
27
|
import('./apps/auth-routes/index.js'),
|
|
28
28
|
import('./apps/board-api-routes/index.js'),
|
|
29
29
|
import('./apps/board-routes.js'),
|
|
30
|
-
import('./apps/reindex-store.js')
|
|
30
|
+
import('./apps/reindex-store.js'),
|
|
31
|
+
import('./apps/store-filter.js')
|
|
31
32
|
];
|
|
32
33
|
|
|
33
34
|
import loadConfig from './load-config.js';
|
package/lib/store.js
CHANGED
|
@@ -4,6 +4,9 @@ import { issueIdent } from './util/index.js';
|
|
|
4
4
|
import { findLinks } from './util/links.js';
|
|
5
5
|
import { Links } from './links.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @typedef { import('./apps/search/Search.js').FilterFn } FilterFn
|
|
9
|
+
*/
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* The store that holds all board data
|
|
@@ -39,6 +42,10 @@ export default class Store {
|
|
|
39
42
|
this.updateContext = null;
|
|
40
43
|
this.queuedUpdates = [];
|
|
41
44
|
|
|
45
|
+
/**
|
|
46
|
+
* @type { FilterFn }
|
|
47
|
+
*/
|
|
48
|
+
this.ignoreFilter = (issue) => false;
|
|
42
49
|
|
|
43
50
|
this.on('updateIssue', async event => {
|
|
44
51
|
|
|
@@ -303,7 +310,9 @@ export default class Store {
|
|
|
303
310
|
/**
|
|
304
311
|
* Update issue, tagging it as updated.
|
|
305
312
|
*
|
|
306
|
-
*
|
|
313
|
+
* If issue matches the ignore filter it will be removed as part of the update.
|
|
314
|
+
*
|
|
315
|
+
* @return {Promise<Object|undefined>} a promise to the updated issue or undefined in case the update triggered issue deletion
|
|
307
316
|
*/
|
|
308
317
|
updateIssue(update) {
|
|
309
318
|
|
|
@@ -374,6 +383,14 @@ export default class Store {
|
|
|
374
383
|
|
|
375
384
|
const ident = issueIdent(updatedIssue);
|
|
376
385
|
|
|
386
|
+
if (this.ignoreFilter(updatedIssue)) {
|
|
387
|
+
this.log.debug({ issue: ident }, 'issue matching ignore filter');
|
|
388
|
+
|
|
389
|
+
await this.removeIssueById(id);
|
|
390
|
+
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
|
|
377
394
|
this.log.debug({
|
|
378
395
|
issue: ident
|
|
379
396
|
}, 'process update');
|
|
@@ -861,6 +878,13 @@ export default class Store {
|
|
|
861
878
|
}, 'load JSON complete');
|
|
862
879
|
}
|
|
863
880
|
|
|
881
|
+
/**
|
|
882
|
+
* @param { FilterFn } ignoreFilter
|
|
883
|
+
*/
|
|
884
|
+
setIgnoreFilter(ignoreFilter) {
|
|
885
|
+
this.ignoreFilter = ignoreFilter;
|
|
886
|
+
}
|
|
887
|
+
|
|
864
888
|
}
|
|
865
889
|
|
|
866
890
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wuffle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.73.0",
|
|
4
4
|
"description": "A multi-repository task board for GitHub issues",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Nico Rehwaldt",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"index.js",
|
|
83
83
|
"wuffle.config.example.js"
|
|
84
84
|
],
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "a58cc7fcd73db7a1dc7babc25b97bb590119b69d"
|
|
86
86
|
}
|
package/wuffle.config.example.js
CHANGED
|
@@ -1,47 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This defines board specific configuration.
|
|
3
|
-
*
|
|
4
|
-
* ### Name
|
|
5
|
-
*
|
|
6
|
-
* The name of your board, displayed in the board header.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* ### Description
|
|
10
|
-
*
|
|
11
|
-
* Optional description of the board, will be served with the board front-end
|
|
12
|
-
* for SEO purposes.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* ### Columns
|
|
16
|
-
*
|
|
17
|
-
* Valid fields for columns are
|
|
18
|
-
*
|
|
19
|
-
* * name - unique name
|
|
20
|
-
* * label - label, if present on a GitHub issue column will be set
|
|
21
|
-
* * closed - if the column issues must be closed
|
|
22
|
-
* * sorting - true if column cards should be sorted
|
|
23
|
-
* incrementally based on links
|
|
24
|
-
* * fifo - true to turn the default column ordering from
|
|
25
|
-
* last in first out to first in first out
|
|
26
|
-
* * states - a list of board states to map to this column
|
|
27
|
-
*
|
|
28
|
-
* The default column is the column that holds open issues without
|
|
29
|
-
* any label constraints (Inbox in the example below).
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* ### Search Config
|
|
33
|
-
*
|
|
34
|
-
* You may define a default filter to apply to the board if
|
|
35
|
-
* there is no user-defined search query.
|
|
36
|
-
*
|
|
37
|
-
* You may also configure whether bots are counted as
|
|
38
|
-
* legitimate reviewers (for both review and approval).
|
|
39
3
|
*/
|
|
40
4
|
export default {
|
|
41
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The name of your board, displayed in the board header.
|
|
8
|
+
*/
|
|
42
9
|
name: 'My Wuffle Board',
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* (Optional) description of the board, will be served with the board
|
|
13
|
+
* front-end for SEO purposes.
|
|
14
|
+
*/
|
|
43
15
|
description: 'This board organizes all my tasks',
|
|
44
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Definitions of columns to display on the board, and their state.
|
|
19
|
+
*
|
|
20
|
+
* Valid fields for columns are
|
|
21
|
+
*
|
|
22
|
+
* * name - unique name
|
|
23
|
+
* * label - label, if present on a GitHub issue column will be set
|
|
24
|
+
* * closed - if the column issues must be closed
|
|
25
|
+
* * sorting - true if column cards should be sorted
|
|
26
|
+
* incrementally based on links
|
|
27
|
+
* * fifo - true to turn the default column ordering from
|
|
28
|
+
* last in first out to first in first out
|
|
29
|
+
* * states - a list of board states to map to this column
|
|
30
|
+
*
|
|
31
|
+
* The default column is the column that holds open issues without
|
|
32
|
+
* any label constraints (Inbox in the example below).
|
|
33
|
+
*/
|
|
45
34
|
columns: [
|
|
46
35
|
{ name: 'Inbox', label: null },
|
|
47
36
|
{ name: 'Backlog', label: 'backlog', sorting: true },
|
|
@@ -51,7 +40,23 @@ export default {
|
|
|
51
40
|
{ name: 'Done', label: null, closed: true }
|
|
52
41
|
],
|
|
53
42
|
|
|
43
|
+
/**
|
|
44
|
+
* (Optional) default filter to apply to the board if there is no
|
|
45
|
+
* user-defined search query.
|
|
46
|
+
*/
|
|
54
47
|
defaultFilter: '!repo:"some/ignored-repository"',
|
|
55
48
|
|
|
49
|
+
/**
|
|
50
|
+
* (Optional) Filter matching issues that shall not be saved.
|
|
51
|
+
*
|
|
52
|
+
* Matching issues will not be added. If they were previously on the board
|
|
53
|
+
* they will be removed as part of an update.
|
|
54
|
+
*/
|
|
55
|
+
ignoreFilter: 'label:"invalid"',
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Whether or not bots are treated as legitimate reviewers, for review and
|
|
59
|
+
* approval queries. Defaults to `false`.
|
|
60
|
+
*/
|
|
56
61
|
treatBotsAsReviewers: false
|
|
57
62
|
};
|