mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-09 12:35:51 +00:00
Merge pull request #13641 from overleaf/ii-review-panel-migration-overview-view
[web] Create overview view shell for review panel GitOrigin-RevId: 21cc8a744253aec53f089ec6e6c1221d7153f3a4
This commit is contained in:
parent
87013d20f8
commit
936ab81b65
18 changed files with 274 additions and 141 deletions
|
@ -1,6 +1,3 @@
|
|||
import Toggler from './toggler'
|
||||
import Toolbar from './toolbar/toolbar'
|
||||
import Nav from './nav'
|
||||
import classnames from 'classnames'
|
||||
|
||||
const reviewPanelClasses = ['ol-cm-review-panel']
|
||||
|
@ -18,11 +15,6 @@ function Container({ children, classNames, ...rest }: ContainerProps) {
|
|||
{...rest}
|
||||
data-testid="review-panel"
|
||||
>
|
||||
<div className="review-panel-tools">
|
||||
<Toolbar />
|
||||
<Nav />
|
||||
</div>
|
||||
<Toggler />
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { useMemo } from 'react'
|
||||
import Container from './container'
|
||||
import Toolbar from './toolbar/toolbar'
|
||||
import Nav from './nav'
|
||||
import Toggler from './toggler'
|
||||
import ChangeEntry from './entries/change-entry'
|
||||
import AggregateChangeEntry from './entries/aggregate-change-entry'
|
||||
import CommentEntry from './entries/comment-entry'
|
||||
|
@ -26,54 +30,62 @@ function CurrentFileContainer() {
|
|||
}, [currentDocEntries])
|
||||
|
||||
return (
|
||||
<div
|
||||
id="review-panel-current-file"
|
||||
role="tabpanel"
|
||||
tabIndex={0}
|
||||
aria-labelledby="review-panel-tab-current-file"
|
||||
>
|
||||
<div
|
||||
className="rp-entry-list-inner"
|
||||
style={{ height: `${contentHeight}px` }}
|
||||
>
|
||||
{openDocId &&
|
||||
objectEntries.map(([id, entry]) => {
|
||||
if (!entry.visible) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (entry.type === 'insert' || entry.type === 'delete') {
|
||||
return <ChangeEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'aggregate-change') {
|
||||
return <AggregateChangeEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'comment' && !loadingThreads) {
|
||||
return (
|
||||
<CommentEntry
|
||||
key={id}
|
||||
docId={openDocId}
|
||||
entry={entry}
|
||||
entryId={id}
|
||||
threads={commentThreads}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (entry.type === 'add-comment' && permissions.comment) {
|
||||
return <AddCommentEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'bulk-actions') {
|
||||
return <BulkActionsEntry key={id} />
|
||||
}
|
||||
|
||||
return null
|
||||
})}
|
||||
<Container>
|
||||
<div className="review-panel-tools">
|
||||
<Toolbar />
|
||||
<Nav />
|
||||
</div>
|
||||
</div>
|
||||
<Toggler />
|
||||
<div
|
||||
id="review-panel-current-file"
|
||||
role="tabpanel"
|
||||
tabIndex={0}
|
||||
aria-labelledby="review-panel-tab-current-file"
|
||||
>
|
||||
<div
|
||||
className="rp-entry-list-inner"
|
||||
style={{ height: `${contentHeight}px` }}
|
||||
>
|
||||
{openDocId &&
|
||||
objectEntries.map(([id, entry]) => {
|
||||
if (!entry.visible) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (entry.type === 'insert' || entry.type === 'delete') {
|
||||
return <ChangeEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'aggregate-change') {
|
||||
return <AggregateChangeEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'comment' && !loadingThreads) {
|
||||
return (
|
||||
<CommentEntry
|
||||
key={id}
|
||||
docId={openDocId}
|
||||
entry={entry}
|
||||
entryId={id}
|
||||
permissions={permissions}
|
||||
threads={commentThreads}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (entry.type === 'add-comment' && permissions.comment) {
|
||||
return <AddCommentEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'bulk-actions') {
|
||||
return <BulkActionsEntry key={id} />
|
||||
}
|
||||
|
||||
return null
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,22 +14,29 @@ import {
|
|||
import classnames from 'classnames'
|
||||
import { ReviewPanelCommentEntry } from '../../../../../../../types/review-panel/entry'
|
||||
import {
|
||||
DocId,
|
||||
ReviewPanelCommentThreads,
|
||||
ReviewPanelPermissions,
|
||||
ThreadId,
|
||||
} from '../../../../../../../types/review-panel/review-panel'
|
||||
import { DocId } from '../../../../../../../types/project-settings'
|
||||
|
||||
type CommentEntryProps = {
|
||||
docId: DocId
|
||||
entry: ReviewPanelCommentEntry
|
||||
entryId: ThreadId
|
||||
permissions: ReviewPanelPermissions
|
||||
threads: ReviewPanelCommentThreads
|
||||
}
|
||||
|
||||
function CommentEntry({ docId, entry, entryId, threads }: CommentEntryProps) {
|
||||
function CommentEntry({
|
||||
docId,
|
||||
entry,
|
||||
entryId,
|
||||
permissions,
|
||||
threads,
|
||||
}: CommentEntryProps) {
|
||||
const { t } = useTranslation()
|
||||
const {
|
||||
permissions,
|
||||
gotoEntry,
|
||||
toggleReviewPanel,
|
||||
resolveComment,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { useEffect } from 'react'
|
||||
|
||||
function useCollapseHeight(
|
||||
elRef: React.MutableRefObject<HTMLElement | null>,
|
||||
shouldCollapse: boolean
|
||||
) {
|
||||
useEffect(() => {
|
||||
if (elRef.current) {
|
||||
const neededHeight = elRef.current.scrollHeight
|
||||
|
||||
if (neededHeight > 0) {
|
||||
const height = shouldCollapse ? 0 : neededHeight
|
||||
// This might result in a too big height if the element has css prop of
|
||||
// `box-sizing` set to `content-box`. To fix that, values of props such as
|
||||
// box-sizing, padding and border could be extracted from `height` to compensate.
|
||||
elRef.current.style.height = `${height}px`
|
||||
} else {
|
||||
if (shouldCollapse) {
|
||||
elRef.current.style.height = '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [elRef, shouldCollapse])
|
||||
}
|
||||
|
||||
export default useCollapseHeight
|
|
@ -1,41 +1,41 @@
|
|||
import Container from './container'
|
||||
import Toggler from './toggler'
|
||||
import Toolbar from './toolbar/toolbar'
|
||||
import Nav from './nav'
|
||||
import Icon from '../../../../shared/components/icon'
|
||||
import OverviewFile from './overview-file'
|
||||
import { useReviewPanelValueContext } from '../../context/review-panel/review-panel-context'
|
||||
|
||||
function OverviewContainer() {
|
||||
const { loading, docs } = useReviewPanelValueContext()
|
||||
|
||||
return (
|
||||
<div
|
||||
className="rp-entry-list"
|
||||
id="review-panel-overview"
|
||||
role="tabpanel"
|
||||
tabIndex={0}
|
||||
aria-labelledby="review-panel-tab-overview"
|
||||
>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Et malesuada fames ac
|
||||
turpis egestas integer eget aliquet nibh. Et leo duis ut diam quam nulla
|
||||
porttitor massa id. Risus quis varius quam quisque id diam vel quam
|
||||
elementum. Nibh venenatis cras sed felis. Sit amet commodo nulla facilisi
|
||||
nullam vehicula ipsum a arcu. Dui ut ornare lectus sit amet est placerat
|
||||
in. Aliquam ultrices sagittis orci a. Leo a diam sollicitudin tempor id eu
|
||||
nisl nunc mi. Quis ipsum suspendisse ultrices gravida dictum fusce. Ut
|
||||
etiam sit amet nisl purus in mollis nunc sed. Rhoncus est pellentesque
|
||||
elit ullamcorper dignissim cras. Faucibus turpis in eu mi bibendum. Proin
|
||||
libero nunc consequat interdum. Ac placerat vestibulum lectus mauris
|
||||
ultrices eros in cursus turpis. Ac felis donec et odio. Nullam ac tortor
|
||||
vitae purus faucibus. Consectetur lorem donec massa sapien faucibus et
|
||||
molestie. Praesent elementum facilisis leo vel fringilla est ullamcorper
|
||||
eget nulla. Adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus
|
||||
urna. Cursus metus aliquam eleifend mi in nulla posuere sollicitudin
|
||||
aliquam. Eget nullam non nisi est sit amet facilisis magna. Donec
|
||||
adipiscing tristique risus nec feugiat in fermentum posuere. Gravida
|
||||
rutrum quisque non tellus orci ac auctor augue. Euismod in pellentesque
|
||||
massa placerat duis ultricies lacus. Pellentesque diam volutpat commodo
|
||||
sed egestas. Tempus iaculis urna id volutpat lacus laoreet. Lorem ipsum
|
||||
dolor sit amet consectetur. Tincidunt id aliquet risus feugiat in ante
|
||||
metus. Risus ultricies tristique nulla aliquet enim tortor at auctor urna.
|
||||
Purus in mollis nunc sed. In ante metus dictum at. Magna eget est lorem
|
||||
ipsum dolor sit. Fusce id velit ut tortor pretium viverra. Augue neque
|
||||
gravida in fermentum et sollicitudin ac. Et malesuada fames ac turpis.
|
||||
Felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices.
|
||||
Varius vel pharetra vel turpis nunc eget.
|
||||
</div>
|
||||
<Container>
|
||||
<Toggler />
|
||||
<Toolbar />
|
||||
<div
|
||||
className="rp-entry-list"
|
||||
id="review-panel-overview"
|
||||
role="tabpanel"
|
||||
tabIndex={0}
|
||||
aria-labelledby="review-panel-tab-overview"
|
||||
>
|
||||
{loading ? (
|
||||
<div className="rp-loading">
|
||||
<Icon type="spinner" spin />
|
||||
</div>
|
||||
) : (
|
||||
docs?.map(doc => (
|
||||
<OverviewFile
|
||||
key={doc.doc.id}
|
||||
docId={doc.doc.id}
|
||||
docPath={doc.path}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
<Nav />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
import { useMemo, useRef } from 'react'
|
||||
import Icon from '../../../../shared/components/icon'
|
||||
import ChangeEntry from './entries/change-entry'
|
||||
import AggregateChangeEntry from './entries/aggregate-change-entry'
|
||||
import CommentEntry from './entries/comment-entry'
|
||||
import {
|
||||
useReviewPanelUpdaterFnsContext,
|
||||
useReviewPanelValueContext,
|
||||
} from '../../context/review-panel/review-panel-context'
|
||||
import classnames from 'classnames'
|
||||
import { ThreadId } from '../../../../../../types/review-panel/review-panel'
|
||||
import { MainDocument } from '../../../../../../types/project-settings'
|
||||
import { ReviewPanelEntry } from '../../../../../../types/review-panel/entry'
|
||||
import useCollapseHeight from './hooks/use-collapse-height'
|
||||
|
||||
type OverviewFileProps = {
|
||||
docId: MainDocument['doc']['id']
|
||||
docPath: MainDocument['path']
|
||||
}
|
||||
|
||||
function OverviewFile({ docId, docPath }: OverviewFileProps) {
|
||||
const { entries, collapsed, commentThreads, permissions } =
|
||||
useReviewPanelValueContext()
|
||||
const { setCollapsed } = useReviewPanelUpdaterFnsContext()
|
||||
|
||||
const docCollapsed = collapsed[docId]
|
||||
const docEntries = useMemo(
|
||||
() => (docId in entries ? entries[docId] : {}),
|
||||
[docId, entries]
|
||||
)
|
||||
const objectEntries = useMemo(() => {
|
||||
const entries = Object.entries(docEntries) as Array<
|
||||
[ThreadId, ReviewPanelEntry]
|
||||
>
|
||||
|
||||
const orderedEntries = entries.sort(([, entryA], [, entryB]) => {
|
||||
return entryA.offset - entryB.offset
|
||||
})
|
||||
|
||||
return orderedEntries
|
||||
}, [docEntries])
|
||||
const entryCount = Object.keys(docEntries).length
|
||||
|
||||
const handleToggleCollapsed = () => {
|
||||
setCollapsed({ ...collapsed, [docId]: !docCollapsed })
|
||||
}
|
||||
|
||||
const entriesContainerRef = useRef<HTMLDivElement | null>(null)
|
||||
useCollapseHeight(entriesContainerRef, docCollapsed)
|
||||
|
||||
return (
|
||||
<div className="rp-overview-file">
|
||||
{entryCount > 0 && (
|
||||
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
||||
<div
|
||||
className="rp-overview-file-header"
|
||||
onClick={handleToggleCollapsed}
|
||||
>
|
||||
<span
|
||||
className={classnames('rp-overview-file-header-collapse', {
|
||||
'rp-overview-file-header-collapse-on': docCollapsed,
|
||||
})}
|
||||
>
|
||||
<Icon type="angle-down" />
|
||||
</span>
|
||||
{docPath}
|
||||
{docCollapsed && (
|
||||
<>
|
||||
|
||||
<span className="rp-overview-file-num-entries">
|
||||
({entryCount})
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="rp-overview-file-entries" ref={entriesContainerRef}>
|
||||
{objectEntries.map(([id, entry]) => {
|
||||
if (entry.type === 'insert' || entry.type === 'delete') {
|
||||
return <ChangeEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'aggregate-change') {
|
||||
return <AggregateChangeEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'comment') {
|
||||
if (!commentThreads[entry.thread_id]?.resolved) {
|
||||
return (
|
||||
<CommentEntry
|
||||
key={id}
|
||||
docId={docId}
|
||||
entry={entry}
|
||||
entryId={id}
|
||||
permissions={permissions}
|
||||
threads={commentThreads}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default OverviewFile
|
|
@ -1,5 +1,4 @@
|
|||
import ReactDOM from 'react-dom'
|
||||
import Container from './container'
|
||||
import CurrentFileContainer from './current-file-container'
|
||||
import OverviewContainer from './overview-container'
|
||||
import { useCodeMirrorViewContext } from '../codemirror-editor'
|
||||
|
@ -19,13 +18,9 @@ function ReviewPanelView({ parentDomNode }: ReviewPanelViewProps) {
|
|||
return ReactDOM.createPortal(
|
||||
<>
|
||||
{isCurrentFileView(subView) ? (
|
||||
<Container>
|
||||
<CurrentFileContainer />
|
||||
</Container>
|
||||
<CurrentFileContainer />
|
||||
) : (
|
||||
<Container>
|
||||
<OverviewContainer />
|
||||
</Container>
|
||||
<OverviewContainer />
|
||||
)}
|
||||
</>,
|
||||
parentDomNode
|
||||
|
|
|
@ -6,11 +6,11 @@ import ResolvedCommentsScroller from './resolved-comments-scroller'
|
|||
import classnames from 'classnames'
|
||||
import { useReviewPanelValueContext } from '../../../context/review-panel/review-panel-context'
|
||||
import {
|
||||
DocId,
|
||||
ReviewPanelDocEntries,
|
||||
ThreadId,
|
||||
} from '../../../../../../../types/review-panel/review-panel'
|
||||
import { ReviewPanelResolvedCommentThread } from '../../../../../../../types/review-panel/comment-thread'
|
||||
import { DocId } from '../../../../../../../types/project-settings'
|
||||
|
||||
export interface FilteredResolvedComments
|
||||
extends ReviewPanelResolvedCommentThread {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useRef } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import Tooltip from '../../../../../shared/components/tooltip'
|
||||
import Icon from '../../../../../shared/components/icon'
|
||||
|
@ -9,6 +9,7 @@ import {
|
|||
useReviewPanelValueContext,
|
||||
} from '../../../context/review-panel/review-panel-context'
|
||||
import classnames from 'classnames'
|
||||
import useCollapseHeight from '../hooks/use-collapse-height'
|
||||
|
||||
function ToggleMenu() {
|
||||
const { t } = useTranslation()
|
||||
|
@ -29,21 +30,7 @@ function ToggleMenu() {
|
|||
} = useReviewPanelValueContext()
|
||||
|
||||
const containerRef = useRef<HTMLUListElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (containerRef.current) {
|
||||
const neededHeight = containerRef.current.scrollHeight
|
||||
|
||||
if (neededHeight > 0) {
|
||||
const height = shouldCollapse ? 0 : neededHeight
|
||||
containerRef.current.style.height = `${height}px`
|
||||
} else {
|
||||
if (shouldCollapse) {
|
||||
containerRef.current.style.height = '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [shouldCollapse])
|
||||
useCollapseHeight(containerRef, shouldCollapse)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -13,6 +13,9 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
|||
const [subView, setSubView] = useScopeValue<ReviewPanel.Value<'subView'>>(
|
||||
'reviewPanel.subView'
|
||||
)
|
||||
const [loading] = useScopeValue<ReviewPanel.Value<'loading'>>(
|
||||
'reviewPanel.overview.loading'
|
||||
)
|
||||
const [collapsed, setCollapsed] = useScopeValue<
|
||||
ReviewPanel.Value<'collapsed'>
|
||||
>('reviewPanel.overview.docsCollapsedState')
|
||||
|
@ -130,6 +133,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
|||
submitReply,
|
||||
subView,
|
||||
wantTrackChanges,
|
||||
loading,
|
||||
openDocId,
|
||||
toggleTrackChangesForEveryone,
|
||||
toggleTrackChangesForUser,
|
||||
|
@ -162,6 +166,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
|||
submitReply,
|
||||
subView,
|
||||
wantTrackChanges,
|
||||
loading,
|
||||
openDocId,
|
||||
toggleTrackChangesForEveryone,
|
||||
toggleTrackChangesForUser,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import {
|
||||
CommentId,
|
||||
DocId,
|
||||
ReviewPanelCommentThreads,
|
||||
ReviewPanelEntries,
|
||||
ReviewPanelPermissions,
|
||||
|
@ -8,11 +7,14 @@ import {
|
|||
ThreadId,
|
||||
} from '../../../../../../../types/review-panel/review-panel'
|
||||
import { ReviewPanelCommentEntry } from '../../../../../../../types/review-panel/entry'
|
||||
import { MainDocument } from '../../../../../../../types/project-settings'
|
||||
import {
|
||||
DocId,
|
||||
MainDocument,
|
||||
} from '../../../../../../../types/project-settings'
|
||||
|
||||
export interface ReviewPanelState {
|
||||
values: {
|
||||
collapsed: Record<string, boolean>
|
||||
collapsed: Record<DocId, boolean>
|
||||
commentThreads: ReviewPanelCommentThreads
|
||||
deleteComment: (threadId: ThreadId, commentId: CommentId) => void
|
||||
docs: MainDocument[] | undefined
|
||||
|
@ -33,6 +35,7 @@ export interface ReviewPanelState {
|
|||
submitReply: (entry: ReviewPanelCommentEntry, replyContent: string) => void
|
||||
subView: SubView
|
||||
wantTrackChanges: boolean
|
||||
loading: boolean
|
||||
openDocId: DocId | null
|
||||
toggleTrackChangesForEveryone: (isOn: boolean) => unknown
|
||||
toggleTrackChangesForUser: (isOn: boolean, memberId: string) => unknown
|
||||
|
|
|
@ -1260,6 +1260,7 @@ button when (@is-overleaf-light = true) {
|
|||
top: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.rp-overview-file {
|
||||
|
@ -1267,20 +1268,6 @@ button when (@is-overleaf-light = true) {
|
|||
//height: auto;
|
||||
transition: height ease-in-out 0.15s; //, display 0.15s 0s;
|
||||
}
|
||||
|
||||
.rp-overview-file-num-entries {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.rp-overview-file-collapse {
|
||||
.rp-overview-file-num-entries {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.rp-overview-file-entries {
|
||||
// height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rp-nav-item {
|
||||
|
|
|
@ -352,7 +352,7 @@ describe('<EditorLeftMenu />', function () {
|
|||
id: 'id1',
|
||||
type: 'doc',
|
||||
selected: false,
|
||||
},
|
||||
} as MainDocument['doc'],
|
||||
},
|
||||
{
|
||||
path: 'main2.tex',
|
||||
|
@ -361,7 +361,7 @@ describe('<EditorLeftMenu />', function () {
|
|||
id: 'id2',
|
||||
type: 'doc',
|
||||
selected: false,
|
||||
},
|
||||
} as MainDocument['doc'],
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ describe('<SettingsDocument />', function () {
|
|||
id: '123abc',
|
||||
type: 'doc',
|
||||
selected: false,
|
||||
},
|
||||
} as MainDocument['doc'],
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -192,4 +192,12 @@ describe('<ReviewPanel />', function () {
|
|||
// eslint-disable-next-line mocha/no-skipped-tests
|
||||
it.skip('resolves comment', function () {})
|
||||
})
|
||||
|
||||
describe('overview mode', function () {
|
||||
// eslint-disable-next-line mocha/no-skipped-tests
|
||||
it.skip('shows list of files changed', function () {})
|
||||
|
||||
// eslint-disable-next-line mocha/no-skipped-tests
|
||||
it.skip('renders comments', function () {})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import { OverallTheme } from '../frontend/js/features/source-editor/extensions/theme'
|
||||
import { Brand } from './helpers/brand'
|
||||
|
||||
export type AllowedImageName = {
|
||||
imageDesc: string
|
||||
imageName: string
|
||||
}
|
||||
|
||||
export type DocId = Brand<string, 'DocId'>
|
||||
export type MainDocument = {
|
||||
doc: {
|
||||
name: string
|
||||
id: string
|
||||
id: DocId
|
||||
type: string
|
||||
selected: boolean
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ interface ReviewPanelEntryScreenPos {
|
|||
|
||||
interface ReviewPanelBaseEntry {
|
||||
visible: boolean
|
||||
offset: number
|
||||
}
|
||||
|
||||
export interface ReviewPanelCommentEntry extends ReviewPanelBaseEntry {
|
||||
|
@ -15,7 +16,6 @@ export interface ReviewPanelCommentEntry extends ReviewPanelBaseEntry {
|
|||
content: string
|
||||
entry_ids: string[]
|
||||
focused: boolean
|
||||
offset: number
|
||||
screenPos: ReviewPanelEntryScreenPos
|
||||
thread_id: ThreadId
|
||||
replyContent?: string // angular specific
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Brand } from '../helpers/brand'
|
||||
import { DocId } from '../project-settings'
|
||||
import { ReviewPanelEntry } from './entry'
|
||||
import { ReviewPanelCommentThread } from './comment-thread'
|
||||
|
||||
|
@ -14,7 +15,6 @@ export interface ReviewPanelPermissions {
|
|||
export type ThreadId = Brand<string, 'ThreadId'>
|
||||
export type ReviewPanelDocEntries = Record<ThreadId, ReviewPanelEntry>
|
||||
|
||||
export type DocId = Brand<string, 'DocId'>
|
||||
export type ReviewPanelEntries = Record<DocId, ReviewPanelDocEntries>
|
||||
|
||||
export type UserId = Brand<string, 'UserId'>
|
||||
|
|
Loading…
Add table
Reference in a new issue