formSearch.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import flatMap from 'lodash/flatMap';
  2. import flatten from 'lodash/flatten';
  3. import FormSearchActions from 'sentry/actions/formSearchActions';
  4. import {Field, JsonFormObject} from 'sentry/components/forms/type';
  5. import {FormSearchField} from 'sentry/stores/formSearchStore';
  6. type Params = {
  7. fields: Record<string, Field>;
  8. formGroups: JsonFormObject[];
  9. route: string;
  10. };
  11. /**
  12. * Creates a list of objects to be injected by a search source
  13. *
  14. * @param route The route a form field belongs on
  15. * @param formGroups An array of `FormGroup: {title: String, fields: [Field]}`
  16. * @param fields An object whose key is field name and value is a `Field`
  17. */
  18. const createSearchMap = ({
  19. route,
  20. formGroups,
  21. fields,
  22. ...other
  23. }: Params): FormSearchField[] => {
  24. // There are currently two ways to define forms (TODO(billy): Turn this into one):
  25. // If `formGroups` is defined, then return a flattened list of fields in all formGroups
  26. // Otherwise `fields` is a map of fieldName -> fieldObject -- create a list of fields
  27. const listOfFields = formGroups
  28. ? flatMap(formGroups, formGroup => formGroup.fields)
  29. : Object.keys(fields).map(fieldName => fields[fieldName]);
  30. return listOfFields.map(field => ({
  31. ...other,
  32. route,
  33. title: typeof field !== 'function' ? field.label : undefined,
  34. description: typeof field !== 'function' ? field.help : undefined,
  35. field,
  36. }));
  37. };
  38. export function loadSearchMap() {
  39. // Load all form configuration files via webpack that export a named `route`
  40. // as well as either `fields` or `formGroups`
  41. // @ts-ignore This fails on cloud builder, but not in CI...
  42. const context = require.context('../data/forms', true, /\.[tj]sx?$/);
  43. // Get a list of all form fields defined in `../data/forms`
  44. const allFormFields = flatten(
  45. context
  46. .keys()
  47. .map(key => {
  48. const mod = context(key);
  49. // Since we're dynamically importing an entire directly, there could be malformed modules defined?
  50. if (!mod) {
  51. return null;
  52. }
  53. // Only look for module that have `route` exported
  54. if (!mod.route) {
  55. return null;
  56. }
  57. return createSearchMap({
  58. // `formGroups` can be a default export or a named export :<
  59. formGroups: mod.default || mod.formGroups,
  60. fields: mod.fields,
  61. route: mod.route,
  62. });
  63. })
  64. .filter(i => !!i)
  65. );
  66. FormSearchActions.loadSearchMap(allFormFields);
  67. }