Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions demo/app/Sharp/Dashboard/PostDashboard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace App\Sharp\Dashboard;

use App\Sharp\Utils\Filters\PeriodRequiredFilter;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Code16\Sharp\Dashboard\Layout\DashboardLayout;
use Code16\Sharp\Dashboard\Layout\DashboardLayoutRow;
use Code16\Sharp\Dashboard\SharpDashboard;
use Code16\Sharp\Dashboard\Widgets\SharpFigureWidget;
use Code16\Sharp\Dashboard\Widgets\SharpGraphWidgetDataSet;
use Code16\Sharp\Dashboard\Widgets\SharpLineGraphWidget;
use Code16\Sharp\Dashboard\Widgets\WidgetsContainer;
use Code16\Sharp\EntityList\Filters\HiddenFilter;

class PostDashboard extends SharpDashboard
{
protected function buildWidgets(WidgetsContainer $widgetsContainer): void
{
$widgetsContainer
->addWidget(
SharpLineGraphWidget::make('visits_line')
->setTitle('Visits')
->setHeight(200)
->setShowLegend(false)
->setDisplayHorizontalAxisAsTimeline()
)
->addWidget(
SharpFigureWidget::make('visit_count')
->setTitle('Total visits'),
)
->addWidget(
SharpFigureWidget::make('page_count')
->setTitle('Total pageviews'),
);
}

protected function buildDashboardLayout(DashboardLayout $dashboardLayout): void
{
$dashboardLayout
->addFullWidthWidget('visits_line')
->addRow(fn (DashboardLayoutRow $row) => $row
->addWidget(6, 'visit_count')
->addWidget(6, 'page_count')
);
}

public function getFilters(): ?array
{
return [
PeriodRequiredFilter::class,
HiddenFilter::make('post'),
];
}

protected function buildWidgetsData(): void
{
$visitCount = $this->getStartDate()->diffInDays($this->getEndDate()) * rand(10, 100);

$this
->setFigureData('visit_count', figure: $visitCount)
->setFigureData('page_count', figure: $visitCount * rand(2, 10))
->addGraphDataSet(
'visits_line',
SharpGraphWidgetDataSet::make(collect(CarbonPeriod::create($this->getStartDate(), $this->getEndDate()))
->mapWithKeys(fn (Carbon $day, $k) => [
$day->isoFormat('L') => rand(10, 100),
]))
->setLabel('Visits')
->setColor('#274754'),
);
}

protected function getStartDate(): Carbon
{
return $this->queryParams->filterFor(PeriodRequiredFilter::class)->getStart();
}

protected function getEndDate(): Carbon
{
return min(
$this->queryParams->filterFor(PeriodRequiredFilter::class)->getEnd(),
today()->subDay(),
);
}
}
23 changes: 23 additions & 0 deletions demo/app/Sharp/Entities/PostDashboardEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Sharp\Entities;

use App\Sharp\Dashboard\PostDashboard;
use Code16\Sharp\Auth\SharpEntityPolicy;
use Code16\Sharp\Utils\Entities\SharpDashboardEntity;

class PostDashboardEntity extends SharpDashboardEntity
{
protected ?string $view = PostDashboard::class;

protected function getPolicy(): ?SharpEntityPolicy
{
return new class() extends SharpEntityPolicy
{
public function entity($user): bool
{
return $user->isAdmin();
}
};
}
}
8 changes: 8 additions & 0 deletions demo/app/Sharp/Posts/PostShow.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Models\Post;
use App\Sharp\Entities\AuthorEntity;
use App\Sharp\Entities\PostBlockEntity;
use App\Sharp\Entities\PostDashboardEntity;
use App\Sharp\Entities\PostEntity;
use App\Sharp\Posts\Commands\EvaluateDraftPostWizardCommand;
use App\Sharp\Posts\Commands\PreviewPostCommand;
Expand All @@ -14,6 +15,7 @@
use App\Sharp\Utils\Embeds\TableOfContentsEmbed;
use App\Sharp\Utils\Filters\CategoryFilter;
use Code16\Sharp\Form\Eloquent\Uploads\Transformers\SharpUploadModelFormAttributeTransformer;
use Code16\Sharp\Show\Fields\SharpShowDashboardField;
use Code16\Sharp\Show\Fields\SharpShowEntityListField;
use Code16\Sharp\Show\Fields\SharpShowFileField;
use Code16\Sharp\Show\Fields\SharpShowListField;
Expand Down Expand Up @@ -64,6 +66,11 @@ protected function buildShowFields(FieldsContainer $showFields): void
->setLabel('File')
)
)
->addField(
SharpShowDashboardField::make(PostDashboardEntity::class)
->setLabel('Analytics')
->hideFilterWithValue('post', fn ($instanceId) => $instanceId)
)
->addField(
SharpShowEntityListField::make(PostBlockEntity::class)
->setLabel('Blocks')
Expand Down Expand Up @@ -94,6 +101,7 @@ protected function buildShowLayout(ShowLayout $showLayout): void
$column->withField('content');
});
})
->addDashboardSection(PostDashboardEntity::class)
->addEntityListSection(PostBlockEntity::class);
}

Expand Down
3 changes: 2 additions & 1 deletion docs/.vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export function sidebar(): DefaultTheme.SidebarItem[] {
{ text: 'Picture', link: '/guide/show-fields/picture.md' },
{ text: 'List', link: '/guide/show-fields/list.md' },
{ text: 'File', link: '/guide/show-fields/file.md' },
{ text: 'Embedded EntityList', link: '/guide/show-fields/embedded-entity-list.md' },
{ text: 'Entity List', link: '/guide/show-fields/entity-list.md' },
{ text: 'Dashboard', link: '/guide/show-fields/dashboard.md' },
// { text: 'Custom show field', link: '/guide/custom-show-fields.md' }
]
},
Expand Down
6 changes: 3 additions & 3 deletions docs/guide/building-show-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class MyShow extends SharpShow

Each available Show field is detailed below; here are the attributes they all share :

- `setShowIfEmpty(bool $show = true): self`: by default, an empty field (meaning: with null or empty data) is not displayed at all in the Show UI. You can change this behaviour with this attribute. This method has no impact for [embedded EntityList](show-fields/embedded-entity-list.md).
- `setShowIfEmpty(bool $show = true): self`: by default, an empty field (meaning: with null or empty data) is not displayed at all in the Show UI. You can change this behaviour with this attribute. This method has no impact for the [Entity List field](show-fields/entity-list.md).

#### Available simple Show fields

Expand Down Expand Up @@ -95,9 +95,9 @@ Notice that you have three possibilities for the actual code of this Entity List

As always with Sharp, implementation is up to you.

The next thing to do is to scope the data of the embedded Entity List. In our case, we want to display and interact only with the products for this order... For this and more on personalization, refer to the detailed documentation of this field:
The next thing to do is to scope the data of the Entity List field. In our case, we want to display and interact only with the products for this order... For this and more on personalization, refer to the detailed documentation of this field:

- [embedded EntityList](show-fields/embedded-entity-list.md)
- [Entity List field](show-fields/entity-list.md)

### `buildShowLayout(ShowLayout $showLayout): void`

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/entity-class.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,5 @@ You must remove all `->declareEntity()` calls in order to use `->declareEntityRe
:::

::: warning
If you are using a custom entity resolver, you won’t be able to use the `SharpEntity` classes in the [menu](building-menu.md), or in [`LinkTo` links](link-to.md), or for [embedded entity lists](show-fields/embedded-entity-list.md): you will have to use the entity key instead. For instance: `LinkToForm::make('products', $id)`.
If you are using a custom entity resolver, you won’t be able to use the `SharpEntity` classes in the [menu](building-menu.md), or in [`LinkTo` links](link-to.md), or for [Entity List fields](show-fields/entity-list.md): you will have to use the entity key instead. For instance: `LinkToForm::make('products', $id)`.
:::
124 changes: 124 additions & 0 deletions docs/guide/show-fields/dashboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Dashboard

Class: `Code16\Sharp\Show\Fields\SharpShowDashboardField`.

The field allows you to integrate a [Dashboard](../building-dashboard.md) into your Show Page.

## Constructor

This field needs, as first parameter, either the entity key or the `SharpDashboardEntity` class that declares the dashboard which will be included in the Show Page.

For instance:

```php
SharpShowDashboardField::make('posts_dashboard')
```

or

```php
SharpShowDashboardField::make(PostDashboardEntity::class)
```
::: warning
This last syntax is better in terms of DX (since it allows using the IDE to navigate to the Entity List implementation), but it won’t work in two specific cases: if you use a custom `SharpEntityResolver` or if you your Entity is declared with multiple keys.
:::

## Configuration

### `hideFilterWithValue(string $filterName, $value)`
This is the most important method of the field, since it will not only hide a filter but also set its value. The purpose is to allow to **scope the data to the instance** of the Show Page. For example, let’s say we display a Post and that we want to embed a dashboard with the post's statistics:


```php
class PostShow extends SharpShow
{
// ...

public function buildShowFields(FieldsContainer $showFields): void
{
$showFields->addField(
SharpShowDashboardField::make(PostDashboardEntity::class)
->hideFilterWithValue(PostFilter::class, 64)
);
}
}
```

Here we're scoping the `PostDashboard` declared in the `PostDashboardEntity` to the instance of the `Post` with id 64.


You can pass a closure as the value, and it will contain the current Show instance id. In most cases, you'll have to write this:

```php
SharpShowDashboardField::make(PostDashboardEntity::class)
->hideFilterWithValue(PostFilter::class, fn ($instanceId) => $instanceId);
```

**One final note**: sometimes the linked filter is really just a scope, never displayed to the user. In this case, it can be tedious to write a full implementation in the Dashboard. In this situation, you can use the `HiddenFiler` class for the filter, passing a key:

```php
class PostShow extends SharpShow
{
// ...

public function buildShowFields(FieldsContainer $showFields): void
{
$showFields->addField(
SharpShowDashboardField::make(PostDashboardEntity::class)
->hideFilterWithValue('post', fn ($instanceId) => $instanceId);
);
}
}
```

```php
use \Code16\Sharp\EntityList\Filters\HiddenFilter;

class PostDashboard extends SharpDashboard
{
// ...

protected function getFilters(): ?array
{
return [
HiddenFilter::make('post')
];
}

protected function buildWidgetsData(): void
{
return $this->setFigureData('visit_count',
figure: Post::query()
->findOrFail($this->queryParams->filterFor('post'))
->get()?->visit_count
);
}
}
```

### `hideDashboardCommand(array|string $commands): self`

Use it to hide any dashboard command in this particular Dashboard (useful when reusing a Dashboard). This will apply before looking at authorizations.

## Display in layout

To display your dashboard in your show page's layout, you have to use the `addDashboardSection()` method in your Show Page's `buildShowLayout()` method.

```php
protected function buildShowLayout(ShowLayout $showLayout): void
{
$showLayout
->addSection(function (ShowLayoutSection $section) {
$section
->addColumn(7, function (ShowLayoutColumn $column) {
$column
->withFields(categories: 5, author: 7)
// ...
})
->addColumn(5, function (ShowLayoutColumn $column) {
// ...
});
})
->addDashboardSection(PostDashboardEntity::class);
}
```
Loading
Loading