jaocero/activity-timeline

轻松将时间轴添加到自定义页面或infolist条目。此外,它与Spatie Activitylog无缝配合,便于跟踪。

资助包维护!
jaocero

安装次数: 26 130

依赖项: 0

建议者: 0

安全: 0

星标: 59

关注者: 2

分支: 15

v1.2.9 2024-09-04 12:06 UTC

This package is auto-updated.

Last update: 2024-09-04 12:07:30 UTC


README

Header

Latest Version on Packagist Total Downloads

轻松将时间轴添加到自定义页面或infolist条目。此外,它与Spatie Activitylog无缝配合,便于跟踪。

安装

您可以通过composer安装此包。

composer require jaocero/activity-timeline

为了遵守Filament的主题方法,您需要使用自定义主题才能使用此插件。

自定义主题安装 > Filament 文档

将插件的视图添加到您的 tailwind.config.js 文件中。

content: [
    ...'./vendor/jaocero/activity-timeline/resources/views/**/*.blade.php',
]

用法

此插件已在Infolists构建器中可用,并且现在支持 ->state([])->record() 方法。

public function activityTimelineInfolist(Infolist $infolist): Infolist
{
    return $infolist
        ->state([
            'activities' => [
                    [
                        'title' => "Published Article 🔥 - <span class='italic font-normal dark:text-success-400 text-success-600'>Published with Laravel Filament and Tailwind CSS</span>",
                        'description' => "<span>Approved and published. Here is the <a href='#' class='font-bold hover:underline dark:text-orange-300'>link.</a></span>",
                        'status' => 'published',
                        'created_at' => now()->addDays(8),
                    ],
                    [
                        'title' => 'Reviewing Article - Final Touches',
                        'description' => "<span class='italic'>Reviewing the article and making it ready for publication.</span>",
                        'status' => '',
                        'created_at' => now()->addDays(5),
                    ],
                    [
                        'title' => "Drafting Article - <span class='text-sm italic font-normal text-purple-800 dark:text-purple-300'>Make it ready for review</span>",
                        'description' => 'Drafting the article and making it ready for review.',
                        'status' => 'drafting',
                        'created_at' => now()->addDays(2),
                    ],
                    [
                        'title' => 'Ideation - Looking for Ideas 🤯',
                        'description' => 'Idea for my article.',
                        'status' => 'ideation',
                        'created_at' => now()->subDays(7),
                    ]
                ]
        ])
        ->schema([

         /*
    	    You should enclose the entire components within a personalized "ActivitySection" entry.
            This section functions identically to the repeater entry; you simply have to provide the array state's key.
    	 */

            ActivitySection::make('activities')
                ->label('My Activities')
                ->description('These are the activities that have been recorded.')
                ->schema([
                    ActivityTitle::make('title')
                        ->placeholder('No title is set')
                        ->allowHtml(), // Be aware that you will need to ensure that the HTML is safe to render, otherwise your application will be vulnerable to XSS attacks.
                    ActivityDescription::make('description')
                        ->placeholder('No description is set')
                        ->allowHtml(),
                    ActivityDate::make('created_at')
                        ->date('F j, Y', 'Asia/Manila')
                        ->placeholder('No date is set.'),
                    ActivityIcon::make('status')
                        ->icon(fn (string | null $state): string | null => match ($state) {
                            'ideation' => 'heroicon-m-light-bulb',
                            'drafting' => 'heroicon-m-bolt',
                            'reviewing' => 'heroicon-m-document-magnifying-glass',
                            'published' => 'heroicon-m-rocket-launch',
                            default => null,
                        })
                        ->color(fn (string | null $state): string | null => match ($state) {
                            'ideation' => 'purple',
                            'drafting' => 'info',
                            'reviewing' => 'warning',
                            'published' => 'success',
                            default => 'gray',
                        }),
                ])
                ->showItemsCount(2) // Show up to 2 items
                ->showItemsLabel('View Old') // Show "View Old" as link label
                ->showItemsIcon('heroicon-m-chevron-down') // Show button icon
                ->showItemsColor('gray') // Show button color and it supports all colors
                ->aside(true)
                ->headingVisible(true) // make heading visible or not
                ->extraAttributes(['class'=>'my-new-class']) // add extra class
        ]);
}

当使用 ->record() 函数时,您需要以类似于以下代码所示的方式提供您的模型

protected $activities;

public function __construct()
{
    $this->activities = User::query()->with('activities')->where('id', auth()->user()->id)->first();
}

public function activityTimelineInfolist(Infolist $infolist): Infolist
{
    return $infolist
        ->record($this->activities)
        // ... remaining code
}

有时,当我们没有信息向用户显示时,通过显示某些内容来改善他们的体验是很重要的。因此,我包括了一个空状态,类似于 Filament 表格空状态 中的。

public function activityTimelineInfolist(Infolist $infolist): Infolist
{
    return $infolist
        ->state([
            'activities' => []
        )]
        ->schema([
            ActivitySection::make('activities')
                // ... other code
                ->emptyStateHeading('No activities yet.')
                ->emptyStateDescription('Check back later for activities that have been recorded.')
                ->emptyStateIcon('heroicon-o-bolt-slash')
        ])
}

与Spatie Activity Log包一起使用

此插件与 spatie/laravel-activitylog 一起工作,使记录您的应用程序中的用户操作变得容易。它还可以自动记录模型事件,并将所有内容存储在 activity_log 表中。要使用此插件,只需安装 spatie/laravel-activitylog,设置它,然后您就可以开始了。

创建自定义页面

您需要在您的 resources 中创建一个自定义页面,以显示根据路由传递的记录的所有活动。

php artisan make:filament-page ViewOrderActivities --resource=OrderResource --type=custom

在资源类中包含页面

只需将自定义页面包含在 getPages() 方法中,这样我们就可以访问它。

public static function getPages(): array
{
    return [
        // ... other pages
        // The format of route doesn't matter, as long as it includes the route parameter {record}.
        'activities' => Pages\ViewOrderActivities::route('/order/{record}/activities'),
    ];
}

在您的表格的 actions 方法中,包含一个额外的自定义操作。此操作应将用户重定向到我们之前生成的自定义页面。

public static function table(Table $table): Table
{
    return $table
        ->columns([
            // ...
        ])
        ->filters([
            // ...
        ])
        ->actions([
            Tables\Actions\Action::make('view_activities')
                ->label('Activities')
                ->icon('heroicon-m-bolt')
                ->color('purple')
                ->url(fn ($record) => OrderResource::getUrl('activities', ['record' => $record])),
        ])
        ->bulkActions([
            // ...
        ]);
}

设置您的自定义页面

您的自定义页面需要更改。使用 Page 类进行扩展而不是使用由插件提供的特定类 ActivityTimelinePage。此外,您还应包含您的资源类。

use App\Filament\Resources\OrderResource;
use JaOcero\ActivityTimeline\Pages\ActivityTimelinePage;

class ViewOrderActivities extends ActivityTimelinePage
{
    protected static string $resource = OrderResource::class;
}

配置

在幕后,此插件使用之前提到的infolist条目。我们只修改属性/数据,但逻辑保持不变。

use App\Filament\Resources\OrderResource;
use JaOcero\ActivityTimeline\Pages\ActivityTimelinePage;

class ViewOrderActivities extends ActivityTimelinePage
{
    protected static string $resource = OrderResource::class;

    protected function configuration(): array
    {
        return [
            'activity_section' => [
                'label' => 'Activities', // label for the section
                'description' => 'These are the activities that have been recorded.', // description for the section
                'show_items_count' => 0, // show the number of items to be shown
                'show_items_label' => 'Show more', // show button label
                'show_items_icon' => 'heroicon-o-chevron-down', // show button icon,
                'show_items_color' => 'gray', // show button color,
                'aside' => true, // show the section in the aside
                'empty_state_heading' => 'No activities yet', // heading for the empty state
                'empty_state_description' => 'Check back later for activities that have been recorded.', // description for the empty state
                'empty_state_icon' => 'heroicon-o-bolt-slash', // icon for the empty state
                'heading_visible' => true, // show the heading
                'extra_attributes' => [], // extra attributes
            ],
            'activity_title' => [
                'placeholder' => 'No title is set', // this will show when there is no title
                'allow_html' => true, // set true to allow html in the title

                /**
                 * You are free to adjust the state before displaying it on your page.
                 * Take note that the state returns these data below:
                 *      [
                 *       'log_name' => $activity->log_name,
                  *      'description' => $activity->description,
                  *      'subject' => $activity->subject,
                  *      'event' => $activity->event,
                  *      'causer' => $activity->causer,
                  *      'properties' => json_decode($activity->properties, true),
                  *      'batch_uuid' => $activity->batch_uuid,
                  *     ]

                  * If you wish to make modifications, please refer to the default code in the HasSetting trait.
                 */

                // 'modify_state' => function (array $state) {
                //
                // }

            ],
            'activity_description' => [
                'placeholder' => 'No description is set', // this will show when there is no description
                'allow_html' => true, // set true to allow html in the description

                /**
                 * You are free to adjust the state before displaying it on your page.
                 * Take note that the state returns these data below:
                 *      [
                 *       'log_name' => $activity->log_name,
                  *      'description' => $activity->description,
                  *      'subject' => $activity->subject,
                  *      'event' => $activity->event,
                  *      'causer' => $activity->causer,
                  *      'properties' => json_decode($activity->properties, true),
                  *      'batch_uuid' => $activity->batch_uuid,
                  *     ]

                  * If you wish to make modifications, please refer to the default code in the HasSetting trait.
                 */

                // 'modify_state' => function (array $state) {
                //
                // }

            ],
            'activity_date' => [
                'name' => 'created_at', // or updated_at
                'date' => 'F j, Y g:i A', // date format
                'placeholder' => 'No date is set', // this will show when there is no date
            ],
            'activity_icon' => [
                'icon' => fn (string | null $state): string | null => match ($state) {
                    /**
                     * 'event_name' => 'heroicon-o-calendar',
                     * ... and more
                     */
                    default => null
                },
                'color' => fn (string | null $state): string | null => match ($state) {
                    /**
                     * 'event_name' => 'primary',
                     * ... and more
                     */
                    default => null
                },
            ]
        ];
    }
}

样式自定义

类似于Filament,此插件还包含CSS hook类,这些类可以通过CSS自定义不同的HTML元素。

.fi-timeline-section {
    @apply bg-transparent !important;
}

此插件包含许多CSS hook类。为了简单起见,请考虑使用浏览器开发者工具仔细检查元素并识别这些类。

就这些!如果您遇到任何问题或想要讨论的功能,请随时在我们的Discord频道中与我聊天。

更新日志

请参阅 CHANGELOG 了解最近更改的详细信息。

贡献

请参阅 CONTRIBUTING 了解详细信息。

安全漏洞

请查阅我们的安全策略,了解如何报告安全漏洞:我们的安全策略

致谢

许可证

MIT许可证(MIT)。更多详细信息请参阅许可证文件