Просмотр исходного кода

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

[cm6+rt] Figure Modal alpha rollout changes

GitOrigin-RevId: f7591893e8f74aa9c9b41f4b98babecaac4b3c8c
Mathias Jakobsen 3 лет назад
Родитель
Сommit
f747cb000f

+ 6 - 6
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,

+ 22 - 8
services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-other-project-source.tsx

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

+ 4 - 1
services/web/frontend/js/features/source-editor/components/figure-modal/file-sources/figure-modal-project-source.tsx

@@ -11,13 +11,16 @@ export const FigureModalCurrentProjectSource: FC = () => {
     [rootFolder]
   )
   const { dispatch } = useFigureModalContext()
+  const noFiles = files?.length === 0
   return (
     <Select
       items={files || []}
       itemToString={file => (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({

+ 5 - 4
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)
                   )
                 }

+ 7 - 3
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',

+ 1 - 1
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(

+ 1 - 1
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
     }

+ 4 - 1
services/web/frontend/js/shared/components/select.tsx

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