diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json
index 89ae8d9d7d..7510ef3248 100644
--- a/services/web/frontend/extracted-translations.json
+++ b/services/web/frontend/extracted-translations.json
@@ -603,6 +603,7 @@
"large_or_high-resolution_images_taking_too_long": "",
"last_active": "",
"last_active_description": "",
+ "last_edit": "",
"last_logged_in": "",
"last_modified": "",
"last_name": "",
@@ -1022,7 +1023,6 @@
"save_or_cancel-or": "",
"save_or_cancel-save": "",
"save_x_percent_or_more": "",
- "saved_by": "",
"saving": "",
"search": "",
"search_bib_files": "",
diff --git a/services/web/frontend/js/features/history/components/change-list/label-list-item.tsx b/services/web/frontend/js/features/history/components/change-list/label-list-item.tsx
index 9c1a19a012..a6fc87ed8d 100644
--- a/services/web/frontend/js/features/history/components/change-list/label-list-item.tsx
+++ b/services/web/frontend/js/features/history/components/change-list/label-list-item.tsx
@@ -1,9 +1,7 @@
import { memo, useCallback } from 'react'
import { UpdateRange, Version } from '../../services/types/update'
import TagTooltip from './tag-tooltip'
-import { formatTime, isoToUnix } from '../../../utils/format-date'
-import { isPseudoLabel } from '../../utils/label'
-import UserNameWithColoredBadge from './user-name-with-colored-badge'
+import { formatTimeBasedOnYear, isoToUnix } from '../../../utils/format-date'
import HistoryDropdown from './dropdown/history-dropdown'
import HistoryVersionDetails from './history-version-details'
import { LoadedLabel } from '../../services/types/label'
@@ -132,29 +130,18 @@ function LabelListItem({
{labels.map(label => (
-
- {!isPseudoLabel(label) && (
-
-
- {t('saved_by')}
-
-
-
+ {label.lastUpdatedTimestamp && (
+
)}
))}
diff --git a/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx b/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx
index 5fc9ae3a0b..d15b0bed75 100644
--- a/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx
+++ b/services/web/frontend/js/features/history/components/change-list/tag-tooltip.tsx
@@ -12,9 +12,9 @@ import useAddOrRemoveLabels from '../../hooks/use-add-or-remove-labels'
import { useHistoryContext } from '../../context/history-context'
import { deleteLabel } from '../../services/api'
import { isPseudoLabel } from '../../utils/label'
-import { formatDate } from '../../../../utils/dates'
import { LoadedLabel } from '../../services/types/label'
import { debugConsole } from '@/utils/debugging'
+import { formatTimeBasedOnYear } from '@/features/utils/format-date'
type TagProps = {
label: LoadedLabel
@@ -152,7 +152,7 @@ function TagTooltip({ label, currentUserId, showTooltip }: LabelBadgesProps) {
{t('history_label_created_by')} {labelOwnerName}
-
+
}
diff --git a/services/web/frontend/js/features/history/context/history-context.tsx b/services/web/frontend/js/features/history/context/history-context.tsx
index 3d0550e47d..f392a12bf2 100644
--- a/services/web/frontend/js/features/history/context/history-context.tsx
+++ b/services/web/frontend/js/features/history/context/history-context.tsx
@@ -181,9 +181,12 @@ function useHistory() {
Promise.all([updatesPromise, labelsPromise])
.then(([{ updates: updatesData, nextBeforeTimestamp }, labels]) => {
const lastUpdateToV = updatesData.length ? updatesData[0].toV : null
+ const lastUpdatedTimestamp = updatesData.length
+ ? updatesData[0].meta.end_ts
+ : null
if (labels) {
- setLabels(loadLabels(labels, lastUpdateToV))
+ setLabels(loadLabels(labels, lastUpdateToV, lastUpdatedTimestamp))
}
const { updates, visibleUpdateCount, freeHistoryLimitHit } =
diff --git a/services/web/frontend/js/features/history/hooks/use-add-or-remove-labels.ts b/services/web/frontend/js/features/history/hooks/use-add-or-remove-labels.ts
index 465510f9fa..ccad03f2de 100644
--- a/services/web/frontend/js/features/history/hooks/use-add-or-remove-labels.ts
+++ b/services/web/frontend/js/features/history/hooks/use-add-or-remove-labels.ts
@@ -36,7 +36,11 @@ function useAddOrRemoveLabels() {
if (labels) {
const nonPseudoLabels = labels.filter(isLabel)
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)
return newLabels
diff --git a/services/web/frontend/js/features/history/services/types/label.ts b/services/web/frontend/js/features/history/services/types/label.ts
index 6d32b1375d..3f8ebc097c 100644
--- a/services/web/frontend/js/features/history/services/types/label.ts
+++ b/services/web/frontend/js/features/history/services/types/label.ts
@@ -3,6 +3,7 @@ import { Nullable } from '../../../../../../types/utils'
interface LabelBase {
id: string
created_at: string
+ lastUpdatedTimestamp: Nullable
}
interface UpdateLabel extends LabelBase {
diff --git a/services/web/frontend/js/features/history/utils/label.ts b/services/web/frontend/js/features/history/utils/label.ts
index 32948b32af..613ef3e36d 100644
--- a/services/web/frontend/js/features/history/utils/label.ts
+++ b/services/web/frontend/js/features/history/utils/label.ts
@@ -35,7 +35,8 @@ const deletePseudoCurrentStateLabelIfExistent = (labels: LoadedLabel[]) => {
const addPseudoCurrentStateLabelIfNeeded = (
labels: LoadedLabel[],
- mostRecentVersion: Nullable
+ mostRecentVersion: Nullable,
+ lastUpdatedTimestamp: Nullable
) => {
if (!labels.length || labels[0].version !== mostRecentVersion) {
const pseudoCurrentStateLabel: PseudoCurrentStateLabel = {
@@ -43,25 +44,41 @@ const addPseudoCurrentStateLabelIfNeeded = (
isPseudoCurrentStateLabel: true,
version: mostRecentVersion,
created_at: new Date().toISOString(),
+ lastUpdatedTimestamp,
}
return [pseudoCurrentStateLabel, ...labels]
}
return labels
}
+const addLastUpdatedTimestamp = (
+ labels: LoadedLabel[],
+ lastUpdatedTimestamp: Nullable
+) => {
+ return labels.map(label => ({
+ ...label,
+ lastUpdatedTimestamp,
+ }))
+}
+
export const loadLabels = (
labels: Label[],
- lastUpdateToV: Nullable
+ lastUpdateToV: Nullable,
+ lastUpdatedTimestamp: Nullable
) => {
const sortedLabels = sortLabelsByVersionAndDate(labels)
const labelsWithoutPseudoLabel =
deletePseudoCurrentStateLabelIfExistent(sortedLabels)
const labelsWithPseudoLabelIfNeeded = addPseudoCurrentStateLabelIfNeeded(
labelsWithoutPseudoLabel,
- lastUpdateToV
+ lastUpdateToV,
+ lastUpdatedTimestamp
)
-
- return labelsWithPseudoLabelIfNeeded
+ const labelsWithLastUpdatedTimestamp = addLastUpdatedTimestamp(
+ labelsWithPseudoLabelIfNeeded,
+ lastUpdatedTimestamp
+ )
+ return labelsWithLastUpdatedTimestamp
}
export const getVersionWithLabels = (labels: Nullable) => {
diff --git a/services/web/frontend/js/features/utils/format-date.js b/services/web/frontend/js/features/utils/format-date.js
index 090eae1b96..fbef24331e 100644
--- a/services/web/frontend/js/features/utils/format-date.js
+++ b/services/web/frontend/js/features/utils/format-date.js
@@ -19,6 +19,14 @@ export function relativeDate(date) {
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
* @returns {number}
diff --git a/services/web/locales/en.json b/services/web/locales/en.json
index 2ad495f5a8..7f2bef65e2 100644
--- a/services/web/locales/en.json
+++ b/services/web/locales/en.json
@@ -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 them0>.",
"last_active": "Last Active",
"last_active_description": "Last time a project was opened.",
+ "last_edit": "Last edit",
"last_logged_in": "Last logged in",
"last_modified": "Last Modified",
"last_name": "Last Name",
@@ -1547,7 +1548,6 @@
"save_or_cancel-or": "or",
"save_or_cancel-save": "Save",
"save_x_percent_or_more": "Save __percent__% or more",
- "saved_by": "Saved by",
"saving": "Saving",
"saving_20_percent": "Saving 20%!",
"saving_notification_with_seconds": "Saving __docname__... (__seconds__ seconds of unsaved changes)",