Skip to content

Commit

Permalink
Support displaying child workflows (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
Naugrimm authored Nov 8, 2023
1 parent 4d63997 commit 3eb81db
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 51 deletions.
25 changes: 25 additions & 0 deletions app/Dto/ChartDataPoint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);

namespace Waterline\Dto;

use JsonSerializable;

class ChartDataPoint implements JsonSerializable
{
public function __construct(
private string $x,
private float | int $yMin,
private float | int $yMax,
private string $type,
) {}

public function jsonSerialize(): mixed
{
return [
'x' => $this->x,
'y' => [$this->yMin, $this->yMax],
'type' => $this->type,
];
}
}
34 changes: 3 additions & 31 deletions app/Http/Controllers/WorkflowsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Waterline\Http\Controllers;

use SplFileObject;
use Waterline\Http\Resources\StoredWorkflowResource;
use Waterline\Transformer\WorkflowToChartDataTransformer;
use Workflow\Models\StoredWorkflow;
use Workflow\Serializers\Y;

Expand Down Expand Up @@ -34,36 +36,6 @@ public function running() {
public function show($id) {
$flow = config('workflows.stored_workflow_model', StoredWorkflow::class)::with(['exceptions', 'logs'])->find($id);

$flow->arguments = serialize(Y::unserialize($flow->arguments));

$flow->logs = $flow->logs->map(function ($log) {
$log->result = serialize(Y::unserialize($log->result));
return $log;
});

$flow->exceptions = $flow->exceptions->map(function ($exception) {
$exception->code ??= null;
$unserialized = Y::unserialize($exception->exception);
if (is_array($unserialized)
&& array_key_exists('class', $unserialized)
&& is_subclass_of($unserialized['class'], \Throwable::class)
&& file_exists($unserialized['file'])
) {
$file = new SplFileObject($unserialized['file']);
$file->seek($unserialized['line'] - 4);
for ($line = 0; $line < 7; ++$line) {
$exception->code .= $file->current();
$file->next();
if ($file->eof()) break;
}
$exception->code = rtrim($exception->code);
$exception->exception = serialize($unserialized);
}
return $exception;
});

$flow->output = $flow->output === null ? serialize(null) : serialize(Y::unserialize($flow->output));

return $flow;
return StoredWorkflowResource::make($flow);
}
}
50 changes: 50 additions & 0 deletions app/Http/Resources/StoredWorkflowExceptionResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);

namespace Waterline\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use SplFileObject;
use Waterline\Transformer\WorkflowToChartDataTransformer;
use Workflow\Models\StoredWorkflow;
use Workflow\Models\StoredWorkflowException;
use Workflow\Serializers\Y;

/**
* @mixin StoredWorkflowException
*/
class StoredWorkflowExceptionResource extends JsonResource
{
public static $wrap = null;

public function toArray(Request $request)
{
$code = null;
$exception = $this->exception;

$unserialized = Y::unserialize($exception);
if (is_array($unserialized)
&& array_key_exists('class', $unserialized)
&& is_subclass_of($unserialized['class'], \Throwable::class)
&& file_exists($unserialized['file'])
) {
$file = new SplFileObject($unserialized['file']);
$file->seek($unserialized['line'] - 4);
for ($line = 0; $line < 7; ++$line) {
$exception->code .= $file->current();
$file->next();
if ($file->eof()) break;
}
$code = rtrim($exception->code);
$exception = serialize($unserialized);
}

return [
"code" => $code,
"exception" => $exception,
"class" => $this->class,
"created_at" => $this->created_at,
];
}
}
31 changes: 31 additions & 0 deletions app/Http/Resources/StoredWorkflowLogResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);

namespace Waterline\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Waterline\Transformer\WorkflowToChartDataTransformer;
use Workflow\Models\StoredWorkflow;
use Workflow\Models\StoredWorkflowLog;
use Workflow\Serializers\Y;

/**
* @mixin StoredWorkflowLog
*/
class StoredWorkflowLogResource extends JsonResource
{
public static $wrap = null;

public function toArray(Request $request)
{
return [
"id" => $this->id,
"index" => $this->index,
"now" => $this->now,
"class" => $this->class,
"result" => serialize(Y::unserialize($this->result)),
"created_at" => $this->created_at,
];
}
}
34 changes: 34 additions & 0 deletions app/Http/Resources/StoredWorkflowResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);

namespace Waterline\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Waterline\Transformer\WorkflowToChartDataTransformer;
use Workflow\Models\StoredWorkflow;
use Workflow\Serializers\Y;

/**
* @mixin StoredWorkflow
*/
class StoredWorkflowResource extends JsonResource
{
public static $wrap = null;

public function toArray(Request $request)
{
return [
"id" => $this->id,
"class" => $this->class,
"arguments" => serialize(Y::unserialize($this->arguments)),
"output" => $this->output === null ? serialize(null) : serialize(Y::unserialize($this->output)),
"status" => $this->status,
"created_at" => $this->created_at,
"updated_at" => $this->updated_at,
"logs" => StoredWorkflowLogResource::collection($this->logs),
"exceptions" => StoredWorkflowExceptionResource::collection($this->exceptions),
"chartData" => app(WorkflowToChartDataTransformer::class)->transform($this->resource),
];
}
}
70 changes: 70 additions & 0 deletions app/Transformer/WorkflowToChartDataTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);

namespace Waterline\Transformer;

use Carbon\CarbonInterface;
use DateTimeInterface;
use Illuminate\Support\Arr;
use Waterline\Dto\ChartDataPoint;
use Workflow\Models\StoredWorkflow;
use Workflow\Models\StoredWorkflowLog;
use Workflow\Workflow;

class WorkflowToChartDataTransformer
{
/**
* @return ChartDataPoint[]
*/
public function transform(StoredWorkflow $storedWorkflow) : array {
$data = $this->transformWorkflow($storedWorkflow);

foreach ($storedWorkflow->children as $childWorkflow) {
$data = array_merge(
$data,
$this->transform($childWorkflow),
);
}

return $data;
}

/**
* @return ChartDataPoint[]
*/
private function transformWorkflow(StoredWorkflow $storedWorkflow) : array {
$data = [
app(ChartDataPoint::class, [
'x' => $storedWorkflow->class,
'yMin' => (float) $storedWorkflow->created_at->isoFormat('XSSS'),
'yMax' => (float) $storedWorkflow->updated_at->isoFormat('XSSS'),
'type' => 'Workflow'
])
];

$prevLogCreated = $storedWorkflow->created_at;
foreach ($storedWorkflow->logs as $log) {
if (is_subclass_of($log->class, Workflow::class)) {
continue;
}

$data[] = $this->transformLog($log, $prevLogCreated);
$prevLogCreated = $log->created_at;
}

return $data;
}

/**
* @return ChartDataPoint
*/
private function transformLog(StoredWorkflowLog $storedWorkflowLog, CarbonInterface $prevLogCreated) : ChartDataPoint {

return app(ChartDataPoint::class, [
'x' => $storedWorkflowLog->class,
'yMin' => (float) $prevLogCreated->isoFormat('XSSS'),
'yMax' => (float) $storedWorkflowLog->created_at->isoFormat('XSSS'),
'type' => 'Activity',
]);
}
}
9 changes: 2 additions & 7 deletions public/app.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"/app.js": "/app.js?id=ad4fe9437176e22cd21076e124a481f3",
"/app.js": "/app.js?id=d8462d5df178a947e8a71869b5ea1018",
"/app-dark.css": "/app-dark.css?id=3e8dddb1d146175eb19d916f9cd87bfa",
"/app.css": "/app.css?id=12fca36d651455c3d460d9c4abf772c5",
"/img/favicon.png": "/img/favicon.png?id=7c006241b093796d6abfa3049df93a59",
Expand Down
15 changes: 3 additions & 12 deletions resources/js/screens/flows/flow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export default {
let data = w.globals.initialSeries[seriesIndex].data[dataPointIndex]
return '<div style="padding: 1em">' +
'<b>Activity</b>: ' + data.x.split('_')[0] + '<br />' +
'<b>'+data.type+'</b>: ' + data.x.split('_')[0] + '<br />' +
'<b>Time</b>: ' + (data.y[1] - data.y[0]) + 'ms </div>'
}
if (seriesIndex === 1) {
Expand Down Expand Up @@ -298,16 +298,7 @@ export default {
this.$http.get(Waterline.basePath + '/api/flows/' + id)
.then(response => {
this.flow = response.data;
this.series[0].data = this.flow.logs.map((activity, index, activities) => {
return {
x: activity.class,
y: [
index === 0 ? moment(this.flow.created_at).valueOf() : moment(activities[index - 1].created_at).valueOf(),
moment(activity.created_at).valueOf(),
],
}
})
this.series[0].data = response.data.chartData;
this.series[1].data = this.flow.exceptions.map((exception) => {
this.$nextTick(() => {
this.$nextTick(() => {
Expand All @@ -331,7 +322,7 @@ export default {
],
fillColor: '#721c24',
}
})
});
this.ready = true;
});
Expand Down

0 comments on commit 3eb81db

Please sign in to comment.