mirror of https://github.com/rancher/dashboard.git
186 lines
4.4 KiB
Vue
186 lines
4.4 KiB
Vue
<script>
|
|
import RulePath from '@shell/edit/networking.k8s.io.ingress/RulePath';
|
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
import { random32 } from '@shell/utils/string';
|
|
|
|
export default {
|
|
emits: ['update:value', 'remove'],
|
|
components: { RulePath, LabeledInput },
|
|
props: {
|
|
value: {
|
|
type: Object,
|
|
default: () => {
|
|
return {};
|
|
},
|
|
},
|
|
serviceTargets: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
ingress: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
rules: {
|
|
default: () => ({
|
|
requestHost: [],
|
|
path: [],
|
|
port: [],
|
|
target: []
|
|
}),
|
|
type: Object,
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
host: this.value?.host ?? '',
|
|
paths: this.value?.http?.paths ?? [{ id: random32(1) }],
|
|
ruleMode: this.value.asDefault ? 'asDefault' : 'setHost',
|
|
};
|
|
},
|
|
methods: {
|
|
update() {
|
|
const http = { paths: this.paths };
|
|
const out = { ...this.value, http };
|
|
|
|
if (this.host) {
|
|
out.host = this.host;
|
|
} else {
|
|
delete out.host;
|
|
}
|
|
|
|
this.$nextTick(() => {
|
|
if ((this.paths?.length === 1 && this.pathObjectIsEmpty(this.paths[0])) || this.paths?.length === 0) {
|
|
delete out.http;
|
|
}
|
|
this.$emit('update:value', out);
|
|
});
|
|
},
|
|
pathObjectIsEmpty(pathObject) {
|
|
const servicePort = Number.parseInt(pathObject.servicePort) || pathObject.servicePort;
|
|
const serviceName = pathObject.serviceName;
|
|
const path = pathObject.path;
|
|
const pathType = pathObject.pathType;
|
|
|
|
if (!servicePort && !serviceName && !path && pathType === 'Prefix') {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
addPath(ev) {
|
|
if (ev) {
|
|
ev.preventDefault();
|
|
}
|
|
this.paths = [...this.paths, { id: random32(1) }];
|
|
this.$nextTick(() => {
|
|
if (this.$refs.paths && this.$refs.paths.length > 0) {
|
|
const path = this.$refs.paths[this.$refs.paths.length - 1];
|
|
|
|
path.focus();
|
|
}
|
|
this.update();
|
|
});
|
|
},
|
|
removePath(idx) {
|
|
const neu = [...this.paths];
|
|
|
|
neu.splice(idx, 1);
|
|
this.paths = neu;
|
|
this.update();
|
|
},
|
|
removeRule() {
|
|
this.$emit('remove');
|
|
},
|
|
focus() {
|
|
this.$refs.host.focus();
|
|
},
|
|
makePathKey(i) {
|
|
return JSON.stringify(this.paths[i]);
|
|
}
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="rule">
|
|
<div class="row mb-20">
|
|
<div
|
|
id="host"
|
|
class="col span-6"
|
|
>
|
|
<LabeledInput
|
|
ref="host"
|
|
v-model:value="host"
|
|
:label="t('ingress.rules.requestHost.label')"
|
|
:placeholder="t('ingress.rules.requestHost.placeholder')"
|
|
:rules="rules.requestHost"
|
|
@update:value="update"
|
|
/>
|
|
</div>
|
|
<div
|
|
id="spacer"
|
|
class="col span-5"
|
|
/>
|
|
</div>
|
|
<div class="rule-path-headings row">
|
|
<div
|
|
class="col"
|
|
:class="{'span-6': ingress.showPathType, 'span-4': !ingress.showPathType}"
|
|
>
|
|
<label>{{ t("ingress.rules.path.label") }}</label>
|
|
</div>
|
|
<div
|
|
class="col"
|
|
:class="{'span-3': ingress.showPathType, 'span-4': !ingress.showPathType}"
|
|
>
|
|
<label>{{ t("ingress.rules.target.label") }}</label>
|
|
</div>
|
|
<div
|
|
class="col"
|
|
:class="{'span-2': ingress.showPathType, 'span-3': !ingress.showPathType}"
|
|
:style="{ 'margin-right': '0px' }"
|
|
>
|
|
<label>{{ t("ingress.rules.port.label") }}</label>
|
|
</div>
|
|
<div class="col" />
|
|
</div>
|
|
<template
|
|
v-for="(path, i) in paths"
|
|
:key="path.id"
|
|
>
|
|
<RulePath
|
|
ref="paths"
|
|
v-model:value="paths[i]"
|
|
class="row mb-10"
|
|
:rule-mode="ruleMode"
|
|
:service-targets="serviceTargets"
|
|
:ingress="ingress"
|
|
:rules="{path: rules.path, port: rules.port, target: rules.target}"
|
|
@remove="(e) => removePath(i)"
|
|
@update:value="update"
|
|
/>
|
|
</template>
|
|
<button
|
|
v-if="ruleMode === 'setHost'"
|
|
class="btn role-tertiary add"
|
|
@click="addPath"
|
|
>
|
|
{{ t("ingress.rules.addPath") }}
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
#host {
|
|
align-self: center;
|
|
}
|
|
.close {
|
|
float: right;
|
|
padding: 0px;
|
|
position: relative;
|
|
top: -10px;
|
|
right: -10px;
|
|
}
|
|
</style>
|