@ynput/ayon-frontend-shared 0.2.11 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index.cjs10.js +5 -3
- package/dist/_virtual/index.cjs10.js.map +1 -1
- package/dist/_virtual/index.cjs4.js +4 -4
- package/dist/_virtual/index.cjs5.js +4 -4
- package/dist/_virtual/index.cjs6.js +2 -2
- package/dist/_virtual/index.cjs7.js +3 -5
- package/dist/_virtual/index.cjs7.js.map +1 -1
- package/dist/_virtual/index.es10.js +5 -2
- package/dist/_virtual/index.es10.js.map +1 -1
- package/dist/_virtual/index.es4.js +4 -4
- package/dist/_virtual/index.es5.js +4 -4
- package/dist/_virtual/index.es6.js +2 -2
- package/dist/_virtual/index.es7.js +2 -5
- package/dist/_virtual/index.es7.js.map +1 -1
- package/dist/node_modules/match-sorter/dist/match-sorter.esm.cjs.js +1 -1
- package/dist/node_modules/match-sorter/dist/match-sorter.esm.es.js +1 -1
- package/dist/node_modules/parse-numeric-range/index.cjs.js +1 -1
- package/dist/node_modules/parse-numeric-range/index.es.js +1 -1
- package/dist/node_modules/rehype-parse/lib/index.cjs.js +1 -1
- package/dist/node_modules/rehype-parse/lib/index.es.js +1 -1
- package/dist/node_modules/rehype-prism-plus/dist/index.es.cjs.js +1 -1
- package/dist/node_modules/rehype-prism-plus/dist/index.es.es.js +1 -1
- package/dist/node_modules/remove-accents/index.cjs.js +1 -1
- package/dist/node_modules/remove-accents/index.es.js +1 -1
- package/dist/shared/src/containers/Feed/Feed.cjs.js +9 -4
- package/dist/shared/src/containers/Feed/Feed.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/Feed.es.js +9 -4
- package/dist/shared/src/containers/Feed/Feed.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js +2 -1
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js +2 -1
- package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js.map +1 -1
- package/dist/types/containers/Feed/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const _commonjsHelpers = require("./_commonjsHelpers.cjs.js");
|
|
3
|
+
const index = require("../node_modules/parse5/lib/parser/index.cjs.js");
|
|
4
|
+
var parserExports = index.__require();
|
|
5
|
+
const Parser5 = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(parserExports);
|
|
6
|
+
module.exports = Parser5;
|
|
5
7
|
//# sourceMappingURL=index.cjs10.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs10.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs10.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const _commonjsHelpers = require("./_commonjsHelpers.cjs.js");
|
|
3
|
-
const index = require("../node_modules/
|
|
4
|
-
var
|
|
5
|
-
const
|
|
6
|
-
module.exports =
|
|
3
|
+
const index = require("../node_modules/remove-accents/index.cjs.js");
|
|
4
|
+
var removeAccentsExports = index.__require();
|
|
5
|
+
const removeAccents = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(removeAccentsExports);
|
|
6
|
+
module.exports = removeAccents;
|
|
7
7
|
//# sourceMappingURL=index.cjs4.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const _commonjsHelpers = require("./_commonjsHelpers.cjs.js");
|
|
3
|
-
const index = require("../node_modules/
|
|
4
|
-
var
|
|
5
|
-
const
|
|
6
|
-
module.exports =
|
|
3
|
+
const index = require("../node_modules/parse-numeric-range/index.cjs.js");
|
|
4
|
+
var parseNumericRangeExports = index.__require();
|
|
5
|
+
const n = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(parseNumericRangeExports);
|
|
6
|
+
module.exports = n;
|
|
7
7
|
//# sourceMappingURL=index.cjs5.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
var
|
|
4
|
-
exports.__module =
|
|
3
|
+
var removeAccents = { exports: {} };
|
|
4
|
+
exports.__module = removeAccents;
|
|
5
5
|
//# sourceMappingURL=index.cjs6.js.map
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const Parser5 = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(parserExports);
|
|
6
|
-
module.exports = Parser5;
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
var parseNumericRange = { exports: {} };
|
|
4
|
+
exports.__module = parseNumericRange;
|
|
7
5
|
//# sourceMappingURL=index.cjs7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs7.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { getDefaultExportFromCjs } from "./_commonjsHelpers.es.js";
|
|
2
|
+
import { __require as requireParser } from "../node_modules/parse5/lib/parser/index.es.js";
|
|
3
|
+
var parserExports = requireParser();
|
|
4
|
+
const Parser5 = /* @__PURE__ */ getDefaultExportFromCjs(parserExports);
|
|
2
5
|
export {
|
|
3
|
-
|
|
6
|
+
Parser5 as default
|
|
4
7
|
};
|
|
5
8
|
//# sourceMappingURL=index.es10.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es10.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es10.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getDefaultExportFromCjs } from "./_commonjsHelpers.es.js";
|
|
2
|
-
import { __require as
|
|
3
|
-
var
|
|
4
|
-
const
|
|
2
|
+
import { __require as requireRemoveAccents } from "../node_modules/remove-accents/index.es.js";
|
|
3
|
+
var removeAccentsExports = requireRemoveAccents();
|
|
4
|
+
const removeAccents = /* @__PURE__ */ getDefaultExportFromCjs(removeAccentsExports);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
removeAccents as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=index.es4.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getDefaultExportFromCjs } from "./_commonjsHelpers.es.js";
|
|
2
|
-
import { __require as
|
|
3
|
-
var
|
|
4
|
-
const
|
|
2
|
+
import { __require as requireParseNumericRange } from "../node_modules/parse-numeric-range/index.es.js";
|
|
3
|
+
var parseNumericRangeExports = requireParseNumericRange();
|
|
4
|
+
const n = /* @__PURE__ */ getDefaultExportFromCjs(parseNumericRangeExports);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
n as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=index.es5.js.map
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import { __require as requireParser } from "../node_modules/parse5/lib/parser/index.es.js";
|
|
3
|
-
var parserExports = requireParser();
|
|
4
|
-
const Parser5 = /* @__PURE__ */ getDefaultExportFromCjs(parserExports);
|
|
1
|
+
var parseNumericRange = { exports: {} };
|
|
5
2
|
export {
|
|
6
|
-
|
|
3
|
+
parseNumericRange as __module
|
|
7
4
|
};
|
|
8
5
|
//# sourceMappingURL=index.es7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es7.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const index = require("../../_virtual/index.
|
|
3
|
+
const index = require("../../_virtual/index.cjs7.js");
|
|
4
4
|
var hasRequiredParseNumericRange;
|
|
5
5
|
function requireParseNumericRange() {
|
|
6
6
|
if (hasRequiredParseNumericRange) return index.__module.exports;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as parseNumericRange } from "../../_virtual/index.
|
|
1
|
+
import { __module as parseNumericRange } from "../../_virtual/index.es7.js";
|
|
2
2
|
var hasRequiredParseNumericRange;
|
|
3
3
|
function requireParseNumericRange() {
|
|
4
4
|
if (hasRequiredParseNumericRange) return parseNumericRange.exports;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const index = require("../../../_virtual/index.
|
|
2
|
+
const index = require("../../../_virtual/index.cjs10.js");
|
|
3
3
|
const errors = require("./errors.cjs.js");
|
|
4
4
|
const index$1 = require("../../hast-util-from-parse5/lib/index.cjs.js");
|
|
5
5
|
const base = "https://html.spec.whatwg.org/multipage/parsing.html#parse-error-";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Parser5 from "../../../_virtual/index.
|
|
1
|
+
import Parser5 from "../../../_virtual/index.es10.js";
|
|
2
2
|
import { errors } from "./errors.es.js";
|
|
3
3
|
import { fromParse5 } from "../../hast-util-from-parse5/lib/index.es.js";
|
|
4
4
|
const base = "https://html.spec.whatwg.org/multipage/parsing.html#parse-error-";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
3
|
const index$1 = require("../../hast-util-to-string/index.cjs.js");
|
|
4
|
-
const index$2 = require("../../../_virtual/index.
|
|
4
|
+
const index$2 = require("../../../_virtual/index.cjs5.js");
|
|
5
5
|
require("../../refractor/lib/common.cjs.js");
|
|
6
6
|
require("../../refractor/lib/all.cjs.js");
|
|
7
7
|
const index = require("../node_modules/unist-util-visit/lib/index.cjs.js");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toString } from "../../hast-util-to-string/index.es.js";
|
|
2
|
-
import n from "../../../_virtual/index.
|
|
2
|
+
import n from "../../../_virtual/index.es5.js";
|
|
3
3
|
import "../../refractor/lib/common.es.js";
|
|
4
4
|
import "../../refractor/lib/all.es.js";
|
|
5
5
|
import { visit } from "../node_modules/unist-util-visit/lib/index.es.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const index = require("../../_virtual/index.
|
|
3
|
+
const index = require("../../_virtual/index.cjs6.js");
|
|
4
4
|
var hasRequiredRemoveAccents;
|
|
5
5
|
function requireRemoveAccents() {
|
|
6
6
|
if (hasRequiredRemoveAccents) return index.__module.exports;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as removeAccents } from "../../_virtual/index.
|
|
1
|
+
import { __module as removeAccents } from "../../_virtual/index.es6.js";
|
|
2
2
|
var hasRequiredRemoveAccents;
|
|
3
3
|
function requireRemoveAccents() {
|
|
4
4
|
if (hasRequiredRemoveAccents) return removeAccents.exports;
|
|
@@ -62,10 +62,15 @@ const Feed = ({ isMultiProjects, readOnly, statuses = [] }) => {
|
|
|
62
62
|
if (!activitiesWithMergedAnnotations.length) {
|
|
63
63
|
setFeedAnnotations([]);
|
|
64
64
|
}
|
|
65
|
-
const annotations = activitiesWithMergedAnnotations.map(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
const annotations = activitiesWithMergedAnnotations.map(
|
|
66
|
+
(activity) => {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
return (_b = (_a = activity.activityData) == null ? void 0 : _a.annotations) == null ? void 0 : _b.map((a) => ({
|
|
69
|
+
...a,
|
|
70
|
+
activityId: activity.activityId
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
).filter(Boolean).flat();
|
|
69
74
|
setFeedAnnotations(annotations);
|
|
70
75
|
}, [activitiesWithMergedAnnotations]);
|
|
71
76
|
const transformedActivitiesData = useTransformActivities.default(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Feed.cjs.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport mergeAnnotationAttachments from './helpers/mergeAnnotationAttachments'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const {\n openSlideOut,\n highlightedActivities,\n setHighlightedActivities,\n onOpenImage,\n setFeedAnnotations,\n } = useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n const activitiesWithMergedAnnotations = useMemo(\n () => mergeAnnotationAttachments(activitiesData),\n [activitiesData],\n )\n\n useEffect(() => {\n if (!activitiesWithMergedAnnotations.length) {\n setFeedAnnotations([])\n }\n\n const annotations = activitiesWithMergedAnnotations\n .map((activity) => activity.activityData?.annotations)\n .filter(Boolean)\n .flat()\n\n setFeedAnnotations(annotations)\n }, [activitiesWithMergedAnnotations])\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesWithMergedAnnotations,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["useFeedContext","useDetailsPanelContext","useMemo","useEffect","useTransformActivities","useRef","FEED_NEW_COMMENT","index","entityType","isFilePreviewable","getLoadingPlaceholders","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Icon","Styled.FeedContent","EmptyPlaceholder","InView","Styled.LoadMore","CommentInput"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Feed.cjs.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport mergeAnnotationAttachments from './helpers/mergeAnnotationAttachments'\nimport { SavedAnnotationMetadata } from '.'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const {\n openSlideOut,\n highlightedActivities,\n setHighlightedActivities,\n onOpenImage,\n setFeedAnnotations,\n } = useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n const activitiesWithMergedAnnotations = useMemo(\n () => mergeAnnotationAttachments(activitiesData),\n [activitiesData],\n )\n\n useEffect(() => {\n if (!activitiesWithMergedAnnotations.length) {\n setFeedAnnotations([])\n }\n\n const annotations = activitiesWithMergedAnnotations\n .map((activity) =>\n activity.activityData?.annotations?.map((a: SavedAnnotationMetadata) => ({\n ...a,\n activityId: activity.activityId,\n })),\n )\n .filter(Boolean)\n .flat()\n\n setFeedAnnotations(annotations)\n }, [activitiesWithMergedAnnotations])\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesWithMergedAnnotations,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["useFeedContext","useDetailsPanelContext","useMemo","useEffect","useTransformActivities","useRef","FEED_NEW_COMMENT","index","entityType","isFilePreviewable","getLoadingPlaceholders","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Icon","Styled.FeedContent","EmptyPlaceholder","InView","Styled.LoadMore","CommentInput"],"mappings":"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"}
|
|
@@ -60,10 +60,15 @@ const Feed = ({ isMultiProjects, readOnly, statuses = [] }) => {
|
|
|
60
60
|
if (!activitiesWithMergedAnnotations.length) {
|
|
61
61
|
setFeedAnnotations([]);
|
|
62
62
|
}
|
|
63
|
-
const annotations = activitiesWithMergedAnnotations.map(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
const annotations = activitiesWithMergedAnnotations.map(
|
|
64
|
+
(activity) => {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
return (_b = (_a = activity.activityData) == null ? void 0 : _a.annotations) == null ? void 0 : _b.map((a) => ({
|
|
67
|
+
...a,
|
|
68
|
+
activityId: activity.activityId
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
).filter(Boolean).flat();
|
|
67
72
|
setFeedAnnotations(annotations);
|
|
68
73
|
}, [activitiesWithMergedAnnotations]);
|
|
69
74
|
const transformedActivitiesData = useTransformActivities(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Feed.es.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport mergeAnnotationAttachments from './helpers/mergeAnnotationAttachments'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const {\n openSlideOut,\n highlightedActivities,\n setHighlightedActivities,\n onOpenImage,\n setFeedAnnotations,\n } = useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n const activitiesWithMergedAnnotations = useMemo(\n () => mergeAnnotationAttachments(activitiesData),\n [activitiesData],\n )\n\n useEffect(() => {\n if (!activitiesWithMergedAnnotations.length) {\n setFeedAnnotations([])\n }\n\n const annotations = activitiesWithMergedAnnotations\n .map((activity) => activity.activityData?.annotations)\n .filter(Boolean)\n .flat()\n\n setFeedAnnotations(annotations)\n }, [activitiesWithMergedAnnotations])\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesWithMergedAnnotations,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["index","entityType","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Styled.FeedContent","Styled.LoadMore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Feed.es.js","sources":["../../../../../src/containers/Feed/Feed.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react'\nimport ActivityItem from './components/ActivityItem'\nimport CommentInput from './components/CommentInput/CommentInput'\nimport * as Styled from './Feed.styled'\nimport useCommentMutations, { Activity } from './hooks/useCommentMutations'\nimport useTransformActivities from './hooks/useTransformActivities'\nimport { InView } from 'react-intersection-observer'\nimport useSaveScrollPos from './hooks/useSaveScrollPos'\nimport useScrollOnInputOpen from './hooks/useScrollOnInputOpen'\nimport { getLoadingPlaceholders } from './feedHelpers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport clsx from 'clsx'\nimport useScrollToHighlighted from './hooks/useScrollToHighlighted'\nimport { isFilePreviewable } from './components/FileUploadPreview/FileUploadPreview'\nimport EmptyPlaceholder from '@shared/components/EmptyPlaceholder'\nimport { useFeedContext, FEED_NEW_COMMENT } from './context/FeedContext'\nimport { Status } from '../ProjectTreeTable/types/project'\nimport { useDetailsPanelContext } from '@shared/context'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport mergeAnnotationAttachments from './helpers/mergeAnnotationAttachments'\nimport { SavedAnnotationMetadata } from '.'\n\n// number of activities to get\nexport const activitiesLast = 30\n\nexport type FeedProps = {\n isMultiProjects: boolean\n readOnly: boolean\n statuses: Status[]\n}\n\nexport const Feed = ({ isMultiProjects, readOnly, statuses = [] }: FeedProps) => {\n const {\n projectName,\n entities,\n entityType,\n editingId,\n projectInfo,\n setEditingId,\n userName,\n activitiesData,\n isLoadingNew,\n isLoadingNextPage,\n loadNextPage,\n hasNextPage,\n users,\n currentTab,\n } = useFeedContext()\n\n const {\n openSlideOut,\n highlightedActivities,\n setHighlightedActivities,\n onOpenImage,\n setFeedAnnotations,\n } = useDetailsPanelContext()\n\n // hide comment input for specific filters\n const hideCommentInput = ['versions'].includes(currentTab)\n\n const activitiesWithMergedAnnotations = useMemo(\n () => mergeAnnotationAttachments(activitiesData),\n [activitiesData],\n )\n\n useEffect(() => {\n if (!activitiesWithMergedAnnotations.length) {\n setFeedAnnotations([])\n }\n\n const annotations = activitiesWithMergedAnnotations\n .map((activity) =>\n activity.activityData?.annotations?.map((a: SavedAnnotationMetadata) => ({\n ...a,\n activityId: activity.activityId,\n })),\n )\n .filter(Boolean)\n .flat()\n\n setFeedAnnotations(annotations)\n }, [activitiesWithMergedAnnotations])\n\n // do any transformation on activities data\n // 1. status change activities, attach status data based on projectName\n // 2. reverse the order\n // 3. is this activity from the current user?\n const transformedActivitiesData = useTransformActivities(\n // @ts-ignore\n activitiesWithMergedAnnotations,\n users,\n projectInfo,\n entityType,\n userName,\n ) as any[]\n\n // REFS\n const feedRef = useRef(null)\n // const commentInputRef = useRef(null)\n\n // scroll by height of comment input when it opens or closes\n useScrollOnInputOpen({ feedRef, isInputOpen: editingId === FEED_NEW_COMMENT, height: 93 })\n\n // save scroll position of a feed\n useSaveScrollPos({\n entities,\n feedRef,\n filter: currentTab,\n disabled: !!highlightedActivities.length,\n isLoading: isLoadingNew,\n })\n\n // try and scroll to highlightedActivities activity\n useScrollToHighlighted({\n feedRef,\n highlighted: highlightedActivities,\n isLoading: isLoadingNew,\n loadNextPage,\n hasNextPage: !!loadNextPage,\n })\n\n // comment mutations here!\n const { submitComment, updateComment, deleteComment, isSaving } = useCommentMutations({\n projectName,\n entityType: entityType,\n entities,\n filter: currentTab,\n })\n\n // When a checkbox is clicked, update the body to add/remove \"x\" in [ ] markdown\n // Then update comment with new body\n const handleCommentChecked = (e: React.ChangeEvent<HTMLInputElement>, activity: Activity) => {\n const target = e?.target\n if (!target || !activity) return console.log('no target or activity')\n\n // the value that it's changing to\n const checked: boolean = target.checked\n const currentMarkdown: string = checked ? '[ ]' : '[x]'\n const newMarkdown: string = checked ? '[x]' : '[ ]'\n\n const { body } = activity\n\n // based on all li elements in the whole className 'comment-body' with className 'task-list-item'\n // find the index of the task that was checked\n const taskIndex: number = Array.from(\n target.closest('.comment-body')?.querySelectorAll('.task-list-item') || [],\n ).findIndex((li: Element) => li === target.closest('li'))\n\n let replaceIndex: number = taskIndex\n\n // count the number of current markdowns in the body\n const allMarkdowns: string[] = body.match(/\\[.\\]/g) || []\n\n allMarkdowns.forEach((markdown: string, index: number) => {\n // does it match the current markdown?\n if (markdown !== currentMarkdown && index < taskIndex) replaceIndex--\n })\n\n // now find the indexes of the current markdown to replace\n const indexesOfCurrentMarkdownInBody: number[] = []\n let index: number = -1\n while ((index = body.indexOf(currentMarkdown, index + 1)) > -1) {\n indexesOfCurrentMarkdownInBody.push(index)\n }\n\n const indexToReplaceInBody: number | undefined = indexesOfCurrentMarkdownInBody[replaceIndex]\n if (indexToReplaceInBody === undefined) return\n\n const endReplaceIndex: number = indexToReplaceInBody + currentMarkdown.length\n\n // replace the current markdown with the new markdown\n const newBody: string =\n body.slice(0, indexToReplaceInBody) + newMarkdown + body.slice(endReplaceIndex)\n\n if (!newBody) return\n\n updateComment(activity, newBody, activity.files)\n }\n\n const handleRefClick = (ref: {\n entityId: string\n entityType: DetailsPanelEntityType\n activityId: string\n }) => {\n const { entityId, entityType, activityId } = ref\n const supportedTypes = ['version', 'task', 'folder']\n\n if (!entityType || !supportedTypes.includes(entityType))\n return console.log('Entity type not supported yet')\n\n if (!entityId || !entityType || !projectName) return console.log('No entity id or type found')\n\n // open the slide out\n openSlideOut({ entityId, entityType, projectName })\n // set highlighted activity\n setHighlightedActivities([activityId])\n }\n\n const handleFileExpand = ({ index, activityId }: { index: number; activityId: string }) => {\n const previewableFiles = Object.values(transformedActivitiesData)\n .reverse()\n .filter((a) => a.activityType == 'comment')\n .map((a) => ({\n id: a.activityId,\n files: a.files.filter((file: any) => isFilePreviewable(file.mime, file.ext)),\n }))\n .filter((a) => a.files.length > 0)\n\n // open image callback\n onOpenImage?.({ files: previewableFiles, activityId, index, projectName })\n }\n\n const loadingPlaceholders = useMemo(() => getLoadingPlaceholders(10), [])\n\n let warningMessage\n\n // only viewing activities from one project\n if (isMultiProjects)\n warningMessage = `You are only viewing activities from one project: ${projectName}.`\n\n return (\n <>\n <Styled.FeedContainer className=\"feed\">\n {warningMessage && (\n <Styled.Warning>\n <Icon icon=\"info\" />\n {warningMessage}\n </Styled.Warning>\n )}\n <Styled.FeedContent ref={feedRef} className={clsx({ loading: isLoadingNew }, 'no-shimmer')}>\n {isLoadingNew\n ? loadingPlaceholders\n : transformedActivitiesData.map((activity) => (\n <ActivityItem\n key={activity.activityId}\n activity={activity}\n onCheckChange={handleCommentChecked}\n onDelete={deleteComment}\n onUpdate={async (value, files, _refs) =>\n await updateComment(activity, value, files)\n }\n projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={handleRefClick}\n createdAts={entities.map((e) => e.createdAt)}\n onFileExpand={handleFileExpand}\n showOrigin={entities.length > 1}\n filter={currentTab}\n editProps={{\n projectName,\n entities: entities,\n entityType,\n }}\n isHighlighted={highlightedActivities.includes(activity.activityId)}\n readOnly={readOnly}\n statuses={statuses}\n />\n ))}\n {/* message when no versions published */}\n {transformedActivitiesData.length === 1 && currentTab === 'versions' && !isLoadingNew && (\n <EmptyPlaceholder message=\"No versions published yet\" icon=\"layers\" />\n )}\n {hasNextPage && loadNextPage && (\n <InView\n root={feedRef.current}\n onChange={(inView) => inView && loadNextPage()}\n rootMargin={'400px 0px 0px 0px'}\n >\n <Styled.LoadMore style={{ height: 0 }} onClick={() => loadNextPage()}>\n {isLoadingNextPage ? 'Loading more...' : 'Click to load more'}\n </Styled.LoadMore>\n </InView>\n )}\n </Styled.FeedContent>\n {!hideCommentInput && (\n <CommentInput\n initValue={null}\n onSubmit={submitComment}\n isOpen={editingId === FEED_NEW_COMMENT}\n onClose={() => setEditingId(null)}\n onOpen={() => setEditingId(FEED_NEW_COMMENT)}\n disabled={isMultiProjects}\n isLoading={isLoadingNew || !entities.length || isSaving}\n />\n )}\n </Styled.FeedContainer>\n </>\n )\n}\n"],"names":["index","entityType","jsxs","Styled.FeedContainer","Styled.Warning","jsx","Styled.FeedContent","Styled.LoadMore"],"mappings":"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"}
|
|
@@ -65,7 +65,7 @@ const ActivityComment = ({
|
|
|
65
65
|
if (!authorName) authorName = (author == null ? void 0 : author.name) || "";
|
|
66
66
|
if (!authorFullName) authorFullName = (author == null ? void 0 : author.fullName) || authorName;
|
|
67
67
|
const { editingId, setEditingId } = FeedContext.useFeedContext();
|
|
68
|
-
const { onGoToFrame } = DetailsPanelContext.useDetailsPanelContext();
|
|
68
|
+
const { onGoToFrame, setHighlightedActivities } = DetailsPanelContext.useDetailsPanelContext();
|
|
69
69
|
const handleEditComment = () => {
|
|
70
70
|
setEditingId(activityId);
|
|
71
71
|
};
|
|
@@ -124,6 +124,7 @@ const ActivityComment = ({
|
|
|
124
124
|
(file) => {
|
|
125
125
|
if (!file.annotation) return;
|
|
126
126
|
onGoToFrame == null ? void 0 : onGoToFrame(file.annotation.range[0] - 1);
|
|
127
|
+
setHighlightedActivities([activityId]);
|
|
127
128
|
},
|
|
128
129
|
[onGoToFrame]
|
|
129
130
|
);
|
package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActivityComment.cjs.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useCallback, useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\nimport { SavedAnnotationMetadata } from '../../index'\nimport { useDetailsPanelContext } from '@shared/context'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n const { onGoToFrame } = useDetailsPanelContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n const onAnnotationClick = useCallback(\n (file: any) => {\n if (!file.annotation) return\n // annotation frame numbers are 1-based\n onGoToFrame?.((file.annotation as SavedAnnotationMetadata).range[0] - 1)\n },\n [onGoToFrame],\n )\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onAnnotationClick={onAnnotationClick}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["useFeedContext","useDetailsPanelContext","files","getTextRefs","confirmDelete","useMemo","mapGraphQLReactions","useCallback","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","CommentInput","aTag","inputTag","codeTag","blockquoteTag","Styled.Tip","Icon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActivityComment.cjs.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useCallback, useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\nimport { SavedAnnotationMetadata } from '../../index'\nimport { useDetailsPanelContext } from '@shared/context'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n const { onGoToFrame, setHighlightedActivities } = useDetailsPanelContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n const onAnnotationClick = useCallback(\n (file: any) => {\n if (!file.annotation) return\n // annotation frame numbers are 1-based\n onGoToFrame?.((file.annotation as SavedAnnotationMetadata).range[0] - 1)\n setHighlightedActivities([activityId])\n },\n [onGoToFrame],\n )\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onAnnotationClick={onAnnotationClick}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["useFeedContext","useDetailsPanelContext","files","getTextRefs","confirmDelete","useMemo","mapGraphQLReactions","useCallback","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","CommentInput","aTag","inputTag","codeTag","blockquoteTag","Styled.Tip","Icon"],"mappings":"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"}
|
|
@@ -64,7 +64,7 @@ const ActivityComment = ({
|
|
|
64
64
|
if (!authorName) authorName = (author == null ? void 0 : author.name) || "";
|
|
65
65
|
if (!authorFullName) authorFullName = (author == null ? void 0 : author.fullName) || authorName;
|
|
66
66
|
const { editingId, setEditingId } = useFeedContext();
|
|
67
|
-
const { onGoToFrame } = useDetailsPanelContext();
|
|
67
|
+
const { onGoToFrame, setHighlightedActivities } = useDetailsPanelContext();
|
|
68
68
|
const handleEditComment = () => {
|
|
69
69
|
setEditingId(activityId);
|
|
70
70
|
};
|
|
@@ -123,6 +123,7 @@ const ActivityComment = ({
|
|
|
123
123
|
(file) => {
|
|
124
124
|
if (!file.annotation) return;
|
|
125
125
|
onGoToFrame == null ? void 0 : onGoToFrame(file.annotation.range[0] - 1);
|
|
126
|
+
setHighlightedActivities([activityId]);
|
|
126
127
|
},
|
|
127
128
|
[onGoToFrame]
|
|
128
129
|
);
|
package/dist/shared/src/containers/Feed/components/ActivityComment/ActivityComment.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActivityComment.es.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useCallback, useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\nimport { SavedAnnotationMetadata } from '../../index'\nimport { useDetailsPanelContext } from '@shared/context'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n const { onGoToFrame } = useDetailsPanelContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n const onAnnotationClick = useCallback(\n (file: any) => {\n if (!file.annotation) return\n // annotation frame numbers are 1-based\n onGoToFrame?.((file.annotation as SavedAnnotationMetadata).range[0] - 1)\n },\n [onGoToFrame],\n )\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onAnnotationClick={onAnnotationClick}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["files","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","Styled.Tip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActivityComment.es.js","sources":["../../../../../../../src/containers/Feed/components/ActivityComment/ActivityComment.tsx"],"sourcesContent":["import clsx from 'clsx'\nimport { useCallback, useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport emoji from 'remark-emoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkDirective from 'remark-directive'\nimport remarkDirectiveRehype from 'remark-directive-rehype'\n\nimport CommentInput from '../CommentInput/CommentInput'\nimport Reactions from '../ReactionContainer/Reactions'\nimport { Reaction } from '../ReactionContainer/types'\nimport useReferenceTooltip from '../../hooks/useReferenceTooltip'\nimport FilesGrid, { FilesGridProps } from '../FilesGrid/FilesGrid'\n\nimport { getTextRefs } from '../CommentInput/quillToMarkdown'\nimport * as Styled from './ActivityComment.styled'\nimport CommentWrapper from './CommentWrapper'\nimport { aTag, blockquoteTag, codeTag, inputTag } from './ActivityMarkdownComponents'\nimport { mapGraphQLReactions } from './mappers'\nimport { Icon } from '@ynput/ayon-react-components'\nimport ActivityStatus from '../ActivityStatus/ActivityStatus'\nimport { useFeedContext } from '../../context/FeedContext'\nimport { confirmDelete } from '../../../../util'\nimport ActivityHeader, { ActivityHeaderProps } from '../ActivityHeader/ActivityHeader'\nimport type { Status } from '../../../ProjectTreeTable/types/project'\nimport { SavedAnnotationMetadata } from '../../index'\nimport { useDetailsPanelContext } from '@shared/context'\n\ntype Props = {\n activity: any\n onCheckChange?: Function\n onDelete?: (activityId: string, entityId: string, refs: any) => Promise<void>\n onUpdate?: Function\n projectInfo: any\n editProps?: {\n disabled: boolean\n isLoading: boolean\n }\n projectName: string\n entityType: string\n onReferenceClick?: ActivityHeaderProps['onReferenceClick']\n onFileExpand?: FilesGridProps['onExpand']\n showOrigin?: boolean\n isHighlighted?: boolean\n readOnly?: boolean\n statuses: Status[]\n}\n\nconst ActivityComment = ({\n activity = {},\n onCheckChange,\n onDelete,\n onUpdate,\n projectInfo,\n editProps,\n projectName,\n entityType,\n onReferenceClick,\n onFileExpand,\n showOrigin,\n isHighlighted,\n readOnly,\n statuses = [],\n}: Props) => {\n const { userName, createReaction, deleteReaction } = useFeedContext()\n\n let {\n body,\n authorName,\n authorFullName,\n createdAt,\n referenceType,\n entityId,\n activityId,\n author,\n isOwner,\n files = [],\n origin,\n } = activity\n if (!authorName) authorName = author?.name || ''\n if (!authorFullName) authorFullName = author?.fullName || authorName\n\n const { editingId, setEditingId } = useFeedContext()\n const { onGoToFrame, setHighlightedActivities } = useDetailsPanelContext()\n\n const handleEditComment = () => {\n setEditingId(activityId)\n }\n\n const handleEditCancel = () => {\n // close the edit comment\n setEditingId(null)\n }\n\n const handleSave = async (value: any, files: any) => {\n await onUpdate?.(value, files)\n setEditingId(null)\n }\n\n const isEditing = editingId === activityId\n\n const isRef = referenceType !== 'origin' || showOrigin\n\n const handleDelete = async () => {\n const refs = getTextRefs(body)\n\n // if the comment is a reference, (it's origin is not the entity)\n // we need to delete the reference from the origin as well\n // add it to the refs to delete\n if (isRef && origin) {\n refs.push({ id: origin.id, type: origin.type })\n }\n\n // note: body is used to match other refs to delete\n onDelete && (await onDelete(activityId, entityId, refs))\n }\n\n const deleteConfirmation = () => {\n confirmDelete({\n title: 'Delete comment',\n message: 'Are you sure you want to delete this comment?',\n accept: async () => {\n await handleDelete()\n },\n })\n }\n\n const [, setRefTooltip] = useReferenceTooltip()\n\n const mappedReactions = useMemo(\n () => mapGraphQLReactions(activity.reactions, userName),\n [[...(activity.reactions || [])]],\n )\n\n const reactionChangeHandler = (reaction: Reaction) => {\n if (reaction.isActive) {\n createReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n createReactionModel: {\n reaction: reaction.type,\n },\n })\n } else {\n deleteReaction({\n projectName: projectName,\n // @ts-ignore exposed endpoint doesn't need the username, we still need to pass it for the optimistic update\n userName: userName,\n activityId: activityId,\n reaction: reaction.type,\n })\n }\n }\n\n const onAnnotationClick = useCallback(\n (file: any) => {\n if (!file.annotation) return\n // annotation frame numbers are 1-based\n onGoToFrame?.((file.annotation as SavedAnnotationMetadata).range[0] - 1)\n setHighlightedActivities([activityId])\n },\n [onGoToFrame],\n )\n\n return (\n <>\n <Styled.Comment\n className={clsx('comment', { isOwner, isEditing, isHighlighted })}\n id={activityId}\n >\n <ActivityHeader\n name={authorName}\n fullName={authorFullName}\n date={createdAt}\n isRef={isRef}\n activity={activity}\n // projectInfo={projectInfo}\n projectName={projectName}\n entityType={entityType}\n onReferenceClick={onReferenceClick}\n onReferenceTooltip={setRefTooltip}\n children={undefined}\n />\n <Styled.Body className={clsx('comment-body', { isEditing })}>\n {!readOnly && (\n <Styled.Tools className={'tools'}>\n {isOwner && onDelete && (\n <Styled.ToolButton\n icon=\"delete\"\n onClick={deleteConfirmation}\n tooltip=\"Delete comment\"\n />\n )}\n {isOwner && handleEditComment && (\n <Styled.ToolButton icon=\"edit_square\" onClick={handleEditComment} />\n )}\n </Styled.Tools>\n )}\n {isEditing ? (\n <CommentInput\n initValue={body}\n initFiles={files}\n isEditing\n onClose={handleEditCancel}\n onSubmit={handleSave}\n isOpen={true}\n {...editProps}\n />\n ) : (\n <>\n <CommentWrapper>\n <ReactMarkdown\n remarkPlugins={[remarkGfm, emoji, remarkDirective, remarkDirectiveRehype]}\n urlTransform={(url) => url}\n components={{\n // a links\n // @ts-ignore\n a: (props) =>\n // @ts-ignore\n aTag(props, {\n entityId,\n projectName,\n projectInfo,\n onReferenceClick,\n onReferenceTooltip: setRefTooltip,\n activityId,\n }),\n // checkbox inputs\n // @ts-ignore\n input: (props) => inputTag(props, { activity, onCheckChange }),\n // code syntax highlighting\n // eslint-disable-next-line\n // @ts-ignore\n code: (props) => codeTag(props),\n // @ts-ignore\n blockquote: (props) => blockquoteTag(props),\n // @ts-ignore\n tip: (props) => (\n <Styled.Tip>\n <Icon icon=\"info\" />\n {props.children}\n </Styled.Tip>\n ),\n // @ts-ignore\n status: (props) => {\n return (\n <ActivityStatus name={props.id} statuses={statuses}>\n {props.children}\n </ActivityStatus>\n )\n },\n }}\n >\n {body}\n </ReactMarkdown>\n </CommentWrapper>\n {/* file uploads */}\n {/* @ts-ignore */}\n <FilesGrid\n files={files}\n isCompact={files.length > 6}\n activityId={activityId}\n projectName={projectName}\n isDownloadable\n onExpand={onFileExpand}\n onAnnotationClick={onAnnotationClick}\n onRemove={undefined}\n />\n </>\n )}\n\n {!isEditing && (\n <div style={{ marginTop: '16px' }}>\n {mappedReactions && (\n <Reactions\n reactions={mappedReactions}\n changeHandler={reactionChangeHandler}\n readOnly={readOnly}\n />\n )}\n </div>\n )}\n </Styled.Body>\n </Styled.Comment>\n </>\n )\n}\n\nexport default ActivityComment\n"],"names":["files","jsx","Fragment","jsxs","Styled.Comment","Styled.Body","Styled.Tools","Styled.ToolButton","Styled.Tip"],"mappings":"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"}
|