From 4629590f8d0fdddbdd1072e33a64e98bf54601f7 Mon Sep 17 00:00:00 2001
From: Lee Wexler <lbwexler@xh.io>
Date: Thu, 26 Dec 2024 13:00:26 -0500
Subject: [PATCH] RefreshButton takes target instead of model (#3871)

---
 CHANGELOG.md                                  |  2 +-
 desktop/cmp/button/RefreshButton.ts           | 27 +++++++++----------
 desktop/cmp/rest/impl/RestGridToolbar.ts      |  2 +-
 .../cmp/viewmanager/dialog/ManageDialog.ts    |  2 +-
 mobile/cmp/button/RefreshButton.ts            | 24 ++++++++---------
 5 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad2a1cbf6..e685bc953 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,7 +13,7 @@
   `@xh/hoist/cmp/loadingindicator`.
 * `TreeMap` and `SplitTreeMap` are now cross-platform and can be used in mobile applications.
   Their import paths have changed from `@xh/hoist/desktop/cmp/treemap` to `@xh/hoist/cmp/treemap`.
-
+* The `RefreshButton` `model` prop has been renamed `target` for clarity and consistency.
 ### 🎁 New Features
 
 * Major Improvements to ViewManager component
diff --git a/desktop/cmp/button/RefreshButton.ts b/desktop/cmp/button/RefreshButton.ts
index 859bad807..15933bb40 100644
--- a/desktop/cmp/button/RefreshButton.ts
+++ b/desktop/cmp/button/RefreshButton.ts
@@ -4,35 +4,34 @@
  *
  * Copyright © 2024 Extremely Heavy Industries Inc.
  */
-import {hoistCmp, HoistModel, RefreshContextModel, useContextModel} from '@xh/hoist/core';
+import {hoistCmp, Loadable, RefreshContextModel, useContextModel} from '@xh/hoist/core';
 import '@xh/hoist/desktop/register';
 import {Icon} from '@xh/hoist/icon';
-import {errorIf, withDefault} from '@xh/hoist/utils/js';
 import {button, ButtonProps} from './Button';
+import {apiRemoved} from '@xh/hoist/utils/js';
 
-export type RefreshButtonProps = ButtonProps<HoistModel>;
+export interface RefreshButtonProps extends ButtonProps {
+    /** Object to refresh when clicked. */
+    target?: Loadable;
+}
 
 /**
  * Convenience Button preconfigured for use as a trigger for a refresh operation.
  *
- * If an onClick handler is provided it will be used. Otherwise this button will
- * be linked to any model in props with LoadSupport enabled, or the contextual
+ * If an onClick handler is provided it will be used. Otherwise, this button will
+ * be linked to the target in props with LoadSupport enabled, or the contextual
  * See {@link RefreshContextModel}.
  */
 export const [RefreshButton, refreshButton] = hoistCmp.withFactory<RefreshButtonProps>({
     displayName: 'RefreshButton',
-    model: false, // For consistency with all other buttons -- the model prop here could be replaced by 'target'
+    model: false,
 
-    render({model, onClick, ...props}, ref) {
-        const refreshContextModel = useContextModel(RefreshContextModel);
+    render({target, onClick, ...props}, ref) {
+        apiRemoved('model', {test: props.model, msg: 'Use target instead.'});
 
+        const refreshContextModel = useContextModel(RefreshContextModel);
         if (!onClick) {
-            let target: HoistModel = model;
-            errorIf(
-                target && !target.loadSupport,
-                'Models provided to RefreshButton must enable LoadSupport.'
-            );
-            target = withDefault(target, refreshContextModel);
+            target ??= refreshContextModel;
             onClick = target ? () => target.refreshAsync() : null;
         }
 
diff --git a/desktop/cmp/rest/impl/RestGridToolbar.ts b/desktop/cmp/rest/impl/RestGridToolbar.ts
index e792bb639..42d450cdd 100644
--- a/desktop/cmp/rest/impl/RestGridToolbar.ts
+++ b/desktop/cmp/rest/impl/RestGridToolbar.ts
@@ -55,7 +55,7 @@ export const restGridToolbar = hoistCmp.factory({
                 omit: !model.gridModel.enableExport
             }),
             refreshButton({
-                model,
+                target: model,
                 omit: !model.showRefreshButton
             })
         );
diff --git a/desktop/cmp/viewmanager/dialog/ManageDialog.ts b/desktop/cmp/viewmanager/dialog/ManageDialog.ts
index fe823b21c..9e9de51b4 100644
--- a/desktop/cmp/viewmanager/dialog/ManageDialog.ts
+++ b/desktop/cmp/viewmanager/dialog/ManageDialog.ts
@@ -74,7 +74,7 @@ const selectorPanel = hoistCmp.factory<ManageDialogModel>({
                     onFilterChange: f => (model.filter = f)
                 }),
                 filler(),
-                refreshButton({model})
+                refreshButton({target: model})
             ]
         });
     }
diff --git a/mobile/cmp/button/RefreshButton.ts b/mobile/cmp/button/RefreshButton.ts
index a9f66130e..d315acf72 100644
--- a/mobile/cmp/button/RefreshButton.ts
+++ b/mobile/cmp/button/RefreshButton.ts
@@ -4,13 +4,16 @@
  *
  * Copyright © 2024 Extremely Heavy Industries Inc.
  */
-import {hoistCmp, HoistModel, RefreshContextModel, useContextModel} from '@xh/hoist/core';
+import {hoistCmp, Loadable, RefreshContextModel, useContextModel} from '@xh/hoist/core';
 import {Icon} from '@xh/hoist/icon';
 import {button, ButtonProps} from '@xh/hoist/mobile/cmp/button';
 import '@xh/hoist/mobile/register';
-import {errorIf} from '@xh/hoist/utils/js';
+import {apiRemoved} from '@xh/hoist/utils/js';
 
-export type RefreshButtonProps = ButtonProps<HoistModel>;
+export interface RefreshButtonProps extends ButtonProps {
+    /** Object to refresh when clicked. */
+    target?: Loadable;
+}
 
 /**
  * Convenience Button preconfigured for use as a trigger for a refresh operation.
@@ -21,18 +24,15 @@ export type RefreshButtonProps = ButtonProps<HoistModel>;
  */
 export const [RefreshButton, refreshButton] = hoistCmp.withFactory<RefreshButtonProps>({
     displayName: 'RefreshButton',
-    model: false, // For consistency with all other buttons -- the model prop here could be replaced by 'target'
+    model: false,
 
-    render({model, icon = Icon.sync(), onClick, ...props}) {
-        const refreshContextModel = useContextModel(RefreshContextModel);
+    render({target, icon = Icon.sync(), onClick, ...props}) {
+        apiRemoved('model', {test: props.model, msg: 'Use target instead.'});
 
+        const refreshContextModel = useContextModel(RefreshContextModel);
         if (!onClick) {
-            errorIf(
-                model && !model.loadSupport,
-                'Models provided to RefreshButton must enable LoadSupport.'
-            );
-            model = model ?? refreshContextModel;
-            onClick = model ? () => model.refreshAsync() : null;
+            target ??= refreshContextModel;
+            onClick = target ? () => target.refreshAsync() : null;
         }
 
         return button({icon, onClick, ...props});