formPanel.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import * as React from 'react';
  2. import {Panel, PanelBody, PanelHeader} from 'app/components/panels';
  3. import {Scope} from 'app/types';
  4. import {sanitizeQuerySelector} from 'app/utils/sanitizeQuerySelector';
  5. import FieldFromConfig from 'app/views/settings/components/forms/fieldFromConfig';
  6. import {FieldObject, JsonFormObject} from './type';
  7. type DefaultProps = {
  8. additionalFieldProps: {[key: string]: any};
  9. };
  10. type Props = DefaultProps & {
  11. /**
  12. * Panel title
  13. */
  14. title?: React.ReactNode;
  15. /**
  16. * List of fields to render
  17. */
  18. fields: FieldObject[];
  19. access?: Set<Scope>;
  20. features?: Record<string, any>;
  21. /**
  22. * The name of the field that should be highlighted
  23. */
  24. highlighted?: string;
  25. /**
  26. * Renders inside of PanelBody at the start
  27. */
  28. renderHeader?: (arg: JsonFormObject) => React.ReactNode;
  29. /**
  30. * Renders inside of PanelBody before PanelBody close
  31. */
  32. renderFooter?: (arg: JsonFormObject) => React.ReactNode;
  33. /**
  34. * Disables the entire form
  35. */
  36. disabled?: boolean;
  37. };
  38. export default class FormPanel extends React.Component<Props> {
  39. static defaultProps: DefaultProps = {
  40. additionalFieldProps: {},
  41. };
  42. render() {
  43. const {
  44. title,
  45. fields,
  46. access,
  47. disabled,
  48. additionalFieldProps,
  49. renderFooter,
  50. renderHeader,
  51. ...otherProps
  52. } = this.props;
  53. return (
  54. <Panel id={typeof title === 'string' ? sanitizeQuerySelector(title) : undefined}>
  55. {title && <PanelHeader>{title}</PanelHeader>}
  56. <PanelBody>
  57. {typeof renderHeader === 'function' && renderHeader({title, fields})}
  58. {fields.map(field => {
  59. if (typeof field === 'function') {
  60. return field();
  61. }
  62. const {defaultValue: _, ...fieldWithoutDefaultValue} = field;
  63. // Allow the form panel disabled prop to override the fields
  64. // disabled prop, with fallback to the fields disabled state.
  65. if (disabled === true) {
  66. fieldWithoutDefaultValue.disabled = true;
  67. fieldWithoutDefaultValue.disabledReason = undefined;
  68. }
  69. return (
  70. <FieldFromConfig
  71. access={access}
  72. disabled={disabled}
  73. key={field.name}
  74. {...otherProps}
  75. {...additionalFieldProps}
  76. field={fieldWithoutDefaultValue}
  77. highlighted={this.props.highlighted === `#${field.name}`}
  78. />
  79. );
  80. })}
  81. {typeof renderFooter === 'function' && renderFooter({title, fields})}
  82. </PanelBody>
  83. </Panel>
  84. );
  85. }
  86. }