Skip to content

Instantly share code, notes, and snippets.

@mrleblanc101
Created August 16, 2024 16:09
Show Gist options
  • Save mrleblanc101/714180585a24a82383f8fbd5b0e5dccd to your computer and use it in GitHub Desktop.
Save mrleblanc101/714180585a24a82383f8fbd5b0e5dccd to your computer and use it in GitHub Desktop.
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
@php
$id = $getId();
$statePath = $getStatePath();
$practicesData = $getPracticeData($getRecord()->id);
$stateValues = $getStateValues();
$rowKey = 1;
$groupedPractice = collect($practicesData)->sortBy(['category_practice_name', 'name'])->groupBy('category_practice_name');
@endphp
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
<x-filament-tables::container>
<x-filament-tables::table>
@foreach($groupedPractice as $groupLabel => $practices)
@foreach($practices as $i => $practice)
<x-filament-tables::row wire:key="{{ $id }}.{{ $rowKey }}" id="{{ $id }}.{{ $rowKey }}">
@if($i === 0)
<x-filament-tables::cell class="py-4 px-3" rowspan="{{ count($practices) }}">{{ $groupLabel }}</x-filament-tables::cell>
@endif
@php
$supStatPath = $statePath . '.' . $practice['id'];
@endphp
<x-filament-tables::cell class="py-4 px-3">{{ $practice['name'] }}</x-filament-tables::cell>
<x-filament-tables::cell class="py-4 px-3">
<x-filament::input.wrapper>
<x-filament::input.select
id="{{ $id }}.{{ $rowKey }}.state"
wire:key="{{ $id }}.{{ $rowKey }}.state"
wire:model="{{ $supStatPath . '.state' }}"
wire:loading.attr="disabled"
>
@foreach ($stateValues as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</x-filament::input.select>
</x-filament::input.wrapper>
</x-filament-tables::cell>
<x-filament-tables::cell class="py-4 px-3">
<x-filament::input.wrapper>
<x-filament::input
type="text"
id="{{ $id }}.{{ $rowKey }}.notes"
wire:key="{{ $id }}.{{ $rowKey }}.notes"
wire:model="{{ $supStatPath . '.notes' }}"
wire:loading.attr="disabled"
/>
</x-filament::input.wrapper>
</x-filament-tables::cell>
</x-filament-tables::row>
@php
$rowKey++
@endphp
@endforeach
@endforeach
</x-filament-tables::table>
</x-filament-tables::container>
</div>
</x-dynamic-component>
<?php
namespace App\Forms\Components;
use App\Models\DigitalProduct\Practice;
use App\Models\DigitalProduct\Product;
use Filament\Forms\Components\CheckboxList;
class PracticeMatrix extends CheckboxList
{
protected string $view = 'forms.components.practice-matrix';
protected array $practicesData = [];
public function practicesData(array $data): static
{
$this->practicesData = $data;
return $this;
}
public function getPracticesData(): array
{
return $this->evaluate($this->practicesData);
}
public function getStateValues(): array
{
return ['no' => 'Non', 'yes' => 'Oui', 'n/a' => 'N/A'];
}
protected function setUp(): void
{
parent::setUp();
$this->afterStateHydrated(static function ($record, PracticeMatrix $component, $state) {
if ($record) {
$practiceData = self::getPracticeData($record->id);
$component->practicesData($practiceData);
$component->state($practiceData);
}
});
$this->beforeStateDehydrated(static function ($record, PracticeMatrix $component, $state) {
if ($record) {
$practiceData = self::getPracticeData($record->id);
$component->practicesData($practiceData);
$component->state($practiceData);
}
});
}
public static function getPracticeData($id)
{
$allPractices = Practice::all();
$practicesData = [];
if ($id) {
$product = Product::find($id);
$productPractices = $product->practices()->get()->keyBy('id')->toArray();
foreach ($allPractices as $practice) {
$practiceId = $practice->id;
$practicesData[$practiceId] = ['id' => $practiceId, 'name' => $practice->name, 'category_practice_name' => $practice->category_practice ? $practice->category_practice->name : ''];
if (isset($productPractices[$practiceId])) {
foreach ($productPractices[$practiceId]['pivot'] as $fieldname => $value) {
$practicesData[$practiceId][$fieldname] = $value;
}
} else {
foreach ($product->practices()->getPivotColumns() as $fieldname) {
$practicesData[$practiceId][$fieldname] = '';
}
}
}
}
return $practicesData;
}
}
<?php
namespace App\Filament\Resources;
use Filament\Forms;
use Filament\Tables;
use Filament\Forms\Set;
use Filament\Forms\Form;
use Filament\Tables\Table;
use Illuminate\Support\Str;
use Filament\Resources\Resource;
use App\Models\DigitalProduct\Product;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Validation\Rules\Unique;
use App\Forms\Components\PracticeMatrix;
use App\Filament\Resources\ProductResource\Pages;
use App\Filament\Resources\ProductResource\RelationManagers\LinksRelationManager;
use App\Filament\Resources\ProductResource\RelationManagers\ServersRelationManager;
use App\Filament\Resources\ProductResource\RelationManagers\CodeRepositoriesRelationManager;
class ProductResource extends Resource
{
protected static ?string $model = Product::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static bool $shouldRegisterNavigation = true;
protected static ?string $modelLabel = 'Produits numérique';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('client_id')
->relationship('client', 'name')
->required()
->columnSpan('full')
->default(request()->query('ownerRecord')),
Forms\Components\TextInput::make('name')
->label('Nom')
->required()
->default('Site Web')
->maxLength(255)
->live(onBlur: true)
->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))),
Forms\Components\TextInput::make('slug')
->unique(
ignoreRecord: true,
modifyRuleUsing: function (Unique $rule, $get) {
return $rule->where('client_id', $get('client_id'));
})
->default('site-web'),
Forms\Components\Select::make('team_id')
->label('Équipe')
->required()
->relationship('team', 'name')
->columnSpan('full'),
Forms\Components\Select::make('leads')
->label('Personne-ressource')
->multiple()
->columnSpan('full')
->options(
function () {
$selectUsers = [];
$users = \LdapRecord\Models\ActiveDirectory\User::query()
->whereEnabled()
->whereMemberOf('CN=libeo-dev,OU=Roles,OU=Libeo,DC=libeo,DC=com', true)
->get();
foreach ($users as $user) {
$selectUsers[$user->samaccountname[0]] = $user->displayname[0];
}
return $selectUsers;
}
),
Forms\Components\Select::make('state')
->label('État')
->options([
'active' => 'Actif',
'inactive' => 'Inactif'
])
->default(Product::STATE_ACTIVE)
->required()
->columnSpan('full'),
Forms\Components\Select::make('technos')
->label('Technologies')
->multiple()
->relationship('technos', 'name')
->createOptionForm([
Forms\Components\TextInput::make('name')->label('Nom')
->required(),
Forms\Components\Checkbox::make('main')->label('Technologie principal')
->helperText('Cocher s\'il s\'agit d\'un framework, CMS ou librairie principale. Utilisé pour l\'affichage dans les listes du système.'),
])
->preload()
->columnSpan('full'),
Forms\Components\Select::make('specifications')
->label('Spécifications')
->multiple()
->relationship('specifications', 'name')
->createOptionForm([
Forms\Components\TextInput::make('name')
->required()
])
->preload()
->columnSpan('full'),
Forms\Components\RichEditor::make('notes')
->columnSpan('full'),
PracticeMatrix::make('practice_matrix')
->columnSpan('full')
->label('Pratiques appliquées dans le produit')
->hiddenOn(Pages\CreateProduct::class)
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('client.name')
->label('Client')
->searchable()
->sortable(),
TextColumn::make('name')
->label('Nom')
->searchable()
->sortable(),
])
->defaultPaginationPageOption(50)
->filters([
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
]);
}
public static function getRelations(): array
{
return [
LinksRelationManager::class,
ServersRelationManager::class,
CodeRepositoriesRelationManager::class,
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListProducts::route('/'),
'create' => Pages\CreateProduct::route('/create'),
'edit' => Pages\EditProduct::route('/{record}/edit'),
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment