formSearch.tsx 2.4 KB

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