GithubHelp home page GithubHelp logo

Comments (6)

milewski avatar milewski commented on July 17, 2024

Fixed pull again

from conditional-container.

milewski avatar milewski commented on July 17, 2024

For those coming here use the version on the flexible branch:

composer require digital-creative/conditional-container:dev-flexible-content

I haven't merged it yet to master due the validation is still not working, once I get that sorted out I will merge to master and tag a new release on packagist

from conditional-container.

bernhardh avatar bernhardh commented on July 17, 2024

Still getting the join js error msg. Where do I have to put the HasConditionalContainer?

To the HtmlLayout or the Resource? I tried both.

from conditional-container.

milewski avatar milewski commented on July 17, 2024

to your resource, try to clean the cache, and make sure you have the latest version on the flexible branch

I have copied your exact example without the tabs..:

from here:

 Flexible::make('', 'gridBlocks')
                    ->preset(GridFlexibel::class)

and it worked... if it still doesn't maybe is because of the tabs package T_T

from conditional-container.

bernhardh avatar bernhardh commented on July 17, 2024

I have analyzed it and found a couple of issues. First I am using your HasMegaFilterTrait as well, so I had to create my own trait:

trait HasMegaFilterAndConditionalContainer {
    use HasMegaFilterTrait {
        HasMegaFilterTrait::availableFields as availableFieldsForMegafilter;
    }
    use HasConditionalContainer {
        HasConditionalContainer::availableFields as availableFieldsConditionalContainer;
    }

    
    public function availableFields(NovaRequest $request) {
        // Is an index request, so we need MegaFilter
        $controller = $request->route()->controller;
        if ($controller instanceof ResourceIndexController) {
            return $this->availableFieldsForMegafilter($request);
        }
        elseif ($controller instanceof CreationFieldController || $controller instanceof UpdateFieldController) {
            return $this->availableFieldsConditionalContainer($request);
        }

        // All other requests get the regular availableFields method
        return parent::availableFields($request);
    }
}

The second problem is with the way your implementation works and which is incompatible with the Tabs package and probably with other packages and maybe custom macros in some cases as well. The problem is, that you clone all the fields and layouts, but not all their extra properties and metas. For example, if you use the tabs package, your field inside an flexible will lose the tab and panel information after cloning.

Just my thought (maybe I am wrong): It's maybe not the best solution to clone half of the objects (performance wise its definitely not the best). I understand, that the problem is, that you can't manipulate the protected $fields of the Layout objects directly, so you have to clone at least this fields. So we need a method like setFields on the layout:

public function setFields($fields) {
    $this->fields = $fields;
    return $this;
}
  • we can talk to Whitecube so they add it or at least make layouts macroable
  • or as I am doing it right now, implement this by my own and adding this function to my custom layout

My suggestion for a rewrite of your solution then would be

/**
     * @param NovaRequest $request
     *
     * @return FieldCollection
     */
    public function availableFields(NovaRequest $request) {
        $controller = $request->route()->controller;

        if ($controller instanceof CreationFieldController || $controller instanceof UpdateFieldController) {
            $fields = parent::availableFields($request);
            $containers = $this->findAllContainers($fields);
            $expressionsMap = $containers->flatMap->expressions;
            $hasConditionalContainer = $this;

            // Inject conditional container fields meta to fields
            $fields = $fields->each(function ($field) use ($hasConditionalContainer, $expressionsMap) {
                return $hasConditionalContainer->injectMetaIntoFields($field, $expressionsMap);
            });

            return $fields;
        }

        return parent::availableFields($request);
    }


    /**
     * @param $field
     * @param $expressionsMap
     *
     * @return mixed
     */
    protected function injectMetaIntoFields($field, $expressionsMap) {
        if ($field instanceof Flexible) {
            $field->meta["layouts"] = $field->meta["layouts"]->each(function ($layout) use ($expressionsMap) {
                $layout->setFields(collect($layout->fields())->each(function ($field) use ($expressionsMap) {
                    if ($field instanceof ConditionalContainer) {
                        $field->withMeta(['__uses_flexible_field__' => true]);
                        $field->withMeta(['expressionsMap' => $expressionsMap]);

                        $field->fields->each(static function ($field) {
                            if (method_exists($field, 'withMeta')) {
                                $field->withMeta(['__has_flexible_field__' => true]);
                            }
                        });
                    }

                }));

                return $layout;
            });
        }

        return $field;
    }

Maybe I am missing something, but I removed a lot of stuff of yours, where I didn't understand why you need it at all.

from conditional-container.

milewski avatar milewski commented on July 17, 2024

Exactly that was the main problem I couldn't transform the protected $fields from their layout so I had to clone everything, we could reach out to them and submit a PR to add this method, they don't have to use it themselves but would help this package work with theirs.

One small problem I see with your rewrite is that it is not considering that you could have Flexible inside Flexible and a Conditional Container Inside Flexible and Flexible Inside Conditional Container like:

Conditional
   Flexible
      Flexible
          Conditional
Flexible
   Conditional

With the function, I had: findAllFlexibleContentFields would find everything and flatten them all out to inject all the necessary values,

I think it's easy if you could push your changes as a PR and we can discuss directly comment on the code lines

from conditional-container.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.