001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.console.views;
018
019import org.apache.juneau.rest.server.filter.*;
020
021/**
022 * Public DOM/CSS contract for a {@code data-juneau-view} table.
023 *
024 * <p>
025 * Table authoring is FTL {@code <@card type="datatables">} (JSON5 catalog).
026 * This type is the stable set of marker attributes and class names the runtime and consumer chrome still
027 * stamp or select: CSRF on a shell ancestor, layout hint, selection/bulk markers, row-detail template
028 * attributes, and the named overflow class. It is not a Java page-authoring factory.
029 *
030 * <h5 class='section'>See Also:</h5>
031 * <ul>
032 *    <li class='jc'>{@link ViewsMixin}
033 *    <li class='jc'>{@link SelectionDef}
034 *    <li class='jc'>{@link BulkMutateDef}
035 * </ul>
036 *
037 * @since 10.0.0
038 */
039public class ViewTable {
040
041   /** Marker attribute the {@code juneau-views.js} runtime looks for to auto-initialize a view table. */
042   public static final String MARKER_ATTR = "data-juneau-view";
043
044   /** Prefix of the sidecar {@code <script>} element id: {@code juneau-view:<viewId>}. */
045   public static final String SIDECAR_ID_PREFIX = "juneau-view:";
046
047   /**
048    * Class stamped on every emitted {@code <table>} &mdash; top-level and nested alike &mdash; and the anchor of the
049    * toolkit's cell-overflow contract.
050    *
051    * <p>
052    * {@code juneau-views.css} clips cell content through the <b>named</b> selector {@code .juneau-view-table td}
053    * rather than a global unnamed {@code td} rule, so the contract reaches only tables this toolkit produced and
054    * never app markup the toolkit does not own.  See {@link #CELL_WRAP_CLASS} for the opt-out.
055    */
056   public static final String TABLE_CLASS = "juneau-view-table";
057
058   /**
059    * Per-cell opt-out from the clip/ellipsis default: {@code .juneau-view-table td.juneau-cell-wrap} restores the
060    * pre-10.0 wrapping behavior.
061    *
062    * <p>
063    * The named renderers whose output is a chip / bar / link rather than prose ({@code progress}, {@code pill},
064    * {@code tag}, {@code linked}) stamp this themselves through their {@code class} facet; an author who wants a
065    * wrapping prose column stamps it through that column's own class.
066    */
067   public static final String CELL_WRAP_CLASS = "juneau-cell-wrap";
068
069   /**
070    * Attribute the CSRF token is stamped into on a shell ancestor (typically {@code <main>}) so
071    * {@code juneau-views.js} can attach it to mutating requests.
072    *
073    * <p>
074    * On an allowed request the {@link LoopbackBoundaryFilter} publishes the process's CSRF token under
075    * {@link LoopbackBoundaryFilter#TOKEN_ATTRIBUTE}; the host copies it here. The runtime <b>fails closed</b>
076    * when this attribute is absent, empty, or whitespace: it visibly refuses to issue any row-action request
077    * rather than sending one the server would 403.
078    */
079   public static final String CSRF_ATTR = "data-juneau-csrf";
080
081   /**
082    * Marker attribute stamped when a {@link SelectionDef} is declared. Pure DOM signaling
083    * &mdash; never part of the {@code VIEW_META} wire contract; see {@link SelectionDef}'s class javadoc.
084    */
085   public static final String SELECT_ATTR = "data-juneau-select";
086
087   /** Attribute carrying {@link SelectionDef#rowIdField()} &mdash; the row-data key the runtime stamps as each row's stable id. */
088   public static final String ROW_ID_FIELD_ATTR = "data-juneau-row-id-field";
089
090   /** Attribute carrying {@code "1"}/{@code "0"} for {@link SelectionDef#selectAll()}. */
091   public static final String SELECT_ALL_ATTR = "data-juneau-select-all";
092
093   /**
094    * Marker attribute stamped when a {@link BulkMutateDef} is declared; pairs with the
095    * {@link #BULK_SIDECAR_ID_PREFIX} sidecar carrying the actual bulk-action list.
096    */
097   public static final String BULK_ATTR = "data-juneau-bulk";
098
099   /** Prefix of the bulk-actions sidecar {@code <script>} element id: {@code juneau-view-bulk:<viewId>}. */
100   public static final String BULK_SIDECAR_ID_PREFIX = "juneau-view-bulk:";
101
102   /**
103    * Full-real-estate layout hint. A first-class public {@code data-juneau-*} convention: consumer chrome
104    * (the console {@code chrome.css} full-bleed {@code :has} rules) can widen the enclosing card/main out of
105    * its default centered {@code max-width}.
106    */
107   public static final String LAYOUT_ATTR = "data-juneau-layout";
108
109   /** The only {@link #LAYOUT_ATTR} value in v1: request full horizontal real estate for the wrapper's content. */
110   public static final String LAYOUT_WIDE = "wide";
111
112   /**
113    * CSS class on the dedicated row-expand header cell so the expander glyph never shares the first data column.
114    */
115   public static final String DETAIL_TH_CLASS = "juneau-view-detail-th";
116
117   /**
118    * CSS class on the dedicated row-expand body cell (and the DataTables column {@code className}).
119    */
120   public static final String DETAIL_CONTROL_CLASS = "juneau-view-detail-control";
121
122   /** Marker attribute on the row-detail {@code <template>} sibling of the view table. */
123   public static final String DETAIL_TEMPLATE_ATTR = "data-juneau-row-detail";
124
125   /** Attribute carrying the row-detail contract version on the row-detail template. */
126   public static final String DETAIL_CONTRACT_ATTR = "data-juneau-detail-contract";
127
128   /** Attribute carrying the server-stamped expand GET path template on the row-detail template. */
129   public static final String DETAIL_URL_ATTR = "data-juneau-detail-url";
130
131   /** Historical section-id marker; no longer emitted (row-detail bodies are one region). */
132   public static final String DETAIL_SECTION_ATTR = "data-juneau-detail-section";
133
134   /** Marker on a client-painted field-grid value slot ({@code fieldGrid} catalog {@code data} key). */
135   public static final String DETAIL_FIELD_ATTR = "data-juneau-field";
136
137   /** Marker on the optional detail-panel header (title + header actions). */
138   public static final String DETAIL_HEADER_ATTR = "data-juneau-detail-header";
139
140   /** Marker on the header title element filled from a <code>{field}</code> template. */
141   public static final String DETAIL_TITLE_ATTR = "data-juneau-detail-title";
142
143   /** Attribute carrying the header title template (placeholders filled at expand time). */
144   public static final String DETAIL_TITLE_TEMPLATE_ATTR = "data-juneau-detail-title-template";
145
146   /**
147    * Comma-separated {@link RegionDef#titleFields} allowlist stamped on the row-detail {@code <template>}.
148    * Copied onto the cloned panel at expand time; {@code paintDetailTitleSlot} substitutes only these keys.
149    */
150   public static final String DETAIL_TITLE_FIELDS_ATTR = "data-juneau-title-fields";
151
152   /** Attribute carrying the header icon registry name. */
153   public static final String DETAIL_ICON_ATTR = "data-juneau-detail-icon";
154
155   /**
156    * Attribute carrying a {@link FieldFormat} wire token.  Omitted for {@link FieldFormat#TEXT}
157    * (the default).
158    */
159   public static final String DETAIL_FIELD_FORMAT_ATTR = "data-juneau-field-format";
160
161   /** Attribute carrying a field-grid render id.  Omitted when render is unset. */
162   public static final String DETAIL_FIELD_RENDER_ATTR = "data-juneau-field-render";
163
164   /**
165    * Attribute carrying JSON-encoded {@link Render#meta}.  Omitted when meta is null or empty.
166    */
167   public static final String DETAIL_FIELD_RENDER_META_ATTR = "data-juneau-field-render-meta";
168
169   /** Attribute carrying a field-grid href template.  Omitted when href is unset. */
170   public static final String DETAIL_FIELD_RENDER_HREF_ATTR = "data-juneau-field-render-href";
171
172   /** Attribute carrying an {@link org.apache.juneau.console.widgets.ActionRef} id on a write button. */
173   public static final String DETAIL_ACTION_ATTR = "data-juneau-action";
174
175   /** Attribute carrying a {@link org.apache.juneau.console.widgets.SafeAction#wire()} token. */
176   public static final String DETAIL_SAFE_ATTR = "data-juneau-safe";
177
178   /**
179    * Attribute carrying an {@link org.apache.juneau.console.widgets.ActionRef}'s row-state rules as a JSON
180    * array, in the author's declared order. Omitted entirely for an ungated action.
181    *
182    * <p>
183    * Each entry is <c>{"field":..., "op":..., "value"?:..., "reason":...}</c> &mdash; the same
184    * JSON-in-a-data-attribute shape {@link #DETAIL_FIELD_RENDER_META_ATTR} uses.  Declaration order is the array
185    * order, because the first failing rule is the one whose reason an operator sees.
186    */
187   public static final String DETAIL_ACTION_RULES_ATTR = "data-juneau-action-rules";
188
189   /**
190    * Attribute on the hidden node a gated action's disabled reason is painted into, carrying that action's id.
191    * Emitted only alongside {@link #DETAIL_ACTION_RULES_ATTR}.
192    *
193    * <p>
194    * The node exists because {@code aria-describedby} needs something real to point at.  It carries the native
195    * HTML {@code hidden} attribute rather than a utility class, so no stylesheet rule is needed to keep it out of
196    * view and none is added.  It carries no element {@code id} here either: this whole subtree is cloned per
197    * expanded row, so the runtime mints the row-unique one.
198    */
199   public static final String DETAIL_ACTION_DESC_ATTR = "data-juneau-action-desc";
200
201   /**
202    * Marker attribute on the nested-table wrapper {@code <div>} (value {@code "1"}).
203    *
204    * <p>
205    * Nested-table seeding inside a row-detail panel is deferred; this marker remains so a later host can
206    * skip auto-init of a nested {@code data-juneau-view} table until its pane is visible.
207    */
208   public static final String NESTED_ATTR = "data-juneau-nested";
209
210   /**
211    * Attribute on the nested VIEW_META sidecar {@code <script>}, carrying the nested view id.
212    *
213    * <p>
214    * The nested sidecar carries no HTML {@code id} (a {@code <template>} clone would collide); the runtime finds it
215    * as a sibling of the nested {@code <table>} by this attribute instead.
216    */
217   public static final String NESTED_META_ATTR = "data-juneau-nested-meta";
218
219   /** Attribute carrying the nested-table contract version on the nested-table wrapper. */
220   public static final String NESTED_CONTRACT_ATTR = "data-juneau-nested-contract";
221
222   /** Attribute carrying the nested-table parent-scope query parameter name on the nested-table wrapper. */
223   public static final String NESTED_SCOPE_PARAM_ATTR = "data-juneau-nested-scope-param";
224
225   private ViewTable() {}
226}