Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('pim_property_value', function (Blueprint $table) {
$table->boolean('is_group')->default(false)->after('image');

$table->foreignId('group_value_id')
->nullable()
->after('is_group')
->constrained('pim_property_value')
->nullOnDelete();
});
}

public function down(): void
{
Schema::table('pim_property_value', function (Blueprint $table) {
$table->dropConstrainedForeignId('group_value_id');
$table->dropColumn('is_group');
});
}
};
27 changes: 27 additions & 0 deletions resources/lang/en/property-value.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
'table' => [
'columns' => [
'value' => 'Value',
'group' => 'Group',
'aliases' => 'Aliases',
'image' => 'Image',
'info_url' => 'Info URL',
'sort' => 'Sort',
Expand All @@ -45,6 +47,8 @@
'edit' => 'Edit',
'delete' => 'Delete',
'merge' => 'Merge…',
'group_aliases' => 'Group (aliases)',
'remove_from_group' => 'Remove from group',
],
],

Expand Down Expand Up @@ -76,6 +80,21 @@
'merged_error_body' => 'We couldn’t merge these values. Please try again.',
],

'grouping' => [
'success_grouped_title' => 'Grouped',
'success_grouped_body' => ':count value(s) grouped under ":target".',
'success_ungrouped_title' => 'Updated',
'success_ungrouped_body' => ':count value(s) removed from group.',
'error_title' => 'Grouping failed',
'selected_values' => 'Selected values',
'helper_target' => 'Choose the target value into which the selected values will be grouped.',
'errors' => [
'target_in_sources' => 'The target cannot be one of the selected values.',
'target_is_member' => 'The selected target already belongs to another group.',
'different_property' => 'All selected values and the target must belong to the same property.',
],
],

'pages' => [
'title' => [
'with_property' => 'Values for: :property',
Expand All @@ -87,6 +106,14 @@
],
],

'ui' => [
'group_badge' => 'Group',
],

'modal_grouping' => [
'target_label' => 'Target value',
],

'notifications' => [
'import_queued' => [
'title' => 'Import Queued',
Expand Down
27 changes: 27 additions & 0 deletions resources/lang/sl/property-value.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
'table' => [
'columns' => [
'value' => 'Vrednost',
'group' => 'Skupina',
'aliases' => 'Aliasi',
'image' => 'Slika',
'info_url' => 'URL informacij',
'sort' => 'Vrstni red',
Expand All @@ -45,6 +47,8 @@
'edit' => 'Uredi',
'delete' => 'Izbriši',
'merge' => 'Združi…',
'group_aliases' => 'Združi (aliase)',
'remove_from_group' => 'Odstrani iz skupine',
],
],

Expand Down Expand Up @@ -76,6 +80,21 @@
'merged_error_body' => 'Vrednosti trenutno ni mogoče združiti. Poskusite znova.',
],

'grouping' => [
'success_grouped_title' => 'Združeno',
'success_grouped_body' => ':count vrednost(i) združene pod ":target".',
'success_ungrouped_title' => 'Posodobljeno',
'success_ungrouped_body' => ':count vrednost(i) odstranjene iz skupine.',
'error_title' => 'Združevanje ni uspelo',
'selected_values' => 'Izbrane vrednosti',
'helper_target' => 'Izberite ciljno vrednost, v katero bodo združene izbrane vrednosti.',
'errors' => [
'target_in_sources' => 'Cilj ne sme biti med izbranimi vrednostmi.',
'target_is_member' => 'Izbrani cilj že pripada drugi skupini.',
'different_property' => 'Vse izbrane vrednosti in cilj morajo pripadati isti lastnosti.',
],
],

'pages' => [
'title' => [
'with_property' => 'Vrednosti za: :property',
Expand All @@ -87,6 +106,14 @@
],
],

'ui' => [
'group_badge' => 'Skupina',
],

'modal_grouping' => [
'target_label' => 'Ciljna vrednost',
],

'notifications' => [
'import_queued' => [
'title' => 'Uvoz v čakalni vrsti',
Expand Down
24 changes: 24 additions & 0 deletions resources/views/filament/bulk/group-selected-preview.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@php($items = $getState() ?? [])

<div class="space-y-3 max-h-72 overflow-auto">
<div class="text-sm font-medium">
{{ __('eclipse-catalogue::property-value.grouping.selected_values') }}
</div>
<ul class="ms-1 space-y-2">
@foreach($items as $record)
<li>
<div class="flex flex-wrap items-center gap-2">
<span class="text-gray-400 select-none">-</span>
<span class="font-medium">{{ $record->value }}</span>
@if($record->is_group)
<x-filament::badge color="primary" class="!inline-flex !w-auto !px-2 !py-0.5">{{ __('eclipse-catalogue::property-value.ui.group_badge') }}</x-filament::badge>
@elseif($record->group)
<x-filament::badge color="warning" class="!inline-flex !w-auto !px-2 !py-0.5">{{ $record->group->value }}</x-filament::badge>
@endif
</div>
</li>
@endforeach
</ul>
</div>


18 changes: 18 additions & 0 deletions resources/views/filament/columns/group-and-aliases.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@php($rec = $getRecord())

<div class="flex flex-wrap items-center gap-1">
@if($rec->is_group)
<x-filament::badge color="primary">{{ __('eclipse-catalogue::property-value.ui.group_badge') }}</x-filament::badge>
@endif

@if($rec->group)
<x-filament::badge color="warning">{{ $rec->group->value }}</x-filament::badge>
@endif

@php($aliases = $rec->members()->count())
@if($rec->is_group)
<x-filament::badge color="gray">{{ $aliases }}</x-filament::badge>
@endif
</div>


107 changes: 106 additions & 1 deletion src/Filament/Resources/PropertyValueResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ public static function table(Table $table): Table
->searchable()
->sortable(),

Tables\Columns\ViewColumn::make('group_and_aliases')
->label(__('eclipse-catalogue::property-value.table.columns.group'))
->view('eclipse-catalogue::filament.columns.group-and-aliases')
->extraAttributes(['class' => 'space-x-1']),

Tables\Columns\TextColumn::make('color_swatch')
->label('Color')
->state(fn ($record) => $record->getColor())
Expand Down Expand Up @@ -233,6 +238,106 @@ public static function table(Table $table): Table
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\BulkAction::make('group_values')
->label(__('eclipse-catalogue::property-value.table.actions.group_aliases'))
->icon('heroicon-o-rectangle-group')
->form(function (\Filament\Tables\Actions\BulkAction $action) {
$firstRecord = $action->getRecords()->first();
$derivedPropertyId = $firstRecord?->property_id ?? (request()->has('property') ? (int) request('property') : null);

return [
\Filament\Forms\Components\View::make('eclipse-catalogue::filament.bulk.group-selected-preview')
->statePath('selected_records')
->dehydrated(false)
->afterStateHydrated(function ($component) use ($action) {
$component->state($action->getRecords());
})
->columnSpanFull(),

\Filament\Forms\Components\Hidden::make('property_id')
->default($derivedPropertyId),

\Filament\Forms\Components\Select::make('target_id')
->label(__('eclipse-catalogue::property-value.modal_grouping.target_label'))
->helperText(__('eclipse-catalogue::property-value.grouping.helper_target'))
->required()
->options(function (\Filament\Forms\Get $get) {
$query = PropertyValue::query();
$propertyId = $get('property_id');
if ($propertyId) {
$query->sameProperty((int) $propertyId);
}

return $query->orderBy('value')->pluck('value', 'id');
})
->searchable(),
];
})
->action(function (\Illuminate\Support\Collection $records, array $data) {
try {
if ($records->isEmpty()) {
return;
}

$target = PropertyValue::findOrFail((int) $data['target_id']);

$sourceIds = $records->pluck('id');
if ($sourceIds->contains($target->id)) {
Notification::make()->title(__('eclipse-catalogue::property-value.grouping.error_title'))->body(__('eclipse-catalogue::property-value.grouping.errors.target_in_sources'))->danger()->send();

return;
}

if ($target->group_value_id !== null) {
Notification::make()->title(__('eclipse-catalogue::property-value.grouping.error_title'))->body(__('eclipse-catalogue::property-value.grouping.errors.target_is_member'))->danger()->send();

return;
}

$updated = 0;
foreach ($records as $record) {
/** @var PropertyValue $source */
$source = $record instanceof PropertyValue ? $record : PropertyValue::findOrFail($record);
if ($source->property_id !== $target->property_id) {
Notification::make()->title(__('eclipse-catalogue::property-value.grouping.error_title'))->body(__('eclipse-catalogue::property-value.grouping.errors.different_property'))->danger()->send();

return;
}
$source->groupInto($target->id);
$updated++;
}

Notification::make()->title(__('eclipse-catalogue::property-value.grouping.success_grouped_title'))
->body(__('eclipse-catalogue::property-value.grouping.success_grouped_body', ['count' => $updated, 'target' => $target->value]))
->success()->send();
} catch (\Throwable $e) {
\Log::error('Bulk group failed', ['exception' => $e]);
Notification::make()->title(__('eclipse-catalogue::property-value.grouping.error_title'))->body(__('eclipse-catalogue::property-value.messages.merged_error_body'))->danger()->send();
}
})
->deselectRecordsAfterCompletion(),

Tables\Actions\BulkAction::make('ungroup_values')
->label(__('eclipse-catalogue::property-value.table.actions.remove_from_group'))
->icon('heroicon-o-squares-2x2')
->action(function (\Illuminate\Support\Collection $records) {
try {
$updated = 0;
foreach ($records as $record) {
/** @var PropertyValue $model */
$model = $record instanceof PropertyValue ? $record : PropertyValue::findOrFail($record);
$model->removeFromGroup();
$updated++;
}
Notification::make()->title(__('eclipse-catalogue::property-value.grouping.success_ungrouped_title'))
->body(__('eclipse-catalogue::property-value.grouping.success_ungrouped_body', ['count' => $updated]))
->success()->send();
} catch (\Throwable $e) {
\Log::error('Bulk ungroup failed', ['exception' => $e]);
Notification::make()->title(__('eclipse-catalogue::property-value.grouping.error_title'))->body(__('eclipse-catalogue::property-value.messages.merged_error_body'))->danger()->send();
}
})
->deselectRecordsAfterCompletion(),
Tables\Actions\DeleteBulkAction::make(),
]),
]);
Expand Down Expand Up @@ -344,6 +449,6 @@ public static function getEloquentQuery(): Builder
$query->where('property_id', request('property'));
}

return $query;
return $query->with(['group', 'members'])->groupedOrder();
}
}
Loading