Skip to content
Open
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
1 change: 1 addition & 0 deletions demo/app/Sharp/Dashboard/DemoDashboard.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ protected function buildPageAlert(PageAlert $pageAlert): void
{
$pageAlert
->setLevelInfo()
->onSection('stats-section')
->setMessage(
sprintf(
'Graphs below are delimited by period %s - %s (and yes, visits figures are randomly generated)',
Expand Down
15 changes: 7 additions & 8 deletions demo/app/Sharp/Posts/PostShow.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,13 @@ protected function buildPageAlert(PageAlert $pageAlert): void
{
$pageAlert
->setLevelInfo()
->setMessage(function (array $data) {
return $data['publication']['is_planned']
? sprintf(
'This post is planned for publication, on %s',
$data['publication']['published_at'],
)
: null;
});
->setMessage(fn (array $data) => $data['publication']['is_planned']
? sprintf(
'This post is planned for publication, on %s',
$data['publication']['published_at'],
)
: null
);
}

public function getInstanceCommands(): ?array
Expand Down
30 changes: 30 additions & 0 deletions docs/guide/page-alerts.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,33 @@ class MyEntityList extends SharpEntityList
}
```

## Attach the page alert to a specific section (Show Page and Dashboard only)

The `onSection()` method allows you to specify the section where the alert should be displayed (instead of the default, the top of the page):

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

protected function buildShowLayout(ShowLayout $showLayout): void
{
$showLayout
->addSection(function (ShowLayoutSection $section) {
$section
->setKey('content')
->addColumn(/* ... */);
})
->addSection(/* ... */);
}

protected function buildPageAlert(PageAlert $pageAlert): void
{
$pageAlert
->setMessage('This page has been edited recently.')
->onSection('content');
}
}
```


2 changes: 1 addition & 1 deletion resources/js/Pages/Dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
</template>

<div class="container @container mx-auto">
<div :class="dashboard.pageAlert ? 'pt-4' : 'pt-10'">
<div :class="dashboard.pageAlert && !dashboard.pageAlert.sectionKey ? 'pt-4' : 'pt-10'">
<DashboardComponent
:dashboard-key="dashboardKey"
:dashboard="dashboard"
Expand Down
12 changes: 10 additions & 2 deletions resources/js/Pages/Show/Show.vue
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@

<WithCommands :commands="commands">
<div class="@container">
<div :class="show.pageAlert ? 'pt-4' : 'pt-6 @3xl:pt-10'">
<template v-if="show.pageAlert">
<div :class="show.pageAlert && !show.pageAlert.sectionKey ? 'pt-4' : 'pt-6 @3xl:pt-10'">
<template v-if="show.pageAlert && !show.pageAlert.sectionKey">
<div class="container">
<PageAlert
class="mb-4"
Expand All @@ -153,6 +153,14 @@
v-show="show.sectionShouldBeVisible(section, locale) || i == 0"
v-slot="{ collapsed, onCollapseToggle }"
>
<template v-if="show.pageAlert?.sectionKey && show.pageAlert.sectionKey === section.key">
<div class="container">
<PageAlert
class="mb-4"
:page-alert="show.pageAlert"
/>
</div>
</template>
<template v-if="show.sectionHasField(section, 'entityList')">
<template v-for="column in section.columns">
<template v-for="row in column.fields">
Expand Down
2 changes: 1 addition & 1 deletion resources/js/dashboard/Dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class Dashboard {
layout: DashboardData['layout'];
data: DashboardData['data'];
filterValues: DashboardData['filterValues'];
pageAlert:DashboardData['pageAlert'];
pageAlert: DashboardData['pageAlert'];
query: DashboardData['query'];

dashboardKey: string;
Expand Down
8 changes: 7 additions & 1 deletion resources/js/dashboard/components/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@

<template>
<WithCommands :commands="commands">
<template v-if="dashboard?.pageAlert">
<template v-if="dashboard && dashboard.pageAlert && !dashboard.pageAlert.sectionKey">
<PageAlert
class="mb-8"
:page-alert="dashboard.pageAlert"
Expand Down Expand Up @@ -186,6 +186,12 @@
</h2>
</template>
</template>
<template v-if="dashboard.pageAlert?.sectionKey && dashboard.pageAlert.sectionKey === section.key">
<PageAlert
class="mb-4"
:page-alert="dashboard.pageAlert"
/>
</template>
<template v-if="dashboard.sectionVisibleFilters(section)?.length || dashboard.visibleCommands?.[section.key]?.flat().length">
<div class="flex gap-2 mb-4">
<template v-if="dashboard.sectionVisibleFilters(section)?.length">
Expand Down
11 changes: 6 additions & 5 deletions resources/js/types/generated.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,6 @@ export type EmbedFormData = {
fields: { [key: string]: FormFieldData };
layout: FormLayoutData | null;
};
export type EmbeddedFieldAuthorizationsData = {
view: boolean;
};
export type EntityListAuthorizationsData = {
create: boolean;
reorder: boolean;
Expand Down Expand Up @@ -726,6 +723,7 @@ export type OrderedListWidgetData = {
export type PageAlertData = {
level: PageAlertLevel;
text: string;
sectionKey: string | null;
buttonLabel: string | null;
buttonUrl: string | null;
};
Expand Down Expand Up @@ -811,7 +809,7 @@ export type ShowDashboardFieldData = {
dashboardKey: string;
hiddenCommands: Array<string>;
endpointUrl: string;
authorizations: EmbeddedFieldAuthorizationsData;
authorizations: ShowFieldAuthorizationsData;
label: string | null;
hiddenFilters: { [key: string]: any } | null;
};
Expand All @@ -838,10 +836,13 @@ export type ShowEntityListFieldData = {
showSearchField: boolean;
showCount: boolean;
endpointUrl: string;
authorizations: EmbeddedFieldAuthorizationsData;
authorizations: ShowFieldAuthorizationsData;
label: string | null;
hiddenFilters: { [key: string]: any } | null;
};
export type ShowFieldAuthorizationsData = {
view: boolean;
};
export type ShowFieldData =
| ShowDashboardFieldData
| ShowEntityListFieldData
Expand Down
1 change: 1 addition & 0 deletions src/Data/PageAlertData.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ final class PageAlertData extends Data
public function __construct(
public PageAlertLevel $level,
public string $text,
public ?string $sectionKey = null,
public ?string $buttonLabel = null,
public ?string $buttonUrl = null,
) {}
Expand Down
9 changes: 9 additions & 0 deletions src/Utils/PageAlerts/PageAlert.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class PageAlert
protected PageAlertLevel $pageAlertLevel = PageAlertLevel::Info;
protected ?string $text;
protected array $data;
protected ?string $sectionKey = null;
protected ?string $buttonLabel = null;
protected ?string $buttonUrl = null;

Expand Down Expand Up @@ -54,6 +55,13 @@ public function setLevelSecondary(): self
return $this->setLevel(PageAlertLevel::Secondary);
}

public function onSection(string $sectionKey): self
{
$this->sectionKey = $sectionKey;

return $this;
}

public function setMessage(Closure|string $message): self
{
$this->text = $message instanceof Closure
Expand All @@ -77,6 +85,7 @@ final public function toArray(): ?array
? Arr::whereNotNull([
'level' => $this->pageAlertLevel,
'text' => $this->text,
'sectionKey' => $this->sectionKey,
'buttonLabel' => $this->buttonLabel,
'buttonUrl' => $this->buttonUrl,
])
Expand Down
27 changes: 27 additions & 0 deletions tests/Http/ShowControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,33 @@ public function buildPageAlert(PageAlert $pageAlert): void
);
});

it('allows to configure a page alert on a specific section', function () {
fakeShowFor('person', new class() extends PersonShow
{
public function buildPageAlert(PageAlert $pageAlert): void
{
$pageAlert
->setLevelInfo()
->onSection('my-section')
->setMessage('My page alert')
->setButton('My button', 'https://example.com');
}
});

$this->get('/sharp/s-list/person/s-show/person/1')
->assertOk()
->assertInertia(fn (Assert $page) => $page
->where('show.pageAlert', [
'level' => PageAlertLevel::Info->value,
'text' => 'My page alert',
'sectionKey' => 'my-section',
'buttonLabel' => 'My button',
'buttonUrl' => 'https://example.com',
])
->etc()
);
});

it('allows to configure a page alert with a closure as content', function () {
fakeShowFor('person', new class() extends PersonShow
{
Expand Down
Loading