Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Best practice question on DataSourceField.viewRequires related use case

    Hi Isomorphic,

    how is the following use case best solved?
    Whole application is about 1 object type that is displayed in different lists depending on status (using the same DataSource for all those ListGrids).
    This moving from list to list is working fine with criteria on the ListGrid and cacheSync when an entry moves from a to b.

    Now depending on the status there are different fields important in different lists. Also, some clients don't use all fields (then the ListGridField is not added to list as of now) and some want fields to be hidden on start (hidden:true, canHide:true).
    I see that this would involve way less Java code if I used an auxiliary Velocity object in viewRequires and just added all fields. With this, I'd also not query and transfer unneeded and most likely empty fields and potentially save some joins. From testing I do know this works as expected.

    But I have a problem w.r.t. to the "displayed in different lists depending on status". Here I can't say viewRequires->true for one ListGrid and viewRequires->false for another with Velocity, correct?
    How would I solve this best using as little code as possible. It would be great if I could get rid of all my e.g.
    Code:
    addFieldIfVisible("CAMPAIGN_ID", campaignLGF, fields);
    that do these checks now.
    Also, from how I understand it, viewRequires needs to evaluate always to true if I want to use that field in some list. Actually it needs to evaluate always to the same result for a user within his or her session.

    Do you have any pointers?
    I could think of different outputs per OperationBinding, that is used just for a specific ListGrid, which would also safe some joins, but still would mean the same ListGridField-adding code.

    Here I also do have an enhancement suggestion: It would be good if outputs were also a VelocityExpression and not a string, because now I'd have to use ServerDataSourceImplementation / DynamicDSGenerator to modify the outputs, which is way more complicated.

    Thank you & Best regards
    Blama

    PS: For anyone else reading this: .ds.xml and it's attributes, in combination with Velocity and perhaps ServerDataSourceImplementation are a REALLY strong tool. If I had understood this from the beginning, I'm sure that I might have done many things way more efficient. With it, you get role base security for free with zero code (even on a field level!) as well as client and server side validation.

    #2
    viewRequires and related Declarative Security settings are for security (hence the name). They must always be the same for the same user. They should never be used to attempt any kind of display difference on a per-component basis.

    It's unclear on what basis you are trying to omit fields - you've just made a vague reference to "status". So for now, all that can be said is: if it's not security, then don't use Declarative Security to do it.

    Comment


      #3
      Hi Isomorphic,

      yes and no. I think I can't use viewRequires then. I want to cover these cases:
      • Always visible in some ListGrid using this DataSource (=viewRequires: true, detail:false/false)
      • Can be shown in some ListGrid using this DataSource (=viewRequires: true, detail:true/false)
      • Field not in available in some ListGrid using this DataSource (=virtually viewRequires: false in some ListGrids, but this is not possible)
      • Not used or always hidden for this user (=viewRequires: false, detail does not matter)
      This needs to be configurable, meaning it's some setting in the DB, that can be read via Velocity or DataSourceGenerator.

      Example:
      1st list: "In creation"
      2nd list: "Responsible" (same DataSource as above)
      • On transition from "In creation" to "Responsible" a responsible person needs to be selected and is stored in an integer field.
      • For display purposes, the name field is joined with includeFrom.
      • The display in one or the other list is done with isNull or notNull criteria, cacheSync takes care of showing an entry in only one list if a responsible person gets assigned.
      This is already working.

      Now, it's never necessary to show the responsible person field in the 1st list (neither from start or as detail), as there never is one. Can I somehow do this without either not-adding the field to the ListGrid or adding it as hidden:true, canHide:false?
      Also, I'd like for the join to the responsibleUserTable not to take place if fetching for the 1st list (this could be done with outputs in the operationBinding or the fetch(), but is it the only way?)
      For another field the customer might decide that he or she only wants to see this as a detail field in one list, but always visible in another.

      Does this make it any clearer? The more I think about it the more I guess I'll need to continue configuring hidden and canHide myself on the ListGridFields, but perhaps there is another solution.

      Thank you & Best regards
      Blama

      Comment


        #4
        So again, because this is component specific and/or related to user preferences, it does not make sense to use viewRequires to do this, since that's a security setting.

        It also doesn't make sense to consider this as a Velocity problem, since Velocity evaluation happens on the server side, once ever during DataSource load, and this is a per-component and even dynamic per-component setting.

        You've got complete freedom to control field visibility with the hidden/canHide settings, and data fetching via outputs, and we don't see an obvious way to make either API simpler. We don't know what you don't like about your current code, but you're not looking in the right area for possible simplifications.

        Comment


          #5
          Hi Isomorphic,

          I agree. I'll use viewRequires for the case where the admin decides that a column should be invisible at all times, as this will also save join-Generation.
          For the rest I'll use hidden/canHide in Java.

          Thank you & Best regards
          Blama

          Comment

          Working...
          X