[Freeipa-devel] Nesting widgets

Adam Young ayoung at redhat.com
Wed Nov 2 15:53:04 UTC 2011


This sounds pretty good.  I think it is the right approach.


On 11/01/2011 09:11 PM, Endi Sukma Dewata wrote:
>> >>> So I decided to try to get an IP Address widget working. See the
>> >>> attached patch. It was fairly trivial.
>> >>>
>> >>> However, this widget is not really all that useful by itself. It 
>> would
>> >>> need to work as a part of a multivalued_text widget in order to
>> replace
>> >>> the widget used on the dnsrecord page. And looking at the 
>> multivalued
>> >>> text widget, I think you will agree that is going to be tricky.
>> >>
>> >> I think we can create an extend point for validation logic (EG
>> >> validator object in field's spec) instead of inheriting the widget.
>
> To summarize the recent discussion on IRC and other threads, we're 
> planning to split the existing widget concept into (logical) fields 
> and (visual) widgets. See: https://fedorahosted.org/freeipa/ticket/2040
>
> The new widgets will be used mainly for input/output like the existing 
> widgets, but they can also be any other UI components such as header 
> or separator.
>
> The widgets will support nesting. For example, the multivalued widget 
> will become a composite widget which has an Add and Undo All links and 
> can contain other widgets:
>
>   widgets: [
>       {
>           factory: IPA.multivalued_widget,
>           name: 'fullName',
>           widget: IPA.text_widget
>       }
>   ]
>
> The widgets can be arranged inside a section, which is also a 
> composite widget that has a header and is collapsible.
>
>   widgets: [
>       {
>           factory: IPA.section_widget,
>           name: 'identity',
>           widgets: [
>               {
>                   factory: IPA.text_widget,
>                   name: 'fullName'
>               }
>           ]
>       }
>   ]
>
> For IP address we could either use a text widget with an IP address 
> validator, or we could also implement a custom IP address widget. 
> Either solution can be used inside multivalued widget.
>
>   widgets: [
>       {
>           factory: IPA.multivalued_widget,
>           name: 'ipaddress1',
>           widget: {
>               factory: IPA.text_widget,
>               validator: IPA.ipaddress_validator
>           }
>       },
>       {
>           factory: IPA.multivalued_widget,
>           name: 'ipaddress2',
>           widget: IPA.ipaddress_widget,
>       },
>   ]
>
>> > Interesting concept. Yes, this would work too, and solve the issue for
>> > IP addresses validation. But there are places where we may want to
>> > validate only a single IP address, and we may end up with code
>> > duplication, although more likely they will both just call the same
>> > utility function.
>
> Since the multivalued widget is completely separate, we can reuse the 
> IP address widget for a single valued attribute.
>
>   widgets: [
>       {
>           factory: IPA.ipaddress_widget,
>           name: 'ipaddress'
>       }
>   ]
>
>> >>> In order to make the widget scheme more nestable, the section
>> >>> section.load and save can do more work, such as scoping down the 
>> piece
>> >>> of the request record to just that portion required by the widget.
>> >>> Bascially, it can do what widget.load does, just externally
>> >>
>> >> I don't think this would help. This would limit the widget. Currently
>> >> most widget works with the record.[widget name]. But we can override
>> >> load and save method to break the 1:1 mapping between widget and
>> >> record. Widget can consist of several widgets and supply them custom
>> >> record object (it can assume that the simple widget would fetch the
>> >> value of its name. The name is defined by the master widget (no
>> >> problem here).)
>> >>
>> >> The concept you mentioned could be beneficial if we abandon flat
>> >> records and introduce structured ones. But I think there is no will
>> >> for it. Event then I don't know if sections should be responsible for
>> >> this. It's not their purpose.
>> >
>> > Records are already structured, just that by the time we get to the
>> > individual fields, they tend to be flat. But the record is JSON and 
>> is a
>> > tree structure.
>> >
>> > But I like what you are saying. I agree that the interface for Widget
>> > and Section should be the same. Right now Section is:
>> > that.save = function(record) {};
>> > that.load = function(record) {);
>> >
>> > and load is
>> > that.load = function(record) {};
>> > that.save = function() {};
>> >
>> > It is this last function that needs to be changed, but it will have 
>> far
>> > reaching effects. We use save to extract the value or values from the
>> > field for many uses. I think we can do this: For all widgets, rename
>> > save() to get_value(); and then add a save(record) method that calls
>> > get_value(); Then widget and record have the same interface, which 
>> is a
>> > big first step.
>
> The fields will be used to load/store attributes. Each field usually 
> will have a corresponding widget, except hidden fields:
>
>   fields: [
>       {
>           name: 'krbprincipalname' // hidden
>       },
>       {
>           name: 'cn',
>           widget: 'identity.fullName' // widget inside a section
>       },
>       {
>           name: 'mail',
>           widget: 'contact.email' // multivalued widget
>       }
>   ]
>
> During load the fields will be used to get the attributes from the 
> records returned by the server and then pass them to the corresponding 
> widgets to be displayed.
>
> During update the fields will be used to save the values from the 
> corresponding widgets and they will be used to generate the update 
> commands. This will be covered in this ticket:
> https://fedorahosted.org/freeipa/ticket/2041
>
> We might be able to do nested fields too to handle hierarchical 
> records, but that's not needed now.
>
>> >> Another (maybe bigger) problem is layout. For multivalued textbox 
>> with
>> >> IP address widget one of the problems can be the placement (or even
>> >> behaviour) of 'undo' and 'error-link'. Possible solution could be:
>> >> specifying container for these parts by its container - the 
>> containing
>> >> widget could control where they would be rendered. Another one can be
>> >> API notification of the state change (no visual by the widget itself)
>> >> and handling it by the parent widget.
>> >>
>> >> For more layout demanding widgets section layout can be limiting 
>> (like
>> >> in host adder dialog which force to implement custom section instead
>> >> of widget). Which in my opinion is bad, but we don't have any other
>> >> solution for this yet. I think there is a ticket for it.
>> >
>> > Perhaps for more complex widgets, we can extract the layout into 
>> its own
>> > object, and pass it to the constructore. We'll provide one by default,
>> > but allow overloading.
>
> Yes, by default all containers (facets, dialogs, or composite widgets) 
> will use 1-column layout. So the nested widgets will be arranged 
> vertically with the same width. Each widget will be able to implement 
> custom layout. This is probably sufficient for now. See also:
> https://fedorahosted.org/freeipa/ticket/1501
>
> Other related tickets:
> https://fedorahosted.org/freeipa/ticket/2042
> https://fedorahosted.org/freeipa/ticket/2043
> https://fedorahosted.org/freeipa/ticket/2052
>




More information about the Freeipa-devel mailing list