formSearch.tsx 2.3 KB

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