Skip to content

[react@18] More breaking type fixes (should be the last pr)#192266

Merged
Dosant merged 13 commits intoelastic:mainfrom
Dosant:react18/as-fixes
Sep 12, 2024
Merged

[react@18] More breaking type fixes (should be the last pr)#192266
Dosant merged 13 commits intoelastic:mainfrom
Dosant:react18/as-fixes

Conversation

@Dosant
Copy link
Contributor

@Dosant Dosant commented Sep 6, 2024

Summary

Part of #138222

in @types/react@18 types DefinitelyTyped/DefinitelyTyped#56210. This PR addresses a bunch of remaining fixes (hopefully the last mass ping PR like this) The most common are:

1 Objects are no longer considered a valid ReactNode

In types@17 the ReactNode typing was too soft, it allowed objects and functions being passed as ReactNode, e.g.

let obj: React.ReactNode = {};
let func: React.ReactNode = () => {};

This was by mistake, and this PR mutes most of such cases by simply casting to a string or ReactNode.
In some cases, it is worth to follow up and address the raised issues in a better way (see in comments)

function MyComponent() {

const error: string | Error = 'Error'

return (
  <div>
-   {error}
+   {error as string}
  </div>
)

}

Most common problems are related to rendering errors, where it could be string | Error object rendered directly as a ReactNode. Most often it is related to alerting framework:

export interface RuleFormParamsErrors {
  [key: string]: string | string[] | RuleFormParamsErrors;
}

Not sure if there is a better fix then casting, surely not short-term.

2 More useCallback implicit any fixes

Follow up to #191659

3 EuiSelect doesn't have a placeholder prop

In a couple of places, the placeholder prop was removed. This is because react types were updated and placeholder was removed from the base HTML element, so it highlighted places where placeholder prop was redundant

@Dosant Dosant added chore release_note:skip Skip the PR/issue when compiling release notes Team:SharedUX Platform AppEx-SharedUX (formerly Global Experience) t// labels Sep 6, 2024
@Dosant Dosant self-assigned this Sep 6, 2024
css={badgeCss}
>
{logLevel}
{logLevel as React.ReactNode}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logLevel is {} for some reason. Might be worth fixing on a level higher, but I didn't want to look into what would fail :)

*/
export type Props = AllowedButtonProps &
AllowedPopoverProps & {
Omit<AllowedPopoverProps, 'children'> & {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We omit children from this type to properly replace using our custom type

}

const NavigationWrapper: FC<Props & Partial<EuiCollapsibleNavBetaProps>> = (props) => {
const NavigationWrapper: FC<Props & Omit<Partial<EuiCollapsibleNavBetaProps>, 'children'>> = (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We omit children from this type to properly replace using our custom type

) : (
icon
// TODO: check this, icon might be a ComponentType
(icon as unknown as React.ReactNode)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type allows ComponentType and this would render incorrectly in runtime. Worth following up (or feel free to improve in this PR)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the work on this @Dosant! 🙏

A couple of questions. Is the comment still needed?

Also, to clarify - are you saying that if the 'icon' is a component then it would not render correctly?
I believe this component is currently only used with icon types as strings (e.g. 'pencil') passed in. Should it be updated to not allow icon components to be passed in?
cc @qn895 for anything I may have missed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thanks for looking.

Also, to clarify - are you saying that if the 'icon' is a component then it would not render correctly?

Yes!

The type of component allows ComponentType but it isn't handled properly during rendering. I put a TODO to call this out. If the ComponentType is not intended to be used, then the easier fix would be indeed to exclude it from the props. I'll take a look

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated 👍

options={tokenOptions}
value={activeApiToken.type}
onChange={(e) => setTokenType(e.target.value)}
placeholder={i18n.translate(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See explanation in the PR description

restrictWidth={false}
customPageSections
bottomBorder="extended"
docLink="inference_endpoints"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prop didn't exist, hope I am not missing anything

data-test-subj="settingsOutputsFlyout.kafkaVersionInput"
{...inputs.kafkaVersionInput.props}
options={kafkaVersionOptions}
placeholder={i18n.translate(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See explanation in the PR description

<DragAndDropTextList
label={fieldsConfig.patterns.label!}
helpText={fieldsConfig.patterns.helpText}
helpText={
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is follow-up to #192083
I missed it in the pr

/>
</p>
<p>{missingFieldsMessage && missingFieldsMessage.longMessage}</p>
<p>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is worth a follow-up (or feel free to help in this PR)

The longMessage is typed as React.ReactNode | ((closePopover: () => void) => React.ReactNode); but used in the most places simply as a ReactNode, which is incorrect

Ideally, this should simply be ReactNode or a typeof === function case should be handled with every render.

const selectCaseModal = cases.hooks.useCasesAddToExistingCaseModal();

return (
<EuiPageTemplate template="empty">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this prop didn't exist

@Dosant Dosant changed the title [react@18] Breaking type fixes [react@18] More breaking type fixes Sep 6, 2024
@Dosant Dosant changed the title [react@18] More breaking type fixes [react@18] More breaking type fixes (should be the last) Sep 9, 2024
fullWidth
id="timeWindow"
error={errors.timeWindow}
error={errors.timeWindow as string[]}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of dummy casting is caused by this alerting error object that is typed as

export interface RuleFormParamsErrors {
  [key: string]: string | string[] | RuleFormParamsErrors;
}

not sure if there is a better short term fix :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fine, in practice this is only ever string[] 👍

@Dosant Dosant marked this pull request as ready for review September 9, 2024 13:48
@Dosant Dosant requested a review from a team as a code owner September 9, 2024 13:48
@elasticmachine
Copy link
Contributor

Pinging @elastic/appex-sharedux (Team:SharedUX)

@Dosant Dosant requested review from a team as code owners September 9, 2024 13:48
@Dosant Dosant requested a review from a team September 9, 2024 13:48
@Dosant Dosant requested review from a team as code owners September 9, 2024 13:48
Copy link
Contributor

@jeramysoucy jeramysoucy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kibana security changes LGTM

Copy link
Contributor

@criamico criamico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fleet changes LGTM

Copy link
Contributor

@szwarckonrad szwarckonrad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DW/Osquery changes LGTM. Thanks!

itemComponentProps={handleCardProps}
onChange={handlePaginationChange}
error={error}
error={error as React.ReactNode}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps consider tightening the type for the component props, as it seems that error on this side isn’t intended to be a ReactNode.

# Conflicts:
#	x-pack/plugins/lens/public/datasources/form_based/utils.test.tsx
Copy link
Contributor

@alvarezmelissa87 alvarezmelissa87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@eokoneyo eokoneyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shared UX changes LGTM

Copy link
Contributor

@awahab07 awahab07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obs UX Logs changes LGTM!

@Dosant
Copy link
Contributor Author

Dosant commented Sep 11, 2024

@elasticmachine merge upstream

@Dosant
Copy link
Contributor Author

Dosant commented Sep 11, 2024

@elasticmachine merge upstream

@Dosant
Copy link
Contributor Author

Dosant commented Sep 12, 2024

@elasticmachine merge upstream

@kibana-ci
Copy link

kibana-ci commented Sep 12, 2024

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
aiops 547.4KB 547.5KB +40.0B
apm 3.5MB 3.5MB -38.0B
dataVisualizer 725.2KB 725.1KB -21.0B
enterpriseSearch 2.6MB 2.6MB -166.0B
fleet 1.8MB 1.8MB -410.0B
infra 1.6MB 1.6MB -11.0B
ingestPipelines 375.1KB 375.3KB +156.0B
sessionView 392.0KB 392.1KB +4.0B
slo 852.3KB 852.3KB -1.0B
total -447.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
fleet 169.8KB 169.8KB +16.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @Dosant

Copy link
Contributor

@logeekal logeekal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from investigations side. It is a bummer we have to do these castings but thanks for doing it. Just had a small question.

);

const onAlertTableUpdate: AlertsTableStateProps['onUpdate'] = useCallback(
const onAlertTableUpdate = useCallback<NonNullable<AlertsTableStateProps['onUpdate']>>(
Copy link
Contributor

@logeekal logeekal Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask why NonNullable is needed here and what was the problem with previous type?

Copy link
Contributor Author

@Dosant Dosant Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! When assigned like this const onAlertTableUpdate: AlertsTableStateProps['onUpdate']
the argument in the function was implicitly any

to fix it, we assign like this: const onAlertTableUpdate = useCallback<AlertsTableStateProps['onUpdate']>

But this gives an error because AlertsTableStateProps['onUpdate'] could be undefined and it can't be used as a generic param. So with NonNullable we exclude undefined from that type

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect. Thanks for explanation. I understand now.

@Dosant Dosant merged commit 240c4ff into elastic:main Sep 12, 2024
@kibanamachine kibanamachine added v8.16.0 backport:skip This PR does not require backporting labels Sep 12, 2024
@Dosant Dosant mentioned this pull request Sep 12, 2024
@Dosant Dosant added the React@18 label Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apm:review backport:skip This PR does not require backporting chore ci:project-deploy-observability Create an Observability project React@18 release_note:skip Skip the PR/issue when compiling release notes Team:actionable-obs Formerly "obs-ux-management", responsible for SLO, o11y alerting, significant events, & synthetics. Team:Fleet Team label for Observability Data Collection Fleet team Team:Obs AI Assistant Observability AI Assistant Team:obs-ux-infra_services - DEPRECATED DEPRECATED - Use Team:obs-presentation. Team:SharedUX Platform AppEx-SharedUX (formerly Global Experience) t// v8.16.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Comments