V5 Kanban - moving tasks between columns

Hi,

I can’t seem to find any info on it but… should I be able to simply drag and drop tasks from one column to another in kanban view? I saw that in a few videos on v4.x and I’m not able to do it on v5. I tried a bunch of different browsers, I also tried https://demo.invoiceninja.com to see if it was somehow my install that was buggy, but I can’t move tasks on your demo either - to put them in different columns I have to manually edit their status. Am I missing something?

Thanks

Hi,

In v5 you currently need to hold for a second to start dragging the task.

2 Likes

Oh wow :joy:

Thansk so much, I thought I was going crazy…

Hello again @hillel ,

After your last input, everything was working fine with visually reorganizing tasks until now: I now get an Error 500 when moving tasks from column to column in Kanban mode. Here is what I get in laravel.log when this happens:

[2021-05-21 17:12:03] production.ERROR: Creating default object from empty value {"userId":1,"exception":"[object] (ErrorException(code: 0): Creating default object from empty value at domain.com/app/Http/Controllers/TaskController.php:659)
[stacktrace]
#0 domain.com/app/Http/Controllers/TaskController.php(659): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(2, 'Creating defaul...', '/home/charleso/...', 659, Array)
#1 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\\Http\\Controllers\\TaskController->sort(Object(App\\Http\\Requests\\Task\\SortTaskRequest))
#2 domain.com/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('sort', Array)
#3 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Route.php(254): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\TaskController), 'sort')
#4 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Route.php(197): Illuminate\\Routing\\Route->runController()
#5 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(695): Illuminate\\Routing\\Route->run()
#6 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#7 domain.com/app/Http/Middleware/Locale.php(34): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#8 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\Locale->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#9 domain.com/app/Http/Middleware/TokenAuth.php(80): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#10 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\TokenAuth->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#11 domain.com/app/Http/Middleware/SetDb.php(40): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#12 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\SetDb->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#13 domain.com/app/Http/Middleware/Cors.php(25): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#14 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\Cors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#15 domain.com/app/Http/Middleware/QueryLogging.php(40): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#16 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\QueryLogging->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#17 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#18 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#19 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(127): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#20 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(63): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequest(Object(Illuminate\\Http\\Request), Object(Closure), Array)
#21 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure), '300', '1')
#22 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#23 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(697): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#24 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(672): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#25 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(636): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#26 domain.com/vendor/laravel/framework/src/Illuminate/Routing/Router.php(625): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#27 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(166): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#28 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#29 domain.com/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php(55): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#30 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Sentry\\Laravel\\Http\\SetRequestIpMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#31 domain.com/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php(52): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#32 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Sentry\\Laravel\\Http\\SetRequestMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#33 domain.com/app/Http/Middleware/Cors.php(25): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#34 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\Cors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#35 domain.com/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#36 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#37 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#38 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#39 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#40 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#41 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#42 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#43 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#44 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#45 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#46 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#47 domain.com/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Middleware.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#48 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Sentry\\Laravel\\Tracing\\Middleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#49 domain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#50 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(141): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#51 domain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#52 domain.com/public/index.php(57): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#53 {main}
"} 

If I manually edit the task to change their status, it works and then if I then reload the kanban boards, the modified tasks would have moved to the appropriate columns. But if I use the drag and drop feature, the 500 Error happens. Reloading the page after the 500 Error seems to indicate that the status was actually changed during the drag&drop, but it needs a refresh to show up.

Any help with this would be much appreciated!

Thanks

Update: refreshing the page after the 500 Error does not seem to move a task anymore. I have to manually edit its state.

Update 2: It was a database issue. A deleted task that was restored was still showing a timestamp at “deleted_at” in the task table in the db, which was causing the error. Nulling the entry in that column fixed the error!

Was this problem caused by the app or did you manually update the database?

It’s hard to tell what happened exactly, but I remeber manually deleting a test task in the database after seeing that I could not completely deleting it (as far as I understand) directly in Invoice Ninja. Then maybe some cache file was responsible for corrupting the db by making the task still available while at the same time having an entry for a deleted date, which screwed up Kanban (but all tasks were still working in other display modes).

So I am potentially partially responsible for the issue, but could it be possible to make 500 Errors a bit more verbose? The Laravel log was very opaque and eventually pretty much incomprehensible for me and I had more success looking through the database for rogue entries than trying to understand what Illuminate/Routing/ControllerDispatcher.php is all about :sweat_smile:

It’s extremely hard for us to make the app work (or even fail) reliably when manual changes are made to the database. We STRONGLY ADVISE never making any direct changes unless absolutely required.

cc @david

Duly noted! I won’t touch the database anymore unless necessary!

Thanks for all your hard work on the app, it is really nicely done by the way! :slight_smile:

1 Like

Was this problem caused by the app or did you manually update the database?

Hi @hillel ,

In a previous message we thought that I had 500 errors with Kanban due to me tampering with the database, but it started happening again after my “fix”, so I went to my test install with Debug Mode on (with a fresh, untouched database) and I tried to reproduce the error, and I did.

Basically, it seems that as soon as I archive a task and I try to move other, active tasks from a column to another, I get a an error with /public/index.php/api/v1/tasks/sort?

The message I get is 500: Creating default object from empty value

As soon as I restore the archived task to “Active” to 500 error stops when moving either this task or another one through columns. I thus think that it may be a real bug, since I can reproduce it 100% on a fresh install.

I also tried testing with deleting a task, and it ends up the same way as archiving it. Restoring it from deletion fixes the issue.

As noted in a previous message, this issue is only happening in Kanban mode: manually switching the state of a task between backlog/ready to go/in progress/done does not cause 500 Errors.

Update: the bug also happens on your hosted demo:

Thanks for the details!

cc @david

1 Like

Fix checked in, available in the next release.

1 Like

@david

That was fast, thanks so much!! :star_struck:

1 Like

Wow, I thought that this functionality was removed in v5. Thanks for the tip.