Skip to content

Commit

Permalink
Add validators to Docker Images & Containers forms
Browse files Browse the repository at this point in the history
  • Loading branch information
Maëlys Bras de fer committed Jun 25, 2021
1 parent 3edcacf commit 9818b77
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 49 deletions.
1 change: 1 addition & 0 deletions dockers/manager/front/src/components/BaseTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
label="Search"
dense
outlined
autofocus
debounce="200"
>
<template #append>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
multiple
new-value-mode="add"
:loading="loading"
outlined
hide-dropdown-icon
style="grid-column-start:2;grid-column-end:4;"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
multiple
new-value-mode="add"
:loading="loading"
outlined
hide-dropdown-icon
style="grid-column-start:2;grid-column-end:4;"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,53 +10,70 @@
<base-grid-input
:readonly="readonly"
:titles="['Container port', 'Protocol', 'Targets']"
grid-format="3fr 2fr 6fr"
grid-format="150px 85px auto"
:entries="form"
@addEntry="addEntry"
@removeEntry="removeEntry"
>
<template #inputs>
<q-input
ref="port"
v-model.number="model.containerPort"
mask="#####"
:rules="[validatePort]"
lazy-rules="ondemand"
label="Container port"
@input="$refs.port.resetValidation()"
@keypress.enter.prevent="addEntry"
@input="addPort"
@change="addPort(model.containerPort)"
/>
<q-select
v-model="model.protocol"
class="fit"
label="Protocol"
:options="['tcp', 'udp']"
/>
<q-select
v-model="model.targets"
class="fit"
use-chips
new-value-mode="add"
use-input
hide-dropdown-icon
multiple
outlined
label="Targets"
/>
</template>
<template #entry="{entry}">
<div class="ellipsis">
{{ entry.containerPort }}

<q-popup-edit v-model="entry.containerPort">
<q-input
v-model.number="entry.containerPort"
:readonly="readonly"
label="Container port"
/>
<q-popup-edit
v-model="entry.containerPort"
:validate="validatePort"
>
<template #default="{validate}">
<q-input
v-model.number="entry.containerPort"
mask="#####"
:rules="[validate]"
:readonly="readonly"
dense
autofocus
/>
</template>
</q-popup-edit>
</div>
<div class="ellipsis">
{{ entry.protocol }}
<q-popup-edit v-model="entry.protocol">
<q-popup-edit v-model="entry.protocol" :validate="required()">
<q-select
v-model="entry.protocol"
:readonly="readonly"
label="Protocol"
:options="['tcp', 'udp']"
dense
autofocus
/>
</q-popup-edit>
</div>
Expand All @@ -72,7 +89,7 @@
use-input
hide-dropdown-icon
multiple
label="Targets"
outlined
/>
</q-popup-edit>
</div>
Expand Down Expand Up @@ -101,17 +118,27 @@ export default {
container: { type: Object, default: null }
},
formDefinition: [],
data: () => ({ model: defaultModel }),
data: () => ({ model: { ...defaultModel } }),
methods: {
validatePort(p) {
const max = 2 ** 16 - 1;
return (
(Number.isInteger(p) && p >= 0 && p <= max) ||
`Must be in range 0 - ${max}`
);
},
addPort(port) {
this.model.targets = [`0.0.0.0:${port}`];
this.model.targets = port ? [`0.0.0.0:${port}`] : [];
},
addEntry() {
if (!this.model.protocol) return;
if (this.$refs.port.validate()) {
this.form.unshift(this.model);
this.model = { ...defaultModel };
}
},
removeEntry(idx) {
this.form.splice(idx, 1);
},
addEntry() {
this.form.unshift(this.model);
this.model = defaultModel;
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
clearable
label="Search"
class="full-width"
autofocus
@input="doSearch"
/>
</q-card-section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,51 @@
<template #inputs>
<q-select
v-model="model.type"
class="fit"
flat
:options="['volume', 'bind', 'tmpfs']"
label="Type"
@keypress.enter.prevent="addEntry"
/>
<div v-if="model.type === 'volume'" style="overflow: hidden">
<div class="fit overflow-hidden">
<q-select
v-if="model.type === 'volume'"
ref="source"
v-model="model.name"
:rules="[required('Please select a volume')]"
lazy-rules="ondemand"
flat
:options="volumeOptions"
label="Name"
@input="$refs.source.resetValidation()"
@keypress.enter.prevent="addEntry"
>
<template #selected-item="{opt}">
<div class="ellipsis">{{ opt }}</div>
</template>
</q-select>
</div>
<div v-if="model.type === 'bind'" style="overflow: hidden">
<q-input
v-else-if="model.type === 'bind'"
ref="source"
v-model="model.source"
:rules="[required('A bind mount must have a source')]"
lazy-rules="ondemand"
flat
label="Source"
@input="$refs.source.resetValidation()"
@keypress.enter.prevent="addEntry"
/>
</div>
<div v-if="model.type === 'tmpfs'" style="overflow: hidden">
<q-input disable value="-" flat />
<q-input v-else ref="source" disable value="-" flat />
</div>
<q-input
ref="target"
v-model="model.target"
:rules="[required('You must specify a mountpoint')]"
lazy-rules="ondemand"
class="col"
flat
label="Target"
@input="$refs.target.resetValidation()"
@keypress.enter.prevent="addEntry"
/>
<div>
Expand All @@ -68,26 +79,39 @@
<div v-if="entry.type === 'volume'" class="ellipsis">
<volume-link :name="entry.name" />

<q-popup-edit v-model="entry.name">
<q-input
v-model="entry.name"
:readonly="readonly"
dense
autofocus
/>
<q-popup-edit
v-model="entry.name"
:validate="required('Please select a volume')"
>
<template #default="{validate}">
<q-select
v-model="entry.name"
:rules="[validate]"
:options="volumeOptions"
:readonly="readonly"
dense
autofocus
/>
</template>
</q-popup-edit>
</div>

<div v-if="entry.type === 'bind'" class="ellipsis">
{{ entry.source }}

<q-popup-edit v-model="entry.source">
<q-input
v-model="entry.source"
:readonly="readonly"
dense
autofocus
/>
<q-popup-edit
v-model="entry.source"
:validate="required('A bind mount must have a source')"
>
<template #default="{validate}">
<q-input
v-model="entry.source"
:rules="[validate]"
:readonly="readonly"
dense
autofocus
/>
</template>
</q-popup-edit>
</div>
<div v-if="entry.type === 'tmpfs'" class="ellipsis">
Expand All @@ -96,13 +120,19 @@
<div class="ellipsis">
{{ entry.target }}

<q-popup-edit v-model="entry.target">
<q-input
v-model="entry.target"
:readonly="readonly"
dense
autofocus
/>
<q-popup-edit
v-model="entry.target"
:validate="required('You must specify a mountpoint')"
>
<template #default="{validate}">
<q-input
v-model="entry.target"
:rules="[validate]"
:readonly="readonly"
dense
autofocus
/>
</template>
</q-popup-edit>
</div>
<div>
Expand Down Expand Up @@ -160,7 +190,7 @@ export default {
query: api.docker.volumes.LIST_VOLUMES
}
},
data: () => ({ model: defaultModel }),
data: () => ({ model: { ...defaultModel } }),
computed: {
volumeOptions() {
return (this.dockerVolumes ?? []).map(v => v.name);
Expand All @@ -176,13 +206,18 @@ export default {
}
},
methods: {
addEntry() {
if (!this.model.type) return;
const fields = [this.$refs.source, this.$refs.target];
if (fields.map(f => f.validate()).every(x => x)) {
this.form.unshift(this.model);
this.model = { ...defaultModel };
fields.forEach(f => f.resetValidation());
}
},
removeEntry(idx) {
this.form.splice(idx, 1);
},
addEntry() {
this.form.unshift(this.model);
this.model = defaultModel;
},
createVolume() {
this.$q.dialog({
component: VolumeDialog,
Expand Down

0 comments on commit 9818b77

Please sign in to comment.