Merge pull request #1003 from JonnyTischbein/settings-dialog

This commit is contained in:
Julius Härtl 2023-04-26 17:33:00 +02:00 коммит произвёл GitHub
Родитель be0b49868c 89824615e6
Коммит 66a5e4db9b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 138 добавлений и 229 удалений

Просмотреть файл

@ -17,18 +17,18 @@
@category-selected="onSelectCategory"
@note-deleted="onNoteDeleted"
/>
<NcAppNavigationItem
:title="t('notes', 'Help')"
:pinned="true"
@click.prevent="openHelp"
>
<InfoIcon slot="icon" :size="20" />
</NcAppNavigationItem>
<AppHelp :open.sync="helpVisible" />
</template>
<template #footer>
<AppSettings v-if="!loading.notes && error !== true" @reload="reloadNotes" />
<ul class="app-navigation-entry__settings">
<NcAppNavigationItem
:title="t('notes', 'Notes settings')"
@click.prevent="openSettings"
>
<CogIcon slot="icon" :size="20" />
</NcAppNavigationItem>
</ul>
<AppSettings v-if="!loading.notes && error !== true" :open.sync="settingsVisible" @reload="reloadNotes" />
</template>
</NcAppNavigation>
@ -57,12 +57,11 @@ import { loadState } from '@nextcloud/initial-state'
import { showSuccess, TOAST_UNDO_TIMEOUT, TOAST_PERMANENT_TIMEOUT } from '@nextcloud/dialogs'
import '@nextcloud/dialogs/dist/index.css'
import InfoIcon from 'vue-material-design-icons/Information.vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import CogIcon from 'vue-material-design-icons/Cog.vue'
import AppSettings from './components/AppSettings.vue'
import NavigationList from './components/NavigationList.vue'
import AppHelp from './components/AppHelp.vue'
import EditorHint from './components/Modal/EditorHint.vue'
import { config } from './config.js'
@ -73,16 +72,15 @@ export default {
name: 'App',
components: {
AppHelp,
AppSettings,
EditorHint,
InfoIcon,
NavigationList,
NcAppContent,
NcAppNavigation,
NcAppNavigationNew,
NcAppNavigationItem,
NcContent,
CogIcon,
PlusIcon,
},
@ -100,8 +98,8 @@ export default {
undoTimer: null,
deletedNotes: [],
refreshTimer: null,
helpVisible: false,
editorHint: loadState('notes', 'editorHint', '') === 'yes' && window.OCA.Text?.createEditor,
settingsVisible: false,
}
},
@ -248,8 +246,8 @@ export default {
}
},
openHelp() {
this.helpVisible = true
openSettings() {
this.settingsVisible = true
},
onNewNote() {
@ -345,3 +343,14 @@ export default {
},
}
</script>
<style scoped lang="scss">
// Source for footer fix: https://github.com/nextcloud/server/blob/master/apps/files/src/views/Navigation.vue
.app-navigation-entry__settings {
height: auto !important;
overflow: hidden !important;
padding-top: 0 !important;
// Prevent shrinking or growing
flex: 0 0 auto;
}
</style>

Просмотреть файл

@ -1,188 +0,0 @@
<template>
<div>
<NcAppSettingsDialog
:title="t('notes', 'Help')"
:show-navigation="true"
:open="helpOpen"
@update:open="setHelpOpen($event)"
>
<NcAppSettingsSection id="help-basics" :title="t('notes', 'Basics')">
<div class="feature icon-add">
{{ t('notes', 'Start writing a note by clicking on “{newnote}” in the app navigation.', { newnote: t('notes', 'New note') }) }}
</div>
<div class="feature icon-fullscreen">
{{ t('notes', 'Write down your thoughts without any distractions.') }}
</div>
<div class="feature icon-files-dark">
{{ t('notes', 'Organize your notes in categories.') }}
</div>
</NcAppSettingsSection>
<NcAppSettingsSection id="help-markdown" :title="t('notes', 'Markdown')">
<div class="feature icon-toggle-filelist">
{{ t('notes', 'Use Markdown markups to style your text.') }}
</div>
<p>
<CreateSampleButton @click="setHelpOpen(false)" />
</p>
<br>
<table class="notes-help">
<tr>
<th>
{{ t('notes', 'Sequence') }}
</th>
<th>
{{ t('notes', 'Result') }}
</th>
<th>
{{ t('notes', 'Visualized') }}
</th>
</tr>
<tr v-for="(item, index) in formatting" :key="index">
<!-- eslint-disable-next-line vue/no-v-html -->
<td v-html="item.sequence" />
<td>
{{ item.result }}
</td>
<!-- eslint-disable-next-line vue/no-v-html -->
<td v-html="item.visualized" />
</tr>
</table>
</NcAppSettingsSection>
<NcAppSettingsSection id="help-shortcuts" :title="t('notes', 'Shortcuts')">
<div class="feature icon-toggle-filelist">
{{ t('notes', 'Use shortcuts to quickly navigate this app.') }}
</div>
<table class="notes-help">
<tr>
<th>{{ t('notes', 'Shortcut') }}</th>
<th>{{ t('notes', 'Action') }}</th>
</tr>
<tr v-for="(item, index) in shortcuts" :key="index">
<td>{{ item.shortcut }}</td>
<td>{{ item.action }}</td>
</tr>
</table>
</NcAppSettingsSection>
<NcAppSettingsSection id="help-apps" :title="t('notes', 'Mobile apps')">
<HelpMobile />
</NcAppSettingsSection>
</NcAppSettingsDialog>
</div>
</template>
<script>
import {
NcAppSettingsDialog,
NcAppSettingsSection,
} from '@nextcloud/vue'
import CreateSampleButton from './CreateSampleButton.vue'
import HelpMobile from './HelpMobile.vue'
export default {
name: 'AppHelp',
components: {
CreateSampleButton,
HelpMobile,
NcAppSettingsDialog,
NcAppSettingsSection,
},
props: {
open: Boolean,
},
data() {
return {
helpOpen: this.open,
shortcuts: [
{ shortcut: t('notes', 'CTRL') + '+B', action: t('notes', 'Make the selection bold') },
{ shortcut: t('notes', 'CTRL') + '+I', action: t('notes', 'Make the selection italic') },
{ shortcut: t('notes', 'CTRL') + '+\'', action: t('notes', 'Wrap the selection in quotes') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'ALT') + '+C', action: t('notes', 'The selection will be turned into monospace') },
{ shortcut: t('notes', 'CTRL') + '+E', action: t('notes', 'Remove any styles from the selected text') },
{ shortcut: t('notes', 'CTRL') + '+L', action: t('notes', 'Makes the current line a list element') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'ALT') + '+L', action: t('notes', 'Makes the current line a list element with a number') },
{ shortcut: t('notes', 'CTRL') + '+H', action: t('notes', 'Toggle heading for current line') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'SHIFT') + '+H', action: t('notes', 'Set the current line as a big heading') },
{ shortcut: t('notes', 'CTRL') + '+K', action: t('notes', 'Insert link') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'ALT') + '+I', action: t('notes', 'Insert image') },
{ shortcut: t('notes', 'CTRL') + '+/', action: t('notes', 'Switch between editor and viewer') },
],
formatting: [
{ sequence: '**' + t('notes', 'bold') + '**', result: t('notes', 'bold'), visualized: '<b>' + t('notes', 'bold') + '</b>' },
{ sequence: '*' + t('notes', 'italic') + '*', result: t('notes', 'italic'), visualized: '<em>' + t('notes', 'italic') + '</em>' },
{ sequence: '~~' + t('notes', 'strikethrough') + '~~', result: t('notes', 'strikethrough'), visualized: '<s>' + t('notes', 'strikethrough') + '</s>' },
{ sequence: '# ' + t('notes', 'Big header'), result: t('notes', 'Big header'), visualized: '<h2>' + t('notes', 'Big header') + '</h2>' },
{ sequence: '## ' + t('notes', 'Medium header'), result: t('notes', 'Medium header'), visualized: '<b><h3>' + t('notes', 'Medium header') + '</h3></b>' },
{ sequence: '### ' + t('notes', 'Small header'), result: t('notes', 'Small header'), visualized: '<h3>' + t('notes', 'Small header') + '</h3>' },
{ sequence: '#### ' + t('notes', 'Tiny header'), result: t('notes', 'Tiny header'), visualized: '<h4>' + t('notes', 'Tiny header') + '</h4>' },
{ sequence: '* ' + t('notes', 'Generic list item'), result: t('notes', 'Generic list'), visualized: '<li>' + t('notes', 'Generic list item') + '</li>' },
{ sequence: '- ' + t('notes', 'Generic list item'), result: t('notes', 'Generic list'), visualized: '<li>' + t('notes', 'Generic list item') + '</li>' },
{
sequence: '1. William Riker<br>2. Deanna Troi<br>3. Beverly Crusher<br>',
result: t('notes', 'Numbered list'),
visualized: '<ol><li>William Riker</li><li>Deanna Troi</li><li>Beverly Crusher</li></ol>',
},
{ sequence: '[' + t('notes', 'Link title') + '](http://www.example.com)', result: t('notes', 'link'), visualized: '<a href="http://www.example.com">' + t('notes', 'Link title') + '</a>' },
{ sequence: '![' + t('notes', 'Image title') + '](http://www.example.com/image.jpg)', result: t('notes', 'image'), visualized: '<img src="http://www.example.com" alt="' + t('notes', 'Image title') + '" />' },
{ sequence: '> ' + t('notes', 'This is a quote.'), result: t('notes', 'quote'), visualized: '<blockquote>' + t('notes', 'This is a quote.') + '</blockquote>' },
{ sequence: '`' + t('notes', 'code') + '`', result: t('notes', 'code'), visualized: '<code>' + t('notes', 'code') + '</code>' },
{ sequence: '```<br>' + t('notes', 'Multi line block code') + '<br>```', result: t('notes', 'Multi line block code'), visualized: '<pre>' + t('notes', 'Multi line block code') + '</pre>' },
],
}
},
watch: {
open(newValue) {
this.helpOpen = newValue
},
},
methods: {
setHelpOpen(newValue) {
this.helpOpen = newValue
this.$emit('update:open', newValue)
},
},
}
</script>
<style scoped>
table.notes-help {
width: 70%;
border: 1px lightgray solid;
border-spacing: 0;
border-collapse:separate;
border-radius:6px;
}
table.notes-help th {
font-style: oblique;
font-weight: bold;
border-top: none;
}
table.notes-help th, table.notes-help td {
padding: 5px;
border-left: 1px lightgray solid;
}
table.notes-help td:first-child, table.notes-help th:first-child {
border-left: none;
}
table.notes-help tr:nth-child(even) {
background-color: var(--color-background-dark);
}
</style>

Просмотреть файл

@ -1,22 +1,37 @@
<template>
<NcAppNavigationSettings :title="t('notes', 'Notes settings')" :class="{ loading: saving }">
<div class="settings-block">
<p class="settings-hint">
<label for="notesPath">{{ t('notes', 'Folder to store your notes') }}</label>
<NcAppSettingsDialog
:title="t('notes', 'Notes settings')"
:class="{ loading: saving }"
:show-navigation="true"
:open="settingsOpen"
@update:open="setSettingsOpen($event)"
>
<NcAppSettingsSection id="help-basics" :title="t('notes', 'Basics')">
<div class="feature icon-add">
{{ t('notes', 'Start writing a note by clicking on “{newnote}” in the app navigation.', { newnote: t('notes', 'New note') }) }}
</div>
<div class="feature icon-fullscreen">
{{ t('notes', 'Write down your thoughts without any distractions.') }}
</div>
<div class="feature icon-files-dark">
{{ t('notes', 'Organize your notes in categories.') }}
</div>
</NcAppSettingsSection>
<NcAppSettingsSection id="notes-path-section" :title="t('notes', 'Notes path')">
<p class="app-settings-section__desc">
{{ t('notes', 'Folder to store your notes') }}
</p>
<form @submit.prevent="onChangeSettingsReload">
<input id="notesPath"
v-model="settings.notesPath"
type="text"
name="notesPath"
:placeholder="t('notes', 'Root directory')"
@change="onChangeSettingsReload"
><input type="submit" class="icon-confirm" value="">
</form>
</div>
<div class="settings-block">
<p class="settings-hint">
<label for="fileSuffix">{{ t('notes', 'File extension for new notes') }}</label>
<input id="notesPath"
v-model="settings.notesPath"
type="text"
name="notesPath"
:placeholder="t('notes', 'Root directory')"
@click="onChangeNotePath"
>
</NcAppSettingsSection>
<NcAppSettingsSection id="file-suffix-section" :title="t('notes', 'File extension')">
<p class="app-settings-section__desc">
{{ t('notes', 'File extension for new notes') }}
</p>
<select id="fileSuffix" v-model="settings.fileSuffix" @change="onChangeSettings">
<option v-for="extension in extensions" :key="extension.value" :value="extension.value">
@ -31,33 +46,61 @@
placeholder=".txt"
@change="onChangeSettings"
>
</div>
<div class="settings-block">
<p class="settings-hint">
<label for="noteMode">{{ t('notes', 'Display mode for notes') }}</label>
</NcAppSettingsSection>
<NcAppSettingsSection id="note-mode-section" :title="t('notes', 'Display mode')">
<p class="app-settings-section__desc">
{{ t('notes', 'Display mode for notes') }}
</p>
<select id="noteMode" v-model="settings.noteMode" @change="onChangeSettings">
<option v-for="mode in noteModes" :key="mode.value" :value="mode.value">
{{ mode.label }}
</option>
</select>
</div>
</NcAppNavigationSettings>
</NcAppSettingsSection>
<NcAppSettingsSection id="help-shortcuts" :title="t('notes', 'Shortcuts')">
<div class="feature icon-toggle-filelist">
{{ t('notes', 'Use shortcuts to quickly navigate this app.') }}
</div>
<table class="notes-help">
<tr>
<th>{{ t('notes', 'Shortcut') }}</th>
<th>{{ t('notes', 'Action') }}</th>
</tr>
<tr v-for="(item, index) in shortcuts" :key="index">
<td>{{ item.shortcut }}</td>
<td>{{ item.action }}</td>
</tr>
</table>
</NcAppSettingsSection>
<NcAppSettingsSection id="help-apps" :title="t('notes', 'Mobile apps')">
<HelpMobile />
</NcAppSettingsSection>
</NcAppSettingsDialog>
</template>
<script>
import {
NcAppNavigationSettings,
NcAppSettingsDialog,
NcAppSettingsSection,
} from '@nextcloud/vue'
import { FilePicker, FilePickerType } from '@nextcloud/dialogs'
import { setSettings } from '../NotesService.js'
import store from '../store.js'
import HelpMobile from './HelpMobile.vue'
export default {
name: 'AppSettings',
components: {
NcAppNavigationSettings,
NcAppSettingsDialog,
NcAppSettingsSection,
HelpMobile,
},
props: {
open: Boolean,
},
data() {
@ -73,6 +116,21 @@ export default {
{ value: 'preview', label: t('notes', 'Open in preview mode') },
],
saving: false,
settingsOpen: this.open,
shortcuts: [
{ shortcut: t('notes', 'CTRL') + '+B', action: t('notes', 'Make the selection bold') },
{ shortcut: t('notes', 'CTRL') + '+I', action: t('notes', 'Make the selection italic') },
{ shortcut: t('notes', 'CTRL') + '+\'', action: t('notes', 'Wrap the selection in quotes') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'ALT') + '+C', action: t('notes', 'The selection will be turned into monospace') },
{ shortcut: t('notes', 'CTRL') + '+E', action: t('notes', 'Remove any styles from the selected text') },
{ shortcut: t('notes', 'CTRL') + '+L', action: t('notes', 'Makes the current line a list element') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'ALT') + '+L', action: t('notes', 'Makes the current line a list element with a number') },
{ shortcut: t('notes', 'CTRL') + '+H', action: t('notes', 'Toggle heading for current line') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'SHIFT') + '+H', action: t('notes', 'Set the current line as a big heading') },
{ shortcut: t('notes', 'CTRL') + '+K', action: t('notes', 'Insert link') },
{ shortcut: t('notes', 'CTRL') + '+' + t('notes', 'ALT') + '+I', action: t('notes', 'Insert image') },
{ shortcut: t('notes', 'CTRL') + '+/', action: t('notes', 'Switch between editor and viewer') },
],
}
},
@ -82,6 +140,12 @@ export default {
},
},
watch: {
open(newValue) {
this.settingsOpen = newValue
},
},
created() {
if (!window.OCA.Text?.createEditor) {
this.noteModes.splice(0, 1)
@ -89,6 +153,25 @@ export default {
},
methods: {
onChangeNotePath(event) {
// Code Example from: https://github.com/nextcloud/text/blob/main/src/components/Menu/ActionInsertLink.vue#L130-L155
const filePicker = new FilePicker(
t('text', 'Select folder to link to'),
false, // multiselect
['text/directory'], // mime filter
true, // modal
FilePickerType.Choose, // type
true, // directories
event.target.value === '' ? '/' : event.target.value // path
)
filePicker.pick().then((file) => {
const client = OC.Files.getClient()
client.getFileInfo(file).then((_status, fileInfo) => {
this.settings.notesPath = fileInfo.path === '/' ? `/${fileInfo.name}` : `${fileInfo.path}/${fileInfo.name}`
this.onChangeSettingsReload()
})
})
},
onChangeSettings() {
this.saving = true
return setSettings(this.settings)
@ -105,6 +188,11 @@ export default {
this.$emit('reload')
})
},
setSettingsOpen(newValue) {
this.settingsOpen = newValue
this.$emit('update:open', newValue)
},
},
}
</script>