mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
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:
parent
234eb31ffb
commit
f747cb000f
8 changed files with 50 additions and 25 deletions
|
@ -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,
|
||||||
|
|
|
@ -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}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue