Skip to content
Snippets Groups Projects
Unverified Commit d96f4f4b authored by Raphael Krut-Landau's avatar Raphael Krut-Landau Committed by GitHub
Browse files

Port LastEditInfoLabel to TypeScript (#38109)

parent 6d4a2942
Branches
Tags
No related merge requests found
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { t } from "ttag";
// eslint-disable-next-line no-restricted-imports -- deprecated usage
import moment from "moment-timezone";
import { getUser } from "metabase/selectors/user";
import { getFullName } from "metabase/lib/user";
import { TextButton } from "metabase/components/Button.styled";
import Tooltip from "metabase/core/components/Tooltip";
import DateTime from "metabase/components/DateTime";
function mapStateToProps(state) {
return {
user: getUser(state),
};
}
LastEditInfoLabel.propTypes = {
item: PropTypes.shape({
"last-edit-info": PropTypes.shape({
id: PropTypes.number,
email: PropTypes.string,
first_name: PropTypes.string,
last_name: PropTypes.string,
timestamp: PropTypes.string,
}).isRequired,
}),
prefix: PropTypes.string,
user: PropTypes.shape({
id: PropTypes.number,
}).isRequired,
onClick: PropTypes.func,
className: PropTypes.string,
};
function formatEditorName(lastEditInfo) {
const name = getFullName(lastEditInfo);
return name || lastEditInfo.email;
}
function LastEditInfoLabel({
item,
user,
prefix = t`Edited`,
onClick,
className,
}) {
const lastEditInfo = item["last-edit-info"];
const { id: editorId, timestamp } = lastEditInfo;
const momentTimestamp = moment(timestamp);
const timeLabel =
timestamp && momentTimestamp.isValid() ? momentTimestamp.fromNow() : null;
const editor = editorId === user.id ? t`you` : formatEditorName(lastEditInfo);
const editorLabel = editor ? t`by ${editor}` : null;
const label =
timeLabel || editorLabel
? [timeLabel, editorLabel].filter(Boolean).join(" ")
: null;
return label ? (
<Tooltip
tooltip={timestamp ? <DateTime value={timestamp} /> : null}
isEnabled={!!timeLabel}
>
<TextButton
size="small"
className={className}
onClick={onClick}
data-testid="revision-history-button"
>
{prefix} {label}
</TextButton>
</Tooltip>
) : null;
}
export default connect(mapStateToProps)(LastEditInfoLabel);
import type { MouseEventHandler } from "react";
import { connect } from "react-redux";
import { t } from "ttag";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { getUser } from "metabase/selectors/user";
import type { NamedUser } from "metabase/lib/user";
import { getFullName } from "metabase/lib/user";
import { TextButton } from "metabase/components/Button.styled";
import type { TooltipProps } from "metabase/ui";
import { Tooltip } from "metabase/ui";
import DateTime from "metabase/components/DateTime";
import type { User } from "metabase-types/api";
dayjs.extend(relativeTime);
export type ItemWithLastEditInfo = {
"last-edit-info": Edit;
};
export type Edit = {
id?: number;
timestamp: string;
first_name?: string;
last_name?: string;
full_name?: string | null;
};
export const getHowLongAgo = (timestamp: string) => {
const date = dayjs(timestamp);
if (timestamp && date.isValid()) {
return date.fromNow();
} else {
return t`(invalid date)`;
}
};
function mapStateToProps(state: any, props: any) {
return {
...props,
user: getUser(state),
};
}
function formatEditorName(lastEditInfo: NamedUser) {
const name = getFullName(lastEditInfo);
return name || lastEditInfo.email;
}
function LastEditInfoLabel({
prefix,
item,
user,
onClick,
className,
fullName = null,
tooltipProps,
children,
}: {
prefix: string;
item: ItemWithLastEditInfo;
user: User;
onClick?: MouseEventHandler<HTMLButtonElement>;
className?: string;
fullName: string | null;
tooltipProps?: TooltipProps;
children?: React.ReactNode;
}) {
const lastEditInfo = item["last-edit-info"];
const editorId = lastEditInfo?.id;
const timestamp = lastEditInfo?.timestamp;
const timeLabel = timestamp ? getHowLongAgo(timestamp) : "";
fullName ||= formatEditorName(lastEditInfo) || null;
const editorFullName = editorId === user.id ? t`you` : fullName;
tooltipProps ??= { children: null, label: null };
tooltipProps.label ??= timestamp ? <DateTime value={timestamp} /> : null;
if (!children) {
if (prefix) {
// FIXME: The following two strings won't correctly translate.
if (editorFullName) {
children = `${prefix} ${timeLabel} by ${editorFullName}`;
} else {
children = `${prefix} ${timeLabel}`;
}
} else {
if (editorFullName) {
children = t`Edited ${timeLabel} by ${editorFullName}`;
} else {
children = t`Edited ${timeLabel}`;
}
}
}
return (
<Tooltip disabled={!timeLabel} {...tooltipProps}>
<TextButton
size="small"
className={className}
onClick={onClick}
data-testid="revision-history-button"
>
{children}
</TextButton>
</Tooltip>
);
}
// eslint-disable-next-line import/no-default-export -- deprecated usage
export default connect(mapStateToProps)(LastEditInfoLabel);
import type { User } from "metabase-types/api";
export function getFullName(user: NamedUser): string | null {
const firstName = user.first_name?.trim() || "";
const lastName = user.last_name?.trim() || "";
return [firstName, lastName].join(" ").trim() || null;
}
export function getFullName(user: User): string | null {
return [user.first_name, user.last_name].join(" ").trim() || null;
export interface NamedUser {
first_name?: string | null;
last_name?: string | null;
email?: string;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment