001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.uif.layout;
017
018import java.util.List;
019import java.util.Map;
020import java.util.Set;
021
022import org.kuali.rice.krad.uif.component.Component;
023import org.kuali.rice.krad.uif.container.Group;
024import org.kuali.rice.krad.uif.element.Action;
025import org.kuali.rice.krad.uif.element.Label;
026import org.kuali.rice.krad.uif.field.Field;
027import org.kuali.rice.krad.uif.field.FieldGroup;
028import org.kuali.rice.krad.uif.util.ColumnCalculationInfo;
029import org.kuali.rice.krad.uif.widget.RichTable;
030
031/**
032 * Layout manager that works with {@code CollectionGroup} components and renders the collection as a
033 * Table.
034 * 
035 * @author Kuali Rice Team (rice.collab@kuali.org)
036 */
037public interface TableLayoutManager extends CollectionLayoutManager {
038
039    /**
040     * Indicates the number of columns that should make up one row of data.
041     *
042     * <p>If the item count is greater than the number of columns, a new row will
043     * be created to render the remaining items (and so on until all items are
044     * placed).</p>
045     *
046     * <p>Note this does not include any generated columns by the layout manager,
047     * so the final column count could be greater (if label fields are
048     * separate).</p>
049     *
050     * @return int number of columns
051     */
052    int getNumberOfColumns();
053
054    /**
055     * @see TableLayoutManager#getNumberOfColumns()
056     */
057    void setNumberOfColumns(int numberOfColumns);
058
059    /**
060     * Indicates whether the number of columns for the table data should match
061     * the number of fields given in the container's items list (so that each
062     * field takes up one column without wrapping), this overrides the configured
063     * numberOfColumns.
064     *
065     * <p>If set to true during the initialize phase the number of columns will be
066     * set to the size of the container's field list, if false the configured
067     * number of columns is used</p>
068     *
069     * @return true if the column count should match the container's
070     *         field count, false to use the configured number of columns
071     */
072    boolean isSuppressLineWrapping();
073
074    /**
075     * @see TableLayoutManager#isSuppressLineWrapping()
076     */
077    void setSuppressLineWrapping(boolean suppressLineWrapping);
078
079    /**
080     * Indicates whether the column text should be truncated when the table cell
081     * is to small to display the text without wrapping.
082     *
083     * <p>A tooltip is added to the table cell which displays the text before truncation.</p>
084     *
085     * @return true if the column should be truncated
086     */
087    Boolean isAutoTruncateColumns();
088
089    /**
090     * @see TableLayoutManager#isAutoTruncateColumns()
091     */
092    void setAutoTruncateColumns(Boolean autoTruncateColumns);
093
094    /**
095     * Indicates whether alternating row styles should be applied.
096     *
097     * <p>Indicator to layout manager templates to apply alternating row styles.
098     * See the configured template for the actual style classes used</p>
099     *
100     * @return true if alternating styles should be applied, false if
101     *         all rows should have the same style
102     */
103    boolean isApplyAlternatingRowStyles();
104
105    /**
106     * @see TableLayoutManager#isApplyAlternatingRowStyles()
107     */
108    void setApplyAlternatingRowStyles(boolean applyAlternatingRowStyles);
109
110    /**
111     * Indicates whether the manager should default the cell widths.
112     *
113     * <p>If true, the manager will set the cell width by equally dividing by the
114     * number of columns</p>
115     *
116     * @return true if default cell widths should be applied, false if
117     *         no defaults should be applied
118     */
119    boolean isApplyDefaultCellWidths();
120
121    /**
122     * @see TableLayoutManager#isApplyDefaultCellWidths()
123     */
124    void setApplyDefaultCellWidths(boolean applyDefaultCellWidths);
125
126    /**
127     * List of styles for each row.
128     *
129     * <p>Each entry in the list gives the style for the row with the same index. This style will be added to
130     * the <tr> tag when the table rows are rendered in the grid.tag. This is used to store the styles for newly added lines
131     * and other special cases like the add item row.</p>
132     *
133     * @return list of styles for the rows
134     */
135    List<String> getRowCssClasses();
136
137    /**
138     * @see TableLayoutManager#getRowCssClasses()
139     */
140    void setRowCssClasses(List<String> rowCssClasses);
141
142    /**
143     * List of data attributes for each row.
144     *
145     * <p>Each entry in the list gives the data attributes for the row with the same index. These data attributes will be added to
146     * the <tr> tag when the table rows are rendered in the grid.tag. This is used to store the data attributes for newly added lines
147     * and other special cases like the add item row.</p>
148     *
149     * @return list of styles for the rows
150     */
151    List<String> getRowDataAttributes();
152
153    /**
154     * @see TableLayoutManager#getRowDataAttributes()
155     */
156    void setRowDataAttributes(List<String> rowDataAttributes);
157
158    /**
159     * Indicates whether the short label for the collection field should be used as the table header
160     * or the regular label
161     *
162     * @return true if short label should be used, false if long label should be used
163     */
164    boolean isUseShortLabels();
165
166    /**
167     * Setter for the use short label indicator
168     *
169     * @param useShortLabels
170     */
171    void setUseShortLabels(boolean useShortLabels);
172
173    /**
174     * Indicates whether the header should be repeated before each collection row. If false the
175     * header is only rendered at the beginning of the table
176     *
177     * @return true if header should be repeated, false if it should only be rendered once
178     */
179    boolean isRepeatHeader();
180
181    /**
182     * Setter for the repeat header indicator
183     *
184     * @param repeatHeader
185     */
186    void setRepeatHeader(boolean repeatHeader);
187
188    /**
189     * {@code Label} instance to use as a prototype for creating the tables header fields. For each
190     * header field the prototype will be copied and adjusted as necessary
191     *
192     * @return Label instance to serve as prototype
193     */
194    Label getHeaderLabelPrototype();
195
196    /**
197     * Setter for the header field prototype
198     *
199     * @param headerLabelPrototype
200     */
201    void setHeaderLabelPrototype(Label headerLabelPrototype);
202
203    /**
204     * List of {@code Label} instances that should be rendered to make up the tables header
205     *
206     * @return List of label field instances
207     */
208    List<Label> getHeaderLabels();
209
210    /**
211     * Indicates whether the sequence field should be rendered for the collection
212     *
213     * @return true if sequence field should be rendered, false if not
214     */
215    boolean isRenderSequenceField();
216
217    /**
218     * Setter for the render sequence field indicator
219     *
220     * @param renderSequenceField
221     */
222    void setRenderSequenceField(boolean renderSequenceField);
223
224    /**
225     * Attribute name to use as sequence value. For each collection line the value of this field on
226     * the line will be retrieved and used as the sequence value
227     *
228     * @return sequence property name
229     */
230    String getSequencePropertyName();
231
232    /**
233     * Setter for the sequence property name
234     *
235     * @param sequencePropertyName
236     */
237    void setSequencePropertyName(String sequencePropertyName);
238
239    /**
240     * Indicates whether the sequence field should be generated with the current line number
241     *
242     * <p>
243     * If set to true the sequence field prototype will be changed to a message field (if not
244     * already a message field) and the text will be set to the current line number
245     * </p>
246     *
247     * @return true if the sequence field should be generated from the line number, false if not
248     */
249    boolean isGenerateAutoSequence();
250
251    /**
252     * Setter for the generate auto sequence field
253     *
254     * @param generateAutoSequence
255     */
256    void setGenerateAutoSequence(boolean generateAutoSequence);
257
258    /**
259     * {@code Field} instance to serve as a prototype for the sequence field. For each collection
260     * line this instance is copied and adjusted as necessary
261     *
262     * @return Attribute field instance
263     */
264    Field getSequenceFieldPrototype();
265
266    /**
267     * Setter for the sequence field prototype
268     *
269     * @param sequenceFieldPrototype
270     */
271    void setSequenceFieldPrototype(Field sequenceFieldPrototype);
272
273    /**
274     * {@code FieldGroup} instance to serve as a prototype for the actions column. For each
275     * collection line this instance is copied and adjusted as necessary. Note the actual actions
276     * for the group come from the collection groups actions List
277     * (org.kuali.rice.krad.uif.container.CollectionGroup.getActions()). The FieldGroup prototype is
278     * useful for setting styling of the actions column and for the layout of the action fields.
279     * Note also the label associated with the prototype is used for the action column header
280     *
281     * @return GroupField instance
282     */
283    FieldGroup getActionFieldPrototype();
284
285    /**
286     * Setter for the action field prototype
287     *
288     * @param actionFieldPrototype
289     */
290    void setActionFieldPrototype(FieldGroup actionFieldPrototype);
291
292    /**
293     * Indicates whether the add line should be rendered in a separate group, or as part of the
294     * table (first line)
295     *
296     * <p>
297     * When separate add line is enabled, the fields for the add line will be placed in the
298     * {@link #getAddLineGroup()}. This group can be used to configure the add line presentation. In
299     * addition to the fields, the header on the group (unless already set) will be set to
300     * {@link org.kuali.rice.krad.uif.container.CollectionGroup#getAddLabel()} and the add line
301     * actions will be placed into the group's footer.
302     * </p>
303     *
304     * @return true if add line should be separated, false if it should be placed into the table
305     */
306    boolean isSeparateAddLine();
307
308    /**
309     * Setter for the separate add line indicator
310     *
311     * @param separateAddLine
312     */
313    void setSeparateAddLine(boolean separateAddLine);
314
315    /**
316     * List of {@link Field} instances that make up all the table's rows of data
317     *
318     * @return table body fields
319     */
320    List<Field> getAllRowFields();
321
322    /**
323     * List of {@link Field} instances that make us the table's first row of data
324     *
325     * @return list of field instances
326     */
327    List<Field> getFirstRowFields();
328
329    /**
330     * Widget associated with the table to add functionality such as sorting, paging, and export
331     *
332     * @return RichTable instance
333     */
334    RichTable getRichTable();
335
336    /**
337     * Setter for the rich table widget
338     *
339     * @param richTable
340     */
341    void setRichTable(RichTable richTable);
342
343    /**
344     * @return the numberOfDataColumns
345     */
346    int getNumberOfDataColumns();
347
348    /**
349     * @param numberOfDataColumns the numberOfDataColumns to set
350     */
351    void setNumberOfDataColumns(int numberOfDataColumns);
352
353    /**
354     * Gets a set of property names defining hidden columns.
355     * 
356     * @return set of property names
357     * @see org.kuali.rice.krad.uif.widget.RichTable#getHiddenColumns()
358     */
359    Set<String> getHiddenColumns();
360
361    /**
362     * Setter for {@link #getHiddenColumns()}.
363     * 
364     * @param hiddenColumns set of property names
365     */
366    void setHiddenColumns(Set<String> hiddenColumns);
367
368    /**
369     * Gets a set of property names defining sortable columns.
370     * 
371     * @return set of property names
372     * @see org.kuali.rice.krad.uif.widget.RichTable#getSortableColumns()
373     */
374    Set<String> getSortableColumns();
375
376    /**
377     * Setterfor {@link #getSortableColumns()}.
378     * 
379     * @param sortableColumns set of property names
380     */
381    void setSortableColumns(Set<String> sortableColumns);
382
383    /**
384     * Indicates the index of the action column
385     *
386     * @return the action column index
387     */
388    int getActionColumnIndex();
389
390    /**
391     * Indicates the actions column placement
392     *
393     * <p>
394     * Valid values are 'LEFT', 'RIGHT' or any valid number. The default is 'RIGHT' or '-1'. The
395     * column placement index takes all displayed columns, including sequence and selection columns,
396     * into account.
397     * </p>
398     *
399     * @return the action column placement
400     */
401    String getActionColumnPlacement();
402
403    /**
404     * Setter for the action column placement
405     *
406     * @param actionColumnPlacement action column placement string
407     */
408    void setActionColumnPlacement(String actionColumnPlacement);
409
410    /**
411     * The row details info group to use when using a TableLayoutManager with the a richTable.
412     *
413     * <p>
414     * This group will be displayed when the user clicks the "Details" link/image on a row. This
415     * allows extra/long data to be hidden in table rows and then revealed during interaction with
416     * the table without the need to leave the page. Allows for any group content.
417     * </p>
418     *
419     * <p>
420     * Does not currently work with javascript required content.
421     * </p>
422     *
423     * @return rowDetailsGroup component
424     */
425    Group getRowDetailsGroup();
426
427    /**
428     * Set the row details info group
429     *
430     * @param rowDetailsGroup row details group
431     */
432    void setRowDetailsGroup(Group rowDetailsGroup);
433
434    /**
435     * A list of all the columns to be calculated
436     *
437     * <p>
438     * The list must contain valid column indexes. The indexes takes all displayed columns into
439     * account.
440     * </p>
441     *
442     * @return the total columns list
443     */
444    List<String> getColumnsToCalculate();
445
446    /**
447     * Gets showTotal. showTotal shows/calculates the total field when true, otherwise it is not
448     * rendered. <br/>
449     * <b>Only used when renderOnlyLeftTotalLabels is TRUE, this overrides the
450     * ColumnConfigurationInfo setting. Otherwise, the ColumnConfigurationInfo setting takes
451     * precedence.</b>
452     *
453     * @return true if showing the total, false otherwise.
454     */
455    boolean isShowTotal();
456
457    /**
458     * Sets showTotal. showTotal shows/calculates the total field when true, otherwise it is not
459     * rendered. <br/>
460     * <b>Only used when renderOnlyLeftTotalLabels is TRUE, this overrides the
461     * ColumnConfigurationInfo setting. Otherwise, the ColumnConfigurationInfo setting takes
462     * precedence.</b>
463     *
464     * @param showTotal
465     */
466    void setShowTotal(boolean showTotal);
467
468    /**
469     * Gets showTotal. showTotal shows/calculates the total field when true, otherwise it is not
470     * rendered. <br/>
471     * <b>Only used when renderOnlyLeftTotalLabels is TRUE, this overrides the
472     * ColumnConfigurationInfo setting. Otherwise, the ColumnConfigurationInfo setting takes
473     * precedence.</b>
474     *
475     * @return true if showing the page total, false otherwise.
476     */
477    boolean isShowPageTotal();
478
479    /**
480     * Sets showPageTotal. showPageTotal shows/calculates the total field for the page when true
481     * (and only when the table actually has pages), otherwise it is not rendered. <br/>
482     * <b>Only used when renderOnlyLeftTotalLabels is TRUE, this overrides the
483     * ColumnConfigurationInfo setting. Otherwise, the ColumnConfigurationInfo setting takes
484     * precedence.</b>
485     *
486     * @param showPageTotal
487     */
488    void setShowPageTotal(boolean showPageTotal);
489
490    /**
491     * Gets showGroupTotal. showGroupTotal shows/calculates the total field for each grouping when
492     * true (and only when the table actually has grouping turned on), otherwise it is not rendered. <br/>
493     * <b>Only used when renderOnlyLeftTotalLabels is TRUE, this overrides the
494     * ColumnConfigurationInfo setting. Otherwise, the ColumnConfigurationInfo setting takes
495     * precedence.</b>
496     *
497     * @return true if showing the group total, false otherwise.
498     */
499    boolean isShowGroupTotal();
500
501    /**
502     * Sets showGroupTotal. showGroupTotal shows/calculates the total field for each grouping when
503     * true (and only when the table actually has grouping turned on), otherwise it is not rendered. <br/>
504     * <b>Only used when renderOnlyLeftTotalLabels is TRUE, this overrides the
505     * ColumnConfigurationInfo setting. Otherwise, the ColumnConfigurationInfo setting takes
506     * precedence.</b>
507     *
508     * @param showGroupTotal
509     */
510    void setShowGroupTotal(boolean showGroupTotal);
511
512    /**
513     * The total label to use when renderOnlyLeftTotalLabels is TRUE for total. This label will
514     * appear in the left most column.
515     *
516     * @return the totalLabel
517     */
518    Label getTotalLabel();
519
520    /**
521     * Sets the total label to use when renderOnlyLeftTotalLabels is TRUE for total.
522     *
523     * @param totalLabel
524     */
525    void setTotalLabel(Label totalLabel);
526
527    /**
528     * The pageTotal label to use when renderOnlyLeftTotalLabels is TRUE for total. This label will
529     * appear in the left most column.
530     *
531     * @return the totalLabel
532     */
533    Label getPageTotalLabel();
534
535    /**
536     * Sets the pageTotal label to use when renderOnlyLeftTotalLabels is TRUE for total.
537     *
538     * @param pageTotalLabel
539     */
540    void setPageTotalLabel(Label pageTotalLabel);
541
542    /**
543     * The groupTotal label to use when renderOnlyLeftTotalLabels is TRUE. This label will appear in
544     * the left most column.
545     *
546     * @return the totalLabel
547     */
548    Label getGroupTotalLabelPrototype();
549
550    /**
551     * Sets the groupTotal label to use when renderOnlyLeftTotalLabels is TRUE.
552     *
553     * @param groupTotalLabelPrototype
554     */
555    void setGroupTotalLabelPrototype(Label groupTotalLabelPrototype);
556
557    /**
558     * Gets the column calculations. This is a list of ColumnCalcuationInfo that when set provides
559     * calculations to be performed on the columns they specify. These calculations appear in the
560     * table's footer. This feature is only available when using richTable functionality.
561     *
562     * @return the columnCalculations to use
563     */
564    List<ColumnCalculationInfo> getColumnCalculations();
565
566    /**
567     * Sets the columnCalculations.
568     *
569     * @param columnCalculations
570     */
571    void setColumnCalculations(List<ColumnCalculationInfo> columnCalculations);
572
573    /**
574     * When true, labels for the totals fields will only appear in the left most column. Showing of
575     * the totals is controlled by the settings on the TableLayoutManager itself when this property
576     * is true.
577     *
578     * @return true when rendering totals footer labels in the left-most column, false otherwise
579     */
580    boolean isRenderOnlyLeftTotalLabels();
581
582    /**
583     * Set the renderOnlyLeftTotalLabels flag for rendring total labels in the left-most column
584     *
585     * @param renderOnlyLeftTotalLabels
586     */
587    void setRenderOnlyLeftTotalLabels(boolean renderOnlyLeftTotalLabels);
588
589    /**
590     * Gets the footer calculation components to be used by the layout. These are set by the
591     * framework and cannot be set directly.
592     *
593     * @return the list of components for the footer
594     */
595    List<Component> getFooterCalculationComponents();
596
597    /**
598     * Gets the list of property names to use for grouping.
599     *
600     * <p>
601     * When this property is set, grouping for this collection will be enabled and the lines of the
602     * collection will be grouped by the propertyName(s) supplied. Supplying multiple property names
603     * will cause the grouping to be on multiple fields and ordered alphabetically on
604     * "propetyValue1, propertyValue2" (this is also how the group title will display for each
605     * group). The property names supplied must be relative to the line, so #lp SHOULD NOT be used
606     * (it is assumed automatically).
607     * </p>
608     *
609     * @return propertyNames to group on
610     */
611    List<String> getGroupingPropertyNames();
612
613    /**
614     * Sets the list of property names to use for grouping.
615     *
616     * @param groupingPropertyNames
617     */
618    void setGroupingPropertyNames(List<String> groupingPropertyNames);
619
620    /**
621     * Get the groupingTitle. The groupingTitle MUST contain a SpringEL expression to uniquely
622     * identify a group's line (ie it cannot be a static string because each group must be
623     * identified by some value). <b>This overrides groupingPropertyNames(if set) because it
624     * provides full control of grouping value used by the collection. SpringEL defined here must
625     * use #lp if referencing values of the line.</b>
626     *
627     * @return groupingTitle to be used
628     */
629    String getGroupingTitle();
630
631    /**
632     * Set the groupingTitle. This will throw an exception if the title does not contain a SpringEL
633     * expression.
634     *
635     * @param groupingTitle
636     */
637    void setGroupingTitle(String groupingTitle);
638
639    /**
640     * Get the groupingPrefix. The groupingPrefix is used to prefix the generated title (not used
641     * when groupingTitle is set directly) when using groupingPropertyNames.
642     *
643     * @return String
644     */
645    String getGroupingPrefix();
646
647    /**
648     * Set the groupingPrefix. This is not used when groupingTitle is set directly.
649     *
650     * @param groupingPrefix
651     */
652    void setGroupingPrefix(String groupingPrefix);
653
654    /**
655     * If true, all details will be opened by default when the table loads. Can only be used on
656     * tables that have row details setup.
657     *
658     * @return true if row details
659     */
660    boolean isRowDetailsOpen();
661
662    /**
663     * Set if row details should be open on table load
664     *
665     * @param rowDetailsOpen
666     */
667    void setRowDetailsOpen(boolean rowDetailsOpen);
668
669    /**
670     * If true, the toggleAllDetailsAction will be shown. This button allows all details to be
671     * open/closed simultaneously.
672     *
673     * @return true if the action button to toggle all row details opened/closed
674     */
675    boolean isShowToggleAllDetails();
676
677    /**
678     * Set if the toggleAllDetailsAction should be shown
679     *
680     * @param showToggleAllDetails
681     */
682    void setShowToggleAllDetails(boolean showToggleAllDetails);
683
684    /**
685     * The toggleAllDetailsAction action component used to toggle all row details open/closed. This
686     * property is set by the default configuration and should not be reset in most cases.
687     *
688     * @return Action component to use for the toggle action button
689     */
690    Action getToggleAllDetailsAction();
691
692    /**
693     * Set the toggleAllDetailsAction action component used to toggle all row details open/closed.
694     * This property is set by the default configuration and should not be reset in most cases.
695     *
696     * @param toggleAllDetailsAction
697     */
698    void setToggleAllDetailsAction(Action toggleAllDetailsAction);
699
700    /**
701     * If true, when a row details open action is performed, it will get the details content from
702     * the server the first time it is opened. The methodToCall will be a component "refresh" call
703     * by default (this can be set on expandDetailsActionPrototype) and the additional action
704     * parameters sent to the server will be those set on the expandDetailsActionPrototype
705     * (lineIndex will be sent by default).
706     *
707     * @return true if ajax row details retrieval will be used
708     */
709    boolean isAjaxDetailsRetrieval();
710
711    /**
712     * Set if row details content should be retrieved fromt he server
713     *
714     * @param ajaxDetailsRetrieval
715     */
716    void setAjaxDetailsRetrieval(boolean ajaxDetailsRetrieval);
717
718    /**
719     * The Action prototype used for the row details expand link. Should be set to
720     * "Uif-ExpandDetailsAction" or "Uif-ExpandDetailsImageAction". Properties can be configured to
721     * allow for different methodToCall and actionParameters to be set for ajax row details
722     * retrieval.
723     *
724     * @return the Action details link prototype
725     */
726    Action getExpandDetailsActionPrototype();
727
728    /**
729     * Gets the grouping column index
730     *
731     * @return the grouping column index
732     */
733    int getGroupingColumnIndex();
734
735    /**
736     * Set the expand details Action prototype link
737     *
738     * @param expandDetailsActionPrototype
739     */
740    void setExpandDetailsActionPrototype(Action expandDetailsActionPrototype);
741
742    /**
743     * The row css classes for the rows of this layout
744     *
745     * <p>
746     * To set a css class on all rows, use "all" as a key. To set a class for even rows, use "even"
747     * as a key, for odd rows, use "odd". Use a one-based index to target a specific row by index.
748     * SpringEL can be used as a key and the expression will be evaluated; if evaluated to true, the
749     * class(es) specified will be applied.
750     * </p>
751     *
752     * @return a map which represents the css classes of the rows of this layout
753     */
754    Map<String, String> getConditionalRowCssClasses();
755
756    /**
757     * Set the conditionalRowCssClasses
758     *
759     * @param conditionalRowCssClasses
760     */
761    void setConditionalRowCssClasses(Map<String, String> conditionalRowCssClasses);
762
763    /**
764     * Gets a list of column calculation components.
765     * 
766     * @return list of column calculation components
767     */
768   List<Component> getColumnCalculationComponents();
769
770}