Files
landing-api/app/Filament/Resources/Projects/Pages/CreateProject.php
Josep Piguillem b32d6bf001
Some checks failed
Tests / test (push) Has been cancelled
Tests / test-postgres (push) Has been cancelled
Tests / mcp (push) Has been cancelled
Tests / lint (push) Has been cancelled
Open a TaskStream board from the panel's project form
A "TaskStream" section on the create form (toggle and optional key,
suggested from the slug) opens the board before saving, as the person
signed in, with the Pireon token of their session. A refusal shows on the
key field and a TaskStream outage as a notification; either way nothing is
saved. The created notification carries the link, and the edit page has
an "Open in TaskStream" button.

Documented in the user manual (and its PDF) and the README.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:01:55 +02:00

83 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Resources\Projects\Pages;
use App\Actions\Projects\OpenInTaskStream;
use App\Filament\Resources\Projects\ProjectResource;
use App\Models\Project;
use App\Services\Pireon\TokenStore;
use App\Services\TaskStream\TaskStreamClient;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;
use Filament\Support\Exceptions\Halt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class CreateProject extends CreateRecord
{
protected static string $resource = ProjectResource::class;
/**
* With the TaskStream toggle on, the board is opened before the project
* is saved, as the person signed in (their Pireon token from the session).
*/
protected function handleRecordCreation(array $data): Model
{
$taskstream = (bool) Arr::pull($data, 'taskstream', false);
$key = Arr::pull($data, 'taskstream_key');
$project = new Project($data);
if ($taskstream) {
$this->openInTaskStream($project, filled($key) ? $key : null);
}
$project->save();
return $project;
}
protected function openInTaskStream(Project $project, ?string $key): void
{
try {
app(OpenInTaskStream::class)->handle($project, Auth::user(), app(TokenStore::class)->accessToken(), $key);
} catch (ValidationException $e) {
// The action names the API's fields; here they live under `data`.
throw ValidationException::withMessages(
collect($e->errors())->mapWithKeys(fn (array $messages, string $field) => ["data.{$field}" => $messages])->all(),
);
} catch (HttpException $e) {
Notification::make()->danger()->title($e->getMessage())->send();
throw (new Halt)->rollBackDatabaseTransaction();
}
}
protected function getCreatedNotification(): ?Notification
{
$notification = parent::getCreatedNotification();
$key = $this->getRecord()->taskstream_key;
if ($notification === null || $key === null) {
return $notification;
}
$url = app(TaskStreamClient::class)->projectUrl($key);
return $notification
->body(__('panel.projects.taskstream.created', ['url' => $url]))
->actions([
Action::make('taskstream')
->label(__('panel.projects.taskstream.open'))
->url($url, shouldOpenInNewTab: true),
])
->persistent();
}
}