mirror of
https://github.com/louislam/dockge.git
synced 2026-05-22 14:32:16 +00:00
Compare commits
3 Commits
codemirror
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f2c091175 | ||
|
|
f809ae192b | ||
|
|
749e2c5c88 |
@@ -553,7 +553,7 @@ export class Stack {
|
|||||||
|
|
||||||
async startService(socket: DockgeSocket, serviceName: string) {
|
async startService(socket: DockgeSocket, serviceName: string) {
|
||||||
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
||||||
const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "up", "-d", serviceName], this.path);
|
const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "up", "-d", serviceName ], this.path);
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
throw new Error(`Failed to start service ${serviceName}, please check logs for more information.`);
|
throw new Error(`Failed to start service ${serviceName}, please check logs for more information.`);
|
||||||
}
|
}
|
||||||
@@ -563,7 +563,7 @@ export class Stack {
|
|||||||
|
|
||||||
async stopService(socket: DockgeSocket, serviceName: string): Promise<number> {
|
async stopService(socket: DockgeSocket, serviceName: string): Promise<number> {
|
||||||
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
||||||
const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "stop", serviceName], this.path);
|
const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "stop", serviceName ], this.path);
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
throw new Error(`Failed to stop service ${serviceName}, please check logs for more information.`);
|
throw new Error(`Failed to stop service ${serviceName}, please check logs for more information.`);
|
||||||
}
|
}
|
||||||
@@ -573,7 +573,7 @@ export class Stack {
|
|||||||
|
|
||||||
async restartService(socket: DockgeSocket, serviceName: string): Promise<number> {
|
async restartService(socket: DockgeSocket, serviceName: string): Promise<number> {
|
||||||
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
|
||||||
const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "restart", serviceName], this.path);
|
const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "restart", serviceName ], this.path);
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
throw new Error(`Failed to restart service ${serviceName}, please check logs for more information.`);
|
throw new Error(`Failed to restart service ${serviceName}, please check logs for more information.`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,24 +21,30 @@
|
|||||||
<font-awesome-icon icon="terminal" />
|
<font-awesome-icon icon="terminal" />
|
||||||
Bash
|
Bash
|
||||||
</router-link>
|
</router-link>
|
||||||
<button v-if="this.serviceCount > 1 && !isEditMode && status !== 'running' && status !== 'healthy'"
|
<button
|
||||||
|
v-if="serviceCount > 1 && !isEditMode && status !== 'running' && status !== 'healthy'"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
:disabled="processing"
|
:disabled="processing"
|
||||||
@click="startService">
|
@click="startService"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="play" class="me-1" />
|
<font-awesome-icon icon="play" class="me-1" />
|
||||||
{{ $t("startStack") }}
|
{{ $t("startStack") }}
|
||||||
</button>
|
</button>
|
||||||
<button v-if="this.serviceCount > 1 && !isEditMode && (status === 'running' || status === 'healthy' || status === 'unhealthy')"
|
<button
|
||||||
|
v-if="serviceCount > 1 && !isEditMode && (status === 'running' || status === 'healthy' || status === 'unhealthy')"
|
||||||
class="btn btn-normal"
|
class="btn btn-normal"
|
||||||
:disabled="processing"
|
:disabled="processing"
|
||||||
@click="restartService">
|
@click="restartService"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="rotate" class="me-1" />
|
<font-awesome-icon icon="rotate" class="me-1" />
|
||||||
{{ $t("restartStack") }}
|
{{ $t("restartStack") }}
|
||||||
</button>
|
</button>
|
||||||
<button v-if="this.serviceCount > 1 && !isEditMode && (status === 'running' || status === 'healthy' || status === 'unhealthy')"
|
<button
|
||||||
|
v-if="serviceCount > 1 && !isEditMode && (status === 'running' || status === 'healthy' || status === 'unhealthy')"
|
||||||
class="btn btn-normal"
|
class="btn btn-normal"
|
||||||
:disabled="processing"
|
:disabled="processing"
|
||||||
@click="stopService">
|
@click="stopService"
|
||||||
|
>
|
||||||
<font-awesome-icon icon="stop" class="me-1" />
|
<font-awesome-icon icon="stop" class="me-1" />
|
||||||
{{ $t("stopStack") }}
|
{{ $t("stopStack") }}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<div class="header-top">
|
<div class="header-top">
|
||||||
<!-- TODO -->
|
<!-- TODO -->
|
||||||
<button v-if="false" class="btn btn-outline-normal ms-2" :class="{ 'active': selectMode }" type="button"
|
<button
|
||||||
@click="selectMode = !selectMode">
|
v-if="false" class="btn btn-outline-normal ms-2" :class="{ 'active': selectMode }" type="button"
|
||||||
|
@click="selectMode = !selectMode"
|
||||||
|
>
|
||||||
{{ $t("Select") }}
|
{{ $t("Select") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -31,10 +33,14 @@
|
|||||||
<div v-if="selectMode && false" class="selection-controls px-2 pt-2">
|
<div v-if="selectMode && false" class="selection-controls px-2 pt-2">
|
||||||
<input v-model="selectAll" class="form-check-input select-input" type="checkbox" />
|
<input v-model="selectAll" class="form-check-input select-input" type="checkbox" />
|
||||||
|
|
||||||
<button class="btn-outline-normal" @click="pauseDialog"><font-awesome-icon icon="pause" size="sm" /> {{
|
<button class="btn-outline-normal" @click="pauseDialog">
|
||||||
$t("Pause") }}</button>
|
<font-awesome-icon icon="pause" size="sm" /> {{
|
||||||
<button class="btn-outline-normal" @click="resumeSelected"><font-awesome-icon icon="play" size="sm" />
|
$t("Pause") }}
|
||||||
{{ $t("Resume") }}</button>
|
</button>
|
||||||
|
<button class="btn-outline-normal" @click="resumeSelected">
|
||||||
|
<font-awesome-icon icon="play" size="sm" />
|
||||||
|
{{ $t("Resume") }}
|
||||||
|
</button>
|
||||||
|
|
||||||
<span v-if="selectedStackCount > 0">
|
<span v-if="selectedStackCount > 0">
|
||||||
{{ $t("selectedStackCount", [selectedStackCount]) }}
|
{{ $t("selectedStackCount", [selectedStackCount]) }}
|
||||||
@@ -45,9 +51,11 @@
|
|||||||
<div v-if="agentStackList[0] && agentStackList[0].stacks.length === 0" class="text-center mt-3">
|
<div v-if="agentStackList[0] && agentStackList[0].stacks.length === 0" class="text-center mt-3">
|
||||||
<router-link to="/compose">{{ $t("addFirstStackMsg") }}</router-link>
|
<router-link to="/compose">{{ $t("addFirstStackMsg") }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="stack-list-inner" v-for="(agent, index) in agentStackList" :key="index">
|
<div v-for="(agent, agentIndex) in agentStackList" :key="agentIndex" class="stack-list-inner">
|
||||||
<div v-if="$root.agentCount > 1" class="p-2 agent-select"
|
<div
|
||||||
@click="closedAgents.set(agent.endpoint, !closedAgents.get(agent.endpoint))">
|
v-if="$root.agentCount > 1" class="p-2 agent-select"
|
||||||
|
@click="closedAgents.set(agent.endpoint, !closedAgents.get(agent.endpoint))"
|
||||||
|
>
|
||||||
<span class="me-1">
|
<span class="me-1">
|
||||||
<font-awesome-icon v-show="closedAgents.get(agent.endpoint)" icon="chevron-circle-right" />
|
<font-awesome-icon v-show="closedAgents.get(agent.endpoint)" icon="chevron-circle-right" />
|
||||||
<font-awesome-icon v-show="!closedAgents.get(agent.endpoint)" icon="chevron-circle-down" />
|
<font-awesome-icon v-show="!closedAgents.get(agent.endpoint)" icon="chevron-circle-down" />
|
||||||
@@ -55,9 +63,11 @@
|
|||||||
<span v-if="agent.endpoint === 'current'">{{ $t("currentEndpoint") }}</span>
|
<span v-if="agent.endpoint === 'current'">{{ $t("currentEndpoint") }}</span>
|
||||||
<span v-else>{{ agent.endpoint }}</span>
|
<span v-else>{{ agent.endpoint }}</span>
|
||||||
</div>
|
</div>
|
||||||
<StackListItem v-show="$root.agentCount === 1 || !closedAgents.get(agent.endpoint)"
|
<StackListItem
|
||||||
v-for="(item, index) in agent.stacks" :key="index" :stack="item" :isSelectMode="selectMode"
|
v-for="(item, index) in agent.stacks"
|
||||||
:isSelected="isSelected" :select="select" :deselect="deselect" />
|
v-show="$root.agentCount === 1 || !closedAgents.get(agent.endpoint)" :key="index" :stack="item" :isSelectMode="selectMode"
|
||||||
|
:isSelected="isSelected" :select="select" :deselect="deselect"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -195,20 +205,20 @@ export default {
|
|||||||
// and the rest are sorted alphabetically
|
// and the rest are sorted alphabetically
|
||||||
result = [
|
result = [
|
||||||
...result.reduce((acc, stack) => {
|
...result.reduce((acc, stack) => {
|
||||||
const endpoint = stack.endpoint || 'current';
|
const endpoint = stack.endpoint || "current";
|
||||||
if (!acc.has(endpoint)) {
|
if (!acc.has(endpoint)) {
|
||||||
acc.set(endpoint, []);
|
acc.set(endpoint, []);
|
||||||
}
|
}
|
||||||
acc.get(endpoint).push(stack);
|
acc.get(endpoint).push(stack);
|
||||||
return acc;
|
return acc;
|
||||||
}, new Map()).entries()
|
}, new Map()).entries()
|
||||||
].map(([endpoint, stacks]) => ({
|
].map(([ endpoint, stacks ]) => ({
|
||||||
endpoint,
|
endpoint,
|
||||||
stacks
|
stacks
|
||||||
})).sort((a, b) => {
|
})).sort((a, b) => {
|
||||||
if (a.endpoint === 'current' && b.endpoint !== 'current') {
|
if (a.endpoint === "current" && b.endpoint !== "current") {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (a.endpoint !== 'current' && b.endpoint === 'current') {
|
} else if (a.endpoint !== "current" && b.endpoint === "current") {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return a.endpoint.localeCompare(b.endpoint);
|
return a.endpoint.localeCompare(b.endpoint);
|
||||||
|
|||||||
@@ -20,22 +20,24 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
require: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
endpoint: {
|
endpoint: {
|
||||||
type: String,
|
type: String,
|
||||||
require: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Require if mode is interactive
|
// Require if mode is interactive
|
||||||
stackName: {
|
stackName: {
|
||||||
type: String,
|
type: String,
|
||||||
|
default: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Require if mode is interactive
|
// Require if mode is interactive
|
||||||
serviceName: {
|
serviceName: {
|
||||||
type: String,
|
type: String,
|
||||||
|
default: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Require if mode is interactive
|
// Require if mode is interactive
|
||||||
@@ -102,7 +104,7 @@ export default {
|
|||||||
this.terminal.focus();
|
this.terminal.focus();
|
||||||
|
|
||||||
// Add right-click context menu handler for paste
|
// Add right-click context menu handler for paste
|
||||||
this.$refs.terminal.addEventListener('contextmenu', this.handleContextMenu);
|
this.$refs.terminal.addEventListener("contextmenu", this.handleContextMenu);
|
||||||
|
|
||||||
// Add selection handler for copy to clipboard
|
// Add selection handler for copy to clipboard
|
||||||
this.terminal.onSelectionChange(() => {
|
this.terminal.onSelectionChange(() => {
|
||||||
@@ -143,7 +145,7 @@ export default {
|
|||||||
window.removeEventListener("resize", this.onResizeEvent); // Remove the resize event listener from the window object.
|
window.removeEventListener("resize", this.onResizeEvent); // Remove the resize event listener from the window object.
|
||||||
this.$root.unbindTerminal(this.name);
|
this.$root.unbindTerminal(this.name);
|
||||||
this.terminal.dispose();
|
this.terminal.dispose();
|
||||||
this.$refs.terminal?.removeEventListener('contextmenu', this.handleContextMenu);
|
this.$refs.terminal?.removeEventListener("contextmenu", this.handleContextMenu);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ export default {
|
|||||||
EditorView.focusChangeEffect.of(focusEffectHandler),
|
EditorView.focusChangeEffect.of(focusEffectHandler),
|
||||||
];
|
];
|
||||||
|
|
||||||
return { editorFocus, extensionsEnv };
|
return { editorFocus,
|
||||||
|
extensionsEnv };
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -94,10 +94,18 @@
|
|||||||
<TwoFADialog ref="TwoFADialog" />
|
<TwoFADialog ref="TwoFADialog" />
|
||||||
|
|
||||||
<Confirm ref="confirmDisableAuth" btn-style="btn-danger" :yes-text="$t('I understand, please disable')" :no-text="$t('Leave')" @yes="disableAuth">
|
<Confirm ref="confirmDisableAuth" btn-style="btn-danger" :yes-text="$t('I understand, please disable')" :no-text="$t('Leave')" @yes="disableAuth">
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
<i18n-t keypath="disableauth.message1" tag="p">
|
||||||
<p v-html="$t('disableauth.message1')"></p>
|
<template #disableAuth>
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
<strong>{{ $t('disableAuth') }}</strong>
|
||||||
<p v-html="$t('disableauth.message2')"></p>
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
|
||||||
|
<i18n-t keypath="disableauth.message2" tag="p">
|
||||||
|
<template #scenarios>
|
||||||
|
<strong>{{ $t('scenarios') }}</strong>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
|
||||||
<p>{{ $t("Please use this option carefully!") }}</p>
|
<p>{{ $t("Please use this option carefully!") }}</p>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
|||||||
@@ -47,8 +47,10 @@
|
|||||||
"deleteContainer": "Delete",
|
"deleteContainer": "Delete",
|
||||||
"addContainer": "Add Container",
|
"addContainer": "Add Container",
|
||||||
"addNetwork": "Add Network",
|
"addNetwork": "Add Network",
|
||||||
"disableauth.message1": "Are you sure want to <strong>disable authentication</strong>?",
|
"disableauth.message1": "Are you sure want to {disableAuth}?",
|
||||||
"disableauth.message2": "It is designed for scenarios <strong>where you intend to implement third-party authentication</strong> in front of Dockge such as Cloudflare Access, Authelia or other authentication mechanisms.",
|
"disableauth.message2": "It is designed for scenarios {scenarios}",
|
||||||
|
"disableAuth": "disable authentication",
|
||||||
|
"scenarios": "where you intend to implement third-party authentication",
|
||||||
"passwordNotMatchMsg": "The repeat password does not match.",
|
"passwordNotMatchMsg": "The repeat password does not match.",
|
||||||
"autoGet": "Auto Get",
|
"autoGet": "Auto Get",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
@@ -139,8 +141,12 @@
|
|||||||
"networkIO": "Network I/O",
|
"networkIO": "Network I/O",
|
||||||
"blockIO": "Block I/O",
|
"blockIO": "Block I/O",
|
||||||
"Console is not enabled": "Console is not enabled",
|
"Console is not enabled": "Console is not enabled",
|
||||||
"ConsoleNotEnabledMSG1": "Console is a powerful tool that allows you to execute any commands such as <code>docker</code>, <code>rm</code> within the Dockge's container in this Web UI.",
|
"ConsoleNotEnabledMSG1": "Console is a powerful tool that allows you to execute any commands such as {docker}, {rm} within the Dockge's container in this Web UI.",
|
||||||
"ConsoleNotEnabledMSG2": "It might be dangerous since this Dockge container is connecting to the host's Docker daemon. Also Dockge could be possibly taken down by commands like <code>rm -rf</code>" ,
|
"ConsoleNotEnabledMSG2": "It might be dangerous since this Dockge container is connecting to the host's Docker daemon. Also Dockge could be possibly taken down by commands like {rmRf}",
|
||||||
"ConsoleNotEnabledMSG3": "If you understand the risk, you can enable it by setting <code>DOCKGE_ENABLE_CONSOLE=true</code> in the environment variables.",
|
"ConsoleNotEnabledMSG3": "If you understand the risk, you can enable it by setting {envVar} in the environment variables.",
|
||||||
|
"dockerCode": "docker",
|
||||||
|
"rmCode": "rm",
|
||||||
|
"rmRfCode": "rm -rf",
|
||||||
|
"envVarCode": "DOCKGE_ENABLE_CONSOLE=true",
|
||||||
"confirmLeaveStack": "You are currently editing a stack. Are you sure you want to leave?"
|
"confirmLeaveStack": "You are currently editing a stack. Are you sure you want to leave?"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
endpointDisplayFunction(endpoint : string) {
|
endpointDisplayFunction(endpoint : string) {
|
||||||
for (const [k, v] of Object.entries(this.$data.agentList)) {
|
for (const [ k, v ] of Object.entries(this.$data.agentList)) {
|
||||||
if (endpoint) {
|
if (endpoint) {
|
||||||
if (endpoint === v["endpoint"] && v["name"] !== "") {
|
if (endpoint === v["endpoint"] && v["name"] !== "") {
|
||||||
return v["name"];
|
return v["name"];
|
||||||
|
|||||||
@@ -221,6 +221,15 @@
|
|||||||
<NetworkInput />
|
<NetworkInput />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="shadow-box big-padding mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label"> Search Templates</label>
|
||||||
|
<input id="name" v-model="name" type="text" class="form-control" placeholder="Search..." required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<prism-editor v-if="false" v-model="yamlConfig" class="yaml-editor" :highlight="highlighter" line-numbers @input="yamlCodeChange"></prism-editor>
|
||||||
|
</div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -241,9 +250,9 @@ import CodeMirror from "vue-codemirror6";
|
|||||||
import { yaml } from "@codemirror/lang-yaml";
|
import { yaml } from "@codemirror/lang-yaml";
|
||||||
import { python } from "@codemirror/lang-python";
|
import { python } from "@codemirror/lang-python";
|
||||||
import { dracula as editorTheme } from "thememirror";
|
import { dracula as editorTheme } from "thememirror";
|
||||||
import { lineNumbers, EditorView, Decoration, ViewPlugin } from "@codemirror/view";
|
import { lineNumbers, EditorView } from "@codemirror/view";
|
||||||
import { parseDocument, Document } from "yaml";
|
import { parseDocument, Document } from "yaml";
|
||||||
import { RangeSetBuilder } from "@codemirror/state";
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||||
import {
|
import {
|
||||||
COMBINED_TERMINAL_COLS,
|
COMBINED_TERMINAL_COLS,
|
||||||
@@ -274,43 +283,6 @@ let yamlErrorTimeout = null;
|
|||||||
let serviceStatusTimeout = null;
|
let serviceStatusTimeout = null;
|
||||||
let dockerStatsTimeout = null;
|
let dockerStatsTimeout = null;
|
||||||
|
|
||||||
// Highlight $VAR and ${VAR}
|
|
||||||
const variableHighlight = ViewPlugin.fromClass(class {
|
|
||||||
constructor(view) {
|
|
||||||
this.decorations = this.buildDecorations(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(update) {
|
|
||||||
if (update.docChanged || update.viewportChanged) {
|
|
||||||
this.decorations = this.buildDecorations(update.view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildDecorations(view) {
|
|
||||||
const builder = new RangeSetBuilder();
|
|
||||||
|
|
||||||
for (const { from, to } of view.visibleRanges) {
|
|
||||||
const text = view.state.doc.sliceString(from, to);
|
|
||||||
const variableRegex = /\$\{?[A-Za-z0-9_]+\}?/g;
|
|
||||||
let match;
|
|
||||||
while ((match = variableRegex.exec(text)) !== null) {
|
|
||||||
const start = from + match.index;
|
|
||||||
const end = start + match[0].length;
|
|
||||||
|
|
||||||
builder.add(
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
Decoration.mark({ class: "cm-variable-highlight" })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.finish();
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
decorations: v => v.decorations
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
NetworkInput,
|
NetworkInput,
|
||||||
@@ -335,7 +307,6 @@ export default {
|
|||||||
const extensions = [
|
const extensions = [
|
||||||
editorTheme,
|
editorTheme,
|
||||||
yaml(),
|
yaml(),
|
||||||
variableHighlight,
|
|
||||||
lineNumbers(),
|
lineNumbers(),
|
||||||
EditorView.focusChangeEffect.of(focusEffectHandler)
|
EditorView.focusChangeEffect.of(focusEffectHandler)
|
||||||
];
|
];
|
||||||
@@ -343,13 +314,11 @@ export default {
|
|||||||
const extensionsEnv = [
|
const extensionsEnv = [
|
||||||
editorTheme,
|
editorTheme,
|
||||||
python(),
|
python(),
|
||||||
variableHighlight,
|
|
||||||
lineNumbers(),
|
lineNumbers(),
|
||||||
EditorView.focusChangeEffect.of(focusEffectHandler)
|
EditorView.focusChangeEffect.of(focusEffectHandler)
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return { extensions,
|
||||||
extensions,
|
|
||||||
extensionsEnv,
|
extensionsEnv,
|
||||||
editorFocus };
|
editorFocus };
|
||||||
},
|
},
|
||||||
@@ -804,7 +773,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
checkYAML() {
|
checkYAML() {
|
||||||
// TODO: implement validation
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addContainer() {
|
addContainer() {
|
||||||
@@ -884,11 +853,6 @@ export default {
|
|||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.cm-variable-highlight) {
|
|
||||||
color: #fe6000;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-box {
|
.editor-box {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|||||||
@@ -7,9 +7,22 @@
|
|||||||
|
|
||||||
<div v-else class="alert alert-warning shadow-box" role="alert">
|
<div v-else class="alert alert-warning shadow-box" role="alert">
|
||||||
<h4 class="alert-heading">{{ $t("Console is not enabled") }}</h4>
|
<h4 class="alert-heading">{{ $t("Console is not enabled") }}</h4>
|
||||||
<p v-html="$t('ConsoleNotEnabledMSG1')"></p>
|
<i18n-t keypath="ConsoleNotEnabledMSG1" tag="p">
|
||||||
<p v-html="$t('ConsoleNotEnabledMSG2')"></p>
|
<template #docker><code>{{ $t('dockerCode') }}</code></template>
|
||||||
<p v-html="$t('ConsoleNotEnabledMSG3')"></p>
|
<template #rm><code>{{ $t('rmCode') }}</code></template>
|
||||||
|
</i18n-t>
|
||||||
|
|
||||||
|
<i18n-t keypath="ConsoleNotEnabledMSG2" tag="p">
|
||||||
|
<template #rmRf>
|
||||||
|
<code>{{ $t('rmRfCode') }}</code>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
|
||||||
|
<i18n-t keypath="ConsoleNotEnabledMSG3" tag="p">
|
||||||
|
<template #envVar>
|
||||||
|
<code>{{ $t('envVarCode') }}</code>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="slide-fade" appear>
|
<transition name="slide-fade" appear>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="mb-3">{{$t("terminal")}} - {{ serviceName }} ({{ stackName }})</h1>
|
<h1 class="mb-3">{{ $t("terminal") }} - {{ serviceName }} ({{ stackName }})</h1>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<router-link :to="sh" class="btn btn-normal me-2">{{ $t("Switch to sh") }}</router-link>
|
<router-link :to="sh" class="btn btn-normal me-2">{{ $t("Switch to sh") }}</router-link>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<div class="shadow-box big-padding">
|
<div class="shadow-box big-padding">
|
||||||
<h4 class="mb-3">{{ $tc("dockgeAgent", 2) }} <span class="badge bg-warning" style="font-size: 12px;">beta</span></h4>
|
<h4 class="mb-3">{{ $tc("dockgeAgent", 2) }} <span class="badge bg-warning" style="font-size: 12px;">beta</span></h4>
|
||||||
|
|
||||||
<div v-for="(agent, endpoint) in $root.agentList" :key="endpoint" class="mb-3 agent">
|
<div v-for="(agentItem, endpoint) in $root.agentList" :key="endpoint" class="mb-3 agent">
|
||||||
<!-- Agent Status -->
|
<!-- Agent Status -->
|
||||||
<template v-if="$root.agentStatusList[endpoint]">
|
<template v-if="$root.agentStatusList[endpoint]">
|
||||||
<span v-if="$root.agentStatusList[endpoint] === 'online'" class="badge bg-primary me-2">{{ $t("agentOnline") }}</span>
|
<span v-if="$root.agentStatusList[endpoint] === 'online'" class="badge bg-primary me-2">{{ $t("agentOnline") }}</span>
|
||||||
@@ -50,26 +50,26 @@
|
|||||||
|
|
||||||
<!-- Agent Display Name -->
|
<!-- Agent Display Name -->
|
||||||
<template v-if="$root.agentStatusList[endpoint]">
|
<template v-if="$root.agentStatusList[endpoint]">
|
||||||
<span v-if="endpoint === '' && agent.name === ''" class="badge bg-secondary me-2">Current</span>
|
<span v-if="endpoint === '' && agentItem.name === ''" class="badge bg-secondary me-2">Current</span>
|
||||||
<span v-else-if="agent.name === ''" :href="agent.url" class="me-2">{{ endpoint }}</span>
|
<span v-else-if="agentItem.name === ''" :href="agentItem.url" class="me-2">{{ endpoint }}</span>
|
||||||
<span v-else :href="agent.url" class="me-2">{{ agent.name }}</span>
|
<span v-else :href="agentItem.url" class="me-2">{{ agentItem.name }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Edit Name -->
|
<!-- Edit Name -->
|
||||||
<font-awesome-icon v-if="agent.name !== ''" icon="pen-to-square" @click="showEditAgentNameDialog[agent.name] = !showEditAgentNameDialog[agent.Name]" />
|
<font-awesome-icon v-if="agentItem.name !== ''" icon="pen-to-square" @click="showEditAgentNameDialog[agentItem.name] = !showEditAgentNameDialog[agentItem.Name]" />
|
||||||
|
|
||||||
<!-- Edit Dialog -->
|
<!-- Edit Dialog -->
|
||||||
<BModal v-model="showEditAgentNameDialog[agent.name]" :no-close-on-backdrop="true" :close-on-esc="true" :okTitle="$t('Update Name')" okVariant="info" @ok="updateName(agent.url, agent.updatedName)">
|
<BModal v-model="showEditAgentNameDialog[agentItem.name]" :no-close-on-backdrop="true" :close-on-esc="true" :okTitle="$t('Update Name')" okVariant="info" @ok="updateName(agentItem.url, agentItem.updatedName)">
|
||||||
<label for="Update Name" class="form-label">Current value: {{ $t(agent.name) }}</label>
|
<label for="Update Name" class="form-label">Current value: {{ $t(agentItem.name) }}</label>
|
||||||
<input id="updatedName" v-model="agent.updatedName" type="text" class="form-control" optional>
|
<input id="updatedName" v-model="agentItem.updatedName" type="text" class="form-control" optional>
|
||||||
</BModal>
|
</BModal>
|
||||||
|
|
||||||
<!-- Remove Button -->
|
<!-- Remove Button -->
|
||||||
<font-awesome-icon v-if="endpoint !== ''" class="ms-2 remove-agent" icon="trash" @click="showRemoveAgentDialog[agent.url] = !showRemoveAgentDialog[agent.url]" />
|
<font-awesome-icon v-if="endpoint !== ''" class="ms-2 remove-agent" icon="trash" @click="showRemoveAgentDialog[agentItem.url] = !showRemoveAgentDialog[agentItem.url]" />
|
||||||
|
|
||||||
<!-- Remove Agent Dialog -->
|
<!-- Remove Agent Dialog -->
|
||||||
<BModal v-model="showRemoveAgentDialog[agent.url]" :okTitle="$t('removeAgent')" okVariant="danger" @ok="removeAgent(agent.url)">
|
<BModal v-model="showRemoveAgentDialog[agentItem.url]" :okTitle="$t('removeAgent')" okVariant="danger" @ok="removeAgent(agentItem.url)">
|
||||||
<p>{{ agent.url }}</p>
|
<p>{{ agentItem.url }}</p>
|
||||||
{{ $t("removeAgentMsg") }}
|
{{ $t("removeAgentMsg") }}
|
||||||
</BModal>
|
</BModal>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
572
package-lock.json
generated
572
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -55,7 +55,7 @@
|
|||||||
"ts-command-line-args": "~2.5.1",
|
"ts-command-line-args": "~2.5.1",
|
||||||
"tsx": "~4.19.3",
|
"tsx": "~4.19.3",
|
||||||
"type-fest": "~4.3.3",
|
"type-fest": "~4.3.3",
|
||||||
"yaml": "~2.3.4"
|
"yaml": "~2.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^6.0.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user