Skip to content

Commit bc8488b

Browse files
better read of custom comp
1 parent e2728cc commit bc8488b

File tree

5 files changed

+44
-19
lines changed

5 files changed

+44
-19
lines changed

ui/.eslintrc.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ module.exports = {
5555
'testing-library/await-async-queries': 'error', // Prevent missing awaits on async queries
5656
'testing-library/no-await-sync-queries': 'error', // Prevent unnecessary await on sync queries
5757
'testing-library/no-dom-import': 'error', // Prevent wrong imports; enforce @testing-library/react
58-
'testing-library/prefer-presence-queries': 'error', // prefers getBy*/queryBy* over findBy* for presence/absence checks
58+
'testing-library/prefer-presence-queries': 'error', // prefers getBy*/queryBy* over findBy* for presence/absence checks
5959
},
6060
},
6161
],

ui/src/components/BaseFormView/BaseFormView.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -1116,8 +1116,7 @@ class BaseFormView extends PureComponent<BaseFormProps, BaseFormState> {
11161116
this.props.groupName
11171117
);
11181118
resolve(Hook);
1119-
}
1120-
if (type === 'external') {
1119+
} else if (type === 'external') {
11211120
import(/* @vite-ignore */ `${getBuildDirPath()}/custom/${module}.js`).then(
11221121
(external) => {
11231122
const Hook = external.default as CustomHookConstructor;

ui/src/components/table/CustomTableCell.tsx

+14-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getBuildDirPath } from '../../util/script';
77
import { RowDataFields } from '../../context/TableContext';
88
import { CustomCellBase, CustomCellConstructor } from './CustomTableCellBase';
99
import { invariant } from '../../util/invariant';
10+
import { CustomComponentContextType } from '../../context/CustomComponentContext';
1011

1112
type CustomCellError = {
1213
methodName: string;
@@ -26,6 +27,7 @@ type CustomTableCellProps = {
2627
field: string;
2728
fileName: string;
2829
type: string;
30+
customComponentContext?: CustomComponentContextType;
2931
};
3032

3133
type CustomTableCellState = {
@@ -36,6 +38,8 @@ type CustomTableCellState = {
3638
};
3739

3840
class CustomTableCell extends Component<CustomTableCellProps, CustomTableCellState> {
41+
customComponentContext?: CustomComponentContextType;
42+
3943
customCell?: CustomCellBase;
4044

4145
el: HTMLSpanElement | null = null;
@@ -48,6 +52,7 @@ class CustomTableCell extends Component<CustomTableCellProps, CustomTableCellSta
4852
methodNotPresentError: '', // Stores error message if a method is missing
4953
rowUpdatedByControl: false, // Flag to track if the row was updated by custom control
5054
};
55+
this.customComponentContext = props.customComponentContext; // Store custom component context
5156
}
5257

5358
// Lifecycle method that updates the component's state when props change
@@ -83,8 +88,10 @@ class CustomTableCell extends Component<CustomTableCellProps, CustomTableCellSta
8388
new Promise((resolve, reject) => {
8489
const { type, fileName } = this.props;
8590
const globalConfig = getUnifiedConfigs();
86-
87-
if (type === 'external') {
91+
if (this.customComponentContext?.[this.props.fileName]) {
92+
const Control = this.customComponentContext?.[this.props.fileName];
93+
resolve(Control as CustomCellConstructor);
94+
} else if (type === 'external') {
8895
import(/* webpackIgnore: true */ `${getBuildDirPath()}/custom/${fileName}.js`)
8996
.then((external) => resolve(external.default))
9097
.catch((error) => reject(error));
@@ -137,12 +144,14 @@ class CustomTableCell extends Component<CustomTableCellProps, CustomTableCellSta
137144

138145
this.handleNoRender();
139146
})
140-
.catch(() =>
147+
.catch((e) => {
141148
this.setState({
142149
loading: false,
143150
methodNotPresentError: 'Error loading custom Cell module',
144-
})
145-
);
151+
});
152+
// eslint-disable-next-line no-console
153+
console.error(`[Custom Cell] Error loading custom control ${e}`);
154+
});
146155
}
147156

148157
render() {

ui/src/components/table/CustomTableControl.tsx

+14-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getBuildDirPath } from '../../util/script';
88
import { getExpansionRowData } from './TableExpansionRowData';
99
import { RowDataFields } from '../../context/TableContext';
1010
import { CustomRowBase, CustomRowConstructor } from './CustomRowBase';
11+
import { CustomComponentContextType } from '../../context/CustomComponentContext';
1112

1213
type CustomControlError = {
1314
methodName: string;
@@ -27,6 +28,7 @@ type CustomTableControlProps = {
2728
fileName: string;
2829
type: string;
2930
moreInfo: Array<{ name: string; value: string; mapping?: Record<string, string> }>;
31+
customComponentContext?: CustomComponentContextType;
3032
};
3133

3234
type CustomTableControlState = {
@@ -38,6 +40,8 @@ type CustomTableControlState = {
3840
};
3941

4042
class CustomTableControl extends Component<CustomTableControlProps, CustomTableControlState> {
43+
customComponentContext?: CustomComponentContextType;
44+
4145
customControl?: CustomRowBase; // Custom control instance
4246

4347
el: HTMLSpanElement | null = null; // Reference to the DOM element for the custom control
@@ -54,6 +58,7 @@ class CustomTableControl extends Component<CustomTableControlProps, CustomTableC
5458
rowUpdatedByControl: false, // Flag to track if the row was updated by custom control
5559
};
5660
this.shouldRender = true; // Flag to control rendering logic
61+
this.customComponentContext = props.customComponentContext; // Store custom component context
5762
}
5863

5964
// Lifecycle method that updates the component's state when props change
@@ -101,8 +106,10 @@ class CustomTableControl extends Component<CustomTableControlProps, CustomTableC
101106
new Promise((resolve, reject) => {
102107
const { type, fileName } = this.props;
103108
const globalConfig = getUnifiedConfigs();
104-
105-
if (type === 'external') {
109+
if (this.customComponentContext?.[this.props.fileName]) {
110+
const Control = this.customComponentContext?.[this.props.fileName];
111+
resolve(Control as CustomRowConstructor);
112+
} else if (type === 'external') {
106113
import(/* @vite-ignore */ `${getBuildDirPath()}/custom/${fileName}.js`)
107114
.then((external) => resolve(external.default))
108115
.catch((error) => reject(error));
@@ -195,12 +202,14 @@ class CustomTableControl extends Component<CustomTableControlProps, CustomTableC
195202
this.handleNoGetDLRows();
196203
}
197204
})
198-
.catch(() =>
205+
.catch((e) => {
199206
this.setState({
200207
loading: false,
201208
methodNotPresentError: 'Error loading custom control',
202-
})
203-
);
209+
});
210+
// eslint-disable-next-line no-console
211+
console.error(`[Custom Control] Error loading custom control ${e}`);
212+
});
204213
}
205214

206215
render() {

ui/src/components/table/tests/TableExpansionRow.test.tsx

+14-6
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,12 @@ const getExpandable = (inputRow: HTMLElement) => {
153153
};
154154

155155
async function expectIntervalInExpandedRow(inputRow: HTMLElement, expectedInterval: number) {
156-
mockCustomRowInput();
157156
const expandable = getExpandable(inputRow);
158157
if (expandable.getAttribute('aria-expanded') === 'false') {
159158
await userEvent.click(expandable);
160159
await waitFor(() => expect(expandable.getAttribute('aria-expanded')).not.toBe('false'));
161160
}
161+
162162
const loading = screen.queryByText('Loading...');
163163
if (loading) {
164164
await waitForElementToBeRemoved(loading);
@@ -173,7 +173,7 @@ async function expectIntervalInExpandedRow(inputRow: HTMLElement, expectedInterv
173173
});
174174
}
175175

176-
it('should update custom Expansion Row when Input has changed', async () => {
176+
it('should correctly display custom Expansion Row for Input', async () => {
177177
mockCustomRowInput();
178178
setup();
179179
const inputRow = await screen.findByRole('row', { name: `row-${inputName}` });
@@ -201,10 +201,6 @@ it('should update custom Expansion Row when Input has changed', async () => {
201201
}
202202
)
203203
);
204-
await expectIntervalInExpandedRow(
205-
await screen.findByRole('row', { name: `row-${inputName}` }),
206-
interval
207-
);
208204

209205
await userEvent.click(within(inputRow).getByRole('button', { name: /edit/i }));
210206
const dialog = await screen.findByRole('dialog');
@@ -224,6 +220,18 @@ it('should update custom Expansion Row when Input has changed', async () => {
224220
);
225221
});
226222

223+
it('should update custom Expansion Row when Input has changed', async () => {
224+
mockCustomRowInput();
225+
setup();
226+
227+
expect(
228+
await expectIntervalInExpandedRow(
229+
await screen.findByRole('row', { name: `row-${inputName}` }),
230+
interval
231+
)
232+
).toBeUndefined();
233+
});
234+
227235
it('Should display error message as getDLRows throws Error', async () => {
228236
mockCustomRowInputGetDLError();
229237

0 commit comments

Comments
 (0)