From 4c11546ae7601ad7c69f4fa34417585a04532766 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Date: Thu, 7 Mar 2019 00:18:25 +0100 Subject: [PATCH] transform many components to React Functions --- .../Alerts/Templates/Alert.tsx | 62 +++--- .../Alerts/Templates/AlertType.tsx | 21 +- .../Authorization/Admin/ColoredRadios.tsx | 34 ++-- .../Authorization/Templates/Role.tsx | 27 ++- .../Authorization/Templates/User.tsx | 98 ++++----- .../Basics/Templates/ColorTypeahead.tsx | 78 ++++---- .../Basics/Templates/DateSpan.tsx | 36 ++-- .../Basics/Templates/IconTypeahead.tsx | 104 +++++----- .../Basics/Templates/PropertyRouteCombo.tsx | 45 +++-- .../Basics/Templates/ScrollPanel.tsx | 149 -------------- .../Basics/Templates/TimeSpan.tsx | 42 ++-- .../Dashboard/Admin/Dashboard.tsx | 91 +++++---- .../Dashboard/Admin/LinkListPart.tsx | 36 ++-- .../Dashboard/Admin/UserChartPart.tsx | 30 ++- .../Dashboard/Admin/UserQueryPart.tsx | 19 +- .../Admin/ValueUserQueryListPart.tsx | 40 ++-- .../Dynamic/CSS/DynamicCSSOverride.tsx | 41 ++-- .../Dynamic/Type/DynamicMixinConnection.tsx | 78 ++++---- .../Dynamic/Type/DynamicSqlMigration.tsx | 69 +++---- .../Dynamic/Type/ValueComponent.tsx | 189 +++++++++--------- .../Dynamic/View/HtmlAttributesComponent.tsx | 175 ++++++++-------- .../Excel/Templates/ExcelReport.tsx | 22 +- .../Joyride/Templates/Joyride.tsx | 63 +++--- .../Joyride/Templates/JoyrideStep.tsx | 35 ++-- .../Joyride/Templates/JoyrideStepStyle.tsx | 31 ++- .../PredictorClassificationMetrics.tsx | 48 +++-- .../Templates/PredictorMetrics.tsx | 48 +++-- .../Templates/PredictorRegressionMetrics.tsx | 57 +++--- .../Templates/PredictorSubQuery.tsx | 154 +++++++------- .../MachineLearning/Templates/ProgressBar.tsx | 73 ++++--- .../Templates/SimpleResultButton.tsx | 41 ++-- .../Mailing/MailingMenu.tsx | 54 +++-- .../Mailing/Newsletters/Newsletter.tsx | 22 +- .../Newsletters/NewsletterDelivery.tsx | 24 +-- .../Mailing/Pop3/Pop3Configuration.tsx | 32 ++- .../Mailing/Pop3/Pop3Reception.tsx | 28 ++- .../Mailing/Templates/EmailAddress.tsx | 30 ++- .../Mailing/Templates/EmailConfiguration.tsx | 52 +++-- .../Mailing/Templates/EmailMasterTemplate.tsx | 84 ++++---- .../Mailing/Templates/EmailMessage.tsx | 171 ++++++++-------- .../Mailing/Templates/EmailPackage.tsx | 32 ++- .../Mailing/Templates/EmailRecipient.tsx | 36 ++-- .../Mailing/Templates/EmailTemplate.tsx | 156 +++++++-------- .../Mailing/Templates/SmtpConfiguration.tsx | 72 +++---- Signum.React.Extensions/Notes/NotesClient.tsx | 1 - .../Notes/Templates/Note.tsx | 42 ++-- .../Notes/Templates/NoteType.tsx | 19 -- .../Printing/Templates/PrintLine.tsx | 36 ++-- .../Printing/Templates/PrintPackage.tsx | 24 +-- .../Processes/Templates/Package.tsx | 24 +-- .../Processes/Templates/PackageLine.tsx | 38 ++-- .../Processes/Templates/PackageOperation.tsx | 26 ++- .../Rest/Templates/RestApiKey.tsx | 42 ++-- .../Scheduler/Templates/HolidayCalendar.tsx | 42 ++-- .../Templates/ScheduleRuleMinutely.tsx | 18 +- .../Templates/ScheduleRuleMonths.tsx | 61 +++--- .../Templates/ScheduleRuleWeekDays.tsx | 48 +++-- .../Scheduler/Templates/ScheduledTask.tsx | 28 ++- .../Templating/Templates/QueryModel.tsx | 38 ++-- .../Templates/TemplateApplicable.tsx | 85 ++++---- .../Toolbar/Templates/Toolbar.tsx | 36 ++-- .../Toolbar/Templates/ToolbarElement.tsx | 93 +++++---- .../Toolbar/Templates/ToolbarMenu.tsx | 18 +- .../Tree/Templates/MoveTreeModel.tsx | 44 ++-- Signum.React.Extensions/Tree/TreeButton.tsx | 19 +- .../Templates/QueryTokenEmbeddedBuilder.tsx | 71 +++---- .../Word/Templates/WordTemplate.tsx | 56 +++--- .../Word/WordEntityMenu.tsx | 46 ++--- .../Word/WordSearchMenu.tsx | 49 +++-- .../Workflow/Case/CaseButtonBar.tsx | 81 ++++---- .../Workflow/Case/CaseFlowButton.tsx | 19 +- .../Workflow/Case/CaseTagType.tsx | 28 +-- .../Workflow/Case/CaseTagsModel.tsx | 20 +- Signum.React.Extensions/Workflow/Case/Tag.tsx | 24 +-- .../Workflow/Workflow/WorkflowAction.tsx | 82 ++++---- .../Workflow/WorkflowConnectionModel.tsx | 52 +++-- .../Workflow/Workflow/WorkflowEventModel.tsx | 2 +- .../WorkflowEventTaskActionComponent.tsx | 64 +++--- .../WorkflowEventTaskConditionComponent.tsx | 34 ++-- .../Workflow/WorkflowHelpComponent.tsx | 24 +-- .../Workflow/Workflow/WorkflowLaneModel.tsx | 42 ++-- .../Workflow/WorkflowReplacementComponent.tsx | 104 +++++----- .../Workflow/WorkflowTimerCondition.tsx | 75 ++++--- 83 files changed, 2025 insertions(+), 2459 deletions(-) delete mode 100644 Signum.React.Extensions/Basics/Templates/ScrollPanel.tsx delete mode 100644 Signum.React.Extensions/Notes/Templates/NoteType.tsx diff --git a/Signum.React.Extensions/Alerts/Templates/Alert.tsx b/Signum.React.Extensions/Alerts/Templates/Alert.tsx index 66d5916738..dff468b824 100644 --- a/Signum.React.Extensions/Alerts/Templates/Alert.tsx +++ b/Signum.React.Extensions/Alerts/Templates/Alert.tsx @@ -1,41 +1,37 @@ -import * as React from 'react' +import * as React from 'react' import { ValueLine, EntityLine, EntityCombo } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { AlertEntity } from '../Signum.Entities.Alerts' -export default class Alert extends React.Component<{ ctx: TypeContext }> { +export default function Alert(p : { ctx: TypeContext }){ + const e = p.ctx; - render() { + const ec = e.subCtx({ labelColumns: { sm: 2 } }); + const sc = ec.subCtx({ formGroupStyle: "Basic" }); - const e = this.props.ctx; - const ec = e.subCtx({ labelColumns: { sm: 2 } }); - const sc = ec.subCtx({ formGroupStyle: "Basic" }); - - - return ( -
- {!ec.value.isNew && -
- e.createdBy)} readOnly={true} /> - e.creationDate)} readOnly={true} /> -
- } - {ec.value.target && n.target)} readOnly={true} />} - n.recipient)} /> -
- n.title)} /> - n.alertType)} /> - n.alertDate)} /> - n.text)} valueHtmlAttributes={{ style: { height: "180px" } }} /> - {ec.value.state == "Attended" && -
-
- e.attendedDate)} readOnly={true} /> - e.attendedBy)} readOnly={true} /> -
- } -
- ); - } + return ( +
+ {!ec.value.isNew && +
+ e.createdBy)} readOnly={true} /> + e.creationDate)} readOnly={true} /> +
+ } + {ec.value.target && n.target)} readOnly={true} />} + n.recipient)} /> +
+ n.title)} /> + n.alertType)} /> + n.alertDate)} /> + n.text)} valueHtmlAttributes={{ style: { height: "180px" } }} /> + {ec.value.state == "Attended" && +
+
+ e.attendedDate)} readOnly={true} /> + e.attendedBy)} readOnly={true} /> +
+ } +
+ ); } diff --git a/Signum.React.Extensions/Alerts/Templates/AlertType.tsx b/Signum.React.Extensions/Alerts/Templates/AlertType.tsx index b7adfd6198..93060e4010 100644 --- a/Signum.React.Extensions/Alerts/Templates/AlertType.tsx +++ b/Signum.React.Extensions/Alerts/Templates/AlertType.tsx @@ -1,17 +1,14 @@ -import * as React from 'react' +import * as React from 'react' import { ValueLine } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { AlertTypeEntity } from '../Signum.Entities.Alerts' -export default class AlertType extends React.Component<{ ctx: TypeContext }> { - - render() { - const ctx = this.props.ctx; - const ctx4 = ctx.subCtx({ labelColumns: 2 }); - return ( -
- n.name)} /> -
- ); - } +export default function AlertType(p : { ctx: TypeContext }){ + const ctx = p.ctx; + const ctx4 = ctx.subCtx({ labelColumns: 2 }); + return ( +
+ n.name)} /> +
+ ); } diff --git a/Signum.React.Extensions/Authorization/Admin/ColoredRadios.tsx b/Signum.React.Extensions/Authorization/Admin/ColoredRadios.tsx index 45fd1855b8..842048f06d 100644 --- a/Signum.React.Extensions/Authorization/Admin/ColoredRadios.tsx +++ b/Signum.React.Extensions/Authorization/Admin/ColoredRadios.tsx @@ -1,4 +1,4 @@ -import * as React from 'react' +import * as React from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { IconProp } from '@fortawesome/fontawesome-svg-core' import "./AuthAdmin.css" @@ -11,26 +11,22 @@ interface ColorRadioProps { icon?: IconProp | null; } -export class ColorRadio extends React.Component { - render() { - return ( - { e.preventDefault(); this.props.onClicked(e); }} title={this.props.title} - className="sf-auth-chooser" - style={{ color: this.props.checked ? this.props.color : "#aaa" }}> - - - ); - } +export function ColorRadio(p : ColorRadioProps){ + return ( + { e.preventDefault(); p.onClicked(e); }} title={p.title} + className="sf-auth-chooser" + style={{ color: p.checked ? p.color : "#aaa" }}> + + + ); } -export class GrayCheckbox extends React.Component<{ checked: boolean, onUnchecked: () => void }> { - render() { - return ( - - - - ); - } +export function GrayCheckbox(p : { checked: boolean, onUnchecked: () => void }){ + return ( + + + + ); } diff --git a/Signum.React.Extensions/Authorization/Templates/Role.tsx b/Signum.React.Extensions/Authorization/Templates/Role.tsx index 67def1ba52..fa47164fb9 100644 --- a/Signum.React.Extensions/Authorization/Templates/Role.tsx +++ b/Signum.React.Extensions/Authorization/Templates/Role.tsx @@ -1,23 +1,22 @@ import * as React from 'react' import { RoleEntity, AuthAdminMessage } from '../Signum.Entities.Authorization' import { ValueLine, EntityList, TypeContext } from '@framework/Lines' +import { useForceUpdate } from '@framework/Hooks' -export default class Role extends React.Component<{ ctx: TypeContext }> { +export default function Role(p : { ctx: TypeContext }){ + const forceUpdate = useForceUpdate(); - render() { - const ctx = this.props.ctx; - return ( -
- e.name)} /> - e.mergeStrategy)} unitText={this.rolesMessage()} onChange={() => this.forceUpdate()} /> - e.roles)} onChange={() => this.forceUpdate()} /> -
- ); - } - - rolesMessage(): string { + function rolesMessage() { return AuthAdminMessage.NoRoles.niceToString() + " ⇒ " + - (this.props.ctx.value.mergeStrategy == "Union" ? AuthAdminMessage.Nothing : AuthAdminMessage.Everything).niceToString(); + (p.ctx.value.mergeStrategy == "Union" ? AuthAdminMessage.Nothing : AuthAdminMessage.Everything).niceToString(); } + const ctx = p.ctx; + return ( +
+ e.name)} /> + e.mergeStrategy)} unitText={rolesMessage()} onChange={() => forceUpdate()} /> + e.roles)} onChange={() => forceUpdate()} /> +
+ ); } diff --git a/Signum.React.Extensions/Authorization/Templates/User.tsx b/Signum.React.Extensions/Authorization/Templates/User.tsx index 2897825ee5..5b11aa8ab0 100644 --- a/Signum.React.Extensions/Authorization/Templates/User.tsx +++ b/Signum.React.Extensions/Authorization/Templates/User.tsx @@ -1,79 +1,67 @@ -import * as React from 'react' +import * as React from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { AuthMessage, UserEntity } from '../Signum.Entities.Authorization' +import { AuthMessage, UserEntity, UserState } from '../Signum.Entities.Authorization' import { Binding } from '@framework/Reflection' import { ValueLine, EntityLine, EntityCombo, FormGroup, TypeContext } from '@framework/Lines' -export default class User extends React.Component<{ ctx: TypeContext }, { withPassword: boolean }> { +export default function User(p: { ctx: TypeContext }) { - constructor(props: any) { - super(props); - this.state = { withPassword: false }; - } + const ctx = p.ctx.subCtx({ labelColumns: { sm: 3 } }); + const entity = p.ctx.value; - render() { - const ctx = this.props.ctx.subCtx({ labelColumns: { sm: 3 } }); - const entity = this.props.ctx.value; + return ( +
+ e.state, { readOnly: true })} /> + e.userName)} /> + (ctx, undefined, undefined as any, Binding.create(ctx.value, v => v.newPassword))} isNew={entity.isNew} /> : + e.role)} /> + e.email)} /> + e.cultureInfo)} /> + e.passwordNeverExpires)} /> + e.passwordSetDate)} /> +
+ ); +} - return ( -
- e.state, { readOnly: true })} /> - e.userName)} /> - {entity.isNew || this.state.withPassword ? - (ctx, undefined, undefined as any, Binding.create(ctx.value, v => v.newPassword))} /> : - !ctx.readOnly && this.renderButton(ctx) - } - e.role)} /> - e.email)} /> - e.cultureInfo)} /> - e.passwordNeverExpires)} /> - e.passwordSetDate)} /> -
- ); - } +function DoublePassword(p: { ctx: TypeContext, isNew: boolean }) { - renderButton(ctx: TypeContext) { - return ( - - this.setState({ withPassword: true })}> - {AuthMessage.ChangePassword.niceToString()} - - - ); - } -} + const [withPassword, setWithPassword] = React.useState(p.isNew); -class DoublePassword extends React.Component<{ ctx: TypeContext }>{ + if (!withPassword) { + return + setWithPassword(true)}> + {AuthMessage.ChangePassword.niceToString()} + + + } - handlePasswordBlur = (event: React.SyntheticEvent) => { - const ctx = this.props.ctx; + function handlePasswordBlur(e: React.SyntheticEvent) { + const ctx = p.ctx; - if (this.newPass.value && this.newPass2.value && this.newPass.value != this.newPass2.value) { + if (newPass.current!.value && newPass2.current!.value && newPass.current!.value != newPass2.current!.value) { ctx.error = AuthMessage.PasswordsAreDifferent.niceToString() } else { ctx.error = undefined; - ctx.value = this.newPass.value; + ctx.value = newPass.current!.value; } ctx.frame!.revalidate(); } - newPass!: HTMLInputElement; - newPass2!: HTMLInputElement; + var newPass = React.useRef(null); + var newPass2 = React.useRef(null); - render() { - return ( -
- - this.newPass = p!} className={this.props.ctx.formControlClass} onBlur={this.handlePasswordBlur} /> - - - this.newPass2 = p!} className={this.props.ctx.formControlClass} onBlur={this.handlePasswordBlur} /> - -
- ); - } + return ( +
+ + + + + + +
+ ); } diff --git a/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx b/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx index 80ce6ce01e..f9914b399a 100644 --- a/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx +++ b/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx @@ -1,4 +1,4 @@ - + import * as React from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { classes, Dic } from '@framework/Globals' @@ -6,29 +6,28 @@ import { FormGroup } from '@framework/Lines' import { Typeahead } from '@framework/Components' import { TypeContext } from '@framework/TypeContext' import { namedColors } from '../Color' +import { useForceUpdate } from '@framework/Hooks' -export class ColorTypeaheadLine extends React.Component<{ ctx: TypeContext; onChange?: () => void }>{ - - handleOnChange = (newColor: string | undefined | null) => { - this.props.ctx.value = newColor; - if (this.props.onChange) - this.props.onChange(); - this.forceUpdate(); +export function ColorTypeaheadLine(p : { ctx: TypeContext; onChange?: () => void }){ + const forceUpdate = useForceUpdate(); + function handleOnChange(newColor: string | undefined | null) { + p.ctx.value = newColor; + if (p.onChange) + p.onChange(); + forceUpdate(); } - render() { - var ctx = this.props.ctx; + var ctx = p.ctx; - return ( - - - - ); - } + return ( + + + + ); } interface ColorTypeaheadProps { @@ -37,9 +36,9 @@ interface ColorTypeaheadProps { formControlClass: string | undefined; } -export class ColorTypeahead extends React.Component{ - - handleGetItems = (query: string) => { +export function ColorTypeahead(p : ColorTypeaheadProps){ + const forceUpdate = useForceUpdate(); + function handleGetItems(query: string) { if (!query) return Promise.resolve([ "black", @@ -59,14 +58,13 @@ export class ColorTypeahead extends React.Component{ return Promise.resolve(result); } - handleSelect = (item: unknown | string) => { - this.props.onChange(item as string); - this.forceUpdate(); + function handleSelect(item: unknown | string) { + p.onChange(item as string); + forceUpdate(); return item as string; } - handleRenderItem = (item: unknown, query: string) => { - + function handleRenderItem(item: unknown, query: string) { return ( @@ -75,21 +73,19 @@ export class ColorTypeahead extends React.Component{ ); } - render() { - return ( -
- -
- ); - } + return ( +
+ +
+ ); } diff --git a/Signum.React.Extensions/Basics/Templates/DateSpan.tsx b/Signum.React.Extensions/Basics/Templates/DateSpan.tsx index 52e1601cdb..e68ba1b052 100644 --- a/Signum.React.Extensions/Basics/Templates/DateSpan.tsx +++ b/Signum.React.Extensions/Basics/Templates/DateSpan.tsx @@ -1,27 +1,23 @@ -import * as React from 'react' +import * as React from 'react' import { ValueLine } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { DateSpanEmbedded } from '../Signum.Entities.Basics' -export default class DateSpan extends React.Component<{ ctx: TypeContext }> { +export default function DateSpan(p : { ctx: TypeContext }){ + const e = p.ctx; + const sc = e.subCtx({ formGroupStyle: "BasicDown" }); - render() { - - const e = this.props.ctx; - const sc = e.subCtx({ formGroupStyle: "BasicDown" }); - - return ( -
-
- n.years)} /> -
-
- n.months)} /> -
-
- n.days)} /> -
+ return ( +
+
+ n.years)} /> +
+
+ n.months)} /> +
+
+ n.days)} />
- ); - } +
+ ); } diff --git a/Signum.React.Extensions/Basics/Templates/IconTypeahead.tsx b/Signum.React.Extensions/Basics/Templates/IconTypeahead.tsx index 1e7445ca7c..0b1e036b24 100644 --- a/Signum.React.Extensions/Basics/Templates/IconTypeahead.tsx +++ b/Signum.React.Extensions/Basics/Templates/IconTypeahead.tsx @@ -1,4 +1,4 @@ - + import * as React from 'react' import { classes, Dic } from '@framework/Globals' import { FormGroup } from '@framework/Lines' @@ -7,6 +7,7 @@ import { TypeContext } from '@framework/TypeContext' import { library } from '@fortawesome/fontawesome-svg-core' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { parseIcon } from '../../Dashboard/Admin/Dashboard'; +import { useForceUpdate } from '@framework/Hooks' export interface IconTypeaheadLineProps { ctx: TypeContext; @@ -14,27 +15,25 @@ export interface IconTypeaheadLineProps { extraIcons?: string[]; } -export class IconTypeaheadLine extends React.Component{ - - handleChange = (newIcon: string | undefined | null) => { - this.props.ctx.value = newIcon; - if (this.props.onChange) - this.props.onChange(); - this.forceUpdate(); +export function IconTypeaheadLine(p : IconTypeaheadLineProps){ + const forceUpdate = useForceUpdate(); + function handleChange(newIcon: string | undefined | null) { + p.ctx.value = newIcon; + if (p.onChange) + p.onChange(); + forceUpdate(); } - render() { - var ctx = this.props.ctx; + var ctx = p.ctx; - return ( - - - - ); - } + return ( + + + + ); } export interface IconTypeaheadProps { @@ -44,29 +43,25 @@ export interface IconTypeaheadProps { formControlClass: string | undefined; } -export class IconTypeahead extends React.Component{ - - icons: string[]; - constructor(props: IconTypeaheadProps) { - super(props); +export function IconTypeahead(p: IconTypeaheadProps) { + const forceUpdate = useForceUpdate(); - var lib = library as any as { - definitions: { - [iconPrefix: string]: { - [iconName: string]: any; - } + var lib = library as any as { + definitions: { + [iconPrefix: string]: { + [iconName: string]: any; } - }; + } + }; - var fontAwesome = Dic.getKeys(lib.definitions).flatMap(prefix => Dic.getKeys(lib.definitions[prefix]).map(name => `${prefix} fa-${name}`)); - this.icons = ([] as string[]).concat(props.extraIcons || []).concat(fontAwesome); - } + var fontAwesome = Dic.getKeys(lib.definitions).flatMap(prefix => Dic.getKeys(lib.definitions[prefix]).map(name => `${prefix} fa-${name}`)); + var icons = ([] as string[]).concat(p.extraIcons || []).concat(fontAwesome); - handleGetItems = (query: string) => { + function handleGetItems(query: string) { if (!query) - return Promise.resolve(([] as string[]).concat(this.props.extraIcons || []).concat(["far fa-", "fas fa-"])); + return Promise.resolve(([] as string[]).concat(p.extraIcons || []).concat(["far fa-", "fas fa-"])); - const result = this.icons + const result = icons .filter(k => k.toLowerCase().contains(query.toLowerCase())) .orderBy(a => a.length) .filter((k, i) => i < 5); @@ -74,14 +69,13 @@ export class IconTypeahead extends React.Component{ return Promise.resolve(result); } - handleSelect = (item: string | unknown) => { - this.props.onChange(item as string); - this.forceUpdate(); + function handleSelect(item: string | unknown) { + p.onChange(item as string); + forceUpdate(); return item as string; } - handleRenderItem = (item: unknown, query: string) => { - + function handleRenderItem(item: unknown, query: string) { var icon = parseIcon(item as string); return ( @@ -92,19 +86,17 @@ export class IconTypeahead extends React.Component{ ); } - render() { - return ( -
- -
- ); - } + return ( +
+ +
+ ); } diff --git a/Signum.React.Extensions/Basics/Templates/PropertyRouteCombo.tsx b/Signum.React.Extensions/Basics/Templates/PropertyRouteCombo.tsx index 939899b487..bfcba0a0df 100644 --- a/Signum.React.Extensions/Basics/Templates/PropertyRouteCombo.tsx +++ b/Signum.React.Extensions/Basics/Templates/PropertyRouteCombo.tsx @@ -1,8 +1,9 @@ -import * as React from 'react' +import * as React from 'react' import { Dic } from '@framework/Globals' import { TypeEntity, PropertyRouteEntity } from '@framework/Signum.Entities.Basics' import { TypeContext } from '@framework/Lines' import { getTypeInfo, MemberInfo, PropertyRoute } from "@framework/Reflection"; +import { useForceUpdate } from '@framework/Hooks' export interface PropertyRouteComboProps { @@ -13,32 +14,32 @@ export interface PropertyRouteComboProps { onChange?: () => void; } -export default class PropertyRouteCombo extends React.Component { +export default function PropertyRouteCombo(p : PropertyRouteComboProps){ + const forceUpdate = useForceUpdate(); - static defaultProps: Partial = { - filter: a => a.name != "Id" - }; - handleChange = (e: React.FormEvent) => { + function handleChange(e: React.FormEvent) { var currentValue = (e.currentTarget as HTMLSelectElement).value; - this.props.ctx.value = currentValue ? PropertyRouteEntity.New({ path: currentValue, rootType: this.props.type }) : null; - this.forceUpdate(); - if (this.props.onChange) - this.props.onChange(); + p.ctx.value = currentValue ? PropertyRouteEntity.New({ path: currentValue, rootType: p.type }) : null; + forceUpdate(); + if (p.onChange) + p.onChange(); } - render() { - var ctx = this.props.ctx; + var ctx = p.ctx; - var routes = this.props.routes || Dic.getValues(getTypeInfo(this.props.type.cleanName).members).filter(this.props.filter!).map(mi => PropertyRoute.parse(this.props.type.cleanName, mi.name)); + var routes = p.routes || Dic.getValues(getTypeInfo(p.type.cleanName).members).filter(p.filter!).map(mi => PropertyRoute.parse(p.type.cleanName, mi.name)); - return ( - - );; - } + return ( + + );; } + +PropertyRouteCombo.defaultProps = { + filter: a => a.name != "Id" +} as Partial; diff --git a/Signum.React.Extensions/Basics/Templates/ScrollPanel.tsx b/Signum.React.Extensions/Basics/Templates/ScrollPanel.tsx deleted file mode 100644 index 43f6c101f2..0000000000 --- a/Signum.React.Extensions/Basics/Templates/ScrollPanel.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import * as React from 'react' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' - -export interface ScrollPanelsProps { - children: React.ReactElement[]; - backId?: string; -} - - -export class ScrollPanels extends React.Component { - - render() { - return ( -
-
    - { - this.props.children.map(p => -
  • - {p.props.title} -
  • - ) - } -
- { - React.Children.map(this.props.children, - (p, i) => React.cloneElement((p as React.ReactElement), { eventKey: i, key: i, backId: this.props.backId })) - } -
); - } -} - -export interface ScrollPanelProps { - id: string; - title: React.ReactNode; - backId?: string; -} - -export class ScrollPanel extends React.Component { - render() { - return ( -
-

{this.props.title} {this.props.backId && }

- {this.props.children} -
- ); - } -} - -export interface ScrollchorProps extends React.AnchorHTMLAttributes { - to: string; -} - -export class Scrollchor extends React.Component { - - handleClick = (event: React.MouseEvent) => { - event && event.preventDefault(); - const id = animateScroll(this.props.to, { offset: 0, duration: 500, easing: easeOutQuad }); - } - - render() { - const { to, ...props } = this.props; // eslint-disable-line no-unused-vars - - return !this.props.children - ? null - : ; - } -} - -function easeOutQuad(t: number, start: number, change: number, duration: number) { - return -change * (t /= duration) * (t - 2) + start; -} - -interface AnimateScroll { - offset: number; - duration: number; - easing: (t: number, start: number, change: number, duration: number) => number; -} - -export function animateScroll(id: string, animate: AnimateScroll) { - const element = id ? document.getElementById(id) : document.body; - - if (!element) { - console.warn(`Cannot find element: #${id}`); - return null; - } - - const { offset, duration, easing } = animate; - const parent = getScrollParent(element); - if (!parent) { - console.warn(`Element #${id} has no scroll parent`); - return null; - } - const start = getScrollTop(parent); - const to = getOffsetTop(element, parent) + offset; - const change = to - start; - - function animateFn(elapsedTime = 0) { - const increment = 20; - const elapsed = elapsedTime + increment; - const position = easing(elapsed, start, change, duration); - setScrollTop(parent!, position); - elapsed < duration && - setTimeout(function () { - animateFn(elapsed); - }, increment); - } - - animateFn(); - return id; -} - -function getScrollTop(element: HTMLElement): number { - if (element == document.documentElement) - return document.documentElement.scrollTop || document.body.scrollTop /*Edge*/; - else - return element.scrollTop; -} - -function setScrollTop(element: HTMLElement, value: number) { - if (element == document.documentElement) { - document.documentElement.scrollTop = value; - document.body.scrollTop = value;/*Edge*/ - } else { - element.scrollTop = value; - } -} - -function getScrollParent(element: HTMLElement, includeHidden: boolean = false) { - var style = getComputedStyle(element); - var excludeStaticParent = style.position === "absolute"; - var overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/; - - if (style.position === "fixed") return document.body; - for (var parent: HTMLElement = element; (parent = parent.parentElement!);) { - style = getComputedStyle(parent); - if (excludeStaticParent && style.position === "static") { - continue; - } - if (overflowRegex.test(style.overflow! + style.overflowY! + style.overflowX!)) - return parent; - } - - return document.documentElement; -} - -function getOffsetTop(element: HTMLElement, scrollParent: HTMLElement) { - const { top } = element.getBoundingClientRect(); - return top + getScrollTop(scrollParent); -} diff --git a/Signum.React.Extensions/Basics/Templates/TimeSpan.tsx b/Signum.React.Extensions/Basics/Templates/TimeSpan.tsx index 1544d0e4ee..578f31eecc 100644 --- a/Signum.React.Extensions/Basics/Templates/TimeSpan.tsx +++ b/Signum.React.Extensions/Basics/Templates/TimeSpan.tsx @@ -1,30 +1,26 @@ -import * as React from 'react' +import * as React from 'react' import { ValueLine } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { TimeSpanEmbedded } from '../Signum.Entities.Basics' -export default class TimeSpan extends React.Component<{ ctx: TypeContext }> { +export default function TimeSpan(p : { ctx: TypeContext }){ + const e = p.ctx; + const sc = e.subCtx({ formGroupStyle: "BasicDown" }); - render() { - - const e = this.props.ctx; - const sc = e.subCtx({ formGroupStyle: "BasicDown" }); - - return ( -
-
- n.days)} /> -
-
- n.hours)} /> -
-
- n.minutes)} /> -
-
- n.seconds)} /> -
+ return ( +
+
+ n.days)} /> +
+
+ n.hours)} /> +
+
+ n.minutes)} /> +
+
+ n.seconds)} />
- ); - } +
+ ); } diff --git a/Signum.React.Extensions/Dashboard/Admin/Dashboard.tsx b/Signum.React.Extensions/Dashboard/Admin/Dashboard.tsx index 29d581e5c9..691089362a 100644 --- a/Signum.React.Extensions/Dashboard/Admin/Dashboard.tsx +++ b/Signum.React.Extensions/Dashboard/Admin/Dashboard.tsx @@ -13,52 +13,19 @@ import { IconTypeaheadLine } from "../../Basics/Templates/IconTypeahead"; import { ColorTypeaheadLine } from "../../Basics/Templates/ColorTypeahead"; import "../Dashboard.css" import { getToString } from '@framework/Signum.Entities'; +import { useForceUpdate } from '@framework/Hooks' -export default class Dashboard extends React.Component<{ ctx: TypeContext }> { +export default function Dashboard(p : { ctx: TypeContext }){ + const forceUpdate = useForceUpdate(); + function handleEntityTypeChange() { + if (!p.ctx.value.entityType) + p.ctx.value.embeddedInEntity = null; - handleEntityTypeChange = () => { - if (!this.props.ctx.value.entityType) - this.props.ctx.value.embeddedInEntity = null; - - this.forceUpdate() + forceUpdate() } - render() { - const ctx = this.props.ctx; - const sc = ctx.subCtx({ formGroupStyle: "Basic" }); - return ( -
-
-
-
- cp.displayName)} /> -
-
- cp.dashboardPriority)} /> -
-
- cp.autoRefreshPeriod)} /> -
-
-
-
- cp.owner)} create={false} /> -
-
- cp.entityType)} onChange={this.handleEntityTypeChange} /> -
- {sc.value.entityType &&
- f.embeddedInEntity)} /> -
} -
-
- cp.combineSimilarRows)} inlineCheckbox={true} /> - cp.parts)} getComponent={this.renderPart} onCreate={this.handleOnCreate} /> -
- ); - } - handleOnCreate = () => { + function handleOnCreate() { const pr = DashboardEntity.memberInfo(a => a.parts![0].element.content); return SelectorModal.chooseType(getTypeInfos(pr.type)) @@ -80,8 +47,7 @@ export default class Dashboard extends React.Component<{ ctx: TypeContext) => { - + function renderPart(tc: TypeContext) { const tcs = tc.subCtx({ formGroupStyle: "SrOnly", formSize: "ExtraSmall", placeholderLabels: true }); var icon = parseIcon(tc.value.iconName); @@ -96,13 +62,13 @@ export default class Dashboard extends React.Component<{ ctx: TypeContext pp.title)} labelText={getToString(tcs.value.content) || tcs.niceName(pp => pp.title)} />
- pp.style)} onChange={() => this.forceUpdate()} /> + pp.style)} onChange={() => forceUpdate()} />
- t.iconName)} onChange={() => this.forceUpdate()} /> + t.iconName)} onChange={() => forceUpdate()} />
- t.iconColor)} onChange={() => this.forceUpdate()} /> + t.iconColor)} onChange={() => forceUpdate()} />
@@ -116,6 +82,39 @@ export default class Dashboard extends React.Component<{ ctx: TypeContext ); } + + const ctx = p.ctx; + const sc = ctx.subCtx({ formGroupStyle: "Basic" }); + return ( +
+
+
+
+ cp.displayName)} /> +
+
+ cp.dashboardPriority)} /> +
+
+ cp.autoRefreshPeriod)} /> +
+
+
+
+ cp.owner)} create={false} /> +
+
+ cp.entityType)} onChange={handleEntityTypeChange} /> +
+ {sc.value.entityType &&
+ f.embeddedInEntity)} /> +
} +
+
+ cp.combineSimilarRows)} inlineCheckbox={true} /> + cp.parts)} getComponent={renderPart} onCreate={handleOnCreate} /> +
+ ); } diff --git a/Signum.React.Extensions/Dashboard/Admin/LinkListPart.tsx b/Signum.React.Extensions/Dashboard/Admin/LinkListPart.tsx index 4c00135238..05be61ab74 100644 --- a/Signum.React.Extensions/Dashboard/Admin/LinkListPart.tsx +++ b/Signum.React.Extensions/Dashboard/Admin/LinkListPart.tsx @@ -4,26 +4,20 @@ import { ValueLine, EntityRepeater } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { LinkListPartEntity, LinkElementEmbedded } from '../Signum.Entities.Dashboard' -export default class ValueSearchControlPart extends React.Component<{ ctx: TypeContext }> { +export default function ValueSearchControlPart(p : { ctx: TypeContext }){ + const ctx = p.ctx.subCtx({ formGroupStyle: "SrOnly", placeholderLabels: true }); - render() { - const ctx = this.props.ctx.subCtx({ formGroupStyle: "SrOnly", placeholderLabels: true }); - - return ( -
- p.links)} getComponent={this.renderLink} /> -
- ); - } - - renderLink = (tc: TypeContext) => { - return ( -
- cuq.label)} /> -   - cuq.link)} /> -
- ); - - } + return ( +
+ p.links)} getComponent={(tc: TypeContext) => { + return ( +
+ cuq.label)} /> +   + cuq.link)} /> +
+ ); + }} /> +
+ ); } diff --git a/Signum.React.Extensions/Dashboard/Admin/UserChartPart.tsx b/Signum.React.Extensions/Dashboard/Admin/UserChartPart.tsx index dfb6eadba1..be3cb3b843 100644 --- a/Signum.React.Extensions/Dashboard/Admin/UserChartPart.tsx +++ b/Signum.React.Extensions/Dashboard/Admin/UserChartPart.tsx @@ -3,24 +3,22 @@ import { ValueLine, EntityLine } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { UserChartPartEntity, DashboardEntity } from '../Signum.Entities.Dashboard' -export default class UserChartPart extends React.Component<{ ctx: TypeContext }> { - render() { - const ctx = this.props.ctx; +export default function UserChartPart(p : { ctx: TypeContext }){ + const ctx = p.ctx; - return ( -
- p.userChart)} create={false} onChange={() => ctx.findParentCtx(DashboardEntity).frame!.entityComponent!.forceUpdate()} /> + return ( +
+ p.userChart)} create={false} onChange={() => ctx.findParentCtx(DashboardEntity).frame!.entityComponent!.forceUpdate()} /> -
-
- p.showData)} inlineCheckbox={true} /> -
-
- p.allowChangeShowData)} inlineCheckbox={true} /> -
+
+
+ p.showData)} inlineCheckbox={true} /> +
+
+ p.allowChangeShowData)} inlineCheckbox={true} />
-
- ); - } + +
+ ); } diff --git a/Signum.React.Extensions/Dashboard/Admin/UserQueryPart.tsx b/Signum.React.Extensions/Dashboard/Admin/UserQueryPart.tsx index d94f2777d2..c8a9c9e2e3 100644 --- a/Signum.React.Extensions/Dashboard/Admin/UserQueryPart.tsx +++ b/Signum.React.Extensions/Dashboard/Admin/UserQueryPart.tsx @@ -3,16 +3,13 @@ import { ValueLine, EntityLine } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { UserQueryPartEntity, DashboardEntity } from '../Signum.Entities.Dashboard' -export default class UserQueryPart extends React.Component<{ ctx: TypeContext }> { +export default function UserQueryPart(p : { ctx: TypeContext }){ + const ctx = p.ctx; - render() { - const ctx = this.props.ctx; - - return ( -
- p.userQuery)} create={false} onChange={() => ctx.findParentCtx(DashboardEntity).frame!.entityComponent!.forceUpdate()} /> - p.renderMode)} inlineCheckbox={true} /> -
- ); - } + return ( +
+ p.userQuery)} create={false} onChange={() => ctx.findParentCtx(DashboardEntity).frame!.entityComponent!.forceUpdate()} /> + p.renderMode)} inlineCheckbox={true} /> +
+ ); } diff --git a/Signum.React.Extensions/Dashboard/Admin/ValueUserQueryListPart.tsx b/Signum.React.Extensions/Dashboard/Admin/ValueUserQueryListPart.tsx index 81d51e28e6..3f8bc65735 100644 --- a/Signum.React.Extensions/Dashboard/Admin/ValueUserQueryListPart.tsx +++ b/Signum.React.Extensions/Dashboard/Admin/ValueUserQueryListPart.tsx @@ -4,27 +4,23 @@ import { ValueLine, EntityLine, EntityRepeater } from '@framework/Lines' import { TypeContext } from '@framework/TypeContext' import { ValueUserQueryListPartEntity, ValueUserQueryElementEmbedded } from '../Signum.Entities.Dashboard' -export default class ValueUserQueryListPart extends React.Component<{ ctx: TypeContext }> { - render() { - const ctx = this.props.ctx.subCtx({ formGroupStyle: "SrOnly", placeholderLabels: true }); +export default function ValueUserQueryListPart(p : { ctx: TypeContext }){ + + const ctx = p.ctx.subCtx({ formGroupStyle: "SrOnly", placeholderLabels: true }); - return ( -
- p.userQueries)} getComponent={ctx => this.renderUserQuery(ctx as TypeContext)} /> -
- ); - } - - renderUserQuery = (tc: TypeContext) => { - return ( -
- cuq.label)} /> -   - cuq.userQuery)} formGroupHtmlAttributes={{ style: { maxWidth: "300px" } }} /> -   - cuq.href)} /> -
- ); - - } + return ( +
+ p.userQueries)} getComponent={(tc: TypeContext) => { + return ( +
+ cuq.label)} /> +   + cuq.userQuery)} formGroupHtmlAttributes={{ style: { maxWidth: "300px" } }} /> +   + cuq.href)} /> +
+ ); + }} /> +
+ ); } diff --git a/Signum.React.Extensions/Dynamic/CSS/DynamicCSSOverride.tsx b/Signum.React.Extensions/Dynamic/CSS/DynamicCSSOverride.tsx index 0419c2b0a3..29a55096bf 100644 --- a/Signum.React.Extensions/Dynamic/CSS/DynamicCSSOverride.tsx +++ b/Signum.React.Extensions/Dynamic/CSS/DynamicCSSOverride.tsx @@ -1,29 +1,28 @@ -import * as React from 'react' +import * as React from 'react' import { ValueLine, TypeContext } from '@framework/Lines' import CSSCodeMirror from '../../Codemirror/CSSCodeMirror' import { DynamicCSSOverrideEntity } from '../Signum.Entities.Dynamic' +import { useForceUpdate } from '@framework/Hooks' -export default class DynamicCSSOverrideComponent extends React.Component<{ ctx: TypeContext }> { +export default function DynamicCSSOverrideComponent(p : { ctx: TypeContext }){ + const forceUpdate = useForceUpdate(); + function handleCodeChange(newScript: string) { + const entity = p.ctx.value; + entity.script = newScript; + entity.modified = true; + forceUpdate(); + } - handleCodeChange = (newScript: string) => { - const entity = this.props.ctx.value; - entity.script = newScript; - entity.modified = true; - this.forceUpdate(); - } + var ctx = p.ctx; - render() { - var ctx = this.props.ctx; - - return ( -
- dt.name)} /> -
-
- -
-
- ); - } + return ( +
+ dt.name)} /> +
+
+ +
+
+ ); } diff --git a/Signum.React.Extensions/Dynamic/Type/DynamicMixinConnection.tsx b/Signum.React.Extensions/Dynamic/Type/DynamicMixinConnection.tsx index 52467129b0..fa0034aba8 100644 --- a/Signum.React.Extensions/Dynamic/Type/DynamicMixinConnection.tsx +++ b/Signum.React.Extensions/Dynamic/Type/DynamicMixinConnection.tsx @@ -9,27 +9,26 @@ import { ModifiableEntity, Entity, Lite, JavascriptMessage } from '@framework/Si import { getTypeInfo, Binding, PropertyRoute, symbolNiceName, getQueryNiceName } from '@framework/Reflection' import * as DynamicTypeClient from '../DynamicTypeClient' import { Typeahead } from '@framework/Components'; +import { useForceUpdate } from '@framework/Hooks' interface DynamicMixinConnectionComponentProps { ctx: TypeContext; } -export default class DynamicMixinConnectionComponent extends React.Component { +export default function DynamicMixinConnectionComponent(p : DynamicMixinConnectionComponentProps){ + const forceUpdate = useForceUpdate(); + const ctx = p.ctx; - render() { - const ctx = this.props.ctx; - - return ( -
- a.mixinName)} - labelText={ctx.niceName(a => a.mixinName)} - labelColumns={2} - onChange={() => this.forceUpdate()} /> - dt.entityType)} /> -
- ); - } + return ( +
+ a.mixinName)} + labelText={ctx.niceName(a => a.mixinName)} + labelColumns={2} + onChange={() => forceUpdate()} /> + dt.entityType)} /> +
+ ); } export interface MixinComboProps { @@ -39,9 +38,9 @@ export interface MixinComboProps { onChange?: () => void; } -export class MixinCombo extends React.Component{ - - handleGetItems = (query: string) => { +export function MixinCombo(p : MixinComboProps){ + const forceUpdate = useForceUpdate(); + function handleGetItems(query: string) { return Finder.fetchEntitiesWithFilters( DynamicTypeEntity, [ @@ -51,30 +50,29 @@ export class MixinCombo extends React.Component{ .then(lites => lites && lites.map(a => a.toStr)); } - handleOnChange = (newValue: string) => { - this.props.binding.setValue(newValue); - this.forceUpdate(); + function handleOnChange(newValue: string) { + p.binding.setValue(newValue); + forceUpdate(); - if (this.props.onChange) - this.props.onChange(); + if (p.onChange) + p.onChange(); } - render() { - let lc = this.props.labelColumns; - return ( -
- -
-
- -
+ let lc = p.labelColumns; + return ( +
+ +
+
+
-
); - } +
+
+ ); } diff --git a/Signum.React.Extensions/Dynamic/Type/DynamicSqlMigration.tsx b/Signum.React.Extensions/Dynamic/Type/DynamicSqlMigration.tsx index b709b7e5e6..4fe8aa9e71 100644 --- a/Signum.React.Extensions/Dynamic/Type/DynamicSqlMigration.tsx +++ b/Signum.React.Extensions/Dynamic/Type/DynamicSqlMigration.tsx @@ -11,43 +11,38 @@ import SqlCodeMirror from '../../Codemirror/SqlCodeMirror' interface DynamicSqlMigrationComponentProps { - ctx: TypeContext; + ctx: TypeContext; } -export default class DynamicSqlMigrationComponent extends React.Component { - - handleScriptChange = (newScript: string) => { - - const ctxValue = this.props.ctx.value; - ctxValue.script = newScript; - ctxValue.modified = true; - } - - render() { - - const ctx = this.props.ctx; - const ctx4 = ctx.subCtx({ labelColumns: { sm: 4 } }); - const executed = ctx.value.executedBy != null; - - return ( -
-
-
- sm.creationDate)} readOnly={true} /> - sm.executionDate)} readOnly={true} /> -
- -
- sm.createdBy)} readOnly={true} /> - sm.executedBy)} readOnly={true} /> -
-
- - sm.comment)} readOnly={executed} /> -
- -
-
- ); - } +export default function DynamicSqlMigrationComponent(p : DynamicSqlMigrationComponentProps){ + function handleScriptChange(newScript: string) { + const ctxValue = p.ctx.value; + ctxValue.script = newScript; + ctxValue.modified = true; + } + + const ctx = p.ctx; + const ctx4 = ctx.subCtx({ labelColumns: { sm: 4 } }); + const executed = ctx.value.executedBy != null; + + return ( +
+
+
+ sm.creationDate)} readOnly={true} /> + sm.executionDate)} readOnly={true} /> +
+ +
+ sm.createdBy)} readOnly={true} /> + sm.executedBy)} readOnly={true} /> +
+
+ + sm.comment)} readOnly={executed} /> +
+ +
+
+ ); } diff --git a/Signum.React.Extensions/Dynamic/Type/ValueComponent.tsx b/Signum.React.Extensions/Dynamic/Type/ValueComponent.tsx index 2af34a0cac..f471e01783 100644 --- a/Signum.React.Extensions/Dynamic/Type/ValueComponent.tsx +++ b/Signum.React.Extensions/Dynamic/Type/ValueComponent.tsx @@ -5,118 +5,113 @@ import { DynamicTypeDesignContext } from './DynamicTypeDefinitionComponent' export interface ValueComponentProps { - binding: Binding; - dc: DynamicTypeDesignContext; - type: "number" | "string" | "boolean" | "textArea" | null; - options?: (string | number)[]; - labelClass?: string; - defaultValue: number | string | boolean | null; - avoidDelete?: boolean; - hideLabel?: boolean; - labelColumns?: number; - autoOpacity?: boolean; - onBlur?: () => void; - onChange?: () => void; + binding: Binding; + dc: DynamicTypeDesignContext; + type: "number" | "string" | "boolean" | "textArea" | null; + options?: (string | number)[]; + labelClass?: string; + defaultValue: number | string | boolean | null; + avoidDelete?: boolean; + hideLabel?: boolean; + labelColumns?: number; + autoOpacity?: boolean; + onBlur?: () => void; + onChange?: () => void; } -export default class ValueComponent extends React.Component { +export default function ValueComponent(p : ValueComponentProps){ + function updateValue(value: string | boolean | undefined) { - updateValue(value: string | boolean | undefined) { - var p = this.props; + var parsedValue = p.type != "number" ? value : (parseFloat(value as string) || null); - var parsedValue = p.type != "number" ? value : (parseFloat(value as string) || null); + if (parsedValue === "") + parsedValue = null; - if (parsedValue === "") - parsedValue = null; + if (parsedValue == p.defaultValue && !p.avoidDelete) + p.binding.deleteValue(); + else + p.binding.setValue(parsedValue); - if (parsedValue == p.defaultValue && !p.avoidDelete) - p.binding.deleteValue(); - else - p.binding.setValue(parsedValue); + if (p.onChange) + p.onChange(); - if (p.onChange) - p.onChange(); + p.dc.refreshView(); + } - p.dc.refreshView(); - } - - handleChangeCheckbox = (e: React.ChangeEvent) => { - var sender = (e.currentTarget as HTMLInputElement); - this.updateValue(sender.checked); - } - - handleChangeSelectOrInput = (e: React.ChangeEvent) => { - var sender = (e.currentTarget as HTMLSelectElement | HTMLInputElement); - this.updateValue(sender.value); - } + function handleChangeCheckbox(e: React.ChangeEvent) { + var sender = (e.currentTarget as HTMLInputElement); + updateValue(sender.checked); + } + function handleChangeSelectOrInput(e: React.ChangeEvent) { + var sender = (e.currentTarget as HTMLSelectElement | HTMLInputElement); + updateValue(sender.value); + } - render() { - const p = this.props; - const value = p.binding.getValue(); - var opacity = p.autoOpacity && value == null ? { opacity: 0.5 } as React.CSSProperties: undefined; + function renderValue(value: number | string | boolean | null | undefined) { - if (this.props.hideLabel) { - return ( -
- {this.renderValue(value)} -
- ); - } + const val = value === undefined ? p.defaultValue : value; - const lc = this.props.labelColumns; + const style = p.hideLabel ? { display: "inline-block" } as React.CSSProperties : undefined; - return ( -
- -
- {this.renderValue(value)} -
-
- ); + if (p.options) { + return ( + ); } - - renderValue(value: number | string | boolean | null | undefined) { - - const val = value === undefined ? this.props.defaultValue : value; - - const style = this.props.hideLabel ? { display: "inline-block" } as React.CSSProperties : undefined; - - if (this.props.options) { - return ( - ); - } - else { - - if (this.props.type == "boolean") { - return ( - ); - } - - if (this.props.type == "textArea") { - return (