Merge pull request #13097 from overleaf/mj-figure-modal-alpha-changes

[cm6+rt] Figure Modal alpha rollout changes

GitOrigin-RevId: f7591893e8f74aa9c9b41f4b98babecaac4b3c8c
This commit is contained in:
Mathias Jakobsen 2023-05-17 08:13:09 +01:00 committed by Copybot
parent 234eb31ffb
commit f747cb000f
8 changed files with 50 additions and 25 deletions

View file

@ -122,8 +122,8 @@ const FigureModalContent = () => {
dispatch({ error: String(error) }) dispatch({ error: String(error) })
return return
} }
const labelCommand = includeLabel ? '\\label{fig:enter-label}' : '' const labelCommand = includeLabel ? '\n\\label{fig:enter-label}' : ''
const captionCommand = includeCaption ? '\\caption{Enter Caption}' : '' const captionCommand = includeCaption ? '\n\\caption{Enter Caption}' : ''
if (figure) { if (figure) {
// Updating existing figure // Updating existing figure
@ -133,15 +133,15 @@ const FigureModalContent = () => {
if (!hadCaptionBefore && includeCaption) { if (!hadCaptionBefore && includeCaption) {
// We should insert a caption // We should insert a caption
changes.push({ changes.push({
from: figure.label?.from ?? figure.graphicsCommand.to, from: figure.graphicsCommand.to,
insert: (figure.label ? '' : '\n') + captionCommand, insert: captionCommand,
}) })
} }
if (!hadLabelBefore && includeLabel) { if (!hadLabelBefore && includeLabel) {
// We should insert a label // We should insert a label
changes.push({ changes.push({
from: figure.caption?.to ?? figure.graphicsCommand.to, from: figure.caption?.to ?? figure.graphicsCommand.to,
insert: (includeCaption ? '' : '\n') + labelCommand, insert: labelCommand,
}) })
} }
if (hadCaptionBefore && !includeCaption) { if (hadCaptionBefore && !includeCaption) {
@ -187,7 +187,7 @@ const FigureModalContent = () => {
const { pos, suffix } = ensureEmptyLine(view.state, range) const { pos, suffix } = ensureEmptyLine(view.state, range)
const graphicxCommand = `\\includegraphics[width=${width}\\linewidth]{${path}}` const graphicxCommand = `\\includegraphics[width=${width}\\linewidth]{${path}}`
const changes: ChangeSpec = view.state.changes({ const changes: ChangeSpec = view.state.changes({
insert: `\\begin{figure}\n\\centering\n${graphicxCommand}\n${captionCommand}${labelCommand}${ insert: `\\begin{figure}\n\\centering\n${graphicxCommand}${captionCommand}${labelCommand}${
labelCommand || captionCommand ? '\n' : '' // Add an extra newline if we've added a caption or label labelCommand || captionCommand ? '\n' : '' // Add an extra newline if we've added a caption or label
}\\end{figure}${suffix}`, }\\end{figure}${suffix}`,
from: pos, from: pos,

View file

@ -187,20 +187,30 @@ const SelectFile = <T extends { path: string }>({
disabled, disabled,
files, files,
onSelectedItemChange, onSelectedItemChange,
defaultText = 'Select a file',
label = 'Image file',
loading = false,
}: { }: {
disabled: boolean disabled: boolean
files?: T[] files?: T[] | null
defaultText?: string
label?: string
loading?: boolean
onSelectedItemChange?: (item: T | null | undefined) => any onSelectedItemChange?: (item: T | null | undefined) => any
}) => { }) => {
const imageFiles = useMemo(() => files?.filter(isImageEntity), [files]) const imageFiles = useMemo(() => files?.filter(isImageEntity), [files])
const empty = loading || !imageFiles || imageFiles.length === 0
return ( return (
<Select <Select
loading={loading}
items={imageFiles ?? []} items={imageFiles ?? []}
itemToString={file => (file ? file.path.replace(/^\//, '') : '')} itemToString={file => (file ? file.path.replace(/^\//, '') : '')}
itemToKey={file => file.path} itemToKey={file => file.path}
defaultText="Select a file" defaultText={
label="Image file" imageFiles?.length === 0 ? 'No image files found' : defaultText
disabled={disabled} }
label={label}
disabled={disabled || empty}
onSelectedItemChanged={onSelectedItemChange} onSelectedItemChanged={onSelectedItemChange}
/> />
) )
@ -219,8 +229,9 @@ const SelectFromProject: FC<{
}, [error, dispatch]) }, [error, dispatch])
return ( return (
<SelectFile <SelectFile
files={entities ?? []} files={entities}
disabled={loading || !projectId} loading={loading}
disabled={!projectId}
onSelectedItemChange={onSelectedItemChange} onSelectedItemChange={onSelectedItemChange}
/> />
) )
@ -239,8 +250,11 @@ const SelectFromProjectOutputFiles: FC<{
}, [error, dispatch]) }, [error, dispatch])
return ( return (
<SelectFile <SelectFile
files={entities ?? []} label="Output file"
disabled={loading || !projectId} defaultText="Select an output file"
loading={loading}
files={entities}
disabled={!projectId}
onSelectedItemChange={onSelectedItemChange} onSelectedItemChange={onSelectedItemChange}
/> />
) )

View file

@ -11,13 +11,16 @@ export const FigureModalCurrentProjectSource: FC = () => {
[rootFolder] [rootFolder]
) )
const { dispatch } = useFigureModalContext() const { dispatch } = useFigureModalContext()
const noFiles = files?.length === 0
return ( return (
<Select <Select
items={files || []} items={files || []}
itemToString={file => (file ? file.name : '')} itemToString={file => (file ? file.name : '')}
itemToSubtitle={item => item?.path ?? ''} itemToSubtitle={item => item?.path ?? ''}
itemToKey={item => item.id} itemToKey={item => item.id}
defaultText="Select image from project files" defaultText={
noFiles ? 'No image files found' : 'Select image from project files'
}
label="Image file" label="Image file"
onSelectedItemChanged={item => { onSelectedItemChanged={item => {
dispatch({ dispatch({

View file

@ -77,9 +77,10 @@ export const markDecorations = ViewPlugin.define(
}).range(nodeRef.from, nodeRef.to) }).range(nodeRef.from, nodeRef.to)
) )
} }
} else if (nodeRef.type.is('Caption')) { } else if (nodeRef.type.is('Caption') || nodeRef.type.is('Label')) {
// decorate caption lines with a class, for styling const type = nodeRef.type.is('Caption') ? 'caption' : 'label'
const argument = nodeRef.node.getChild('TextArgument') // decorate caption and label lines with a class, for styling
const argument = nodeRef.node.getChild('$Argument')
if (argument) { if (argument) {
const lines = { const lines = {
@ -95,7 +96,7 @@ export const markDecorations = ViewPlugin.define(
const line = state.doc.line(lineNumber) const line = state.doc.line(lineNumber)
decorations.push( decorations.push(
Decoration.line({ Decoration.line({
class: 'ol-cm-caption-line', class: `ol-cm-${type}-line`,
}).range(line.from) }).range(line.from)
) )
} }

View file

@ -241,9 +241,13 @@ export const visualTheme = EditorView.theme({
overflowWrap: 'break-word', overflowWrap: 'break-word',
hyphens: 'auto', hyphens: 'auto',
}, },
'.ol-cm-environment-centered.ol-cm-caption-line': { '.ol-cm-environment-centered': {
padding: '0 10%', '&.ol-cm-label-line, &.ol-cm-caption-line': {
textAlign: 'center', textAlign: 'center',
},
'&.ol-cm-caption-line': {
padding: '0 10%',
},
}, },
'.ol-cm-caption-line .ol-cm-label': { '.ol-cm-caption-line .ol-cm-label': {
marginRight: '1ch', marginRight: '1ch',

View file

@ -21,7 +21,7 @@ export class EditableGraphicsWidget extends GraphicsWidget {
updateDOM(element: HTMLImageElement, view: EditorView): boolean { updateDOM(element: HTMLImageElement, view: EditorView): boolean {
if ( if (
this.filePath === element.dataset.filepath && this.filePath === element.dataset.filepath &&
element.dataset.width === this.figureData?.width?.toString() element.dataset.width === String(this.figureData?.width?.toString())
) { ) {
// Figure remained the same, so just update the event listener on the button // Figure remained the same, so just update the event listener on the button
this.setEditDispatcher( this.setEditDispatcher(

View file

@ -50,7 +50,7 @@ export class GraphicsWidget extends WidgetType {
element.classList.toggle('ol-cm-environment-centered', this.centered) element.classList.toggle('ol-cm-environment-centered', this.centered)
if ( if (
this.filePath === element.dataset.filepath && this.filePath === element.dataset.filepath &&
element.dataset.width === this.figureData?.width?.toString() element.dataset.width === String(this.figureData?.width?.toString())
) { ) {
return true return true
} }

View file

@ -14,6 +14,7 @@ type SelectProps<T> = {
onSelectedItemChanged?: (item: T | null | undefined) => void onSelectedItemChanged?: (item: T | null | undefined) => void
disabled?: boolean disabled?: boolean
optionalLabel?: boolean optionalLabel?: boolean
loading?: boolean
} }
export const Select = <T,>({ export const Select = <T,>({
@ -26,6 +27,7 @@ export const Select = <T,>({
onSelectedItemChanged, onSelectedItemChanged,
disabled = false, disabled = false,
optionalLabel = false, optionalLabel = false,
loading = false,
}: SelectProps<T>) => { }: SelectProps<T>) => {
const { const {
isOpen, isOpen,
@ -54,7 +56,8 @@ export const Select = <T,>({
<span className="select-optional-label text-muted"> <span className="select-optional-label text-muted">
(Optional) (Optional)
</span> </span>
)} )}{' '}
{loading && <Icon fw type="spinner" spin />}
</label> </label>
) : null} ) : null}
<div <div