-
Notifications
You must be signed in to change notification settings - Fork 156
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(admin): Monaco, Resize panels, improved explorer (#509)
* feat(admin): merge frontmatter and content * chore: init monaco * chore: fix lint * feat: monaco dark mode * feat(admin): resizable panels, close #484 * style: improve explorer * chore: enabled wordWrap for monaco * style: panel style * style(admin): explorer scoll * fix(admin): monaco build
- Loading branch information
Showing
19 changed files
with
406 additions
and
260 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,35 @@ | ||
<template> | ||
<textarea v-model="frontmatter" class="h-24 w-full font-mono px-4 py-2 d-border border-b outline-none text-sm" /> | ||
<textarea v-model="content" class="w-full h-full font-mono px-4 py-2 outline-none text-sm" /> | ||
<Monaco :value="raw" language="markdown" @change="update" /> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import YAML from 'js-yaml' | ||
import { GrayMatterFile } from 'gray-matter' | ||
import { defineComponent, computed, ref, watch, PropType } from 'vue3' | ||
<script setup lang="ts"> | ||
import type { PropType } from 'vue3' | ||
import { ref, watch, defineProps } from 'vue3' | ||
import type { File } from '../../type' | ||
import { useApi } from '../plugins/api' | ||
import Monaco from './Monaco.vue' | ||
type PermissiveGrayMatterFile = GrayMatterFile<any> & { file: any; path: any } | ||
export default defineComponent({ | ||
props: { | ||
file: { | ||
type: Object as PropType<PermissiveGrayMatterFile>, | ||
required: true | ||
} | ||
}, | ||
setup(props) { | ||
const api = useApi() | ||
// Sync local data when file changes | ||
watch( | ||
() => props.file, | ||
newVal => { | ||
data.value = newVal.data | ||
content.value = newVal.content | ||
} | ||
) | ||
// Local data | ||
const data = ref(props.file.data) | ||
const content = ref(props.file.content) | ||
// Stringified reference for frontmatter text-area | ||
const frontmatter = computed({ | ||
get() { | ||
return YAML.dump(data.value, null, 2) | ||
}, | ||
set(value: string) { | ||
try { | ||
data.value = YAML.parse(value) | ||
} catch (e) { | ||
// New value is not a valid YAML string. | ||
// Do nothing and wait for the next valid YAML input. | ||
} | ||
} | ||
}) | ||
const props = defineProps({ | ||
file: { | ||
type: Object as PropType<File>, | ||
required: true | ||
} | ||
}) | ||
// API update on change on data or content | ||
watch([data, content], () => { | ||
api.put(`/content${props.file.path}`, { | ||
data: data.value, | ||
content: content.value | ||
}) | ||
}) | ||
const api = useApi() | ||
const raw = ref(props.file.raw) | ||
return { | ||
frontmatter, | ||
content | ||
} | ||
// Sync local data when file changes | ||
watch( | ||
() => props.file, | ||
newVal => { | ||
raw.value = newVal.raw | ||
} | ||
}) | ||
</script> | ||
) | ||
<style lang="postcss" scoped> | ||
textarea { | ||
@apply whitespace-nowrap overflow-scroll bg-transparent; | ||
function update(content) { | ||
api.put(`/content${props.file.path}`, { | ||
raw: content | ||
}) | ||
} | ||
</style> | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,25 @@ | ||
<template> | ||
<svg | ||
v-if="isDir(file) && file.isOpen" | ||
class="mr-1 h-4 w-4 text-gray-500" | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
stroke="currentColor" | ||
> | ||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> | ||
</svg> | ||
|
||
<svg | ||
v-else-if="isDir(file)" | ||
class="mr-1 h-4 w-4 text-gray-500" | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
stroke="currentColor" | ||
> | ||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /> | ||
</svg> | ||
|
||
<span v-else class="mr-1 inline-block h-4 w-4" /> | ||
|
||
<svg | ||
v-if="isDir(file)" | ||
class="mr-1 h-5 w-5 text-blue-400" | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="currentColor" | ||
viewBox="0 0 24 24" | ||
> | ||
<path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" /> | ||
</svg> | ||
|
||
<svg | ||
v-else-if="isImage(file)" | ||
class="mr-1 h-5 w-5 text-gray-500" | ||
:class="{ 'text-gray-600': isCurrent(file) }" | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
stroke="currentColor" | ||
> | ||
<path | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
stroke-width="2" | ||
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" | ||
/> | ||
</svg> | ||
|
||
<svg | ||
v-else | ||
class="mr-1 h-5 w-5 text-gray-500" | ||
:class="{ 'text-gray-600': isCurrent(file) }" | ||
xmlns="http://www.w3.org/2000/svg" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
stroke="currentColor" | ||
> | ||
<path | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
stroke-width="2" | ||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" | ||
/> | ||
</svg> | ||
<vscode-icons:default-folder-opened v-if="isDir && file.isOpen" /> | ||
<vscode-icons:default-folder v-else-if="isDir" /> | ||
<mdi:language-markdown v-else-if="isMarkdown" /> | ||
<vscode-icons:file-type-vue v-else-if="isVue" /> | ||
<heroicons-outline:photograph v-else-if="isImage" /> | ||
<heroicons-outline:document v-else /> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent, inject } from 'vue3' | ||
export default defineComponent({ | ||
props: { | ||
file: { | ||
type: Object, | ||
required: true | ||
} | ||
}, | ||
setup() { | ||
const { isDir, isCurrent, isImage, hasOneDir, open } = inject('tree-helpers') | ||
<script setup lang="ts"> | ||
import { defineProps, computed } from 'vue3' | ||
import { isImage as isFileImage } from '../utils' | ||
return { | ||
isDir, | ||
isCurrent, | ||
isImage, | ||
hasOneDir, | ||
open | ||
} | ||
const props = defineProps({ | ||
file: { | ||
type: Object, | ||
required: true | ||
} | ||
}) | ||
const isDir = computed(() => props.file.type === 'directory') | ||
const isImage = computed(() => isFileImage(props.file)) | ||
const isMarkdown = computed(() => props.file.extension === '.md') | ||
const isVue = computed(() => props.file.extension === '.vue') | ||
</script> |
Oops, something went wrong.
37a772e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nuxtjs-with-docus – ./
nuxtjs-with-docus.vercel.app
nuxtjs-with-docus-nuxtlabs.vercel.app
nuxtjs-with-docus-git-dev-nuxtlabs.vercel.app
nuxtjs.docus.com