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

Add External link in admin navigation #6328

Open
wants to merge 6 commits into
base: 2.5
Choose a base branch
from
Open

Conversation

sebheitzmann
Copy link

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Fixed tickets fixes #5207
Related issues/PRs #5207
License MIT
Documentation PR sulu/sulu-docs#

What's in this PR?

Permit the admin navitation to link to external url

Why?

Link to external tools ( google analytics, or other web companion )

Example Usage

To Do

  • Create a documentation PR

@sebheitzmann
Copy link
Author

That's the php part for the moment. I've implemented an NavigationItemInterface to handle types in the registry and adminController. Feel free to comment and propose an other approach.

@sebheitzmann
Copy link
Author

Moving on the front part.

@alexander-schranz alexander-schranz changed the title External link in navigation #5207 Add External link in admin navigation Oct 29, 2021
@alexander-schranz alexander-schranz added the Feature New functionality not yet included in Sulu label Oct 29, 2021
Copy link
Member

@alexander-schranz alexander-schranz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sebheitzmann Thanks for working on this, I did a quick review and we maybe need to discuss the Interface, but at all it looks good to that you could start with the frontend part.

Comment on lines 32 to 33
public function hasLink();
public function getView();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sulu/core-team how we define a interface here. In the views we only have in the interface which really relevant for all types and use options array to provide type specific options. I'm thinking about here that the normal NavigationItem has only a setView and getView and will write this into an options array like we do it for views e.g.:

public function setView(string $view):  void
{
    return $this->options['view'] = $view;
}

and the ExternalNavigationItem then with:

public function setUrl(string $url):  void
{
    return $this->options['url'] = $url;
}

And so the NavigationItemInterface instead of having getView it will have a getOptions and getType method.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have done this because they are used in the Registry. But maybe it should be avoided

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not sure if i would separate internal and external navigation items into separate classes. they share a lot of things (eg. label, icon, position), right?

maybe it would be better to add a type on the NavigationItem class? we could add a ViewNavigationItemBuilder and a ExternalLinkNavigationItemBuilder to create and validate different types of navigation items. this would be consistent to the existing View concept.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good for me to have the same concept as for Views here. We would need a NavigationBuilderFactory then like the ViewBuilderFactory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For backward compatibility the NavigationItemCollection would need to be changed to accept NavigationItemBuilder and NavigationItem then.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry but I don't really understand what i should do with the ViewBuilderFactory. I can merge the NavigationItem and the ExternalNavigation if you want.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can I Help ?

@@ -76,7 +76,7 @@ private function loadNavigationItems(): void
}

$navigationItems = \array_filter($navigationItemCollection->all(), function($navigationItem) {
return $navigationItem->getChildren() || $navigationItem->getView();
return $navigationItem->getChildren() || $navigationItem->hasLink();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting didn't know we filter this out here this way. Need to check if the whole array_filter maybe could be removed so we don't need to have something like hasLink here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't really understand why we sould filter the items. Is it possible to have items without view ? If they are hidden i think it's useless. I will correct this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the items are filtered to filter out empty parents. for example, if a user does not have permissions for accounts and for contacts, the Contact navigation item would be empty

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I will revert my change to keep the getChildren filter. But the getView is useless no ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the getView is needed if there is no children. Instead all the leaf link will be removed

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a shouldShow() function on the interface ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add a special GroupNavigationItem we would not need a shouldShow instead we could check here: return !$navigationItem instanceOf GroupNavigatinItemBuilder || count(!$navigationItem->getChildren());. Because a ViewNavigationItem without view or a ExternalNavigationItem without Url would never exists and so don't need to be filtered out.

public function copyChildless()
{
$new = $this->copyWithName();
$new->setView($this->getView());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think this should be $new->setUrl($this->getUrl());

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thing that an external link should not have children. So maybe this function should be removed. ( but corrected )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we introduce a speical GroupNavigationItem because if we name the other one ViewNavigationItem it also does not make sense that it can have children.

return $this->getUrl() !== null;
}

public function getView()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The external should know nothing about view, need to discuss the Interface with the other core team members.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getView is used in the NavigationRegistry ( line 108 )

        // add child views
        $mainView = $navigationItem->getView();
        if ($mainView) {
            $mainPath = $this->viewRegistry->findViewByName($mainView)->getPath();
            if ('/' !== $mainPath) {
                foreach ($this->viewRegistry->getViews() as $view) {
                    if (0 === \strpos($view->getPath(), $mainPath)) {
                        $navigationItem->addChildView($view->getName());
                    }
                }
            }
        }

Maybe this should be done in the Item and not in the registry.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thinks that it's for the "active" feature.

@sebheitzmann
Copy link
Author

image

@alexander-schranz alexander-schranz added the hacktoberfest-accepted Accepted for hacktoberfest but will be merged later label Oct 31, 2021

namespace Sulu\Bundle\AdminBundle\Admin\Navigation;

class NavigationExternalItem implements \Iterator, NavigationItemInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is missing proper type information. We should use the php typehinting:

/**
* @var string
*/
protected $id;

will become

protected string $id;

That way we have help from php checking the types. Same with arguments and return types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New functionality not yet included in Sulu hacktoberfest-accepted Accepted for hacktoberfest but will be merged later
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support NavigationItems with absolute url configuration
4 participants