index.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import { useBoolean } from 'ahooks'
  6. import { isEqual } from 'lodash-es'
  7. import produce from 'immer'
  8. import FeaturePanel from '@/app/components/app/configuration/base/feature-panel'
  9. import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
  10. import CardItem from '@/app/components/app/configuration/dataset-config/card-item'
  11. import SelectDataSet from '@/app/components/app/configuration/dataset-config/select-dataset'
  12. import type { DataSet } from '@/models/datasets'
  13. type Props = {
  14. readonly?: boolean
  15. dataSets: DataSet[]
  16. onChange?: (data: DataSet[]) => void
  17. }
  18. const DatasetConfig: FC<Props> = ({
  19. readonly,
  20. dataSets,
  21. onChange,
  22. }) => {
  23. const { t } = useTranslation()
  24. const selectedIds = dataSets.map(item => item.id)
  25. const hasData = dataSets.length > 0
  26. const [isShowSelectDataSet, { setTrue: showSelectDataSet, setFalse: hideSelectDataSet }] = useBoolean(false)
  27. const handleSelect = (data: DataSet[]) => {
  28. if (isEqual(data.map(item => item.id), dataSets.map(item => item.id))) {
  29. hideSelectDataSet()
  30. return
  31. }
  32. if (data.find(item => !item.name)) { // has not loaded selected dataset
  33. const newSelected = produce(data, (draft) => {
  34. data.forEach((item, index) => {
  35. if (!item.name) { // not fetched database
  36. const newItem = dataSets.find(i => i.id === item.id)
  37. if (newItem)
  38. draft[index] = newItem
  39. }
  40. })
  41. })
  42. onChange?.(newSelected)
  43. }
  44. else {
  45. onChange?.(data)
  46. }
  47. hideSelectDataSet()
  48. }
  49. const onRemove = (id: string) => {
  50. onChange?.(dataSets.filter(item => item.id !== id))
  51. }
  52. return (
  53. <FeaturePanel
  54. className='mt-3'
  55. title={t('appDebug.feature.dataSet.title')}
  56. headerRight={!readonly && <OperationBtn type="add" onClick={showSelectDataSet} />}
  57. hasHeaderBottomBorder={!hasData}
  58. >
  59. {hasData
  60. ? (
  61. <div className='max-h-[220px] overflow-y-auto'>
  62. {dataSets.map(item => (
  63. <CardItem
  64. className="mb-2 !w-full"
  65. key={item.id}
  66. config={item}
  67. onRemove={onRemove}
  68. readonly={readonly}
  69. />
  70. ))}
  71. </div>
  72. )
  73. : (
  74. <div className='pt-2 pb-1 text-xs text-gray-500'>{t('appDebug.feature.dataSet.noData')}</div>
  75. )}
  76. {isShowSelectDataSet && (
  77. <SelectDataSet
  78. isShow={isShowSelectDataSet}
  79. onClose={hideSelectDataSet}
  80. selectedIds={selectedIds}
  81. onSelect={handleSelect}
  82. />
  83. )}
  84. </FeaturePanel>
  85. )
  86. }
  87. export default React.memo(DatasetConfig)