Skip to content

Commit 103d8ef

Browse files
author
Vinicius Reis
committed
✨ (#2904): Able to show outiline in readonly mode
Signed-off-by: Vinicius Reis <vinicius.reis@nextcloud.com>
1 parent faab200 commit 103d8ef

File tree

9 files changed

+190
-75
lines changed

9 files changed

+190
-75
lines changed

css/print.scss

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@media print {
22
@page {
33
size: A4;
4-
margin: 2.5cm 2cm 2cm 2.5cm;
4+
margin: 2.5cm 2cm 2cm 2.5cm;
55
}
66

77
body {
@@ -81,4 +81,24 @@
8181
}
8282
}
8383
}
84-
}
84+
85+
.menubar-placeholder, .text-editor--readonly-bar {
86+
display: none;
87+
}
88+
89+
.text-editor__content-wrapper {
90+
&.--show-outline {
91+
display: block;
92+
}
93+
94+
.editor--outline {
95+
width: auto;
96+
height: auto;
97+
overflow: unset;
98+
position: relative;
99+
}
100+
.editor--outline__btn-close {
101+
display: none;
102+
}
103+
}
104+
}

css/prosemirror.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ div.ProseMirror {
8888
margin-top: 10px;
8989
}
9090

91+
> h1,h2,h3,h4,h5,h6 {
92+
&:first-child {
93+
margin-top: 0;
94+
}
95+
}
96+
9197
a {
9298
color: var(--color-primary-element);
9399
text-decoration: underline;

cypress/e2e/share.spec.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ describe('Open test.md in viewer', function() {
5555
cy.getContent()
5656
.should('contain', 'Hello world')
5757
.find('h2').should('contain', 'Hello world')
58+
59+
cy.get('.text-editor--readonly-bar')
60+
.getActionEntry('outline')
61+
.click()
62+
63+
cy.getOutline()
64+
.find('header')
65+
.should('exist')
5866
})
5967
})
6068

src/components/Editor.vue

Lines changed: 80 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,26 @@
3434
:content-loaded="contentLoaded"
3535
:show-author-annotations="showAuthorAnnotations">
3636
<MainContainer v-if="$editor">
37-
<MenuBar v-if="renderMenus"
38-
ref="menubar"
39-
:autohide="autohide"
40-
:loaded.sync="menubarLoaded">
41-
<Status :document="document"
42-
:dirty="dirty"
43-
:sessions="filteredSessions"
44-
:sync-error="syncError"
45-
:has-connection-issue="hasConnectionIssue"
46-
:last-saved-string="lastSavedString" />
47-
<slot name="header" />
48-
</MenuBar>
49-
<div v-if="!menubarLoaded" class="menubar-placeholder" />
37+
<!-- Readonly -->
38+
<div v-if="readOnly" class="text-editor--readonly-bar">
39+
<ReadonlyBar />
40+
</div>
41+
<!-- Rich Menu -->
42+
<template v-else>
43+
<MenuBar v-if="renderMenus"
44+
ref="menubar"
45+
:autohide="autohide"
46+
:loaded.sync="menubarLoaded">
47+
<Status :document="document"
48+
:dirty="dirty"
49+
:sessions="filteredSessions"
50+
:sync-error="syncError"
51+
:has-connection-issue="hasConnectionIssue"
52+
:last-saved-string="lastSavedString" />
53+
<slot name="header" />
54+
</MenuBar>
55+
<div v-else class="menubar-placeholder" />
56+
</template>
5057
<ContentContainer v-show="contentLoaded"
5158
ref="contentWrapper">
5259
<MenuBubble v-if="renderMenus"
@@ -84,6 +91,7 @@ import {
8491
IS_RICH_WORKSPACE,
8592
SYNC_SERVICE,
8693
} from './Editor.provider.js'
94+
import ReadonlyBar from './Menu/ReadonlyBar.vue'
8795
8896
import { logger } from '../helpers/logger.js'
8997
import { SyncService, ERROR_TYPE, IDLE_TIMEOUT } from './../services/SyncService.js'
@@ -112,6 +120,7 @@ export default {
112120
DocumentStatus,
113121
Wrapper,
114122
MainContainer,
123+
ReadonlyBar,
115124
ContentContainer,
116125
MenuBar,
117126
MenuBubble: () => import(/* webpackChunkName: "editor-rich" */'./MenuBubble.vue'),
@@ -686,61 +695,74 @@ export default {
686695
</script>
687696
688697
<style scoped lang="scss">
689-
.modal-container .text-editor {
690-
top: 0;
691-
height: calc(100vh - var(--header-height));
692-
}
698+
.modal-container .text-editor {
699+
top: 0;
700+
height: calc(100vh - var(--header-height));
701+
}
693702
694-
.text-editor {
695-
display: block;
696-
width: 100%;
697-
max-width: 100%;
698-
height: 100%;
699-
left: 0;
700-
margin: 0 auto;
701-
position: relative;
702-
background-color: var(--color-main-background);
703-
}
703+
.text-editor {
704+
display: block;
705+
width: 100%;
706+
max-width: 100%;
707+
height: 100%;
708+
left: 0;
709+
margin: 0 auto;
710+
position: relative;
711+
background-color: var(--color-main-background);
712+
}
704713
705-
.text-editor .text-editor__wrapper.has-conflicts {
706-
height: calc(100% - 50px);
714+
.text-editor .text-editor__wrapper.has-conflicts {
715+
height: calc(100% - 50px);
707716
708-
.text-editor__main, #read-only-editor {
709-
width: 50%;
710-
height: 100%;
711-
}
717+
.text-editor__main, #read-only-editor {
718+
width: 50%;
719+
height: 100%;
712720
}
721+
}
713722
714-
#body-public {
715-
height: auto;
716-
}
723+
#body-public {
724+
height: auto;
725+
}
717726
718-
#files-public-content {
719-
.text-editor {
720-
top: 0;
721-
width: 100%;
727+
#files-public-content {
728+
.text-editor {
729+
top: 0;
730+
width: 100%;
722731
723-
.text-editor__main {
724-
overflow: auto;
725-
z-index: 20;
726-
}
727-
.has-conflicts .text-editor__main {
728-
padding-top: 0;
729-
}
732+
.text-editor__main {
733+
overflow: auto;
734+
z-index: 20;
735+
}
736+
.has-conflicts .text-editor__main {
737+
padding-top: 0;
730738
}
731739
}
740+
}
732741
733-
.menubar-placeholder {
734-
position: fixed;
735-
position: -webkit-sticky;
736-
position: sticky;
737-
top: 0;
738-
opacity: 0;
739-
visibility: hidden;
740-
height: 44px; // important for mobile so that the buttons are always inside the container
741-
padding-top:3px;
742-
padding-bottom: 3px;
743-
}
742+
.menubar-placeholder,
743+
.text-editor--readonly-bar {
744+
position: fixed;
745+
position: -webkit-sticky;
746+
position: sticky;
747+
top: 0;
748+
opacity: 0;
749+
visibility: hidden;
750+
height: 44px; // important for mobile so that the buttons are always inside the container
751+
padding-top:3px;
752+
padding-bottom: 3px;
753+
}
754+
755+
.text-editor--readonly-bar,
756+
.menubar-placeholder--with-slot {
757+
opacity: unset;
758+
visibility: unset;
759+
760+
z-index: 50;
761+
max-width: var(--text-editor-max-width);
762+
margin: auto;
763+
width: 100%;
764+
background-color: var(--color-main-background);
765+
}
744766
745767
</style>
746768

src/components/Editor/EditorOutline.vue

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
<template>
22
<div data-text-el="editor-outline" class="editor--outline" :class="{ 'editor--outline-mobile': mobile }">
33
<header class="editor--outline__header">
4-
<h2>{{ t('text', 'Outline') }}</h2>
5-
<NcButton type="tertiary" :aria-label="t('text', 'Close outline view')" @click="$outlineActions.toggle">
4+
<NcButton class="editor--outline__btn-close"
5+
type="tertiary"
6+
:aria-label="t('text', 'Close outline view')"
7+
@click="$outlineActions.toggle">
68
<template #icon>
79
<Close />
810
</template>
911
</NcButton>
12+
<h2>{{ t('text', 'Outline') }}</h2>
1013
</header>
1114
<TableOfContents />
1215
</div>
@@ -72,18 +75,21 @@ export default {
7275
background-color: var(--color-main-background-translucent);
7376
z-index: 1;
7477
}
75-
}
7678
77-
.editor--outline__header {
78-
margin: 0rem;
79-
position: sticky;
80-
padding: 10px;
81-
display: flex;
82-
height: 44px;
83-
h2 {
84-
font-size: 1rem;
85-
margin-top: 13px;
86-
flex-grow: 1;
79+
&__header {
80+
margin: 0;
81+
position: sticky;
82+
padding: 0.6em 0.6em 0.6em 0;
83+
display: flex;
84+
align-items: center;
85+
86+
h2 {
87+
font-size: 1rem;
88+
line-height: 1.1rem;
89+
flex-grow: 1;
90+
padding: 0;
91+
margin: 0;
92+
}
8793
}
8894
}
8995
</style>

src/components/Menu/ActionSingle.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export default {
113113
// do not use title if is a item of action list
114114
const title = isItem ? undefined : label
115115
116-
if (isItem) {
116+
if (isItem || actionEntry.forceLabel) {
117117
// add label
118118
children.push(label)
119119
}

src/components/Menu/BaseActionEntry.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ const BaseActionEntry = {
6666
return getKeyshortcuts(this.actionEntry)
6767
},
6868
tooltip() {
69-
return [this.actionEntry.label, getKeys(this.$isMobile, this.actionEntry)].join(' ')
69+
return [
70+
this.label,
71+
getKeys(this.$isMobile, this.actionEntry),
72+
].join(' ')
7073
},
7174
},
7275
mounted() {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<template>
2+
<div data-text-el="readonly-bar" class="text-readonly-bar">
3+
<div ref="menubar"
4+
role="group"
5+
class="text-readonly-bar__entries"
6+
:aria-label="t('text', 'Editor actions')">
7+
<ActionEntry v-for="actionEntry of visibleEntries"
8+
v-bind="{ actionEntry }"
9+
:key="`text-action--${actionEntry.key}`" />
10+
</div>
11+
</div>
12+
</template>
13+
14+
<script>
15+
import { defineComponent } from 'vue'
16+
import { ReadonlyEntries as entries } from './entries.js'
17+
import ActionEntry from './ActionEntry.js'
18+
19+
export default defineComponent({
20+
name: 'ReadonlyBar',
21+
components: { ActionEntry },
22+
setup() {
23+
return {
24+
visibleEntries: entries,
25+
}
26+
},
27+
})
28+
</script>
29+
30+
<style scoped>
31+
.text-readonly-bar__entries {
32+
display: flex;
33+
flex-grow: 1;
34+
}
35+
</style>

src/components/Menu/entries.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ import ActionAttachmentUpload from './ActionAttachmentUpload.vue'
5151

5252
import { MODIFIERS } from './keys.js'
5353

54+
export const ReadonlyEntries = [{
55+
key: 'outline',
56+
forceLabel: true,
57+
icon: FormatListBulleted,
58+
click: ({ $outlineActions }) => $outlineActions.toggle(),
59+
label: ({ $outlineState }) => {
60+
return $outlineState.visible
61+
? t('text', 'Hide outline')
62+
: t('text', 'Show outline')
63+
},
64+
}]
65+
5466
export default [
5567
{
5668
key: 'undo',
@@ -184,6 +196,9 @@ export default [
184196
key: 'outline',
185197
icon: FormatListBulleted,
186198
click: ({ $outlineActions }) => $outlineActions.toggle(),
199+
visible: ({ $outlineState }) => {
200+
return $outlineState.enable
201+
},
187202
label: ({ $outlineState }) => {
188203
return $outlineState.visible
189204
? t('text', 'Hide outline')

0 commit comments

Comments
 (0)