Merge pull request 'Added request characteristics resource pages' (#248) from ranjith-dev into master
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Reviewed-on: #248
This commit was merged in pull request #248.
This commit is contained in:
573
app/Filament/Resources/RequestCharacteristicResource.php
Normal file
573
app/Filament/Resources/RequestCharacteristicResource.php
Normal file
@@ -0,0 +1,573 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\RequestCharacteristicResource\Pages;
|
||||
use App\Models\CharacteristicApproverMaster;
|
||||
use App\Models\Item;
|
||||
use App\Models\Machine;
|
||||
use App\Models\RequestCharacteristic;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class RequestCharacteristicResource extends Resource
|
||||
{
|
||||
protected static ?string $model = RequestCharacteristic::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
|
||||
protected static ?string $navigationGroup = 'Laser Marking';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
|
||||
// $disableField = function ($get) {
|
||||
// $currentUser = Filament::auth()->user();
|
||||
// $approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
// if (!$approverId) return true; // disable if no approver selected
|
||||
|
||||
// $approver = CharacteristicApproverMaster::find($approverId);
|
||||
// if (!$approver) return true;
|
||||
|
||||
// // Enable if Super Admin
|
||||
// if ($currentUser && $currentUser->hasRole('Super Admin')) {
|
||||
// return false; // not disabled
|
||||
// }
|
||||
|
||||
// // Enable only if current user is one of the approvers
|
||||
// $userName = $currentUser?->name;
|
||||
|
||||
// return !in_array($userName, [
|
||||
// $approver->name1,
|
||||
// $approver->name2,
|
||||
// $approver->name3,
|
||||
// ]);
|
||||
// };
|
||||
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Select::make('plant_id')
|
||||
->label('Plant')
|
||||
->relationship('plant', 'name')
|
||||
->required()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\Select::make('machine_id')
|
||||
->label('Work Center')
|
||||
// ->relationship('machine', 'name')
|
||||
->reactive()
|
||||
->searchable()
|
||||
->options(function (callable $get) {
|
||||
$plantId = $get('plant_id');
|
||||
if (empty($plantId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Machine::where('plant_id', $plantId)->pluck('work_center', 'id');
|
||||
})
|
||||
->required()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\TextInput::make('work_flow_id')
|
||||
->label('Work Flow ID')
|
||||
->readOnly()
|
||||
->reactive(),
|
||||
// ->rule(function (callable $get) {
|
||||
// return Rule::unique('request_characteristics', 'work_flow_id')
|
||||
// ->where('plant_id', $get('plant_id'))
|
||||
// ->ignore($get('id'));
|
||||
// }),
|
||||
Forms\Components\Select::make('item_id')
|
||||
->label('Item')
|
||||
// ->relationship('item', 'id')
|
||||
->reactive()
|
||||
->searchable()
|
||||
->options(function (callable $get) {
|
||||
$plantId = $get('plant_id');
|
||||
if (empty($plantId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Item::where('plant_id', $plantId)->pluck('code', 'id');
|
||||
})
|
||||
->required()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\Select::make('characteristic_approver_master_id')
|
||||
->label('Characteristic Approver')
|
||||
// ->relationship('characteristicApproverMaster', 'id')
|
||||
->reactive()
|
||||
->searchable()
|
||||
->options(function (callable $get) {
|
||||
$plantId = $get('plant_id');
|
||||
|
||||
$machineId = $get('machine_id');
|
||||
|
||||
if (! $plantId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$approvers = CharacteristicApproverMaster::where('plant_id', $plantId)
|
||||
->where('machine_id', $machineId)
|
||||
->get();
|
||||
|
||||
$options = [];
|
||||
|
||||
foreach ($approvers as $approver) {
|
||||
if ($approver->name1) {
|
||||
$options[$approver->id.'_name1'] = $approver->name1;
|
||||
}
|
||||
if ($approver->name2) {
|
||||
$options[$approver->id.'_name2'] = $approver->name2;
|
||||
}
|
||||
if ($approver->name3) {
|
||||
$options[$approver->id.'_name3'] = $approver->name3;
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
})
|
||||
->dehydrateStateUsing(function ($state, callable $set) {
|
||||
|
||||
if (empty($state) || ! str_contains($state, '_')) {
|
||||
return $state;
|
||||
}
|
||||
|
||||
$parts = explode('_', $state);
|
||||
|
||||
if (count($parts) != 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
[$id, $level] = $parts;
|
||||
|
||||
$set('approver_level', $level);
|
||||
|
||||
return (int) $id;
|
||||
})
|
||||
->required()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\TextInput::make('aufnr')
|
||||
->label('Aufnr')
|
||||
->reactive()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\TextInput::make('characteristic_name')
|
||||
->label('Characteristic Name')
|
||||
->reactive()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\TextInput::make('current_value')
|
||||
->label('Current Value')
|
||||
->reactive()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\TextInput::make('update_value')
|
||||
->label('Update Value')
|
||||
->reactive()
|
||||
->disabled(fn ($get) => self::isFieldDisabled($get)),
|
||||
Forms\Components\Select::make('approver_status1')
|
||||
->label('Approver Status 1')
|
||||
->reactive()
|
||||
->options([
|
||||
'Approved' => 'Approved',
|
||||
'Hold' => 'Hold',
|
||||
'Rejected' => 'Rejected',
|
||||
])
|
||||
->disabled(function ($get) {
|
||||
$currentUser = Filament::auth()->user();
|
||||
$approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
if (! $approverId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($approverId, '_')) {
|
||||
[$approverId, $level] = explode('_', $approverId);
|
||||
}
|
||||
|
||||
$approver = CharacteristicApproverMaster::find($approverId);
|
||||
if (! $approver) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Super Admin can edit any
|
||||
if ($currentUser && $currentUser->hasRole('Super Admin')) {
|
||||
return false; // field enabled
|
||||
}
|
||||
|
||||
// Otherwise, enable only if the user's name matches
|
||||
return $approver->name1 != $currentUser?->name;
|
||||
}),
|
||||
Forms\Components\TextInput::make('approver_remark1')
|
||||
->label('Approver Remark 1')
|
||||
->reactive(),
|
||||
Forms\Components\DateTimePicker::make('approved1_at')
|
||||
->label('Approved At 1')
|
||||
->reactive()
|
||||
->disabled(function ($get) {
|
||||
$currentUser = Filament::auth()->user(); // logged-in user
|
||||
$approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
if (! $approverId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($approverId, '_')) {
|
||||
[$approverId, $level] = explode('_', $approverId);
|
||||
}
|
||||
|
||||
$approver = CharacteristicApproverMaster::find($approverId);
|
||||
if (! $approver) {
|
||||
return true;
|
||||
}
|
||||
if ($currentUser && $currentUser->hasRole('Super Admin')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $approver->name1 != $currentUser?->name;
|
||||
}),
|
||||
Forms\Components\Select::make('approver_status2')
|
||||
->label('Approver Status 2')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state, callable $set, callable $get) {
|
||||
if ($state && empty($get('approved2_at'))) {
|
||||
$set('approved2_at', now());
|
||||
}
|
||||
})
|
||||
->options([
|
||||
'Approved' => 'Approved',
|
||||
'Hold' => 'Hold',
|
||||
'Rejected' => 'Rejected',
|
||||
])
|
||||
->disabled(function ($get) {
|
||||
$currentUser = Filament::auth()->user(); // get the User object
|
||||
$approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
if (! $approverId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($approverId, '_')) {
|
||||
[$approverId, $level] = explode('_', $approverId);
|
||||
}
|
||||
|
||||
$approver = CharacteristicApproverMaster::find($approverId);
|
||||
if (! $approver) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Super Admin can always edit
|
||||
if ($currentUser && $currentUser->hasRole('Super Admin')) {
|
||||
return false; // ENABLE field
|
||||
}
|
||||
|
||||
// Otherwise, enable only if the user's name matches
|
||||
return $approver->name2 != $currentUser?->name;
|
||||
}),
|
||||
Forms\Components\TextInput::make('approver_remark2')
|
||||
->label('Approver Remark 2')
|
||||
->reactive(),
|
||||
Forms\Components\DateTimePicker::make('approved2_at')
|
||||
->label('Approverd At 2')
|
||||
->reactive()
|
||||
->disabled(function ($get) {
|
||||
$currentUser = Filament::auth()->user(); // logged-in user
|
||||
$approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
if (! $approverId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($approverId, '_')) {
|
||||
[$approverId, $level] = explode('_', $approverId);
|
||||
}
|
||||
|
||||
$approver = CharacteristicApproverMaster::find($approverId);
|
||||
if (! $approver) {
|
||||
return true;
|
||||
}
|
||||
if ($currentUser && $currentUser->hasRole('Super Admin')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $approver->name2 != $currentUser?->name;
|
||||
})
|
||||
->dehydrated(true),
|
||||
Forms\Components\Select::make('approver_status3')
|
||||
->label('Approver Status 3')
|
||||
->reactive()
|
||||
->options([
|
||||
'Approved' => 'Approved',
|
||||
'Hold' => 'Hold',
|
||||
'Rejected' => 'Rejected',
|
||||
])
|
||||
->disabled(function ($get) {
|
||||
$currentUser = Filament::auth()->user();
|
||||
$approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
if (! $approverId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($approverId, '_')) {
|
||||
[$approverId, $level] = explode('_', $approverId);
|
||||
}
|
||||
|
||||
$approver = CharacteristicApproverMaster::find($approverId);
|
||||
if (! $approver) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($currentUser->hasRole('Super Admin')) {
|
||||
return false;
|
||||
} else {
|
||||
return $approver->name3 != $currentUser?->name;
|
||||
}
|
||||
|
||||
}),
|
||||
Forms\Components\TextInput::make('approver_remark3')
|
||||
->label('Approver Remark 3')
|
||||
->reactive(),
|
||||
Forms\Components\DateTimePicker::make('approved3_at')
|
||||
->label('Approverd At 3')
|
||||
->reactive()
|
||||
->disabled(function ($get) {
|
||||
$currentUser = Filament::auth()->user(); // logged-in user
|
||||
$approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
if (! $approverId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($approverId, '_')) {
|
||||
[$approverId, $level] = explode('_', $approverId);
|
||||
}
|
||||
|
||||
$approver = CharacteristicApproverMaster::find($approverId);
|
||||
if (! $approver) {
|
||||
return true;
|
||||
}
|
||||
if ($currentUser && $currentUser->hasRole('Super Admin')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $approver->name3 != $currentUser?->name;
|
||||
}),
|
||||
Forms\Components\Hidden::make('created_by')
|
||||
->label('Created By')
|
||||
->default(Filament::auth()->user()?->name),
|
||||
Forms\Components\Hidden::make('updated_by')
|
||||
->label('Updated By')
|
||||
->default(Filament::auth()->user()?->name),
|
||||
Forms\Components\TextInput::make('id')
|
||||
->hidden()
|
||||
->readOnly(),
|
||||
]);
|
||||
}
|
||||
|
||||
protected static function isFieldDisabled($get): bool
|
||||
{
|
||||
$currentUser = Filament::auth()->user();
|
||||
$approverId = $get('characteristic_approver_master_id');
|
||||
|
||||
if (! $approverId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (str_contains($approverId, '_')) {
|
||||
[$approverId, $level] = explode('_', $approverId);
|
||||
}
|
||||
|
||||
$approver = CharacteristicApproverMaster::find($approverId);
|
||||
if (! $approver) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($currentUser && $currentUser->hasRole('Super Admin')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$userName = $currentUser?->name;
|
||||
|
||||
return in_array($userName, [
|
||||
$approver->name1,
|
||||
$approver->name2,
|
||||
$approver->name3,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('No.')
|
||||
->label('No.')
|
||||
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
|
||||
$paginator = $livewire->getTableRecords();
|
||||
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
|
||||
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
|
||||
|
||||
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
|
||||
}),
|
||||
Tables\Columns\TextColumn::make('work_flow_id')
|
||||
->label('Work Flow ID')
|
||||
->alignCenter()
|
||||
->searchable(), // isIndividual: true
|
||||
Tables\Columns\TextColumn::make('plant.name')
|
||||
->label('Plant')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('machine.work_center')
|
||||
->label('Work Center')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('item.code')
|
||||
->label('Item Code')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('aufnr')
|
||||
->label('Aufnr')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('characteristic_name')
|
||||
->label('Characteristic Name')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('current_value')
|
||||
->label('Current Value')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('update_value')
|
||||
->label('Update Value')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('characteristicApproverMaster.name1')
|
||||
->label('Approver Name 1')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('approver_status1')
|
||||
->label('Approver Status 1')
|
||||
// ->color('success')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('approved1_at')
|
||||
->label('Approver At 1')
|
||||
->alignCenter()
|
||||
->dateTime()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('characteristicApproverMaster.name2')
|
||||
->label('Approver Name 2')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('approver_status2')
|
||||
->label('Approver Status 2')
|
||||
// ->color('danger')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('approved2_at')
|
||||
->label('Approver At 2')
|
||||
->alignCenter()
|
||||
->dateTime()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('characteristicApproverMaster.name3')
|
||||
->label('Approver Name 3')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('approver_status3')
|
||||
->label('Approver Status 3')
|
||||
// ->color('primary')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('approved3_at')
|
||||
->label('Approver At 3')
|
||||
->alignCenter()
|
||||
->dateTime()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_by')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_by')
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('deleted_at')
|
||||
->dateTime()
|
||||
->alignCenter()
|
||||
->searchable()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->searchPlaceholder('Search Work Flow ID')
|
||||
->filters([
|
||||
Tables\Filters\TrashedFilter::make(),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
Tables\Actions\ForceDeleteBulkAction::make(),
|
||||
Tables\Actions\RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListRequestCharacteristics::route('/'),
|
||||
'create' => Pages\CreateRequestCharacteristic::route('/create'),
|
||||
'view' => Pages\ViewRequestCharacteristic::route('/{record}'),
|
||||
'edit' => Pages\EditRequestCharacteristic::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\RequestCharacteristicResource\Pages;
|
||||
|
||||
use App\Filament\Resources\RequestCharacteristicResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateRequestCharacteristic extends CreateRecord
|
||||
{
|
||||
protected static string $resource = RequestCharacteristicResource::class;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\RequestCharacteristicResource\Pages;
|
||||
|
||||
use App\Filament\Resources\RequestCharacteristicResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditRequestCharacteristic extends EditRecord
|
||||
{
|
||||
protected static string $resource = RequestCharacteristicResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\ViewAction::make(),
|
||||
Actions\DeleteAction::make(),
|
||||
Actions\ForceDeleteAction::make(),
|
||||
Actions\RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\RequestCharacteristicResource\Pages;
|
||||
|
||||
use App\Filament\Resources\RequestCharacteristicResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListRequestCharacteristics extends ListRecords
|
||||
{
|
||||
protected static string $resource = RequestCharacteristicResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\RequestCharacteristicResource\Pages;
|
||||
|
||||
use App\Filament\Resources\RequestCharacteristicResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
|
||||
class ViewRequestCharacteristic extends ViewRecord
|
||||
{
|
||||
protected static string $resource = RequestCharacteristicResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\EditAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user