imdone-core 1.54.1 → 1.54.3
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/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- package/cli.js +68 -0
- package/lib/adapters/file-gateway.js +9 -0
- package/lib/adapters/parsers/content-transformer.js +11 -0
- package/lib/card.js +3 -9
- package/lib/file.js +10 -7
- package/lib/migrate-config.js +1 -1
- package/lib/plugins/default-board-actions-plugin.js +2 -1
- package/lib/plugins/default-board-properties-plugin.js +31 -15
- package/lib/plugins/plugin-manager.js +6 -4
- package/lib/project.js +35 -4
- package/lib/repository.js +54 -26
- package/package.json +5 -2
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve imdone
|
|
4
|
+
title: ''
|
|
5
|
+
labels: 'bug'
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce**
|
|
14
|
+
Steps to reproduce the behavior:
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. Scroll down to '....'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
**Expected behavior**
|
|
21
|
+
A clear and concise description of what you expected to happen.
|
|
22
|
+
|
|
23
|
+
**Screenshots**
|
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
|
25
|
+
|
|
26
|
+
**Desktop (please complete the following information):**
|
|
27
|
+
- OS: [e.g. iOS]
|
|
28
|
+
- Browser (If imdone web site) [e.g. chrome, safari]
|
|
29
|
+
- Imdone Version [e.g. 22]
|
|
30
|
+
|
|
31
|
+
**Additional context**
|
|
32
|
+
Add any other context about the problem here.
|
|
33
|
+
|
|
34
|
+
**DoD**
|
|
35
|
+
- [ ] Issue is understood
|
|
36
|
+
- [ ] Fix is implemented and tested
|
|
37
|
+
- [ ] Fix is deployed in the current release
|
package/cli.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const ora = require('ora')
|
|
5
|
+
const chalk = require('chalk')
|
|
6
|
+
const package = require('./package.json')
|
|
7
|
+
const { createFileSystemProject } = require('./lib/project-factory.js')
|
|
8
|
+
// const { log } = hideLogs()
|
|
9
|
+
const spinner = ora('Loading unicorns')
|
|
10
|
+
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
spinner.color = 'yellow';
|
|
13
|
+
spinner.text = 'Loading rainbows';
|
|
14
|
+
}, 1000);
|
|
15
|
+
|
|
16
|
+
function actionCancelled() {
|
|
17
|
+
log(chalk.bgRed('Action canceled'))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const mainCmd = program
|
|
21
|
+
.version(package.version, '-v, --version', 'output the current version')
|
|
22
|
+
|
|
23
|
+
mainCmd
|
|
24
|
+
.command('action <pluginName> <actionTitle>')
|
|
25
|
+
.option('-t, --task <task>', 'Task filePath:line')
|
|
26
|
+
.description('Run a board action')
|
|
27
|
+
.action(async function (plugin, title, options) {
|
|
28
|
+
spinner.start()
|
|
29
|
+
const action = {plugin, title}
|
|
30
|
+
const [filePath, line] = options.task ? options.task.split(':') : []
|
|
31
|
+
try {
|
|
32
|
+
const project = createFileSystemProject({path: process.env.PWD})
|
|
33
|
+
await project.init()
|
|
34
|
+
await project.toImdoneJSON()
|
|
35
|
+
chalk.bgGreen('Project loaded')
|
|
36
|
+
const file = filePath && project.getFile(filePath)
|
|
37
|
+
const task = file && line > -1 && file.getTaskAtLine(line)
|
|
38
|
+
await project.performBoardAction(action, task)
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error(e)
|
|
41
|
+
actionCancelled()
|
|
42
|
+
} finally {
|
|
43
|
+
spinner.stop()
|
|
44
|
+
process.exit(0)
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
program.parse();
|
|
50
|
+
|
|
51
|
+
function hideLogs() {
|
|
52
|
+
const log = console.log
|
|
53
|
+
const info = console.info
|
|
54
|
+
const warn = console.warn
|
|
55
|
+
const logQueue = {warn: [], info: [], log: []}
|
|
56
|
+
if (!process.env.DEBUG) {
|
|
57
|
+
Object.keys(logQueue).forEach((key) => {
|
|
58
|
+
console[key] = function(...args) {
|
|
59
|
+
logQueue[key].push(args)
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
return {log, info, warn, logQueue}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function actionCancelled() {
|
|
67
|
+
log(chalk.bgRed('Action canceled'))
|
|
68
|
+
}
|
|
@@ -38,6 +38,15 @@ const gateway = {
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
|
|
41
|
+
async stat(path, opts) {
|
|
42
|
+
try {
|
|
43
|
+
return await fs.promises.stat(path, opts)
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
41
50
|
readFileSync(...args) {
|
|
42
51
|
console.warn('sync call')
|
|
43
52
|
return fs.readFileSync.apply({}, args)
|
|
@@ -3,6 +3,7 @@ const uniqid = require('uniqid');
|
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
5
|
format,
|
|
6
|
+
encodeMarkdownLinks
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
function removeDisplayComments(description) {
|
|
@@ -59,6 +60,16 @@ function interpolate(content, data, opts) {
|
|
|
59
60
|
return { content, hasInterpolation, errorTokens };
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
function encodeMarkdownLinks(content) {
|
|
64
|
+
return content.replace(/(?<!!)\[(.*?)\]\((.*?)( ".*?")?\)/g, (match, p1, p2, p3) => {
|
|
65
|
+
// URI encode file links
|
|
66
|
+
const title = p3 || '';
|
|
67
|
+
const encodedUrl = p2.replace(/\s/g, '%20').replace(/\)/g, '%29').replace(/\(/g, '%28');
|
|
68
|
+
const link = `[${p1}](${encodedUrl}${title})`;
|
|
69
|
+
return link.replace(/%20(".*?"\))$/, ' $1');
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
62
73
|
function format(content, data, mustache) {
|
|
63
74
|
const opts = { interpolate: /(?<![`\\])\${([\s\S]+?)}/g };
|
|
64
75
|
const errorTokens = {};
|
package/lib/card.js
CHANGED
|
@@ -9,7 +9,7 @@ const _get = require('lodash.get')
|
|
|
9
9
|
const eol = require('eol')
|
|
10
10
|
const allEmoji = require('markdown-it-emoji/lib/data/full.json')
|
|
11
11
|
const { getFunctionSignature } = require('./adapters/parsers/function-parser')
|
|
12
|
-
const { format } = require('./adapters/parsers/content-transformer')
|
|
12
|
+
const { format, encodeMarkdownLinks } = require('./adapters/parsers/content-transformer')
|
|
13
13
|
const { removeMD } = require('./adapters/markdown')
|
|
14
14
|
|
|
15
15
|
const CONTENT_TOKEN = '__CONTENT__'
|
|
@@ -218,14 +218,8 @@ module.exports = function newCard(task, _project, dontParse) {
|
|
|
218
218
|
})
|
|
219
219
|
const encodedText = encodeURIComponent(plainDescription)
|
|
220
220
|
const encodedMD = encodeURIComponent(content)
|
|
221
|
-
content = content
|
|
222
|
-
|
|
223
|
-
.replace(/(?<!!)\[(.*?)\]\((.*?)( ".*?")?\)/g, (match, p1, p2, p3) => {
|
|
224
|
-
// URI encode file links
|
|
225
|
-
const title = p3 || ''
|
|
226
|
-
const link = `[${p1}](${p2.replace(/\s/g, '%20')}${title})`
|
|
227
|
-
return link.replace(/%20(".*?"\))$/, ' $1')
|
|
228
|
-
})
|
|
221
|
+
content = content.replace(CONTENT_TOKEN, encodedText)
|
|
222
|
+
content = encodeMarkdownLinks(content)
|
|
229
223
|
return { encodedMD, encodedText, content }
|
|
230
224
|
}
|
|
231
225
|
|
package/lib/file.js
CHANGED
|
@@ -324,7 +324,7 @@ File.prototype.transformTasks = function (config, modify) {
|
|
|
324
324
|
|
|
325
325
|
// TODO Blank lines should be allowed in code tasks
|
|
326
326
|
// <!--
|
|
327
|
-
// #imdone-1.
|
|
327
|
+
// #imdone-1.54.0
|
|
328
328
|
// #feature
|
|
329
329
|
// order:-105
|
|
330
330
|
// -->
|
|
@@ -338,7 +338,7 @@ File.prototype.extractCodeStyleTasks = function (config, pos, content) {
|
|
|
338
338
|
while ((result = codeStyleRegex.exec(content)) !== null) {
|
|
339
339
|
var posInContent = pos + result.index
|
|
340
340
|
var line = this.getLineNumber(posInContent)
|
|
341
|
-
if (self.
|
|
341
|
+
if (self.getTaskAtLine(line)) continue
|
|
342
342
|
var charBeforeList = this.getContent().substring(
|
|
343
343
|
posInContent - 1,
|
|
344
344
|
posInContent
|
|
@@ -391,7 +391,7 @@ File.prototype.extractHashStyleTasks = function (config, pos, content) {
|
|
|
391
391
|
if (this.isWithinCodeSpanOrBlock(result.index, content)) continue
|
|
392
392
|
|
|
393
393
|
const line = this.getLineNumber(posInContent)
|
|
394
|
-
if (this.
|
|
394
|
+
if (this.getTaskAtLine(line)) continue
|
|
395
395
|
|
|
396
396
|
if (lang.block) {
|
|
397
397
|
const blockEndPos = text.indexOf(lang.block.end)
|
|
@@ -427,7 +427,7 @@ File.prototype.extractLinkStyleTasks = function (config, pos, content) {
|
|
|
427
427
|
const posInContent = result.index + pos + beforeLength
|
|
428
428
|
if (this.isWithinCodeSpanOrBlock(result.index, content)) continue
|
|
429
429
|
var line = this.getLineNumber(posInContent)
|
|
430
|
-
if (self.
|
|
430
|
+
if (self.getTaskAtLine(line)) continue
|
|
431
431
|
if (!config.listExists(list)) continue
|
|
432
432
|
log = require('debug')('extractLinkStyleTasks')
|
|
433
433
|
log('*********************************************************')
|
|
@@ -462,7 +462,7 @@ File.prototype.extractCheckboxTasks = function (config, pos, content) {
|
|
|
462
462
|
let tasks = []
|
|
463
463
|
const hasTaskAtLine = (line) => {
|
|
464
464
|
return (
|
|
465
|
-
this.
|
|
465
|
+
this.getTaskAtLine(line) ||
|
|
466
466
|
tasks.find((task) => {
|
|
467
467
|
return line >= task.line && line <= task.lastLine
|
|
468
468
|
})
|
|
@@ -493,7 +493,7 @@ File.prototype.extractCheckboxTasks = function (config, pos, content) {
|
|
|
493
493
|
if (tasks) {
|
|
494
494
|
const hasTaskAtLine = (line) => {
|
|
495
495
|
return (
|
|
496
|
-
this.
|
|
496
|
+
this.getTaskAtLine(line) ||
|
|
497
497
|
tasks.find((task) => {
|
|
498
498
|
return line > task.line && line <= task.lastLine
|
|
499
499
|
})
|
|
@@ -541,6 +541,9 @@ File.prototype.extractAndTransformTasks = function (config) {
|
|
|
541
541
|
this.transformTasks(config)
|
|
542
542
|
}
|
|
543
543
|
|
|
544
|
+
// TODO Extract functions should be moved to another file
|
|
545
|
+
// Only pass the needed config values to the functions
|
|
546
|
+
// #imdone-1.54.0
|
|
544
547
|
File.prototype.extractTasksInCodeFile = function (config) {
|
|
545
548
|
var self = this
|
|
546
549
|
var commentRegex = this.getCodeCommentRegex()
|
|
@@ -1002,7 +1005,7 @@ File.prototype.tasksMatch = function (config, task, line, taskText) {
|
|
|
1002
1005
|
)
|
|
1003
1006
|
}
|
|
1004
1007
|
|
|
1005
|
-
File.prototype.
|
|
1008
|
+
File.prototype.getTaskAtLine = function (line) {
|
|
1006
1009
|
return this.getTasks().find((task) => {
|
|
1007
1010
|
return line >= task.line && line <= task.lastLine
|
|
1008
1011
|
})
|
package/lib/migrate-config.js
CHANGED
|
@@ -135,7 +135,7 @@ module.exports = function (repo, defaultSettings = defaultSettingsObject) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
// Remove settings.filteredLists
|
|
138
|
-
if (config.settings.filteredLists
|
|
138
|
+
if (config.settings.filteredLists) {
|
|
139
139
|
delete config.settings.filteredLists
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -8,6 +8,7 @@ module.exports = class DefaultBoardActionsPlugin extends Plugin {
|
|
|
8
8
|
getBoardActions() {
|
|
9
9
|
const project = this.project
|
|
10
10
|
const isWindows = process.platform === 'win32'
|
|
11
|
+
const openIn = isWindows ? 'Explorer' : 'Finder'
|
|
11
12
|
|
|
12
13
|
return [
|
|
13
14
|
{
|
|
@@ -42,7 +43,7 @@ module.exports = class DefaultBoardActionsPlugin extends Plugin {
|
|
|
42
43
|
},
|
|
43
44
|
},
|
|
44
45
|
{
|
|
45
|
-
title: `Open in ${
|
|
46
|
+
title: `Open in ${openIn}`,
|
|
46
47
|
keys: ['alt+shift+o'],
|
|
47
48
|
icon: "folder",
|
|
48
49
|
async action () {
|
|
@@ -28,11 +28,12 @@ module.exports = class DefaultBoardPropertiesPlugin extends Plugin {
|
|
|
28
28
|
const clearFilterURL = this.getFilterURL('');
|
|
29
29
|
const getFilterURL = (filter) => this.getFilterURL(filter);
|
|
30
30
|
const getFilterLink = (filter) => `[Filter By: ${filter}](${this.getFilterURL(filter)})`;
|
|
31
|
-
//
|
|
31
|
+
// TODO Make board properties self documenting
|
|
32
32
|
// <!--
|
|
33
33
|
// #imdone-1.53.16
|
|
34
34
|
// #feature
|
|
35
35
|
// created:2025-02-14T16:54:22-05:00
|
|
36
|
+
// order:-185
|
|
36
37
|
// -->
|
|
37
38
|
// [Feature Description]
|
|
38
39
|
// ## :ballot_box_with_check: Tasks
|
|
@@ -59,28 +60,43 @@ module.exports = class DefaultBoardPropertiesPlugin extends Plugin {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
getFilterURL(filter) {
|
|
62
|
-
|
|
63
|
+
filter = filter.replace(/\(/g, '%28').replace(/\)/g, '%29');
|
|
64
|
+
return encodeURI(`imdone://${this.project.path}?filter=${filter}`)
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
// READY Also include templates (md files) in .github and it's subdirs
|
|
68
|
+
// <!--
|
|
69
|
+
// order:0
|
|
70
|
+
// -->
|
|
65
71
|
async getTemplates() {
|
|
66
|
-
const { preparePathForWriting, readdir, readFile } = this.project.fileGateway
|
|
72
|
+
const { preparePathForWriting, readdir, readFile, stat } = this.project.fileGateway;
|
|
67
73
|
const templateDir = path.join(this.project.configDir, 'templates');
|
|
74
|
+
const githubDir = path.join(this.project.path, '.github');
|
|
75
|
+
|
|
68
76
|
preparePathForWriting(templateDir);
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
77
|
+
|
|
78
|
+
const readMarkdownFiles = async (dir, prefix = '') => {
|
|
79
|
+
const files = await readdir(dir);
|
|
80
|
+
const readFilePromises = files.map(async (file) => {
|
|
81
|
+
const filePath = path.join(dir, file);
|
|
82
|
+
const fileStat = await stat(filePath);
|
|
83
|
+
if (fileStat && fileStat.isDirectory()) {
|
|
84
|
+
return readMarkdownFiles(filePath, `${prefix}${file}_`);
|
|
85
|
+
} else if (file.endsWith('.md')) {
|
|
86
|
+
const data = await readFile(filePath, 'utf-8');
|
|
87
|
+
const templateName = `${prefix}${file.replace('.md', '').replace(/[^a-zA-Z0-9]/g, '_')}`;
|
|
88
|
+
return { [templateName]: data };
|
|
89
|
+
}
|
|
90
|
+
return {};
|
|
75
91
|
});
|
|
76
|
-
});
|
|
77
92
|
|
|
78
|
-
|
|
93
|
+
const allTemplates = await Promise.all(readFilePromises);
|
|
94
|
+
return allTemplates.reduce((acc, template) => ({ ...acc, ...template }), {});
|
|
95
|
+
};
|
|
79
96
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
}, {});
|
|
97
|
+
const templatesFromTemplateDir = await readMarkdownFiles(templateDir);
|
|
98
|
+
const templatesFromGithubDir = await readMarkdownFiles(githubDir, 'github_');
|
|
83
99
|
|
|
84
|
-
return { simple: simpleTemplate, ...
|
|
100
|
+
return { simple: simpleTemplate, ...templatesFromTemplateDir, ...templatesFromGithubDir };
|
|
85
101
|
}
|
|
86
102
|
}
|
|
@@ -216,7 +216,9 @@ module.exports = class PluginManager extends Emitter {
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
getPluginInstance(name) {
|
|
219
|
-
|
|
219
|
+
const plugin = this.getPlugin(name)
|
|
220
|
+
if (!plugin) throw new Error(`Plugin ${name} not found`)
|
|
221
|
+
return plugin.pluginInstance
|
|
220
222
|
}
|
|
221
223
|
|
|
222
224
|
getPlugin(name) {
|
|
@@ -392,12 +394,12 @@ module.exports = class PluginManager extends Emitter {
|
|
|
392
394
|
}
|
|
393
395
|
}
|
|
394
396
|
|
|
395
|
-
performBoardAction(action, task) {
|
|
397
|
+
async performBoardAction(action, task) {
|
|
396
398
|
const plugin = this.getPluginInstance(action.plugin)
|
|
397
399
|
try {
|
|
398
400
|
return action.index
|
|
399
|
-
? plugin.getBoardActions()[action.index].action(task)
|
|
400
|
-
: plugin.getBoardActions().find(a => a.title === action.title).action(task)
|
|
401
|
+
? await plugin.getBoardActions()[action.index].action(task)
|
|
402
|
+
: await plugin.getBoardActions().find(a => a.title === action.title).action(task)
|
|
401
403
|
} catch (e) {
|
|
402
404
|
this.pluginError('getBoardActions', plugin, e)
|
|
403
405
|
}
|
package/lib/project.js
CHANGED
|
@@ -174,10 +174,9 @@ module.exports = class WorkerProject extends Project {
|
|
|
174
174
|
console.timeEnd('getTags time')
|
|
175
175
|
|
|
176
176
|
console.time('getLists time')
|
|
177
|
-
const lists = this.filter
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}) : allLists
|
|
177
|
+
const lists = this.filter
|
|
178
|
+
? this.getRequestedLists(cards)
|
|
179
|
+
: allLists
|
|
181
180
|
console.timeEnd('getLists time')
|
|
182
181
|
|
|
183
182
|
console.timeEnd('toJSON time')
|
|
@@ -202,6 +201,20 @@ module.exports = class WorkerProject extends Project {
|
|
|
202
201
|
}
|
|
203
202
|
}
|
|
204
203
|
|
|
204
|
+
getRequestedLists(cards) {
|
|
205
|
+
return this.getLists({
|
|
206
|
+
tasks: this.getCards(this.filter, cards),
|
|
207
|
+
populateFiltered: true,
|
|
208
|
+
}).map(list => {
|
|
209
|
+
const configList = this.config.lists.find(l => l.name === list.name)
|
|
210
|
+
list.hidden = configList && configList.hidden
|
|
211
|
+
if (this.hideLists.includes(list.name)) {
|
|
212
|
+
list.hidden = true
|
|
213
|
+
}
|
|
214
|
+
return list
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
|
|
205
218
|
emit() {} // This is implemented in imdone UI worker
|
|
206
219
|
|
|
207
220
|
emitUpdate() {
|
|
@@ -350,9 +363,12 @@ module.exports = class WorkerProject extends Project {
|
|
|
350
363
|
}
|
|
351
364
|
|
|
352
365
|
filterCards(cards, filter) {
|
|
366
|
+
this.hideLists = []
|
|
353
367
|
const {
|
|
354
368
|
result,
|
|
369
|
+
hideLists
|
|
355
370
|
} = Repository.filterCards(cards, filter)
|
|
371
|
+
this.hideLists = hideLists
|
|
356
372
|
return result
|
|
357
373
|
}
|
|
358
374
|
|
|
@@ -457,6 +473,10 @@ module.exports = class WorkerProject extends Project {
|
|
|
457
473
|
})
|
|
458
474
|
}
|
|
459
475
|
|
|
476
|
+
getFile(filePath) {
|
|
477
|
+
return this.repo.getFile(filePath)
|
|
478
|
+
}
|
|
479
|
+
|
|
460
480
|
getFileForTask(task) {
|
|
461
481
|
return this.repo.getFileForTask(task)
|
|
462
482
|
}
|
|
@@ -503,6 +523,12 @@ module.exports = class WorkerProject extends Project {
|
|
|
503
523
|
this.emit('project.openUrl', url)
|
|
504
524
|
}
|
|
505
525
|
|
|
526
|
+
// TODO For methods that emit, they should still do the thing without imdone UI
|
|
527
|
+
// <!--
|
|
528
|
+
// #urgent
|
|
529
|
+
// #important
|
|
530
|
+
// order:-195
|
|
531
|
+
// -->
|
|
506
532
|
async openPath(path) {
|
|
507
533
|
this.emit('project.openPath', path)
|
|
508
534
|
}
|
|
@@ -760,6 +786,11 @@ module.exports = class WorkerProject extends Project {
|
|
|
760
786
|
if (action.plugin) return this.pluginManager.performCardAction(action, task)
|
|
761
787
|
|
|
762
788
|
const actionFunction = task.getCardActions()[action.index].action
|
|
789
|
+
// TODO These card actions should be removed
|
|
790
|
+
// #imdone-1.54.0
|
|
791
|
+
// <!--
|
|
792
|
+
// order:-175
|
|
793
|
+
// -->
|
|
763
794
|
const actions = {
|
|
764
795
|
filter: (filter) => {
|
|
765
796
|
this.setFilter(filter)
|
package/lib/repository.js
CHANGED
|
@@ -33,11 +33,11 @@ var _isFunction = require('lodash.isfunction'),
|
|
|
33
33
|
Task = require('./task'),
|
|
34
34
|
newCard = require('./card'),
|
|
35
35
|
{ replaceDateLanguage } = require('./adapters/parsers/DateLanguageParser'),
|
|
36
|
-
{ getRawTask, isNumber } = require('./adapters/parsers/task/CardContentParser')
|
|
37
|
-
|
|
36
|
+
{ getRawTask, isNumber, LIST_NAME_PATTERN } = require('./adapters/parsers/task/CardContentParser'),
|
|
37
|
+
XRegExp = require('xregexp'),
|
|
38
|
+
promisify = require('util').promisify
|
|
38
39
|
|
|
39
40
|
const appContext = require('./context/ApplicationContext')
|
|
40
|
-
const get = require('lodash.get')
|
|
41
41
|
|
|
42
42
|
var ERRORS = constants.ERRORS,
|
|
43
43
|
DEFAULT_FILE_PATTERN = constants.DEFAULT_FILE_PATTERN,
|
|
@@ -210,24 +210,28 @@ Repository.prototype.addAllMeta = function (meta) {
|
|
|
210
210
|
* @param {} list
|
|
211
211
|
* @return
|
|
212
212
|
*/
|
|
213
|
-
Repository.prototype.addList = function (list, cb) {
|
|
214
|
-
cb = tools.cb(cb)
|
|
215
|
-
if (this.listExists(list.name)) return cb()
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
this.config.code.include_lists.push(codeList)
|
|
213
|
+
Repository.prototype.addList = async function (list, cb) {
|
|
214
|
+
cb = tools.cb(cb);
|
|
215
|
+
if (this.listExists(list.name)) return cb();
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
list = _omit(list, 'tasks');
|
|
219
|
+
this.config.lists.push(new List(list));
|
|
220
|
+
|
|
221
|
+
if (!list.filter && !/[a-z]/.test(list.name)) {
|
|
222
|
+
const codeList = list.name.replace(/\s+/g, '-').toUpperCase();
|
|
223
|
+
if (!this.config.code.include_lists.find((name) => name === codeList)) {
|
|
224
|
+
this.config.code.include_lists.push(codeList);
|
|
225
|
+
}
|
|
227
226
|
}
|
|
227
|
+
|
|
228
|
+
await promisify(this.saveConfig).bind(this)();
|
|
229
|
+
this.emit('list.modified', list);
|
|
230
|
+
cb();
|
|
231
|
+
} catch (err) {
|
|
232
|
+
cb(err);
|
|
228
233
|
}
|
|
229
|
-
|
|
230
|
-
}
|
|
234
|
+
};
|
|
231
235
|
|
|
232
236
|
Repository.prototype.removeList = function (list, cb) {
|
|
233
237
|
return new Promise((resolve, reject) => {
|
|
@@ -271,7 +275,7 @@ Repository.prototype.getConfig = function () {
|
|
|
271
275
|
* @return MemberExpression
|
|
272
276
|
*/
|
|
273
277
|
Repository.prototype.getLists = function () {
|
|
274
|
-
return this.getConfig().lists
|
|
278
|
+
return this.getConfig().lists.map(obj => ({...obj}));
|
|
275
279
|
}
|
|
276
280
|
|
|
277
281
|
Repository.prototype.getVisibleLists = function () {
|
|
@@ -503,6 +507,7 @@ Repository.prototype.removeFile = function (file) {
|
|
|
503
507
|
* @return CallExpression
|
|
504
508
|
*/
|
|
505
509
|
Repository.prototype.getFile = function (path) {
|
|
510
|
+
path = this.getRelativePath(path)
|
|
506
511
|
return this.files.find((file) => file.path === path)
|
|
507
512
|
}
|
|
508
513
|
|
|
@@ -768,8 +773,8 @@ Repository.prototype.getList = function (name) {
|
|
|
768
773
|
}
|
|
769
774
|
|
|
770
775
|
|
|
771
|
-
Repository.prototype.getListById = function(id) {
|
|
772
|
-
return
|
|
776
|
+
Repository.prototype.getListById = function(id, lists = this.getLists()) {
|
|
777
|
+
return lists.find((list) => list.id === id)
|
|
773
778
|
}
|
|
774
779
|
|
|
775
780
|
Repository.prototype.hideList = function (name, cb) {
|
|
@@ -864,11 +869,11 @@ Repository.prototype.updateList = function(id, {name, filter}) {
|
|
|
864
869
|
if (!filter && this.listExists(name)) return resolve()
|
|
865
870
|
|
|
866
871
|
const lists = this.getLists()
|
|
867
|
-
const list = this.getListById(id)
|
|
872
|
+
const list = this.getListById(id, lists)
|
|
868
873
|
const oldName = list.name
|
|
869
874
|
const oldFilter = list.filter
|
|
870
875
|
list.name = name
|
|
871
|
-
|
|
876
|
+
if (oldFilter) list.filter = filter
|
|
872
877
|
this.setLists(lists)
|
|
873
878
|
|
|
874
879
|
if (oldName === name || oldFilter) {
|
|
@@ -1627,6 +1632,25 @@ Repository.regexQuery = function (tasks, queryString) {
|
|
|
1627
1632
|
};
|
|
1628
1633
|
|
|
1629
1634
|
|
|
1635
|
+
Repository.parseHideListsFromQueryString = function (queryString) {
|
|
1636
|
+
const hideLists = []
|
|
1637
|
+
const regex = `hide:(\\s*((${LIST_NAME_PATTERN},?\\s?)+))?`
|
|
1638
|
+
queryString = queryString.replaceAll(
|
|
1639
|
+
// hide lists example `hide: list1, list2`
|
|
1640
|
+
new XRegExp(regex, 'g'),
|
|
1641
|
+
(match, allLists, lists) => {
|
|
1642
|
+
lists && lists.split(',').forEach((list) => {
|
|
1643
|
+
hideLists.push(list.trim())
|
|
1644
|
+
})
|
|
1645
|
+
return ''
|
|
1646
|
+
}
|
|
1647
|
+
).trim()
|
|
1648
|
+
return {
|
|
1649
|
+
hideLists,
|
|
1650
|
+
queryString,
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1630
1654
|
Repository.parseSortFromQueryString = function (queryString) {
|
|
1631
1655
|
const sort = []
|
|
1632
1656
|
queryString = queryString.replace(
|
|
@@ -1663,7 +1687,10 @@ Repository.sortByQuery = function (tasks, queryString = '') {
|
|
|
1663
1687
|
Repository.filterCards = function (tasks, _queryString = '') {
|
|
1664
1688
|
let query
|
|
1665
1689
|
_queryString = replaceDateLanguage(_queryString)
|
|
1666
|
-
let { sort, queryString } = Repository.parseSortFromQueryString(_queryString)
|
|
1690
|
+
let { sort, queryString } = Repository.parseSortFromQueryString(_queryString);
|
|
1691
|
+
const hideListsQuery = Repository.parseHideListsFromQueryString(queryString);
|
|
1692
|
+
queryString = hideListsQuery.queryString;
|
|
1693
|
+
const hideLists = hideListsQuery.hideLists;
|
|
1667
1694
|
try {
|
|
1668
1695
|
query = monquery(queryString)
|
|
1669
1696
|
} catch (e) {
|
|
@@ -1679,7 +1706,8 @@ Repository.filterCards = function (tasks, _queryString = '') {
|
|
|
1679
1706
|
return {
|
|
1680
1707
|
result,
|
|
1681
1708
|
query,
|
|
1682
|
-
sort
|
|
1709
|
+
sort,
|
|
1710
|
+
hideLists
|
|
1683
1711
|
}
|
|
1684
1712
|
}
|
|
1685
1713
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imdone-core",
|
|
3
|
-
"version": "1.54.
|
|
3
|
+
"version": "1.54.3",
|
|
4
4
|
"description": "imdone-core",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"imdone-cli": "./cli.js"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
10
|
"build": "doctoc --github --notitle README.md && npm test",
|
|
8
11
|
"coverage": "nyc --reporter=lcov --reporter=text --reporter=html mocha --exit",
|
|
@@ -48,7 +51,7 @@
|
|
|
48
51
|
"cheerio": "^1.0.0-rc.10",
|
|
49
52
|
"chrono-node": "^2.6.4",
|
|
50
53
|
"command-exists": "^1.2.9",
|
|
51
|
-
"commander": "^11.
|
|
54
|
+
"commander": "^11.1.0",
|
|
52
55
|
"debug": ">=4.3.4",
|
|
53
56
|
"download": "^8.0.0",
|
|
54
57
|
"eol": "^0.9.1",
|