Add URL and improve ArrayInput handling

This commit is contained in:
Louis Lam 2023-11-25 22:06:58 +08:00
parent f6fffcc064
commit 99eda980f8
5 changed files with 101 additions and 6 deletions

View file

@ -10,6 +10,8 @@ declare module 'vue' {
About: typeof import('./src/components/settings/About.vue')['default'] About: typeof import('./src/components/settings/About.vue')['default']
Appearance: typeof import('./src/components/settings/Appearance.vue')['default'] Appearance: typeof import('./src/components/settings/Appearance.vue')['default']
ArrayInput: typeof import('./src/components/ArrayInput.vue')['default'] ArrayInput: typeof import('./src/components/ArrayInput.vue')['default']
ArrayInputGeneral: typeof import('./src/components/ArrayInputGeneral.vue')['default']
ArrayInputXDockge: typeof import('./src/components/ArrayInputXDockge.vue')['default']
ArraySelect: typeof import('./src/components/ArraySelect.vue')['default'] ArraySelect: typeof import('./src/components/ArraySelect.vue')['default']
BDropdown: typeof import('bootstrap-vue-next')['BDropdown'] BDropdown: typeof import('bootstrap-vue-next')['BDropdown']
BDropdownItem: typeof import('bootstrap-vue-next')['BDropdownItem'] BDropdownItem: typeof import('bootstrap-vue-next')['BDropdownItem']

View file

@ -30,6 +30,10 @@ export default {
displayName: { displayName: {
type: String, type: String,
required: true, required: true,
},
objectType: {
type: String,
default: "service",
} }
}, },
data() { data() {
@ -41,8 +45,7 @@ export default {
array() { array() {
// Create the array if not exists, it should be safe. // Create the array if not exists, it should be safe.
if (!this.service[this.name]) { if (!this.service[this.name]) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties return [];
this.service[this.name] = [];
} }
return this.service[this.name]; return this.service[this.name];
}, },
@ -56,8 +59,24 @@ export default {
return this.service[this.name] !== undefined; return this.service[this.name] !== undefined;
}, },
/**
* Not a good name, but it is used to get the object.
*/
service() { service() {
if (this.objectType === "service") {
// Used in Container.vue
return this.$parent.$parent.service; return this.$parent.$parent.service;
} else if (this.objectType === "x-dockge") {
if (!this.$parent.$parent.jsonConfig["x-dockge"]) {
return {};
}
// Used in Compose.vue
return this.$parent.$parent.jsonConfig["x-dockge"];
} else {
return {};
}
}, },
valid() { valid() {
@ -81,6 +100,19 @@ export default {
}, },
methods: { methods: {
addField() { addField() {
// Create the object if not exists.
if (this.objectType === "x-dockge") {
if (!this.$parent.$parent.jsonConfig["x-dockge"]) {
this.$parent.$parent.jsonConfig["x-dockge"] = {};
}
}
// Create the array if not exists.
if (!this.service[this.name]) {
this.service[this.name] = [];
}
this.array.push(""); this.array.push("");
}, },
remove(index) { remove(index) {

View file

@ -49,8 +49,7 @@ export default {
array() { array() {
// Create the array if not exists, it should be safe. // Create the array if not exists, it should be safe.
if (!this.service[this.name]) { if (!this.service[this.name]) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties return [];
this.service[this.name] = [];
} }
return this.service[this.name]; return this.service[this.name];
}, },
@ -89,6 +88,10 @@ export default {
}, },
methods: { methods: {
addField() { addField() {
// Create the array if not exists.
if (!this.service[this.name]) {
this.service[this.name] = [];
}
this.array.push(""); this.array.push("");
}, },
remove(index) { remove(index) {

View file

@ -91,5 +91,6 @@
"Allowed commands:": "Allowed commands:", "Allowed commands:": "Allowed commands:",
"Internal Networks": "Internal Networks", "Internal Networks": "Internal Networks",
"External Networks": "External Networks", "External Networks": "External Networks",
"No External Networks": "No External Networks" "No External Networks": "No External Networks",
"url": "URL | URLs"
} }

View file

@ -56,6 +56,13 @@
</button> </button>
</div> </div>
<!-- URLs -->
<div v-if="urls.length > 0" class="mb-3">
<a v-for="(url, index) in urls" :key="index" target="_blank" :href="url.url">
<span class="badge bg-secondary me-2">{{ url.display }}</span>
</a>
</div>
<!-- Progress Terminal --> <!-- Progress Terminal -->
<transition name="slide-fade" appear> <transition name="slide-fade" appear>
<Terminal <Terminal
@ -80,6 +87,14 @@
<input id="name" v-model="stack.name" type="text" class="form-control" required @blur="stackNameToLowercase"> <input id="name" v-model="stack.name" type="text" class="form-control" required @blur="stackNameToLowercase">
<div class="form-text">{{ $t("Lowercase only") }}</div> <div class="form-text">{{ $t("Lowercase only") }}</div>
</div> </div>
<!-- URLs -->
<div class="mb-4">
<label class="form-label">
{{ $tc("url", 2) }}
</label>
<ArrayInput name="urls" :display-name="$t('url')" placeholder="https://" object-type="x-dockge" />
</div>
</div> </div>
</div> </div>
@ -111,6 +126,20 @@
<button v-if="false && isEditMode && jsonConfig.services && Object.keys(jsonConfig.services).length > 0" class="btn btn-normal mb-3" @click="addContainer">{{ $t("addContainer") }}</button> <button v-if="false && isEditMode && jsonConfig.services && Object.keys(jsonConfig.services).length > 0" class="btn btn-normal mb-3" @click="addContainer">{{ $t("addContainer") }}</button>
<!-- General -->
<div v-if="isEditMode">
<h4 class="mb-3">{{ $t("Extra") }}</h4>
<div class="shadow-box big-padding mb-3">
<!-- URLs -->
<div class="mb-4">
<label class="form-label">
{{ $tc("url", 2) }}
</label>
<ArrayInput name="urls" :display-name="$t('url')" placeholder="https://" object-type="x-dockge" />
</div>
</div>
</div>
<!-- Combined Terminal Output --> <!-- Combined Terminal Output -->
<div v-show="!isEditMode"> <div v-show="!isEditMode">
<h4 class="mb-3">Terminal</h4> <h4 class="mb-3">Terminal</h4>
@ -252,6 +281,34 @@ export default {
}; };
}, },
computed: { computed: {
urls() {
if (!this.jsonConfig["x-dockge"] || !this.jsonConfig["x-dockge"].urls || !Array.isArray(this.jsonConfig["x-dockge"].urls)) {
return [];
}
let urls = [];
for (const url of this.jsonConfig["x-dockge"].urls) {
let display;
try {
let obj = new URL(url);
let pathname = obj.pathname;
if (pathname === "/") {
pathname = "";
}
display = obj.host + pathname + obj.search;
} catch (e) {
display = url;
}
urls.push({
display,
url,
});
}
return urls;
},
isAdd() { isAdd() {
return this.$route.path === "/compose" && !this.submitted; return this.$route.path === "/compose" && !this.submitted;
}, },