feat: add custom title bar
This commit is contained in:
parent
b580fedade
commit
1a4622cfd0
|
@ -63,7 +63,7 @@ watch(
|
|||
class="fill-height">
|
||||
<n-global-style />
|
||||
<n-dialog-provider>
|
||||
<n-spin v-show="initializing" :theme-overrides="{ opacitySpinning: 0 }">
|
||||
<n-spin v-show="initializing" :theme-overrides="{ opacitySpinning: 0 }" style="--wails-draggable: drag">
|
||||
<div id="launch-container" />
|
||||
</n-spin>
|
||||
<app-content v-if="!initializing" class="flex-item-expand" />
|
||||
|
|
|
@ -11,6 +11,11 @@ import useTabStore from './stores/tab.js'
|
|||
import usePreferencesStore from './stores/preferences.js'
|
||||
import useConnectionStore from './stores/connections.js'
|
||||
import ContentLogPane from './components/content/ContentLogPane.vue'
|
||||
import ContentValueTab from '@/components/content/ContentValueTab.vue'
|
||||
import ToolbarControlWidget from '@/components/common/ToolbarControlWidget.vue'
|
||||
import { WindowToggleMaximise } from 'wailsjs/runtime/runtime.js'
|
||||
import { isMacOS } from '@/utils/platform.js'
|
||||
import iconUrl from '@/assets/images/icon.png'
|
||||
|
||||
const themeVars = useThemeVars()
|
||||
|
||||
|
@ -19,6 +24,7 @@ const data = reactive({
|
|||
navMenuWidth: 60,
|
||||
hoverResize: false,
|
||||
resizing: false,
|
||||
toolbarHeight: 45,
|
||||
})
|
||||
|
||||
const tabStore = useTabStore()
|
||||
|
@ -69,10 +75,45 @@ watch(
|
|||
|
||||
<template>
|
||||
<!-- app content-->
|
||||
<div id="app-content-wrapper" :class="{ dragging }" :style="prefStore.generalFont" class="flex-box-h">
|
||||
<div id="app-content-wrapper" class="flex-box-v">
|
||||
<!-- title bar -->
|
||||
<div
|
||||
id="app-toolbar"
|
||||
class="flex-box-h"
|
||||
style="--wails-draggable: drag"
|
||||
:style="{ height: data.toolbarHeight + 'px' }"
|
||||
@dblclick="WindowToggleMaximise">
|
||||
<!-- title -->
|
||||
<div
|
||||
id="app-toolbar-title"
|
||||
:style="{
|
||||
width: `${data.navMenuWidth + prefStore.general.asideWidth}px`,
|
||||
paddingLeft: isMacOS() ? '70px' : '10px',
|
||||
}">
|
||||
<n-space align="center" :wrap-item="false" :wrap="false" :size="3">
|
||||
<n-avatar :src="iconUrl" color="#0000" :size="35" style="min-width: 35px" />
|
||||
<div style="min-width: 68px; font-weight: 800">Tiny RDM</div>
|
||||
<transition name="fade">
|
||||
<n-text v-if="tabStore.nav === 'browser'" strong class="ellipsis" style="font-size: 13px">
|
||||
- {{ get(tabStore.currentTab, 'name') }}
|
||||
</n-text>
|
||||
</transition>
|
||||
</n-space>
|
||||
</div>
|
||||
<!-- browser tabs -->
|
||||
<div v-show="tabStore.nav === 'browser'" class="app-toolbar-tab flex-item-expand">
|
||||
<content-value-tab />
|
||||
</div>
|
||||
<div class="flex-item-expand"></div>
|
||||
<!-- simulate window control buttons -->
|
||||
<toolbar-control-widget v-if="!isMacOS()" :size="data.toolbarHeight" style="align-self: flex-start" />
|
||||
</div>
|
||||
|
||||
<!-- content -->
|
||||
<div id="app-content" :style="prefStore.generalFont" class="flex-box-h flex-item-expand">
|
||||
<nav-menu v-model:value="tabStore.nav" :width="data.navMenuWidth" />
|
||||
<!-- browser page-->
|
||||
<div v-show="tabStore.nav === 'browser'" class="flex-box-h flex-item-expand">
|
||||
<div v-show="tabStore.nav === 'browser'" :class="{ dragging }" class="flex-box-h flex-item-expand">
|
||||
<div id="app-side" :style="{ width: asideWidthVal }" class="flex-box-h flex-item">
|
||||
<browser-pane
|
||||
v-for="t in tabStore.tabs"
|
||||
|
@ -93,7 +134,7 @@ watch(
|
|||
</div>
|
||||
|
||||
<!-- server list page -->
|
||||
<div v-show="tabStore.nav === 'server'" class="flex-box-h flex-item-expand">
|
||||
<div v-show="tabStore.nav === 'server'" :class="{ dragging }" class="flex-box-h flex-item-expand">
|
||||
<div id="app-side" :style="{ width: asideWidthVal }" class="flex-box-h flex-item">
|
||||
<connection-pane class="flex-item-expand" />
|
||||
<div
|
||||
|
@ -114,18 +155,35 @@ watch(
|
|||
<content-log-pane ref="logPaneRef" class="flex-item-expand" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#app-content-wrapper {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-top: v-bind('themeVars.borderColor') 1px solid;
|
||||
box-sizing: border-box;
|
||||
|
||||
#app-toolbar {
|
||||
height: 40px;
|
||||
border-bottom: v-bind('themeVars.borderColor') 1px solid;
|
||||
background-color: v-bind('themeVars.tabColor');
|
||||
border-bottom: 1px solid v-bind('themeVars.borderColor');
|
||||
|
||||
&-title {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
box-sizing: border-box;
|
||||
align-self: center;
|
||||
align-items: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
.app-toolbar-tab {
|
||||
align-self: flex-end;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
#app-content {
|
||||
height: calc(100% - 60px);
|
||||
}
|
||||
|
||||
#app-side {
|
||||
|
@ -157,4 +215,14 @@ watch(
|
|||
.dragging {
|
||||
cursor: col-resize !important;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
</style>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
|
@ -0,0 +1,82 @@
|
|||
<script setup>
|
||||
import WindowMin from '@/components/icons/WindowMin.vue'
|
||||
import WindowMax from '@/components/icons/WindowMax.vue'
|
||||
import WindowClose from '@/components/icons/WindowClose.vue'
|
||||
import { computed } from 'vue'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
import { Quit, WindowMinimise, WindowToggleMaximise } from 'wailsjs/runtime/runtime.js'
|
||||
|
||||
const themeVars = useThemeVars()
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: Number,
|
||||
default: 35,
|
||||
},
|
||||
})
|
||||
|
||||
const buttonSize = computed(() => {
|
||||
return props.size + 'px'
|
||||
})
|
||||
|
||||
const handleMinimise = async () => {
|
||||
WindowMinimise()
|
||||
}
|
||||
|
||||
const handleMaximise = () => {
|
||||
WindowToggleMaximise()
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
Quit()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-space :wrap-item="false" align="center" justify="center" :size="0">
|
||||
<div class="btn-wrapper" @click="handleMinimise">
|
||||
<window-min />
|
||||
</div>
|
||||
<div class="btn-wrapper" @click="handleMaximise">
|
||||
<window-max />
|
||||
</div>
|
||||
<div class="btn-wrapper" @click="handleClose">
|
||||
<window-close />
|
||||
</div>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.btn-wrapper {
|
||||
width: v-bind('buttonSize');
|
||||
height: v-bind('buttonSize');
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
--wails-draggable: none;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
&:hover {
|
||||
background-color: v-bind('themeVars.closeColorHover');
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: v-bind('themeVars.closeColorPressed');
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
&:hover {
|
||||
background-color: v-bind('themeVars.primaryColorHover');
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: v-bind('themeVars.primaryColorPressed');
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -90,7 +90,7 @@ defineExpose({
|
|||
<icon-button :icon="Delete" border t-tooltip="clean_log" @click="cleanHistory" />
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<div class="fill-height flex-box-h" style="user-select: text">
|
||||
<div class="content-value fill-height flex-box-h">
|
||||
<n-data-table
|
||||
ref="tableRef"
|
||||
:columns="[
|
||||
|
|
|
@ -121,34 +121,10 @@ const onReloadKey = async () => {
|
|||
}
|
||||
await connectionStore.loadKeyValue(tab.name, tab.db, tab.key)
|
||||
}
|
||||
|
||||
const i18n = useI18n()
|
||||
const onCloseTab = (tabIndex) => {
|
||||
$dialog.warning(i18n.t('close_confirm'), () => {
|
||||
const tab = get(tabStore.tabs, tabIndex)
|
||||
if (tab != null) {
|
||||
connectionStore.closeConnection(tab.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="content-container flex-box-v">
|
||||
<!-- <content-value-tab :tabs="tab" />-->
|
||||
<n-tabs
|
||||
v-model:value="tabStore.activatedIndex"
|
||||
:closable="true"
|
||||
size="small"
|
||||
type="card"
|
||||
@close="onCloseTab"
|
||||
@update:value="onUpdateValue">
|
||||
<n-tab v-for="(t, i) in tab" :key="i" :name="i">
|
||||
<n-ellipsis style="max-width: 150px">{{ t.label }}</n-ellipsis>
|
||||
</n-tab>
|
||||
</n-tabs>
|
||||
<!-- TODO: add loading status -->
|
||||
|
||||
<div v-if="showServerStatus" class="content-container flex-item-expand flex-box-v">
|
||||
<!-- select nothing or select server node, display server status -->
|
||||
<content-server-status
|
||||
|
|
|
@ -1,136 +1,88 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ConnectionType } from '@/consts/connection_type.js'
|
||||
import Close from '@/components/icons/Close.vue'
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
import ToggleServer from '@/components/icons/ToggleServer.vue'
|
||||
import useTabStore from 'stores/tab.js'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { get, map } from 'lodash'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
|
||||
const emit = defineEmits(['switchTab', 'closeTab', 'update:modelValue'])
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
|
||||
const themeVars = useThemeVars()
|
||||
const i18n = useI18n()
|
||||
const tabStore = useTabStore()
|
||||
const connectionStore = useConnectionStore()
|
||||
|
||||
const props = defineProps({
|
||||
selectedIndex: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: [
|
||||
{
|
||||
// label: 'tab1',
|
||||
// key: 'key',
|
||||
// bgColor: 'white',
|
||||
},
|
||||
],
|
||||
},
|
||||
tabs: {
|
||||
type: Array,
|
||||
default: [
|
||||
{
|
||||
// label: 'tab1',
|
||||
// key: 'key',
|
||||
// bgColor: 'white',
|
||||
},
|
||||
],
|
||||
},
|
||||
backgroundColor: String,
|
||||
})
|
||||
|
||||
const connectionStore = useConnectionStore()
|
||||
const onCurrentSelectChange = ({ type, group = '', server = '', db = 0, key = '' }) => {
|
||||
console.log(`group: ${group}\n server: ${server}\n db: ${db}\n key: ${key}`)
|
||||
if (type === ConnectionType.RedisValue) {
|
||||
// load and update content value
|
||||
}
|
||||
}
|
||||
// watch(() => databaseStore.currentSelect, throttle(onCurrentSelectChange, 1000))
|
||||
|
||||
const items = ref(props.modelValue)
|
||||
const selIndex = ref(props.selectedIndex)
|
||||
|
||||
const onClickTab = (idx, key) => {
|
||||
if (idx !== selIndex.value) {
|
||||
selIndex.value = idx
|
||||
emit('update:modelValue', idx, key)
|
||||
const onCloseTab = (tabIndex) => {
|
||||
$dialog.warning(i18n.t('close_confirm'), () => {
|
||||
const tab = get(tabStore.tabs, tabIndex)
|
||||
if (tab != null) {
|
||||
connectionStore.closeConnection(tab.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const onCloseTab = (idx, key) => {
|
||||
emit('closeTab', idx, key)
|
||||
}
|
||||
const activeTabStyle = computed(() => ({
|
||||
backgroundColor: themeVars.value.baseColor,
|
||||
borderTopWidth: '1px',
|
||||
borderTopColor: themeVars.value.borderColor,
|
||||
borderBottomColor: themeVars.value.baseColor,
|
||||
borderTopLeftRadius: themeVars.value.borderRadius,
|
||||
borderTopRightRadius: themeVars.value.borderRadius,
|
||||
}))
|
||||
const inactiveTabStyle = computed(() => ({
|
||||
borderWidth: '0 0 1px',
|
||||
borderBottomColor: themeVars.value.borderColor,
|
||||
borderTopLeftRadius: themeVars.value.borderRadius,
|
||||
borderTopRightRadius: themeVars.value.borderRadius,
|
||||
}))
|
||||
|
||||
const tab = computed(() =>
|
||||
map(tabStore.tabs, (item) => ({
|
||||
key: item.name,
|
||||
label: item.title,
|
||||
})),
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- TODO: 检查标签是否太多, 左右两边显示左右切换翻页按钮 -->
|
||||
<div class="content-tab flex-box-h">
|
||||
<div
|
||||
v-for="(item, i) in props.tabs"
|
||||
:key="item.key"
|
||||
:class="{ 'content-tab_selected': selIndex === i }"
|
||||
:style="{ backgroundColor: item.bgColor || '' }"
|
||||
:title="item.label"
|
||||
class="content-tab_item flex-item-expand icon-btn flex-box-h"
|
||||
@click="onClickTab(i, item.key)">
|
||||
<n-icon :component="Close" class="content-tab_item-close" size="20" @click.stop="onCloseTab(i, item.key)" />
|
||||
<div class="content-tab_item-label ellipsis flex-item-expand">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<n-tabs
|
||||
v-model:value="tabStore.activatedIndex"
|
||||
:closable="true"
|
||||
:tab-style="{
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '1px',
|
||||
}"
|
||||
size="small"
|
||||
type="card"
|
||||
@close="onCloseTab"
|
||||
@update:value="(tabIndex) => tabStore.switchTab(tabIndex)"
|
||||
:theme-overrides="{
|
||||
tabFontWeightActive: 800,
|
||||
tabBorderRadius: 0,
|
||||
tabGapSmallCard: 0,
|
||||
tabGapMediumCard: 0,
|
||||
tabGapLargeCard: 0,
|
||||
tabColor: '#0000',
|
||||
tabBorderColor: themeVars.borderColor,
|
||||
}">
|
||||
<n-tab
|
||||
v-for="(t, i) in tab"
|
||||
:key="i"
|
||||
:name="i"
|
||||
:closable="tabStore.activatedIndex === i"
|
||||
:style="tabStore.activatedIndex === i ? activeTabStyle : inactiveTabStyle"
|
||||
style="--wails-draggable: none"
|
||||
@dblclick.stop="() => {}">
|
||||
<n-space align="center" justify="center" :wrap-item="false" :size="5" inline>
|
||||
<n-icon :component="ToggleServer" size="18" />
|
||||
<n-ellipsis style="max-width: 150px">{{ t.label }}</n-ellipsis>
|
||||
</n-space>
|
||||
</n-tab>
|
||||
</n-tabs>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content-tab {
|
||||
align-items: center;
|
||||
//justify-content: center;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
|
||||
&_item {
|
||||
flex: 1 0;
|
||||
overflow: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--bg-color-page);
|
||||
color: var(--text-color-secondary);
|
||||
padding: 0 5px;
|
||||
|
||||
//border-top: var(--el-border-color) 1px solid;
|
||||
border-right: var(--border-color) 1px solid;
|
||||
transition: all var(--transition-duration-fast) var(--transition-function-ease-in-out-bezier);
|
||||
|
||||
&-label {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-close {
|
||||
//display: none;
|
||||
display: inline-flex;
|
||||
width: 0;
|
||||
transition: width 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgb(176, 177, 182, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.content-tab_item-close {
|
||||
//display: block;
|
||||
width: 20px;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&_selected {
|
||||
border-top: v-bind('themeVars.primaryColor') 4px solid !important;
|
||||
background-color: #ffffff;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -265,13 +265,15 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
{{ $t('add_row') }}
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="fill-height flex-box-h" style="user-select: text">
|
||||
<div class="value-wrapper fill-height flex-box-h">
|
||||
<n-data-table
|
||||
:key="(row) => row.no"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:single-column="true"
|
||||
:single-line="false"
|
||||
:bordered="false"
|
||||
:bottom-bordered="false"
|
||||
flex-height
|
||||
max-height="100%"
|
||||
size="small"
|
||||
|
|
|
@ -189,13 +189,15 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
{{ $t('add_row') }}
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="fill-height flex-box-h" style="user-select: text">
|
||||
<div class="value-wrapper fill-height flex-box-h">
|
||||
<n-data-table
|
||||
:key="(row) => row.no"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:single-column="true"
|
||||
:single-line="false"
|
||||
:bordered="false"
|
||||
:bottom-bordered="false"
|
||||
flex-height
|
||||
max-height="100%"
|
||||
size="small"
|
||||
|
|
|
@ -185,13 +185,15 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
{{ $t('add_row') }}
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="fill-height flex-box-h" style="user-select: text">
|
||||
<div class="value-wrapper fill-height flex-box-h">
|
||||
<n-data-table
|
||||
:key="(row) => row.no"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:single-column="true"
|
||||
:single-line="false"
|
||||
:bordered="false"
|
||||
:bottom-bordered="false"
|
||||
flex-height
|
||||
max-height="100%"
|
||||
size="small"
|
||||
|
|
|
@ -178,13 +178,15 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
{{ $t('add_row') }}
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="fill-height flex-box-h" style="user-select: text">
|
||||
<div class="value-wrapper fill-height flex-box-h">
|
||||
<n-data-table
|
||||
:key="(row) => row.id"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:single-column="true"
|
||||
:single-line="false"
|
||||
:bordered="false"
|
||||
:bottom-bordered="false"
|
||||
flex-height
|
||||
max-height="100%"
|
||||
size="small"
|
||||
|
|
|
@ -220,5 +220,6 @@ const onSaveValue = async () => {
|
|||
.value-wrapper {
|
||||
overflow: hidden;
|
||||
border-top: v-bind('themeVars.borderColor') 1px solid;
|
||||
padding: 5px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -296,13 +296,15 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
{{ $t('add_row') }}
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="fill-height flex-box-h" style="user-select: text">
|
||||
<div class="value-wrapper fill-height flex-box-h">
|
||||
<n-data-table
|
||||
:key="(row) => row.no"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:single-column="true"
|
||||
:single-line="false"
|
||||
:bordered="false"
|
||||
:bottom-bordered="false"
|
||||
flex-height
|
||||
max-height="100%"
|
||||
size="small"
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<script setup>
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 12,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg aria-hidden="false" :width="props.size" :height="props.size" viewBox="0 0 12 12">
|
||||
<polygon
|
||||
fill="currentColor"
|
||||
fill-rule="evenodd"
|
||||
points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1"></polygon>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,16 @@
|
|||
<script setup>
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 12,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg aria-hidden="false" :width="props.size" :height="props.size" viewBox="0 0 12 12">
|
||||
<rect width="9" height="9" x="1.5" y="1.5" fill="none" stroke="currentColor"></rect>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,16 @@
|
|||
<script setup>
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 12,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg aria-hidden="false" :width="props.size" :height="props.size" viewBox="0 0 12 12">
|
||||
<rect fill="currentColor" width="10" height="1" x="1" y="6"></rect>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -50,14 +50,15 @@ const selectedKeys = computed(() => {
|
|||
|
||||
const data = computed(() => {
|
||||
const dbs = get(connectionStore.databases, props.server, [])
|
||||
return [
|
||||
{
|
||||
key: `${props.server}`,
|
||||
label: props.server,
|
||||
type: ConnectionType.Server,
|
||||
children: dbs,
|
||||
},
|
||||
]
|
||||
return dbs
|
||||
// return [
|
||||
// {
|
||||
// key: `${props.server}`,
|
||||
// label: props.server,
|
||||
// type: ConnectionType.Server,
|
||||
// children: dbs,
|
||||
// },
|
||||
// ]
|
||||
})
|
||||
|
||||
const backgroundColor = computed(() => {
|
||||
|
@ -368,6 +369,8 @@ const renderPrefix = ({ option }) => {
|
|||
// render tree item label
|
||||
const renderLabel = ({ option }) => {
|
||||
switch (option.type) {
|
||||
case ConnectionType.Server:
|
||||
return h('b', {}, { default: () => option.label })
|
||||
case ConnectionType.RedisDB:
|
||||
const { name: server, db } = option
|
||||
let { match: matchPattern, type: typeFilter } = connectionStore.getKeyFilter(server, db)
|
||||
|
|
|
@ -32,7 +32,7 @@ const emit = defineEmits(['update:value'])
|
|||
|
||||
const iconSize = computed(() => Math.floor(props.width * 0.4))
|
||||
const renderIcon = (icon) => {
|
||||
return () => h(NIcon, null, { default: () => h(icon, { strokeWidth: 4 }) })
|
||||
return () => h(NIcon, null, { default: () => h(icon, { strokeWidth: 3 }) })
|
||||
}
|
||||
|
||||
const connectionStore = useConnectionStore()
|
||||
|
@ -122,7 +122,7 @@ const openGithub = () => {
|
|||
:render-label="renderContextLabel"
|
||||
trigger="click"
|
||||
@select="onSelectPreferenceMenu">
|
||||
<icon-button :icon="Config" :size="iconSize" stroke-width="4" class="nav-menu-button" />
|
||||
<icon-button :icon="Config" :size="iconSize" :stroke-width="3" class="nav-menu-button" />
|
||||
</n-dropdown>
|
||||
<icon-button :icon="Github" :size="iconSize" class="nav-menu-button" @click="openGithub" />
|
||||
</div>
|
||||
|
@ -131,7 +131,7 @@ const openGithub = () => {
|
|||
|
||||
<style lang="scss">
|
||||
#app-nav-menu {
|
||||
height: 100vh;
|
||||
//height: 100vh;
|
||||
//border-right: v-bind('themeVars.borderColor') solid 1px;
|
||||
|
||||
.nav-menu-item {
|
||||
|
|
|
@ -8,6 +8,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'
|
|||
import { i18n } from '@/utils/i18n.js'
|
||||
import { setupDiscreteApi } from '@/utils/discrete.js'
|
||||
import usePreferencesStore from 'stores/preferences.js'
|
||||
import { loadEnvironment } from '@/utils/platform.js'
|
||||
|
||||
dayjs.extend(duration)
|
||||
dayjs.extend(relativeTime)
|
||||
|
@ -17,6 +18,7 @@ async function setupApp() {
|
|||
app.use(i18n)
|
||||
app.use(createPinia())
|
||||
|
||||
await loadEnvironment()
|
||||
const prefStore = usePreferencesStore()
|
||||
await prefStore.loadPreferences()
|
||||
await setupDiscreteApi()
|
||||
|
|
|
@ -11,5 +11,9 @@
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.content-value {
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
}
|
||||
|
|
|
@ -96,7 +96,6 @@ body {
|
|||
|
||||
.value-wrapper {
|
||||
//border-top: v-bind('themeVars.borderColor') 1px solid;
|
||||
padding: 5px;
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { Environment } from 'wailsjs/runtime/runtime.js'
|
||||
|
||||
let os = ''
|
||||
|
||||
export async function loadEnvironment() {
|
||||
const env = await Environment()
|
||||
os = env.platform
|
||||
}
|
||||
|
||||
export function isMacOS() {
|
||||
return os === 'darwin'
|
||||
}
|
|
@ -20,6 +20,7 @@ export const themeOverrides = {
|
|||
tabGapSmallCard: '2px',
|
||||
tabGapMediumCard: '2px',
|
||||
tabGapLargeCard: '2px',
|
||||
tabFontWeightActive: 450,
|
||||
},
|
||||
Form: {
|
||||
labelFontSizeTopSmall: '12px',
|
||||
|
|
10
main.go
10
main.go
|
@ -41,6 +41,7 @@ func main() {
|
|||
Height: 768,
|
||||
MinWidth: 1024,
|
||||
MinHeight: 768,
|
||||
Frameless: runtime.GOOS != "darwin",
|
||||
Menu: appMenu,
|
||||
AssetServer: &assetserver.Options{
|
||||
Assets: assets,
|
||||
|
@ -59,14 +60,7 @@ func main() {
|
|||
prefSvc,
|
||||
},
|
||||
Mac: &mac.Options{
|
||||
TitleBar: &mac.TitleBar{
|
||||
TitlebarAppearsTransparent: false,
|
||||
HideTitle: false,
|
||||
HideTitleBar: false,
|
||||
FullSizeContent: false,
|
||||
UseToolbar: false,
|
||||
HideToolbarSeparator: true,
|
||||
},
|
||||
TitleBar: mac.TitleBarHiddenInset(),
|
||||
About: &mac.AboutInfo{
|
||||
Title: "Tiny RDM " + version,
|
||||
Message: "A modern lightweight cross-platform Redis desktop client.\n\nCopyright © 2023",
|
||||
|
|
Loading…
Reference in New Issue