Display import source data on documents (#6651)
* Display import source in Insights * Ensure sourceMetadata is not returned on public requests * Support createdByName * Prefer display source name
This commit is contained in:
@@ -96,7 +96,16 @@ const DocumentMeta: React.FC<Props> = ({
|
||||
</span>
|
||||
);
|
||||
} else if (createdAt === updatedAt) {
|
||||
content = (
|
||||
content = document.sourceMetadata ? (
|
||||
<span>
|
||||
{document.sourceMetadata.createdByName
|
||||
? t("{{ userName }} created", {
|
||||
userName: document.sourceMetadata.createdByName,
|
||||
})
|
||||
: t("Imported")}{" "}
|
||||
<Time dateTime={createdAt} addSuffix />
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
{lastUpdatedByCurrentUser
|
||||
? t("You created")
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { addDays, differenceInDays } from "date-fns";
|
||||
import i18n, { t } from "i18next";
|
||||
import capitalize from "lodash/capitalize";
|
||||
import floor from "lodash/floor";
|
||||
import { action, autorun, computed, observable, set } from "mobx";
|
||||
import { ExportContentType, NotificationEventType } from "@shared/types";
|
||||
import {
|
||||
ExportContentType,
|
||||
FileOperationFormat,
|
||||
NotificationEventType,
|
||||
} from "@shared/types";
|
||||
import type { JSONObject, NavigationNode } from "@shared/types";
|
||||
import Storage from "@shared/utils/Storage";
|
||||
import { isRTL } from "@shared/utils/rtl";
|
||||
@@ -56,6 +61,43 @@ export default class Document extends ParanoidModel {
|
||||
@observable
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The original data source of the document, if imported.
|
||||
*/
|
||||
sourceMetadata?: {
|
||||
/**
|
||||
* The type of importer that was used, if any. This can also be empty if an individual file was
|
||||
* imported through drag-and-drop, for example.
|
||||
*/
|
||||
importType?: FileOperationFormat;
|
||||
/** The date this document was imported. */
|
||||
importedAt?: string;
|
||||
/** The name of the user the created the original source document. */
|
||||
createdByName?: string;
|
||||
/** The name of the file this document was imported from. */
|
||||
fileName?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* The name of the original data source, if imported.
|
||||
*/
|
||||
get sourceName() {
|
||||
if (!this.sourceMetadata) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
switch (this.sourceMetadata.importType) {
|
||||
case FileOperationFormat.MarkdownZip:
|
||||
return "Markdown";
|
||||
case FileOperationFormat.JSON:
|
||||
return "JSON";
|
||||
case FileOperationFormat.Notion:
|
||||
return "Notion";
|
||||
default:
|
||||
return capitalize(this.sourceMetadata.importType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the collection that this document belongs to, if any.
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { useHistory, useRouteMatch } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import { s } from "@shared/styles";
|
||||
import { stringToColor } from "@shared/utils/color";
|
||||
import User from "~/models/User";
|
||||
import Avatar from "~/components/Avatar";
|
||||
import { useDocumentContext } from "~/components/DocumentContext";
|
||||
@@ -56,6 +57,20 @@ function Insights() {
|
||||
>
|
||||
<div>
|
||||
<Content column>
|
||||
{document.sourceMetadata && (
|
||||
<>
|
||||
<Heading>{t("Source")}</Heading>
|
||||
{
|
||||
<Text as="p" type="secondary" size="small">
|
||||
{t("Imported from {{ source }}", {
|
||||
source:
|
||||
document.sourceName ??
|
||||
`“${document.sourceMetadata.fileName}”`,
|
||||
})}
|
||||
</Text>
|
||||
}
|
||||
</>
|
||||
)}
|
||||
<Heading>{t("Stats")}</Heading>
|
||||
<Text as="p" type="secondary" size="small">
|
||||
<List>
|
||||
@@ -108,6 +123,26 @@ function Insights() {
|
||||
<Time dateTime={document.updatedAt} addSuffix />.
|
||||
</Text>
|
||||
<ListSpacing>
|
||||
{document.sourceMetadata?.createdByName && (
|
||||
<ListItem
|
||||
title={document.sourceMetadata?.createdByName}
|
||||
image={
|
||||
<Avatar
|
||||
model={{
|
||||
color: stringToColor(
|
||||
document.sourceMetadata.createdByName
|
||||
),
|
||||
avatarUrl: null,
|
||||
initial: document.sourceMetadata.createdByName[0],
|
||||
}}
|
||||
size={32}
|
||||
/>
|
||||
}
|
||||
subtitle={t("Creator")}
|
||||
border={false}
|
||||
small
|
||||
/>
|
||||
)}
|
||||
<PaginatedList
|
||||
aria-label={t("Contributors")}
|
||||
items={document.collaborators}
|
||||
@@ -118,7 +153,9 @@ function Insights() {
|
||||
image={<Avatar model={model} size={32} />}
|
||||
subtitle={
|
||||
model.id === document.createdBy?.id
|
||||
? t("Creator")
|
||||
? document.sourceMetadata?.createdByName
|
||||
? t("Imported")
|
||||
: t("Creator")
|
||||
: model.id === document.updatedBy?.id
|
||||
? t("Last edited")
|
||||
: t("Previously edited")
|
||||
|
||||
Reference in New Issue
Block a user