feat: automatically create subtask relations based on indention #2443

Merged
konrad merged 6 commits from feature/subtask-via-indention into main 2022-09-30 11:47:22 +00:00
Owner

This PR adds the automatic creation of subtasks via indention.

For example, creating tasks with this multiline input:

parent task
  sub task one
  sub task two
    sub task three

will make sub task one and sub task two a sub task of parent task and sub task three a sub task of sub task two.

This PR adds the automatic creation of subtasks via indention. For example, creating tasks with this multiline input: ``` parent task sub task one sub task two sub task three ``` will make `sub task one` and `sub task two` a sub task of `parent task` and `sub task three` a sub task of `sub task two`.
konrad requested review from dpschen 2022-09-28 17:48:20 +00:00
Member

Hi konrad!

Thank you for creating a PR!

I've deployed the changes of this PR on a preview environment under this URL: https://2443-feature-subtask-via-indention--vikunja-frontend-preview.netlify.app

You can use this url to view the changes live and test them out.
You will need to manually connect this to an api running somehwere. The easiest to use is https://try.vikunja.io/.

Have a nice day!

Beep boop, I'm a bot.

Hi konrad! Thank you for creating a PR! I've deployed the changes of this PR on a preview environment under this URL: https://2443-feature-subtask-via-indention--vikunja-frontend-preview.netlify.app You can use this url to view the changes live and test them out. You will need to manually connect this to an api running somehwere. The easiest to use is https://try.vikunja.io/. Have a nice day! > Beep boop, I'm a bot.
dpschen requested changes 2022-09-28 19:14:57 +00:00
@ -165,1 +164,3 @@
if (title === '') {
const createdTasks: ITask[] = []
const tasksToCreate = parseSubtasksViaIndention(newTaskTitle.value)
const newTasks = tasksToCreate.map(async t => {

spread title: ({title}) => {

spread title: `({title}) => {`
konrad marked this conversation as resolved
@ -181,0 +185,4 @@
const relations = tasksToCreate.map(async t => {
const createdTask = createdTasks.find(ct => ct.title === t.title)
if (t.parent === null) {
emit('taskAdded', createdTask)

In line 194 we return if typeof createdTask === 'undefined'.
This implies that createdTask could be undefined here aswell. Is that intended?

In line 194 we return if `typeof createdTask === 'undefined'`. This implies that createdTask could be undefined here aswell. Is that intended?
Author
Owner

mhh I didn't think this through. It should never be null.

I've adjusted this so that there's a check before emitting it.

mhh I didn't think this through. It should never be null. I've adjusted this so that there's a check before emitting it.
konrad marked this conversation as resolved
@ -0,0 +1,42 @@
export interface TaskWithParent {

Why do we create a new interface for this and don't use ITask for this?

Why do we create a new interface for this and don't use ITask for this?
Author
Owner

Because this is only used to hold the title and parent title. Using ITask would probably work but I felt it would introduce too much overhead for a simple relation.

Because this is only used to hold the title and parent title. Using `ITask` would probably work but I felt it would introduce too much overhead for a simple relation.

Unsure: would it make sense to create the new type still on ITask with the help of Pick, like:

export interface TaskWithPartent = Pick<ITask, 'id' | 'parent'>
Unsure: would it make sense to create the new type still on `ITask` with the help of `Pick`, like: ```ts export interface TaskWithPartent = Pick<ITask, 'id' | 'parent'> ```
Author
Owner

I think explicitely declaring it is more readable.

I think explicitely declaring it is more readable.

Good with me. I still think we should reuse the types from the task interface. Meaning:

export interface TaskWithParent {
	title: string,
	parent: ITask['id'] | null,
}

The reason beeing here: In the medium term we should change the id in the frontend to a string to make indexing easier. Because objects don't support number types as keys. The alternative would beto use Maps everywhere which is unrealistic (because they do support numbers as keys). By using zod this shouldn't be too complex.

Good with me. I still think we should reuse the types from the task interface. Meaning: ```t export interface TaskWithParent { title: string, parent: ITask['id'] | null, } ``` The reason beeing here: In the medium term we should change the id in the frontend to a string to make indexing easier. Because objects don't support number types as keys. The alternative would beto use Maps everywhere which is unrealistic (because they do support numbers as keys). By using zod this shouldn't be too complex.
Author
Owner

But we're not even using IDs here, only string titles.

But we're not even using IDs here, only string titles.

Arrrrgh… makes sense. Sry i missed that part :D

Arrrrgh… makes sense. Sry i missed that part :D
dpschen marked this conversation as resolved
@ -0,0 +14,4 @@
export function parseSubtasksViaIndention(taskTitles: string): TaskWithParent[] {
const titles = taskTitles.split(/[\r\n]+/)
return titles.map((t, i) => {

Picky: use clear variable name, e.g. title, index.

Makes reading easier since you don't have to remember and jump to the var definition.

Picky: use clear variable name, e.g. `title`, `index`. Makes reading easier since you don't have to remember and jump to the var definition.
Author
Owner

Makes sense. Done!

Makes sense. Done!
konrad marked this conversation as resolved
@ -0,0 +20,4 @@
parent: null,
}
const matched = spaceRegex.exec(t)

Move matched and matchedSpaces in condition aswell since it's not used for index === 0

Move `matched` and `matchedSpaces` in condition aswell since it's not used for `index === 0`
Author
Owner

Added an earlier break for index === 0.

Added an earlier break for `index === 0`.
konrad marked this conversation as resolved
konrad was assigned by dpschen 2022-09-28 19:15:03 +00:00
konrad force-pushed feature/subtask-via-indention from c5f4f22923 to 65b1d9abc5 2022-09-29 16:02:52 +00:00 Compare
dpschen reviewed 2022-09-29 18:18:00 +00:00
dpschen reviewed 2022-09-29 18:21:19 +00:00
@ -0,0 +9,4 @@
const spaceRegex = /^ */
// taskTitles should be multiple lines of task tiles with indention to declare their parent/subtask
Idea: use [JSDoc to explain param](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#param-and-returns)
dpschen marked this conversation as resolved
dpschen reviewed 2022-09-29 18:21:25 +00:00
dpschen approved these changes 2022-09-29 18:22:38 +00:00
dpschen left a comment
Member

Check if any comments make sense, else ready to merge 👍

Check if any comments make sense, else ready to merge 👍
konrad force-pushed feature/subtask-via-indention from 4a05db20f8 to 5bd7c77b68 2022-09-30 11:37:23 +00:00 Compare
konrad scheduled this pull request to auto merge when all checks succeed 2022-09-30 11:37:40 +00:00
konrad merged commit ec227a6872 into main 2022-09-30 11:47:22 +00:00
konrad deleted branch feature/subtask-via-indention 2022-09-30 11:47:53 +00:00
This repo is archived. You cannot comment on pull requests.
No description provided.