wwf
3 天以前 a430284aa21e3ae1f0d5654e55b2ad2852519cc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import React, { useEffect, useState } from 'react'
import dayjs from 'dayjs'
import { useTranslation } from 'react-i18next'
import ContextMenu from './context-menu'
import cn from '@/utils/classnames'
import type { VersionHistory } from '@/types/workflow'
import { type VersionHistoryContextMenuOptions, WorkflowVersion } from '../../types'
 
type VersionHistoryItemProps = {
  item: VersionHistory
  currentVersion: VersionHistory | null
  latestVersionId: string
  onClick: (item: VersionHistory) => void
  handleClickMenuItem: (operation: VersionHistoryContextMenuOptions) => void
  isLast: boolean
}
 
const formatVersion = (versionHistory: VersionHistory, latestVersionId: string): string => {
  const { version, id } = versionHistory
  if (version === WorkflowVersion.Draft)
    return WorkflowVersion.Draft
  if (id === latestVersionId)
    return WorkflowVersion.Latest
  try {
    const date = new Date(version)
    if (Number.isNaN(date.getTime()))
      return version
 
    // format as YYYY-MM-DD HH:mm:ss
    return date.toISOString().slice(0, 19).replace('T', ' ')
  }
  catch {
    return version
  }
}
 
const VersionHistoryItem: React.FC<VersionHistoryItemProps> = ({
  item,
  currentVersion,
  latestVersionId,
  onClick,
  handleClickMenuItem,
  isLast,
}) => {
  const { t } = useTranslation()
  const [isHovering, setIsHovering] = useState(false)
  const [open, setOpen] = useState(false)
 
  const formatTime = (time: number) => dayjs.unix(time).format('YYYY-MM-DD HH:mm')
  const formattedVersion = formatVersion(item, latestVersionId)
  const isSelected = item.version === currentVersion?.version
  const isDraft = formattedVersion === WorkflowVersion.Draft
  const isLatest = formattedVersion === WorkflowVersion.Latest
 
  useEffect(() => {
    if (isDraft)
      onClick(item)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
 
  const handleClickItem = () => {
    if (isSelected)
      return
    onClick(item)
  }
 
  return (
    <div
      className={cn(
        'group relative flex gap-x-1 rounded-lg p-2',
        isSelected ? 'cursor-not-allowed bg-state-accent-active' : 'cursor-pointer hover:bg-state-base-hover',
      )}
      onClick={handleClickItem}
      onMouseEnter={() => setIsHovering(true)}
      onMouseLeave={() => {
        setIsHovering(false)
        setOpen(false)
      }}
      onContextMenu={(e) => {
        e.preventDefault()
        setOpen(true)
      }}
    >
      {!isLast && <div className='absolute left-4 top-6 h-[calc(100%-0.75rem)] w-0.5 bg-divider-subtle' />}
      <div className=' flex h-5 w-[18px] shrink-0 items-center justify-center'>
        <div className={cn(
          'h-2 w-2 rounded-lg border-[2px]',
          isSelected ? 'border-text-accent' : 'border-text-quaternary',
        )}/>
      </div>
      <div className='flex grow flex-col gap-y-0.5 overflow-hidden'>
        <div className='mr-6 flex h-5 items-center gap-x-1'>
          <div className={cn(
            'system-sm-semibold truncate py-[1px]',
            isSelected ? 'text-text-accent' : 'text-text-secondary',
          )}>
            {isDraft ? t('workflow.versionHistory.currentDraft') : item.marked_name || t('workflow.versionHistory.defaultName')}
          </div>
          {isLatest && (
            <div className='system-2xs-medium-uppercase flex h-5 shrink-0 items-center rounded-md border border-text-accent-secondary
            bg-components-badge-bg-dimm px-[5px] text-text-accent-secondary'>
              {t('workflow.versionHistory.latest')}
            </div>
          )}
        </div>
        {
          !isDraft && (
            <div className='system-xs-regular break-words text-text-secondary'>
              {item.marked_comment || ''}
            </div>
          )
        }
        {
          !isDraft && (
            <div className='system-xs-regular truncate text-text-tertiary'>
              {`${formatTime(item.created_at)} · ${item.created_by.name}`}
            </div>
          )
        }
      </div>
      {/* Context Menu */}
      {!isDraft && isHovering && (
        <div className='absolute right-1 top-1'>
          <ContextMenu
            isShowDelete={!isLatest}
            isNamedVersion={!!item.marked_name}
            open={open}
            setOpen={setOpen}
            handleClickMenuItem={handleClickMenuItem}
          />
        </div>
      )}
    </div>
  )
}
 
export default React.memo(VersionHistoryItem)