Browse Source

react/display-name fix

Leszek Wiesner 4 years ago
parent
commit
cd2d44088a

+ 4 - 1
pioneer/packages/joy-forum/src/validation.tsx

@@ -2,6 +2,7 @@ import React from 'react';
 import { withMulti } from '@polkadot/react-api/with';
 import { InputValidationLengthConstraint } from '@joystream/types/forum';
 import { withForumCalls } from './calls';
+import { componentName } from '@polkadot/joy-utils/react/helpers';
 
 export type ValidationProps = {
   categoryTitleConstraint?: InputValidationLengthConstraint;
@@ -25,7 +26,7 @@ function waitForRequiredConstraints (
   requiredConstraintNames: Array<keyof ValidationProps>
 ) {
   return function (Component: React.ComponentType<any>) {
-    return function (props: ValidationProps) {
+    const ResultComponent: React.FunctionComponent<ValidationProps> = (props: ValidationProps) => {
       const nonEmptyProps = requiredConstraintNames
         .filter(name => props[name] !== undefined)
         .length;
@@ -34,6 +35,8 @@ function waitForRequiredConstraints (
       }
       return <Component {...props} />;
     };
+    ResultComponent.displayName = `waitForRequiredConstraints(${componentName(Component)})`;
+    return ResultComponent;
   };
 }
 

+ 4 - 1
pioneer/packages/joy-media/src/DiscoveryProvider.tsx

@@ -9,6 +9,7 @@ import { Url } from '@joystream/types/discovery';
 import ApiContext from '@polkadot/react-api/ApiContext';
 import { ApiProps } from '@polkadot/react-api/types';
 import { JoyInfo } from '@polkadot/joy-utils/JoyStatus';
+import { componentName } from '@polkadot/joy-utils/react/helpers';
 
 export type BootstrapNodes = {
   bootstrapNodes?: Url[];
@@ -153,7 +154,7 @@ export const useDiscoveryProvider = () =>
   useContext(DiscoveryProviderContext);
 
 export function withDiscoveryProvider (Component: React.ComponentType<DiscoveryProviderProps>) {
-  return (props: React.PropsWithChildren<{}>) => {
+  const ResultComponent: React.FunctionComponent<{}> = (props: React.PropsWithChildren<{}>) => {
     const discoveryProvider = useDiscoveryProvider();
     if (!discoveryProvider) {
       return <JoyInfo title={'Please wait...'}>Loading discovery provider.</JoyInfo>;
@@ -165,4 +166,6 @@ export function withDiscoveryProvider (Component: React.ComponentType<DiscoveryP
       </Component>
     );
   };
+  ResultComponent.displayName = `withDiscoveryProvider(${componentName(Component)})`;
+  return ResultComponent;
 }

+ 66 - 62
pioneer/packages/joy-media/src/common/MediaForms.tsx

@@ -7,6 +7,7 @@ import { TxFailedCallback, TxCallback } from '@polkadot/react-components/Status/
 import { MediaDropdownOptions } from './MediaDropdownOptions';
 import { OnTxButtonClick } from '@polkadot/joy-utils/TxButton';
 import isEqual from 'lodash/isEqual';
+import { componentName } from '@polkadot/joy-utils/react/helpers';
 
 export const datePlaceholder = 'Date in format yyyy-mm-dd';
 
@@ -122,67 +123,70 @@ export function withMediaForm<OuterProps, FormValues>
     }} />;
   };
 
-  return function (props: MediaFormProps<OuterProps, FormValues>) {
-    const {
-      initialValues,
-      values,
-      dirty,
-      touched,
-      errors,
-      isValid,
-      setSubmitting,
-      opts = MediaDropdownOptions.Empty
-    } = props;
-
-    const isFieldChanged = (field: FieldName | FieldObject): boolean => {
-      const fieldName = typeof field === 'string' ? field : (field as FieldObject).id;
-      return (
-        dirty &&
-        touched[fieldName] === true &&
-        !isEqual(values[fieldName], initialValues[fieldName])
-      );
+  const ResultComponent: React.FunctionComponent<MediaFormProps<OuterProps, FormValues>> =
+    (props: MediaFormProps<OuterProps, FormValues>) => {
+      const {
+        initialValues,
+        values,
+        dirty,
+        touched,
+        errors,
+        isValid,
+        setSubmitting,
+        opts = MediaDropdownOptions.Empty
+      } = props;
+
+      const isFieldChanged = (field: FieldName | FieldObject): boolean => {
+        const fieldName = typeof field === 'string' ? field : (field as FieldObject).id;
+        return (
+          dirty &&
+          touched[fieldName] === true &&
+          !isEqual(values[fieldName], initialValues[fieldName])
+        );
+      };
+
+      const onSubmit = (sendTx: () => void) => {
+        if (isValid) {
+          sendTx();
+        } else {
+          console.log('Form is invalid. Errors:', errors);
+        }
+      };
+
+      const onTxSuccess: TxCallback = (_txResult: SubmittableResult) => {
+        setSubmitting(false);
+      };
+
+      const onTxFailed: TxFailedCallback = (txResult: SubmittableResult | null) => {
+        setSubmitting(false);
+        if (txResult === null) {
+          // Tx cancelled
+
+        }
+      };
+
+      const allProps = {
+        ...props,
+
+        // Callbacks:
+        onSubmit,
+        onTxSuccess,
+        onTxFailed,
+
+        // Components:
+        LabelledText,
+        LabelledField,
+        MediaText,
+        MediaField,
+        MediaDropdown,
+
+        // Other
+        opts,
+        isFieldChanged
+      };
+
+      return <Component {...allProps} />;
     };
-
-    const onSubmit = (sendTx: () => void) => {
-      if (isValid) {
-        sendTx();
-      } else {
-        console.log('Form is invalid. Errors:', errors);
-      }
-    };
-
-    const onTxSuccess: TxCallback = (_txResult: SubmittableResult) => {
-      setSubmitting(false);
-    };
-
-    const onTxFailed: TxFailedCallback = (txResult: SubmittableResult | null) => {
-      setSubmitting(false);
-      if (txResult === null) {
-        // Tx cancelled
-
-      }
-    };
-
-    const allProps = {
-      ...props,
-
-      // Callbacks:
-      onSubmit,
-      onTxSuccess,
-      onTxFailed,
-
-      // Components:
-      LabelledText,
-      LabelledField,
-      MediaText,
-      MediaField,
-      MediaDropdown,
-
-      // Other
-      opts,
-      isFieldChanged
-    };
-
-    return <Component {...allProps} />;
-  };
+  ResultComponent.displayName = `withMediaForm(${componentName(Component)})`;
+  return ResultComponent;
 }

+ 7 - 3
pioneer/packages/joy-roles/src/tabs.stories.tsx

@@ -23,10 +23,14 @@ export const RolesPage = () => {
     </Container>
   );
 
+  const renderWorkingGroups = () => tab;
+  const renderOpportunitySandbox = () => <OpportunitySandbox />;
+  const renderMyRolesSandbox = () => <MyRolesSandbox />;
+
   const panes = [
-    { menuItem: 'Working groups', render: () => tab },
-    { menuItem: 'Opportunities', render: () => <OpportunitySandbox /> },
-    { menuItem: 'My roles', render: () => <MyRolesSandbox /> }
+    { menuItem: 'Working groups', render: renderWorkingGroups },
+    { menuItem: 'Opportunities', render: renderOpportunitySandbox },
+    { menuItem: 'My roles', render: renderMyRolesSandbox }
   ];
 
   return (

+ 9 - 7
pioneer/packages/joy-roles/src/tabs/Opportunity.controller.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 
-import { Controller, memoize, View } from '@polkadot/joy-utils/index';
+import { Controller, memoize, View, Params } from '@polkadot/joy-utils/index';
 
 import { ITransport } from '../transport';
 
@@ -41,12 +41,14 @@ export class OpportunityController extends Controller<State, ITransport> {
   }
 }
 
+const renderOpeningView = (state: State, controller: OpportunityController, params: Params) => {
+  controller.getOpportunity(params.get('id'));
+  return (
+    <OpeningView {...state.opportunity!} block_time_in_seconds={state.blockTime!} member_id={state.memberId} />
+  );
+};
+
 export const OpportunityView = View<OpportunityController, State>({
   errorComponent: OpeningError,
-  render: (state, controller, params) => {
-    controller.getOpportunity(params.get('id'));
-    return (
-      <OpeningView {...state.opportunity!} block_time_in_seconds={state.blockTime!} member_id={state.memberId} />
-    );
-  }
+  render: renderOpeningView
 });

+ 64 - 60
pioneer/packages/joy-utils/src/JoyEasyForms.tsx

@@ -6,6 +6,7 @@ import { SubmittableResult } from '@polkadot/api';
 import { TxFailedCallback, TxCallback } from '@polkadot/react-components/Status/types';
 import { OnTxButtonClick } from '@polkadot/joy-utils/TxButton';
 import isEqual from 'lodash/isEqual';
+import { componentName } from '@polkadot/joy-utils/react/helpers';
 
 export type FormCallbacks = {
   onSubmit: OnTxButtonClick;
@@ -118,65 +119,68 @@ export function withEasyForm<OuterProps, FormValues>
     }} />;
   };
 
-  return function (props: EasyFormProps<OuterProps, FormValues>) {
-    const {
-      initialValues,
-      values,
-      dirty,
-      touched,
-      errors,
-      isValid,
-      setSubmitting
-    } = props;
-
-    const isFieldChanged = (field: FieldName | FieldObject): boolean => {
-      const fieldName = typeof field === 'string' ? field : (field as FieldObject).id;
-      return (
-        dirty &&
-        touched[fieldName] === true &&
-        !isEqual(values[fieldName], initialValues[fieldName])
-      );
+  const ResultComponent: React.FunctionComponent<EasyFormProps<OuterProps, FormValues>> =
+    (props: EasyFormProps<OuterProps, FormValues>) => {
+      const {
+        initialValues,
+        values,
+        dirty,
+        touched,
+        errors,
+        isValid,
+        setSubmitting
+      } = props;
+
+      const isFieldChanged = (field: FieldName | FieldObject): boolean => {
+        const fieldName = typeof field === 'string' ? field : (field as FieldObject).id;
+        return (
+          dirty &&
+          touched[fieldName] === true &&
+          !isEqual(values[fieldName], initialValues[fieldName])
+        );
+      };
+
+      const onSubmit = (sendTx: () => void) => {
+        if (isValid) {
+          sendTx();
+        } else {
+          console.log('Form is invalid. Errors:', errors);
+        }
+      };
+
+      const onTxSuccess: TxCallback = (_txResult: SubmittableResult) => {
+        setSubmitting(false);
+      };
+
+      const onTxFailed: TxFailedCallback = (txResult: SubmittableResult | null) => {
+        setSubmitting(false);
+        if (txResult === null) {
+          // Tx cancelled
+
+        }
+      };
+
+      const allProps = {
+        ...props,
+
+        // Callbacks:
+        onSubmit,
+        onTxSuccess,
+        onTxFailed,
+
+        // Components:
+        LabelledText,
+        LabelledField,
+        EasyText,
+        EasyField,
+        EasyDropdown,
+
+        // Other
+        isFieldChanged
+      };
+
+      return <Component {...allProps} />;
     };
-
-    const onSubmit = (sendTx: () => void) => {
-      if (isValid) {
-        sendTx();
-      } else {
-        console.log('Form is invalid. Errors:', errors);
-      }
-    };
-
-    const onTxSuccess: TxCallback = (_txResult: SubmittableResult) => {
-      setSubmitting(false);
-    };
-
-    const onTxFailed: TxFailedCallback = (txResult: SubmittableResult | null) => {
-      setSubmitting(false);
-      if (txResult === null) {
-        // Tx cancelled
-
-      }
-    };
-
-    const allProps = {
-      ...props,
-
-      // Callbacks:
-      onSubmit,
-      onTxSuccess,
-      onTxFailed,
-
-      // Components:
-      LabelledText,
-      LabelledField,
-      EasyText,
-      EasyField,
-      EasyDropdown,
-
-      // Other
-      isFieldChanged
-    };
-
-    return <Component {...allProps} />;
-  };
+  ResultComponent.displayName = `withEasyForm(${componentName(Component)})`;
+  return ResultComponent;
 }

+ 23 - 7
pioneer/packages/joy-utils/src/MyAccount.tsx

@@ -16,6 +16,8 @@ import { useMyAccount } from '@polkadot/joy-utils/MyAccountContext';
 import { queryToProp, MultipleLinkedMapEntry, SingleLinkedMapEntry } from '@polkadot/joy-utils/index';
 import { useMyMembership } from './MyMembershipContext';
 
+import { componentName } from '@polkadot/joy-utils/react/helpers';
+
 export type MyAddressProps = {
   myAddress?: string;
 };
@@ -46,13 +48,15 @@ export type MyAccountProps = MyAddressProps & {
 };
 
 function withMyAddress<P extends MyAccountProps> (Component: React.ComponentType<P>) {
-  return function (props: P) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
     const {
       state: { address }
     } = useMyAccount();
     const myAccountId = address ? new GenericAccountId(address) : undefined;
     return <Component myAddress={address} myAccountId={myAccountId} {...props} />;
   };
+  ResultComponent.displayName = `withMyAddress(${componentName(Component)})`;
+  return ResultComponent;
 }
 
 const withMyMemberIds = withCalls<MyAccountProps>(
@@ -61,7 +65,7 @@ const withMyMemberIds = withCalls<MyAccountProps>(
 );
 
 function withMyMembership<P extends MyAccountProps> (Component: React.ComponentType<P>) {
-  return function (props: P) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
     const { memberIdsByRootAccountId, memberIdsByControllerAccountId } = props;
 
     const myMemberIdChecked = memberIdsByRootAccountId && memberIdsByControllerAccountId;
@@ -84,6 +88,8 @@ function withMyMembership<P extends MyAccountProps> (Component: React.ComponentT
 
     return <Component {...props} {...newProps} />;
   };
+  ResultComponent.displayName = `withMyMembership(${componentName(Component)})`;
+  return ResultComponent;
 }
 
 const withMyProfile = withCalls<MyAccountProps>(queryMembershipToProp('memberProfile', 'myMemberId'));
@@ -94,7 +100,7 @@ const withContentWorkingGroupDetails = withCalls<MyAccountProps>(
 );
 
 function resolveLead<P extends MyAccountProps> (Component: React.ComponentType<P>) {
-  return function (props: P) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
     const { isLeadSet } = props;
 
     let contentLeadId;
@@ -109,6 +115,8 @@ function resolveLead<P extends MyAccountProps> (Component: React.ComponentType<P
 
     return <Component {...props} {...newProps} />;
   };
+  ResultComponent.displayName = `resolveLead(${componentName(Component)})`;
+  return ResultComponent;
 }
 
 const resolveLeadEntry = withCalls<MyAccountProps>(
@@ -119,7 +127,7 @@ const withContentWorkingGroup = <P extends MyAccountProps>(Component: React.Comp
   withMulti(Component, withContentWorkingGroupDetails, resolveLead, resolveLeadEntry);
 
 function withMyRoles<P extends MyAccountProps> (Component: React.ComponentType<P>) {
-  return function (props: P) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
     const { iAmMember, memberProfile } = props;
 
     let myContentLeadId;
@@ -148,6 +156,8 @@ function withMyRoles<P extends MyAccountProps> (Component: React.ComponentType<P
 
     return <Component {...props} {...newProps} />;
   };
+  ResultComponent.displayName = `withMyRoles(${componentName(Component)})`;
+  return ResultComponent;
 }
 
 const canUseAccount = (account: AccountId, allAccounts: SubjectInfo | undefined) => {
@@ -163,7 +173,7 @@ const canUseAccount = (account: AccountId, allAccounts: SubjectInfo | undefined)
 };
 
 function withCurationActor<P extends MyAccountProps> (Component: React.ComponentType<P>) {
-  return function (props: P) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
     const {
       myAccountId,
       isLeadSet,
@@ -257,6 +267,8 @@ function withCurationActor<P extends MyAccountProps> (Component: React.Component
     // we don't have any key that can fulfill a curation action
     return <Component {...props} />;
   };
+  ResultComponent.displayName = `withCurationActor(${componentName(Component)})`;
+  return ResultComponent;
 }
 
 export const withMyAccount = <P extends MyAccountProps>(Component: React.ComponentType<P>) =>
@@ -273,7 +285,7 @@ export const withMyAccount = <P extends MyAccountProps>(Component: React.Compone
   );
 
 export function MembershipRequired<P extends {}> (Component: React.ComponentType<P>): React.ComponentType<P> {
-  return function (props: P) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
     const { myMemberIdChecked, iAmMember } = useMyMembership();
 
     if (!myMemberIdChecked) {
@@ -297,10 +309,12 @@ export function MembershipRequired<P extends {}> (Component: React.ComponentType
       </Message>
     );
   };
+  ResultComponent.displayName = `MembershipRequired(${componentName(Component)})`;
+  return ResultComponent;
 }
 
 export function AccountRequired<P extends {}> (Component: React.ComponentType<P>): React.ComponentType<P> {
-  return function (props: P) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
     const { allAccounts } = useMyMembership();
 
     if (allAccounts && !Object.keys(allAccounts).length) {
@@ -318,6 +332,8 @@ export function AccountRequired<P extends {}> (Component: React.ComponentType<P>
 
     return <Component {...props} />;
   };
+  ResultComponent.displayName = `AccountRequired(${componentName(Component)})`;
+  return ResultComponent;
 }
 
 // TODO: We could probably use withAccountRequired, which wouldn't pass any addiotional props, just like withMembershipRequired.

+ 31 - 29
pioneer/packages/joy-utils/src/forms.tsx

@@ -21,41 +21,43 @@ export type LabelledProps<FormValues> = {
 };
 
 export function LabelledField<FormValues> () {
-  return (props: LabelledProps<FormValues>) => {
-    const { name, label, invisibleLabel = false, tooltip, required = false, touched, errors, children, style } = props;
+  const LabelledFieldInner: React.FunctionComponent<LabelledProps<FormValues>> =
+    (props: LabelledProps<FormValues>) => {
+      const { name, label, invisibleLabel = false, tooltip, required = false, touched, errors, children, style } = props;
 
-    const hasError = name && touched[name] && errors[name];
+      const hasError = name && touched[name] && errors[name];
 
-    const errorClass = hasError ? 'error' : '';
+      const errorClass = hasError ? 'error' : '';
 
-    const fieldWithError =
-      <>
-        <div>{children}</div>
-        {name && hasError && <div className='ui pointing red label'>{errors[name]}</div>}
-      </>;
+      const fieldWithError =
+        <>
+          <div>{children}</div>
+          {name && hasError && <div className='ui pointing red label'>{errors[name]}</div>}
+        </>;
 
-    const renderLabel = () =>
-      nonEmptyStr(label)
-        ? <>
-            {required && <b style={{ color: 'red' }} title='This field is required'>* </b>}
-            {label}
-          </>
-        : null;
+      const renderLabel = () =>
+        nonEmptyStr(label)
+          ? <>
+              {required && <b style={{ color: 'red' }} title='This field is required'>* </b>}
+              {label}
+            </>
+          : null;
 
-    return (label || invisibleLabel)
-      ? <div style={style} className={`ui--Labelled field ${errorClass}`}>
-        <label htmlFor={name as string}>
-          {renderLabel()}
-          {tooltip && <FieldTooltip>{tooltip}</FieldTooltip> }
-        </label>
-        <div className='ui--Labelled-content'>
-          {fieldWithError}
+      return (label || invisibleLabel)
+        ? <div style={style} className={`ui--Labelled field ${errorClass}`}>
+          <label htmlFor={name as string}>
+            {renderLabel()}
+            {tooltip && <FieldTooltip>{tooltip}</FieldTooltip> }
+          </label>
+          <div className='ui--Labelled-content'>
+            {fieldWithError}
+          </div>
         </div>
-      </div>
-      : <div style={style} className={`field ${errorClass}`}>
-        {fieldWithError}
-      </div>;
-  };
+        : <div style={style} className={`field ${errorClass}`}>
+          {fieldWithError}
+        </div>;
+    };
+  return LabelledFieldInner;
 }
 
 export function LabelledText<FormValues> () {

+ 5 - 0
pioneer/packages/joy-utils/src/react/helpers/index.ts

@@ -0,0 +1,5 @@
+import React from 'react';
+
+export function componentName (WrappedComponent: React.ComponentType<any>) {
+  return WrappedComponent.displayName || WrappedComponent.name || 'Component';
+}