Gryfon
Gryfon
FFilament
Created by Gryfon on 11/2/2024 in #❓┊help
Using Sushi with Filament Table and refresh the data
Just a little up 🙈
8 replies
FFilament
Created by Gryfon on 11/2/2024 in #❓┊help
Using Sushi with Filament Table and refresh the data
public function table(Table $table): Table
{
return $table
->query( Log::query() )
->poll('10')
->columns([
//
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
public function table(Table $table): Table
{
return $table
->query( Log::query() )
->poll('10')
->columns([
//
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
Unfortunately, it doesn't change anything 😢 I've also added log loading by default in my Model because otherwise the $this->logFilePath was empty... In my Model class :
public function getRows(): array {
$rows = [];
// I added this :
if(!$this->logFilePath) {
$this->logFilePath = storage_path('logs/laravel.log');
}

if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);

$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}

if ($currentEntry) {
$rows[] = $currentEntry;
}
}
return $rows;
}
public function getRows(): array {
$rows = [];
// I added this :
if(!$this->logFilePath) {
$this->logFilePath = storage_path('logs/laravel.log');
}

if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);

$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}

if ($currentEntry) {
$rows[] = $currentEntry;
}
}
return $rows;
}
I don't know what to do 😦
8 replies
FFilament
Created by Gryfon on 11/2/2024 in #❓┊help
Using Sushi with Filament Table and refresh the data
Ok with somes test, I have new... Here, everything work well :
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->selectedLogfile = $this->logsFiles[$state];
$this->log->setLogFile('/logs/' . $this->selectedLogfile);
dd($this->log->getRows()); //Here, all good ! :)
$this->dispatch('refresh');
}),
]);
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->selectedLogfile = $this->logsFiles[$state];
$this->log->setLogFile('/logs/' . $this->selectedLogfile);
dd($this->log->getRows()); //Here, all good ! :)
$this->dispatch('refresh');
}),
]);
The dd() shows me the contents of the log file I've selected. I guess the problem is here:
public function table(Table $table): Table
{
return $table
->query(Log::query()) //Here :(
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
public function table(Table $table): Table
{
return $table
->query(Log::query()) //Here :(
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
How can I refresh the data in my table according to the getRows() updated in my Model?
8 replies
FFilament
Created by Gryfon on 11/2/2024 in #❓┊help
Using Sushi with Filament Table and refresh the data
And my Component :
class LogViewer extends Component implements HasTable, HasForms
{
use InteractsWithTable;
use InteractsWithForms;

public ?array $logsFiles = [];
public string $selectedLogfile = '';
public Model $log;

public function mount(): void
{
$this->logsFiles = $this->getLogFiles();
$this->selectedLogfile = $this->logsFiles[0];
$this->log = new Log();
}

public function form(Form $form): Form {
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->log->getRows('/logs/'.$this->logsFiles[$state]);
}),
]);
}

public function table(Table $table): Table
{
return $table
->query(Log::query())
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}

public function render()
{
return view('livewire.admin.log-viewer');
}

public function getLogFiles(): array
{
$logPath = storage_path('logs');
$logFiles = File::files($logPath);

return array_map(fn ($file) => $file->getFilename(),
array_filter($logFiles, fn ($file) => $file->isFile() && str_ends_with($file->getFilename(), '.log')));
}
}
class LogViewer extends Component implements HasTable, HasForms
{
use InteractsWithTable;
use InteractsWithForms;

public ?array $logsFiles = [];
public string $selectedLogfile = '';
public Model $log;

public function mount(): void
{
$this->logsFiles = $this->getLogFiles();
$this->selectedLogfile = $this->logsFiles[0];
$this->log = new Log();
}

public function form(Form $form): Form {
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->log->getRows('/logs/'.$this->logsFiles[$state]);
}),
]);
}

public function table(Table $table): Table
{
return $table
->query(Log::query())
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}

public function render()
{
return view('livewire.admin.log-viewer');
}

public function getLogFiles(): array
{
$logPath = storage_path('logs');
$logFiles = File::files($logPath);

return array_map(fn ($file) => $file->getFilename(),
array_filter($logFiles, fn ($file) => $file->isFile() && str_ends_with($file->getFilename(), '.log')));
}
}
Thanks for your help 😅
8 replies
FFilament
Created by Gryfon on 11/2/2024 in #❓┊help
Using Sushi with Filament Table and refresh the data
Here, the Model :
<?php

namespace App\Models;

use App\Enums\LogLevel;
use Illuminate\Database\Eloquent\Model;
use Sushi\Sushi;
use Illuminate\Support\Facades\File;

class Log extends Model
{
use Sushi;

protected $schema = [
'timestamp' => 'string',
'level' => 'string',
'environment' => 'string',
'message' => 'text',
];

protected $casts = [
'level' => LogLevel::class,
];

protected ?string $logFilePath = null;


public function getRows($logFile = '/logs/laravel.log'): array

{
$rows = [];
if($logFile === null) {
$this->logFilePath = storage_path() . '/logs/laravel.log';
} else {
$this->logFilePath = storage_path() . $logFile;
}

if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);

$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}

if ($currentEntry) {
$rows[] = $currentEntry;
}
}

return $rows;
}

protected function sushiShouldCache(): bool
{
return false;
}
}
<?php

namespace App\Models;

use App\Enums\LogLevel;
use Illuminate\Database\Eloquent\Model;
use Sushi\Sushi;
use Illuminate\Support\Facades\File;

class Log extends Model
{
use Sushi;

protected $schema = [
'timestamp' => 'string',
'level' => 'string',
'environment' => 'string',
'message' => 'text',
];

protected $casts = [
'level' => LogLevel::class,
];

protected ?string $logFilePath = null;


public function getRows($logFile = '/logs/laravel.log'): array

{
$rows = [];
if($logFile === null) {
$this->logFilePath = storage_path() . '/logs/laravel.log';
} else {
$this->logFilePath = storage_path() . $logFile;
}

if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);

$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}

if ($currentEntry) {
$rows[] = $currentEntry;
}
}

return $rows;
}

protected function sushiShouldCache(): bool
{
return false;
}
}
8 replies
FFilament
Created by Pritbor on 8/8/2024 in #❓┊help
How to get real-time validation error before clicking create/save button
4 replies