Class FieldsMeta<T extends org.cxbox.api.data.dto.DataResponseDTO>

java.lang.Object
org.cxbox.api.data.dto.rowmeta.FieldsDTO
org.cxbox.core.dto.rowmeta.RowDependentFieldsMeta<T>
org.cxbox.core.dto.rowmeta.FieldsMeta<T>
All Implemented Interfaces:
Iterable<org.cxbox.api.data.dto.rowmeta.FieldDTO>
Direct Known Subclasses:
EngineFieldsMeta

public class FieldsMeta<T extends org.cxbox.api.data.dto.DataResponseDTO> extends RowDependentFieldsMeta<T>
  • Constructor Details

    • FieldsMeta

      public FieldsMeta(com.fasterxml.jackson.databind.ObjectMapper objectMapper)
  • Method Details

    • addConcreteFilterValue

      public final void addConcreteFilterValue(DtoField<? super T,?> field, org.cxbox.api.data.dictionary.SimpleDictionary dictDTO)
      Adds a value to the existing list of filterable values
      Parameters:
      field - widget field with type dictionary
      dictDTO - DTO with dictionary value
    • enableFilter

      @SafeVarargs public final void enableFilter(DtoField<? super T,?>... fields)
    • setAllFilterValuesByLovType

      public final void setAllFilterValuesByLovType(DtoField<? super T,?> field, org.cxbox.api.data.dictionary.IDictionaryType type)
      Parameters:
      field - dto field
      type - dictionary type


      Field filter drop-downs (on List widgets header and so on) values sorted by display_order, then by key. display_order can be null

      See dicts.sort and LinkedHashMap lines in DictionaryCacheImpl.Cache.load()


      Attention - sorting rows in List widgets always ignores display_order and is done by lov.key lexicographically!

    • setAllFilterValuesByLovType

      public final void setAllFilterValuesByLovType(DtoField<?,?> field, @NonNull @NonNull org.cxbox.api.data.dictionary.IDictionaryType type, @NonNull @NonNull Comparator<org.cxbox.api.data.dictionary.SimpleDictionary> comparator)
      Parameters:
      field - dto field
      type - dictionary type
      comparator - filter drop-downs will show values sorted by this comparator

      Attention - sorting rows in List widgets always ignores display_order and is done by lov.key lexicographically!

    • setConcreteFilterValues

      public final void setConcreteFilterValues(DtoField<? super T,?> field, Collection<org.cxbox.api.data.dictionary.SimpleDictionary> dictDtoList)
    • setEnumFilterValues

      public <T extends org.cxbox.api.data.dto.DataResponseDTO, E extends Enum> void setEnumFilterValues(@NonNull @NonNull FieldsMeta<T> fieldsMeta, @Nullable DtoField<? super T,E> field, @NonNull @NonNull E... values)
    • setForceActive

      @SafeVarargs public final void setForceActive(DtoField<? super T,?>... fields)
    • setEphemeral

      @SafeVarargs public final void setEphemeral(DtoField<? super T,?>... fields)
    • setFilterValuesWithIcons

      @Deprecated(since="4.0.0-M11") public final void setFilterValuesWithIcons(DtoField<? super T,?> field, org.cxbox.api.data.dictionary.IDictionaryType type, Map<org.cxbox.api.data.dictionary.LOV,org.cxbox.api.data.dto.rowmeta.IconCode> valueIconMap)
    • setAllValuesWithIcons

      public final void setAllValuesWithIcons(DtoField<? super T,?> field, org.cxbox.api.data.dictionary.IDictionaryType type, Map<org.cxbox.api.data.dictionary.LOV,org.cxbox.api.data.dto.rowmeta.Icon> valueIconMap)
      Show icon for fields having "type":"dictionary" in widget.json based on LOV. Icon will appear in both From, List widgets etc. For List widget filtration and rows will get icons - no others method are needed to be called Icon can depend on parent bc
      Parameters:
      field - dto field
      type - dictionary type
      valueIconMap - <LOV, Icon> LOV to icon mapping
    • setAllValuesWithIcons

      public final <E extends Enum> void setAllValuesWithIcons(DtoField<? super T,?> field, Map<E,org.cxbox.api.data.dto.rowmeta.Icon> valueIconMap)
      Same as setAllValuesWithIcons(DtoField, IDictionaryType, Map) but for Enum base dictionary fields
      Parameters:
      field - dto field
      valueIconMap - <extends Enum, Icon> Enum to icon mapping

      Example 1:
      
       @RequiredArgsConstructor
       @Getter
       public enum IconsEnum implements Icon {
        ARROW_UP("arrow-up #0cbfe9"),
        WATERMELON("watermelon"),
        DOWN("down");
      
       private final String icon;
       }
      
       @Getter
       @AllArgsConstructor
       public enum CustomFieldDictionaryEnum {
      
        HIGH("High", IconsEnum.ARROW_UP),
        MIDDLE("Middle", IconsEnum.DOWN),
        LOW("Low", IconsEnum.WATERMELON);
      
        @JsonValue
        private final String value;
      
        private final Icon icon;
      
        public static Map<CustomFieldDictionaryEnum, Icon> iconMap() {
            return Arrays.stream(CustomFieldDictionaryEnum.values())
            .filter(e -> e.icon != null)
            .collect(Collectors.toMap(e -> e, e -> e.icon));
        }
      
       }
      Add to buildIndependentMeta
      
        fields.setAllValuesWithIcons(MyExampleDTO_.customFieldDictionary, CustomFieldDictionaryEnum.iconMap());
       
    • setFileAccept

      public final void setFileAccept(DtoField<? super T,?> field, @NonNull @NonNull List<String> accept)
    • enableSort

      @SafeVarargs public final void enableSort(DtoField<? super T,?>... fields)
      Parameters:
      fields - fields to be made sortable. Sort icon will appear in UI, that user can interact with to apply/change sorting order
      • See additional abilities for sorting (how to set default sort order and so on) in this java doc WidgetFieldsIdResolverProperties.sortEnabledDefault
    • defaultGroupingHierarchy

      public <D extends org.cxbox.api.data.dto.DataResponseDTO, E1> void defaultGroupingHierarchy(@NonNull @NonNull DtoField<D,E1> field1, @NonNull @NonNull UnaryOperator<org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E1,?>> hierarchyBuilder)


      This method sets default hierarchy for "GroupingHierarchy" widget, that will always be shown (even, when widget has no data from backend). Use this method only for hierarchies grouped by SINGLE column

      Example 1: explicitly provided default hierarchy (grouped by single Enum field document):
      
       fields.defaultGroupingHierarchy(
        MeetingDocumentsDTO_.document,
        lvl -> lvl
          .add(Documents.REFERENCE),
          .add(Documents.POLICY)
       );
       

      Resulting "GroupingHierarchy" widget in UI, when NO data came from backend (e.g. only default hierarchy will be shown):
      
        UI ("default hierarchy")
       _________________________
       |Document↓   |File      |
       _________________________
       |Reference(0)|          |
       |Policy   (0)|          |
       _________________________
                  ↑ ↑
             Backend data
       _________________________
       |Document    |File      |
       _________________________
       _________________________
      
       
      Resulting "GroupingHierarchy" widget in UI, when data came from backend (e.g. default hierarchy merged with backend data will be shown)
      
       UI ("default hierarchy" merged with data)
       _________________________
       |Document↓    |File     |
       _________________________
       |Reference (0)|         |
       |Policy↓   (2)|File1.jpg|
       |             |File2.jpg|
       |Legal     (1)|File3.jpg|
       _________________________
                  ↑ ↑
             Backend data
       _________________________
       |Document     |File     |
       _________________________
       |Policy       |File1.jpg|
       |Policy       |File2.jpg|
       |Legal        |File3.jpg|
       _________________________
       


      Example 2: dynamically provided default hierarchy tree (grouped by single Enum field document). Can be convenient, when default hierarchy structure is configurable through admin UI, so needed to be loaded from DB/microservice:
      
       fields.defaultGroupingHierarchy(
        MeetingDocumentsDTO_.document,
        l -> Arrays.stream(Documents.values()).collect(Hierarchy.toHierarchyWithCfg(
          e -> e,
          (e, cfg) -> cfg.options(Map.of("sdfsdf", "sdzfdsf"))
         )
        )
       );
       


      Preconditions for both examples:
      
       {
        "name": "meetingDocumentsList",
        "title": "",
        "type": "GroupingHierarchy",
        "bc": "meetingDocumentEdit",
        "fields": [
          {
            "title": "Document",
            "key": "document",
            "type": "dictionary"
          },
          {
            "title": "File",
            "key": "file",
            "type": "fileUpload",
            "fileIdKey": "fileId"
          }
        ],
        "options": {
          "groupingHierarchy": {
            "counterMode": "always",
            "fields": ["document"]
          }
        }
       }
       
      
       public enum Documents {
        REFERENCE("Reference"),
        POLICY("Policy"),
        LEGAL("Legal");
      
        @JsonValue
        private final String value;
       }
       
      
       public class MeetingDocumentsDTO extends DataResponseDTO {
        @SearchParameter(name = "document", provider = EnumValueProvider.class)
        private Documents document;
      
        @SearchParameter(name = "file", provider = StringValueProvider.class)
        private String file;
      
        private String fileId;;
       }
       
      see details in documentation

      Type Parameters:
      D - DTO type
      E1 - DTO field type. Usually one will use field with "type":"input" or "type":"dictionary, so DTO field types will usually be String or Enum
      Parameters:
      field1 - FIRST field listed in .widget. json -> "options" -> "groupingHierarchy" -> "fields"
      hierarchyBuilder - builder for default hierarchy. See usage example at this java-doc beginning
    • defaultGroupingHierarchy

      public <D extends org.cxbox.api.data.dto.DataResponseDTO, E1, E2> void defaultGroupingHierarchy(@NonNull @NonNull DtoField<D,E1> field1, @NonNull @NonNull DtoField<D,E2> field2, @NonNull @NonNull UnaryOperator<org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E1,org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E2,?>>> hierarchyBuilder)


      This method sets default hierarchy for "GroupingHierarchy" widget, that will always be shown (even, when widget has no data from backend). Use this method only for hierarchies grouped by TWO columns

      Example 1: explicitly provided default hierarchy tree (grouped by two Enum fields document and then briefing):
      
       fields.defaultGroupingHierarchy(
        MeetingDocumentsDTO_.document,
        MeetingDocumentsDTO_.briefing,
        lvl -> lvl
          .add(
              Documents.REFERENCE,
              lvl2 -> lvl2.
                add(Briefings.FINANCIAL),
                add(Briefings.PROJECT)
              )
           ),
          .add(
              Documents.POLICY
           )
        )
       );
       

      Resulting "GroupingHierarchy" widget in UI, when NO data came from backend (e.g. only default hierarchy will be shown):
      
             UI ("default hierarchy")
       _______________________________________
       |Document↓    | Briefing↓   |File     |
       _______________________________________
       |Reference↓(0)| Financial(0)|         |
       |             | Project  (0)|         |
       |Policy    (0)|             |         |
       _______________________________________
                         ↑ ↑
                    Backend data
       _______________________________________
       |Document     | Briefing    |File     |
       _______________________________________
       ______________________________________|
       

      Resulting "GroupingHierarchy" widget in UI, when data came from backend (e.g. default hierarchy merged with backend data will be shown)
      
       UI ("default hierarchy" merged with data)
       _________________________________________
       |Document↓    | Briefing↓     |File     |
       _________________________________________
       |Reference↓(1)| Financial  (0)|         |
       |             | Project    (0)|         |
       |             | Operational(1)|File1.jpg|
       |Policy↓   (3)| Security↓  (2)|File2.jpg|
       |             |               |File3.jpg|
       |             | Project    (1)|File4.jpg|
       |Legal     (1)| Operational(1)|File5.jpg|
       _________________________________________
                         ↑ ↑
                    Backend data
       _________________________________________
       |Document     | Briefing      |File     |
       _________________________________________
       |Reference    | Operational   |File1.jpg|
       |Policy       | Security      |File2.jpg|
       |Policy       | Security      |File3.jpg|
       |Policy       | Project       |File4.jpg|
       |Legal        | Operational   |File5.jpg|
       _________________________________________
       


      Example 2: dynamically provided default hierarchy tree (grouped by single Enum field document). Can be convenient, when default hierarchy structure is configurable through admin UI, so needed to be loaded from DB/microservice:
      
       Map<Documents, Set<Briefings>> external = Map.of(
        Documents.REFERENCE, Set.of(Briefings.FINANCIAL, Briefings.PROJECT),
        Documents.POLICY, new HashSet<>()
       );
       fields.defaultGroupingHierarchy(
        MeetingDocumentsDTO_.document,
        MeetingDocumentsDTO_.briefing,
        lvl1 -> external.entrySet().stream().collect(Hierarchy.toHierarchy(
          Entry::getKey,
          (doc, lvl2) -> doc.getValue().stream().collect(Hierarchy.toHierarchy(brief -> brief))
         )
        )
       );
       


      Preconditions for both examples:
      
       {
        "name": "meetingDocumentsList",
        "title": "",
        "type": "GroupingHierarchy",
        "bc": "meetingDocumentEdit",
        "fields": [
          {
            "title": "Document",
            "key": "document",
            "type": "dictionary"
          },
          {
            "title": "Briefing",
            "key": "briefing",
            "type": "dictionary"
          },
          {
            "title": "File",
            "key": "file",
            "type": "fileUpload",
            "fileIdKey": "fileId"
          }
        ],
        "options": {
          "groupingHierarchy": {
            "counterMode": "always",
            "fields": ["document", "briefing"]
          }
        }
       }
       
      
       public enum Documents {
        REFERENCE("Reference"),
        POLICY("Policy"),
        LEGAL("Legal");
      
        @JsonValue
        private final String value;
       }
       
      
       public enum Briefings {
        FINANCIAL("Financial"),
        PROJECT("Project"),
        SECURITY("Security"),
        OPERATIONAL("Operational");
      
        @JsonValue
        private final String value;
       }
       
      
       public class MeetingDocumentsDTO extends DataResponseDTO {
        @SearchParameter(name = "document", provider = EnumValueProvider.class)
        private Documents document;
      
        @SearchParameter(name = "briefing", provider = EnumValueProvider.class)
        private Briefings briefing;
      
        @SearchParameter(name = "file", provider = StringValueProvider.class)
        private String file;
      
        private String fileId;;
       }
       

      Type Parameters:
      D - DTO type
      E1 - DTO field type. Usually one will use field with "type":"input" or "type":"dictionary, so DTO field types will usually be String or Enum
      Parameters:
      field1 - FIRST field listed in .widget. json -> "options" -> "groupingHierarchy" -> "fields"
      field2 - SECOND field listed in .widget. json -> "options" -> "groupingHierarchy" -> "fields"
      hierarchyBuilder - builder for default hierarchy. See usage example at this java-doc beginning
    • defaultGroupingHierarchy

      public <D extends org.cxbox.api.data.dto.DataResponseDTO, E1, E2, E3> void defaultGroupingHierarchy(@NonNull @NonNull DtoField<D,E1> field1, @NonNull @NonNull DtoField<D,E2> field2, @NonNull @NonNull DtoField<D,E3> field3, @NonNull @NonNull UnaryOperator<org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E1,org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E2,org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E3,?>>>> hierarchyBuilder)


      This method sets default hierarchy for "GroupingHierarchy" widget, that will always be shown (even, when widget has no data from backend). Use this method only for hierarchies grouped by TREE columns

      See usage example here defaultGroupingHierarchy(DtoField, DtoField, UnaryOperator)

      Type Parameters:
      D - DTO type
      E1 - DTO field type. Usually one will use field with "type":"input" or "type":"dictionary, so DTO field types will usually be String or Enum
      Parameters:
      field1 - FIRST field listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields"
      field2 - SECOND field listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields"
      field3 - THIRD field listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields"
      hierarchyBuilder - builder for default hierarchy. See usage example at this java-doc beginning
    • defaultGroupingHierarchy

      public <D extends org.cxbox.api.data.dto.DataResponseDTO, E1, E2, E3, E4> void defaultGroupingHierarchy(@NonNull @NonNull DtoField<D,E1> field1, @NonNull @NonNull DtoField<D,E2> field2, @NonNull @NonNull DtoField<D,E3> field3, @NonNull @NonNull DtoField<D,E4> field4, @NonNull @NonNull UnaryOperator<org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E1,org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E2,org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E3,org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<E4,?>>>>> hierarchyBuilder)
      ---------------------------------------------------------------------------------------------------------------
      This method sets default hierarchy for "GroupingHierarchy" widget, that will always be shown (even, when widget has no data from backend). Use this method only for hierarchies grouped by FOUR columns

      See usage example here defaultGroupingHierarchy(DtoField, DtoField, UnaryOperator)

      Type Parameters:
      D - DTO type
      E1 - DTO field type. Usually one will use field with "type":"input" or "type":"dictionary, so DTO field types will usually be String or Enum
      Parameters:
      field1 - FIRST field listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields"
      field2 - SECOND field listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields"
      field3 - THIRD field listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields"
      field4 - FOURTH field listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields"
      hierarchyBuilder - builder for default hierarchy. See usage example at this java-doc beginning
    • defaultGroupingHierarchy

      public <D extends org.cxbox.api.data.dto.DataResponseDTO> void defaultGroupingHierarchy(@NonNull @NonNull List<DtoField<D,?>> groupByFields, @NonNull @NonNull org.cxbox.api.data.dto.hierarhy.grouping.Hierarchy<?,?> hierarchy)


      Internal API.

      This method sets default hierarchy for "GroupingHierarchy" widget, that will always be shown (even, when widget has no data from backend). This method is designed to support hierarchies grouped by more, then FOUR columns, but is not strongly typed, so is marked as internal for other cases.

      Please, do not use this method directly. Use one of existing STRONGLY TYPED methods:
      or create own analog if more, then FOUR hierarchy levels are needed
      Type Parameters:
      D - - DTO
      Parameters:
      groupByFields - for widget with "type": "GroupingHierarchy" exactly equal to fields listed in .widget.json -> "options" -> "groupingHierarchy" -> "fields". Fields must be listed in same sequence
      hierarchy - hierarchy structure. This structure will be shown even when widget has no data. If data is present - hierarchy parts that are not present in data will be shown too