]> _ Git - fluidbook-toolbox.git/commitdiff
wait #7993 @18:00 moveMarkdown
authorsoufiane <soufiane@cubedesigners.com>
Thu, 19 Feb 2026 10:20:24 +0000 (11:20 +0100)
committersoufiane <soufiane@cubedesigners.com>
Thu, 19 Feb 2026 10:20:24 +0000 (11:20 +0100)
app/Http/Controllers/Admin/Operations/FluidbookPublication/MarkdownOperation.php
resources/markdowneditor/js/markdowneditor.js
resources/markdowneditor/js/markdowneditor.popup.js [new file with mode: 0644]
resources/markdowneditor/js/markdowneditor.resize.js [new file with mode: 0644]
resources/markdowneditor/style/inc/_form.sass [new file with mode: 0644]
resources/markdowneditor/style/inc/_popup.sass [new file with mode: 0644]
resources/markdowneditor/style/inc/_variables.sass [new file with mode: 0644]
resources/markdowneditor/style/style.sass
resources/views/fluidbook_publication/markdown_editor.blade.php

index e737743d4a6f0d2ee11450c9b689fa663ddf9d86..011022e92378a1d5caac1aeeee65fe6802f3e71d 100644 (file)
@@ -6,6 +6,7 @@ use App\Fluidbook\Link\LinksData;
 use App\Models\FluidbookPublication;
 use App\Models\User;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Redirect;
 use Illuminate\Support\Facades\Route;
 use Illuminate\Support\Str;
 use Cubist\Util\Files\Files;
@@ -22,6 +23,7 @@ trait MarkdownOperation
         Route::match(['get'], $segment . '/{id}/markdown', $controller . '@getFilesById');
         Route::match(['put'], $segment . '/{id}/save/markdown', $controller . '@saveMarkdown');
         Route::match(['get'], $segment . '/{id}/import/markdown', $controller . '@importMarkdown');
+        Route::match(['post'], $segment . '/{id}/edit/markdown/move', $controller . '@moveMarkdown');
     }
 
     public function markdown($id)
@@ -174,4 +176,42 @@ trait MarkdownOperation
 
         return response()->json(['success' => $md['pages']]);
     }
+
+    protected function moveMarkdown($fluidbook_id) {
+        if (!FluidbookPublication::hasPermission($fluidbook_id)) {
+            abort(401);
+        }
+
+        $offset = intval(request('number', 1));
+        $from = intval(request('start', 0));
+
+        $markdown = $this->getLatestMarkdown($fluidbook_id)['pages'];
+
+        $newOrder = [];
+        $newKey = 1;
+
+        $newOrder = array_slice($markdown, 0, $from > 1 ? $from - 1 : $from,true);
+        $markdown = array_slice($markdown, $from > 1 ? $from - 1 : $from, count($markdown), true);
+
+        foreach ($markdown as $k => $m) {
+
+            if ($offset < 0) {
+                $k -= abs($offset);
+            } else {
+                $k += $offset;
+            }
+
+            if(!array_key_exists($newKey,$newOrder)) {
+                $newOrder[$newKey] = "";
+            }
+
+            $newOrder["".$k] = $m;
+            $newKey++;
+        }
+
+        ksort($newOrder);
+
+        $this->saveMarkdown($fluidbook_id, __('Décalage de :nb pages à partir de la page :page', ['nb' => $offset, 'page' => $from, 'date' => date('Y-m-d H:i:s')]), $newOrder);
+        return Redirect::back();
+    }
 }
index f181745fc9a82ea82b00e17a8c37cc622db2d92a..b385525fab69e4144a56c242f56179764fea340b 100644 (file)
@@ -5,6 +5,8 @@ import MarkdowneditorUndo from "./markdowneditor.undo";
 import MarkdowneditorSave from "./markdowneditor.save";
 import MarkdowneditorVersions from "./markdowneditor.versions";
 import MarkdowneditorZoom from "./markdowneditor.zoom";
+import MarkdowneditorPopup from "./markdowneditor.popup";
+import MarkdowneditorResize from "./markdowneditor.resize";
 
 import tippy from "tippy.js";
 import 'tippy.js/dist/tippy.css';
@@ -12,6 +14,7 @@ import 'tippy.js/dist/tippy.css';
 import Noty from "noty";
 import 'noty/lib/noty.css';
 import 'noty/lib/themes/mint.css';
+import LinkeditorPopup from "../../linkeditor/js/linkeditor.popup";
 
 window.$ = window.jQuery = require('jquery');
 window.key = require('keymaster-reloaded');
@@ -60,9 +63,11 @@ MarkdownEditor.prototype = {
     init: function() {
         new MarkdowneditorToolbar(this);
         this.undo = new MarkdowneditorUndo(this);
+        this.resize = new MarkdowneditorResize(this);
         this.save = new MarkdowneditorSave(this);
         this.versions = new MarkdowneditorVersions(this);
         this.zoom = new MarkdowneditorZoom(this);
+        this.popup = new MarkdowneditorPopup(this);
 
         this.options = {
             el: document.querySelector('#editor'),
diff --git a/resources/markdowneditor/js/markdowneditor.popup.js b/resources/markdowneditor/js/markdowneditor.popup.js
new file mode 100644 (file)
index 0000000..0594713
--- /dev/null
@@ -0,0 +1,53 @@
+function MarkdowneditorPopup(markdowneditor) {
+    this.markdowneditor = markdowneditor;
+    this.init();
+}
+
+MarkdowneditorPopup.prototype = {
+    init: function () {
+        var $this = this;
+        $(document).on('click', '.popup .close', function () {
+            if ($this.hasOpenPopup()) {
+                $this.close();
+            }
+        });
+    },
+
+    openLinksMove() {
+        this.open('moveLinks');
+    },
+
+    open: function (name) {
+        var clone = $("#popup-templates [data-popup=" + name + "]").clone();
+        $("#popup-holder").append(clone);
+        $("#popup-overlay").addClass('show');
+        this.resize();
+    },
+
+    close: function (name = '') {
+        $("#popup-overlay").removeClass('show');
+        $("#popup-holder").html('');
+    },
+
+    hasOpenPopup() {
+        return $("#popup-overlay.show").length === 1;
+    },
+
+    resize: function () {
+        if (!this.hasOpenPopup()) {
+            return;
+        }
+        var p = $("#popup-holder>div");
+        var w = $(p).outerWidth();
+        var h = $(p).outerHeight();
+        var left = (this.markdowneditor.resize.ww - w) / 2;
+        var top = (this.markdowneditor.resize.hh - h) / 2;
+        $("#popup-holder").css({
+            width: w,
+            height: h,
+            left: left,
+            top: top,
+        })
+    }
+};
+export default  MarkdowneditorPopup;
diff --git a/resources/markdowneditor/js/markdowneditor.resize.js b/resources/markdowneditor/js/markdowneditor.resize.js
new file mode 100644 (file)
index 0000000..6e63465
--- /dev/null
@@ -0,0 +1,127 @@
+function MarkdowneditorResize(markdowneditor) {
+    this.markdowneditor = markdowneditor;
+    this.init();
+}
+
+MarkdowneditorResize.prototype = {
+    init: function () {
+        var $this = this;
+        $(window).on('resize', function () {
+            $this.resize();
+            setTimeout(function () {
+                $this.resize();
+            }, 100);
+        });
+        this.updateWindowDimensions();
+    },
+
+    updateWindowDimensions: function () {
+        this.ww = $(window).outerWidth();
+        this.hh = $(window).outerHeight();
+    },
+
+    resize: function () {
+        let special = this.markdowneditor.utils.isSpecialPage();
+        if (this.markdowneditor.single || special) {
+            $("#markdowneditor").addClass('single').removeClass('double');
+        } else {
+            $("#markdowneditor").addClass('double').removeClass('single');
+        }
+        this.resizePages();
+        this.updateWindowDimensions();
+        this.resizeMain();
+        this.resizeCanvas();
+        if (this.markdowneditor.panels) {
+            this.markdowneditor.panels.resize(this.ww);
+        }
+        this.markdowneditor.rulers.updateRulers();
+        if (this.markdowneditor.popup) {
+            this.markdowneditor.popup.resize();
+        }
+        let width = $("#markdowneditor-fluidbook").css("width")
+        let height = $("#markdowneditor-fluidbook").css("height")
+        let transform = $("#markdowneditor-fluidbook").css("transform")
+        let left_ = $("#markdowneditor-fluidbook").css("left")
+        let top_ = $("#markdowneditor-fluidbook").css("top")
+
+        $("#markdowneditor-layer-links").css({
+            'width':width,
+            'height':height,
+            'left':left_,
+            'top':top_,
+            'transform':transform,
+        })
+        //this.markdowneditor.previewLinks.setPreview()
+    },
+
+    resizePages: function () {
+        let $this = this;
+        let dimCover = $this.markdowneditor.utils.getPageDimensions(1);
+        let pw;
+        let ph;
+        let special = false;
+
+        $(".markdowneditor-page[data-page]:visible").each(function () {
+            let p = $(this).attr('data-page');
+            let dim = $this.markdowneditor.utils.getPageDimensions(p);
+            if (dim === undefined) {
+                dim = dimCover;
+            }
+            pw = dim[0];
+            ph = dim[1];
+
+            if ($this.markdowneditor.utils.isSpecialPage(p)) {
+                special = true;
+            } else if ($this.markdowneditor.mobileFirst) {
+                pw = dimCover[0];
+            } else {
+                pw = dimCover[0];
+                ph = dimCover[1];
+            }
+            $(this).css({width: pw, height: ph});
+        });
+
+        let fw = pw;
+        if (!this.markdowneditor.single && !special) {
+            fw *= 2;
+        }
+        $("#markdowneditor-page-right").css({left: this.markdowneditor.pw});
+        $("#markdowneditor-fluidbook,#markdowneditor-layer-links,.markdowneditor-fluidbook-copy").css({width: fw, height: ph});
+    },
+
+    resizeMain: function () {
+        $("#markdowneditor-main").css('width', this.ww - $('#markdowneditor-left').outerWidth() - $('#markdowneditor-right').outerWidth());
+    },
+
+    resizeCanvas: function () {
+        this.markdowneditor.canvasRect = $("#markdowneditor-canvas").get(0).getBoundingClientRect();
+        this.markdowneditor.editorRect = $("#markdowneditor-editor").get(0).getBoundingClientRect();
+        var aw = this.markdowneditor.canvasRect.width - 30;
+        var ah = this.markdowneditor.canvasRect.height - 30;
+
+        if (this.markdowneditor.utils.isSpecialPage()) {
+            let dim = this.markdowneditor.utils.getPageDimensions();
+            this.markdowneditor.fs = Math.min(1, aw / dim[0], ah / dim[1]);
+        } else if (this.markdowneditor.mobileFirst) {
+            this.markdowneditor.fs = 620 / this.markdowneditor.fw;
+        } else {
+            this.markdowneditor.fs = Math.min(aw / this.markdowneditor.fw, ah / this.markdowneditor.fh);
+        }
+
+        let left, top;
+
+        if (this.markdowneditor.utils.isSpecialPage()) {
+            let dim = this.markdowneditor.utils.getPageDimensions();
+            left = (this.markdowneditor.canvasRect.width - (dim[0] * this.markdowneditor.fs)) / 2;
+            top = (this.markdowneditor.canvasRect.height - (dim[1] * this.markdowneditor.fs)) / 2;
+        } else if (!this.markdowneditor.mobileFirst) {
+            left = ((this.markdowneditor.canvasRect.width * 2) - this.markdowneditor.fw * this.markdowneditor.fs) / 2;
+            top = ((this.markdowneditor.canvasRect.height * 2) - this.markdowneditor.fh * this.markdowneditor.fs) / 2;
+        } else {
+            left = (this.markdowneditor.canvasRect.width - this.markdowneditor.fw * this.markdowneditor.fs) / 2;
+            top = 75;
+        }
+        $("#markdowneditor-fluidbook,#markdowneditor-layer-links").css({left: left, top: top, transform: 'scale(' + this.markdowneditor.fs + ')'});
+    },
+};
+export default MarkdowneditorResize;
diff --git a/resources/markdowneditor/style/inc/_form.sass b/resources/markdowneditor/style/inc/_form.sass
new file mode 100644 (file)
index 0000000..77953ba
--- /dev/null
@@ -0,0 +1,303 @@
+body
+    --form-text-color: #5d5d5d
+    --field-background: #fff
+    --field-color: #bbb
+    --field-border: #aaa
+    --field-border-background: #fff
+    --field-color-button: #bbb
+    --field-border-button: #aaa
+
+    @include dark-theme
+        --form-text-color: #aaa
+        --field-background: #fff
+        --field-color: #bbb
+        --field-border: #ccc
+        --field-background-button: #000
+        --field-color-button: #ccc
+        --field-border-button: #bbb
+
+textarea, input[type="text"], input[type="number"], input[type="email"], input[type="url"], input[type="tel"]
+    font-family: $font
+    font-weight: 400
+    color: var(--field-color)
+    background-color: var(--field-background)
+    border: 1px solid var(--field-border)
+    border-radius: 3px
+    font-size: 13px
+    transition: box-shadow 500ms, border 500ms
+    appearance: none
+
+    &:focus
+        border: 1px solid var(--field-border)
+        box-shadow: 0 0 8px rgba(0, 0, 0, 0.3)
+
+input[type="checkbox"]
+    margin-right: 8px
+    appearance: none
+    position: relative
+    cursor: pointer
+    color: var(--form-text-color)
+
+    &::before
+        content: ''
+        display: inline-block
+        width: 14px
+        height: 14px
+        border: 1px solid currentColor
+        border-radius: 2px
+        vertical-align: baseline
+
+    &:checked
+        &::after
+            content: ''
+            display: block
+            width: 12px
+            height: 12px
+            position: absolute
+            top: 1px
+            left: 1px
+            clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%)
+            background-color: currentColor
+
+
+input[type=number]
+    &, &:hover
+        appearance: textfield
+
+        &::-webkit-inner-spin-button, &::-webkit-outer-spin-button
+            -webkit-appearance: none
+            margin: 0
+            visibility: hidden
+
+button
+    font-family: $font
+    font-weight: 500
+    font-size: 15px
+    padding: 5px 10px
+    border: 1px solid var(--field-border-button)
+    border-radius: 4px
+    color: var(--field-color-button)
+    background-color: var(--field-background-button)
+    cursor: pointer
+
+.select2-hidden-accessible
+    position: fixed !important
+
+#linkeditor-form-templates
+    display: none
+
+.linkeditor-linktype
+    &::before
+        display: inline-block
+        width: 12px
+        height: 12px
+        border-radius: 2px
+        margin: 2px 10px 0 0
+        content: ""
+        vertical-align: top
+        position: relative
+
+
+#linkeditor-panel-form
+
+
+    padding: 12px
+    font-size: 13px
+
+    .select2-container--bootstrap
+        font-size: 13px
+        font-weight: 400
+
+        hr
+            border: 0
+            height: 1px
+            background-color: var(--form-text-color)
+            margin: 5px 0
+
+        &, .select2-selection
+            color: var(--form-text-color)
+            background-color: var(--field-background)
+            border-color: var(--field-background)
+            border-radius: 4px
+            box-shadow: none
+
+        &.select2-container--focus .select2-selection, &.select2-container--open .select2-selection
+            box-shadow: 0 0 8px rgba(0, 0, 0, 0.1)
+            border-color: var(--field-border)
+
+    h3
+        font-size: 16px
+        color: var(--form-text-color)
+        text-transform: uppercase
+        padding-top: 15px
+        border-top: 1px solid var(--form-text-color)
+        margin-top: 20px
+
+    p.help-block
+        color: var(--form-text-color)
+        font-size: 11px
+        padding-top: 2px
+        white-space: normal
+
+    .freefile-file
+        position: relative
+
+        &.loading
+            &::after
+                background-image: url("/images/linkeditor/dots-animated.svg")
+                @include dark-theme
+                    background-image: url("/images/linkeditor/dots-dark-animated.svg")
+
+            input
+                pointer-events: none
+                cursor: wait
+
+        &::after
+            content: ""
+            position: absolute
+            display: block
+            padding: 6px
+            right: 0
+            top: 6px
+            width: 25px
+            height: 25px
+            background-image: url("/images/linkeditor/dots.svg")
+            color: var(--field-color)
+            box-sizing: border-box
+            pointer-events: none
+            font-size: 17px
+            @include dark-theme
+                background-image: url("/images/linkeditor/dots-dark.svg")
+
+        input[type=file]
+            position: absolute
+            right: 0
+            width: 35px
+            opacity: 0
+            height: 100%
+            cursor: pointer
+
+        a.upload
+            position: absolute
+            right: 0
+            width: 35px
+            opacity: 0
+            height: 100%
+            cursor: pointer
+            z-index: 2
+
+
+    .input-group
+        position: relative
+
+        .input-group-append
+            position: absolute
+            height: 100%
+            top: 0
+            right: 0
+            pointer-events: none
+            padding: 8px
+
+    textarea, input[type="text"], input[type="number"], input[type="email"], input[type="url"], input[type="tel"]
+        height: 34px
+        padding: 8px
+        width: 100%
+
+    textarea
+        height: auto
+        min-height: 150px
+        max-width: 100%
+        min-width: 100%
+
+    span
+        font-weight: 400
+        font-size: 13px
+        color: var(--form-text-color)
+
+    label
+        display: block
+        font-weight: 600
+        font-size: 12px
+        color: var(--form-text-color)
+        margin: 8px 0 5px 0
+
+    .checkbox
+        margin: 4px 0 5px 0
+
+        position: relative
+        top: 6px
+
+        label
+            vertical-align: baseline
+            display: inline-block
+            position: relative
+            top: -4px
+            margin: 0
+            cursor: pointer
+
+        span
+            margin-left: 5px
+
+
+    #group_position, #group_dimensions, #group_transform
+        margin-top: 5px
+
+        h4
+            font-size: 12px
+            font-weight: 700
+            color: var(--form-text-color)
+            grid-column: 1 / 3
+            grid-row: 1 / 2
+            margin-bottom: 5px
+
+        display: grid
+        grid-template-columns: repeat( 2, 1fr)
+        grid-gap: 2px 25px
+
+        label
+            display: inline-block
+            width: 20px
+
+        input
+            width: calc(100% - 20px)
+
+        [data-name="rot"]
+            label
+                display: block
+
+            .input-group
+                .input-group-append
+                    right: 0
+
+        .input-group
+            display: inline-block
+
+            .input-group-append
+                right: 20px
+
+
+    #group_transform
+        input
+            width: 100%
+
+.select2-container--bootstrap .select2-results > .select2-results__options
+    max-height: 350px !important
+
+
+[data-name='image_rollover'] label
+    display: flex !important
+    align-items: end
+    justify-content: space-between
+
+#linkeditor-start-animation
+    display: flex
+    width: 26px
+    height: 26px
+    background: transparent
+    padding: 4px 4px
+    border: 0
+    &:hover
+        background-color: #000
+    svg
+        width: 100%
+        fill: transparent
diff --git a/resources/markdowneditor/style/inc/_popup.sass b/resources/markdowneditor/style/inc/_popup.sass
new file mode 100644 (file)
index 0000000..ce08b17
--- /dev/null
@@ -0,0 +1,67 @@
+#popup-templates
+    display: none
+
+#popup-overlay
+    background-color: rgba(0, 0, 0, 0.5)
+    position: absolute
+    top: 0
+    left: 0
+    opacity: 0
+    pointer-events: none
+    transition: opacity 350ms
+    width: 100%
+    height: 100%
+    z-index: 10000000
+
+    &.show,
+    &.unavailable
+        opacity: 1
+        pointer-events: auto
+
+    #popup-holder
+        position: absolute
+        max-width: 100%
+        max-height: 100%
+
+        .popup
+            background-color: #dbdddf
+            color: #5D5D5D
+            font-size: 13px
+            padding: 20px
+            box-shadow: 0 0 20px rgba(0,0,0,0.5)
+
+            h2
+                font-size: 16px
+                padding-bottom: 10px
+                font-weight: 500
+                margin: 0
+
+            a.close
+                display: block
+                position: absolute
+                top: 20px
+                right: 20px
+                width: 15px
+                height: 15px
+                cursor: pointer
+
+            p
+                margin: 12px 0
+                white-space: normal
+
+            p.button
+                text-align: right
+                margin: 20px 0 0 0
+
+
+            @include dark-theme
+                background-color: #333
+                color: #d5d5d5
+
+            &[data-popup="moveLinks"]
+                input
+                    &[type="text"],&[type="number"]
+                        width: 50px
+                        height: 20px
+                        margin: 0 5px
+                        padding: 4px
diff --git a/resources/markdowneditor/style/inc/_variables.sass b/resources/markdowneditor/style/inc/_variables.sass
new file mode 100644 (file)
index 0000000..2246963
--- /dev/null
@@ -0,0 +1,18 @@
+$font: Montserrat, sans-serif
+$font-size: 16px
+$sidebar-icons-width: 46px
+$sidebar-handle-width: 3px
+$rulers-size: 16px
+$ruler-margin: 2px
+
+$toolbar-height: 40px
+$toolbar-color: #5d5d5d
+$toolbar-color-dark: #bbb
+
+$toolbar-color-disabled: #bbb
+$toolbar-color-disabled-dark: #666
+
+$panel-background: #dcdcdc
+
+$color: #5d5d5d
+$color-dark: #bbb
index 975ebae57a8996b5a6d2dd116524e069bc473f0b..b90d433bdbd50af18afa30393ae9b2095b28842c 100644 (file)
@@ -330,3 +330,7 @@ input::-webkit-inner-spin-button
                 @include dark-theme
                     background-color: #222 !important
                     border-top-color: #222 !important
+
+@import "inc/_variables"
+@import "inc/_form"
+@import "inc/_popup"
index 4ff80b9e49e46bfc52b7314786eb89f31f662472..b0f78eb453962064932dd86a25806950ee746b5a 100644 (file)
 
 @section('content')
     @include('fluidbook_publication.link_editor_icons')
+    <div id="popup-overlay">
+        <div id="popup-holder">
+        </div>
+    </div>
+    <div id="popup-templates">
+        <div class="popup" data-popup="moveLinks" style="max-width: 300px">
+            <h2>{{__('Déplacer le contenu')}}</h2>
+            <a nohref="" class="close" data-icon="close"></a>
+            <form action="/fluidbook-publication/{{$fbdata['id']}}/edit/markdown/move"
+                  data-save-before-submit="{{__("Sauvegarde avant le déplacement de liens")}}"
+                  class="reloadAfterSuccess" method="post">
+                @csrf
+                <p>{!! __('Déplacer le contenu de :nb pages :br à partir de la page :page',
+                    ['br'=>'</p><p>','nb'=>'<input type="number" name="number">','page'=>'<input type="text" name="start">'])!!}</p>
+                <p class="button">
+                    <button type="submit">{{__('Déplacer le contenu')}}</button>
+                </p>
+            </form>
+        </div>
+    </div>
     <div class="markdown">
         <div id="markdown-revision" class="markdown-revision">
             <div class="markdown-revision-nav">
                 <a href="#" id="linkeditor-icon-versions" data-panel="form" data-icon="wayback-machine"
                    data-action="toggleRevisions"
-                   data-tooltip="{{__('Restaurer une version précédente')}} (F8)" data-key="f8"></a>
+                   data-tooltip="{{__('Paramètres du lien')}} (F8)" data-key="f8"></a>
             </div>
             <div class="markdown-revision-panel">
                 <div id="markdown-panel-versions">
         <div class="markdown-editor">
             <div class="markdown-nav markdown-toolbar">
                 <nav class="markdown-toolbar-left" id="markdown-toolbar-left">
-                    <div class="markdown-toolbar-save-block">
+                    <div class="loading-block markdown-toolbar-save-block">
                         <a href="#" data-icon="save" data-action="save.save" data-tooltip="{{__('Sauvegarder')}} (Ctrl+S)"
-                           ></a>
+                           data-key="ctrl+s"></a>
                         <a nohref data-icon="loading" class=""></a>
                     </div>
                     <a href="#" data-icon="undo" data-action="undo.undo"
                     <div class="separator"></div>
                 </nav>
                 <nav class="markdown-toolbar-center" id="markdown-toolbar-center">
+                    <a href="#" data-action="popup.openLinksMove" data-icon="move-links"
+                       data-tooltip="{{__('Déplacer les liens')}}" tabindex="-1"></a>
                     <a href="#" data-action="firstPage" data-icon="first-page"
                        data-tooltip="{{__('Aller à la couverture')}}"></a>
                     <a href="#" data-action="previousPage" data-icon="previous-page"
                     <a href="#" data-action="lastPage" data-icon="last-page"
                        data-tooltip="{{__('Aller à la dernière page')}}"></a>
                     <div class="separator"></div>
-                    <a href="#" data-action="importMarkdown" data-icon="import-markdown"
-                       data-tooltip="{{__('Réimporter les contenus à partir du PDF')}}"></a>
+                    <div class="loading-block">
+                        <a href="#" data-action="importMarkdown" data-icon="import-markdown"
+                           data-tooltip="{{__('Importer le markdown')}}"></a>
+                        <a nohref data-icon="loading" class=""></a>
+                    </div>
+                    <div class="loading-block">
+                        <a href="#" data-action="importSingleMarkdown" data-icon="import-single-markdown"
+                           data-tooltip="{{__('Importer le markdown de la page courante')}}">
+                        </a>
+                        <a nohref data-icon="loading" class=""></a>
+                    </div>
                     <a href="#" data-action="openFluidbook" data-icon="open-fluidbook"
                        data-tooltip="{{__('Ouvrir le fluidbook à la page courante')}}"></a>
                 </nav>