diff --git a/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal.tsx b/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal.tsx index 7b6bd6685c..69e4d1fa78 100644 --- a/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal.tsx +++ b/services/web/frontend/js/features/source-editor/components/figure-modal/figure-modal.tsx @@ -122,8 +122,8 @@ const FigureModalContent = () => { dispatch({ error: String(error) }) return } - const labelCommand = includeLabel ? '\\label{fig:enter-label}' : '' - const captionCommand = includeCaption ? '\\caption{Enter Caption}' : '' + const labelCommand = includeLabel ? '\n\\label{fig:enter-label}' : '' + const captionCommand = includeCaption ? '\n\\caption{Enter Caption}' : '' if (figure) { // Updating existing figure @@ -133,15 +133,15 @@ const FigureModalContent = () => { if (!hadCaptionBefore && includeCaption) { // We should insert a caption changes.push({ - from: figure.label?.from ?? figure.graphicsCommand.to, - insert: (figure.label ? '' : '\n') + captionCommand, + from: figure.graphicsCommand.to, + insert: captionCommand, }) } if (!hadLabelBefore && includeLabel) { // We should insert a label changes.push({ from: figure.caption?.to ?? figure.graphicsCommand.to, - insert: (includeCaption ? '' : '\n') + labelCommand, + insert: labelCommand, }) } if (hadCaptionBefore && !includeCaption) { @@ -187,7 +187,7 @@ const FigureModalContent = () => { const { pos, suffix } = ensureEmptyLine(view.state, range) const graphicxCommand = `\\includegraphics[width=${width}\\linewidth]{${path}}` 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 }\\end{figure}${suffix}`, from: pos, diff --git a/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx b/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx index b9b12d2ba4..85d25f37ca 100644 --- a/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx +++ b/services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx @@ -187,20 +187,30 @@ const SelectFile = ({ disabled, files, onSelectedItemChange, + defaultText = 'Select a file', + label = 'Image file', + loading = false, }: { disabled: boolean - files?: T[] + files?: T[] | null + defaultText?: string + label?: string + loading?: boolean onSelectedItemChange?: (item: T | null | undefined) => any }) => { const imageFiles = useMemo(() => files?.filter(isImageEntity), [files]) + const empty = loading || !imageFiles || imageFiles.length === 0 return ( (file ? file.name : '')} itemToSubtitle={item => item?.path ?? ''} itemToKey={item => item.id} - defaultText="Select image from project files" + defaultText={ + noFiles ? 'No image files found' : 'Select image from project files' + } label="Image file" onSelectedItemChanged={item => { dispatch({ diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts b/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts index 878e4f06f1..26f69a8ad8 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/mark-decorations.ts @@ -77,9 +77,10 @@ export const markDecorations = ViewPlugin.define( }).range(nodeRef.from, nodeRef.to) ) } - } else if (nodeRef.type.is('Caption')) { - // decorate caption lines with a class, for styling - const argument = nodeRef.node.getChild('TextArgument') + } else if (nodeRef.type.is('Caption') || nodeRef.type.is('Label')) { + const type = nodeRef.type.is('Caption') ? 'caption' : 'label' + // decorate caption and label lines with a class, for styling + const argument = nodeRef.node.getChild('$Argument') if (argument) { const lines = { @@ -95,7 +96,7 @@ export const markDecorations = ViewPlugin.define( const line = state.doc.line(lineNumber) decorations.push( Decoration.line({ - class: 'ol-cm-caption-line', + class: `ol-cm-${type}-line`, }).range(line.from) ) } diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts b/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts index 0d3b08fa91..4768201918 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/visual-theme.ts @@ -241,9 +241,13 @@ export const visualTheme = EditorView.theme({ overflowWrap: 'break-word', hyphens: 'auto', }, - '.ol-cm-environment-centered.ol-cm-caption-line': { - padding: '0 10%', - textAlign: 'center', + '.ol-cm-environment-centered': { + '&.ol-cm-label-line, &.ol-cm-caption-line': { + textAlign: 'center', + }, + '&.ol-cm-caption-line': { + padding: '0 10%', + }, }, '.ol-cm-caption-line .ol-cm-label': { marginRight: '1ch', diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/editable-graphics.ts b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/editable-graphics.ts index 6b86b86d0f..129f03132b 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/editable-graphics.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/editable-graphics.ts @@ -21,7 +21,7 @@ export class EditableGraphicsWidget extends GraphicsWidget { updateDOM(element: HTMLImageElement, view: EditorView): boolean { if ( 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 this.setEditDispatcher( diff --git a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/graphics.ts b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/graphics.ts index f7e2972b27..be9939c787 100644 --- a/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/graphics.ts +++ b/services/web/frontend/js/features/source-editor/extensions/visual/visual-widgets/graphics.ts @@ -50,7 +50,7 @@ export class GraphicsWidget extends WidgetType { element.classList.toggle('ol-cm-environment-centered', this.centered) if ( this.filePath === element.dataset.filepath && - element.dataset.width === this.figureData?.width?.toString() + element.dataset.width === String(this.figureData?.width?.toString()) ) { return true } diff --git a/services/web/frontend/js/shared/components/select.tsx b/services/web/frontend/js/shared/components/select.tsx index 0daf034352..a70448cffd 100644 --- a/services/web/frontend/js/shared/components/select.tsx +++ b/services/web/frontend/js/shared/components/select.tsx @@ -14,6 +14,7 @@ type SelectProps = { onSelectedItemChanged?: (item: T | null | undefined) => void disabled?: boolean optionalLabel?: boolean + loading?: boolean } export const Select = ({ @@ -26,6 +27,7 @@ export const Select = ({ onSelectedItemChanged, disabled = false, optionalLabel = false, + loading = false, }: SelectProps) => { const { isOpen, @@ -54,7 +56,8 @@ export const Select = ({ (Optional) - )} + )}{' '} + {loading && } ) : null}