store.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. 'use client';
  2. import { atom } from "jotai";
  3. import { atomFamily, atomWithReducer } from 'jotai/utils'
  4. import * as R from 'ramda'
  5. export const flowModelRecordAtom = atom()
  6. flowModelRecordAtom.debugLabel = 'flowModelRecordAtom'
  7. // LF nodes model
  8. export const flowModelAtom = atom(get => {
  9. const record = get(flowModelRecordAtom)
  10. const { nodes, edges } = record?.content ?? {}
  11. const chainNodes = []
  12. let curNode = R.find(R.propEq('node_id_1', 'id'), nodes ?? [])
  13. if (curNode) {
  14. chainNodes.push(curNode)
  15. const cached = new Set()
  16. while (true) {
  17. const nextNode = R.find(
  18. R.propEq(
  19. R.prop(
  20. 'targetNodeId',
  21. R.find(R.propEq(curNode.id, 'sourceNodeId'), edges)
  22. ),
  23. 'id'
  24. ),
  25. nodes
  26. )
  27. if (!nextNode || nextNode.id === 'node_id_2') {
  28. break;
  29. }
  30. if (cached.has(nextNode.id)) {
  31. break;
  32. }
  33. cached.add(nextNode.id)
  34. curNode = nextNode
  35. chainNodes.push(nextNode)
  36. }
  37. }
  38. return chainNodes
  39. })
  40. flowModelAtom.debugLabel = 'flowModelAtom'
  41. // react flow nodes model
  42. export const flowModelTranslatedAtom = atom(get => {
  43. // TODO translated to react flow model
  44. return get(flowModelAtom)
  45. })
  46. flowModelTranslatedAtom.debugLabel = 'flowModelTranslatedAtom'
  47. // filtered for steps nodes model
  48. export const stepsNodesAtom = atom(get => {
  49. const nodes = get(flowModelTranslatedAtom)
  50. return R.filter(
  51. R.propSatisfies(
  52. R.includes(
  53. R.__,
  54. ['form_card', 'UserTask']
  55. ),
  56. 'type'
  57. ),
  58. nodes
  59. )
  60. })
  61. stepsNodesAtom.debugLabel = 'stepsNodesAtom'
  62. export const curStepAtom = atom(0)
  63. curStepAtom.debugLabel = 'curStepAtom'
  64. export const viewedStepAtom = atom(0)
  65. viewedStepAtom.debugLabel = 'viewedStepAtom'
  66. export const curNodeAtom = atom(get => {
  67. const stepsNodes = get(stepsNodesAtom)
  68. const curStep = get(curStepAtom)
  69. return R.prop(curStep, stepsNodes)
  70. })
  71. curNodeAtom.debugLabel = 'curNodeAtom'
  72. export const viewedNodeAtom = atom(get => {
  73. const stepsNodes = get(stepsNodesAtom)
  74. const viewedStep = get(viewedStepAtom)
  75. return R.prop(viewedStep, stepsNodes)
  76. })
  77. viewedNodeAtom.debugLabel = 'viewedNodeAtom'
  78. export const arrowStateAtom = atom(get => {
  79. const stepsNodes = get(stepsNodesAtom)
  80. const curStep = get(curStepAtom)
  81. return {
  82. prev: stepsNodes && curStep > 0,
  83. next: stepsNodes && curStep < stepsNodes?.length - 1
  84. }
  85. })
  86. arrowStateAtom.debugLabel = 'arrowStateAtom'
  87. // node render下相关的状态
  88. export const cardInstantAtomFamily = atomFamily(
  89. (node) => {
  90. const defaults = { id: node?.id, type: node?.type }
  91. switch (node?.type) {
  92. case 'form_card':
  93. defaults['fieldsDefinition'] = node?.properties?.fields
  94. break;
  95. case 'UserTask':
  96. defaults['assistantName'] = R.path(['properties', 'item', 'assistantName'], node)
  97. break;
  98. default:
  99. break;
  100. }
  101. return atom(defaults)
  102. },
  103. (a, b) => a?.id === b?.id
  104. )
  105. export const cardInstantAtomsAtom = atomWithReducer(
  106. {},
  107. (prev, action: { payload: { [K in any]?: any }, type: 'replace' | 'update' } = { payload: {}, type: 'update' }) => {
  108. switch (action.type) {
  109. case 'replace':
  110. return action.payload
  111. case 'update':
  112. return { ...prev, ...action.payload }
  113. default:
  114. return prev
  115. }
  116. }
  117. )
  118. cardInstantAtomsAtom.debugLabel = 'cardInstantAtomsAtom'
  119. // Readonly
  120. export const instantDataAtom = atom(get => {
  121. const cardInstantAtoms = get(cardInstantAtomsAtom)
  122. const cardInstant = R.map((at) => get(at), cardInstantAtoms)
  123. return cardInstant
  124. })
  125. instantDataAtom.debugLabel = 'instantDataAtom'
  126. // aside下相关的状态
  127. export const asideInstantAtomFamily = atomFamily(
  128. (node) => atom({ id: node?.id }),
  129. (a, b) => a?.id === b?.id
  130. )
  131. export const asideInstantAtomsAtom = atomWithReducer(
  132. {},
  133. (prev, action: { payload: { [K in any]?: any }, type: 'replace' | 'update' } = { payload: {}, type: 'update' }) => {
  134. switch (action.type) {
  135. case 'replace':
  136. return action.payload
  137. case 'update':
  138. return { ...prev, ...action.payload }
  139. default:
  140. return prev
  141. }
  142. }
  143. )
  144. asideInstantAtomsAtom.debugLabel = 'asideInstantAtomsAtom'