Tweeks to the Labels view in the project history (#16046)

* added lastUpdatedTimestamp in label list item

* formatTimeBasedOnYear

* removed unused translation

* fix typos

* translate last_edit

* use moment().subtract()

* using moment.diff

* fix formatting

GitOrigin-RevId: 16af3962eaa4c718fcd749caaff05de82a431bcc
This commit is contained in:
Domagoj Kriskovic 2023-12-04 14:15:20 +01:00 committed by Copybot
parent 8035241cc0
commit 788ebd2bce
9 changed files with 54 additions and 34 deletions

View file

@ -603,6 +603,7 @@
"large_or_high-resolution_images_taking_too_long": "", "large_or_high-resolution_images_taking_too_long": "",
"last_active": "", "last_active": "",
"last_active_description": "", "last_active_description": "",
"last_edit": "",
"last_logged_in": "", "last_logged_in": "",
"last_modified": "", "last_modified": "",
"last_name": "", "last_name": "",
@ -1022,7 +1023,6 @@
"save_or_cancel-or": "", "save_or_cancel-or": "",
"save_or_cancel-save": "", "save_or_cancel-save": "",
"save_x_percent_or_more": "", "save_x_percent_or_more": "",
"saved_by": "",
"saving": "", "saving": "",
"search": "", "search": "",
"search_bib_files": "", "search_bib_files": "",

View file

@ -1,9 +1,7 @@
import { memo, useCallback } from 'react' import { memo, useCallback } from 'react'
import { UpdateRange, Version } from '../../services/types/update' import { UpdateRange, Version } from '../../services/types/update'
import TagTooltip from './tag-tooltip' import TagTooltip from './tag-tooltip'
import { formatTime, isoToUnix } from '../../../utils/format-date' import { formatTimeBasedOnYear, isoToUnix } from '../../../utils/format-date'
import { isPseudoLabel } from '../../utils/label'
import UserNameWithColoredBadge from './user-name-with-colored-badge'
import HistoryDropdown from './dropdown/history-dropdown' import HistoryDropdown from './dropdown/history-dropdown'
import HistoryVersionDetails from './history-version-details' import HistoryVersionDetails from './history-version-details'
import { LoadedLabel } from '../../services/types/label' import { LoadedLabel } from '../../services/types/label'
@ -132,29 +130,18 @@ function LabelListItem({
{labels.map(label => ( {labels.map(label => (
<div key={label.id} className="history-version-label"> <div key={label.id} className="history-version-label">
<TagTooltip <TagTooltip
showTooltip={false} showTooltip
currentUserId={currentUserId} currentUserId={currentUserId}
label={label} label={label}
/> />
{label.lastUpdatedTimestamp && (
<time <time
className="history-version-metadata-time" className="history-version-metadata-time"
data-testid="history-version-metadata-time" data-testid="history-version-metadata-time"
> >
{formatTime(label.created_at, 'Do MMMM, h:mm a')} {t('last_edit')}{' '}
{formatTimeBasedOnYear(label.lastUpdatedTimestamp)}
</time> </time>
{!isPseudoLabel(label) && (
<div className="history-version-saved-by">
<span className="history-version-saved-by-label">
{t('saved_by')}
</span>
<UserNameWithColoredBadge
user={{
id: label.user_id,
displayName: label.user_display_name,
}}
currentUserId={currentUserId}
/>
</div>
)} )}
</div> </div>
))} ))}

View file

@ -12,9 +12,9 @@ import useAddOrRemoveLabels from '../../hooks/use-add-or-remove-labels'
import { useHistoryContext } from '../../context/history-context' import { useHistoryContext } from '../../context/history-context'
import { deleteLabel } from '../../services/api' import { deleteLabel } from '../../services/api'
import { isPseudoLabel } from '../../utils/label' import { isPseudoLabel } from '../../utils/label'
import { formatDate } from '../../../../utils/dates'
import { LoadedLabel } from '../../services/types/label' import { LoadedLabel } from '../../services/types/label'
import { debugConsole } from '@/utils/debugging' import { debugConsole } from '@/utils/debugging'
import { formatTimeBasedOnYear } from '@/features/utils/format-date'
type TagProps = { type TagProps = {
label: LoadedLabel label: LoadedLabel
@ -152,7 +152,7 @@ function TagTooltip({ label, currentUserId, showTooltip }: LabelBadgesProps) {
{t('history_label_created_by')} {labelOwnerName} {t('history_label_created_by')} {labelOwnerName}
</div> </div>
<div className="history-version-label-tooltip-row"> <div className="history-version-label-tooltip-row">
<time>{formatDate(label.created_at)}</time> <time>{formatTimeBasedOnYear(label.created_at)}</time>
</div> </div>
</div> </div>
} }

View file

@ -181,9 +181,12 @@ function useHistory() {
Promise.all([updatesPromise, labelsPromise]) Promise.all([updatesPromise, labelsPromise])
.then(([{ updates: updatesData, nextBeforeTimestamp }, labels]) => { .then(([{ updates: updatesData, nextBeforeTimestamp }, labels]) => {
const lastUpdateToV = updatesData.length ? updatesData[0].toV : null const lastUpdateToV = updatesData.length ? updatesData[0].toV : null
const lastUpdatedTimestamp = updatesData.length
? updatesData[0].meta.end_ts
: null
if (labels) { if (labels) {
setLabels(loadLabels(labels, lastUpdateToV)) setLabels(loadLabels(labels, lastUpdateToV, lastUpdatedTimestamp))
} }
const { updates, visibleUpdateCount, freeHistoryLimitHit } = const { updates, visibleUpdateCount, freeHistoryLimitHit } =

View file

@ -36,7 +36,11 @@ function useAddOrRemoveLabels() {
if (labels) { if (labels) {
const nonPseudoLabels = labels.filter(isLabel) const nonPseudoLabels = labels.filter(isLabel)
const processedNonPseudoLabels = labelsHandler(nonPseudoLabels) const processedNonPseudoLabels = labelsHandler(nonPseudoLabels)
const newLabels = loadLabels(processedNonPseudoLabels, tempUpdates[0].toV) const newLabels = loadLabels(
processedNonPseudoLabels,
tempUpdates[0].toV,
tempUpdates[0].meta.end_ts
)
setLabels(newLabels) setLabels(newLabels)
return newLabels return newLabels

View file

@ -3,6 +3,7 @@ import { Nullable } from '../../../../../../types/utils'
interface LabelBase { interface LabelBase {
id: string id: string
created_at: string created_at: string
lastUpdatedTimestamp: Nullable<number>
} }
interface UpdateLabel extends LabelBase { interface UpdateLabel extends LabelBase {

View file

@ -35,7 +35,8 @@ const deletePseudoCurrentStateLabelIfExistent = (labels: LoadedLabel[]) => {
const addPseudoCurrentStateLabelIfNeeded = ( const addPseudoCurrentStateLabelIfNeeded = (
labels: LoadedLabel[], labels: LoadedLabel[],
mostRecentVersion: Nullable<number> mostRecentVersion: Nullable<number>,
lastUpdatedTimestamp: Nullable<number>
) => { ) => {
if (!labels.length || labels[0].version !== mostRecentVersion) { if (!labels.length || labels[0].version !== mostRecentVersion) {
const pseudoCurrentStateLabel: PseudoCurrentStateLabel = { const pseudoCurrentStateLabel: PseudoCurrentStateLabel = {
@ -43,25 +44,41 @@ const addPseudoCurrentStateLabelIfNeeded = (
isPseudoCurrentStateLabel: true, isPseudoCurrentStateLabel: true,
version: mostRecentVersion, version: mostRecentVersion,
created_at: new Date().toISOString(), created_at: new Date().toISOString(),
lastUpdatedTimestamp,
} }
return [pseudoCurrentStateLabel, ...labels] return [pseudoCurrentStateLabel, ...labels]
} }
return labels return labels
} }
const addLastUpdatedTimestamp = (
labels: LoadedLabel[],
lastUpdatedTimestamp: Nullable<number>
) => {
return labels.map(label => ({
...label,
lastUpdatedTimestamp,
}))
}
export const loadLabels = ( export const loadLabels = (
labels: Label[], labels: Label[],
lastUpdateToV: Nullable<number> lastUpdateToV: Nullable<number>,
lastUpdatedTimestamp: Nullable<number>
) => { ) => {
const sortedLabels = sortLabelsByVersionAndDate(labels) const sortedLabels = sortLabelsByVersionAndDate(labels)
const labelsWithoutPseudoLabel = const labelsWithoutPseudoLabel =
deletePseudoCurrentStateLabelIfExistent(sortedLabels) deletePseudoCurrentStateLabelIfExistent(sortedLabels)
const labelsWithPseudoLabelIfNeeded = addPseudoCurrentStateLabelIfNeeded( const labelsWithPseudoLabelIfNeeded = addPseudoCurrentStateLabelIfNeeded(
labelsWithoutPseudoLabel, labelsWithoutPseudoLabel,
lastUpdateToV lastUpdateToV,
lastUpdatedTimestamp
) )
const labelsWithLastUpdatedTimestamp = addLastUpdatedTimestamp(
return labelsWithPseudoLabelIfNeeded labelsWithPseudoLabelIfNeeded,
lastUpdatedTimestamp
)
return labelsWithLastUpdatedTimestamp
} }
export const getVersionWithLabels = (labels: Nullable<LoadedLabel[]>) => { export const getVersionWithLabels = (labels: Nullable<LoadedLabel[]>) => {

View file

@ -19,6 +19,14 @@ export function relativeDate(date) {
return moment(date).calendar() return moment(date).calendar()
} }
export function formatTimeBasedOnYear(date) {
const currentDate = moment()
return currentDate.diff(date, 'years') > 0
? formatTime(date, 'D MMMM YYYY, h:mm a')
: formatTime(date, 'D MMMM, h:mm a')
}
/** /**
* @param {string} isoTimestamp * @param {string} isoTimestamp
* @returns {number} * @returns {number}

View file

@ -922,6 +922,7 @@
"large_or_high-resolution_images_taking_too_long": "Large or high-resolution images taking too long to process. You may be able to <0>optimize them</0>.", "large_or_high-resolution_images_taking_too_long": "Large or high-resolution images taking too long to process. You may be able to <0>optimize them</0>.",
"last_active": "Last Active", "last_active": "Last Active",
"last_active_description": "Last time a project was opened.", "last_active_description": "Last time a project was opened.",
"last_edit": "Last edit",
"last_logged_in": "Last logged in", "last_logged_in": "Last logged in",
"last_modified": "Last Modified", "last_modified": "Last Modified",
"last_name": "Last Name", "last_name": "Last Name",
@ -1547,7 +1548,6 @@
"save_or_cancel-or": "or", "save_or_cancel-or": "or",
"save_or_cancel-save": "Save", "save_or_cancel-save": "Save",
"save_x_percent_or_more": "Save __percent__% or more", "save_x_percent_or_more": "Save __percent__% or more",
"saved_by": "Saved by",
"saving": "Saving", "saving": "Saving",
"saving_20_percent": "Saving 20%!", "saving_20_percent": "Saving 20%!",
"saving_notification_with_seconds": "Saving __docname__... (__seconds__ seconds of unsaved changes)", "saving_notification_with_seconds": "Saving __docname__... (__seconds__ seconds of unsaved changes)",