[增添]添加了datasource的setting数据库以及默认值

This commit is contained in:
makotocc0107
2024-08-27 09:57:44 +08:00
parent d111dfaea4
commit 72eb990970
10955 changed files with 978898 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
@php
use Filament\Support\Enums\Alignment;
@endphp
@props([
'actions',
'alignment' => Alignment::End,
'record' => null,
'wrap' => false,
])
@php
$actions = array_filter(
$actions,
function ($action) use ($record): bool {
if (! $action instanceof \Filament\Tables\Actions\BulkAction) {
$action->record($record);
}
return $action->isVisible();
},
);
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
@endphp
@if ($actions)
<div
{{
$attributes->class([
'fi-ta-actions flex shrink-0 items-center gap-3',
'flex-wrap' => $wrap,
'sm:flex-nowrap' => $wrap === '-sm',
match ($alignment) {
Alignment::Center => 'justify-center',
Alignment::Start, Alignment::Left => 'justify-start',
Alignment::End, Alignment::Right => 'justify-end',
Alignment::Between, Alignment::Justify => 'justify-between',
'start md:end' => 'justify-start md:justify-end',
default => $alignment,
},
])
}}
>
@foreach ($actions as $action)
{{ $action }}
@endforeach
</div>
@endif

View File

@@ -0,0 +1,10 @@
<x-filament-tables::cell
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-ta-actions-cell'])
"
>
<div class="whitespace-nowrap px-3 py-4">
{{ $slot }}
</div>
</x-filament-tables::cell>

View File

@@ -0,0 +1,9 @@
@props([
'tag' => 'td',
])
<{{ $tag }}
{{ $attributes->class(['fi-ta-cell p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3']) }}
>
{{ $slot }}
</{{ $tag }}>

View File

@@ -0,0 +1,29 @@
@props([
'form',
'maxHeight' => null,
'triggerAction',
'width' => 'xs',
])
<x-filament::dropdown
:max-height="$maxHeight"
placement="bottom-end"
shift
:width="$width"
wire:key="{{ $this->getId() }}.table.column-toggle"
{{ $attributes->class(['fi-ta-col-toggle']) }}
>
<x-slot name="trigger">
{{ $triggerAction }}
</x-slot>
<div class="grid gap-y-4 p-6">
<h4
class="text-base font-semibold leading-6 text-gray-950 dark:text-white"
>
{{ __('filament-tables::table.column_toggle.heading') }}
</h4>
{{ $form }}
</div>
</x-filament::dropdown>

View File

@@ -0,0 +1,87 @@
@props([
'column',
'isClickDisabled' => false,
'record',
'recordAction' => null,
'recordKey' => null,
'recordUrl' => null,
'shouldOpenRecordUrlInNewTab' => false,
])
@php
use Filament\Support\Enums\Alignment;
$action = $column->getAction();
$alignment = $column->getAlignment() ?? Alignment::Start;
$name = $column->getName();
$shouldOpenUrlInNewTab = $column->shouldOpenUrlInNewTab();
$tooltip = $column->getTooltip();
$url = $column->getUrl();
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
$columnClasses = \Illuminate\Support\Arr::toCssClasses([
'flex w-full disabled:pointer-events-none',
match ($alignment) {
Alignment::Start => 'justify-start text-start',
Alignment::Center => 'justify-center text-center',
Alignment::End => 'justify-end text-end',
Alignment::Left => 'justify-start text-left',
Alignment::Right => 'justify-end text-right',
Alignment::Justify, Alignment::Between => 'justify-between text-justify',
default => $alignment,
},
]);
$slot = $column->viewData(['recordKey' => $recordKey]);
@endphp
<div
@if (filled($tooltip))
x-data="{}"
x-tooltip="{
content: @js($tooltip),
theme: $store.theme,
}"
@endif
{{ $attributes->class(['fi-ta-col-wrp']) }}
>
@if (($url || ($recordUrl && $action === null)) && (! $isClickDisabled))
<a
{{ \Filament\Support\generate_href_html($url ?: $recordUrl, $url ? $shouldOpenUrlInNewTab : $shouldOpenRecordUrlInNewTab) }}
class="{{ $columnClasses }}"
>
{{ $slot }}
</a>
@elseif (($action || $recordAction) && (! $isClickDisabled))
@php
if ($action instanceof \Filament\Tables\Actions\Action) {
$wireClickAction = "mountTableAction('{$action->getName()}', '{$recordKey}')";
} elseif ($action) {
$wireClickAction = "callTableColumnAction('{$name}', '{$recordKey}')";
} else {
if ($this->getTable()->getAction($recordAction)) {
$wireClickAction = "mountTableAction('{$recordAction}', '{$recordKey}')";
} else {
$wireClickAction = "{$recordAction}('{$recordKey}')";
}
}
@endphp
<button
type="button"
wire:click="{{ $wireClickAction }}"
wire:loading.attr="disabled"
wire:target="{{ $wireClickAction }}"
class="{{ $columnClasses }}"
>
{{ $slot }}
</button>
@else
<div class="{{ $columnClasses }}">
{{ $slot }}
</div>
@endif
</div>

View File

@@ -0,0 +1,72 @@
@props([
'components',
'record',
'recordKey' => null,
'rowLoop' => null,
])
@php
$getHiddenClasses = function (Filament\Tables\Columns\Column | Filament\Tables\Columns\Layout\Component $layoutComponent): ?string {
if ($breakpoint = $layoutComponent->getHiddenFrom()) {
return match ($breakpoint) {
'sm' => 'sm:hidden',
'md' => 'md:hidden',
'lg' => 'lg:hidden',
'xl' => 'xl:hidden',
'2xl' => '2xl:hidden',
};
}
if ($breakpoint = $layoutComponent->getVisibleFrom()) {
return match ($breakpoint) {
'sm' => 'hidden sm:block',
'md' => 'hidden md:block',
'lg' => 'hidden lg:block',
'xl' => 'hidden xl:block',
'2xl' => 'hidden 2xl:block',
};
}
return null;
};
@endphp
@foreach ($components as $layoutComponent)
@php
$layoutComponent->record($record);
$layoutComponent->rowLoop($rowLoop);
$isColumn = $layoutComponent instanceof \Filament\Tables\Columns\Column;
@endphp
@if ($layoutComponent->isVisible())
<x-filament::grid.column
:default="$layoutComponent->getColumnSpan('default')"
:sm="$layoutComponent->getColumnSpan('sm')"
:md="$layoutComponent->getColumnSpan('md')"
:lg="$layoutComponent->getColumnSpan('lg')"
:xl="$layoutComponent->getColumnSpan('xl')"
:twoXl="$layoutComponent->getColumnSpan('2xl')"
:defaultStart="$layoutComponent->getColumnStart('default')"
:smStart="$layoutComponent->getColumnStart('sm')"
:mdStart="$layoutComponent->getColumnStart('md')"
:lgStart="$layoutComponent->getColumnStart('lg')"
:xlStart="$layoutComponent->getColumnStart('xl')"
:twoXlStart="$layoutComponent->getColumnStart('2xl')"
@class([
'flex-1 w-full' => $layoutComponent->canGrow(),
$getHiddenClasses($layoutComponent),
])
>
@if ($isColumn)
<x-filament-tables::columns.column
:column="$layoutComponent->inline()"
:record="$record"
:record-key="$recordKey"
/>
@else
{{ $layoutComponent->viewData(['recordKey' => $recordKey]) }}
@endif
</x-filament::grid.column>
@endif
@endforeach

View File

@@ -0,0 +1,5 @@
<div
class="fi-ta-placeholder text-sm leading-6 text-gray-400 dark:text-gray-500"
>
{{ $slot }}
</div>

View File

@@ -0,0 +1,9 @@
<div
{{
$attributes->class([
'fi-ta-ctn divide-y divide-gray-200 overflow-hidden rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:divide-white/10 dark:bg-gray-900 dark:ring-white/10',
])
}}
>
{{ $slot }}
</div>

View File

@@ -0,0 +1,5 @@
<p
{{ $attributes->class(['fi-ta-empty-state-description text-sm text-gray-500 dark:text-gray-400']) }}
>
{{ $slot }}
</p>

View File

@@ -0,0 +1,5 @@
<h4
{{ $attributes->class(['fi-ta-empty-state-heading text-base font-semibold leading-6 text-gray-950 dark:text-white']) }}
>
{{ $slot }}
</h4>

View File

@@ -0,0 +1,46 @@
@php
use Filament\Support\Enums\Alignment;
@endphp
@props([
'actions' => [],
'description' => null,
'heading',
'icon',
])
<div
{{ $attributes->class(['fi-ta-empty-state px-6 py-12']) }}
>
<div
class="fi-ta-empty-state-content mx-auto grid max-w-lg justify-items-center text-center"
>
<div
class="fi-ta-empty-state-icon-ctn mb-4 rounded-full bg-gray-100 p-3 dark:bg-gray-500/20"
>
<x-filament::icon
:icon="$icon"
class="fi-ta-empty-state-icon h-6 w-6 text-gray-500 dark:text-gray-400"
/>
</div>
<x-filament-tables::empty-state.heading>
{{ $heading }}
</x-filament-tables::empty-state.heading>
@if ($description)
<x-filament-tables::empty-state.description class="mt-1">
{{ $description }}
</x-filament-tables::empty-state.description>
@endif
@if ($actions)
<x-filament-tables::actions
:actions="$actions"
:alignment="Alignment::Center"
wrap
class="mt-6"
/>
@endif
</div>
</div>

View File

@@ -0,0 +1,64 @@
@php
use Filament\Tables\Enums\FiltersLayout;
@endphp
@props([
'activeFiltersCount' => 0,
'applyAction',
'form',
'layout',
'maxHeight' => null,
'triggerAction',
'width' => 'xs',
])
@if (($layout === FiltersLayout::Modal) || $triggerAction->isModalSlideOver())
<x-filament::modal
:alignment="$triggerAction->getModalAlignment()"
:autofocus="$triggerAction->isModalAutofocused()"
:close-button="$triggerAction->hasModalCloseButton()"
:close-by-clicking-away="$triggerAction->isModalClosedByClickingAway()"
:close-by-escaping="$triggerAction?->isModalClosedByEscaping()"
:description="$triggerAction->getModalDescription()"
:footer-actions="$triggerAction->getVisibleModalFooterActions()"
:footer-actions-alignment="$triggerAction->getModalFooterActionsAlignment()"
:heading="$triggerAction->getCustomModalHeading() ?? __('filament-tables::table.filters.heading')"
:icon="$triggerAction->getModalIcon()"
:icon-color="$triggerAction->getModalIconColor()"
:slide-over="$triggerAction->isModalSlideOver()"
:sticky-footer="$triggerAction->isModalFooterSticky()"
:sticky-header="$triggerAction->isModalHeaderSticky()"
:width="$width"
wire:key="{{ $this->getId() }}.table.filters"
{{ $attributes->class(['fi-ta-filters-modal']) }}
>
<x-slot name="trigger">
{{ $triggerAction->badge($activeFiltersCount) }}
</x-slot>
{{ $triggerAction->getModalContent() }}
{{ $form }}
{{ $triggerAction->getModalContentFooter() }}
</x-filament::modal>
@else
<x-filament::dropdown
:max-height="$maxHeight"
placement="bottom-end"
shift
:width="$width"
wire:key="{{ $this->getId() }}.table.filters"
{{ $attributes->class(['fi-ta-filters-dropdown']) }}
>
<x-slot name="trigger">
{{ $triggerAction->badge($activeFiltersCount) }}
</x-slot>
<x-filament-tables::filters
:apply-action="$applyAction"
:form="$form"
class="p-6"
/>
</x-filament::dropdown>
@endif

View File

@@ -0,0 +1,51 @@
@props([
'applyAction',
'form',
])
<div {{ $attributes->class(['fi-ta-filters grid gap-y-4']) }}>
<div class="flex items-center justify-between">
<h4
class="text-base font-semibold leading-6 text-gray-950 dark:text-white"
>
{{ __('filament-tables::table.filters.heading') }}
</h4>
<div>
<x-filament::link
:attributes="
\Filament\Support\prepare_inherited_attributes(
new \Illuminate\View\ComponentAttributeBag([
'color' => 'danger',
'tag' => 'button',
'wire:click' => 'resetTableFiltersForm',
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => '',
'wire:target' => 'resetTableFiltersForm',
])
)
"
>
{{ __('filament-tables::table.filters.actions.reset.label') }}
</x-filament::link>
<x-filament::loading-indicator
:attributes="
\Filament\Support\prepare_inherited_attributes(
new \Illuminate\View\ComponentAttributeBag([
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
'wire:target' => 'tableFilters,applyTableFilters,resetTableFiltersForm',
])
)->class(['h-5 w-5 text-gray-400 dark:text-gray-500'])
"
/>
</div>
</div>
{{ $form }}
@if ($applyAction->isVisible())
<div>
{{ $applyAction }}
</div>
@endif
</div>

View File

@@ -0,0 +1,45 @@
@props([
'indicators' => [],
])
<div
{{ $attributes->class(['fi-ta-filter-indicators flex items-start justify-between gap-x-3 bg-gray-50 px-3 py-1.5 dark:bg-white/5 sm:px-6']) }}
>
<div class="flex flex-col gap-x-3 gap-y-1 sm:flex-row">
<span
class="whitespace-nowrap text-sm font-medium leading-6 text-gray-700 dark:text-gray-200"
>
{{ __('filament-tables::table.filters.indicator') }}
</span>
<div class="flex flex-wrap gap-1.5">
@foreach ($indicators as $indicator)
<x-filament::badge :color="$indicator->getColor()">
{{ $indicator->getLabel() }}
@if ($indicator->isRemovable())
<x-slot
name="deleteButton"
:label="__('filament-tables::table.filters.actions.remove.label')"
wire:click="{{ $indicator->getRemoveLivewireClickHandler() }}"
wire:loading.attr="disabled"
wire:target="removeTableFilter"
></x-slot>
@endif
</x-filament::badge>
@endforeach
</div>
</div>
<div class="mt-0.5">
<x-filament::icon-button
color="gray"
icon="heroicon-m-x-mark"
icon-alias="tables::filters.remove-all-button"
size="sm"
:tooltip="__('filament-tables::table.filters.actions.remove_all.tooltip')"
wire:click="removeTableFilters"
wire:target="removeTableFilters,removeTableFilter"
/>
</div>
</div>

View File

@@ -0,0 +1,49 @@
@props([
'collapsible' => false,
'description' => null,
'label' => null,
'start' => null,
'title',
])
<div
@if ($collapsible)
x-on:click="toggleCollapseGroup(@js($title))"
@endif
{{
$attributes->class([
'fi-ta-group-header flex w-full items-center gap-x-3 bg-gray-50 px-3 py-2 dark:bg-white/5',
'cursor-pointer' => $collapsible,
])
}}
>
{{ $start }}
<div class="grid">
<h4 class="text-sm font-medium text-gray-950 dark:text-white">
@if (filled($label))
{{ $label }}:
@endif
{{ $title }}
</h4>
@if (filled($description))
<p class="text-sm text-gray-500 dark:text-gray-400">
{{ $description }}
</p>
@endif
</div>
@if ($collapsible)
<x-filament::icon-button
color="gray"
icon="heroicon-m-chevron-up"
icon-alias="tables::grouping.collapse-button"
:label="filled($label) ? ($label . ': ' . $title) : $title"
size="sm"
:x-bind:aria-expanded="'! isGroupCollapsed(' . \Illuminate\Support\Js::from($title) . ')'"
:x-bind:class="'isGroupCollapsed(' . \Illuminate\Support\Js::from($title) . ') && \'-rotate-180\''"
/>
@endif
</div>

View File

@@ -0,0 +1,143 @@
@props([
'directionSetting' => false,
'dropdownOnDesktop' => false,
'groups',
'triggerAction',
])
@php
$labelClasses = 'text-sm font-medium leading-6 text-gray-950 dark:text-white';
@endphp
<div
x-data="{
direction: $wire.$entangle('tableGroupingDirection', true),
group: $wire.$entangle('tableGrouping', true),
}"
x-init="
$watch('group', function (newGroup, oldGroup) {
if (newGroup && direction) {
return
}
if (! newGroup) {
direction = null
return
}
if (oldGroup) {
return
}
direction = 'asc'
})
"
>
<x-filament::dropdown
placement="bottom-start"
shift
width="xs"
wire:key="{{ $this->getId() }}.table.grouping"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class([
'sm:hidden' => ! $dropdownOnDesktop,
])
"
>
<x-slot name="trigger">
{{ $triggerAction }}
</x-slot>
<div class="grid gap-y-6 p-6">
<label class="grid gap-y-2">
<span class="{{ $labelClasses }}">
{{ __('filament-tables::table.grouping.fields.group.label') }}
</span>
<x-filament::input.wrapper>
<x-filament::input.select
x-model="group"
x-on:change="resetCollapsedGroups()"
>
<option value="">-</option>
@foreach ($groups as $group)
<option value="{{ $group->getId() }}">
{{ $group->getLabel() }}
</option>
@endforeach
</x-filament::input.select>
</x-filament::input.wrapper>
</label>
@if (! $directionSetting)
<label x-cloak x-show="group" class="grid gap-y-2">
<span class="{{ $labelClasses }}">
{{ __('filament-tables::table.grouping.fields.direction.label') }}
</span>
<x-filament::input.wrapper>
<x-filament::input.select x-model="direction">
<option value="asc">
{{ __('filament-tables::table.grouping.fields.direction.options.asc') }}
</option>
<option value="desc">
{{ __('filament-tables::table.grouping.fields.direction.options.desc') }}
</option>
</x-filament::input.select>
</x-filament::input.wrapper>
</label>
@endif
</div>
</x-filament::dropdown>
@if (! $dropdownOnDesktop)
<div class="hidden items-center gap-x-3 sm:flex">
<label>
<span class="sr-only">
{{ __('filament-tables::table.grouping.fields.group.label') }}
</span>
<x-filament::input.wrapper>
<x-filament::input.select
x-model="group"
x-on:change="resetCollapsedGroups()"
>
<option value="">
{{ __('filament-tables::table.grouping.fields.group.placeholder') }}
</option>
@foreach ($groups as $group)
<option value="{{ $group->getId() }}">
{{ $group->getLabel() }}
</option>
@endforeach
</x-filament::input.select>
</x-filament::input.wrapper>
</label>
@if (! $directionSetting)
<label x-cloak x-show="group">
<span class="sr-only">
{{ __('filament-tables::table.grouping.fields.direction.label') }}
</span>
<x-filament::input.wrapper>
<x-filament::input.select x-model="direction">
<option value="asc">
{{ __('filament-tables::table.grouping.fields.direction.options.asc') }}
</option>
<option value="desc">
{{ __('filament-tables::table.grouping.fields.direction.options.desc') }}
</option>
</x-filament::input.select>
</x-filament::input.wrapper>
</label>
@endif
</div>
@endif
</div>

View File

@@ -0,0 +1,62 @@
@php
use Filament\Support\Enums\Alignment;
@endphp
@props([
'activelySorted' => false,
'alignment' => Alignment::Start,
'name',
'sortable' => false,
'sortDirection',
'wrap' => false,
])
@php
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
@endphp
<th
{{ $attributes->class(['fi-ta-header-cell px-3 py-3.5 sm:first-of-type:ps-6 sm:last-of-type:pe-6']) }}
>
<{{ $sortable ? 'button' : 'span' }}
@if ($sortable)
aria-label="{{ __('filament-tables::table.sorting.fields.column.label') }} {{ $sortDirection === 'asc' ? __('filament-tables::table.sorting.fields.direction.options.desc') : __('filament-tables::table.sorting.fields.direction.options.asc') }}"
type="button"
wire:click="sortTable('{{ $name }}')"
@endif
@class([
'group flex w-full items-center gap-x-1',
'whitespace-nowrap' => ! $wrap,
'whitespace-normal' => $wrap,
match ($alignment) {
Alignment::Start => 'justify-start',
Alignment::Center => 'justify-center',
Alignment::End => 'justify-end',
Alignment::Left => 'justify-start rtl:flex-row-reverse',
Alignment::Right => 'justify-end rtl:flex-row-reverse',
Alignment::Justify, Alignment::Between => 'justify-between',
default => $alignment,
},
])
>
<span
class="fi-ta-header-cell-label text-sm font-semibold text-gray-950 dark:text-white"
>
{{ $slot }}
</span>
@if ($sortable)
<x-filament::icon
:alias="$activelySorted && $sortDirection === 'asc' ? 'tables::header-cell.sort-asc-button' : 'tables::header-cell.sort-desc-button'"
:icon="$activelySorted && $sortDirection === 'asc' ? 'heroicon-m-chevron-up' : 'heroicon-m-chevron-down'"
@class([
'fi-ta-header-cell-sort-icon h-5 w-5 shrink-0 transition duration-75',
'text-gray-950 dark:text-white' => $activelySorted,
'text-gray-400 dark:text-gray-500 group-hover:text-gray-500 group-focus-visible:text-gray-500 dark:group-hover:text-gray-400 dark:group-focus-visible:text-gray-400' => ! $activelySorted,
])
/>
@endif
</{{ $sortable ? 'button' : 'span' }}>
</th>

View File

@@ -0,0 +1,52 @@
@php
use Filament\Support\Enums\Alignment;
use Filament\Tables\Actions\HeaderActionsPosition;
@endphp
@props([
'actions' => [],
'actionsPosition',
'description' => null,
'heading' => null,
])
<div
{{
$attributes->class([
'fi-ta-header flex flex-col gap-3 p-4 sm:px-6',
'sm:flex-row sm:items-center' => $actionsPosition === HeaderActionsPosition::Adaptive,
])
}}
>
@if ($heading || $description)
<div class="grid gap-y-1">
@if ($heading)
<h3
class="fi-ta-header-heading text-base font-semibold leading-6 text-gray-950 dark:text-white"
>
{{ $heading }}
</h3>
@endif
@if ($description)
<p
class="fi-ta-header-description text-sm text-gray-600 dark:text-gray-400"
>
{{ $description }}
</p>
@endif
</div>
@endif
@if ($actions)
<x-filament-tables::actions
:actions="$actions"
:alignment="Alignment::Start"
wrap
@class([
'ms-auto' => $actionsPosition === HeaderActionsPosition::Adaptive && ! ($heading || $description),
'sm:ms-auto' => $actionsPosition === HeaderActionsPosition::Adaptive,
])
/>
@endif
</div>

View File

@@ -0,0 +1,10 @@
<x-filament-tables::cell
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['w-1'])
"
>
<div class="px-3">
{{ $slot }}
</div>
</x-filament-tables::cell>

View File

@@ -0,0 +1,10 @@
<x-filament::icon-button
color="gray"
icon="heroicon-m-bars-2"
{{-- @deprecated Use `tables::reorder.handle` instead of `tables::reorder.button`. --}}
:icon-alias="['tables::reorder.handle', 'tables::reorder.button']"
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['cursor-move'])
"
/>

View File

@@ -0,0 +1,29 @@
<div
x-cloak
{{
$attributes
->merge([
'wire:key' => "{$this->getId()}.table.reorder.indicator",
], escape: false)
->class([
'fi-ta-reorder-indicator flex gap-x-3 bg-gray-50 px-3 py-1.5 dark:bg-white/5 sm:px-6',
])
}}
>
<x-filament::loading-indicator
:attributes="
\Filament\Support\prepare_inherited_attributes(
new \Illuminate\View\ComponentAttributeBag([
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
'wire:target' => 'reorderTable',
])
)->class(['h-5 w-5 text-gray-400 dark:text-gray-500'])
"
/>
<span
class="text-sm font-medium leading-6 text-gray-700 dark:text-gray-200"
>
{{ __('filament-tables::table.reorder_indicator') }}
</span>
</div>

View File

@@ -0,0 +1,33 @@
@props([
'alpineHidden' => null,
'alpineSelected' => null,
'recordAction' => null,
'recordUrl' => null,
'striped' => false,
])
@php
$hasAlpineHiddenClasses = filled($alpineHidden);
$hasAlpineSelectedClasses = filled($alpineSelected);
$stripedClasses = 'bg-gray-50 dark:bg-white/5';
@endphp
<tr
@if ($hasAlpineHiddenClasses || $hasAlpineSelectedClasses)
x-bind:class="{
{{ $hasAlpineHiddenClasses ? "'hidden': {$alpineHidden}," : null }}
{{ $hasAlpineSelectedClasses && (! $striped) ? "'{$stripedClasses}': {$alpineSelected}," : null }}
{{ $hasAlpineSelectedClasses ? "'[&>*:first-child]:relative [&>*:first-child]:before:absolute [&>*:first-child]:before:start-0 [&>*:first-child]:before:inset-y-0 [&>*:first-child]:before:w-0.5 [&>*:first-child]:before:bg-primary-600 [&>*:first-child]:dark:before:bg-primary-500': {$alpineSelected}," : null }}
}"
@endif
{{
$attributes->class([
'fi-ta-row [@media(hover:hover)]:transition [@media(hover:hover)]:duration-75',
'hover:bg-gray-50 dark:hover:bg-white/5' => $recordAction || $recordUrl,
$stripedClasses => $striped,
])
}}
>
{{ $slot }}
</tr>

View File

@@ -0,0 +1,45 @@
@php
use Illuminate\View\ComponentAttributeBag;
@endphp
@props([
'debounce' => '500ms',
'onBlur' => false,
'placeholder' => __('filament-tables::table.fields.search.placeholder'),
'wireModel' => 'tableSearch',
])
@php
$wireModelAttribute = $onBlur ? 'wire:model.blur' : "wire:model.live.debounce.{$debounce}";
@endphp
<div
x-id="['input']"
{{ $attributes->class(['fi-ta-search-field']) }}
>
<label x-bind:for="$id('input')" class="sr-only">
{{ __('filament-tables::table.fields.search.label') }}
</label>
<x-filament::input.wrapper
inline-prefix
prefix-icon="heroicon-m-magnifying-glass"
prefix-icon-alias="tables::search-field"
:wire:target="$wireModel"
>
<x-filament::input
:attributes="
(new ComponentAttributeBag())->merge([
'autocomplete' => 'off',
'inlinePrefix' => true,
'placeholder' => $placeholder,
'type' => 'search',
'wire:key' => $this->getId() . '.table.' . $wireModel . '.field.input',
$wireModelAttribute => $wireModel,
'x-bind:id' => '$id(\'input\')',
'x-on:keyup' => 'if ($event.key === \'Enter\') { $wire.$refresh() }',
])
"
/>
</x-filament::input.wrapper>
</div>

View File

@@ -0,0 +1,10 @@
<x-filament-tables::cell
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-ta-selection-cell w-1'])
"
>
<div class="px-3 py-4">
{{ $slot }}
</div>
</x-filament-tables::cell>

View File

@@ -0,0 +1,21 @@
@props([
'label' => null,
])
<label class="flex">
<x-filament::input.checkbox
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->merge([
'wire:loading.attr' => 'disabled',
'wire:target' => implode(',', \Filament\Tables\Table::LOADING_TARGETS),
], escape: false)
"
/>
@if (filled($label))
<span class="sr-only">
{{ $label }}
</span>
@endif
</label>

View File

@@ -0,0 +1,10 @@
<x-filament-tables::cell
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-ta-group-selection-cell bg-gray-50 dark:bg-white/5 w-1'])
"
>
<div class="px-3">
{{ $slot }}
</div>
</x-filament-tables::cell>

View File

@@ -0,0 +1,26 @@
@props([
'key',
'page' => null,
'title',
])
{{-- format-ignore-start --}}
<x-filament-tables::selection.checkbox
:wire:key="$this->getId() . 'table.bulk_select_group.checkbox.' . $page"
:label="__('filament-tables::table.fields.bulk_select_group.label', ['title' => $title])"
:x-bind:checked="'
const recordsInGroup = getRecordsInGroupOnPage(' . \Illuminate\Support\Js::from($key) . ')
if (recordsInGroup.length && areRecordsSelected(recordsInGroup)) {
$el.checked = true
return \'checked\'
}
$el.checked = false
return null
'"
:x-on:click="'toggleSelectRecordsInGroup(' . \Illuminate\Support\Js::from($key) . ')'"
/>
{{-- format-ignore-end --}}

View File

@@ -0,0 +1,68 @@
@props([
'allSelectableRecordsCount',
'deselectAllRecordsAction' => 'deselectAllRecords',
'end' => null,
'page' => null,
'selectAllRecordsAction' => 'selectAllRecords',
'selectCurrentPageOnly' => false,
'selectedRecordsCount',
'selectedRecordsPropertyName' => 'selectedRecords',
])
<div
x-cloak
{{
$attributes
->merge([
'wire:key' => "{$this->getId()}.table.selection.indicator",
], escape: false)
->class([
'fi-ta-selection-indicator flex flex-col justify-between gap-y-1 bg-gray-50 px-3 py-2 dark:bg-white/5 sm:flex-row sm:items-center sm:px-6 sm:py-1.5',
])
}}
>
<div class="flex gap-x-3">
<x-filament::loading-indicator
x-show="isLoading"
class="h-5 w-5 text-gray-400 dark:text-gray-500"
/>
<span
x-text="
window.pluralize(@js(__('filament-tables::table.selection_indicator.selected_count')), {{ $selectedRecordsPropertyName }}.length, {
count: {{ $selectedRecordsPropertyName }}.length,
})
"
class="text-sm font-medium leading-6 text-gray-700 dark:text-gray-200"
></span>
</div>
<div class="flex gap-x-3">
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\Tables\View\TablesRenderHook::SELECTION_INDICATOR_ACTIONS_BEFORE, scopes: static::class) }}
<div class="flex gap-x-3">
<x-filament::link
color="primary"
tag="button"
:x-on:click="$selectAllRecordsAction"
:x-show="$selectCurrentPageOnly ? '! areRecordsSelected(getRecordsOnPage())' : $allSelectableRecordsCount . ' !== ' . $selectedRecordsPropertyName . '.length'"
{{-- Make sure the Alpine attributes get re-evaluated after a Livewire request: --}}
:wire:key="$this->getId() . 'table.selection.indicator.actions.select-all.' . $allSelectableRecordsCount . '.' . $page"
>
{{ trans_choice('filament-tables::table.selection_indicator.actions.select_all.label', $allSelectableRecordsCount) }}
</x-filament::link>
<x-filament::link
color="danger"
tag="button"
:x-on:click="$deselectAllRecordsAction"
>
{{ __('filament-tables::table.selection_indicator.actions.deselect_all.label') }}
</x-filament::link>
</div>
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\Tables\View\TablesRenderHook::SELECTION_INDICATOR_ACTIONS_AFTER, scopes: static::class) }}
{{ $end }}
</div>
</div>

View File

@@ -0,0 +1,5 @@
<td
{{ $attributes->class(['fi-ta-summary-header-cell px-3 py-2 text-sm font-medium text-gray-950 dark:text-white sm:first-of-type:ps-6']) }}
>
{{ $slot }}
</td>

View File

@@ -0,0 +1,135 @@
@props([
'actions' => false,
'actionsPosition' => null,
'columns',
'extraHeadingColumn' => false,
'groupColumn' => null,
'groupsOnly' => false,
'placeholderColumns' => true,
'pluralModelLabel',
'recordCheckboxPosition' => null,
'records',
'selectionEnabled' => false,
])
@php
use Filament\Support\Enums\Alignment;
use Filament\Tables\Columns\Column;
use Filament\Tables\Enums\ActionsPosition;
use Filament\Tables\Enums\RecordCheckboxPosition;
if ($groupsOnly && $groupColumn) {
$columns = collect($columns)
->reject(fn (Column $column): bool => $column->getName() === $groupColumn)
->all();
}
$hasPageSummary = (! $groupsOnly) && $records instanceof \Illuminate\Contracts\Pagination\Paginator && $records->hasPages();
@endphp
@if ($hasPageSummary)
<x-filament-tables::row
class="fi-ta-summary-header-row bg-gray-50 dark:bg-white/5"
>
@if ($placeholderColumns && $actions && in_array($actionsPosition, [ActionsPosition::BeforeCells, ActionsPosition::BeforeColumns]))
<td></td>
@endif
@if ($placeholderColumns && $selectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells)
<td></td>
@endif
@if ($extraHeadingColumn)
<x-filament-tables::summary.header-cell>
{{ __('filament-tables::table.summary.heading', ['label' => $pluralModelLabel]) }}
</x-filament-tables::summary.header-cell>
@endif
@foreach ($columns as $column)
@if ($placeholderColumns || $column->hasSummary())
@php
$alignment = $column->getAlignment() ?? Alignment::Start;
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
$hasColumnHeaderLabel = (! $placeholderColumns) || $column->hasSummary();
@endphp
<x-filament-tables::summary.header-cell
:attributes="
\Filament\Support\prepare_inherited_attributes($column->getExtraHeaderAttributeBag())
->class([
'whitespace-nowrap' => ! $column->isHeaderWrapped(),
'whitespace-normal' => $column->isHeaderWrapped(),
match ($alignment) {
Alignment::Start => 'text-start',
Alignment::Center => 'text-center',
Alignment::End => 'text-end',
Alignment::Left => 'text-left',
Alignment::Right => 'text-right',
Alignment::Justify, Alignment::Between => 'text-justify',
default => $alignment,
} => (! ($loop->first && (! $extraHeadingColumn))) && $hasColumnHeaderLabel,
])
"
>
@if ($loop->first && (! $extraHeadingColumn))
{{ __('filament-tables::table.summary.heading', ['label' => $pluralModelLabel]) }}
@elseif ($hasColumnHeaderLabel)
{{ $column->getLabel() }}
@endif
</x-filament-tables::summary.header-cell>
@endif
@endforeach
@if ($placeholderColumns && $actions && in_array($actionsPosition, [ActionsPosition::AfterColumns, ActionsPosition::AfterCells]))
<td></td>
@endif
@if ($placeholderColumns && $selectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::AfterCells)
<td></td>
@endif
</x-filament-tables::row>
@php
$query = $this->getPageTableSummaryQuery();
$selectedState = $this->getTableSummarySelectedState($query)[0] ?? [];
@endphp
<x-filament-tables::summary.row
:actions="$actions"
:actions-position="$actionsPosition"
:columns="$columns"
:extra-heading-column="$extraHeadingColumn"
:heading="__('filament-tables::table.summary.subheadings.page', ['label' => $pluralModelLabel])"
:placeholder-columns="$placeholderColumns"
:query="$query"
:record-checkbox-position="$recordCheckboxPosition"
:selected-state="$selectedState"
:selection-enabled="$selectionEnabled"
/>
@endif
@php
$query = $this->getAllTableSummaryQuery();
$selectedState = $this->getTableSummarySelectedState($query)[0] ?? [];
@endphp
<x-filament-tables::summary.row
:actions="$actions"
:actions-position="$actionsPosition"
:columns="$columns"
:extra-heading-column="$extraHeadingColumn"
:groups-only="$groupsOnly"
:heading="__(($hasPageSummary ? 'filament-tables::table.summary.subheadings.all' : 'filament-tables::table.summary.heading'), ['label' => $pluralModelLabel])"
:placeholder-columns="$placeholderColumns"
:query="$query"
:record-checkbox-position="$recordCheckboxPosition"
:selected-state="$selectedState"
:selection-enabled="$selectionEnabled"
@class([
'bg-gray-50 dark:bg-white/5' => ! $hasPageSummary,
])
/>

View File

@@ -0,0 +1,115 @@
@props([
'actions' => false,
'actionsPosition' => null,
'columns',
'extraHeadingColumn' => false,
'groupColumn' => null,
'groupsOnly' => false,
'heading',
'placeholderColumns' => true,
'query',
'selectionEnabled' => false,
'selectedState',
'recordCheckboxPosition' => null,
])
@php
use Filament\Support\Enums\Alignment;
use Filament\Tables\Columns\Column;
use Filament\Tables\Enums\ActionsPosition;
use Filament\Tables\Enums\RecordCheckboxPosition;
if ($groupsOnly && $groupColumn) {
$columns = collect($columns)
->reject(fn (Column $column): bool => $column->getName() === $groupColumn)
->all();
}
@endphp
<x-filament-tables::row
:attributes="
\Filament\Support\prepare_inherited_attributes($attributes)
->class(['fi-ta-summary-row'])
"
>
@if ($placeholderColumns && $actions && in_array($actionsPosition, [ActionsPosition::BeforeCells, ActionsPosition::BeforeColumns]))
<td></td>
@endif
@if ($placeholderColumns && $selectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::BeforeCells)
<td></td>
@endif
@if ($extraHeadingColumn || $groupsOnly)
<x-filament-tables::cell
class="text-sm font-medium text-gray-950 dark:text-white"
>
<span class="px-3 py-4">
{{ $heading }}
</span>
</x-filament-tables::cell>
@else
@php
$headingColumnSpan = 1;
foreach ($columns as $index => $column) {
if ($index === array_key_first($columns)) {
continue;
}
if ($column->hasSummary()) {
break;
}
$headingColumnSpan++;
}
@endphp
@endif
@foreach ($columns as $column)
@if (($loop->first || $extraHeadingColumn || $groupsOnly || ($loop->iteration > $headingColumnSpan)) && ($placeholderColumns || $column->hasSummary()))
@php
$alignment = $column->getAlignment() ?? Alignment::Start;
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
@endphp
<x-filament-tables::cell
:colspan="($loop->first && (! $extraHeadingColumn) && (! $groupsOnly) && ($headingColumnSpan > 1)) ? $headingColumnSpan : null"
@class([
match ($alignment) {
Alignment::Start => 'text-start',
Alignment::Center => 'text-center',
Alignment::End => 'text-end',
Alignment::Left => 'text-left',
Alignment::Right => 'text-right',
Alignment::Justify, Alignment::Between => 'text-justify',
default => $alignment,
},
])
>
@if ($loop->first && (! $extraHeadingColumn) && (! $groupsOnly))
<span
class="flex px-3 py-4 text-sm font-medium text-gray-950 dark:text-white"
>
{{ $heading }}
</span>
@elseif ((! $placeholderColumns) || $column->hasSummary())
@foreach ($column->getSummarizers() as $summarizer)
{{ $summarizer->query($query)->selectedState($selectedState) }}
@endforeach
@endif
</x-filament-tables::cell>
@endif
@endforeach
@if ($placeholderColumns && $actions && in_array($actionsPosition, [ActionsPosition::AfterColumns, ActionsPosition::AfterCells]))
<td></td>
@endif
@if ($placeholderColumns && $selectionEnabled && $recordCheckboxPosition === RecordCheckboxPosition::AfterCells)
<td></td>
@endif
</x-filament-tables::row>

View File

@@ -0,0 +1,44 @@
@props([
'footer' => null,
'header' => null,
'headerGroups' => null,
'reorderable' => false,
'reorderAnimationDuration' => 300,
])
<table
{{ $attributes->class(['fi-ta-table w-full table-auto divide-y divide-gray-200 text-start dark:divide-white/5']) }}
>
@if ($header)
<thead class="divide-y divide-gray-200 dark:divide-white/5">
@if ($headerGroups)
<tr class="bg-gray-100 dark:bg-transparent">
{{ $headerGroups }}
</tr>
@endif
<tr class="bg-gray-50 dark:bg-white/5">
{{ $header }}
</tr>
</thead>
@endif
<tbody
@if ($reorderable)
x-on:end.stop="$wire.reorderTable($event.target.sortable.toArray())"
x-sortable
data-sortable-animation-duration="{{ $reorderAnimationDuration }}"
@endif
class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5"
>
{{ $slot }}
</tbody>
@if ($footer)
<tfoot class="bg-gray-50 dark:bg-white/5">
<tr>
{{ $footer }}
</tr>
</tfoot>
@endif
</table>