diff --git a/resources/js/components/nav/Branch.vue b/resources/js/components/nav/Branch.vue
index d988073e51..33d95db526 100644
--- a/resources/js/components/nav/Branch.vue
+++ b/resources/js/components/nav/Branch.vue
@@ -4,9 +4,9 @@
-
+
-
+
-
+
-
+
@@ -70,6 +70,7 @@ export default {
root: Boolean,
vm: Object,
isOpen: Boolean,
+ isChild: Boolean,
hasChildren: Boolean,
disableSections: Boolean,
topLevel: Boolean,
@@ -96,7 +97,9 @@ export default {
},
icon() {
- return data_get(this.item.config, 'icon') || 'entries';
+ return data_get(this.item, 'config.icon')
+ || data_get(this.item, 'original.icon')
+ || 'entries';
},
isAlreadySvg() {
diff --git a/resources/js/components/nav/Builder.vue b/resources/js/components/nav/Builder.vue
index fd10c2c1f5..4bce368c63 100644
--- a/resources/js/components/nav/Builder.vue
+++ b/resources/js/components/nav/Builder.vue
@@ -85,6 +85,7 @@
:depth="vm.level"
:vm="vm"
:is-open="item.open"
+ :is-child="isChildItemNode(item)"
:has-children="item.children.length > 0"
:disable-sections="true"
:top-level="true"
@@ -95,7 +96,7 @@
+ @click="addItem(item.children, item)" />
@@ -136,6 +137,7 @@
:depth="vm.level"
:vm="vm"
:is-open="item.open"
+ :is-child="isChildItemNode(item)"
:has-children="item.children.length > 0"
@edit="editItem(item)"
@toggle-open="store.toggleOpen(item)"
@@ -144,7 +146,7 @@
+ @click="addItem(item.children, item)" />
@@ -174,6 +176,7 @@
@@ -181,6 +184,7 @@
@@ -275,6 +279,7 @@ export default {
changed: false,
targetDataArray: null,
creatingItem: false,
+ creatingItemIsChild: false,
editingItem: false,
creatingSection: false,
editingSection: false,
@@ -433,6 +438,18 @@ export default {
return data_get(node, 'isSection', false);
},
+ isParentItemNode(node) {
+ return ! this.isSectionNode(node) && ! this.isChildItemNode(node);
+ },
+
+ isChildItemNode(node) {
+ if (data_get(node, 'parent.isRoot')) {
+ return false;
+ }
+
+ return ! this.isSectionNode(node.parent);
+ },
+
isCustomSectionNode(node) {
return this.isSectionNode(node) && data_get(node, 'manipulations.action') === '@create';
},
@@ -445,14 +462,6 @@ export default {
return node;
},
- isChildItemNode(node) {
- if (data_get(node, 'parent.isRoot')) {
- return false;
- }
-
- return ! this.isSectionNode(node.parent);
- },
-
traverseTree(nodes, callback, parentPath = []) {
const nodesArray = Array.isArray(nodes) ? nodes : [nodes];
@@ -473,9 +482,10 @@ export default {
});
},
- addItem(targetDataArray) {
+ addItem(targetDataArray, parentItem) {
this.targetDataArray = targetDataArray;
this.creatingItem = true;
+ this.creatingItemIsChild = parentItem && this.isParentItemNode(parentItem);
},
addSection() {
@@ -489,6 +499,7 @@ export default {
action: '@create',
display: createdConfig.display,
url: createdConfig.url,
+ icon: createdConfig.icon,
};
this.targetDataArray.push(item);
@@ -518,9 +529,11 @@ export default {
itemUpdated(updatedConfig, item) {
item.text = updatedConfig.display;
+ item.config.icon = updatedConfig.icon;
this.updateItemManipulation(item, 'display', updatedConfig.display);
this.updateItemManipulation(item, 'url', updatedConfig.url);
+ this.updateItemManipulation(item, 'icon', updatedConfig.icon);
this.updateItemAction(item);
this.resetItemEditor();
@@ -674,6 +687,7 @@ export default {
resetItemEditor() {
this.editingItem = false;
this.creatingItem = false;
+ this.creatingItemIsChild = false;
this.targetDataArray = false;
},
diff --git a/resources/js/components/nav/ItemEditor.vue b/resources/js/components/nav/ItemEditor.vue
index 8da7c77dad..9477b6e51c 100644
--- a/resources/js/components/nav/ItemEditor.vue
+++ b/resources/js/components/nav/ItemEditor.vue
@@ -35,6 +35,19 @@
+
+
@@ -61,11 +74,12 @@ export default {
props: {
creating: false,
item: {},
+ isChild: false,
},
data() {
return {
- config: data_get(this.item, 'config', this.createNewItem()),
+ config: clone(data_get(this.item, 'config', this.createNewItem())),
saveKeyBinding: null,
validateDisplay: false,
validateUrl: false,
@@ -89,6 +103,7 @@ export default {
return {
display: '',
url: '',
+ icon: null,
};
},
@@ -108,6 +123,14 @@ export default {
return;
}
+ let config = clone(this.config);
+
+ if (this.isChild) {
+ config.icon = null;
+ } else if (! config.icon) {
+ config.icon = data_get(this.item, 'original.icon');
+ }
+
this.$emit('updated', this.config, this.item);
},
diff --git a/resources/views/nav/updates.blade.php b/resources/views/nav/updates.blade.php
index 9016f11c71..bdf60b4c63 100644
--- a/resources/views/nav/updates.blade.php
+++ b/resources/views/nav/updates.blade.php
@@ -1,6 +1,6 @@
- {!! $item->icon() !!}{{ __($item->name()) }}
+ {!! $item->svg() !!}{{ __($item->name()) }}
diff --git a/resources/views/partials/nav-main.blade.php b/resources/views/partials/nav-main.blade.php
index 6e4dda8227..bd0fccb3f6 100644
--- a/resources/views/partials/nav-main.blade.php
+++ b/resources/views/partials/nav-main.blade.php
@@ -12,7 +12,7 @@
@unless ($item->view())
attributes() }}>
- {!! $item->icon() !!}{{ __($item->name()) }}
+ {!! $item->svg() !!}{{ __($item->name()) }}
@if ($item->children() && $item->isActive())
diff --git a/resources/views/partials/nav-mobile.blade.php b/resources/views/partials/nav-mobile.blade.php
index 4190aad2df..f9499cc7f2 100644
--- a/resources/views/partials/nav-mobile.blade.php
+++ b/resources/views/partials/nav-mobile.blade.php
@@ -11,7 +11,7 @@
@unless ($item->view())
-
- {!! $item->icon() !!}{{ __($item->name()) }}
+ {!! $item->svg() !!}{{ __($item->name()) }}
@if ($item->children() && $item->isActive())
diff --git a/src/CP/Navigation/CoreNav.php b/src/CP/Navigation/CoreNav.php
index 45c6616a22..a69e8798a8 100644
--- a/src/CP/Navigation/CoreNav.php
+++ b/src/CP/Navigation/CoreNav.php
@@ -50,7 +50,7 @@ protected function makeTopLevel()
if (count(config('statamic.cp.widgets')) > 0 || config('statamic.cp.start_page') === 'dashboard') {
Nav::topLevel('Dashboard')
->route('dashboard')
- ->icon('/charts');
+ ->icon('charts');
}
return $this;
@@ -65,7 +65,7 @@ protected function makeContentSection()
{
Nav::content('Collections')
->route('collections.index')
- ->icon('/content-writing')
+ ->icon('content-writing')
->can('index', Collection::class)
->children(function () {
return CollectionAPI::all()->sortBy->title()
@@ -86,7 +86,7 @@ protected function makeContentSection()
Nav::content('Navigation')
->route('navigation.index')
- ->icon('/hierarchy-files')
+ ->icon('hierarchy-files')
->can('index', NavContract::class)
->children(function () {
return NavAPI::all()->sortBy->title()
@@ -107,7 +107,7 @@ protected function makeContentSection()
Nav::content('Taxonomies')
->route('taxonomies.index')
- ->icon('/tags')
+ ->icon('tags')
->can('index', Taxonomy::class)
->children(function () {
return TaxonomyAPI::all()->sortBy->title()->map(function ($taxonomy) {
@@ -119,7 +119,7 @@ protected function makeContentSection()
Nav::content('Assets')
->route('assets.index')
- ->icon('/assets')
+ ->icon('assets')
->can('index', AssetContainer::class)
->children(function () {
return AssetContainerAPI::all()->sortBy->title()->map(function ($assetContainer) {
@@ -131,7 +131,7 @@ protected function makeContentSection()
Nav::content('Globals')
->route('globals.index')
- ->icon('/earth')
+ ->icon('earth')
->can('index', GlobalSet::class)
->children(function () {
return GlobalSetAPI::all()->sortBy->title()
@@ -160,12 +160,12 @@ protected function makeFieldsSection()
{
Nav::fields('Blueprints')
->route('blueprints.index')
- ->icon('/blueprint')
+ ->icon('blueprint')
->can('configure fields');
Nav::fields('Fieldsets')
->route('fieldsets.index')
- ->icon('/fieldsets')
+ ->icon('fieldsets')
->can('configure fields');
return $this;
@@ -180,7 +180,7 @@ protected function makeToolsSection()
{
Nav::tools('Forms')
->route('forms.index')
- ->icon('/drawer-file')
+ ->icon('drawer-file')
->can('index', Form::class)
->children(function () {
return FormAPI::all()->sortBy->title()->map(function ($form) {
@@ -192,19 +192,19 @@ protected function makeToolsSection()
Nav::tools('Updates')
->route('updater')
- ->icon('/loading-bar')
+ ->icon('loading-bar')
->view('statamic::nav.updates')
->can('view updates');
Nav::tools('Addons')
->route('addons.index')
- ->icon('/addons')
+ ->icon('addons')
->can('configure addons');
if (Stache::duplicates()->isNotEmpty()) {
Nav::tools('Duplicate IDs')
->route('duplicates')
- ->icon('/duplicate-ids')
+ ->icon('duplicate-ids')
->view('statamic::nav.duplicates')
->can('resolve duplicate ids');
}
@@ -214,7 +214,7 @@ protected function makeToolsSection()
if (config('statamic.graphql.enabled') && Statamic::pro()) {
Nav::tools('GraphQL')
->route('graphql.index')
- ->icon('/array')
+ ->icon('array')
->attributes(['target' => '_blank'])
->can('view graphql');
}
@@ -236,7 +236,7 @@ protected function makeUtilitiesItems()
if (count($utilities)) {
Nav::tools('Utilities')
->route('utilities.index')
- ->icon('/settings-slider')
+ ->icon('settings-slider')
->children($utilities);
}
@@ -252,12 +252,12 @@ protected function makeSettingsSection()
{
Nav::settings(Site::multiEnabled() ? 'Sites' : 'Site')
->route('sites.edit')
- ->icon('/sites')
+ ->icon('sites')
->can('configure sites');
Nav::settings('Preferences')
->route('preferences.index')
- ->icon('/settings')
+ ->icon('settings')
->children([
Nav::item('General')->route('preferences.index'),
Nav::item('CP Nav')->route('preferences.nav.index'),
@@ -279,12 +279,12 @@ protected function makeUsersSection()
Nav::users('Users')
->route('users.index')
- ->icon('/users-box')
+ ->icon('users-box')
->can('index', UserContract::class);
Nav::users('Groups')
->route('user-groups.index')
- ->icon('/users-multiple')
+ ->icon('users-multiple')
->can('edit user groups')
->children(function () {
return UserGroupAPI::all()->sortBy->title()->map(function ($userGroup) {
@@ -295,7 +295,7 @@ protected function makeUsersSection()
Nav::users('Permissions')
->route('roles.index')
- ->icon('/shield-key')
+ ->icon('shield-key')
->can('edit roles')
->children(function () {
return RoleAPI::all()->sortBy->title()->map(function ($role) {
diff --git a/src/CP/Navigation/NavItem.php b/src/CP/Navigation/NavItem.php
index ec931f7b9c..3d0878a6b5 100644
--- a/src/CP/Navigation/NavItem.php
+++ b/src/CP/Navigation/NavItem.php
@@ -188,15 +188,19 @@ public function editableUrl()
*/
public function icon($icon = null)
{
- return $this
- ->fluentlyGetOrSet('icon')
- ->getter(function ($value) {
- return $value ?? Statamic::svg('entries');
- })
- ->setter(function ($value) {
- return Str::startsWith($value, '