mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
feat(terminal): add terminal button visibility setting (#13772)
This commit is contained in:
@@ -149,14 +149,14 @@ func checkSettingValueRange(key, value string) bool {
|
||||
// @Tags System Setting
|
||||
// @Summary Update system terminal setting
|
||||
// @Accept json
|
||||
// @Param request body dto.TerminalInfo true "request"
|
||||
// @Param request body dto.TerminalUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /core/settings/terminal/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统终端配置","formatEN":"update system terminal setting"}
|
||||
func (b *BaseApi) UpdateTerminalSetting(c *gin.Context) {
|
||||
var req dto.TerminalInfo
|
||||
var req dto.TerminalUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -236,16 +236,31 @@ type MenuLabelSort struct {
|
||||
}
|
||||
|
||||
type TerminalInfo struct {
|
||||
LineHeight string `json:"lineHeight"`
|
||||
LetterSpacing string `json:"letterSpacing"`
|
||||
FontSize string `json:"fontSize"`
|
||||
FontFamily string `json:"fontFamily"`
|
||||
BackgroundColor string `json:"backgroundColor"`
|
||||
ForegroundColor string `json:"foregroundColor"`
|
||||
CursorBlink string `json:"cursorBlink"`
|
||||
CursorStyle string `json:"cursorStyle"`
|
||||
Scrollback string `json:"scrollback"`
|
||||
ScrollSensitivity string `json:"scrollSensitivity"`
|
||||
ShowTerminalButton string `json:"showTerminalButton"`
|
||||
LineHeight string `json:"lineHeight"`
|
||||
LetterSpacing string `json:"letterSpacing"`
|
||||
FontSize string `json:"fontSize"`
|
||||
FontFamily string `json:"fontFamily"`
|
||||
BackgroundColor string `json:"backgroundColor"`
|
||||
ForegroundColor string `json:"foregroundColor"`
|
||||
CursorBlink string `json:"cursorBlink"`
|
||||
CursorStyle string `json:"cursorStyle"`
|
||||
Scrollback string `json:"scrollback"`
|
||||
ScrollSensitivity string `json:"scrollSensitivity"`
|
||||
}
|
||||
|
||||
type TerminalUpdate struct {
|
||||
ShowTerminalButton *string `json:"showTerminalButton,omitempty" validate:"omitempty,oneof=Enable Disable"`
|
||||
LineHeight *string `json:"lineHeight,omitempty"`
|
||||
LetterSpacing *string `json:"letterSpacing,omitempty"`
|
||||
FontSize *string `json:"fontSize,omitempty"`
|
||||
FontFamily *string `json:"fontFamily,omitempty"`
|
||||
BackgroundColor *string `json:"backgroundColor,omitempty"`
|
||||
ForegroundColor *string `json:"foregroundColor,omitempty"`
|
||||
CursorBlink *string `json:"cursorBlink,omitempty"`
|
||||
CursorStyle *string `json:"cursorStyle,omitempty"`
|
||||
Scrollback *string `json:"scrollback,omitempty"`
|
||||
ScrollSensitivity *string `json:"scrollSensitivity,omitempty"`
|
||||
}
|
||||
|
||||
type AppstoreUpdate struct {
|
||||
|
||||
@@ -57,7 +57,7 @@ type ISettingService interface {
|
||||
UpdateProxy(req dto.ProxyUpdate) error
|
||||
|
||||
GetTerminalInfo() (*dto.TerminalInfo, error)
|
||||
UpdateTerminal(req dto.TerminalInfo) error
|
||||
UpdateTerminal(req dto.TerminalUpdate) error
|
||||
|
||||
UpdateSystemSSL() error
|
||||
GenerateRSAKey() error
|
||||
@@ -559,7 +559,7 @@ func (u *SettingService) GetTerminalInfo() (*dto.TerminalInfo, error) {
|
||||
for _, set := range setting {
|
||||
settingMap[set.Key] = set.Value
|
||||
}
|
||||
var info dto.TerminalInfo
|
||||
info := dto.TerminalInfo{ShowTerminalButton: "Enable"}
|
||||
arr, err := json.Marshal(settingMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -569,39 +569,30 @@ func (u *SettingService) GetTerminalInfo() (*dto.TerminalInfo, error) {
|
||||
}
|
||||
return &info, err
|
||||
}
|
||||
func (u *SettingService) UpdateTerminal(req dto.TerminalInfo) error {
|
||||
if err := settingRepo.UpdateOrCreate("LineHeight", req.LineHeight); err != nil {
|
||||
return err
|
||||
func (u *SettingService) UpdateTerminal(req dto.TerminalUpdate) error {
|
||||
settings := []struct {
|
||||
key string
|
||||
value *string
|
||||
}{
|
||||
{"ShowTerminalButton", req.ShowTerminalButton},
|
||||
{"LineHeight", req.LineHeight},
|
||||
{"LetterSpacing", req.LetterSpacing},
|
||||
{"FontSize", req.FontSize},
|
||||
{"FontFamily", req.FontFamily},
|
||||
{"CursorBlink", req.CursorBlink},
|
||||
{"BackgroundColor", req.BackgroundColor},
|
||||
{"ForegroundColor", req.ForegroundColor},
|
||||
{"CursorStyle", req.CursorStyle},
|
||||
{"Scrollback", req.Scrollback},
|
||||
{"ScrollSensitivity", req.ScrollSensitivity},
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("LetterSpacing", req.LetterSpacing); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("FontSize", req.FontSize); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("FontFamily", req.FontFamily); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("CursorBlink", req.CursorBlink); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("BackgroundColor", req.BackgroundColor); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("ForegroundColor", req.ForegroundColor); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("CursorBlink", req.CursorBlink); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("CursorStyle", req.CursorStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("Scrollback", req.Scrollback); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate("ScrollSensitivity", req.ScrollSensitivity); err != nil {
|
||||
return err
|
||||
for _, setting := range settings {
|
||||
if setting.value == nil {
|
||||
continue
|
||||
}
|
||||
if err := settingRepo.UpdateOrCreate(setting.key, *setting.value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11683,7 +11683,7 @@ const docTemplate = `{
|
||||
"name": "request",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.TerminalInfo"
|
||||
"$ref": "#/definitions/dto.TerminalUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -40869,6 +40869,47 @@ const docTemplate = `{
|
||||
},
|
||||
"scrollback": {
|
||||
"type": "string"
|
||||
},
|
||||
"showTerminalButton": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"dto.TerminalUpdate": {
|
||||
"properties": {
|
||||
"backgroundColor": {
|
||||
"type": "string"
|
||||
},
|
||||
"cursorBlink": {
|
||||
"type": "string"
|
||||
},
|
||||
"cursorStyle": {
|
||||
"type": "string"
|
||||
},
|
||||
"fontFamily": {
|
||||
"type": "string"
|
||||
},
|
||||
"fontSize": {
|
||||
"type": "string"
|
||||
},
|
||||
"foregroundColor": {
|
||||
"type": "string"
|
||||
},
|
||||
"letterSpacing": {
|
||||
"type": "string"
|
||||
},
|
||||
"lineHeight": {
|
||||
"type": "string"
|
||||
},
|
||||
"scrollSensitivity": {
|
||||
"type": "string"
|
||||
},
|
||||
"scrollback": {
|
||||
"type": "string"
|
||||
},
|
||||
"showTerminalButton": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
||||
@@ -11679,7 +11679,7 @@
|
||||
"name": "request",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.TerminalInfo"
|
||||
"$ref": "#/definitions/dto.TerminalUpdate"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -40865,6 +40865,47 @@
|
||||
},
|
||||
"scrollback": {
|
||||
"type": "string"
|
||||
},
|
||||
"showTerminalButton": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"dto.TerminalUpdate": {
|
||||
"properties": {
|
||||
"backgroundColor": {
|
||||
"type": "string"
|
||||
},
|
||||
"cursorBlink": {
|
||||
"type": "string"
|
||||
},
|
||||
"cursorStyle": {
|
||||
"type": "string"
|
||||
},
|
||||
"fontFamily": {
|
||||
"type": "string"
|
||||
},
|
||||
"fontSize": {
|
||||
"type": "string"
|
||||
},
|
||||
"foregroundColor": {
|
||||
"type": "string"
|
||||
},
|
||||
"letterSpacing": {
|
||||
"type": "string"
|
||||
},
|
||||
"lineHeight": {
|
||||
"type": "string"
|
||||
},
|
||||
"scrollSensitivity": {
|
||||
"type": "string"
|
||||
},
|
||||
"scrollback": {
|
||||
"type": "string"
|
||||
},
|
||||
"showTerminalButton": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
||||
@@ -101,6 +101,7 @@ export namespace Setting {
|
||||
dashboardSimpleNodeVisible: string;
|
||||
}
|
||||
export interface TerminalInfo {
|
||||
showTerminalButton?: string;
|
||||
lineHeight: string;
|
||||
letterSpacing: string;
|
||||
fontSize: string;
|
||||
|
||||
@@ -126,7 +126,7 @@ export const getSettingBaseInfo = () => {
|
||||
export const getTerminalInfo = () => {
|
||||
return http.post<Setting.TerminalInfo>(`/core/settings/terminal/search`);
|
||||
};
|
||||
export const UpdateTerminalInfo = (param: Setting.TerminalInfo) => {
|
||||
export const UpdateTerminalInfo = (param: Partial<Setting.TerminalInfo>) => {
|
||||
return http.post(`/core/settings/terminal/update`, param);
|
||||
};
|
||||
export const getSystemAvailable = () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<!-- Right edge handle: open a terminal from any page without leaving it. Hidden on the terminal page itself. -->
|
||||
<div v-if="!onTerminalPage" class="terminal-dock-handle" @click="show">
|
||||
<div v-if="terminalStore.showTerminalButton && !onTerminalPage" class="terminal-dock-handle" @click="show">
|
||||
<el-badge
|
||||
:value="store.entries.length"
|
||||
:hidden="store.entries.length === 0"
|
||||
@@ -143,11 +143,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import i18n from '@/lang';
|
||||
import { ElTree } from 'element-plus';
|
||||
import { TerminalSessionStore } from '@/store';
|
||||
import { TerminalSessionStore, TerminalStore } from '@/store';
|
||||
import { getTerminalInfo } from '@/api/modules/setting';
|
||||
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||
import { getHostTree, testByID, testLocalConn } from '@/api/modules/terminal';
|
||||
import { MsgError } from '@/utils/message';
|
||||
@@ -155,10 +156,16 @@ import { ElMessageBox } from 'element-plus';
|
||||
import { Host } from '@/api/interface/host';
|
||||
|
||||
const store = TerminalSessionStore();
|
||||
const terminalStore = TerminalStore();
|
||||
const { isNodeAdmin } = useGlobalStore();
|
||||
const route = useRoute();
|
||||
const onTerminalPage = computed(() => route.path.startsWith('/terminal'));
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await getTerminalInfo();
|
||||
terminalStore.showTerminalButton = res.data.showTerminalButton !== 'Disable';
|
||||
});
|
||||
|
||||
const open = ref(false);
|
||||
const active = ref('');
|
||||
const showConnections = ref(false);
|
||||
|
||||
@@ -2068,6 +2068,8 @@ const message = {
|
||||
profileBlockDesc: 'Measures blocking on channels, select statements, and synchronization primitives.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'Show Terminal Button',
|
||||
showTerminalButtonHelper: 'Show the terminal shortcut button in the bottom-right corner of the page.',
|
||||
local: 'Local',
|
||||
defaultConn: 'Default Connection',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2107,6 +2107,8 @@ const message = {
|
||||
profileBlockDesc: 'Mide los bloqueos en canales, select y primitivas de sincronización.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'Mostrar botón de terminal',
|
||||
showTerminalButtonHelper: 'Mostrar el botón de acceso al terminal en la esquina inferior derecha de la página.',
|
||||
local: 'Local',
|
||||
defaultConn: 'Conexión predeterminada',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2049,6 +2049,8 @@ const message = {
|
||||
profileBlockDesc: 'زمان انسداد روی Channel، Select و ابزارهای همگامسازی را اندازهگیری میکند.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'نمایش دکمه ترمینال',
|
||||
showTerminalButtonHelper: 'نمایش دکمه میانبر ترمینال در گوشه پایین سمت راست صفحه.',
|
||||
local: 'محلی',
|
||||
defaultConn: 'اتصال پیشفرض',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2057,6 +2057,8 @@ const message = {
|
||||
profileBlockDesc: 'Channel、Select、同期プリミティブでのブロック待機時間を測定します。',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'ターミナルボタンを表示',
|
||||
showTerminalButtonHelper: 'ページの右下にターミナルのショートカットボタンを表示します。',
|
||||
local: 'ローカル',
|
||||
defaultConn: 'デフォルト接続',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2031,6 +2031,8 @@ const message = {
|
||||
profileBlockDesc: 'Channel, Select 및 동기화 프리미티브의 차단 대기 시간을 측정합니다.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: '터미널 버튼 표시',
|
||||
showTerminalButtonHelper: '페이지 오른쪽 아래에 터미널 바로가기 버튼을 표시합니다.',
|
||||
local: '로컬',
|
||||
defaultConn: '기본 연결',
|
||||
defaultConnHelper: '이 작업은 【{0}】의 터미널을 연 후 자동으로 노드 터미널에 연결됩니다. 계속하시겠습니까?',
|
||||
|
||||
@@ -2015,6 +2015,8 @@ const message = {
|
||||
profileBlockDesc: 'ວັດແທກການບລັອກໃນ Channel, Select Statement ແລະ ກົນໄກ Synchronization.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'ສະແດງປຸ່ມ Terminal',
|
||||
showTerminalButtonHelper: 'ສະແດງປຸ່ມທາງລັດ Terminal ຢູ່ມຸມຂວາລຸ່ມຂອງໜ້າ.',
|
||||
local: 'ພາຍໃນເຄື່ອງ (Local)',
|
||||
defaultConn: 'ການເຊື່ອມຕໍ່ເລີ່ມຕົ້ນ',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2095,6 +2095,8 @@ const message = {
|
||||
profileBlockDesc: 'Mengukur sekatan pada Channel, Select dan primitif penyegerakan.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'Papar Butang Terminal',
|
||||
showTerminalButtonHelper: 'Paparkan butang pintasan terminal di sudut kanan bawah halaman.',
|
||||
local: 'Tempatan',
|
||||
defaultConn: 'Sambungan Lalai',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2100,6 +2100,8 @@ const message = {
|
||||
profileBlockDesc: 'Mede bloqueios em canais, select e primitivas de sincronização.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'Mostrar botão do terminal',
|
||||
showTerminalButtonHelper: 'Mostrar o botão de acesso ao terminal no canto inferior direito da página.',
|
||||
local: 'Local',
|
||||
defaultConn: 'Conexão Padrão',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2081,6 +2081,8 @@ const message = {
|
||||
profileBlockDesc: 'Измеряет блокировки на каналах, select и примитивах синхронизации.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'Показывать кнопку терминала',
|
||||
showTerminalButtonHelper: 'Показывать кнопку быстрого доступа к терминалу в правом нижнем углу страницы.',
|
||||
local: 'Локальный',
|
||||
defaultConn: 'Соединение по умолчанию',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -2087,6 +2087,8 @@ const message = {
|
||||
profileBlockDesc: 'Channel, select ve eşzamanlama araçlarındaki engelleme süresini ölçer.',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: 'Terminal düğmesini göster',
|
||||
showTerminalButtonHelper: 'Sayfanın sağ alt köşesinde terminal kısayol düğmesini gösterir.',
|
||||
local: 'Yerel',
|
||||
defaultConn: 'Varsayılan Bağlantı',
|
||||
defaultConnHelper:
|
||||
|
||||
@@ -1954,6 +1954,8 @@ const message = {
|
||||
profileBlockDesc: '統計 Channel、Select 和同步原語的阻塞等待,用於定位長時間阻塞。',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: '顯示終端按鈕',
|
||||
showTerminalButtonHelper: '在頁面右下角顯示終端快捷按鈕。',
|
||||
local: '本機',
|
||||
defaultConn: '預設連接',
|
||||
defaultConnHelper: '該操作將【{0}】開啟終端後自動連線到所在節點終端,是否繼續?',
|
||||
|
||||
@@ -1984,6 +1984,8 @@ const message = {
|
||||
profileBlockDesc: '统计 Channel、Select 和同步原语的阻塞等待,用于定位长时间阻塞。',
|
||||
},
|
||||
terminal: {
|
||||
showTerminalButton: '显示终端按钮',
|
||||
showTerminalButtonHelper: '在页面右下角显示终端快捷按钮。',
|
||||
local: '本机',
|
||||
defaultConn: '默认连接',
|
||||
defaultConnHelper: '该操作将【{0}】打开终端后自动连接所在节点终端,是否继续?',
|
||||
|
||||
@@ -84,6 +84,7 @@ export interface MenuState {
|
||||
}
|
||||
|
||||
export interface TerminalState {
|
||||
showTerminalButton: boolean;
|
||||
lineHeight: number;
|
||||
letterSpacing: number;
|
||||
fontSize: number;
|
||||
|
||||
@@ -5,6 +5,7 @@ import { TerminalState } from '../interface';
|
||||
|
||||
export const TerminalStore = defineStore('TerminalState', {
|
||||
state: (): TerminalState => ({
|
||||
showTerminalButton: true,
|
||||
lineHeight: 1.2,
|
||||
letterSpacing: 1.2,
|
||||
fontSize: 12,
|
||||
|
||||
@@ -68,6 +68,7 @@ const handleChange = (tab: any) => {
|
||||
const loadTerminalSetting = async () => {
|
||||
await getTerminalInfo().then((res) => {
|
||||
terminalStore.$patch({
|
||||
showTerminalButton: res.data.showTerminalButton !== 'Disable',
|
||||
lineHeight: Number(res.data.lineHeight),
|
||||
letterSpacing: Number(res.data.letterSpacing),
|
||||
fontSize: Number(res.data.fontSize),
|
||||
|
||||
@@ -126,6 +126,13 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider border-style="dashed" />
|
||||
|
||||
<el-form-item :label="$t('terminal.showTerminalButton')">
|
||||
<el-switch v-model="form.showTerminalButton" @change="changeTerminalButton" />
|
||||
<span class="input-help">{{ $t('terminal.showTerminalButtonHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
@@ -182,6 +189,7 @@ const fontFamilyOptions = [
|
||||
];
|
||||
|
||||
const form = reactive({
|
||||
showTerminalButton: true,
|
||||
lineHeight: 1.2,
|
||||
letterSpacing: 1.2,
|
||||
fontSize: 12,
|
||||
@@ -254,6 +262,7 @@ const search = async (withReset?: boolean) => {
|
||||
await getTerminalInfo()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
form.showTerminalButton = res.data.showTerminalButton !== 'Disable';
|
||||
form.lineHeight = Number(res.data.lineHeight);
|
||||
form.letterSpacing = Number(res.data.letterSpacing);
|
||||
form.fontSize = Number(res.data.fontSize);
|
||||
@@ -276,6 +285,22 @@ const search = async (withReset?: boolean) => {
|
||||
});
|
||||
};
|
||||
|
||||
const changeTerminalButton = async () => {
|
||||
const showTerminalButton = form.showTerminalButton;
|
||||
loading.value = true;
|
||||
try {
|
||||
await UpdateTerminalInfo({
|
||||
showTerminalButton: showTerminalButton ? 'Enable' : 'Disable',
|
||||
});
|
||||
terminalStore.showTerminalButton = showTerminalButton;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
} catch {
|
||||
form.showTerminalButton = !showTerminalButton;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const loadConnShow = async () => {
|
||||
await loadLocalConn().then((res) => {
|
||||
form.showDefaultConn = res.data.localSSHConnShow === 'Enable';
|
||||
|
||||
Reference in New Issue
Block a user