mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-05 07:10:55 +00:00
Merge pull request #13528 from overleaf/ii-review-panel-migration-current-file-view
[web] Create initial current file container GitOrigin-RevId: 81635922bb10b97637af296d987f28d43cf61262
This commit is contained in:
parent
78314a0ee0
commit
b61ee4c4d3
23 changed files with 268 additions and 130 deletions
|
@ -1,7 +1,7 @@
|
|||
import { Project, Sort } from '../../../../../types/project/dashboard/api'
|
||||
import { SortingOrder } from '../../../../../types/sorting-order'
|
||||
import { getOwnerName } from './project'
|
||||
import { Compare } from '../../../../../types/array/sort'
|
||||
import { Compare } from '../../../../../types/helpers/array/sort'
|
||||
|
||||
const order = (order: SortingOrder, projects: Project[]) => {
|
||||
return order === 'asc' ? [...projects] : projects.reverse()
|
||||
|
|
|
@ -18,10 +18,12 @@ function Container({ children, classNames, ...rest }: ContainerProps) {
|
|||
{...rest}
|
||||
data-testid="review-panel"
|
||||
>
|
||||
<div className="review-panel-tools">
|
||||
<Toolbar />
|
||||
<Nav />
|
||||
</div>
|
||||
<Toggler />
|
||||
<Toolbar />
|
||||
{children}
|
||||
<Nav />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,50 +1,61 @@
|
|||
import Container from './container'
|
||||
import ChangeEntry from './entries/change-entry'
|
||||
import AggregateChangeEntry from './entries/aggregate-change-entry'
|
||||
import CommentEntry from './entries/comment-entry'
|
||||
import AddCommentEntry from './entries/add-comment-entry'
|
||||
import BulkActionsEntry from './entries/bulk-actions-entry'
|
||||
import { useReviewPanelValueContext } from '../../context/review-panel/review-panel-context'
|
||||
import useCodeMirrorContentHeight from '../../hooks/use-codemirror-content-height'
|
||||
|
||||
function CurrentFileContainer() {
|
||||
const { entries, openDocId, permissions } = useReviewPanelValueContext()
|
||||
const contentHeight = useCodeMirrorContentHeight()
|
||||
|
||||
console.log('Review panel got content height', contentHeight)
|
||||
|
||||
const currentDocEntries =
|
||||
openDocId && openDocId in entries ? entries[openDocId] : undefined
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div
|
||||
id="review-panel-current-file"
|
||||
role="tabpanel"
|
||||
tabIndex={0}
|
||||
aria-labelledby="review-panel-tab-current-file"
|
||||
>
|
||||
<div
|
||||
id="review-panel-current-file"
|
||||
role="tabpanel"
|
||||
tabIndex={0}
|
||||
aria-labelledby="review-panel-tab-current-file"
|
||||
className="rp-entry-list-inner"
|
||||
style={{ height: `${contentHeight}px` }}
|
||||
>
|
||||
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.
|
||||
{currentDocEntries &&
|
||||
Object.entries(currentDocEntries).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') {
|
||||
return <CommentEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'add-comment' && permissions.comment) {
|
||||
return <AddCommentEntry key={id} />
|
||||
}
|
||||
|
||||
if (entry.type === 'bulk-actions') {
|
||||
return <BulkActionsEntry key={id} />
|
||||
}
|
||||
|
||||
return null
|
||||
})}
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import EntryContainer from './entry-container'
|
||||
|
||||
function AddCommentEntry() {
|
||||
return <EntryContainer>Add comment entry</EntryContainer>
|
||||
}
|
||||
|
||||
export default AddCommentEntry
|
|
@ -0,0 +1,7 @@
|
|||
import EntryContainer from './entry-container'
|
||||
|
||||
function AggregateChangeEntry() {
|
||||
return <EntryContainer>Aggregate change entry</EntryContainer>
|
||||
}
|
||||
|
||||
export default AggregateChangeEntry
|
|
@ -0,0 +1,7 @@
|
|||
import EntryContainer from './entry-container'
|
||||
|
||||
function BulkActionsEntry() {
|
||||
return <EntryContainer>Bulk actions entry</EntryContainer>
|
||||
}
|
||||
|
||||
export default BulkActionsEntry
|
|
@ -0,0 +1,7 @@
|
|||
import EntryContainer from './entry-container'
|
||||
|
||||
function ChangeEntry() {
|
||||
return <EntryContainer>Change entry</EntryContainer>
|
||||
}
|
||||
|
||||
export default ChangeEntry
|
|
@ -0,0 +1,7 @@
|
|||
import EntryContainer from './entry-container'
|
||||
|
||||
function CommentEntry() {
|
||||
return <EntryContainer>Comment entry</EntryContainer>
|
||||
}
|
||||
|
||||
export default CommentEntry
|
|
@ -0,0 +1,9 @@
|
|||
type EntryContainerProps = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
function EntryContainer({ children }: EntryContainerProps) {
|
||||
return <div className="rp-entry-wrapper">{children}</div>
|
||||
}
|
||||
|
||||
export default EntryContainer
|
|
@ -1,32 +1,41 @@
|
|||
import Container from './container'
|
||||
|
||||
function OverviewContainer() {
|
||||
return (
|
||||
<Container>
|
||||
<div
|
||||
id="review-panel-overview"
|
||||
role="tabpanel"
|
||||
tabIndex={0}
|
||||
aria-labelledby="review-panel-tab-overview"
|
||||
>
|
||||
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.
|
||||
</div>
|
||||
</Container>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
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'
|
||||
import {
|
||||
ReviewPanelProvider,
|
||||
useReviewPanelValueContext,
|
||||
} from '../../context/review-panel/review-panel-context'
|
||||
import CurrentFileContainer from './current-file-container'
|
||||
import OverviewContainer from './overview-container'
|
||||
import { isCurrentFileView } from '../../utils/sub-view'
|
||||
|
||||
type ReviewPanelViewProps = {
|
||||
|
@ -18,9 +19,13 @@ function ReviewPanelView({ parentDomNode }: ReviewPanelViewProps) {
|
|||
return ReactDOM.createPortal(
|
||||
<>
|
||||
{isCurrentFileView(subView) ? (
|
||||
<CurrentFileContainer />
|
||||
<Container>
|
||||
<CurrentFileContainer />
|
||||
</Container>
|
||||
) : (
|
||||
<OverviewContainer />
|
||||
<Container>
|
||||
<OverviewContainer />
|
||||
</Container>
|
||||
)}
|
||||
</>,
|
||||
parentDomNode
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { useMemo } from 'react'
|
||||
import ResolvedCommentEntry from './resolved-comment-entry'
|
||||
import ResolvedCommentEntry from '../entries/resolved-comment-entry'
|
||||
import moment from 'moment'
|
||||
|
||||
type ResolvedCommentsScrollerProps = {
|
||||
|
|
|
@ -3,7 +3,7 @@ import useScopeValue from '../../../../../shared/hooks/use-scope-value'
|
|||
import { ReviewPanelState } from '../types/review-panel-state'
|
||||
import { sendMB } from '../../../../../infrastructure/event-tracking'
|
||||
import * as ReviewPanel from '../types/review-panel-state'
|
||||
import { SubView } from '../../../../../../../types/review-panel'
|
||||
import { SubView } from '../../../../../../../types/review-panel/review-panel'
|
||||
|
||||
function useAngularReviewPanelState(): ReviewPanelState {
|
||||
const [subView, setSubView] = useScopeValue<ReviewPanel.Value<'subView'>>(
|
||||
|
@ -12,12 +12,18 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
|||
const [collapsed, setCollapsed] = useScopeValue<
|
||||
ReviewPanel.Value<'collapsed'>
|
||||
>('reviewPanel.overview.docsCollapsedState')
|
||||
const [entries] = useScopeValue<ReviewPanel.Value<'entries'>>(
|
||||
'reviewPanel.entries'
|
||||
)
|
||||
|
||||
const [permissions] =
|
||||
useScopeValue<ReviewPanel.Value<'permissions'>>('permissions')
|
||||
|
||||
const [wantTrackChanges] = useScopeValue<
|
||||
ReviewPanel.Value<'wantTrackChanges'>
|
||||
>('editor.wantTrackChanges')
|
||||
const [openDocId] =
|
||||
useScopeValue<ReviewPanel.Value<'openDocId'>>('editor.open_doc_id')
|
||||
const [shouldCollapse, setShouldCollapse] = useScopeValue<
|
||||
ReviewPanel.Value<'shouldCollapse'>
|
||||
>('reviewPanel.fullTCStateCollapsed')
|
||||
|
@ -63,10 +69,12 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
|||
const values = useMemo<ReviewPanelState['values']>(
|
||||
() => ({
|
||||
collapsed,
|
||||
entries,
|
||||
permissions,
|
||||
subView,
|
||||
shouldCollapse,
|
||||
subView,
|
||||
wantTrackChanges,
|
||||
openDocId,
|
||||
toggleTrackChangesForEveryone,
|
||||
toggleTrackChangesForUser,
|
||||
toggleTrackChangesForGuests,
|
||||
|
@ -79,10 +87,12 @@ function useAngularReviewPanelState(): ReviewPanelState {
|
|||
}),
|
||||
[
|
||||
collapsed,
|
||||
entries,
|
||||
permissions,
|
||||
subView,
|
||||
shouldCollapse,
|
||||
subView,
|
||||
wantTrackChanges,
|
||||
openDocId,
|
||||
toggleTrackChangesForEveryone,
|
||||
toggleTrackChangesForUser,
|
||||
toggleTrackChangesForGuests,
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
import {
|
||||
SubView,
|
||||
DocId,
|
||||
ReviewPanelEntries,
|
||||
ReviewPanelPermissions,
|
||||
} from '../../../../../../../types/review-panel'
|
||||
SubView,
|
||||
} from '../../../../../../../types/review-panel/review-panel'
|
||||
|
||||
export interface ReviewPanelState {
|
||||
values: {
|
||||
collapsed: Record<string, boolean>
|
||||
subView: SubView
|
||||
entries: ReviewPanelEntries
|
||||
permissions: ReviewPanelPermissions
|
||||
shouldCollapse: boolean
|
||||
subView: SubView
|
||||
wantTrackChanges: boolean
|
||||
openDocId: DocId | null
|
||||
toggleTrackChangesForEveryone: (isOn: boolean) => unknown
|
||||
toggleTrackChangesForUser: (isOn: boolean, memberId: string) => unknown
|
||||
toggleTrackChangesForGuests: (isOn: boolean) => unknown
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { SubView } from '../../../../../types/review-panel'
|
||||
import { SubView } from '../../../../../types/review-panel/review-panel'
|
||||
|
||||
export const isCurrentFileView = (view: SubView) => view === 'cur_file'
|
||||
export const isOverviewView = (view: SubView) => view === 'overview'
|
||||
|
|
|
@ -1185,8 +1185,19 @@ button when (@is-overleaf-light = true) {
|
|||
|
||||
// CM6-specific review panel rules
|
||||
.ol-cm-review-panel {
|
||||
position: relative;
|
||||
z-index: 6;
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
flex-direction: column;
|
||||
|
||||
background-color: @rp-bg-blue;
|
||||
border-left: solid 0 @rp-border-grey;
|
||||
font-family: @font-family-base;
|
||||
line-height: @line-height-base;
|
||||
font-size: @rp-base-font-size;
|
||||
color: @rp-type-blue;
|
||||
box-sizing: content-box;
|
||||
|
||||
.rp-size-expanded & {
|
||||
display: flex;
|
||||
|
@ -1202,18 +1213,6 @@ button when (@is-overleaf-light = true) {
|
|||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
background-color: @rp-bg-blue;
|
||||
border-left: solid 0 @rp-border-grey;
|
||||
font-family: @font-family-base;
|
||||
line-height: @line-height-base;
|
||||
font-size: @rp-base-font-size;
|
||||
color: @rp-type-blue;
|
||||
z-index: 6;
|
||||
|
||||
position: relative;
|
||||
box-sizing: content-box;
|
||||
flex-direction: column;
|
||||
|
||||
.review-panel-toggler {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -1227,15 +1226,15 @@ button when (@is-overleaf-light = true) {
|
|||
}
|
||||
}
|
||||
|
||||
.review-panel-toolbar-collapse-button {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.review-panel-toolbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
||||
.review-panel-toolbar-collapse-button {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.rp-nav {
|
||||
|
@ -1263,6 +1262,27 @@ button when (@is-overleaf-light = true) {
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.rp-overview-file {
|
||||
.rp-overview-file-entries {
|
||||
//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 {
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
|
@ -1270,32 +1290,6 @@ button when (@is-overleaf-light = true) {
|
|||
background: none;
|
||||
}
|
||||
|
||||
.rp-entry-list {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
|
||||
.rp-overview-file {
|
||||
.rp-overview-file-entries {
|
||||
//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-tc-state {
|
||||
height: 0;
|
||||
transition: height 150ms;
|
||||
|
|
|
@ -78,6 +78,7 @@ export const mockScope = (content?: string) => {
|
|||
subView: 'cur_file',
|
||||
formattedProjectMembers: {},
|
||||
fullTCStateCollapsed: true,
|
||||
entries: {},
|
||||
},
|
||||
ui: {
|
||||
reviewPanelOpen: true,
|
||||
|
|
3
services/web/types/helpers/brand.ts
Normal file
3
services/web/types/helpers/brand.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
declare const brand: unique symbol
|
||||
|
||||
export type Brand<T, TBrand> = T & { [brand]: TBrand }
|
|
@ -1,8 +0,0 @@
|
|||
export type SubView = 'cur_file' | 'overview'
|
||||
|
||||
export interface ReviewPanelPermissions {
|
||||
read: boolean
|
||||
write: boolean
|
||||
admin: boolean
|
||||
comment: boolean
|
||||
}
|
47
services/web/types/review-panel/entry.ts
Normal file
47
services/web/types/review-panel/entry.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
interface ReviewPanelEntryScreenPos {
|
||||
y: number
|
||||
height: number
|
||||
editorPaddingTop: number
|
||||
}
|
||||
|
||||
interface ReviewPanelBaseEntry {
|
||||
visible: boolean
|
||||
}
|
||||
|
||||
interface ReviewPanelCommentEntry extends ReviewPanelBaseEntry {
|
||||
type: 'comment'
|
||||
content: string
|
||||
entry_ids: string[]
|
||||
focused: boolean
|
||||
offset: number
|
||||
screenPos: ReviewPanelEntryScreenPos
|
||||
thread_id: string
|
||||
}
|
||||
|
||||
interface ReviewPanelInsertEntry extends ReviewPanelBaseEntry {
|
||||
type: 'insert'
|
||||
}
|
||||
|
||||
interface ReviewPanelDeleteEntry extends ReviewPanelBaseEntry {
|
||||
type: 'delete'
|
||||
}
|
||||
|
||||
interface ReviewPanelAggregateChangeEntry extends ReviewPanelBaseEntry {
|
||||
type: 'aggregate-change'
|
||||
}
|
||||
|
||||
interface ReviewPanelAddCommentEntry extends ReviewPanelBaseEntry {
|
||||
type: 'add-comment'
|
||||
}
|
||||
|
||||
interface ReviewPanelBulkActionsEntry extends ReviewPanelBaseEntry {
|
||||
type: 'bulk-actions'
|
||||
}
|
||||
|
||||
export type ReviewPanelEntry =
|
||||
| ReviewPanelCommentEntry
|
||||
| ReviewPanelInsertEntry
|
||||
| ReviewPanelDeleteEntry
|
||||
| ReviewPanelAggregateChangeEntry
|
||||
| ReviewPanelAddCommentEntry
|
||||
| ReviewPanelBulkActionsEntry
|
16
services/web/types/review-panel/review-panel.ts
Normal file
16
services/web/types/review-panel/review-panel.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Brand } from '../helpers/brand'
|
||||
import { ReviewPanelEntry } from './entry'
|
||||
|
||||
export type SubView = 'cur_file' | 'overview'
|
||||
|
||||
export interface ReviewPanelPermissions {
|
||||
read: boolean
|
||||
write: boolean
|
||||
admin: boolean
|
||||
comment: boolean
|
||||
}
|
||||
|
||||
export type ReviewPanelDocEntries = Record<string, ReviewPanelEntry>
|
||||
|
||||
export type DocId = Brand<string, 'DocId'>
|
||||
export type ReviewPanelEntries = Record<DocId, ReviewPanelDocEntries>
|
Loading…
Reference in a new issue