Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x] Refine collection visibility for multi-site setups #9583

Merged
merged 11 commits into from
Mar 21, 2024
3 changes: 2 additions & 1 deletion resources/js/components/collections/Listing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<div class="card overflow-hidden p-0" slot-scope="{ filteredRows: rows }">
<data-list-table :rows="rows">
<template slot="cell-title" slot-scope="{ row: collection }">
<a :href="collection.entries_url">{{ __(collection.title) }}</a>
<a v-if="collection.available_in_selected_site" :href="collection.entries_url">{{ __(collection.title) }}</a>
<a v-else :href="collection.edit_url">{{ __(collection.title) }}</a>
</template>
<template slot="actions" slot-scope="{ row: collection, index }">
<dropdown-list placement="left-start">
Expand Down
3 changes: 2 additions & 1 deletion resources/js/components/navigation/Listing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<div class="card p-0" slot-scope="{ filteredRows: rows }">
<data-list-table :rows="rows">
<template slot="cell-title" slot-scope="{ row: structure }">
<a :href="structure.show_url" class="flex items-center" v-text="__(structure.title)" />
<a v-if="structure.available_in_selected_site" :href="structure.show_url" class="flex items-center" v-text="__(structure.title)" />
<a v-else :href="structure.edit_url" class="flex items-center" v-text="__(structure.title)" />
</template>
<template slot="actions" slot-scope="{ row: structure, index }">
<dropdown-list>
Expand Down
57 changes: 41 additions & 16 deletions src/CP/Navigation/CoreNav.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
use Statamic\Facades\GlobalSet as GlobalSetAPI;
use Statamic\Facades\Nav as NavAPI;
use Statamic\Facades\Role as RoleAPI;
use Statamic\Facades\Site;
use Statamic\Facades\Stache;
use Statamic\Facades\Taxonomy as TaxonomyAPI;
use Statamic\Facades\User;
use Statamic\Facades\UserGroup as UserGroupAPI;
use Statamic\Facades\Utility;
use Statamic\Statamic;
Expand Down Expand Up @@ -65,23 +67,41 @@ protected function makeContentSection()
->icon('/content-writing')
->can('index', Collection::class)
->children(function () {
return CollectionAPI::all()->sortBy->title()->map(function ($collection) {
return Nav::item($collection->title())
->url($collection->showUrl())
->can('view', $collection);
});
return CollectionAPI::all()->sortBy->title()
->filter(function ($collection) {
return User::current()->can('configure collections')
|| $collection->sites()->contains(Site::selected()->handle());
})
->map(function ($collection) {
return Nav::item($collection->title())
->url(
$collection->sites()->contains(Site::selected()->handle())
? $collection->showUrl()
: $collection->editUrl()
)
->can('view', $collection);
});
});

Nav::content('Navigation')
->route('navigation.index')
->icon('/hierarchy-files')
->can('index', NavContract::class)
->children(function () {
return NavAPI::all()->sortBy->title()->map(function ($nav) {
return Nav::item($nav->title())
->url($nav->showUrl())
->can('view', $nav);
});
return NavAPI::all()->sortBy->title()
->filter(function ($nav) {
return User::current()->can('configure navs')
|| $nav->sites()->contains(Site::selected()->handle());
})
->map(function ($nav) {
return Nav::item($nav->title())
->url(
$nav->sites()->contains(Site::selected()->handle())
? $nav->showUrl()
: $nav->editUrl()
)
->can('view', $nav);
});
});

Nav::content('Taxonomies')
Expand Down Expand Up @@ -113,13 +133,18 @@ protected function makeContentSection()
->icon('/earth')
->can('index', GlobalSet::class)
->children(function () {
return GlobalSetAPI::all()->sortBy->title()->map(function ($globalSet) {
$localized = $globalSet->inSelectedSite();
return GlobalSetAPI::all()->sortBy->title()
->filter(function ($globalSet) {
return User::current()->can('configure globals')
|| ! is_null($globalSet->inSelectedSite());
})
->map(function ($globalSet) {
$localized = $globalSet->inSelectedSite();

return Nav::item($globalSet->title())
->url($localized ? $localized->editUrl() : $globalSet->editUrl())
->can('view', $globalSet);
})->filter();
return Nav::item($globalSet->title())
->url($localized ? $localized->editUrl() : $globalSet->editUrl())
->can('view', $globalSet);
})->filter();
});

return $this;
Expand Down
42 changes: 24 additions & 18 deletions src/Http/Controllers/CP/Collections/CollectionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,30 @@ public function index()
{
$this->authorize('index', CollectionContract::class, __('You are not authorized to view collections.'));

$collections = Collection::all()->filter(function ($collection) {
return User::current()->can('view', $collection);
})->map(function ($collection) {
return [
'id' => $collection->handle(),
'title' => $collection->title(),
'entries' => $collection->queryEntries()->where('site', Site::selected())->count(),
'edit_url' => $collection->editUrl(),
'delete_url' => $collection->deleteUrl(),
'entries_url' => cp_route('collections.show', $collection->handle()),
'url' => $collection->absoluteUrl(Site::selected()->handle()),
'blueprints_url' => cp_route('collections.blueprints.index', $collection->handle()),
'scaffold_url' => cp_route('collections.scaffold', $collection->handle()),
'deleteable' => User::current()->can('delete', $collection),
'editable' => User::current()->can('edit', $collection),
'blueprint_editable' => User::current()->can('configure fields'),
];
})->values();
$collections = Collection::all()
->filter(function ($collection) {
return User::current()->can('configure collections')
|| User::current()->can('view', $collection)
&& $collection->sites()->contains(Site::selected()->handle());
})
->map(function ($collection) {
return [
'id' => $collection->handle(),
'title' => $collection->title(),
'entries' => $collection->queryEntries()->where('site', Site::selected())->count(),
'edit_url' => $collection->editUrl(),
'delete_url' => $collection->deleteUrl(),
'entries_url' => cp_route('collections.show', $collection->handle()),
'url' => $collection->absoluteUrl(Site::selected()->handle()),
'blueprints_url' => cp_route('collections.blueprints.index', $collection->handle()),
'scaffold_url' => cp_route('collections.scaffold', $collection->handle()),
'deleteable' => User::current()->can('delete', $collection),
'editable' => User::current()->can('edit', $collection),
'blueprint_editable' => User::current()->can('configure fields'),
'available_in_selected_site' => $collection->sites()->contains(Site::selected()->handle()),
];
})
->values();

return view('statamic::collections.index', [
'collections' => $collections,
Expand Down
29 changes: 17 additions & 12 deletions src/Http/Controllers/CP/Navigation/NavigationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,23 @@ public function index()
{
$this->authorize('index', NavContract::class, __('You are not authorized to view navs.'));

$navs = Nav::all()->filter(function ($nav) {
return User::current()->can('view', $nav);
})->map(function ($structure) {
return [
'id' => $structure->handle(),
'title' => $structure->title(),
'show_url' => $structure->showUrl(),
'edit_url' => $structure->editUrl(),
'delete_url' => $structure->deleteUrl(),
'deleteable' => User::current()->can('delete', $structure),
];
})->values();
$navs = Nav::all()
->filter(function ($nav) {
return User::current()->can('configure navs')
|| ($nav->sites()->contains(Site::selected()->handle()) && User::current()->can('view', $nav));
})
->map(function ($structure) {
return [
'id' => $structure->handle(),
'title' => $structure->title(),
'show_url' => $structure->showUrl(),
'edit_url' => $structure->editUrl(),
'delete_url' => $structure->deleteUrl(),
'deleteable' => User::current()->can('delete', $structure),
'available_in_selected_site' => $structure->sites()->contains(Site::selected()->handle()),
];
})
->values();

return view('statamic::navigation.index', compact('navs'));
}
Expand Down
2 changes: 2 additions & 0 deletions tests/Feature/Collections/ViewCollectionListingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function it_shows_a_list_of_collections()
'deleteable' => true,
'editable' => true,
'blueprint_editable' => true,
'available_in_selected_site' => true,
],
[
'id' => 'bar',
Expand All @@ -56,6 +57,7 @@ public function it_shows_a_list_of_collections()
'deleteable' => true,
'editable' => true,
'blueprint_editable' => true,
'available_in_selected_site' => true,
],
]))
->assertDontSee('no-results');
Expand Down
Loading