mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-30 12:24:25 +02:00
Create shared PanelHeading and CollapsibleFileList components (#22995)
GitOrigin-RevId: ffe524cc0ddf6a1cf532a50f37900b1747b2afee
This commit is contained in:
@@ -2,11 +2,10 @@ import { FC, memo, useState } from 'react'
|
||||
import { ReviewPanelResolvedThreadsButton } from './review-panel-resolved-threads-button'
|
||||
import { ReviewPanelTrackChangesMenu } from './review-panel-track-changes-menu'
|
||||
import ReviewPanelTrackChangesMenuButton from './review-panel-track-changes-menu-button'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { useLayoutContext } from '@/shared/context/layout-context'
|
||||
import SplitTestBadge from '@/shared/components/split-test-badge'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { PanelHeading } from '@/shared/components/panel-heading'
|
||||
|
||||
const isReviewerRoleEnabled = getMeta('ol-isReviewerRoleEnabled')
|
||||
|
||||
@@ -18,25 +17,13 @@ const ReviewPanelHeader: FC = () => {
|
||||
|
||||
return (
|
||||
<div className="review-panel-header">
|
||||
<div className="review-panel-heading">
|
||||
<div className="review-panel-label">
|
||||
{t('review')}
|
||||
<span className="review-panel-split-test-badge">
|
||||
<SplitTestBadge
|
||||
splitTestName="review-panel-redesign"
|
||||
displayOnVariants={['enabled']}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<PanelHeading
|
||||
title={t('review')}
|
||||
handleClose={() => setReviewPanelOpen(false)}
|
||||
splitTestName="review-panel-redesign"
|
||||
>
|
||||
{isReviewerRoleEnabled && <ReviewPanelResolvedThreadsButton />}
|
||||
<button
|
||||
type="button"
|
||||
className="btn review-panel-close-button"
|
||||
onClick={() => setReviewPanelOpen(false)}
|
||||
>
|
||||
<MaterialIcon type="close" />
|
||||
</button>
|
||||
</div>
|
||||
</PanelHeading>
|
||||
{!isReviewerRoleEnabled && (
|
||||
<div className="review-panel-tools">
|
||||
<ReviewPanelResolvedThreadsButton />
|
||||
|
||||
@@ -16,9 +16,9 @@ import {
|
||||
} from '../../../../../types/change'
|
||||
import { canAggregate } from '../utils/can-aggregate'
|
||||
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import useOverviewFileCollapsed from '../hooks/use-overview-file-collapsed'
|
||||
import { useThreadsContext } from '../context/threads-context'
|
||||
import { CollapsibleFileHeader } from '@/shared/components/collapsible-file-header'
|
||||
|
||||
export const ReviewPanelOverviewFile: FC<{
|
||||
doc: MainDocument
|
||||
@@ -64,19 +64,12 @@ export const ReviewPanelOverviewFile: FC<{
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="review-panel-overview-file-header"
|
||||
onClick={toggleCollapsed}
|
||||
>
|
||||
<MaterialIcon
|
||||
type={collapsed ? 'keyboard_arrow_right' : 'keyboard_arrow_down'}
|
||||
/>
|
||||
{doc.doc.name}
|
||||
<div className="review-panel-overview-file-entry-count">
|
||||
{entries.length}
|
||||
</div>
|
||||
</button>
|
||||
<CollapsibleFileHeader
|
||||
name={doc.doc.name}
|
||||
count={entries.length}
|
||||
collapsed={collapsed}
|
||||
toggleCollapsed={toggleCollapsed}
|
||||
/>
|
||||
|
||||
{!collapsed && (
|
||||
<div className="review-panel-overview-file-entries">
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { Dispatch, FC, SetStateAction } from 'react'
|
||||
|
||||
export const CollapsibleFileHeader: FC<{
|
||||
name: string
|
||||
count: number
|
||||
collapsed: boolean
|
||||
toggleCollapsed: Dispatch<SetStateAction<any>>
|
||||
}> = ({ name, count, collapsed, toggleCollapsed }) => (
|
||||
<button
|
||||
type="button"
|
||||
className="collapsible-file-header"
|
||||
onClick={toggleCollapsed}
|
||||
>
|
||||
<MaterialIcon
|
||||
type={collapsed ? 'keyboard_arrow_right' : 'keyboard_arrow_down'}
|
||||
/>
|
||||
{name}
|
||||
<div className="collapsible-file-header-count">{count}</div>
|
||||
</button>
|
||||
)
|
||||
38
services/web/frontend/js/shared/components/panel-heading.tsx
Normal file
38
services/web/frontend/js/shared/components/panel-heading.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { FC } from 'react'
|
||||
import SplitTestBadge from '@/shared/components/split-test-badge'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export const PanelHeading: FC<{
|
||||
title: string
|
||||
splitTestName?: string
|
||||
children?: React.ReactNode
|
||||
handleClose(): void
|
||||
}> = ({ title, splitTestName, children, handleClose }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="panel-heading">
|
||||
<div className="panel-heading-label">
|
||||
<span>{title}</span>
|
||||
{splitTestName && (
|
||||
<SplitTestBadge
|
||||
splitTestName={splitTestName}
|
||||
displayOnVariants={['enabled']}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{children}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="btn panel-heading-close-button"
|
||||
aria-label={t('close')}
|
||||
onClick={handleClose}
|
||||
>
|
||||
<MaterialIcon type="close" />
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -498,7 +498,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.review-panel-overview-file-header {
|
||||
.collapsible-file-header {
|
||||
all: unset;
|
||||
padding: 6px 8px;
|
||||
font-size: 14px;
|
||||
@@ -524,7 +524,7 @@
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.review-panel-overview-file-entry-count {
|
||||
.collapsible-file-header-count {
|
||||
background-color: @neutral-20;
|
||||
padding: 2px 4px;
|
||||
margin-left: auto;
|
||||
|
||||
@@ -34,3 +34,5 @@
|
||||
@import 'recurly';
|
||||
@import 'dev-toolbar';
|
||||
@import 'tos';
|
||||
@import 'collapsible-file-header';
|
||||
@import 'panel-heading';
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
.collapsible-file-header {
|
||||
all: unset;
|
||||
padding: var(--spacing-03) var(--spacing-04);
|
||||
font-size: var(--font-size-02);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-04);
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.collapsible-file-header-count {
|
||||
background-color: var(--neutral-20);
|
||||
padding: var(--spacing-01) var(--spacing-02);
|
||||
margin-left: auto;
|
||||
border-radius: var(--border-radius-base);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
.panel-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing-03) var(--spacing-02);
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.panel-heading-label {
|
||||
font-size: var(--font-size-02);
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
text-align: start;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-02);
|
||||
}
|
||||
|
||||
.panel-heading-close-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: var(--content-primary);
|
||||
padding: var(--spacing-01);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--neutral-20);
|
||||
}
|
||||
}
|
||||
@@ -253,39 +253,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.review-panel-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing-03) var(--spacing-02);
|
||||
gap: 2px;
|
||||
|
||||
.review-panel-label {
|
||||
font-size: var(--font-size-02);
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.review-panel-split-test-badge {
|
||||
margin-left: var(--spacing-02);
|
||||
}
|
||||
|
||||
.review-panel-close-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: var(--content-primary);
|
||||
padding: var(--spacing-01);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--neutral-20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.review-panel-resolved-comments {
|
||||
--bs-popover-border-width: 1px;
|
||||
--bs-popover-bg: var(--bg-light-secondary);
|
||||
@@ -505,18 +472,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.review-panel-overview-file-header {
|
||||
all: unset;
|
||||
padding: var(--spacing-03) var(--spacing-04);
|
||||
font-size: var(--font-size-02);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-04);
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.review-panel-overfile-divider {
|
||||
border-bottom: 1px solid var(--border-divider);
|
||||
margin: var(--spacing-01) 0;
|
||||
@@ -531,13 +486,6 @@
|
||||
padding-bottom: var(--spacing-03);
|
||||
}
|
||||
|
||||
.review-panel-overview-file-entry-count {
|
||||
background-color: var(--neutral-20);
|
||||
padding: var(--spacing-01) var(--spacing-02);
|
||||
margin-left: auto;
|
||||
border-radius: var(--border-radius-base);
|
||||
}
|
||||
|
||||
.review-panel-footer {
|
||||
position: fixed;
|
||||
height: 60px;
|
||||
|
||||
Reference in New Issue
Block a user