@xh/hoist 69.0.0-SNAPSHOT.1728079276919 → 69.0.0-SNAPSHOT.1728081402362

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,10 +2,6 @@
2
2
 
3
3
  ## 69.0.0-SNAPSHOT - unreleased
4
4
 
5
- ### 🐞 Bug Fixes
6
-
7
- * Added a workaround for a bug where Panel drag resizing was broken in Safari.
8
-
9
5
  ### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW )
10
6
  * The `INITIALIZING` AppState has been replaced with more fine-grained states (see below). This
11
7
  is not expected to affect any applications.
@@ -16,6 +12,17 @@ is not expected to affect any applications.
16
12
  more granular tracking and timing of app startup lifecycle.
17
13
  * Improved the default "Loaded App" activity tracking entry with more granular data on load timing.
18
14
 
15
+ ### ⚙️ Technical
16
+
17
+ * Improvements to the typing of `HoistBase.addReaction`. Note that applications may need to adjust
18
+ typescript slightly in calls to this method to conform to the tighter typing.
19
+
20
+
21
+ ### 🐞 Bug Fixes
22
+
23
+ * Added a workaround for a bug where Panel drag resizing was broken in Safari.
24
+
25
+
19
26
  ## 68.1.0 - 2024-09-27
20
27
 
21
28
  ### 🎁 New Features
@@ -4,90 +4,39 @@
4
4
  *
5
5
  * Copyright © 2024 Extremely Heavy Industries Inc.
6
6
  */
7
- import {exportFilenameWithDate} from '@xh/hoist/admin/AdminUtils';
8
- import {AppModel} from '@xh/hoist/admin/AppModel';
9
- import * as Col from '@xh/hoist/admin/columns';
10
- import {LogViewerModel} from '@xh/hoist/admin/tabs/cluster/logs/LogViewerModel';
7
+ import {LogLevelDialogModel} from '@xh/hoist/admin/tabs/cluster/logs/levels/LogLevelDialogModel';
11
8
  import {filler, span} from '@xh/hoist/cmp/layout';
12
- import {hoistCmp} from '@xh/hoist/core';
13
- import {FieldSpec} from '@xh/hoist/data';
9
+ import {creates, hoistCmp} from '@xh/hoist/core';
14
10
  import {button} from '@xh/hoist/desktop/cmp/button';
15
- import {textInput} from '@xh/hoist/desktop/cmp/input';
16
11
  import {panel} from '@xh/hoist/desktop/cmp/panel';
17
- import {restGrid, RestGridConfig} from '@xh/hoist/desktop/cmp/rest';
12
+ import {restGrid} from '@xh/hoist/desktop/cmp/rest';
18
13
  import {Icon} from '@xh/hoist/icon';
19
14
  import {dialog} from '@xh/hoist/kit/blueprint';
20
15
 
21
- export const logLevelDialog = hoistCmp.factory<LogViewerModel>(({model}) =>
22
- dialog({
23
- title: 'Configure Log Levels',
24
- icon: Icon.gear(),
25
- className: 'xh-admin-app__editor-dialog',
26
- isOpen: model.showLogLevelDialog,
27
- canOutsideClickClose: false,
28
- onClose: () => (model.showLogLevelDialog = false),
29
- item: panel({
30
- item: restGrid({modelConfig: {...modelSpec, readonly: AppModel.readonly}}),
31
- bbar: [
32
- Icon.infoCircle(),
33
- span('Note - log level adjustments apply to all instances in the cluster'),
34
- filler(),
35
- button({
36
- text: 'Close',
37
- icon: Icon.close(),
38
- onClick: () => (model.showLogLevelDialog = false)
39
- })
40
- ]
41
- })
42
- })
43
- );
44
-
45
- const modelSpec: RestGridConfig = {
46
- persistWith: {localStorageKey: 'xhAdminLogLevelState'},
47
- colChooserModel: true,
48
- enableExport: true,
49
- exportOptions: {filename: exportFilenameWithDate('log-levels')},
50
- store: {
51
- url: 'rest/logLevelAdmin',
52
- fieldDefaults: {disableXssProtection: true},
53
- fields: [
54
- {
55
- name: 'name',
56
- type: 'string',
57
- displayName: 'Package/Class',
58
- required: true
59
- },
60
- {name: 'level', type: 'string', displayName: 'Override', lookupName: 'levels'},
61
- {name: 'defaultLevel', type: 'string', displayName: 'Initial', editable: false},
62
- {name: 'effectiveLevel', type: 'string', displayName: 'Effective', editable: false},
63
- {...(Col.lastUpdated.field as FieldSpec), editable: false},
64
- {...(Col.lastUpdatedBy.field as FieldSpec), editable: false}
65
- ]
66
- },
67
- unit: 'log level',
68
- filterFields: ['name'],
69
- columns: [
70
- {field: 'name', width: 400},
71
- {field: 'defaultLevel', width: 110},
72
- {field: 'level', width: 110},
73
- {field: 'effectiveLevel', width: 110},
74
- Col.lastUpdated,
75
- Col.lastUpdatedBy
76
- ],
77
- editors: [
78
- {
79
- field: 'name',
80
- formField: {
81
- item: textInput({placeholder: 'com.myapp.MyClassWithLogging (or partial path)'})
82
- }
83
- },
84
- {
85
- field: 'level',
86
- formField: {
87
- info: 'Hint - clear to leave at default while keeping record in place to adjust again later.'
88
- }
89
- },
90
- {field: 'lastUpdated'},
91
- {field: 'lastUpdatedBy'}
92
- ]
93
- };
16
+ export const logLevelDialog = hoistCmp.factory({
17
+ model: creates(LogLevelDialogModel),
18
+ render({model}) {
19
+ const {parent} = model;
20
+ return dialog({
21
+ title: 'Configure Log Levels',
22
+ icon: Icon.gear(),
23
+ className: 'xh-admin-app__editor-dialog',
24
+ isOpen: parent.showLogLevelDialog,
25
+ canOutsideClickClose: false,
26
+ onClose: () => (parent.showLogLevelDialog = false),
27
+ item: panel({
28
+ item: restGrid(),
29
+ bbar: [
30
+ Icon.infoCircle(),
31
+ span('Note - log level adjustments apply to all instances in the cluster'),
32
+ filler(),
33
+ button({
34
+ text: 'Close',
35
+ icon: Icon.close(),
36
+ onClick: () => (parent.showLogLevelDialog = false)
37
+ })
38
+ ]
39
+ })
40
+ });
41
+ }
42
+ });
@@ -0,0 +1,103 @@
1
+ /*
2
+ * This file belongs to Hoist, an application development toolkit
3
+ * developed by Extremely Heavy Industries (www.xh.io | info@xh.io)
4
+ *
5
+ * Copyright © 2024 Extremely Heavy Industries Inc.
6
+ */
7
+ import {exportFilenameWithDate} from '@xh/hoist/admin/AdminUtils';
8
+ import {AppModel} from '@xh/hoist/admin/AppModel';
9
+ import * as Col from '@xh/hoist/admin/columns/Rest';
10
+ import {LogViewerModel} from '@xh/hoist/admin/tabs/cluster/logs/LogViewerModel';
11
+ import {HoistModel, managed, lookup, LoadSpec} from '@xh/hoist/core';
12
+ import {FieldSpec} from '@xh/hoist/data';
13
+ import {textInput} from '@xh/hoist/desktop/cmp/input';
14
+ import {RestGridModel} from '@xh/hoist/desktop/cmp/rest';
15
+
16
+ /**
17
+ * @internal
18
+ */
19
+ export class LogLevelDialogModel extends HoistModel {
20
+ @lookup(LogViewerModel)
21
+ parent: LogViewerModel;
22
+
23
+ @managed
24
+ gridModel: RestGridModel;
25
+
26
+ constructor() {
27
+ super();
28
+ this.gridModel = this.createGridModel();
29
+
30
+ // Force a full-reload after any update. Levels cascade, so need to update entire grid
31
+ const {store} = this.gridModel;
32
+ this.addReaction({
33
+ track: () => store.lastLoaded != store.lastUpdated,
34
+ run: async isUpdated => {
35
+ if (isUpdated) await store.loadAsync();
36
+ }
37
+ });
38
+ }
39
+
40
+ override async doLoadAsync(loadSpec: LoadSpec) {
41
+ this.gridModel.loadAsync(loadSpec);
42
+ }
43
+
44
+ private createGridModel() {
45
+ return new RestGridModel({
46
+ persistWith: {localStorageKey: 'xhAdminLogLevelState'},
47
+ colChooserModel: true,
48
+ enableExport: true,
49
+ exportOptions: {filename: exportFilenameWithDate('log-levels')},
50
+ readonly: AppModel.readonly,
51
+ store: {
52
+ url: 'rest/logLevelAdmin',
53
+ fieldDefaults: {disableXssProtection: true},
54
+ fields: [
55
+ {
56
+ name: 'name',
57
+ type: 'string',
58
+ displayName: 'Package/Class',
59
+ required: true
60
+ },
61
+ {name: 'level', type: 'string', displayName: 'Override', lookupName: 'levels'},
62
+ {name: 'defaultLevel', type: 'string', displayName: 'Initial', editable: false},
63
+ {
64
+ name: 'effectiveLevel',
65
+ type: 'string',
66
+ displayName: 'Effective',
67
+ editable: false
68
+ },
69
+ {...(Col.lastUpdated.field as FieldSpec), editable: false},
70
+ {...(Col.lastUpdatedBy.field as FieldSpec), editable: false}
71
+ ]
72
+ },
73
+ unit: 'log level',
74
+ filterFields: ['name'],
75
+ columns: [
76
+ {field: 'name', width: 400},
77
+ {field: 'defaultLevel', width: 110},
78
+ {field: 'level', width: 110},
79
+ {field: 'effectiveLevel', width: 110},
80
+ Col.lastUpdated,
81
+ Col.lastUpdatedBy
82
+ ],
83
+ editors: [
84
+ {
85
+ field: 'name',
86
+ formField: {
87
+ item: textInput({
88
+ placeholder: 'com.myapp.MyClassWithLogging (or partial path)'
89
+ })
90
+ }
91
+ },
92
+ {
93
+ field: 'level',
94
+ formField: {
95
+ info: 'Hint - clear to leave at default while keeping record in place to adjust again later.'
96
+ }
97
+ },
98
+ {field: 'lastUpdated'},
99
+ {field: 'lastUpdatedBy'}
100
+ ]
101
+ });
102
+ }
103
+ }
@@ -1,2 +1,2 @@
1
- import { LogViewerModel } from '@xh/hoist/admin/tabs/cluster/logs/LogViewerModel';
2
- export declare const logLevelDialog: import("@xh/hoist/core").ElementFactory<import("@xh/hoist/core").DefaultHoistProps<LogViewerModel>>;
1
+ import { LogLevelDialogModel } from '@xh/hoist/admin/tabs/cluster/logs/levels/LogLevelDialogModel';
2
+ export declare const logLevelDialog: import("@xh/hoist/core").ElementFactory<import("@xh/hoist/core").DefaultHoistProps<LogLevelDialogModel>>;
@@ -0,0 +1,13 @@
1
+ import { LogViewerModel } from '@xh/hoist/admin/tabs/cluster/logs/LogViewerModel';
2
+ import { HoistModel, LoadSpec } from '@xh/hoist/core';
3
+ import { RestGridModel } from '@xh/hoist/desktop/cmp/rest';
4
+ /**
5
+ * @internal
6
+ */
7
+ export declare class LogLevelDialogModel extends HoistModel {
8
+ parent: LogViewerModel;
9
+ gridModel: RestGridModel;
10
+ constructor();
11
+ doLoadAsync(loadSpec: LoadSpec): Promise<void>;
12
+ private createGridModel;
13
+ }
@@ -71,9 +71,10 @@ export declare abstract class HoistBase {
71
71
  * @param specs - one or more reactions to add
72
72
  * @returns disposer(s) to manually dispose of each created reaction.
73
73
  */
74
+ addReaction<T>(spec: ReactionSpec<T>): IReactionDisposer;
74
75
  addReaction<T extends any[]>(...specs: {
75
76
  [K in keyof T]: ReactionSpec<T[K]>;
76
- }): IReactionDisposer | IReactionDisposer[];
77
+ }): IReactionDisposer[];
77
78
  /**
78
79
  * Add and start one or more managed autoruns.
79
80
  *
package/core/HoistBase.ts CHANGED
@@ -137,9 +137,12 @@ export abstract class HoistBase {
137
137
  * @param specs - one or more reactions to add
138
138
  * @returns disposer(s) to manually dispose of each created reaction.
139
139
  */
140
+ addReaction<T>(spec: ReactionSpec<T>): IReactionDisposer;
140
141
  addReaction<T extends any[]>(
141
142
  ...specs: {[K in keyof T]: ReactionSpec<T[K]>}
142
- ): IReactionDisposer | IReactionDisposer[] {
143
+ ): IReactionDisposer[];
144
+
145
+ addReaction(...specs: ReactionSpec[]): IReactionDisposer | IReactionDisposer[] {
143
146
  const disposers = specs.map(s => {
144
147
  if (!s) return null;
145
148
  let {track, when, run, debounce, ...rest} = s;
@@ -11,6 +11,7 @@ import {hoistCmp, uses} from '@xh/hoist/core';
11
11
  import {exportButton} from '@xh/hoist/desktop/cmp/button';
12
12
  import {recordActionBar} from '@xh/hoist/desktop/cmp/record';
13
13
  import {toolbar, toolbarSep} from '@xh/hoist/desktop/cmp/toolbar';
14
+ import {refreshButton} from '@xh/hoist/desktop/cmp/button';
14
15
  import {castArray, isEmpty, isFunction} from 'lodash';
15
16
  import {RestGridModel} from '../RestGridModel';
16
17
 
@@ -52,7 +53,8 @@ export const restGridToolbar = hoistCmp.factory({
52
53
  exportButton({
53
54
  gridModel,
54
55
  omit: !model.gridModel.enableExport
55
- })
56
+ }),
57
+ refreshButton({model})
56
58
  );
57
59
  }
58
60
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "69.0.0-SNAPSHOT.1728079276919",
3
+ "version": "69.0.0-SNAPSHOT.1728081402362",
4
4
  "description": "Hoist add-on for building and deploying React Applications.",
5
5
  "repository": "github:xh/hoist-react",
6
6
  "homepage": "https://xh.io",