This is an automated email from the ASF dual-hosted git repository.

vogievetsky pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new b0c78ff295 Web console: make retention dialog clearer (#14793)
b0c78ff295 is described below

commit b0c78ff295533df80391109c9038a499271ab2a0
Author: Vadim Ogievetsky <[email protected]>
AuthorDate: Fri Aug 11 09:43:00 2023 -0700

    Web console: make retention dialog clearer (#14793)
    
    * make retention dialog clearer
    
    * tweak
    
    * another tweak
    
    * Update web-console/src/dialogs/retention-dialog/retention-dialog.tsx
    
    Co-authored-by: Suneet Saldanha <[email protected]>
    
    * update snapshot for copy
    
    ---------
    
    Co-authored-by: Suneet Saldanha <[email protected]>
---
 .../src/components/json-input/json-input.tsx       |   5 +-
 .../src/components/rule-editor/rule-editor.tsx     |  41 +--
 .../__snapshots__/retention-dialog.spec.tsx.snap   | 326 ++++++++++++++++++++-
 .../dialogs/retention-dialog/retention-dialog.scss |   4 -
 .../dialogs/retention-dialog/retention-dialog.tsx  |  55 ++--
 5 files changed, 363 insertions(+), 68 deletions(-)

diff --git a/web-console/src/components/json-input/json-input.tsx 
b/web-console/src/components/json-input/json-input.tsx
index b206db77e9..f4ffddc111 100644
--- a/web-console/src/components/json-input/json-input.tsx
+++ b/web-console/src/components/json-input/json-input.tsx
@@ -66,7 +66,7 @@ interface InternalValue {
 
 interface JsonInputProps {
   value: any;
-  onChange: (value: any) => void;
+  onChange?: (value: any) => void;
   setError?: (error: Error | undefined) => void;
   placeholder?: string;
   focus?: boolean;
@@ -123,7 +123,7 @@ export const JsonInput = React.memo(function 
JsonInput(props: JsonInputProps) {
 
           setError?.(error);
           if (!error) {
-            onChange(value);
+            onChange?.(value);
           }
 
           if (showErrorIfNeeded) {
@@ -131,6 +131,7 @@ export const JsonInput = React.memo(function 
JsonInput(props: JsonInputProps) {
           }
         }}
         onBlur={() => setShowErrorIfNeeded(true)}
+        readOnly={!onChange}
         focus={focus}
         fontSize={12}
         width={width || '100%'}
diff --git a/web-console/src/components/rule-editor/rule-editor.tsx 
b/web-console/src/components/rule-editor/rule-editor.tsx
index 52eb5b805c..3f72a8ca41 100644
--- a/web-console/src/components/rule-editor/rule-editor.tsx
+++ b/web-console/src/components/rule-editor/rule-editor.tsx
@@ -42,22 +42,23 @@ const PERIOD_SUGGESTIONS: string[] = ['P1D', 'P7D', 'P1M', 
'P1Y', 'P1000Y'];
 export interface RuleEditorProps {
   rule: Rule;
   tiers: string[];
-  onChange(newRule: Rule): void;
-  onDelete(): void;
-  moveUp: (() => void) | undefined;
-  moveDown: (() => void) | undefined;
+  onChange?: (newRule: Rule) => void;
+  onDelete?: () => void;
+  moveUp?: () => void;
+  moveDown?: () => void;
 }
 
 export const RuleEditor = React.memo(function RuleEditor(props: 
RuleEditorProps) {
   const { rule, onChange, tiers, onDelete, moveUp, moveDown } = props;
   const [isOpen, setIsOpen] = useState(true);
+  const disabled = !onChange;
 
   function removeTier(key: string) {
     const newTierReplicants = { ...rule.tieredReplicants };
     delete newTierReplicants[key];
 
     const newRule = { ...rule, tieredReplicants: newTierReplicants };
-    onChange(newRule);
+    onChange?.(newRule);
   }
 
   function addTier() {
@@ -72,7 +73,7 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
       }
     }
 
-    onChange(RuleUtil.addTieredReplicant(rule, newTierName, 1));
+    onChange?.(RuleUtil.addTieredReplicant(rule, newTierName, 1));
   }
 
   function renderTiers() {
@@ -90,14 +91,15 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
       <FormGroup>
         {tieredReplicantsList.map(([tier, replication]) => (
           <ControlGroup key={tier}>
-            <Button minimal style={{ pointerEvents: 'none' }}>
+            <Button minimal disabled={disabled} style={{ pointerEvents: 'none' 
}}>
               Tier:
             </Button>
             <HTMLSelect
               fill
               value={tier}
+              disabled={disabled}
               onChange={(e: any) =>
-                onChange(RuleUtil.renameTieredReplicants(rule, tier, 
e.target.value))
+                onChange?.(RuleUtil.renameTieredReplicants(rule, tier, 
e.target.value))
               }
             >
               <option key={tier} value={tier}>
@@ -111,19 +113,20 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
                   </option>
                 ))}
             </HTMLSelect>
-            <Button minimal style={{ pointerEvents: 'none' }}>
+            <Button minimal disabled={disabled} style={{ pointerEvents: 'none' 
}}>
               Replicants:
             </Button>
             <NumericInput
               value={replication}
+              disabled={disabled}
               onValueChange={(v: number) => {
                 if (isNaN(v)) return;
-                onChange(RuleUtil.addTieredReplicant(rule, tier, v));
+                onChange?.(RuleUtil.addTieredReplicant(rule, tier, v));
               }}
               min={0}
               max={256}
             />
-            <Button onClick={() => removeTier(tier)} icon={IconNames.TRASH} />
+            {onChange && <Button onClick={() => removeTier(tier)} 
icon={IconNames.TRASH} />}
           </ControlGroup>
         ))}
       </FormGroup>
@@ -131,7 +134,7 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
   }
 
   function renderTierAdder() {
-    const { rule, tiers } = props;
+    if (!onChange) return;
     const disabled = Object.keys(rule.tieredReplicants || {}).length >= 
Object.keys(tiers).length;
 
     return (
@@ -163,7 +166,7 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
         <div className="spacer" />
         {moveUp && <Button minimal icon={IconNames.ARROW_UP} onClick={moveUp} 
/>}
         {moveDown && <Button minimal icon={IconNames.ARROW_DOWN} 
onClick={moveDown} />}
-        <Button minimal icon={IconNames.TRASH} onClick={onDelete} />
+        {onDelete && <Button minimal icon={IconNames.TRASH} onClick={onDelete} 
/>}
       </div>
 
       <Collapse isOpen={isOpen}>
@@ -172,7 +175,8 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
             <ControlGroup>
               <HTMLSelect
                 value={rule.type}
-                onChange={(e: any) => onChange(RuleUtil.changeRuleType(rule, 
e.target.value))}
+                disabled={disabled}
+                onChange={(e: any) => onChange?.(RuleUtil.changeRuleType(rule, 
e.target.value))}
               >
                 {RuleUtil.TYPES.map(type => (
                   <option key={type} value={type}>
@@ -184,9 +188,10 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
                 <SuggestibleInput
                   value={rule.period || ''}
                   sanitizer={durationSanitizer}
+                  disabled={disabled}
                   onValueChange={period => {
                     if (typeof period === 'undefined') return;
-                    onChange(RuleUtil.changePeriod(rule, period));
+                    onChange?.(RuleUtil.changePeriod(rule, period));
                   }}
                   placeholder={PERIOD_SUGGESTIONS[0]}
                   suggestions={PERIOD_SUGGESTIONS}
@@ -197,15 +202,17 @@ export const RuleEditor = React.memo(function 
RuleEditor(props: RuleEditorProps)
                   className="include-future"
                   checked={rule.includeFuture || false}
                   label="Include future"
+                  disabled={disabled}
                   onChange={() => {
-                    onChange(RuleUtil.changeIncludeFuture(rule, 
!rule.includeFuture));
+                    onChange?.(RuleUtil.changeIncludeFuture(rule, 
!rule.includeFuture));
                   }}
                 />
               )}
               {RuleUtil.hasInterval(rule) && (
                 <InputGroup
                   value={rule.interval || ''}
-                  onChange={(e: any) => onChange(RuleUtil.changeInterval(rule, 
e.target.value))}
+                  readOnly={!onChange}
+                  onChange={(e: any) => 
onChange?.(RuleUtil.changeInterval(rule, e.target.value))}
                   placeholder="2010-01-01/2020-01-01"
                 />
               )}
diff --git 
a/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap
 
b/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap
index bc3c6b13c3..68fe45ae1b 100644
--- 
a/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap
+++ 
b/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap
@@ -580,31 +580,325 @@ exports[`RetentionDialog matches snapshot 1`] = `
           <div
             class="bp4-form-group"
           >
+            <label
+              class="bp4-label"
+            >
+              Cluster defaults (
+              <a>
+                edit
+              </a>
+              )
+               
+              <span
+                class="bp4-text-muted"
+              />
+            </label>
             <div
               class="bp4-form-content"
             >
               <p>
-                Cluster defaults (
-                <a>
-                  edit
-                </a>
-                ):
+                The cluster default rules are evaluated if none of the above 
rules match.
               </p>
               <div
-                class="default-rule"
+                class="rule-editor"
               >
-                <button
-                  class="bp4-button bp4-disabled"
-                  disabled=""
-                  tabindex="-1"
-                  type="button"
+                <div
+                  class="title"
                 >
-                  <span
-                    class="bp4-button-text"
+                  <button
+                    class="bp4-button bp4-minimal left"
+                    type="button"
                   >
-                    loadForever(2x)
-                  </span>
-                </button>
+                    <span
+                      class="bp4-button-text"
+                    >
+                      loadForever(2x)
+                    </span>
+                    <span
+                      aria-hidden="true"
+                      class="bp4-icon bp4-icon-caret-down"
+                      icon="caret-down"
+                    >
+                      <svg
+                        data-icon="caret-down"
+                        height="16"
+                        role="img"
+                        viewBox="0 0 16 16"
+                        width="16"
+                      >
+                        <path
+                          d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 
00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
+                          fill-rule="evenodd"
+                        />
+                      </svg>
+                    </span>
+                  </button>
+                  <div
+                    class="spacer"
+                  />
+                </div>
+                <div
+                  class="bp4-collapse"
+                  style="height: auto; overflow-y: visible; transition: none;"
+                >
+                  <div
+                    aria-hidden="false"
+                    class="bp4-collapse-body"
+                    style="transform: translateY(0); transition: none;"
+                  >
+                    <div
+                      class="bp4-card bp4-elevation-2"
+                    >
+                      <div
+                        class="bp4-form-group"
+                      >
+                        <div
+                          class="bp4-form-content"
+                        >
+                          <div
+                            class="bp4-control-group"
+                          >
+                            <div
+                              class="bp4-html-select bp4-disabled"
+                            >
+                              <select
+                                disabled=""
+                              >
+                                <option
+                                  value="loadForever"
+                                >
+                                  loadForever
+                                </option>
+                                <option
+                                  value="loadByInterval"
+                                >
+                                  loadByInterval
+                                </option>
+                                <option
+                                  value="loadByPeriod"
+                                >
+                                  loadByPeriod
+                                </option>
+                                <option
+                                  value="dropForever"
+                                >
+                                  dropForever
+                                </option>
+                                <option
+                                  value="dropByInterval"
+                                >
+                                  dropByInterval
+                                </option>
+                                <option
+                                  value="dropByPeriod"
+                                >
+                                  dropByPeriod
+                                </option>
+                                <option
+                                  value="dropBeforeByPeriod"
+                                >
+                                  dropBeforeByPeriod
+                                </option>
+                                <option
+                                  value="broadcastForever"
+                                >
+                                  broadcastForever
+                                </option>
+                                <option
+                                  value="broadcastByInterval"
+                                >
+                                  broadcastByInterval
+                                </option>
+                                <option
+                                  value="broadcastByPeriod"
+                                >
+                                  broadcastByPeriod
+                                </option>
+                              </select>
+                              <span
+                                class="bp4-icon bp4-icon-double-caret-vertical"
+                                icon="double-caret-vertical"
+                              >
+                                <svg
+                                  aria-labelledby="iconTitle-12"
+                                  data-icon="double-caret-vertical"
+                                  height="16"
+                                  role="img"
+                                  viewBox="0 0 16 16"
+                                  width="16"
+                                >
+                                  <title
+                                    id="iconTitle-12"
+                                  >
+                                    Open dropdown
+                                  </title>
+                                  <path
+                                    d="M5 7h6a1.003 1.003 0 
00.71-1.71l-3-3C8.53 2.11 8.28 2 8 2s-.53.11-.71.29l-3 3A1.003 1.003 0 005 7zm6 
2H5a1.003 1.003 0 00-.71 1.71l3 3c.18.18.43.29.71.29s.53-.11.71-.29l3-3A1.003 
1.003 0 0011 9z"
+                                    fill-rule="evenodd"
+                                  />
+                                </svg>
+                              </span>
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                      <div
+                        class="bp4-form-group"
+                      >
+                        <div
+                          class="bp4-form-content"
+                        >
+                          <div
+                            class="bp4-control-group"
+                          >
+                            <button
+                              class="bp4-button bp4-disabled bp4-minimal"
+                              disabled=""
+                              style="pointer-events: none;"
+                              tabindex="-1"
+                              type="button"
+                            >
+                              <span
+                                class="bp4-button-text"
+                              >
+                                Tier:
+                              </span>
+                            </button>
+                            <div
+                              class="bp4-html-select bp4-disabled bp4-fill"
+                            >
+                              <select
+                                disabled=""
+                              >
+                                <option
+                                  value="_default_tier"
+                                >
+                                  _default_tier
+                                </option>
+                              </select>
+                              <span
+                                class="bp4-icon bp4-icon-double-caret-vertical"
+                                icon="double-caret-vertical"
+                              >
+                                <svg
+                                  aria-labelledby="iconTitle-13"
+                                  data-icon="double-caret-vertical"
+                                  height="16"
+                                  role="img"
+                                  viewBox="0 0 16 16"
+                                  width="16"
+                                >
+                                  <title
+                                    id="iconTitle-13"
+                                  >
+                                    Open dropdown
+                                  </title>
+                                  <path
+                                    d="M5 7h6a1.003 1.003 0 
00.71-1.71l-3-3C8.53 2.11 8.28 2 8 2s-.53.11-.71.29l-3 3A1.003 1.003 0 005 7zm6 
2H5a1.003 1.003 0 00-.71 1.71l3 3c.18.18.43.29.71.29s.53-.11.71-.29l3-3A1.003 
1.003 0 0011 9z"
+                                    fill-rule="evenodd"
+                                  />
+                                </svg>
+                              </span>
+                            </div>
+                            <button
+                              class="bp4-button bp4-disabled bp4-minimal"
+                              disabled=""
+                              style="pointer-events: none;"
+                              tabindex="-1"
+                              type="button"
+                            >
+                              <span
+                                class="bp4-button-text"
+                              >
+                                Replicants:
+                              </span>
+                            </button>
+                            <div
+                              class="bp4-control-group bp4-numeric-input"
+                            >
+                              <div
+                                class="bp4-input-group bp4-disabled"
+                              >
+                                <input
+                                  aria-valuemax="256"
+                                  aria-valuemin="0"
+                                  aria-valuenow="2"
+                                  autocomplete="off"
+                                  class="bp4-input"
+                                  disabled=""
+                                  id="numericInput-1"
+                                  max="256"
+                                  min="0"
+                                  role="spinbutton"
+                                  type="text"
+                                  value="2"
+                                />
+                              </div>
+                              <div
+                                class="bp4-button-group bp4-vertical bp4-fixed"
+                              >
+                                <button
+                                  aria-controls="numericInput-1"
+                                  aria-label="increment"
+                                  class="bp4-button bp4-disabled"
+                                  disabled=""
+                                  tabindex="-1"
+                                  type="button"
+                                >
+                                  <span
+                                    aria-hidden="true"
+                                    class="bp4-icon bp4-icon-chevron-up"
+                                    icon="chevron-up"
+                                  >
+                                    <svg
+                                      data-icon="chevron-up"
+                                      height="16"
+                                      role="img"
+                                      viewBox="0 0 16 16"
+                                      width="16"
+                                    >
+                                      <path
+                                        d="M12.71 9.29l-4-4C8.53 5.11 8.28 5 8 
5s-.53.11-.71.29l-4 4a1.003 1.003 0 001.42 1.42L8 7.41l3.29 
3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71z"
+                                        fill-rule="evenodd"
+                                      />
+                                    </svg>
+                                  </span>
+                                </button>
+                                <button
+                                  aria-controls="numericInput-1"
+                                  aria-label="decrement"
+                                  class="bp4-button bp4-disabled"
+                                  disabled=""
+                                  tabindex="-1"
+                                  type="button"
+                                >
+                                  <span
+                                    aria-hidden="true"
+                                    class="bp4-icon bp4-icon-chevron-down"
+                                    icon="chevron-down"
+                                  >
+                                    <svg
+                                      data-icon="chevron-down"
+                                      height="16"
+                                      role="img"
+                                      viewBox="0 0 16 16"
+                                      width="16"
+                                    >
+                                      <path
+                                        d="M12 5c-.28 0-.53.11-.71.29L8 
8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42l4 
4c.18.18.43.29.71.29s.53-.11.71-.29l4-4A1.003 1.003 0 0012 5z"
+                                        fill-rule="evenodd"
+                                      />
+                                    </svg>
+                                  </span>
+                                </button>
+                              </div>
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
               </div>
             </div>
           </div>
diff --git a/web-console/src/dialogs/retention-dialog/retention-dialog.scss 
b/web-console/src/dialogs/retention-dialog/retention-dialog.scss
index df521abbd1..fb55a8d445 100644
--- a/web-console/src/dialogs/retention-dialog/retention-dialog.scss
+++ b/web-console/src/dialogs/retention-dialog/retention-dialog.scss
@@ -45,9 +45,5 @@
         padding: 0 15px;
       }
     }
-
-    .default-rule {
-      margin-top: 10px;
-    }
   }
 }
diff --git a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx 
b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
index 6420413706..677173cc6d 100644
--- a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
+++ b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx
@@ -28,7 +28,6 @@ import { getLink } from '../../links';
 import { Api } from '../../singletons';
 import { filterMap, queryDruidSql, swapElements } from '../../utils';
 import type { Rule } from '../../utils/load-rule';
-import { RuleUtil } from '../../utils/load-rule';
 import { SnitchDialog } from '..';
 
 import './retention-dialog.scss';
@@ -115,28 +114,6 @@ ORDER BY 1`,
     setCurrentRules(swapElements(currentRules, index, index + direction));
   }
 
-  function renderRule(rule: Rule, index: number) {
-    return (
-      <RuleEditor
-        rule={rule}
-        tiers={tiers}
-        key={index}
-        onChange={r => changeRule(r, index)}
-        onDelete={() => deleteRule(index)}
-        moveUp={index > 0 ? () => moveRule(index, -1) : undefined}
-        moveDown={index < currentRules.length - 1 ? () => moveRule(index, 1) : 
undefined}
-      />
-    );
-  }
-
-  function renderDefaultRule(rule: Rule, index: number) {
-    return (
-      <div className="default-rule" key={index}>
-        <Button disabled>{RuleUtil.ruleToString(rule)}</Button>
-      </div>
-    );
-  }
-
   return (
     <SnitchDialog
       className="retention-dialog"
@@ -167,7 +144,17 @@ ORDER BY 1`,
       {currentTab === 'form' ? (
         <FormGroup>
           {currentRules.length ? (
-            currentRules.map(renderRule)
+            currentRules.map((rule, index) => (
+              <RuleEditor
+                key={index}
+                rule={rule}
+                tiers={tiers}
+                onChange={r => changeRule(r, index)}
+                onDelete={() => deleteRule(index)}
+                moveUp={index > 0 ? () => moveRule(index, -1) : undefined}
+                moveDown={index < currentRules.length - 1 ? () => 
moveRule(index, 1) : undefined}
+              />
+            ))
           ) : datasource !== CLUSTER_DEFAULT_FAKE_DATASOURCE ? (
             <p className="no-rules-message">
               This datasource currently has no rules, it will use the cluster 
defaults.
@@ -194,11 +181,21 @@ ORDER BY 1`,
       {datasource !== CLUSTER_DEFAULT_FAKE_DATASOURCE && (
         <>
           <Divider />
-          <FormGroup>
-            <p>
-              Cluster defaults (<a onClick={onEditDefaults}>edit</a>):
-            </p>
-            {defaultRules.map(renderDefaultRule)}
+          <FormGroup
+            label={
+              <>
+                Cluster defaults (<a onClick={onEditDefaults}>edit</a>)
+              </>
+            }
+          >
+            <p>The cluster default rules are evaluated if none of the above 
rules match.</p>
+            {currentTab === 'form' ? (
+              defaultRules.map((rule, index) => (
+                <RuleEditor key={index} rule={rule} tiers={tiers} />
+              ))
+            ) : (
+              <JsonInput value={defaultRules} />
+            )}
           </FormGroup>
         </>
       )}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to