Compare commits
13 Commits
c0bfe974ad
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5bc322170 | ||
|
|
749208ac97 | ||
|
|
1870583441 | ||
|
|
76c05ebe7c | ||
|
|
515731003c | ||
|
|
a9c7ec6b80 | ||
|
|
4038d47582 | ||
|
|
326987d6de | ||
|
|
f433fc3e41 | ||
|
|
5361c00e7b | ||
|
|
5e37bd1a76 | ||
|
|
5a53b90272 | ||
|
|
59548a486f |
@@ -26,6 +26,7 @@ class CardOrdersTable
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('unique_id')
|
||||
->label(__('ID'))
|
||||
|
||||
@@ -11,7 +11,7 @@ class ManageCards extends ManageRecords
|
||||
{
|
||||
protected static string $resource = CardResource::class;
|
||||
|
||||
public function getTitle(): string | Htmlable
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return __('My cards');
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Cards\Resources\CardPinOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\Cards\Resources\CardPinOrders\CardPinOrderResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListCardPinOrders extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListCardPinOrders extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class CardPinOrdersTable
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID'),
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Loans\LoanOrders\Pages;
|
||||
|
||||
use App\Filament\Clusters\Loans\LoanOrders\LoanOrderResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListLoanOrders extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListLoanOrders extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class LoanOrdersTable
|
||||
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID')
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Loans\Resources\LoanOrderMobiles\Pages;
|
||||
|
||||
use App\Filament\Clusters\Loans\Resources\LoanOrderMobiles\LoanOrderMobileResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListLoanOrderMobiles extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListLoanOrderMobiles extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class LoanOrderMobilesTable
|
||||
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID')
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace App\Filament\Clusters\Loans\Resources\LoanPaidOffLetters\Pages;
|
||||
|
||||
use App\Filament\Clusters\Loans\Resources\LoanPaidOffLetters\LoanPaidOffLetterResource;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
|
||||
class ListLoanPaidOffLetters extends ListRecords
|
||||
{
|
||||
@@ -16,4 +18,23 @@ class ListLoanPaidOffLetters extends ListRecords
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
if (! user()->isSystemUser()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach (array_keys(OrderStatusRepository::statusClasses()) as $status) {
|
||||
if ($status === '') {
|
||||
$data[null] = Tab::make(__('All'));
|
||||
} else {
|
||||
$data[$status] = Tab::make(OrderStatusRepository::statusFormatted($status))->query(fn ($query) => $query->where('status', $status));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class LoanPaidOffLettersTable
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
->label('ID')
|
||||
|
||||
@@ -150,7 +150,7 @@ class VisaMasterPaymentOrderForm
|
||||
AdvancedFileUpload::make('sender_passport_local')
|
||||
->spatieMediaLibrary(collection: 'sender_passport_local')
|
||||
->multiple(),
|
||||
|
||||
|
||||
SpatieMediaLibraryFileUpload::make('sender_passport_international')
|
||||
->collection('sender_passport_international')
|
||||
->label(__('Ugradyja degişli Türkmenistandan çykmak we Türkmenistana girmek üçin pasportynyň asyl görnüşi we göçürmesi')),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Clusters\VisaMasterPayments\Resources\VisaMasterPaymentOrders\Tables;
|
||||
|
||||
use App\Modules\DefaultQueryForResourceIndex\Repositories\DefaultQueryForResourceIndexRepository;
|
||||
use App\Modules\OrderStatus\Repositories\OrderStatusRepository;
|
||||
use App\Modules\Region\Repositories\RegionRepository;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
@@ -14,6 +15,7 @@ use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class VisaMasterPaymentOrdersTable
|
||||
@@ -21,6 +23,9 @@ class VisaMasterPaymentOrdersTable
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->modifyQueryUsing(function (Builder $query) {
|
||||
DefaultQueryForResourceIndexRepository::make($query);
|
||||
})
|
||||
->defaultSort('created_at', direction: 'desc')
|
||||
->columns([
|
||||
TextColumn::make('id')
|
||||
|
||||
@@ -32,7 +32,7 @@ class UserForm
|
||||
->unique(ignoreRecord: true)
|
||||
->mask('99 99 99 99')
|
||||
->prefix('+993')
|
||||
->dehydrateStateUsing(fn($state) => unMaskTurkmenNumber($state))
|
||||
->dehydrateStateUsing(fn ($state) => unMaskTurkmenNumber($state))
|
||||
->rules([
|
||||
new PhoneNumberVerificationRule,
|
||||
])
|
||||
|
||||
69
app/Http/Controllers/MigrationController.php
Normal file
69
app/Http/Controllers/MigrationController.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Database\Seeders\Migrators\ActionEventsMigrator;
|
||||
use Database\Seeders\Migrators\BranchUserMigrator;
|
||||
use Database\Seeders\Migrators\CurrencyRatesMigrator;
|
||||
use Database\Seeders\Migrators\LoanOrderRequiredDocsMigrator;
|
||||
use Database\Seeders\Migrators\LoanOrdersMigrator;
|
||||
use Database\Seeders\Migrators\LoanTypesMigrator;
|
||||
use Database\Seeders\Migrators\MediaMigrator;
|
||||
use Database\Seeders\Migrators\ProvincesMigrator;
|
||||
use Database\Seeders\Migrators\BranchesMigrator;
|
||||
use Database\Seeders\Migrators\UsersMigrator;
|
||||
use Database\Seeders\Migrators\CardStatesMigrator;
|
||||
use Database\Seeders\Migrators\CardTypesMigrator;
|
||||
use Database\Seeders\Migrators\VisaMasterPaymentOrdersMigrator;
|
||||
use Database\Seeders\Migrators\VerificationsMigrator;
|
||||
use Database\Seeders\Migrators\PersonalAccessTokensMigrator;
|
||||
use Database\Seeders\Migrators\CardOrdersMigrator;
|
||||
use Database\Seeders\Migrators\VisaMasterSettingsMigrator;
|
||||
use Database\Seeders\Migrators\CardPinOrdersMigrator;
|
||||
use Database\Seeders\Migrators\ModelHasRolesMigrator;
|
||||
use Database\Seeders\Migrators\OnlinePaymentsMigrator;
|
||||
|
||||
class MigrationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return $this->test();
|
||||
|
||||
$migrators = [
|
||||
new ActionEventsMigrator(),
|
||||
new UsersMigrator(),
|
||||
new ProvincesMigrator(),
|
||||
new BranchesMigrator(),
|
||||
new BranchUserMigrator(),
|
||||
new CardStatesMigrator(),
|
||||
new CardTypesMigrator(),
|
||||
new VerificationsMigrator(),
|
||||
new CurrencyRatesMigrator(),
|
||||
new LoanOrderRequiredDocsMigrator(),
|
||||
new PersonalAccessTokensMigrator(),
|
||||
new LoanTypesMigrator(),
|
||||
new CardOrdersMigrator(),
|
||||
new CardPinOrdersMigrator(),
|
||||
new LoanOrdersMigrator(),
|
||||
new ModelHasRolesMigrator(),
|
||||
new VisaMasterPaymentOrdersMigrator(),
|
||||
new OnlinePaymentsMigrator(),
|
||||
|
||||
new MediaMigrator(),
|
||||
];
|
||||
|
||||
foreach ($migrators as $migrator) {
|
||||
$migrator->migrate();
|
||||
}
|
||||
|
||||
return 'done';
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
(new OnlinePaymentsMigrator())->migrate();
|
||||
|
||||
return 'done';
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@ namespace App\Models;
|
||||
|
||||
use App\Modules\UserAdjustments\Traits\UserAdjustments;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Models\Contracts\HasAvatar;
|
||||
use Filament\Panel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Filament\Models\Contracts\HasAvatar;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -28,6 +29,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar
|
||||
|
||||
use Notifiable;
|
||||
use UserAdjustments;
|
||||
use HasApiTokens;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
||||
64
app/Modules/ActivityLog/ActivityLogModule.php
Normal file
64
app/Modules/ActivityLog/ActivityLogModule.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\ActivityLog;
|
||||
|
||||
use App\Modules\Makeable;
|
||||
use App\Modules\ModuleContract;
|
||||
|
||||
class ActivityLogModule implements ModuleContract
|
||||
{
|
||||
use Makeable;
|
||||
|
||||
/**
|
||||
* Module is enabled
|
||||
*/
|
||||
protected bool $enabled = true;
|
||||
|
||||
/**
|
||||
* Check if is module enabled
|
||||
*/
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable module
|
||||
*/
|
||||
public function disable(): void
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable module
|
||||
*/
|
||||
public function enable(): void
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if module has a filament resource
|
||||
*/
|
||||
public function hasFilamentResource(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer requirements
|
||||
*/
|
||||
public function getComposerRequirements(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module composer suggestions
|
||||
*/
|
||||
public function getComposerSuggestions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\ActivityLog\Repositories;
|
||||
|
||||
class ActivityLogRepository {}
|
||||
@@ -14,6 +14,7 @@ use Illuminate\Http\Response;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@@ -113,7 +114,7 @@ class LoginController extends Controller
|
||||
protected function validateLogin(Request $request): void
|
||||
{
|
||||
$request->validate([
|
||||
$this->username() => ['required', 'string', 'max:250'],
|
||||
$this->username() => ['required', 'string', 'max:250', Rule::notIn('65999990', 'ulanyjy_ady')],
|
||||
'password' => ['required', 'string', 'max:250'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -30,4 +30,5 @@ return [
|
||||
'go_back' => 'Yza',
|
||||
'successfully_changed_phone' => 'Telefon belgiňiz üýtgedildi',
|
||||
'resend' => 'Täze tassyklaýyş belgi ugratmak',
|
||||
'phone_or_username_placeholder' => 'meselem: 65999990 yada ulanyjy_ady',
|
||||
];
|
||||
|
||||
@@ -49,11 +49,12 @@ async function login(event) {
|
||||
id="username"
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="+99365999990 {{ __('or') }} {{ __('module.base-auth::base.username') }}"
|
||||
placeholder="65999990 {{ __('or') }} {{ __('module.base-auth::base.username') }}"
|
||||
autofocus=""
|
||||
value="{{ old('username') }}"
|
||||
>
|
||||
|
||||
<span class="text-gray-500 text-xs">{{ __('module.base-auth::base.phone_or_username_placeholder') }}</span>
|
||||
<span id="username-error-box" class="text-red-500 text-italic error-box"></span>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -109,7 +109,16 @@ class CardOrder extends Model implements BelongsToBranch, HasStatus
|
||||
parent::boot();
|
||||
|
||||
static::creating(LoanOrderRepository::creating());
|
||||
static::created(LoanOrderRepository::created());
|
||||
|
||||
static::created(function ($model) {
|
||||
$uniqueId = LoanOrderRepository::generateUniqueId($model);
|
||||
$model->update(['unique_id' => $uniqueId]);
|
||||
|
||||
sendSMS(
|
||||
$model->phone,
|
||||
__('module.card-order::base.card_order_created', ['order_id' => $uniqueId])
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
5
app/Modules/CardOrder/Resources/Lang/tk/base.php
Normal file
5
app/Modules/CardOrder/Resources/Lang/tk/base.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'card_order_created' => 'Kart sargydyňyz :order_id belgi bilen hasaba alyndy. Sargydy tassyklamak üçin operatorymyz habarlaşar.',
|
||||
];
|
||||
@@ -47,4 +47,3 @@ class OnlinePaymentPolicy
|
||||
return $user->can('ForceDelete:OnlinePayment');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ class SmsRepository
|
||||
public static function sendSMS(string|int $phone, string|int $message): mixed
|
||||
{
|
||||
if (app()->environment('local')) {
|
||||
info('Sending SMS to '.$phone.' with message: '.$message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
*/
|
||||
class VisaMasterPaymentOrder extends Model implements HasMedia, BelongsToBranch
|
||||
class VisaMasterPaymentOrder extends Model implements BelongsToBranch, HasMedia
|
||||
{
|
||||
use InteractsWithMedia;
|
||||
use SoftDeletes;
|
||||
|
||||
@@ -47,4 +47,3 @@ class VisaMasterPaymentOrderItemPolicy
|
||||
return $user->can('ForceDelete:VisaMasterPaymentOrderItem');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,4 +47,3 @@ class VisaMasterPaymentOrderPolicy
|
||||
return $user->can('ForceDelete:VisaMasterPaymentOrder');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,4 +47,3 @@ class VisaMasterSettingsPolicy
|
||||
return $user->can('ForceDelete:VisaMasterSettings');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ use Filament\Panel;
|
||||
use Filament\PanelProvider;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Filament\Widgets\AccountWidget;
|
||||
use Filament\Widgets\FilamentInfoWidget;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
@@ -29,8 +30,6 @@ class WorkPanelProvider extends PanelProvider
|
||||
{
|
||||
public function panel(Panel $panel): Panel
|
||||
{
|
||||
// #content\.form-actions > div
|
||||
|
||||
return $panel
|
||||
->default()
|
||||
->id('work')
|
||||
@@ -47,6 +46,7 @@ class WorkPanelProvider extends PanelProvider
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets')
|
||||
->widgets([
|
||||
AccountWidget::class,
|
||||
FilamentInfoWidget::class,
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
@@ -75,6 +75,7 @@ class WorkPanelProvider extends PanelProvider
|
||||
]),
|
||||
|
||||
FilamentUpload::make(),
|
||||
|
||||
])
|
||||
->authMiddleware([
|
||||
Authenticate::class,
|
||||
|
||||
@@ -7,6 +7,7 @@ use Illuminate\Foundation\Configuration\Middleware;
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__.'/../routes/web.php',
|
||||
api: __DIR__.'/../routes/api.php',
|
||||
commands: __DIR__.'/../routes/console.php',
|
||||
health: '/up',
|
||||
)
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
"halaxa/json-machine": "^1.2",
|
||||
"joaopaulolndev/filament-edit-profile": "^2.0",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"laravel/ui": "^4.6",
|
||||
"mpdf/mpdf": "^8.2",
|
||||
"phpoffice/phpword": "dev-master",
|
||||
"ralphjsmit/laravel-filament-upload": "^1.1",
|
||||
"spatie/laravel-activitylog": "^4.10",
|
||||
"spatie/laravel-medialibrary": "^11.17",
|
||||
"spatie/laravel-translatable": "^6.11",
|
||||
"stevebauman/location": "^7.6"
|
||||
|
||||
156
composer.lock
generated
156
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "28304e2033c8e05f63b010bb15ecec8e",
|
||||
"content-hash": "018635a80495002683ac3d2f58dd6eaf",
|
||||
"packages": [
|
||||
{
|
||||
"name": "abdulmajeed-jamaan/filament-translatable-tabs",
|
||||
@@ -3355,6 +3355,69 @@
|
||||
},
|
||||
"time": "2025-11-21T20:52:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/sanctum",
|
||||
"version": "v4.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/sanctum.git",
|
||||
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/sanctum/zipball/f5fb373be39a246c74a060f2cf2ae2c2145b3664",
|
||||
"reference": "f5fb373be39a246c74a060f2cf2ae2c2145b3664",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/console": "^11.0|^12.0",
|
||||
"illuminate/contracts": "^11.0|^12.0",
|
||||
"illuminate/database": "^11.0|^12.0",
|
||||
"illuminate/support": "^11.0|^12.0",
|
||||
"php": "^8.2",
|
||||
"symfony/console": "^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.6",
|
||||
"orchestra/testbench": "^9.15|^10.8",
|
||||
"phpstan/phpstan": "^1.10"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Sanctum\\SanctumServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Sanctum\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.",
|
||||
"keywords": [
|
||||
"auth",
|
||||
"laravel",
|
||||
"sanctum"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/sanctum/issues",
|
||||
"source": "https://github.com/laravel/sanctum"
|
||||
},
|
||||
"time": "2025-11-21T13:59:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
"version": "v2.0.7",
|
||||
@@ -7358,6 +7421,97 @@
|
||||
],
|
||||
"time": "2024-05-17T09:06:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-activitylog",
|
||||
"version": "4.10.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/laravel-activitylog.git",
|
||||
"reference": "bb879775d487438ed9a99e64f09086b608990c10"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/bb879775d487438ed9a99e64f09086b608990c10",
|
||||
"reference": "bb879775d487438ed9a99e64f09086b608990c10",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/config": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
|
||||
"illuminate/database": "^8.69 || ^9.27 || ^10.0 || ^11.0 || ^12.0",
|
||||
"illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
|
||||
"php": "^8.1",
|
||||
"spatie/laravel-package-tools": "^1.6.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"orchestra/testbench": "^6.23 || ^7.0 || ^8.0 || ^9.0 || ^10.0",
|
||||
"pestphp/pest": "^1.20 || ^2.0 || ^3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Spatie\\Activitylog\\ActivitylogServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Spatie\\Activitylog\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian De Deyne",
|
||||
"email": "sebastian@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Tom Witkowski",
|
||||
"email": "dev.gummibeer@gmail.com",
|
||||
"homepage": "https://gummibeer.de",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A very simple activity logger to monitor the users of your website or application",
|
||||
"homepage": "https://github.com/spatie/activitylog",
|
||||
"keywords": [
|
||||
"activity",
|
||||
"laravel",
|
||||
"log",
|
||||
"spatie",
|
||||
"user"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/laravel-activitylog/issues",
|
||||
"source": "https://github.com/spatie/laravel-activitylog/tree/4.10.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-15T06:59:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-medialibrary",
|
||||
"version": "11.17.7",
|
||||
|
||||
52
config/activitylog.php
Normal file
52
config/activitylog.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
* If set to false, no activities will be saved to the database.
|
||||
*/
|
||||
'enabled' => env('ACTIVITY_LOGGER_ENABLED', true),
|
||||
|
||||
/*
|
||||
* When the clean-command is executed, all recording activities older than
|
||||
* the number of days specified here will be deleted.
|
||||
*/
|
||||
'delete_records_older_than_days' => 365,
|
||||
|
||||
/*
|
||||
* If no log name is passed to the activity() helper
|
||||
* we use this default log name.
|
||||
*/
|
||||
'default_log_name' => 'default',
|
||||
|
||||
/*
|
||||
* You can specify an auth driver here that gets user models.
|
||||
* If this is null we'll use the current Laravel auth driver.
|
||||
*/
|
||||
'default_auth_driver' => null,
|
||||
|
||||
/*
|
||||
* If set to true, the subject returns soft deleted models.
|
||||
*/
|
||||
'subject_returns_soft_deleted_models' => false,
|
||||
|
||||
/*
|
||||
* This model will be used to log activity.
|
||||
* It should implement the Spatie\Activitylog\Contracts\Activity interface
|
||||
* and extend Illuminate\Database\Eloquent\Model.
|
||||
*/
|
||||
'activity_model' => \Spatie\Activitylog\Models\Activity::class,
|
||||
|
||||
/*
|
||||
* This is the name of the table that will be created by the migration and
|
||||
* used by the Activity model shipped with this package.
|
||||
*/
|
||||
'table_name' => env('ACTIVITY_LOGGER_TABLE_NAME', 'activity_log'),
|
||||
|
||||
/*
|
||||
* This is the database connection that will be used by the migration and
|
||||
* the Activity model shipped with this package. In case it's not set
|
||||
* Laravel's database.default will be used instead.
|
||||
*/
|
||||
'database_connection' => env('ACTIVITY_LOGGER_DB_CONNECTION'),
|
||||
];
|
||||
84
config/sanctum.php
Normal file
84
config/sanctum.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Stateful Domains
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Requests from the following domains / hosts will receive stateful API
|
||||
| authentication cookies. Typically, these should include your local
|
||||
| and production domains which access your API via a frontend SPA.
|
||||
|
|
||||
*/
|
||||
|
||||
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
|
||||
'%s%s',
|
||||
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
|
||||
Sanctum::currentApplicationUrlWithPort(),
|
||||
// Sanctum::currentRequestHost(),
|
||||
))),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Guards
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This array contains the authentication guards that will be checked when
|
||||
| Sanctum is trying to authenticate a request. If none of these guards
|
||||
| are able to authenticate the request, Sanctum will use the bearer
|
||||
| token that's present on an incoming request for authentication.
|
||||
|
|
||||
*/
|
||||
|
||||
'guard' => ['web'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Expiration Minutes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value controls the number of minutes until an issued token will be
|
||||
| considered expired. This will override any values set in the token's
|
||||
| "expires_at" attribute, but first-party sessions are not affected.
|
||||
|
|
||||
*/
|
||||
|
||||
'expiration' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Token Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Sanctum can prefix new tokens in order to take advantage of numerous
|
||||
| security scanning initiatives maintained by open source platforms
|
||||
| that notify developers if they commit tokens into repositories.
|
||||
|
|
||||
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
||||
|
|
||||
*/
|
||||
|
||||
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When authenticating your first-party SPA with Sanctum you may need to
|
||||
| customize some of the middleware Sanctum uses while processing the
|
||||
| request. You may change the middleware listed below as required.
|
||||
|
|
||||
*/
|
||||
|
||||
'middleware' => [
|
||||
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
|
||||
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
|
||||
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
|
||||
],
|
||||
|
||||
];
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('action_events', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('batch_id')->nullable();
|
||||
$table->unsignedBigInteger('user_id')->nullable()->index();
|
||||
|
||||
$table->string('name')->index();
|
||||
|
||||
$table->string('actionable_type')->nullable()->index();
|
||||
$table->unsignedBigInteger('actionable_id')->nullable()->index();
|
||||
|
||||
$table->string('target_type')->nullable()->index();
|
||||
$table->unsignedBigInteger('target_id')->nullable()->index();
|
||||
|
||||
$table->string('model_type')->nullable()->index();
|
||||
$table->unsignedBigInteger('model_id')->nullable()->index();
|
||||
|
||||
$table->text('fields')->nullable();
|
||||
$table->string('status')->index()->default('finished');
|
||||
$table->text('exception')->nullable();
|
||||
$table->json('original')->nullable();
|
||||
$table->json('changes')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('action_events');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->text('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable()->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
||||
@@ -13,9 +13,7 @@ class DatabaseSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
FillJsonData::class,
|
||||
// UsersTableSeeder::class,
|
||||
// ShieldSeeder::class,
|
||||
ShieldSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ class FillJsonData extends Seeder
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
public function run(): void
|
||||
{
|
||||
$this->seedVisaMasterPaymentOrders();
|
||||
|
||||
}
|
||||
|
||||
protected function seedUsers(): void
|
||||
@@ -68,4 +68,19 @@ class FillJsonData extends Seeder
|
||||
{
|
||||
(new Migrators\VisaMasterPaymentOrdersMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedActionEvents(): void
|
||||
{
|
||||
(new Migrators\ActionEventsMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedBranchUser(): void
|
||||
{
|
||||
(new Migrators\BranchUserMigrator)->migrate();
|
||||
}
|
||||
|
||||
protected function seedCurrencyRates(): void
|
||||
{
|
||||
(new Migrators\CurrencyRatesMigrator)->migrate();
|
||||
}
|
||||
}
|
||||
|
||||
29
database/seeders/Migrators/ActionEventsMigrator.php
Normal file
29
database/seeders/Migrators/ActionEventsMigrator.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class ActionEventsMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('action_events')->truncate();
|
||||
|
||||
$path = database_path('data/tested/action_events.json');
|
||||
|
||||
$items = Items::fromFile($path);
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
if (! $item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('action_events')->insert((array) $item);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('action_events_id_seq', (SELECT MAX(id) from action_events));");
|
||||
DB::statement("SELECT nextval('action_events_id_seq');");
|
||||
}
|
||||
}
|
||||
29
database/seeders/Migrators/BranchUserMigrator.php
Normal file
29
database/seeders/Migrators/BranchUserMigrator.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class BranchUserMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('branch_user')->truncate();
|
||||
|
||||
$path = database_path('data/tested/branch_user.json');
|
||||
|
||||
$items = Items::fromFile($path);
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
if (! $item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('branch_user')->insert((array) $item);
|
||||
|
||||
DB::statement("SELECT setval('branch_user_id_seq', (SELECT MAX(id) from branch_user));");
|
||||
DB::statement("SELECT nextval('branch_user_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class BranchesMigrator
|
||||
{
|
||||
DB::table('branches')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/branches.json');
|
||||
$path = database_path('data/tested/branches.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -19,5 +19,8 @@ class BranchesMigrator
|
||||
DB::table('branches')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('branches_id_seq', (SELECT MAX(id) from branches));");
|
||||
DB::statement("SELECT nextval('branches_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class CardOrdersMigrator
|
||||
{
|
||||
DB::table('card_orders')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/card_orders.json');
|
||||
$path = database_path('data/tested/card_orders.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -19,5 +19,8 @@ class CardOrdersMigrator
|
||||
DB::table('card_orders')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('card_orders_id_seq', (SELECT MAX(id) from card_orders));");
|
||||
DB::statement("SELECT nextval('card_orders_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class CardPinOrdersMigrator
|
||||
{
|
||||
DB::table('card_pin_orders')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/card_pins.json');
|
||||
$path = database_path('data/tested/card_pins.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -25,5 +25,8 @@ class CardPinOrdersMigrator
|
||||
DB::table('card_pin_orders')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('card_pin_orders_id_seq', (SELECT MAX(id) from card_pin_orders));");
|
||||
DB::statement("SELECT nextval('card_pin_orders_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class CardStatesMigrator
|
||||
{
|
||||
DB::table('card_states')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/card_states.json');
|
||||
$path = database_path('data/tested/card_states.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -19,5 +19,8 @@ class CardStatesMigrator
|
||||
DB::table('card_states')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('card_states_id_seq', (SELECT MAX(id) from card_states));");
|
||||
DB::statement("SELECT nextval('card_states_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class CardTypesMigrator
|
||||
{
|
||||
DB::table('card_types')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/card_types.json');
|
||||
$path = database_path('data/tested/card_types.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -19,5 +19,8 @@ class CardTypesMigrator
|
||||
DB::table('card_types')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('card_types_id_seq', (SELECT MAX(id) from card_types));");
|
||||
DB::statement("SELECT nextval('card_types_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
database/seeders/Migrators/CurrencyRatesMigrator.php
Normal file
29
database/seeders/Migrators/CurrencyRatesMigrator.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class CurrencyRatesMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('currency_rates')->truncate();
|
||||
|
||||
$path = database_path('data/tested/currency_rates.json');
|
||||
|
||||
$items = Items::fromFile($path);
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
if (! $item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('currency_rates')->insert((array) $item);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('currency_rates_id_seq', (SELECT MAX(id) from currency_rates));");
|
||||
DB::statement("SELECT nextval('currency_rates_id_seq');");
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class LoanOrderRequiredDocsMigrator
|
||||
{
|
||||
DB::table('loan_order_required_docs')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/loan_order_required_docs.json');
|
||||
$path = database_path('data/tested/loan_order_required_docs.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -19,5 +19,8 @@ class LoanOrderRequiredDocsMigrator
|
||||
DB::table('loan_order_required_docs')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('loan_order_required_docs_id_seq', (SELECT MAX(id) from loan_order_required_docs));");
|
||||
DB::statement("SELECT nextval('loan_order_required_docs_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,16 @@
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use JsonMachine\JsonMachine;
|
||||
use JsonMachine\Items;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
use Cerbero\LazyJson\LazyJson;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class LoanOrdersMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
// Running on seeder file, may not work.
|
||||
|
||||
DB::table('loan_orders')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/loan_orders.json');
|
||||
$path = database_path('data/tested/loan_orders.json');
|
||||
|
||||
$items = Items::fromFile($path);
|
||||
|
||||
@@ -28,5 +22,8 @@ class LoanOrdersMigrator
|
||||
|
||||
DB::table('loan_orders')->insert((array) $item);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('loan_orders_id_seq', (SELECT MAX(id) from loan_orders));");
|
||||
DB::statement("SELECT nextval('loan_orders_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class LoanTypesMigrator
|
||||
{
|
||||
DB::table('loan_types')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/loan_types.json');
|
||||
$path = database_path('data/tested/loan_types.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -19,5 +19,8 @@ class LoanTypesMigrator
|
||||
DB::table('loan_types')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('loan_types_id_seq', (SELECT MAX(id) from loan_types));");
|
||||
DB::statement("SELECT nextval('loan_types_id_seq');");
|
||||
}
|
||||
}
|
||||
|
||||
29
database/seeders/Migrators/MediaMigrator.php
Normal file
29
database/seeders/Migrators/MediaMigrator.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class MediaMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('media')->truncate();
|
||||
|
||||
$path = database_path('data/tested/media.json');
|
||||
|
||||
$items = Items::fromFile($path);
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
if (! $item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('media')->insert((array) $item);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('media_id_seq', (SELECT MAX(id) from media));");
|
||||
DB::statement("SELECT nextval('media_id_seq');");
|
||||
}
|
||||
}
|
||||
26
database/seeders/Migrators/ModelHasRolesMigrator.php
Normal file
26
database/seeders/Migrators/ModelHasRolesMigrator.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class ModelHasRolesMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('model_has_roles')->truncate();
|
||||
|
||||
$path = database_path('data/tested/model_has_roles.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
foreach ($rawData as $data) {
|
||||
DB::table('model_has_roles')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('model_has_roles_id_seq', (SELECT MAX(id) from model_has_roles));");
|
||||
DB::statement("SELECT nextval('model_has_roles_id_seq');");
|
||||
}
|
||||
}
|
||||
43
database/seeders/Migrators/OnlinePaymentsMigrator.php
Normal file
43
database/seeders/Migrators/OnlinePaymentsMigrator.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use App\Modules\CardOrder\Models\CardOrder;
|
||||
use App\Modules\CardPinOrder\Models\CardPinOrder;
|
||||
use App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class OnlinePaymentsMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('online_payments')->truncate();
|
||||
|
||||
$path = database_path('data/tested/online_payment_histories.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
foreach ($rawData as $data) {
|
||||
if ($data['online_paymantable_type']) {
|
||||
if ($data['online_paymantable_type'] == 'App\Models\Order\Card\Requisite\CardRequisite') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data['online_paymantable_type'] = match ($data['online_paymantable_type']) {
|
||||
'App\Models\Order\Card\CardOrder' => CardOrder::class,
|
||||
'App\Models\Order\Card\CardPin\CardPin' => CardPinOrder::class,
|
||||
// 'App\Modules\SberPaymentOrder\Models\SberPaymentOrder' => SberPaymentOrder::class,
|
||||
'App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder' => VisaMasterPaymentOrder::class,
|
||||
'\App\Modules\VisaMasterPaymentOrder\Models\VisaMasterPaymentOrder' => VisaMasterPaymentOrder::class,
|
||||
};
|
||||
}
|
||||
|
||||
DB::table('online_payments')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('online_payments_id_seq', (SELECT MAX(id) from online_payments));");
|
||||
DB::statement("SELECT nextval('online_payments_id_seq');");
|
||||
}
|
||||
}
|
||||
26
database/seeders/Migrators/PersonalAccessTokensMigrator.php
Normal file
26
database/seeders/Migrators/PersonalAccessTokensMigrator.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class PersonalAccessTokensMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('personal_access_tokens')->truncate();
|
||||
|
||||
$path = database_path('data/tested/personal_access_tokens.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
foreach ($rawData as $data) {
|
||||
DB::table('personal_access_tokens')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('personal_access_tokens_id_seq', (SELECT MAX(id) from personal_access_tokens));");
|
||||
DB::statement("SELECT nextval('personal_access_tokens_id_seq');");
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class ProvincesMigrator
|
||||
{
|
||||
DB::table('provinces')->truncate();
|
||||
|
||||
$path = database_path('data/nurmuhammetsdb/provinces.json');
|
||||
$path = database_path('data/tested/provinces.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
@@ -19,5 +19,8 @@ class ProvincesMigrator
|
||||
DB::table('provinces')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('provinces_id_seq', (SELECT MAX(id) from provinces));");
|
||||
DB::statement("SELECT nextval('provinces_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ class UsersMigrator
|
||||
'active' => $user['active'],
|
||||
]);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('users_id_seq', (SELECT MAX(id) from users));");
|
||||
DB::statement("SELECT nextval('users_id_seq');");
|
||||
}
|
||||
|
||||
protected function extractFirstName(string $name): string
|
||||
|
||||
26
database/seeders/Migrators/VerificationsMigrator.php
Normal file
26
database/seeders/Migrators/VerificationsMigrator.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class VerificationsMigrator
|
||||
{
|
||||
public function migrate(): void
|
||||
{
|
||||
DB::table('verifications')->truncate();
|
||||
|
||||
$path = database_path('data/tested/verifications.json');
|
||||
|
||||
$rawData = File::json($path);
|
||||
|
||||
foreach ($rawData as $data) {
|
||||
DB::table('verifications')
|
||||
->insert($data);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('verifications_id_seq', (SELECT MAX(id) from verifications));");
|
||||
DB::statement("SELECT nextval('verifications_id_seq');");
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Database\Seeders\Migrators;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use JsonMachine\JsonMachine;
|
||||
use JsonMachine\Items;
|
||||
|
||||
class VisaMasterPaymentOrdersMigrator
|
||||
@@ -21,7 +20,6 @@ class VisaMasterPaymentOrdersMigrator
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$sender_datas = json_decode($item->sender_datas);
|
||||
$payment_reciever = json_decode($item->payment_reciever);
|
||||
|
||||
@@ -62,5 +60,8 @@ class VisaMasterPaymentOrdersMigrator
|
||||
'deleted_at' => $item->deleted_at,
|
||||
]);
|
||||
}
|
||||
|
||||
DB::statement("SELECT setval('visa_master_payment_orders_id_seq', (SELECT MAX(id) from visa_master_payment_orders));");
|
||||
DB::statement("SELECT nextval('visa_master_payment_orders_id_seq');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class ShieldSeeder extends Seeder
|
||||
{
|
||||
app()[PermissionRegistrar::class]->forgetCachedPermissions();
|
||||
|
||||
$rolesWithPermissions = '[{"name":"super_admin","guard_name":"web","permissions":["ViewAny:Role","View:Role","Create:Role","Update:Role","Delete:Role","Restore:Role","ForceDelete:Role","ForceDeleteAny:Role","RestoreAny:Role","Replicate:Role","Reorder:Role"]}]';
|
||||
$rolesWithPermissions = '[{"id":2,"name":"super_admin","guard_name":"web","permissions":["ViewAny:Role","View:Role","Create:Role","Update:Role","Delete:Role","Restore:Role","ForceDelete:Role","ForceDeleteAny:Role","RestoreAny:Role","Replicate:Role","Reorder:Role"]}]';
|
||||
$directPermissions = '[]';
|
||||
|
||||
static::makeRolesWithPermissions($rolesWithPermissions);
|
||||
@@ -32,26 +32,32 @@ class ShieldSeeder extends Seeder
|
||||
|
||||
$additionalRoles = collect([
|
||||
[
|
||||
'id' => 3,
|
||||
'name' => 'admin',
|
||||
'guard_name' => 'web',
|
||||
],
|
||||
[
|
||||
'id' => 4,
|
||||
'name' => 'operator',
|
||||
'guard_name' => 'web',
|
||||
],
|
||||
[
|
||||
'id' => 10,
|
||||
'name' => 'operator_card',
|
||||
'guard_name' => 'web',
|
||||
],
|
||||
[
|
||||
'id' => 11,
|
||||
'name' => 'operator_loan',
|
||||
'guard_name' => 'web',
|
||||
],
|
||||
[
|
||||
'id' => 12,
|
||||
'name' => 'client',
|
||||
'guard_name' => 'web',
|
||||
],
|
||||
[
|
||||
'id' => 6,
|
||||
'name' => 'currency_maintainer',
|
||||
'guard_name' => 'web',
|
||||
],
|
||||
@@ -74,6 +80,7 @@ class ShieldSeeder extends Seeder
|
||||
|
||||
foreach ($rolePlusPermissions as $rolePlusPermission) {
|
||||
$role = $roleModel::firstOrCreate([
|
||||
'id' => $rolePlusPermission['id'],
|
||||
'name' => $rolePlusPermission['name'],
|
||||
'guard_name' => $rolePlusPermission['guard_name'],
|
||||
]);
|
||||
|
||||
1
public/build/assets/theme-D6od5FeK.css
Normal file
1
public/build/assets/theme-D6od5FeK.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"resources/css/filament/work/theme.css": {
|
||||
"file": "assets/theme-N6DF4L1Y.css",
|
||||
"file": "assets/theme-D6od5FeK.css",
|
||||
"src": "resources/css/filament/work/theme.css",
|
||||
"isEntry": true,
|
||||
"name": "theme",
|
||||
|
||||
873
public/vendor/livewire/livewire.esm.js
vendored
873
public/vendor/livewire/livewire.esm.js
vendored
File diff suppressed because it is too large
Load Diff
6
public/vendor/livewire/livewire.esm.js.map
vendored
6
public/vendor/livewire/livewire.esm.js.map
vendored
File diff suppressed because one or more lines are too long
624
public/vendor/livewire/livewire.js
vendored
624
public/vendor/livewire/livewire.js
vendored
File diff suppressed because it is too large
Load Diff
15
public/vendor/livewire/livewire.min.js
vendored
15
public/vendor/livewire/livewire.min.js
vendored
File diff suppressed because one or more lines are too long
6
public/vendor/livewire/livewire.min.js.map
vendored
6
public/vendor/livewire/livewire.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/manifest.json
vendored
2
public/vendor/livewire/manifest.json
vendored
@@ -1,2 +1,2 @@
|
||||
|
||||
{"/livewire.js":"df3a17f2"}
|
||||
{"/livewire.js":"0f6341c0"}
|
||||
|
||||
@@ -16,19 +16,53 @@
|
||||
>
|
||||
@foreach ($media as $item)
|
||||
@if (str_starts_with($item->mime_type, 'image/'))
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<img
|
||||
src="{{ $entry->getMediaUrl($item, $media->count() > 1 ? 'thumb' : null) }}"
|
||||
class="w-full rounded-lg"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="text-sm font-medium text-primary-600 decoration-2 center underline focus:outline-none dark:text-primary-500"
|
||||
@click="$dispatch('open-modal', { id: 'preview-image-{{ $item->id }}' })"
|
||||
>
|
||||
{{ __('Watch Full') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 rounded-xl border border-gray-200 bg-white p-2 shadow-sm dark:border-white/10 dark:bg-white/5">
|
||||
<div class="flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-gray-100 dark:bg-white/10 overflow-hidden">
|
||||
<img
|
||||
src="{{ $entry->getMediaUrl($item, $media->count() > 1 ? 'thumb' : null) }}"
|
||||
class="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow overflow-hidden">
|
||||
<p class="truncate text-sm font-medium text-gray-950 dark:text-white" title="{{ $item->name }}">
|
||||
{{ $item->name }}
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ $item->human_readable_size }}
|
||||
<span class="text-gray-300 dark:text-gray-600 px-1">•</span>
|
||||
<span class="uppercase">{{ $item->extension }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex shrink-0 items-center gap-2 pr-2">
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-50 dark:hover:bg-white/10 text-gray-500 hover:text-primary-600 dark:text-gray-400 dark:hover:text-primary-500 transition-colors"
|
||||
@click="$dispatch('open-modal', { id: 'preview-image-{{ $item->id }}' })"
|
||||
title="{{ __('View') }}"
|
||||
>
|
||||
<x-filament::icon
|
||||
icon="heroicon-m-eye"
|
||||
class="h-5 w-5"
|
||||
/>
|
||||
</button>
|
||||
|
||||
@if ($entry->isDownloadable())
|
||||
<a
|
||||
href="{{ $entry->getMediaUrl($item) }}"
|
||||
download
|
||||
class="flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-50 dark:hover:bg-white/10 text-gray-500 hover:text-primary-600 dark:text-gray-400 dark:hover:text-primary-500 transition-colors"
|
||||
title="{{ __('Download') }}"
|
||||
>
|
||||
<x-filament::icon
|
||||
icon="heroicon-m-arrow-down-tray"
|
||||
class="h-5 w-5"
|
||||
/>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-filament::modal id="preview-image-{{ $item->id }}" width="5xl" :close-button="true">
|
||||
<x-slot name="heading">
|
||||
@@ -37,7 +71,7 @@
|
||||
|
||||
<img
|
||||
src="{{ $entry->getMediaUrl($item) }}"
|
||||
class="w-full h-full object-contain"
|
||||
class="max-h-[400px] w-fit"
|
||||
/>
|
||||
</x-filament::modal>
|
||||
@else
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
@php
|
||||
use Filament\Actions\View\ActionsRenderHook;
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
|
||||
$actionModalAlignment = $action->getModalAlignment();
|
||||
$actionIsModalAutofocused = $action->isModalAutofocused();
|
||||
$actionHasModalCloseButton = $action->hasModalCloseButton();
|
||||
$actionIsModalClosedByClickingAway = $action->isModalClosedByClickingAway();
|
||||
$actionIsModalClosedByEscaping = $action->isModalClosedByEscaping();
|
||||
$actionModalDescription = $action->getModalDescription();
|
||||
$actionExtraModalWindowAttributeBag = $action->getExtraModalWindowAttributeBag();
|
||||
$actionModalFooterActions = $action->getVisibleModalFooterActions();
|
||||
$actionModalFooterActionsAlignment = $action->getModalFooterActionsAlignment();
|
||||
$actionModalHeading = $action->getModalHeading();
|
||||
$actionModalIcon = $action->getModalIcon();
|
||||
$actionModalIconColor = $action->getModalIconColor();
|
||||
$actionModalId = "fi-{$this->getId()}-action-{$action->getNestingIndex()}";
|
||||
$actionIsModalSlideOver = $action->isModalSlideOver();
|
||||
$actionIsModalFooterSticky = $action->isModalFooterSticky();
|
||||
$actionIsModalHeaderSticky = $action->isModalHeaderSticky();
|
||||
$actionModalWidth = $action->getModalWidth();
|
||||
$actionLivewireCallMountedActionName = $action->hasFormWrapper() ? $action->getLivewireCallMountedActionName() : null;
|
||||
$actionModalWireKey = "{$this->getId()}.actions.{$action->getName()}.modal";
|
||||
@endphp
|
||||
|
||||
<x-filament::modal
|
||||
:alignment="$actionModalAlignment"
|
||||
:autofocus="$actionIsModalAutofocused"
|
||||
:close-button="$actionHasModalCloseButton"
|
||||
:close-by-clicking-away="$actionIsModalClosedByClickingAway"
|
||||
:close-by-escaping="$actionIsModalClosedByEscaping"
|
||||
:description="$actionModalDescription"
|
||||
:extra-modal-window-attribute-bag="$actionExtraModalWindowAttributeBag"
|
||||
:footer-actions="$actionModalFooterActions"
|
||||
:footer-actions-alignment="$actionModalFooterActionsAlignment"
|
||||
:heading="$actionModalHeading"
|
||||
:icon="$actionModalIcon"
|
||||
:icon-color="$actionModalIconColor"
|
||||
:id="$actionModalId"
|
||||
:slide-over="$actionIsModalSlideOver"
|
||||
:sticky-footer="$actionIsModalFooterSticky"
|
||||
:sticky-header="$actionIsModalHeaderSticky"
|
||||
:width="$actionModalWidth"
|
||||
:wire:key="$actionModalWireKey"
|
||||
:wire:submit.prevent="$actionLivewireCallMountedActionName"
|
||||
:x-on:modal-closed="'if ($event.detail.id === ' . \Illuminate\Support\Js::from($actionModalId) . ') $wire.unmountAction(false)'"
|
||||
>
|
||||
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_BEFORE, scopes: static::class, data: ['action' => $action]) }}
|
||||
|
||||
{{ $action->getModalContent() }}
|
||||
|
||||
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_AFTER, scopes: static::class, data: ['action' => $action]) }}
|
||||
|
||||
@if ($this->mountedActionHasSchema(mountedAction: $action))
|
||||
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_SCHEMA_BEFORE, scopes: static::class, data: ['action' => $action]) }}
|
||||
|
||||
{{ $this->getMountedActionSchema(mountedAction: $action) }}
|
||||
|
||||
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_SCHEMA_AFTER, scopes: static::class, data: ['action' => $action]) }}
|
||||
@endif
|
||||
|
||||
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_FOOTER_BEFORE, scopes: static::class, data: ['action' => $action]) }}
|
||||
|
||||
{{ $action->getModalContentFooter() }}
|
||||
|
||||
{{ FilamentView::renderHook(ActionsRenderHook::MODAL_CUSTOM_CONTENT_FOOTER_AFTER, scopes: static::class, data: ['action' => $action]) }}
|
||||
</x-filament::modal>
|
||||
@@ -1,59 +0,0 @@
|
||||
@props([
|
||||
'actions' => [],
|
||||
'badge' => null,
|
||||
'badgeColor' => null,
|
||||
'button' => false,
|
||||
'color' => null,
|
||||
'dropdownMaxHeight' => null,
|
||||
'dropdownOffset' => null,
|
||||
'dropdownPlacement' => null,
|
||||
'dropdownWidth' => null,
|
||||
'group' => null,
|
||||
'icon' => null,
|
||||
'iconSize' => null,
|
||||
'iconButton' => false,
|
||||
'label' => null,
|
||||
'link' => false,
|
||||
'size' => null,
|
||||
'tooltip' => null,
|
||||
'triggerView' => null,
|
||||
'view' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$group ??= \Filament\Actions\ActionGroup::make($actions)
|
||||
->badgeColor($badgeColor)
|
||||
->color($color)
|
||||
->dropdownMaxHeight($dropdownMaxHeight)
|
||||
->dropdownOffset($dropdownOffset)
|
||||
->dropdownPlacement($dropdownPlacement)
|
||||
->dropdownWidth($dropdownWidth)
|
||||
->icon($icon)
|
||||
->iconSize($iconSize)
|
||||
->label($label)
|
||||
->size($size)
|
||||
->tooltip($tooltip)
|
||||
->triggerView($triggerView)
|
||||
->view($view);
|
||||
|
||||
$badge === true
|
||||
? $group->badge()
|
||||
: $group->badge($badge);
|
||||
|
||||
if ($button) {
|
||||
$group
|
||||
->button()
|
||||
->iconPosition($attributes->get('iconPosition') ?? $attributes->get('icon-position'))
|
||||
->outlined($attributes->get('outlined') ?? false);
|
||||
}
|
||||
|
||||
if ($iconButton) {
|
||||
$group->iconButton();
|
||||
}
|
||||
|
||||
if ($link) {
|
||||
$group->link();
|
||||
}
|
||||
@endphp
|
||||
|
||||
{{ $group }}
|
||||
@@ -1,19 +0,0 @@
|
||||
@if ($this instanceof \Filament\Actions\Contracts\HasActions && (! $this->hasActionsModalRendered))
|
||||
<div
|
||||
wire:partial="action-modals"
|
||||
x-data="filamentActionModals({
|
||||
livewireId: @js($this->getId()),
|
||||
})"
|
||||
style="height: 0"
|
||||
>
|
||||
@foreach ($this->getMountedActions() as $action)
|
||||
@if ((! $loop->last) || $this->mountedActionShouldOpenModal())
|
||||
{{ $action->toModalHtmlable() }}
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@php
|
||||
$this->hasActionsModalRendered = true;
|
||||
@endphp
|
||||
@endif
|
||||
@@ -1,7 +0,0 @@
|
||||
<x-filament-panels::page>
|
||||
@foreach ($this->getRegisteredCustomProfileComponents() as $component)
|
||||
@unless(is_null($component))
|
||||
@livewire($component)
|
||||
@endunless
|
||||
@endforeach
|
||||
</x-filament-panels::page>
|
||||
@@ -1,54 +0,0 @@
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
>
|
||||
<div>
|
||||
<div class="">
|
||||
<div class="text-sm text-gray-600 fi-in-entry">
|
||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ __('filament-edit-profile::default.browser_sessions_content') }}
|
||||
</div>
|
||||
@if (count($data) > 0)
|
||||
<div class="fi-in-entry">
|
||||
@foreach ($data as $session)
|
||||
<div class="fi-sc fi-inline fi-sc-has-gap">
|
||||
<div>
|
||||
@if ($session->device['desktop'])
|
||||
<x-filament::icon
|
||||
icon="heroicon-o-computer-desktop"
|
||||
class="w-8 h-8 text-gray-500 dark:text-gray-400"
|
||||
/>
|
||||
@else
|
||||
<x-filament::icon
|
||||
icon="heroicon-o-device-phone-mobile"
|
||||
class="w-8 h-8 text-gray-500 dark:text-gray-400"
|
||||
/>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="ms-3">
|
||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ $session->device['platform'] ? $session->device['platform'] : __('Unknown') }} - {{ $session->device['browser'] ? $session->device['browser'] : __('Unknown') }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-xs text-gray-500">
|
||||
{{ $session->ip_address }},
|
||||
|
||||
@if ($session->is_current_device)
|
||||
<span class="font-semibold text-primary-500">{{ __('filament-edit-profile::default.browser_sessions_device') }}</span>
|
||||
@else
|
||||
{{ __('filament-edit-profile::default.browser_sessions_last_active') }} {{ $session->last_active }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,12 +0,0 @@
|
||||
<x-dynamic-component
|
||||
:component="$getFieldWrapperView()"
|
||||
:field="$field"
|
||||
>
|
||||
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
|
||||
<div class="text-start">
|
||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ __('filament-edit-profile::default.delete_account_card_description') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,7 +0,0 @@
|
||||
<div>
|
||||
<form class="fi-sc-form">
|
||||
{{ $this->form }}
|
||||
</form>
|
||||
|
||||
<x-filament-actions::modals />
|
||||
</div>
|
||||
@@ -1,9 +0,0 @@
|
||||
<form wire:submit="updateCustomFields" class="fi-sc-form">
|
||||
{{ $this->form }}
|
||||
|
||||
<div class="fi-ac fi-align-end">
|
||||
<x-filament::button type="submit">
|
||||
{{ __('filament-edit-profile::default.save') }}
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,7 +0,0 @@
|
||||
<div>
|
||||
<form class="fi-sc-form">
|
||||
{{ $this->form }}
|
||||
</form>
|
||||
|
||||
<x-filament-actions::modals />
|
||||
</div>
|
||||
@@ -1,9 +0,0 @@
|
||||
<form wire:submit="updatePassword" class="fi-sc-form">
|
||||
{{ $this->form }}
|
||||
|
||||
<div class="fi-ac fi-align-end">
|
||||
<x-filament::button type="submit">
|
||||
{{ __('filament-edit-profile::default.save') }}
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,9 +0,0 @@
|
||||
<form wire:submit="updateProfile" class="fi-sc-form">
|
||||
{{ $this->form }}
|
||||
|
||||
<div class="fi-ac fi-align-end">
|
||||
<x-filament::button type="submit">
|
||||
{{ __('filament-edit-profile::default.save') }}
|
||||
</x-filament::button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,7 +0,0 @@
|
||||
<div>
|
||||
<form class="fi-sc-form">
|
||||
{{ $this->content }}
|
||||
</form>
|
||||
|
||||
<x-filament-actions::modals />
|
||||
</div>
|
||||
@@ -1,11 +0,0 @@
|
||||
<x-filament::section aside>
|
||||
<x-slot name="heading">
|
||||
{{ __('filament-edit-profile::default.token_section_title') }}
|
||||
</x-slot>
|
||||
<x-slot name="description">
|
||||
{{ __('filament-edit-profile::default.token_section_description') }}
|
||||
</x-slot>
|
||||
|
||||
{{ $this->table }}
|
||||
</x-filament::section>
|
||||
|
||||
@@ -1,328 +0,0 @@
|
||||
@php
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$items = $getItems();
|
||||
$blockPickerBlocks = $getBlockPickerBlocks();
|
||||
$blockPickerColumns = $getBlockPickerColumns();
|
||||
$blockPickerWidth = $getBlockPickerWidth();
|
||||
$hasBlockPreviews = $hasBlockPreviews();
|
||||
$hasInteractiveBlockPreviews = $hasInteractiveBlockPreviews();
|
||||
|
||||
$addAction = $getAction($getAddActionName());
|
||||
$addActionAlignment = $getAddActionAlignment();
|
||||
$addBetweenAction = $getAction($getAddBetweenActionName());
|
||||
$cloneAction = $getAction($getCloneActionName());
|
||||
$collapseAllAction = $getAction($getCollapseAllActionName());
|
||||
$editAction = $getAction($getEditActionName());
|
||||
$expandAllAction = $getAction($getExpandAllActionName());
|
||||
$deleteAction = $getAction($getDeleteActionName());
|
||||
$moveDownAction = $getAction($getMoveDownActionName());
|
||||
$moveUpAction = $getAction($getMoveUpActionName());
|
||||
$reorderAction = $getAction($getReorderActionName());
|
||||
$extraItemActions = $getExtraItemActions();
|
||||
|
||||
$isAddable = $isAddable();
|
||||
$isCloneable = $isCloneable();
|
||||
$isCollapsible = $isCollapsible();
|
||||
$isDeletable = $isDeletable();
|
||||
$isReorderableWithButtons = $isReorderableWithButtons();
|
||||
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
|
||||
|
||||
$collapseAllActionIsVisible = $isCollapsible && $collapseAllAction->isVisible();
|
||||
$expandAllActionIsVisible = $isCollapsible && $expandAllAction->isVisible();
|
||||
|
||||
$key = $getKey();
|
||||
$statePath = $getStatePath();
|
||||
|
||||
$blockLabelHeadingTag = $getHeadingTag();
|
||||
$isBlockLabelTruncated = $isBlockLabelTruncated();
|
||||
$labelBetweenItems = $getLabelBetweenItems();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-builder',
|
||||
'fi-collapsible' => $isCollapsible,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if ($collapseAllActionIsVisible || $expandAllActionIsVisible)
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-builder-actions',
|
||||
'fi-hidden' => count($items) < 2,
|
||||
])
|
||||
>
|
||||
@if ($collapseAllActionIsVisible)
|
||||
<span
|
||||
x-on:click="$dispatch('builder-collapse', '{{ $statePath }}')"
|
||||
>
|
||||
{{ $collapseAllAction }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if ($expandAllActionIsVisible)
|
||||
<span
|
||||
x-on:click="$dispatch('builder-expand', '{{ $statePath }}')"
|
||||
>
|
||||
{{ $expandAllAction }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (count($items))
|
||||
<ul
|
||||
x-sortable
|
||||
data-sortable-animation-duration="{{ $getReorderAnimationDuration() }}"
|
||||
x-on:end.stop="
|
||||
$event.oldDraggableIndex !== $event.newDraggableIndex &&
|
||||
$wire.mountAction(
|
||||
'reorder',
|
||||
{ items: $event.target.sortable.toArray() },
|
||||
{ schemaComponent: '{{ $key }}' },
|
||||
)
|
||||
"
|
||||
class="fi-fo-builder-items"
|
||||
>
|
||||
@php
|
||||
$hasBlockLabels = $hasBlockLabels();
|
||||
$hasBlockIcons = $hasBlockIcons();
|
||||
$hasBlockNumbers = $hasBlockNumbers();
|
||||
$hasBlockHeaders = $hasBlockHeaders();
|
||||
@endphp
|
||||
|
||||
@foreach ($items as $itemKey => $item)
|
||||
@php
|
||||
$visibleExtraItemActions = array_filter(
|
||||
$extraItemActions,
|
||||
fn (Action $action): bool => $action(['item' => $itemKey])->isVisible(),
|
||||
);
|
||||
$cloneAction = $cloneAction(['item' => $itemKey]);
|
||||
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
|
||||
$deleteAction = $deleteAction(['item' => $itemKey]);
|
||||
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
|
||||
$editAction = $editAction(['item' => $itemKey]);
|
||||
$editActionIsVisible = $hasBlockPreviews && $editAction->isVisible();
|
||||
$moveDownAction = $moveDownAction(['item' => $itemKey])->disabled($loop->last);
|
||||
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
|
||||
$moveUpAction = $moveUpAction(['item' => $itemKey])->disabled($loop->first);
|
||||
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
|
||||
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
|
||||
$hasItemHeader = $hasBlockHeaders && ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || $hasBlockIcons || $hasBlockLabels || $editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions);
|
||||
@endphp
|
||||
|
||||
<li
|
||||
wire:ignore.self
|
||||
wire:key="{{ $item->getLivewireKey() }}.item"
|
||||
x-data="{
|
||||
isCollapsed: @js($isCollapsed($item)),
|
||||
}"
|
||||
x-on:builder-expand.window="$event.detail === '{{ $statePath }}' && (isCollapsed = false)"
|
||||
x-on:builder-collapse.window="$event.detail === '{{ $statePath }}' && (isCollapsed = true)"
|
||||
x-on:expand="isCollapsed = false"
|
||||
x-sortable-item="{{ $itemKey }}"
|
||||
{{
|
||||
$item->getParentComponent()->getExtraAttributeBag()
|
||||
->class([
|
||||
'fi-fo-builder-item',
|
||||
'fi-fo-builder-item-has-header' => $hasItemHeader,
|
||||
])
|
||||
}}
|
||||
x-bind:class="{ 'fi-collapsed': isCollapsed }"
|
||||
>
|
||||
@if ($hasItemHeader)
|
||||
<div
|
||||
@if ($isCollapsible)
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
@endif
|
||||
class="fi-fo-builder-item-header"
|
||||
>
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<ul
|
||||
class="fi-fo-builder-item-header-start-actions"
|
||||
>
|
||||
@if ($reorderActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $reorderAction->extraAttributes(['x-sortable-handle' => true], merge: true) }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $moveUpAction }}
|
||||
</li>
|
||||
|
||||
<li x-on:click.stop>
|
||||
{{ $moveDownAction }}
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@php
|
||||
$blockIcon = $item->getParentComponent()->getIcon($item->getRawState(), $itemKey);
|
||||
@endphp
|
||||
|
||||
@if ($hasBlockIcons && filled($blockIcon))
|
||||
{{ \Filament\Support\generate_icon_html($blockIcon, (new \Illuminate\View\ComponentAttributeBag)->class(['fi-fo-builder-item-header-icon'])) }}
|
||||
@endif
|
||||
|
||||
@if ($hasBlockLabels)
|
||||
<{{ $blockLabelHeadingTag }}
|
||||
@class([
|
||||
'fi-fo-builder-item-header-label',
|
||||
'fi-truncated' => $isBlockLabelTruncated,
|
||||
])
|
||||
>
|
||||
{{ $item->getParentComponent()->getLabel($item->getRawState(), $itemKey) }}
|
||||
|
||||
@if ($hasBlockNumbers)
|
||||
{{ $loop->iteration }}
|
||||
@endif
|
||||
</{{ $blockLabelHeadingTag }}>
|
||||
@endif
|
||||
|
||||
@if ($editActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
<ul
|
||||
class="fi-fo-builder-item-header-end-actions"
|
||||
>
|
||||
@foreach ($visibleExtraItemActions as $extraItemAction)
|
||||
<li x-on:click.stop>
|
||||
{{ $extraItemAction(['item' => $itemKey]) }}
|
||||
</li>
|
||||
@endforeach
|
||||
|
||||
@if ($editActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $editAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($cloneActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $cloneAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($deleteActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $deleteAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($isCollapsible)
|
||||
<li
|
||||
class="fi-fo-builder-item-header-collapsible-actions"
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
>
|
||||
<div
|
||||
class="fi-fo-builder-item-header-collapse-action"
|
||||
>
|
||||
{{ $getAction('collapse') }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="fi-fo-builder-item-header-expand-action"
|
||||
>
|
||||
{{ $getAction('expand') }}
|
||||
</div>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div
|
||||
x-show="! isCollapsed"
|
||||
@class([
|
||||
'fi-fo-builder-item-content',
|
||||
'fi-fo-builder-item-content-has-preview' => $hasBlockPreviews && $item->getParentComponent()->hasPreview(),
|
||||
])
|
||||
>
|
||||
@if ($hasBlockPreviews && $item->getParentComponent()->hasPreview())
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-builder-item-preview',
|
||||
'fi-interactive' => $hasInteractiveBlockPreviews,
|
||||
])
|
||||
>
|
||||
{{ $item->getParentComponent()->renderPreview($item->getRawState()) }}
|
||||
</div>
|
||||
|
||||
@if ($editActionIsVisible && (! $hasInteractiveBlockPreviews))
|
||||
<div
|
||||
class="fi-fo-builder-item-preview-edit-overlay"
|
||||
role="button"
|
||||
x-on:click.stop="{{ '$wire.mountAction(\'edit\', { item: \'' . $itemKey . '\' }, { schemaComponent: \'' . $key . '\' })' }}"
|
||||
></div>
|
||||
@endif
|
||||
@else
|
||||
{{ $item }}
|
||||
@endif
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@if (! $loop->last)
|
||||
@if ($isAddable && $addBetweenAction(['afterItem' => $itemKey])->isVisible())
|
||||
<li class="fi-fo-builder-add-between-items-ctn">
|
||||
<div class="fi-fo-builder-add-between-items">
|
||||
<div class="fi-fo-builder-block-picker-ctn">
|
||||
<x-filament-forms::builder.block-picker
|
||||
:action="$addBetweenAction"
|
||||
:after-item="$itemKey"
|
||||
:columns="$blockPickerColumns"
|
||||
:blocks="$blockPickerBlocks"
|
||||
:key="$key"
|
||||
:width="$blockPickerWidth"
|
||||
>
|
||||
<x-slot name="trigger">
|
||||
{{ $addBetweenAction(['afterItem' => $itemKey]) }}
|
||||
</x-slot>
|
||||
</x-filament-forms::builder.block-picker>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@elseif (filled($labelBetweenItems))
|
||||
<li class="fi-fo-builder-label-between-items-ctn">
|
||||
<div
|
||||
class="fi-fo-builder-label-between-items-divider-before"
|
||||
></div>
|
||||
|
||||
<span class="fi-fo-builder-label-between-items">
|
||||
{{ $labelBetweenItems }}
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="fi-fo-builder-label-between-items-divider-after"
|
||||
></div>
|
||||
</li>
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if ($isAddable && $addAction->isVisible())
|
||||
<x-filament-forms::builder.block-picker
|
||||
:action="$addAction"
|
||||
:action-alignment="$addActionAlignment"
|
||||
:blocks="$blockPickerBlocks"
|
||||
:columns="$blockPickerColumns"
|
||||
:key="$key"
|
||||
:width="$blockPickerWidth"
|
||||
>
|
||||
<x-slot name="trigger">
|
||||
{{ $addAction }}
|
||||
</x-slot>
|
||||
</x-filament-forms::builder.block-picker>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,70 +0,0 @@
|
||||
@php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Support\Enums\GridDirection;
|
||||
use Illuminate\View\ComponentAttributeBag;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'action',
|
||||
'actionAlignment' => null,
|
||||
'afterItem' => null,
|
||||
'blocks',
|
||||
'columns' => null,
|
||||
'key',
|
||||
'trigger',
|
||||
'width' => null,
|
||||
])
|
||||
|
||||
<x-filament::dropdown
|
||||
:placement="
|
||||
match ($actionAlignment) {
|
||||
Alignment::Start, Alignment::Left => 'bottom-start',
|
||||
Alignment::End, Alignment::Right => 'bottom-end',
|
||||
default => null,
|
||||
}
|
||||
"
|
||||
shift
|
||||
:width="$width"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
$attributes->class([
|
||||
'fi-fo-builder-block-picker',
|
||||
($actionAlignment instanceof Alignment) ? ('fi-align-' . $actionAlignment->value) : $actionAlignment => $actionAlignment,
|
||||
]),
|
||||
)
|
||||
"
|
||||
>
|
||||
<x-slot name="trigger">
|
||||
{{ $trigger }}
|
||||
</x-slot>
|
||||
|
||||
<x-filament::dropdown.list>
|
||||
<div
|
||||
{{ (new ComponentAttributeBag)->grid($columns, GridDirection::Column) }}
|
||||
>
|
||||
@foreach ($blocks as $block)
|
||||
@php
|
||||
$blockIcon = $block->getIcon();
|
||||
|
||||
$wireClickActionArguments = ['block' => $block->getName()];
|
||||
|
||||
if (filled($afterItem)) {
|
||||
$wireClickActionArguments['afterItem'] = $afterItem;
|
||||
}
|
||||
|
||||
$wireClickActionArguments = \Illuminate\Support\Js::from($wireClickActionArguments);
|
||||
|
||||
$wireClickAction = "mountAction('{$action->getName()}', {$wireClickActionArguments}, { schemaComponent: '{$key}' })";
|
||||
@endphp
|
||||
|
||||
<x-filament::dropdown.list.item
|
||||
:icon="$blockIcon"
|
||||
x-on:click="close"
|
||||
:wire:click="$wireClickAction"
|
||||
>
|
||||
{{ $block->getLabel() }}
|
||||
</x-filament::dropdown.list.item>
|
||||
@endforeach
|
||||
</div>
|
||||
</x-filament::dropdown.list>
|
||||
</x-filament::dropdown>
|
||||
@@ -1,151 +0,0 @@
|
||||
@php
|
||||
use Filament\Support\Enums\GridDirection;
|
||||
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraInputAttributeBag = $getExtraInputAttributeBag();
|
||||
$isHtmlAllowed = $isHtmlAllowed();
|
||||
$gridDirection = $getGridDirection() ?? GridDirection::Column;
|
||||
$isBulkToggleable = $isBulkToggleable();
|
||||
$isDisabled = $isDisabled();
|
||||
$isSearchable = $isSearchable();
|
||||
$statePath = $getStatePath();
|
||||
$options = $getOptions();
|
||||
$livewireKey = $getLivewireKey();
|
||||
$wireModelAttribute = $applyStateBindingModifiers('wire:model');
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<div
|
||||
x-load
|
||||
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('checkbox-list', 'filament/forms') }}"
|
||||
x-data="checkboxListFormComponent({
|
||||
livewireId: @js($this->getId()),
|
||||
})"
|
||||
{{ $getExtraAlpineAttributeBag()->class(['fi-fo-checkbox-list']) }}
|
||||
>
|
||||
@if (! $isDisabled)
|
||||
@if ($isSearchable)
|
||||
<x-filament::input.wrapper
|
||||
inline-prefix
|
||||
:prefix-icon="\Filament\Support\Icons\Heroicon::MagnifyingGlass"
|
||||
:prefix-icon-alias="\Filament\Forms\View\FormsIconAlias::COMPONENTS_CHECKBOX_LIST_SEARCH_FIELD"
|
||||
class="fi-fo-checkbox-list-search-input-wrp"
|
||||
>
|
||||
<input
|
||||
placeholder="{{ $getSearchPrompt() }}"
|
||||
type="search"
|
||||
x-model.debounce.{{ $getSearchDebounce() }}="search"
|
||||
class="fi-input fi-input-has-inline-prefix"
|
||||
/>
|
||||
</x-filament::input.wrapper>
|
||||
@endif
|
||||
|
||||
@if ($isBulkToggleable && count($options))
|
||||
<div
|
||||
x-cloak
|
||||
class="fi-fo-checkbox-list-actions"
|
||||
wire:key="{{ $livewireKey }}.actions"
|
||||
>
|
||||
<span
|
||||
x-show="! areAllCheckboxesChecked"
|
||||
x-on:click="toggleAllCheckboxes()"
|
||||
wire:key="{{ $livewireKey }}.actions.select-all"
|
||||
>
|
||||
{{ $getAction('selectAll') }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
x-show="areAllCheckboxesChecked"
|
||||
x-on:click="toggleAllCheckboxes()"
|
||||
wire:key="{{ $livewireKey }}.actions.deselect-all"
|
||||
>
|
||||
{{ $getAction('deselectAll') }}
|
||||
</span>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<div
|
||||
{{
|
||||
$getExtraAttributeBag()
|
||||
->grid($getColumns(), $gridDirection)
|
||||
->merge([
|
||||
'x-show' => $isSearchable ? 'visibleCheckboxListOptions.length' : null,
|
||||
], escape: false)
|
||||
->class([
|
||||
'fi-fo-checkbox-list-options',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@forelse ($options as $value => $label)
|
||||
<div
|
||||
wire:key="{{ $livewireKey }}.options.{{ $value }}"
|
||||
@if ($isSearchable)
|
||||
x-show="
|
||||
$el
|
||||
.querySelector('.fi-fo-checkbox-list-option-label')
|
||||
?.innerText.toLowerCase()
|
||||
.includes(search.toLowerCase()) ||
|
||||
$el
|
||||
.querySelector('.fi-fo-checkbox-list-option-description')
|
||||
?.innerText.toLowerCase()
|
||||
.includes(search.toLowerCase())
|
||||
"
|
||||
@endif
|
||||
class="fi-fo-checkbox-list-option-ctn"
|
||||
>
|
||||
<label class="fi-fo-checkbox-list-option">
|
||||
<input
|
||||
type="checkbox"
|
||||
{{
|
||||
$extraInputAttributeBag
|
||||
->merge([
|
||||
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
|
||||
'value' => $value,
|
||||
'wire:loading.attr' => 'disabled',
|
||||
$wireModelAttribute => $statePath,
|
||||
'x-on:change' => $isBulkToggleable ? 'checkIfAllCheckboxesAreChecked()' : null,
|
||||
], escape: false)
|
||||
->class([
|
||||
'fi-checkbox-input',
|
||||
'fi-valid' => ! $errors->has($statePath),
|
||||
'fi-invalid' => $errors->has($statePath),
|
||||
])
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="fi-fo-checkbox-list-option-text">
|
||||
<span class="fi-fo-checkbox-list-option-label">
|
||||
@if ($isHtmlAllowed)
|
||||
{!! $label !!}
|
||||
@else
|
||||
{{ $label }}
|
||||
@endif
|
||||
</span>
|
||||
|
||||
@if ($hasDescription($value))
|
||||
<p
|
||||
class="fi-fo-checkbox-list-option-description"
|
||||
>
|
||||
{{ $getDescription($value) }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
@empty
|
||||
<div wire:key="{{ $livewireKey }}.empty"></div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
@if ($isSearchable)
|
||||
<div
|
||||
x-cloak
|
||||
x-show="search && ! visibleCheckboxListOptions.length"
|
||||
class="fi-fo-checkbox-list-no-search-results-message"
|
||||
>
|
||||
{{ $getNoSearchResultsMessage() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,34 +0,0 @@
|
||||
@php
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$statePath = $getStatePath();
|
||||
$attributes = $attributes
|
||||
->merge([
|
||||
'autofocus' => $isAutofocused(),
|
||||
'disabled' => $isDisabled(),
|
||||
'id' => $getId(),
|
||||
'required' => $isRequired() && (! $isConcealed()),
|
||||
'wire:loading.attr' => 'disabled',
|
||||
$applyStateBindingModifiers('wire:model') => $statePath,
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraInputAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-checkbox-input',
|
||||
'fi-valid' => ! $errors->has($statePath),
|
||||
'fi-invalid' => $errors->has($statePath),
|
||||
]);
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$fieldWrapperView"
|
||||
:field="$field"
|
||||
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
|
||||
>
|
||||
@if ($isInline())
|
||||
<x-slot name="labelPrefix">
|
||||
<input type="checkbox" {{ $attributes }} />
|
||||
</x-slot>
|
||||
@else
|
||||
<input type="checkbox" {{ $attributes }} />
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
@@ -1,40 +0,0 @@
|
||||
@php
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraAttributeBag = $getExtraAttributeBag();
|
||||
$isDisabled = $isDisabled();
|
||||
$key = $getKey();
|
||||
$language = $getLanguage();
|
||||
$statePath = $getStatePath();
|
||||
$livewireKey = $getLivewireKey();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
|
||||
->class(['fi-fo-code-editor'])
|
||||
"
|
||||
>
|
||||
<div
|
||||
x-load
|
||||
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('code-editor', 'filament/forms') }}"
|
||||
x-data="codeEditorFormComponent({
|
||||
isDisabled: @js($isDisabled),
|
||||
language: @js($language?->value),
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
})"
|
||||
wire:ignore
|
||||
wire:key="{{ $livewireKey }}.{{
|
||||
substr(md5(serialize([
|
||||
$isDisabled,
|
||||
$language?->value,
|
||||
])), 0, 64)
|
||||
}}"
|
||||
{{ $getExtraAlpineAttributeBag() }}
|
||||
>
|
||||
<div x-ref="editor" x-cloak></div>
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
</x-dynamic-component>
|
||||
@@ -1,115 +0,0 @@
|
||||
@php
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraAttributeBag = $getExtraAttributeBag();
|
||||
$isDisabled = $isDisabled();
|
||||
$isLive = $isLive();
|
||||
$isLiveOnBlur = $isLiveOnBlur();
|
||||
$isLiveDebounced = $isLiveDebounced();
|
||||
$isPrefixInline = $isPrefixInline();
|
||||
$isSuffixInline = $isSuffixInline();
|
||||
$liveDebounce = $getLiveDebounce();
|
||||
$prefixActions = $getPrefixActions();
|
||||
$prefixIcon = $getPrefixIcon();
|
||||
$prefixIconColor = $getPrefixIconColor();
|
||||
$prefixLabel = $getPrefixLabel();
|
||||
$suffixActions = $getSuffixActions();
|
||||
$suffixIcon = $getSuffixIcon();
|
||||
$suffixIconColor = $getSuffixIconColor();
|
||||
$suffixLabel = $getSuffixLabel();
|
||||
$statePath = $getStatePath();
|
||||
$placeholder = $getPlaceholder();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$fieldWrapperView"
|
||||
:field="$field"
|
||||
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
|
||||
>
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:inline-prefix="$isPrefixInline"
|
||||
:inline-suffix="$isSuffixInline"
|
||||
:prefix="$prefixLabel"
|
||||
:prefix-actions="$prefixActions"
|
||||
:prefix-icon="$prefixIcon"
|
||||
:prefix-icon-color="$prefixIconColor"
|
||||
:suffix="$suffixLabel"
|
||||
:suffix-actions="$suffixActions"
|
||||
:suffix-icon="$suffixIcon"
|
||||
:suffix-icon-color="$suffixIconColor"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
|
||||
->class('fi-fo-color-picker')
|
||||
"
|
||||
>
|
||||
<div
|
||||
x-load
|
||||
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('color-picker', 'filament/forms') }}"
|
||||
x-data="colorPickerFormComponent({
|
||||
isAutofocused: @js($isAutofocused()),
|
||||
isDisabled: @js($isDisabled),
|
||||
isLive: @js($isLive),
|
||||
isLiveDebounced: @js($isLiveDebounced),
|
||||
isLiveOnBlur: @js($isLiveOnBlur),
|
||||
liveDebounce: @js($liveDebounce),
|
||||
state: $wire.$entangle('{{ $statePath }}'),
|
||||
})"
|
||||
x-on:keydown.esc="isOpen() && $event.stopPropagation()"
|
||||
{{ $getExtraAlpineAttributeBag()->class(['fi-input-wrp-content']) }}
|
||||
>
|
||||
<input
|
||||
x-on:focus="$refs.panel.open($refs.input)"
|
||||
x-on:keydown.enter.prevent.stop="togglePanelVisibility()"
|
||||
x-ref="input"
|
||||
{{
|
||||
$getExtraInputAttributeBag()
|
||||
->merge([
|
||||
'autocomplete' => 'off',
|
||||
'disabled' => $isDisabled,
|
||||
'id' => $getId(),
|
||||
'placeholder' => filled($placeholder) ? e($placeholder) : null,
|
||||
'required' => $isRequired() && (! $isConcealed()),
|
||||
'type' => 'text',
|
||||
'x-model' . ($isLiveDebounced ? '.debounce.' . $liveDebounce : null) => 'state',
|
||||
'x-on:blur' => $isLiveOnBlur ? 'isOpen() ? null : commitState()' : null,
|
||||
], escape: false)
|
||||
->class([
|
||||
'fi-input',
|
||||
'fi-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
|
||||
'fi-input-has-inline-suffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
|
||||
])
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
class="fi-fo-color-picker-preview my-auto me-3 size-5 shrink-0 rounded-full select-none"
|
||||
x-on:click="togglePanelVisibility()"
|
||||
x-bind:class="{
|
||||
'fi-empty': ! state,
|
||||
}"
|
||||
x-bind:style="{ 'background-color': state }"
|
||||
></div>
|
||||
|
||||
<div
|
||||
wire:ignore.self
|
||||
wire:key="{{ $getLivewireKey() }}.panel"
|
||||
x-cloak
|
||||
x-float.placement.bottom-start.offset.flip.shift="{ offset: 8 }"
|
||||
x-ref="panel"
|
||||
class="fi-fo-color-picker-panel"
|
||||
>
|
||||
@php
|
||||
$tag = match ($getFormat()) {
|
||||
'hsl' => 'hsl-string',
|
||||
'rgb' => 'rgb-string',
|
||||
'rgba' => 'rgba-string',
|
||||
default => 'hex',
|
||||
} . '-color-picker';
|
||||
@endphp
|
||||
|
||||
<{{ $tag }} color="{{ $getState() }}" />
|
||||
</div>
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
</x-dynamic-component>
|
||||
@@ -1,294 +0,0 @@
|
||||
@php
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$datalistOptions = $getDatalistOptions();
|
||||
$disabledDates = $getDisabledDates();
|
||||
$extraAlpineAttributes = $getExtraAlpineAttributes();
|
||||
$extraAttributeBag = $getExtraAttributeBag();
|
||||
$extraInputAttributeBag = $getExtraInputAttributeBag();
|
||||
$hasDate = $hasDate();
|
||||
$hasTime = $hasTime();
|
||||
$hasSeconds = $hasSeconds();
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isAutofocused = $isAutofocused();
|
||||
$isPrefixInline = $isPrefixInline();
|
||||
$isSuffixInline = $isSuffixInline();
|
||||
$maxDate = $getMaxDate();
|
||||
$minDate = $getMinDate();
|
||||
$prefixActions = $getPrefixActions();
|
||||
$prefixIcon = $getPrefixIcon();
|
||||
$prefixIconColor = $getPrefixIconColor();
|
||||
$prefixLabel = $getPrefixLabel();
|
||||
$suffixActions = $getSuffixActions();
|
||||
$suffixIcon = $getSuffixIcon();
|
||||
$suffixIconColor = $getSuffixIconColor();
|
||||
$suffixLabel = $getSuffixLabel();
|
||||
$statePath = $getStatePath();
|
||||
$placeholder = $getPlaceholder();
|
||||
$isReadOnly = $isReadOnly();
|
||||
$isRequired = $isRequired();
|
||||
$isConcealed = $isConcealed();
|
||||
$step = $getStep();
|
||||
$type = $getType();
|
||||
$livewireKey = $getLivewireKey();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$fieldWrapperView"
|
||||
:field="$field"
|
||||
:inline-label-vertical-alignment="\Filament\Support\Enums\VerticalAlignment::Center"
|
||||
>
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:inline-prefix="$isPrefixInline"
|
||||
:inline-suffix="$isSuffixInline"
|
||||
:prefix="$prefixLabel"
|
||||
:prefix-actions="$prefixActions"
|
||||
:prefix-icon="$prefixIcon"
|
||||
:prefix-icon-color="$prefixIconColor"
|
||||
:suffix="$suffixLabel"
|
||||
:suffix-actions="$suffixActions"
|
||||
:suffix-icon="$suffixIcon"
|
||||
:suffix-icon-color="$suffixIconColor"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="\Filament\Support\prepare_inherited_attributes($extraAttributeBag)->class(['fi-fo-date-time-picker'])"
|
||||
>
|
||||
@if ($isNative())
|
||||
<input
|
||||
{{
|
||||
$extraInputAttributeBag
|
||||
->merge($extraAlpineAttributes, escape: false)
|
||||
->merge([
|
||||
'autofocus' => $isAutofocused,
|
||||
'disabled' => $isDisabled,
|
||||
'id' => $id,
|
||||
'list' => $datalistOptions ? $id . '-list' : null,
|
||||
'max' => $hasTime ? $maxDate : ($maxDate ? \Carbon\Carbon::parse($maxDate)->toDateString() : null),
|
||||
'min' => $hasTime ? $minDate : ($minDate ? \Carbon\Carbon::parse($minDate)->toDateString() : null),
|
||||
'placeholder' => filled($placeholder) ? e($placeholder) : null,
|
||||
'readonly' => $isReadOnly,
|
||||
'required' => $isRequired && (! $isConcealed),
|
||||
'step' => $step,
|
||||
'type' => $type,
|
||||
$applyStateBindingModifiers('wire:model') => $statePath,
|
||||
'x-data' => count($extraAlpineAttributes) ? '{}' : null,
|
||||
], escape: false)
|
||||
->class([
|
||||
'fi-input',
|
||||
'fi-input-has-inline-prefix' => $isPrefixInline && (count($prefixActions) || $prefixIcon || filled($prefixLabel)),
|
||||
'fi-input-has-inline-suffix' => $isSuffixInline && (count($suffixActions) || $suffixIcon || filled($suffixLabel)),
|
||||
])
|
||||
}}
|
||||
/>
|
||||
@else
|
||||
<div
|
||||
x-load
|
||||
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('date-time-picker', 'filament/forms') }}"
|
||||
x-data="dateTimePickerFormComponent({
|
||||
defaultFocusedDate: @js($defaultFocusedDate),
|
||||
displayFormat:
|
||||
'{{ convert_date_format($getDisplayFormat())->to('day.js') }}',
|
||||
firstDayOfWeek: {{ $getFirstDayOfWeek() }},
|
||||
isAutofocused: @js($isAutofocused),
|
||||
locale: @js($getLocale()),
|
||||
shouldCloseOnDateSelection: @js($shouldCloseOnDateSelection()),
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
})"
|
||||
wire:ignore
|
||||
wire:key="{{ $livewireKey }}.{{
|
||||
substr(md5(serialize([
|
||||
$disabledDates,
|
||||
$isDisabled,
|
||||
$isReadOnly,
|
||||
$maxDate,
|
||||
$minDate,
|
||||
$hasDate,
|
||||
$hasTime,
|
||||
$hasSeconds,
|
||||
])), 0, 64)
|
||||
}}"
|
||||
x-on:keydown.esc="isOpen() && $event.stopPropagation()"
|
||||
{{ $getExtraAlpineAttributeBag() }}
|
||||
>
|
||||
<input x-ref="maxDate" type="hidden" value="{{ $maxDate }}" />
|
||||
|
||||
<input x-ref="minDate" type="hidden" value="{{ $minDate }}" />
|
||||
|
||||
<input
|
||||
x-ref="disabledDates"
|
||||
type="hidden"
|
||||
value="{{ json_encode($disabledDates) }}"
|
||||
/>
|
||||
|
||||
<button
|
||||
x-ref="button"
|
||||
x-on:click="togglePanelVisibility()"
|
||||
x-on:keydown.enter.prevent.stop="
|
||||
if (! $el.disabled) {
|
||||
isOpen() ? selectDate() : togglePanelVisibility()
|
||||
}
|
||||
"
|
||||
x-on:keydown.arrow-left.prevent.stop="if (! $el.disabled) focusPreviousDay()"
|
||||
x-on:keydown.arrow-right.prevent.stop="if (! $el.disabled) focusNextDay()"
|
||||
x-on:keydown.arrow-up.prevent.stop="if (! $el.disabled) focusPreviousWeek()"
|
||||
x-on:keydown.arrow-down.prevent.stop="if (! $el.disabled) focusNextWeek()"
|
||||
x-on:keydown.backspace.prevent.stop="if (! $el.disabled) clearState()"
|
||||
x-on:keydown.clear.prevent.stop="if (! $el.disabled) clearState()"
|
||||
x-on:keydown.delete.prevent.stop="if (! $el.disabled) clearState()"
|
||||
aria-label="{{ $placeholder }}"
|
||||
type="button"
|
||||
tabindex="-1"
|
||||
@disabled($isDisabled || $isReadOnly)
|
||||
{{
|
||||
$getExtraTriggerAttributeBag()->class([
|
||||
'fi-fo-date-time-picker-trigger',
|
||||
])
|
||||
}}
|
||||
>
|
||||
<input
|
||||
@disabled($isDisabled)
|
||||
readonly
|
||||
placeholder="{{ $placeholder }}"
|
||||
wire:key="{{ $livewireKey }}.display-text"
|
||||
x-model="displayText"
|
||||
@if ($id = $getId()) id="{{ $id }}" @endif
|
||||
@class([
|
||||
'fi-fo-date-time-picker-display-text-input',
|
||||
])
|
||||
/>
|
||||
</button>
|
||||
|
||||
<div
|
||||
x-ref="panel"
|
||||
x-cloak
|
||||
x-float.placement.bottom-start.offset.flip.shift="{ offset: 8 }"
|
||||
wire:ignore
|
||||
wire:key="{{ $livewireKey }}.panel"
|
||||
@class([
|
||||
'fi-fo-date-time-picker-panel',
|
||||
])
|
||||
>
|
||||
@if ($hasDate)
|
||||
<div class="fi-fo-date-time-picker-panel-header">
|
||||
<select
|
||||
x-model="focusedMonth"
|
||||
class="fi-fo-date-time-picker-month-select"
|
||||
>
|
||||
<template x-for="(month, index) in months">
|
||||
<option
|
||||
x-bind:value="index"
|
||||
x-text="month"
|
||||
></option>
|
||||
</template>
|
||||
</select>
|
||||
|
||||
<input
|
||||
type="number"
|
||||
inputmode="numeric"
|
||||
x-model.debounce="focusedYear"
|
||||
class="fi-fo-date-time-picker-year-input"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="fi-fo-date-time-picker-calendar-header">
|
||||
<template
|
||||
x-for="(day, index) in dayLabels"
|
||||
x-bind:key="index"
|
||||
>
|
||||
<div
|
||||
x-text="day"
|
||||
class="fi-fo-date-time-picker-calendar-header-day"
|
||||
></div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div
|
||||
role="grid"
|
||||
class="fi-fo-date-time-picker-calendar"
|
||||
>
|
||||
<template
|
||||
x-for="day in emptyDaysInFocusedMonth"
|
||||
x-bind:key="day"
|
||||
>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<template
|
||||
x-for="day in daysInFocusedMonth"
|
||||
x-bind:key="day"
|
||||
>
|
||||
<div
|
||||
x-text="day"
|
||||
x-on:click="dayIsDisabled(day) || selectDate(day)"
|
||||
x-on:mouseenter="setFocusedDay(day)"
|
||||
role="option"
|
||||
x-bind:aria-selected="focusedDate.date() === day"
|
||||
x-bind:class="{
|
||||
'fi-fo-date-time-picker-calendar-day-today': dayIsToday(day),
|
||||
'fi-focused': focusedDate.date() === day,
|
||||
'fi-selected': dayIsSelected(day),
|
||||
'fi-disabled': dayIsDisabled(day),
|
||||
}"
|
||||
class="fi-fo-date-time-picker-calendar-day"
|
||||
></div>
|
||||
</template>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($hasTime)
|
||||
<div class="fi-fo-date-time-picker-time-inputs">
|
||||
<input
|
||||
max="23"
|
||||
min="0"
|
||||
step="{{ $getHoursStep() }}"
|
||||
type="number"
|
||||
inputmode="numeric"
|
||||
x-model.debounce="hour"
|
||||
/>
|
||||
|
||||
<span
|
||||
class="fi-fo-date-time-picker-time-input-separator"
|
||||
>
|
||||
:
|
||||
</span>
|
||||
|
||||
<input
|
||||
max="59"
|
||||
min="0"
|
||||
step="{{ $getMinutesStep() }}"
|
||||
type="number"
|
||||
inputmode="numeric"
|
||||
x-model.debounce="minute"
|
||||
/>
|
||||
|
||||
@if ($hasSeconds)
|
||||
<span
|
||||
class="fi-fo-date-time-picker-time-input-separator"
|
||||
>
|
||||
:
|
||||
</span>
|
||||
|
||||
<input
|
||||
max="59"
|
||||
min="0"
|
||||
step="{{ $getSecondsStep() }}"
|
||||
type="number"
|
||||
inputmode="numeric"
|
||||
x-model.debounce="second"
|
||||
/>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</x-filament::input.wrapper>
|
||||
|
||||
@if ($datalistOptions)
|
||||
<datalist id="{{ $id }}-list">
|
||||
@foreach ($datalistOptions as $option)
|
||||
<option value="{{ $option }}" />
|
||||
@endforeach
|
||||
</datalist>
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
@@ -1,197 +0,0 @@
|
||||
@php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'areHtmlErrorMessagesAllowed' => null,
|
||||
'errorMessage' => null,
|
||||
'errorMessages' => null,
|
||||
'field' => null,
|
||||
'hasErrors' => true,
|
||||
'hasInlineLabel' => null,
|
||||
'hasNestedRecursiveValidationRules' => null,
|
||||
'id' => null,
|
||||
'inlineLabelVerticalAlignment' => VerticalAlignment::Start,
|
||||
'isDisabled' => null,
|
||||
'label' => null,
|
||||
'labelPrefix' => null,
|
||||
'labelSrOnly' => null,
|
||||
'labelSuffix' => null,
|
||||
'labelTag' => 'label',
|
||||
'required' => null,
|
||||
'shouldShowAllValidationMessages' => null,
|
||||
'statePath' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
if ($field) {
|
||||
$hasInlineLabel ??= $field->hasInlineLabel();
|
||||
$hasNestedRecursiveValidationRules ??= $field instanceof \Filament\Forms\Components\Contracts\HasNestedRecursiveValidationRules;
|
||||
$id ??= $field->getId();
|
||||
$isDisabled ??= $field->isDisabled();
|
||||
$label ??= $field->getLabel();
|
||||
$labelSrOnly ??= $field->isLabelHidden();
|
||||
$required ??= $field->isMarkedAsRequired();
|
||||
$statePath ??= $field->getStatePath();
|
||||
$areHtmlErrorMessagesAllowed ??= $field->areHtmlValidationMessagesAllowed();
|
||||
$shouldShowAllValidationMessages ??= $field->shouldShowAllValidationMessages();
|
||||
}
|
||||
|
||||
$aboveLabelSchema = $field?->getChildSchema($field::ABOVE_LABEL_SCHEMA_KEY)?->toHtmlString();
|
||||
$belowLabelSchema = $field?->getChildSchema($field::BELOW_LABEL_SCHEMA_KEY)?->toHtmlString();
|
||||
$beforeLabelSchema = $field?->getChildSchema($field::BEFORE_LABEL_SCHEMA_KEY)?->toHtmlString();
|
||||
$afterLabelSchema = $field?->getChildSchema($field::AFTER_LABEL_SCHEMA_KEY)?->toHtmlString();
|
||||
$aboveContentSchema = $field?->getChildSchema($field::ABOVE_CONTENT_SCHEMA_KEY)?->toHtmlString();
|
||||
$belowContentSchema = $field?->getChildSchema($field::BELOW_CONTENT_SCHEMA_KEY)?->toHtmlString();
|
||||
$beforeContentSchema = $field?->getChildSchema($field::BEFORE_CONTENT_SCHEMA_KEY)?->toHtmlString();
|
||||
$afterContentSchema = $field?->getChildSchema($field::AFTER_CONTENT_SCHEMA_KEY)?->toHtmlString();
|
||||
$aboveErrorMessageSchema = $field?->getChildSchema($field::ABOVE_ERROR_MESSAGE_SCHEMA_KEY)?->toHtmlString();
|
||||
$belowErrorMessageSchema = $field?->getChildSchema($field::BELOW_ERROR_MESSAGE_SCHEMA_KEY)?->toHtmlString();
|
||||
|
||||
$hasError = $hasErrors && (filled($errorMessage) || filled($errorMessages) || (filled($statePath) && ($errors->has($statePath) || ($hasNestedRecursiveValidationRules && $errors->has("{$statePath}.*")))));
|
||||
|
||||
if ($hasError && filled($statePath) && blank($errorMessage) && blank($errorMessages)) {
|
||||
if ($shouldShowAllValidationMessages) {
|
||||
$errorMessages = $errors->has($statePath) ? $errors->get($statePath) : ($hasNestedRecursiveValidationRules ? $errors->get("{$statePath}.*") : []);
|
||||
|
||||
if (count($errorMessages) === 1) {
|
||||
$errorMessage = Arr::first($errorMessages);
|
||||
$errorMessages = [];
|
||||
}
|
||||
} else {
|
||||
$errorMessage = $errors->has($statePath) ? $errors->first($statePath) : ($hasNestedRecursiveValidationRules ? $errors->first("{$statePath}.*") : null);
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div
|
||||
data-field-wrapper
|
||||
{{
|
||||
$attributes
|
||||
->merge($field?->getExtraFieldWrapperAttributes() ?? [], escape: false)
|
||||
->class([
|
||||
'fi-fo-field',
|
||||
'fi-fo-field-has-inline-label' => $hasInlineLabel,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (filled($label) && $labelSrOnly)
|
||||
<{{ $labelTag }}
|
||||
@if ($labelTag === 'label')
|
||||
for="{{ $id }}"
|
||||
@else
|
||||
id="{{ $id }}-label"
|
||||
@endif
|
||||
class="fi-fo-field-label fi-sr-only"
|
||||
>
|
||||
{{ $label }}
|
||||
</{{ $labelTag }}>
|
||||
@endif
|
||||
|
||||
@if ((filled($label) && (! $labelSrOnly)) || $hasInlineLabel || $aboveLabelSchema || $belowLabelSchema || $beforeLabelSchema || $afterLabelSchema || $labelPrefix || $labelSuffix)
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-field-label-col',
|
||||
"fi-vertical-align-{$inlineLabelVerticalAlignment->value}" => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
{{ $aboveLabelSchema }}
|
||||
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-field-label-ctn',
|
||||
($label instanceof \Illuminate\View\ComponentSlot) ? $label->attributes->get('class') : null,
|
||||
])
|
||||
>
|
||||
{{ $beforeLabelSchema }}
|
||||
|
||||
@if ((filled($label) && (! $labelSrOnly)) || $labelPrefix || $labelSuffix)
|
||||
<{{ $labelTag }}
|
||||
@if ($labelTag === 'label')
|
||||
for="{{ $id }}"
|
||||
@else
|
||||
id="{{ $id }}-label"
|
||||
@endif
|
||||
class="fi-fo-field-label"
|
||||
>
|
||||
{{ $labelPrefix }}
|
||||
|
||||
@if (filled($label) && (! $labelSrOnly))
|
||||
<span class="fi-fo-field-label-content">
|
||||
{{ $label }}@if ($required && (! $isDisabled))<sup class="fi-fo-field-label-required-mark">*</sup>
|
||||
@endif
|
||||
</span>
|
||||
@endif
|
||||
|
||||
{{ $labelSuffix }}
|
||||
</{{ $labelTag }}>
|
||||
@endif
|
||||
|
||||
{{ $afterLabelSchema }}
|
||||
</div>
|
||||
|
||||
{{ $belowLabelSchema }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ((! \Filament\Support\is_slot_empty($slot)) || $hasError || $aboveContentSchema || $belowContentSchema || $beforeContentSchema || $afterContentSchema || $aboveErrorMessageSchema || $belowErrorMessageSchema)
|
||||
<div class="fi-fo-field-content-col">
|
||||
{{ $aboveContentSchema }}
|
||||
|
||||
@if ($beforeContentSchema || $afterContentSchema)
|
||||
<div class="fi-fo-field-content-ctn">
|
||||
{{ $beforeContentSchema }}
|
||||
|
||||
<div class="fi-fo-field-content">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
|
||||
{{ $afterContentSchema }}
|
||||
</div>
|
||||
@else
|
||||
{{ $slot }}
|
||||
@endif
|
||||
|
||||
{{ $belowContentSchema }}
|
||||
|
||||
@if ($hasError)
|
||||
{{ $aboveErrorMessageSchema }}
|
||||
|
||||
@if (filled($errorMessages))
|
||||
<ul
|
||||
data-validation-error
|
||||
class="fi-fo-field-wrp-error-list"
|
||||
>
|
||||
@foreach ($errorMessages as $errorMessage)
|
||||
<li class="fi-fo-field-wrp-error-message">
|
||||
@if ($areHtmlErrorMessagesAllowed)
|
||||
{!! $errorMessage !!}
|
||||
@else
|
||||
{{ $errorMessage }}
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@elseif ($areHtmlErrorMessagesAllowed)
|
||||
<div
|
||||
data-validation-error
|
||||
class="fi-fo-field-wrp-error-message"
|
||||
>
|
||||
{!! $errorMessage !!}
|
||||
</div>
|
||||
@else
|
||||
<p
|
||||
data-validation-error
|
||||
class="fi-fo-field-wrp-error-message"
|
||||
>
|
||||
{{ $errorMessage }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
{{ $belowErrorMessageSchema }}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@@ -1,344 +0,0 @@
|
||||
@php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$id = $getId();
|
||||
$imageCropAspectRatio = $getImageCropAspectRatio();
|
||||
$imageResizeTargetHeight = $getImageResizeTargetHeight();
|
||||
$imageResizeTargetWidth = $getImageResizeTargetWidth();
|
||||
$isAvatar = $isAvatar();
|
||||
$isMultiple = $isMultiple();
|
||||
$key = $getKey();
|
||||
$statePath = $getStatePath();
|
||||
$isDisabled = $isDisabled();
|
||||
$hasImageEditor = $hasImageEditor();
|
||||
$hasCircleCropper = $hasCircleCropper();
|
||||
$livewireKey = $getLivewireKey();
|
||||
|
||||
$alignment = $getAlignment() ?? Alignment::Start;
|
||||
|
||||
if (! $alignment instanceof Alignment) {
|
||||
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
|
||||
}
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$fieldWrapperView"
|
||||
:field="$field"
|
||||
label-tag="div"
|
||||
>
|
||||
<div
|
||||
x-load
|
||||
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('file-upload', 'filament/forms') }}"
|
||||
x-data="fileUploadFormComponent({
|
||||
acceptedFileTypes: @js($getAcceptedFileTypes()),
|
||||
imageEditorEmptyFillColor: @js($getImageEditorEmptyFillColor()),
|
||||
imageEditorMode: @js($getImageEditorMode()),
|
||||
imageEditorViewportHeight: @js($getImageEditorViewportHeight()),
|
||||
imageEditorViewportWidth: @js($getImageEditorViewportWidth()),
|
||||
deleteUploadedFileUsing: async (fileKey) => {
|
||||
return await $wire.callSchemaComponentMethod(
|
||||
@js($key),
|
||||
'deleteUploadedFile',
|
||||
{ fileKey },
|
||||
)
|
||||
},
|
||||
getUploadedFilesUsing: async () => {
|
||||
return await $wire.callSchemaComponentMethod(
|
||||
@js($key),
|
||||
'getUploadedFiles',
|
||||
)
|
||||
},
|
||||
hasImageEditor: @js($hasImageEditor),
|
||||
hasCircleCropper: @js($hasCircleCropper),
|
||||
canEditSvgs: @js($canEditSvgs()),
|
||||
isSvgEditingConfirmed: @js($isSvgEditingConfirmed()),
|
||||
confirmSvgEditingMessage: @js(__('filament-forms::components.file_upload.editor.svg.messages.confirmation')),
|
||||
disabledSvgEditingMessage: @js(__('filament-forms::components.file_upload.editor.svg.messages.disabled')),
|
||||
imageCropAspectRatio: @js($imageCropAspectRatio),
|
||||
imagePreviewHeight: @js($getImagePreviewHeight()),
|
||||
imageResizeMode: @js($getImageResizeMode()),
|
||||
imageResizeTargetHeight: @js($imageResizeTargetHeight),
|
||||
imageResizeTargetWidth: @js($imageResizeTargetWidth),
|
||||
imageResizeUpscale: @js($getImageResizeUpscale()),
|
||||
isAvatar: @js($isAvatar),
|
||||
isDeletable: @js($isDeletable()),
|
||||
isDisabled: @js($isDisabled),
|
||||
isDownloadable: @js($isDownloadable()),
|
||||
isMultiple: @js($isMultiple),
|
||||
isOpenable: @js($isOpenable()),
|
||||
isPasteable: @js($isPasteable()),
|
||||
isPreviewable: @js($isPreviewable()),
|
||||
isReorderable: @js($isReorderable()),
|
||||
itemPanelAspectRatio: @js($getItemPanelAspectRatio()),
|
||||
loadingIndicatorPosition: @js($getLoadingIndicatorPosition()),
|
||||
locale: @js(app()->getLocale()),
|
||||
panelAspectRatio: @js($getPanelAspectRatio()),
|
||||
panelLayout: @js($getPanelLayout()),
|
||||
placeholder: @js($getPlaceholder()),
|
||||
maxFiles: @js($maxFiles = $getMaxFiles()),
|
||||
maxFilesValidationMessage: @js($maxFiles ? trans_choice('validation.max.array', $maxFiles, ['attribute' => $getValidationAttribute(), 'max' => $maxFiles]) : null),
|
||||
maxSize: @js(($size = $getMaxSize()) ? "{$size}KB" : null),
|
||||
minSize: @js(($size = $getMinSize()) ? "{$size}KB" : null),
|
||||
mimeTypeMap: @js($getMimeTypeMap()),
|
||||
maxParallelUploads: @js($getMaxParallelUploads()),
|
||||
removeUploadedFileUsing: async (fileKey) => {
|
||||
return await $wire.callSchemaComponentMethod(
|
||||
@js($key),
|
||||
'removeUploadedFile',
|
||||
{ fileKey },
|
||||
)
|
||||
},
|
||||
removeUploadedFileButtonPosition: @js($getRemoveUploadedFileButtonPosition()),
|
||||
reorderUploadedFilesUsing: async (fileKeys) => {
|
||||
return await $wire.callSchemaComponentMethod(
|
||||
@js($key),
|
||||
'reorderUploadedFiles',
|
||||
{ fileKeys },
|
||||
)
|
||||
},
|
||||
shouldAppendFiles: @js($shouldAppendFiles()),
|
||||
shouldOrientImageFromExif: @js($shouldOrientImagesFromExif()),
|
||||
shouldTransformImage: @js($imageCropAspectRatio || $imageResizeTargetHeight || $imageResizeTargetWidth),
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
uploadButtonPosition: @js($getUploadButtonPosition()),
|
||||
uploadingMessage: @js($getUploadingMessage()),
|
||||
uploadProgressIndicatorPosition: @js($getUploadProgressIndicatorPosition()),
|
||||
uploadUsing: (fileKey, file, success, error, progress) => {
|
||||
$wire.upload(
|
||||
`{{ $statePath }}.${fileKey}`,
|
||||
file,
|
||||
() => {
|
||||
success(fileKey)
|
||||
},
|
||||
error,
|
||||
(progressEvent) => {
|
||||
progress(true, progressEvent.detail.progress, 100)
|
||||
},
|
||||
)
|
||||
},
|
||||
})"
|
||||
wire:ignore
|
||||
wire:key="{{ $livewireKey }}.{{
|
||||
substr(md5(serialize([
|
||||
$isDisabled,
|
||||
])), 0, 64)
|
||||
}}"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'aria-labelledby' => "{$id}-label",
|
||||
'id' => $id,
|
||||
'role' => 'group',
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-file-upload',
|
||||
'fi-fo-file-upload-avatar' => $isAvatar,
|
||||
($alignment instanceof Alignment) ? "fi-align-{$alignment->value}" : $alignment,
|
||||
])
|
||||
}}
|
||||
>
|
||||
<div class="fi-fo-file-upload-input-ctn">
|
||||
<input
|
||||
x-ref="input"
|
||||
{{
|
||||
$getExtraInputAttributeBag()
|
||||
->merge([
|
||||
'aria-labelledby' => "{$id}-label",
|
||||
'disabled' => $isDisabled,
|
||||
'multiple' => $isMultiple,
|
||||
'type' => 'file',
|
||||
], escape: false)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
x-show="error"
|
||||
x-text="error"
|
||||
x-cloak
|
||||
class="fi-fo-file-upload-error-message"
|
||||
></div>
|
||||
|
||||
@if ($hasImageEditor && (! $isDisabled))
|
||||
<div
|
||||
x-show="isEditorOpen"
|
||||
x-cloak
|
||||
x-on:click.stop=""
|
||||
x-trap.noscroll="isEditorOpen"
|
||||
x-on:keydown.escape.prevent.stop="closeEditor"
|
||||
@class([
|
||||
'fi-fo-file-upload-editor',
|
||||
'fi-fo-file-upload-editor-circle-cropper' => $hasCircleCropper,
|
||||
])
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fi-fo-file-upload-editor-overlay"
|
||||
></div>
|
||||
|
||||
<div class="fi-fo-file-upload-editor-window">
|
||||
<div class="fi-fo-file-upload-editor-image-ctn">
|
||||
<img
|
||||
x-ref="editor"
|
||||
class="fi-fo-file-upload-editor-image"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="fi-fo-file-upload-editor-control-panel">
|
||||
<div
|
||||
class="fi-fo-file-upload-editor-control-panel-main"
|
||||
>
|
||||
<div
|
||||
class="fi-fo-file-upload-editor-control-panel-group"
|
||||
>
|
||||
@foreach ([
|
||||
[
|
||||
'label' => __('filament-forms::components.file_upload.editor.fields.x_position.label'),
|
||||
'ref' => 'xPositionInput',
|
||||
'unit' => __('filament-forms::components.file_upload.editor.fields.x_position.unit'),
|
||||
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), x: +$el.value})',
|
||||
],
|
||||
[
|
||||
'label' => __('filament-forms::components.file_upload.editor.fields.y_position.label'),
|
||||
'ref' => 'yPositionInput',
|
||||
'unit' => __('filament-forms::components.file_upload.editor.fields.y_position.unit'),
|
||||
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), y: +$el.value})',
|
||||
],
|
||||
[
|
||||
'label' => __('filament-forms::components.file_upload.editor.fields.width.label'),
|
||||
'ref' => 'widthInput',
|
||||
'unit' => __('filament-forms::components.file_upload.editor.fields.width.unit'),
|
||||
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), width: +$el.value})',
|
||||
],
|
||||
[
|
||||
'label' => __('filament-forms::components.file_upload.editor.fields.height.label'),
|
||||
'ref' => 'heightInput',
|
||||
'unit' => __('filament-forms::components.file_upload.editor.fields.height.unit'),
|
||||
'alpineSaveHandler' => 'editor.setData({...editor.getData(true), height: +$el.value})',
|
||||
],
|
||||
[
|
||||
'label' => __('filament-forms::components.file_upload.editor.fields.rotation.label'),
|
||||
'ref' => 'rotationInput',
|
||||
'unit' => __('filament-forms::components.file_upload.editor.fields.rotation.unit'),
|
||||
'alpineSaveHandler' => 'editor.rotateTo(+$el.value)',
|
||||
],
|
||||
] as $input)
|
||||
<label>
|
||||
<x-filament::input.wrapper>
|
||||
<x-slot name="prefix">
|
||||
{{ $input['label'] }}
|
||||
</x-slot>
|
||||
|
||||
<input
|
||||
x-on:keyup.enter.prevent.stop="editor && {!! $input['alpineSaveHandler'] !!}"
|
||||
x-on:blur="editor && {!! $input['alpineSaveHandler'] !!}"
|
||||
x-ref="{{ $input['ref'] }}"
|
||||
x-on:keydown.enter.prevent
|
||||
type="text"
|
||||
class="fi-input"
|
||||
/>
|
||||
|
||||
<x-slot name="suffix">
|
||||
{{ $input['unit'] }}
|
||||
</x-slot>
|
||||
</x-filament::input.wrapper>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="fi-fo-file-upload-editor-control-panel-group"
|
||||
>
|
||||
@foreach ($getImageEditorActions() as $groupedActions)
|
||||
<div class="fi-btn-group">
|
||||
@foreach ($groupedActions as $action)
|
||||
<button
|
||||
aria-label="{{ $action['label'] }}"
|
||||
type="button"
|
||||
x-on:click.prevent.stop="{{ $action['alpineClickHandler'] }}"
|
||||
x-tooltip="{ content: @js($action['label']), theme: $store.theme }"
|
||||
class="fi-btn"
|
||||
>
|
||||
{{ $action['iconHtml'] }}
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@if (count($aspectRatios = $getImageEditorAspectRatiosForJs()))
|
||||
<div
|
||||
class="fi-fo-file-upload-editor-control-panel-group"
|
||||
>
|
||||
<div
|
||||
class="fi-fo-file-upload-editor-control-panel-group-title"
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.aspect_ratios.label') }}
|
||||
</div>
|
||||
|
||||
@foreach (collect($aspectRatios)->chunk(5) as $ratiosChunk)
|
||||
<div class="fi-btn-group">
|
||||
@foreach ($ratiosChunk as $label => $ratio)
|
||||
<button
|
||||
type="button"
|
||||
x-on:click.prevent.stop="
|
||||
currentRatio = @js($label) {!! ';' !!}
|
||||
editor.setAspectRatio(@js($ratio))
|
||||
"
|
||||
x-tooltip="{ content: @js(__('filament-forms::components.file_upload.editor.actions.set_aspect_ratio.label', ['ratio' => $label])), theme: $store.theme }"
|
||||
x-bind:class="{ 'fi-active': currentRatio === @js($label) }"
|
||||
class="fi-btn"
|
||||
>
|
||||
{{ $label }}
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="fi-fo-file-upload-editor-control-panel-footer"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
x-on:click.prevent="pond.imageEditEditor.oncancel"
|
||||
class="fi-btn"
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.actions.cancel.label') }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
x-on:click.prevent.stop="editor.reset()"
|
||||
{{
|
||||
(new \Illuminate\View\ComponentAttributeBag)
|
||||
->color(\Filament\Support\View\Components\ButtonComponent::class, 'danger')
|
||||
->class(['fi-btn fi-fo-file-upload-editor-control-panel-reset-action'])
|
||||
}}
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.actions.reset.label') }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
x-on:click.prevent="saveEditor"
|
||||
{{
|
||||
(new \Illuminate\View\ComponentAttributeBag)
|
||||
->color(\Filament\Support\View\Components\ButtonComponent::class, 'success')
|
||||
->class(['fi-btn'])
|
||||
}}
|
||||
>
|
||||
{{ __('filament-forms::components.file_upload.editor.actions.save.label') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,12 +0,0 @@
|
||||
<input
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
'type' => 'hidden',
|
||||
$applyStateBindingModifiers('wire:model') => $getStatePath(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-hidden'])
|
||||
}}
|
||||
/>
|
||||
@@ -1,148 +0,0 @@
|
||||
@php
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraAttributeBag = $getExtraAttributeBag();
|
||||
$canEditKeys = $canEditKeys();
|
||||
$canEditValues = $canEditValues();
|
||||
$keyPlaceholder = $getKeyPlaceholder();
|
||||
$valuePlaceholder = $getValuePlaceholder();
|
||||
$debounce = $getLiveDebounce();
|
||||
$isAddable = $isAddable();
|
||||
$isDeletable = $isDeletable();
|
||||
$isDisabled = $isDisabled();
|
||||
$isReorderable = $isReorderable();
|
||||
$statePath = $getStatePath();
|
||||
$livewireKey = $getLivewireKey();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component
|
||||
:component="$fieldWrapperView"
|
||||
:field="$field"
|
||||
class="fi-fo-key-value-wrp"
|
||||
>
|
||||
<x-filament::input.wrapper
|
||||
:disabled="$isDisabled"
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
|
||||
->class(['fi-fo-key-value'])
|
||||
"
|
||||
>
|
||||
<div
|
||||
x-load
|
||||
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('key-value', 'filament/forms') }}"
|
||||
x-data="keyValueFormComponent({
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')") }},
|
||||
})"
|
||||
wire:ignore
|
||||
wire:key="{{ $livewireKey }}.{{
|
||||
substr(md5(serialize([
|
||||
$isDisabled,
|
||||
])), 0, 64)
|
||||
}}"
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class(['fi-fo-key-value-table-ctn'])
|
||||
}}
|
||||
>
|
||||
<table class="fi-fo-key-value-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@if ($isReorderable && (! $isDisabled))
|
||||
<th
|
||||
scope="col"
|
||||
x-show="rows.length"
|
||||
class="fi-has-action"
|
||||
></th>
|
||||
@endif
|
||||
|
||||
<th scope="col">
|
||||
{{ $getKeyLabel() }}
|
||||
</th>
|
||||
|
||||
<th scope="col">
|
||||
{{ $getValueLabel() }}
|
||||
</th>
|
||||
|
||||
@if ($isDeletable && (! $isDisabled))
|
||||
<th
|
||||
scope="col"
|
||||
x-show="rows.length"
|
||||
class="fi-has-action"
|
||||
></th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody
|
||||
@if ($isReorderable)
|
||||
x-on:end.stop="reorderRows($event)"
|
||||
x-sortable
|
||||
data-sortable-animation-duration="{{ $getReorderAnimationDuration() }}"
|
||||
@endif
|
||||
>
|
||||
<template
|
||||
x-bind:key="index"
|
||||
x-for="(row, index) in rows"
|
||||
>
|
||||
<tr
|
||||
@if ($isReorderable)
|
||||
x-bind:x-sortable-item="row.key"
|
||||
@endif
|
||||
>
|
||||
@if ($isReorderable && (! $isDisabled))
|
||||
<td class="fi-has-action">
|
||||
<div
|
||||
x-sortable-handle
|
||||
class="fi-fo-key-value-table-row-sortable-handle"
|
||||
>
|
||||
{{ $getAction('reorder') }}
|
||||
</div>
|
||||
</td>
|
||||
@endif
|
||||
|
||||
<td>
|
||||
<input
|
||||
@disabled((! $canEditKeys) || $isDisabled)
|
||||
placeholder="{{ $keyPlaceholder }}"
|
||||
type="text"
|
||||
x-model="row.key"
|
||||
x-on:input.debounce.{{ $debounce ?? '500ms' }}="updateState"
|
||||
class="fi-input"
|
||||
/>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<input
|
||||
@disabled((! $canEditValues) || $isDisabled)
|
||||
placeholder="{{ $valuePlaceholder }}"
|
||||
type="text"
|
||||
x-model="row.value"
|
||||
x-on:input.debounce.{{ $debounce ?? '500ms' }}="updateState"
|
||||
class="fi-input"
|
||||
/>
|
||||
</td>
|
||||
|
||||
@if ($isDeletable && (! $isDisabled))
|
||||
<td class="fi-has-action">
|
||||
<div x-on:click="deleteRow(index)">
|
||||
{{ $getAction('delete') }}
|
||||
</div>
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@if ($isAddable && (! $isDisabled))
|
||||
<div
|
||||
x-on:click="addRow"
|
||||
class="fi-fo-key-value-add-action-ctn"
|
||||
>
|
||||
{{ $getAction('add') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
</x-dynamic-component>
|
||||
@@ -1,30 +0,0 @@
|
||||
@php
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraAttributes = $getExtraAttributes();
|
||||
$id = $getId();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
@if (filled($id) || filled($extraAttributes))
|
||||
{!! '<div' !!}
|
||||
{{-- Avoid formatting issues with unclosed elements --}}
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $id,
|
||||
], escape: false)
|
||||
->merge($extraAttributes, escape: false)
|
||||
}}
|
||||
>
|
||||
@endif
|
||||
|
||||
@if (filled($key = $getLivewireKey()))
|
||||
@livewire($getComponent(), $getComponentProperties(), key($key))
|
||||
@else
|
||||
@livewire($getComponent(), $getComponentProperties())
|
||||
@endif
|
||||
@if (filled($id) || filled($extraAttributes))
|
||||
{!! '</div>' !!}
|
||||
{{-- Avoid formatting issues with unclosed elements --}}
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
@@ -1,77 +0,0 @@
|
||||
@php
|
||||
$id = $getId();
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraAttributeBag = $getExtraAttributeBag();
|
||||
$key = $getKey();
|
||||
$statePath = $getStatePath();
|
||||
$fileAttachmentsMaxSize = $getFileAttachmentsMaxSize();
|
||||
$fileAttachmentsAcceptedFileTypes = $getFileAttachmentsAcceptedFileTypes();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
@if ($isDisabled())
|
||||
<div id="{{ $id }}" class="fi-fo-markdown-editor fi-disabled fi-prose">
|
||||
{!! str($getState())->markdown($getCommonMarkOptions(), $getCommonMarkExtensions())->sanitizeHtml() !!}
|
||||
</div>
|
||||
@else
|
||||
<x-filament::input.wrapper
|
||||
:valid="! $errors->has($statePath)"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($extraAttributeBag)
|
||||
->class(['fi-fo-markdown-editor'])
|
||||
"
|
||||
>
|
||||
<div
|
||||
aria-labelledby="{{ $id }}-label"
|
||||
id="{{ $id }}"
|
||||
role="group"
|
||||
x-load
|
||||
x-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('markdown-editor', 'filament/forms') }}"
|
||||
x-data="markdownEditorFormComponent({
|
||||
canAttachFiles: @js($hasToolbarButton('attachFiles')),
|
||||
isLiveDebounced: @js($isLiveDebounced()),
|
||||
isLiveOnBlur: @js($isLiveOnBlur()),
|
||||
liveDebounce: @js($getNormalizedLiveDebounce()),
|
||||
maxHeight: @js($getMaxHeight()),
|
||||
minHeight: @js($getMinHeight()),
|
||||
placeholder: @js($getPlaceholder()),
|
||||
state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$statePath}')", isOptimisticallyLive: false) }},
|
||||
toolbarButtons: @js($getToolbarButtons()),
|
||||
translations: @js(__('filament-forms::components.markdown_editor')),
|
||||
uploadFileAttachmentUsing: async (file, onSuccess, onError) => {
|
||||
const acceptedTypes = @js($fileAttachmentsAcceptedFileTypes)
|
||||
|
||||
if (acceptedTypes && ! acceptedTypes.includes(file.type)) {
|
||||
return onError(@js($fileAttachmentsAcceptedFileTypes ? __('filament-forms::components.markdown_editor.file_attachments_accepted_file_types_message', ['values' => implode(', ', $fileAttachmentsAcceptedFileTypes)]) : null))
|
||||
}
|
||||
|
||||
const maxSize = @js($fileAttachmentsMaxSize)
|
||||
|
||||
if (maxSize && file.size > +maxSize * 1024) {
|
||||
return onError(@js($fileAttachmentsMaxSize ? trans_choice('filament-forms::components.markdown_editor.file_attachments_max_size_message', $fileAttachmentsMaxSize, ['max' => $fileAttachmentsMaxSize]) : null))
|
||||
}
|
||||
|
||||
$wire.upload(`componentFileAttachments.{{ $statePath }}`, file, () => {
|
||||
$wire
|
||||
.callSchemaComponentMethod(
|
||||
'{{ $key }}',
|
||||
'saveUploadedFileAttachmentAndGetUrl',
|
||||
)
|
||||
.then((url) => {
|
||||
if (! url) {
|
||||
return onError()
|
||||
}
|
||||
|
||||
onSuccess(url)
|
||||
})
|
||||
})
|
||||
},
|
||||
})"
|
||||
wire:ignore
|
||||
{{ $getExtraAlpineAttributeBag() }}
|
||||
>
|
||||
<textarea x-ref="editor" x-cloak></textarea>
|
||||
</div>
|
||||
</x-filament::input.wrapper>
|
||||
@endif
|
||||
</x-dynamic-component>
|
||||
@@ -1,69 +0,0 @@
|
||||
@php
|
||||
use Filament\Forms\Components\TableSelect\Livewire\TableSelectLivewireComponent;
|
||||
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraAttributes = $getExtraAttributes();
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isMultiple = $isMultiple();
|
||||
$hasBadges = $hasBadges();
|
||||
$badgeColor = $getBadgeColor();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $id,
|
||||
], escape: false)
|
||||
->merge($extraAttributes, escape: false)
|
||||
->class([
|
||||
'fi-fo-modal-table-select',
|
||||
'fi-fo-modal-table-select-disabled' => $isDisabled,
|
||||
'fi-fo-modal-table-select-multiple' => $isMultiple,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (((! $isMultiple) && filled($optionLabel = $getOptionLabel())) ||
|
||||
($isMultiple && filled($optionLabels = $getOptionLabels())))
|
||||
@if ($isMultiple && $hasBadges)
|
||||
<div class="fi-fo-modal-table-select-badges-ctn">
|
||||
@foreach ($optionLabels as $optionLabel)
|
||||
@if ($hasBadges)
|
||||
<x-filament::badge :color="$badgeColor">
|
||||
{{ $optionLabel }}
|
||||
</x-filament::badge>
|
||||
@else
|
||||
{{ $optionLabel }}
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div>
|
||||
@if ($hasBadges)
|
||||
<x-filament::badge :color="$badgeColor">
|
||||
{{ $optionLabel }}
|
||||
</x-filament::badge>
|
||||
@elseif ($isMultiple)
|
||||
@foreach ($optionLabels as $optionLabel)
|
||||
{{ $optionLabel . ($loop->last ? '' : ', ') }}
|
||||
@endforeach
|
||||
@else
|
||||
{{ $optionLabel }}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@elseif (filled($placeholder = $getPlaceholder()))
|
||||
<div class="fi-fo-modal-table-select-placeholder">
|
||||
{{ $placeholder }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (! $isDisabled)
|
||||
<div>
|
||||
{{ $getAction('select') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,24 +0,0 @@
|
||||
@php
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$placeholder = $getPlaceholder();
|
||||
$extraAttributes = $getExtraAttributeBag()
|
||||
->merge($getExtraInputAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->merge([
|
||||
'autocomplete' => false,
|
||||
'autofocus' => $isAutofocused(),
|
||||
'disabled' => $isDisabled(),
|
||||
'id' => $getId(),
|
||||
'length' => $getLength(),
|
||||
'placeholder' => filled($placeholder) ? e($placeholder) : null,
|
||||
'readonly' => $isReadOnly(),
|
||||
'required' => $isRequired() && (! $isConcealed()),
|
||||
$applyStateBindingModifiers('wire:model') => $getStatePath(),
|
||||
], escape: false);
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<x-filament::input.one-time-code
|
||||
:attributes="\Filament\Support\prepare_inherited_attributes($extraAttributes)"
|
||||
/>
|
||||
</x-dynamic-component>
|
||||
@@ -1,41 +0,0 @@
|
||||
@props([
|
||||
'field' => null,
|
||||
'id' => null,
|
||||
'label' => null,
|
||||
'labelTag' => 'label',
|
||||
])
|
||||
|
||||
@php
|
||||
use Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
if ($field) {
|
||||
$id ??= $field->getId();
|
||||
$label ??= $field->getLabel();
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div
|
||||
data-field-wrapper
|
||||
{{
|
||||
(new ComponentAttributeBag)
|
||||
->merge($field?->getExtraFieldWrapperAttributes() ?? [], escape: false)
|
||||
->class([
|
||||
'fi-fo-field',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (filled($label))
|
||||
<{{ $labelTag }}
|
||||
@if ($labelTag === 'label')
|
||||
for="{{ $id }}"
|
||||
@else
|
||||
id="{{ $id }}-label"
|
||||
@endif
|
||||
class="fi-fo-field-label fi-sr-only"
|
||||
>
|
||||
{{ $label }}
|
||||
</{{ $labelTag }}>
|
||||
@endif
|
||||
|
||||
{{ $slot }}
|
||||
</div>
|
||||
@@ -1,64 +0,0 @@
|
||||
@php
|
||||
use Filament\Support\Enums\GridDirection;
|
||||
use Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
$extraInputAttributeBag = $getExtraInputAttributeBag();
|
||||
$gridDirection = $getGridDirection() ?? GridDirection::Column;
|
||||
$id = $getId();
|
||||
$isDisabled = $isDisabled();
|
||||
$isInline = $isInline();
|
||||
$statePath = $getStatePath();
|
||||
$wireModelAttribute = $applyStateBindingModifiers('wire:model');
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<div
|
||||
{{
|
||||
$getExtraAttributeBag()
|
||||
->when(! $isInline, fn (ComponentAttributeBag $attributes) => $attributes->grid($getColumns(), $gridDirection))
|
||||
->class([
|
||||
'fi-fo-radio',
|
||||
'fi-inline' => $isInline,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@foreach ($getOptions() as $value => $label)
|
||||
@php
|
||||
$inputAttributes = $extraInputAttributeBag
|
||||
->merge([
|
||||
'disabled' => $isDisabled || $isOptionDisabled($value, $label),
|
||||
'id' => $id . '-' . $value,
|
||||
'name' => $id,
|
||||
'value' => $value,
|
||||
$wireModelAttribute => $statePath,
|
||||
], escape: false);
|
||||
@endphp
|
||||
|
||||
<label class="fi-fo-radio-label">
|
||||
<input
|
||||
type="radio"
|
||||
{{
|
||||
$inputAttributes->class([
|
||||
'fi-radio-input',
|
||||
'fi-valid' => ! $errors->has($statePath),
|
||||
'fi-invalid' => $errors->has($statePath),
|
||||
])
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="fi-fo-radio-label-text">
|
||||
<p>
|
||||
{{ $label }}
|
||||
</p>
|
||||
|
||||
@if ($hasDescription($value))
|
||||
<p class="fi-fo-radio-label-description">
|
||||
{{ $getDescription($value) }}
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,263 +0,0 @@
|
||||
@php
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
|
||||
$items = $getItems();
|
||||
|
||||
$addAction = $getAction($getAddActionName());
|
||||
$addActionAlignment = $getAddActionAlignment();
|
||||
$addBetweenAction = $getAction($getAddBetweenActionName());
|
||||
$cloneAction = $getAction($getCloneActionName());
|
||||
$collapseAllAction = $getAction($getCollapseAllActionName());
|
||||
$expandAllAction = $getAction($getExpandAllActionName());
|
||||
$deleteAction = $getAction($getDeleteActionName());
|
||||
$moveDownAction = $getAction($getMoveDownActionName());
|
||||
$moveUpAction = $getAction($getMoveUpActionName());
|
||||
$reorderAction = $getAction($getReorderActionName());
|
||||
$extraItemActions = $getExtraItemActions();
|
||||
|
||||
$hasItemNumbers = $hasItemNumbers();
|
||||
$hasItemHeaders = $hasItemHeaders();
|
||||
$isAddable = $isAddable();
|
||||
$isCloneable = $isCloneable();
|
||||
$isCollapsible = $isCollapsible();
|
||||
$isDeletable = $isDeletable();
|
||||
$isReorderableWithButtons = $isReorderableWithButtons();
|
||||
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
|
||||
|
||||
$collapseAllActionIsVisible = $isCollapsible && $collapseAllAction->isVisible();
|
||||
$expandAllActionIsVisible = $isCollapsible && $expandAllAction->isVisible();
|
||||
|
||||
$key = $getKey();
|
||||
$statePath = $getStatePath();
|
||||
|
||||
$itemLabelHeadingTag = $getHeadingTag();
|
||||
$isItemLabelTruncated = $isItemLabelTruncated();
|
||||
$labelBetweenItems = $getLabelBetweenItems();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-fo-repeater',
|
||||
'fi-collapsible' => $isCollapsible,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if ($collapseAllActionIsVisible || $expandAllActionIsVisible)
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-repeater-actions',
|
||||
'fi-hidden' => count($items) < 2,
|
||||
])
|
||||
>
|
||||
@if ($collapseAllActionIsVisible)
|
||||
<span
|
||||
x-on:click="$dispatch('repeater-collapse', '{{ $statePath }}')"
|
||||
>
|
||||
{{ $collapseAllAction }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if ($expandAllActionIsVisible)
|
||||
<span
|
||||
x-on:click="$dispatch('repeater-expand', '{{ $statePath }}')"
|
||||
>
|
||||
{{ $expandAllAction }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (count($items))
|
||||
<ul
|
||||
x-sortable
|
||||
{{
|
||||
(new ComponentAttributeBag)
|
||||
->grid($getGridColumns())
|
||||
->merge([
|
||||
'data-sortable-animation-duration' => $getReorderAnimationDuration(),
|
||||
'x-on:end.stop' => '$event.oldDraggableIndex !== $event.newDraggableIndex && $wire.mountAction(\'reorder\', { items: $event.target.sortable.toArray() }, { schemaComponent: \'' . $key . '\' })',
|
||||
], escape: false)
|
||||
->class(['fi-fo-repeater-items'])
|
||||
}}
|
||||
>
|
||||
@foreach ($items as $itemKey => $item)
|
||||
@php
|
||||
$itemLabel = $getItemLabel($itemKey);
|
||||
$visibleExtraItemActions = array_filter(
|
||||
$extraItemActions,
|
||||
fn (Action $action): bool => $action(['item' => $itemKey])->isVisible(),
|
||||
);
|
||||
$cloneAction = $cloneAction(['item' => $itemKey]);
|
||||
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
|
||||
$deleteAction = $deleteAction(['item' => $itemKey]);
|
||||
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
|
||||
$moveDownAction = $moveDownAction(['item' => $itemKey])->disabled($loop->last);
|
||||
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
|
||||
$moveUpAction = $moveUpAction(['item' => $itemKey])->disabled($loop->first);
|
||||
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
|
||||
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
|
||||
$hasItemHeader = $hasItemHeaders && ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || filled($itemLabel) || $cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions);
|
||||
@endphp
|
||||
|
||||
<li
|
||||
wire:ignore.self
|
||||
wire:key="{{ $item->getLivewireKey() }}.item"
|
||||
x-data="{
|
||||
isCollapsed: @js($isCollapsed($item)),
|
||||
}"
|
||||
x-on:repeater-expand.window="$event.detail === '{{ $statePath }}' && (isCollapsed = false)"
|
||||
x-on:repeater-collapse.window="$event.detail === '{{ $statePath }}' && (isCollapsed = true)"
|
||||
x-on:expand="isCollapsed = false"
|
||||
x-sortable-item="{{ $itemKey }}"
|
||||
@class([
|
||||
'fi-fo-repeater-item',
|
||||
'fi-fo-repeater-item-has-header' => $hasItemHeader,
|
||||
])
|
||||
x-bind:class="{ 'fi-collapsed': isCollapsed }"
|
||||
>
|
||||
@if ($hasItemHeader)
|
||||
<div
|
||||
@if ($isCollapsible)
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
@endif
|
||||
class="fi-fo-repeater-item-header"
|
||||
>
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<ul
|
||||
class="fi-fo-repeater-item-header-start-actions"
|
||||
>
|
||||
@if ($reorderActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $reorderAction->extraAttributes(['x-sortable-handle' => true], merge: true) }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $moveUpAction }}
|
||||
</li>
|
||||
|
||||
<li x-on:click.stop>
|
||||
{{ $moveDownAction }}
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if (filled($itemLabel))
|
||||
<{{ $itemLabelHeadingTag }}
|
||||
@class([
|
||||
'fi-fo-repeater-item-header-label',
|
||||
'fi-truncated' => $isItemLabelTruncated,
|
||||
])
|
||||
>
|
||||
{{ $itemLabel }}
|
||||
|
||||
@if ($hasItemNumbers)
|
||||
{{ $loop->iteration }}
|
||||
@endif
|
||||
</{{ $itemLabelHeadingTag }}>
|
||||
@endif
|
||||
|
||||
@if ($cloneActionIsVisible || $deleteActionIsVisible || $isCollapsible || $visibleExtraItemActions)
|
||||
<ul
|
||||
class="fi-fo-repeater-item-header-end-actions"
|
||||
>
|
||||
@foreach ($visibleExtraItemActions as $extraItemAction)
|
||||
<li x-on:click.stop>
|
||||
{{ $extraItemAction(['item' => $itemKey]) }}
|
||||
</li>
|
||||
@endforeach
|
||||
|
||||
@if ($cloneActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $cloneAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($deleteActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $deleteAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($isCollapsible)
|
||||
<li
|
||||
class="fi-fo-repeater-item-header-collapsible-actions"
|
||||
x-on:click.stop="isCollapsed = !isCollapsed"
|
||||
>
|
||||
<div
|
||||
class="fi-fo-repeater-item-header-collapse-action"
|
||||
>
|
||||
{{ $getAction('collapse') }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="fi-fo-repeater-item-header-expand-action"
|
||||
>
|
||||
{{ $getAction('expand') }}
|
||||
</div>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div
|
||||
x-show="! isCollapsed"
|
||||
class="fi-fo-repeater-item-content"
|
||||
>
|
||||
{{ $item }}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@if (! $loop->last)
|
||||
@if ($isAddable && $addBetweenAction(['afterItem' => $itemKey])->isVisible())
|
||||
<li class="fi-fo-repeater-add-between-items-ctn">
|
||||
<div class="fi-fo-repeater-add-between-items">
|
||||
{{ $addBetweenAction(['afterItem' => $itemKey]) }}
|
||||
</div>
|
||||
</li>
|
||||
@elseif (filled($labelBetweenItems))
|
||||
<li class="fi-fo-repeater-label-between-items-ctn">
|
||||
<div
|
||||
class="fi-fo-repeater-label-between-items-divider-before"
|
||||
></div>
|
||||
|
||||
<span
|
||||
class="fi-fo-repeater-label-between-items"
|
||||
>
|
||||
{{ $labelBetweenItems }}
|
||||
</span>
|
||||
|
||||
<div
|
||||
class="fi-fo-repeater-label-between-items-divider-after"
|
||||
></div>
|
||||
</li>
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if ($isAddable && $addAction->isVisible())
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-repeater-add',
|
||||
($addActionAlignment instanceof Alignment) ? ('fi-align-' . $addActionAlignment->value) : $addActionAlignment,
|
||||
])
|
||||
>
|
||||
{{ $addAction }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
@@ -1,129 +0,0 @@
|
||||
@php
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$fieldWrapperView = $getFieldWrapperView();
|
||||
|
||||
$items = $getItems();
|
||||
|
||||
$addAction = $getAction($getAddActionName());
|
||||
$addActionAlignment = $getAddActionAlignment();
|
||||
$cloneAction = $getAction($getCloneActionName());
|
||||
$deleteAction = $getAction($getDeleteActionName());
|
||||
$moveDownAction = $getAction($getMoveDownActionName());
|
||||
$moveUpAction = $getAction($getMoveUpActionName());
|
||||
$reorderAction = $getAction($getReorderActionName());
|
||||
$extraItemActions = $getExtraItemActions();
|
||||
|
||||
$isAddable = $isAddable();
|
||||
$isCloneable = $isCloneable();
|
||||
$isDeletable = $isDeletable();
|
||||
$isReorderableWithButtons = $isReorderableWithButtons();
|
||||
$isReorderableWithDragAndDrop = $isReorderableWithDragAndDrop();
|
||||
|
||||
$key = $getKey();
|
||||
$statePath = $getStatePath();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$fieldWrapperView" :field="$field">
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-fo-simple-repeater'])
|
||||
}}
|
||||
>
|
||||
@if (count($items))
|
||||
<ul
|
||||
x-sortable
|
||||
{{
|
||||
(new ComponentAttributeBag)
|
||||
->grid($getGridColumns())
|
||||
->merge([
|
||||
'data-sortable-animation-duration' => $getReorderAnimationDuration(),
|
||||
'x-on:end.stop' => '$event.oldDraggableIndex !== $event.newDraggableIndex && $wire.mountAction(\'reorder\', { items: $event.target.sortable.toArray() }, { schemaComponent: \'' . $key . '\' })',
|
||||
], escape: false)
|
||||
->class(['fi-fo-simple-repeater-items'])
|
||||
}}
|
||||
>
|
||||
@foreach ($items as $itemKey => $item)
|
||||
@php
|
||||
$visibleExtraItemActions = array_filter(
|
||||
$extraItemActions,
|
||||
fn (Action $action): bool => $action(['item' => $itemKey])->isVisible(),
|
||||
);
|
||||
$cloneAction = $cloneAction(['item' => $itemKey]);
|
||||
$cloneActionIsVisible = $isCloneable && $cloneAction->isVisible();
|
||||
$deleteAction = $deleteAction(['item' => $itemKey]);
|
||||
$deleteActionIsVisible = $isDeletable && $deleteAction->isVisible();
|
||||
$moveDownAction = $moveDownAction(['item' => $itemKey])->disabled($loop->last);
|
||||
$moveDownActionIsVisible = $isReorderableWithButtons && $moveDownAction->isVisible();
|
||||
$moveUpAction = $moveUpAction(['item' => $itemKey])->disabled($loop->first);
|
||||
$moveUpActionIsVisible = $isReorderableWithButtons && $moveUpAction->isVisible();
|
||||
$reorderActionIsVisible = $isReorderableWithDragAndDrop && $reorderAction->isVisible();
|
||||
@endphp
|
||||
|
||||
<li
|
||||
wire:key="{{ $item->getLivewireKey() }}.item"
|
||||
x-sortable-item="{{ $itemKey }}"
|
||||
class="fi-fo-simple-repeater-item"
|
||||
>
|
||||
<div class="fi-fo-simple-repeater-item-content">
|
||||
{{ $item }}
|
||||
</div>
|
||||
|
||||
@if ($reorderActionIsVisible || $moveUpActionIsVisible || $moveDownActionIsVisible || $cloneActionIsVisible || $deleteActionIsVisible || $visibleExtraItemActions)
|
||||
<ul class="fi-fo-simple-repeater-item-actions">
|
||||
@if ($reorderActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $reorderAction->extraAttributes(['x-sortable-handle' => true], merge: true) }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($moveUpActionIsVisible || $moveDownActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $moveUpAction }}
|
||||
</li>
|
||||
|
||||
<li x-on:click.stop>
|
||||
{{ $moveDownAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@foreach ($visibleExtraItemActions as $extraItemAction)
|
||||
<li x-on:click.stop>
|
||||
{{ $extraItemAction(['item' => $itemKey]) }}
|
||||
</li>
|
||||
@endforeach
|
||||
|
||||
@if ($cloneActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $cloneAction }}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
@if ($deleteActionIsVisible)
|
||||
<li x-on:click.stop>
|
||||
{{ $deleteAction }}
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
@if ($isAddable && $addAction->isVisible())
|
||||
<div
|
||||
@class([
|
||||
'fi-fo-simple-repeater-add',
|
||||
($addActionAlignment instanceof Alignment) ? ('fi-align-' . $addActionAlignment->value) : $addActionAlignment,
|
||||
])
|
||||
>
|
||||
{{ $addAction }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user