refactor: update to DevTools v1
This commit is contained in:
@ -1,11 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import './styles/global.css'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Html>
|
<Html>
|
||||||
<Body h-screen>
|
<Body h-screen>
|
||||||
<Notification />
|
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
|||||||
@ -249,8 +249,8 @@ const toggleSchema = computed({
|
|||||||
<NTextInput v-else v-model="column.default" n="orange" />
|
<NTextInput v-else v-model="column.default" n="orange" />
|
||||||
</div>
|
</div>
|
||||||
<div flex justify-center gap2>
|
<div flex justify-center gap2>
|
||||||
<NIconButton icon="carbon-add" n="cyan" @click="addField(index)" />
|
<NButton icon="carbon-add" n="cyan" @click="addField(index)" />
|
||||||
<NIconButton icon="carbon-trash-can" n="red" @click="removeField(index)" />
|
<NButton icon="carbon-trash-can" n="red" @click="removeField(index)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -125,7 +125,7 @@ const copy = useCopy()
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="dbContainer" :class="{ 'h-full': !documents?.length }">
|
<div ref="dbContainer" :class="{ 'h-full': !documents?.length }">
|
||||||
<Navbar v-model:search="search" sticky top-0 px4 py2 backdrop-blur z-10>
|
<NNavbar v-model:search="search" sticky top-0 px4 py2 backdrop-blur z-10>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<NButton icon="carbon:add" n="green" @click="addDocument">
|
<NButton icon="carbon:add" n="green" @click="addDocument">
|
||||||
Add Document
|
Add Document
|
||||||
@ -155,7 +155,7 @@ const copy = useCopy()
|
|||||||
</NSelect>
|
</NSelect>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Navbar>
|
</NNavbar>
|
||||||
<table v-if="documents?.length || selectedDocument" w-full mb10 :class="{ 'editing-mode': editing }">
|
<table v-if="documents?.length || selectedDocument" w-full mb10 :class="{ 'editing-mode': editing }">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -180,14 +180,14 @@ const copy = useCopy()
|
|||||||
<td>
|
<td>
|
||||||
<div flex justify-center gap2 class="group">
|
<div flex justify-center gap2 class="group">
|
||||||
<template v-if="editing && selectedDocument._id === document._id">
|
<template v-if="editing && selectedDocument._id === document._id">
|
||||||
<NIconButton title="Save" icon="carbon-save" @click="saveDocument(selectedDocument, false)" />
|
<NButton title="Save" icon="carbon-save" n="blue" @click="saveDocument(selectedDocument, false)" />
|
||||||
<NIconButton title="Cancel" icon="carbon-close" @click="discardEditing" />
|
<NButton title="Cancel" icon="carbon-close" n="red" @click="discardEditing" />
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<NIconButton title="Edit" icon="carbon-edit" @click="editDocument(document)" />
|
<NButton title="Edit" icon="carbon-edit" n="blue" @click="editDocument(document)" />
|
||||||
<NIconButton title="Delete" icon="carbon-trash-can" @click="deleteDocument(document)" />
|
<NButton title="Delete" icon="carbon-trash-can" n="red" @click="deleteDocument(document)" />
|
||||||
<NIconButton title="Duplicate" icon="carbon-document-multiple-02" @click="saveDocument(document)" />
|
<NButton title="Duplicate" icon="carbon-document-multiple-02" n="cyan" @click="saveDocument(document)" />
|
||||||
<NIconButton title="Copy" n="xs" absolute right-4 opacity-0 group-hover="opacity-100" transition-all icon="carbon-copy" @click="copy(JSON.stringify(document))" />
|
<NButton title="Copy" n="xs purple" absolute right-4 opacity-0 group-hover="opacity-100" transition-all icon="carbon-copy" @click="copy(JSON.stringify(document))" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -198,8 +198,8 @@ const copy = useCopy()
|
|||||||
<input v-else placeholder="ObjectId(_id)" disabled>
|
<input v-else placeholder="ObjectId(_id)" disabled>
|
||||||
</td>
|
</td>
|
||||||
<td flex="~ justify-center gap2">
|
<td flex="~ justify-center gap2">
|
||||||
<NIconButton title="Save" icon="carbon-save" @click="saveDocument(selectedDocument)" />
|
<NButton title="Save" icon="carbon-save" n="green" @click="saveDocument(selectedDocument)" />
|
||||||
<NIconButton title="Cancel" icon="carbon-close" @click="discardEditing" />
|
<NButton title="Cancel" icon="carbon-close" n="red" @click="discardEditing" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@ -1,57 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { onClickOutside, useElementSize } from '@vueuse/core'
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
modelValue?: boolean
|
|
||||||
navbar?: HTMLElement
|
|
||||||
autoClose?: boolean
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'close'): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const el = ref<HTMLElement>()
|
|
||||||
|
|
||||||
const { height: top } = useElementSize(() => props.navbar, undefined, { box: 'border-box' })
|
|
||||||
|
|
||||||
onClickOutside(el, () => {
|
|
||||||
if (props.modelValue && props.autoClose)
|
|
||||||
emit('close')
|
|
||||||
}, {
|
|
||||||
ignore: ['a', 'button', 'summary', '[role="dialog"]'],
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
export default {
|
|
||||||
inheritAttrs: false,
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<Transition
|
|
||||||
enter-active-class="duration-200 ease-in"
|
|
||||||
enter-from-class="transform translate-x-1/1"
|
|
||||||
enter-to-class="opacity-100"
|
|
||||||
leave-active-class="duration-200 ease-out"
|
|
||||||
leave-from-class="opacity-100"
|
|
||||||
leave-to-class="transform translate-x-1/1"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-if="modelValue"
|
|
||||||
ref="el"
|
|
||||||
border="l base"
|
|
||||||
flex="~ col gap-1"
|
|
||||||
absolute bottom-0 right-0 z-10 z-20 of-auto text-sm glass-effect
|
|
||||||
:style="{ top: `${top}px` }"
|
|
||||||
v-bind="$attrs"
|
|
||||||
>
|
|
||||||
<NIconButton absolute right-2 top-2 z-20 text-xl icon="carbon-close" @click="$emit('close')" />
|
|
||||||
<div relative h-full w-full of-auto>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</template>
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
defineProps({
|
|
||||||
search: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
noPadding: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: 'Search...',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(event: 'update:search', value: string): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
function update(event: any) {
|
|
||||||
emit('update:search', event.target.value)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div flex="~ col gap2" border="b base" flex-1 navbar-glass :class="[{ p4: !noPadding }]">
|
|
||||||
<div flex="~ gap4">
|
|
||||||
<slot name="search">
|
|
||||||
<NTextInput
|
|
||||||
:placeholder="placeholder"
|
|
||||||
icon="carbon-search"
|
|
||||||
n="primary" flex-auto
|
|
||||||
:class="{ 'px-5 py-2': !noPadding }"
|
|
||||||
:value="search"
|
|
||||||
@input="update"
|
|
||||||
/>
|
|
||||||
</slot>
|
|
||||||
<slot name="actions" />
|
|
||||||
</div>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
<script setup lang='ts'>
|
|
||||||
const show = ref(false)
|
|
||||||
const icon = ref<string | undefined>()
|
|
||||||
const text = ref<string | undefined>()
|
|
||||||
const classes = ref<string | undefined>()
|
|
||||||
|
|
||||||
provideNotificationFn((data) => {
|
|
||||||
text.value = data.message
|
|
||||||
icon.value = data.icon
|
|
||||||
classes.value = data.classes ?? 'text-green'
|
|
||||||
show.value = true
|
|
||||||
setTimeout(() => {
|
|
||||||
show.value = false
|
|
||||||
}, data.duration ?? 1500)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
fixed left-0 right-0 top-0 z-999 text-center
|
|
||||||
:class="show ? '' : 'pointer-events-none overflow-hidden'"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
border="~ base"
|
|
||||||
flex="~ inline gap2"
|
|
||||||
m-3 inline-block items-center rounded px-4 py-1 transition-all duration-300 bg-base
|
|
||||||
:style="show ? {} : { transform: 'translateY(-300%)' }"
|
|
||||||
:class="[show ? 'shadow' : 'shadow-none', classes]"
|
|
||||||
>
|
|
||||||
<div v-if="icon" :class="icon" />
|
|
||||||
<div>{{ text }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import { computed, ref } from 'vue'
|
|
||||||
import { Pane, Splitpanes } from 'splitpanes'
|
|
||||||
import 'splitpanes/dist/splitpanes.css'
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
storageKey?: string
|
|
||||||
leftSize?: number
|
|
||||||
minSize?: number
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const DEFAULT = 30
|
|
||||||
|
|
||||||
const state = ref()
|
|
||||||
const key = props.storageKey
|
|
||||||
const size = key
|
|
||||||
? computed({
|
|
||||||
get: () => state.value[key] || props.leftSize || DEFAULT,
|
|
||||||
set: (v) => { state.value[key] = v },
|
|
||||||
})
|
|
||||||
: ref(props.leftSize || DEFAULT)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<Splitpanes h-full of-hidden @resize="size = $event[0].size">
|
|
||||||
<Pane border="r base" h-full class="of-auto!" :size="size" :min-size="$slots.right ? (minSize || 10) : 100">
|
|
||||||
<slot name="left" />
|
|
||||||
</Pane>
|
|
||||||
<Pane v-if="$slots.right" relative h-full class="of-auto!" :min-size="minSize || 10">
|
|
||||||
<slot name="right" />
|
|
||||||
</Pane>
|
|
||||||
</Splitpanes>
|
|
||||||
</template>
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
let _showNotification: typeof showNotification
|
|
||||||
|
|
||||||
export function showNotification(data: {
|
|
||||||
message: string
|
|
||||||
icon?: string
|
|
||||||
classes?: string
|
|
||||||
duration?: number
|
|
||||||
}) {
|
|
||||||
_showNotification?.(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function provideNotificationFn(fn: typeof showNotification) {
|
|
||||||
_showNotification = fn
|
|
||||||
}
|
|
||||||
@ -1,14 +1,14 @@
|
|||||||
import { useClipboard } from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { showNotification } from './dialog'
|
// import { } from '@nuxt/devtools-ui-kit'
|
||||||
|
|
||||||
export function useCopy() {
|
export function useCopy() {
|
||||||
const clipboard = useClipboard()
|
const clipboard = useClipboard()
|
||||||
|
|
||||||
return (text: string) => {
|
return (text: string) => {
|
||||||
clipboard.copy(text)
|
clipboard.copy(text)
|
||||||
showNotification({
|
// devtoolsUiShowNotification({
|
||||||
message: 'Copied to clipboard',
|
// message: 'Copied to clipboard',
|
||||||
icon: 'carbon-copy',
|
// icon: 'carbon-copy',
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,22 +36,22 @@ async function refresh() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<SplitPanel :min-left="13" :max-left="20">
|
<NSplitPane :min-left="13" :max-left="20">
|
||||||
<template #left>
|
<template #left>
|
||||||
<div px4>
|
<div px4>
|
||||||
<Navbar v-model:search="search" :placeholder="`${collections?.length ?? '-'} collection in total`" mt2>
|
<NNavbar v-model:search="search" :placeholder="`${collections?.length ?? '-'} collection in total`" mt2 no-padding>
|
||||||
<div flex items-center gap2>
|
<div flex items-center gap2>
|
||||||
<NIconButton w-full mb1.5 icon="carbon-reset" title="Refresh" @click="refresh" />
|
<NButton n="blue" w-full mb1.5 icon="carbon-reset" title="Refresh" @click="refresh" />
|
||||||
<NIconButton w-full mb1.5 icon="carbon-data-base" title="Default" text-green-5 />
|
<!-- <NButton w-full mb1.5 icon="carbon-data-base" title="Default" n="green" /> -->
|
||||||
<NIconButton id="open-drawer-right" w-full mb1.5 icon="carbon-add" title="Create Collection" @click="drawer = true" />
|
<NButton n="green" w-full mb1.5 icon="carbon-add" title="Create Collection" @click="drawer = true" />
|
||||||
</div>
|
</div>
|
||||||
</Navbar>
|
</NNavbar>
|
||||||
<div grid gird-cols-1 my2 mx1>
|
<div grid gird-cols-1 my2 mx1>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
v-for="table in filtered"
|
v-for="table in filtered"
|
||||||
:key="table.name"
|
:key="table.name"
|
||||||
:to="{ name: 'index', query: { table: table.name } }"
|
:to="{ name: 'index', query: { table: table.name } }"
|
||||||
flex justify-between p2 my1 hover-bg-green hover-bg-opacity-5 hover-text-green rounded-lg
|
flex items-center justify-between p2 my1 hover-bg-green hover-bg-opacity-5 hover-text-green rounded-lg
|
||||||
:class="{ 'bg-green bg-opacity-5 text-green': selectedCollection === table.name }"
|
:class="{ 'bg-green bg-opacity-5 text-green': selectedCollection === table.name }"
|
||||||
@click="selectedCollection = table.name"
|
@click="selectedCollection = table.name"
|
||||||
>
|
>
|
||||||
@ -59,9 +59,9 @@ async function refresh() {
|
|||||||
<NIcon icon="carbon-db2-database" />
|
<NIcon icon="carbon-db2-database" />
|
||||||
{{ table.name }}
|
{{ table.name }}
|
||||||
</span>
|
</span>
|
||||||
<div flex gap2>
|
<div flex="~ items-center gap-2">
|
||||||
<NIconButton block n="red" icon="carbon-trash-can" @click="dropCollection(table)" />
|
<NButton :border="false" n="red" icon="carbon-trash-can" @click="dropCollection(table)" />
|
||||||
<!-- <NIconButton icon="carbon-overflow-menu-horizontal" /> -->
|
<!-- <NButton :border="false" icon="carbon-overflow-menu-horizontal" /> -->
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
@ -78,8 +78,8 @@ async function refresh() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</SplitPanel>
|
</NSplitPane>
|
||||||
<Drawer v-model="drawer" style="width: calc(80.5%);" auto-close @close="drawer = false">
|
<NDrawer v-model="drawer" style="width: calc(80.5%);" auto-close @close="drawer = false" z-20>
|
||||||
<CreateResource @refresh="refresh" />
|
<CreateResource @refresh="refresh" />
|
||||||
</Drawer>
|
</NDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
21
client/splitpanes.d.ts
vendored
21
client/splitpanes.d.ts
vendored
@ -1,21 +0,0 @@
|
|||||||
// TODO install @types/splitpanes once updated
|
|
||||||
declare module 'splitpanes' {
|
|
||||||
import { Component } from 'vue'
|
|
||||||
|
|
||||||
export interface SplitpaneProps {
|
|
||||||
horizontal: boolean
|
|
||||||
pushOtherPanes: boolean
|
|
||||||
dblClickSplitter: boolean
|
|
||||||
firstSplitter: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PaneProps {
|
|
||||||
size: number | string
|
|
||||||
minSize: number | string
|
|
||||||
maxSize: number | string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Pane = Component<PaneProps>
|
|
||||||
export const Pane: Pane
|
|
||||||
export const Splitpanes: Component<SplitpaneProps>
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
/* Splitpanes */
|
|
||||||
.splitpanes__splitter {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.splitpanes__splitter:before {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
transition: .2s ease;
|
|
||||||
content: '';
|
|
||||||
transition: opacity 0.4s;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.splitpanes__splitter:hover:before {
|
|
||||||
background: #8881;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.splitpanes--vertical>.splitpanes__splitter {
|
|
||||||
min-width: 0 !important;
|
|
||||||
width: 0 !important;
|
|
||||||
}
|
|
||||||
.splitpanes--horizontal>.splitpanes__splitter {
|
|
||||||
min-height: 0 !important;
|
|
||||||
height: 0 !important;
|
|
||||||
}
|
|
||||||
.splitpanes--vertical>.splitpanes__splitter:before {
|
|
||||||
left: -5px;
|
|
||||||
right: -4px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.splitpanes--horizontal>.splitpanes__splitter:before {
|
|
||||||
top: -5px;
|
|
||||||
bottom: -4px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
28
package.json
28
package.json
@ -49,28 +49,26 @@
|
|||||||
"lint": "eslint . --fix"
|
"lint": "eslint . --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/devtools-kit": "^0.8.4",
|
"@nuxt/devtools-kit": "1.0.0",
|
||||||
"@nuxt/devtools-ui-kit": "^0.8.4",
|
"@nuxt/devtools-ui-kit": "1.0.0",
|
||||||
"@nuxt/kit": "^3.7.3",
|
"@nuxt/kit": "^3.8.0",
|
||||||
"@vueuse/core": "^10.4.1",
|
"@vueuse/core": "^10.5.0",
|
||||||
"defu": "^6.1.2",
|
"defu": "^6.1.3",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
"mongoose": "^7.5.2",
|
"mongoose": "^7.6.3",
|
||||||
"ofetch": "^1.3.3",
|
"ofetch": "^1.3.3",
|
||||||
"pathe": "^1.1.1",
|
"pathe": "^1.1.1",
|
||||||
"pluralize": "^8.0.0",
|
"pluralize": "^8.0.0",
|
||||||
"sirv": "^2.0.3"
|
"sirv": "^2.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^0.43.0",
|
"@antfu/eslint-config": "1.0.0-beta.29",
|
||||||
"@nuxt/module-builder": "^0.5.1",
|
"@nuxt/module-builder": "^0.5.2",
|
||||||
"@types/fs-extra": "^11.0.2",
|
"@types/fs-extra": "^11.0.3",
|
||||||
"@types/pluralize": "^0.0.30",
|
"@types/pluralize": "^0.0.32",
|
||||||
"changelogen": "^0.5.5",
|
"changelogen": "^0.5.5",
|
||||||
"eslint": "8.49.0",
|
"eslint": "8.52.0",
|
||||||
"nuxt": "^3.7.3",
|
"nuxt": "^3.8.0",
|
||||||
"sass": "^1.67.0",
|
"sass": "^1.69.5"
|
||||||
"sass-loader": "^13.3.2",
|
|
||||||
"splitpanes": "^3.1.5"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4014
pnpm-lock.yaml
generated
4014
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user