Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { Survey } from '../entities/index.js'
  2. import { fetchQuestions } from '../services/index.js'
  3. import {
  4. allSteps,
  5. promptOverrides,
  6. promptToComponent,
  7. inputPlaceholders,
  8. invalidInputPrompts,
  9. possible,
  10. aspectsArr,
  11. } from './lang.js'
  12. /**
  13. * Make a step from match or step information
  14. * @param {object} match
  15. * @param {object} step
  16. * @returns something like a response_key with possible responses
  17. */
  18. const formatStep = (match, step) => {
  19. const responsesByCategory = possible['usa']
  20. const responseKey = {
  21. response_key_id: match ? match.response_key_id : null,
  22. response_key_category: match ? match.response_key_category : 'profile',
  23. response_key_prompt: match ? match.response_key_prompt : step,
  24. response_key_description: match ? match.response_key_description : null,
  25. }
  26. // Embarassing hack
  27. const uglyMatch = step.split('-')
  28. if (uglyMatch.length > 1 && uglyMatch[0] == 'aspect') {
  29. responseKey.aspect = match.response_key_category
  30. responseKey.category = 'aspect'
  31. }
  32. return {
  33. ...responseKey,
  34. responses: responsesByCategory[step] ? responsesByCategory[step] : [],
  35. }
  36. }
  37. const associateWithComponent = responseKeyLike => {
  38. let component = promptToComponent[responseKeyLike.response_key_prompt]
  39. // Embarassing hack
  40. if (responseKeyLike.category == 'aspect') {
  41. component = promptToComponent[responseKeyLike.category]
  42. }
  43. return { ...responseKeyLike, component }
  44. }
  45. const hasMatch = (step, inArray) => {
  46. const uglyMatch = step.split('-')
  47. // Embarassing hack
  48. if (uglyMatch.length > 1 && uglyMatch[0] == 'aspect') {
  49. return inArray.find(q => q.response_key_id == uglyMatch[1])
  50. } else {
  51. return inArray.find(q => q.response_key_prompt == step)
  52. }
  53. }
  54. class SurveyFactory {
  55. constructor() {
  56. this.questionsFromDb = []
  57. }
  58. _setSteps(langFile) {
  59. const stepsToProcess = [...Object.values(langFile)]
  60. const seenIds = []
  61. const stepsInCommon = stepsToProcess.map(step => {
  62. // Match question to step
  63. const match = hasMatch(step, this.questionsFromDb)
  64. if (match) {
  65. seenIds.push(match.response_key_id)
  66. }
  67. // Reformat something from the db into something the gui likes
  68. const responseKeyLike = formatStep(match, step)
  69. // Lookup a matching component
  70. const withComponent = associateWithComponent(responseKeyLike)
  71. // Mutate the object with extra stuff
  72. const langStub = responseKeyLike.response_key_prompt
  73. withComponent.survey_stage = langStub
  74. if (promptOverrides[responseKeyLike.response_key_prompt]) {
  75. withComponent.response_key_prompt = promptOverrides[langStub]
  76. withComponent.placeholder = inputPlaceholders[langStub]
  77. withComponent.invalidInputPrompt = invalidInputPrompts[langStub]
  78. } else {
  79. console.warn(
  80. `WARN: ${withComponent.survey_stage} must have promptOverride`,
  81. )
  82. }
  83. return withComponent
  84. })
  85. // temporary extra condition in filter
  86. let unseen = this.questionsFromDb.filter(
  87. q =>
  88. !seenIds.includes(q.response_key_id) &&
  89. aspectsArr.includes(q.response_key_id),
  90. )
  91. return [...stepsInCommon, ...unseen]
  92. }
  93. async getQuestions() {
  94. try {
  95. this.questionsFromDb = await fetchQuestions()
  96. return this.questionsFromDb
  97. } catch (err) {
  98. console.error(err)
  99. }
  100. }
  101. async createSurvey(langFile = allSteps['usa'], roleTree) {
  102. if (!this.questionsFromDb.length) {
  103. const res = await this.getQuestions()
  104. console.warn(
  105. `Attempted to create a survey before getting questions: retrieved ${res.length} questions`,
  106. )
  107. }
  108. const steps = this._setSteps(langFile)
  109. return new Survey(steps, roleTree)
  110. }
  111. }
  112. export { SurveyFactory }