mirror of https://github.com/rancher/dashboard.git
296 lines
6.8 KiB
Vue
296 lines
6.8 KiB
Vue
<script lang="ts">
|
|
import { isEmpty } from 'lodash';
|
|
import { checkSchemasForFindAllHash } from '@shell/utils/auth';
|
|
import { CONFIG_MAP, SECRET } from '@shell/config/types';
|
|
import { PropType } from 'vue';
|
|
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
import { RcButton } from '@components/RcButton';
|
|
import ValueFromResource from '@shell/components/form/ValueFromResource.vue';
|
|
|
|
type KeyRefName = 'configMapKeyRef' | 'secretKeyRef';
|
|
|
|
interface KeyRef {
|
|
key: string,
|
|
name: string,
|
|
namespace?: string,
|
|
}
|
|
|
|
interface ValueFrom {
|
|
configMapKeyRef?: KeyRef,
|
|
secretKeyRef?: KeyRef,
|
|
}
|
|
|
|
interface ValuesFrom {
|
|
id: number,
|
|
valueFrom: ValueFrom
|
|
}
|
|
|
|
interface DataType {
|
|
allSecrets: object[] | null,
|
|
allConfigMaps: object[] | null,
|
|
valuesFrom: ValuesFrom[],
|
|
id: number,
|
|
}
|
|
|
|
export default {
|
|
|
|
name: 'FleetValuesFrom',
|
|
|
|
emits: ['update:value'],
|
|
|
|
components: {
|
|
RcButton,
|
|
ValueFromResource
|
|
},
|
|
|
|
props: {
|
|
value: {
|
|
type: Array as PropType<ValueFrom[]>,
|
|
default: () => []
|
|
},
|
|
|
|
namespace: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
|
|
mode: {
|
|
type: String,
|
|
default: _EDIT
|
|
},
|
|
},
|
|
|
|
async fetch() {
|
|
const hash = await checkSchemasForFindAllHash({
|
|
allSecrets: {
|
|
inStoreType: 'management',
|
|
type: SECRET
|
|
},
|
|
|
|
allConfigMaps: {
|
|
inStoreType: 'management',
|
|
type: CONFIG_MAP
|
|
}
|
|
}, this.$store) as { allSecrets: object[], allConfigMaps: object[] };
|
|
|
|
this.allSecrets = hash.allSecrets || [];
|
|
this.allConfigMaps = hash.allConfigMaps || [];
|
|
},
|
|
|
|
data(): DataType {
|
|
return {
|
|
allSecrets: null,
|
|
allConfigMaps: null,
|
|
valuesFrom: [],
|
|
id: 0,
|
|
};
|
|
},
|
|
|
|
mounted() {
|
|
this.valuesFrom = this.fromValuesFrom(this.value);
|
|
},
|
|
|
|
watch: {
|
|
namespace() {
|
|
this.valuesFrom = [];
|
|
|
|
this.update();
|
|
},
|
|
},
|
|
|
|
computed: {
|
|
valueFromOptions() {
|
|
return [
|
|
{
|
|
value: 'configMapKeyRef', label: this.t('fleet.helmOp.values.valuesFrom.options.configMapKeyRef'), hideVariableName: true
|
|
},
|
|
{
|
|
value: 'secretKeyRef', label: this.t('fleet.helmOp.values.valuesFrom.options.secretKeyRef'), hideVariableName: true
|
|
},
|
|
];
|
|
},
|
|
|
|
isView(): boolean {
|
|
return this.mode === _VIEW;
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
addValueFrom() {
|
|
this.valuesFrom.push({
|
|
id: this.id++,
|
|
valueFrom: {}
|
|
});
|
|
|
|
this.update();
|
|
|
|
(this.$refs['add-button'] as { $el: HTMLElement })?.$el?.blur();
|
|
},
|
|
|
|
updateValueFrom(id: number, value: ValuesFrom) {
|
|
for (let index = 0; index < this.valuesFrom.length; index++) {
|
|
if (this.valuesFrom[index].id === id) {
|
|
const oldKeyRefName = Object.keys(this.valuesFrom[index]?.valueFrom || {})[0] as KeyRefName;
|
|
const newKeyRefName = Object.keys(value?.valueFrom || {})[0] as KeyRefName;
|
|
|
|
const oldKey = this.valuesFrom[index]?.valueFrom?.[oldKeyRefName]?.name;
|
|
const newKey = value?.valueFrom?.[newKeyRefName]?.name;
|
|
|
|
if (oldKeyRefName && newKeyRefName && oldKeyRefName !== newKeyRefName) {
|
|
this.valuesFrom[index].valueFrom = { [newKeyRefName]: {} };
|
|
} else if (oldKey && newKey && oldKey !== newKey) {
|
|
this.valuesFrom[index].valueFrom = {
|
|
[newKeyRefName]: {
|
|
...(value?.valueFrom?.[newKeyRefName] || {}),
|
|
key: ''
|
|
},
|
|
};
|
|
} else {
|
|
this.valuesFrom[index].valueFrom = value?.valueFrom;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.update();
|
|
},
|
|
|
|
removeValueFrom(id: number) {
|
|
this.valuesFrom = this.valuesFrom.filter((el) => el.id !== id);
|
|
|
|
this.update();
|
|
},
|
|
|
|
update() {
|
|
const value = this.toValuesFrom(this.valuesFrom, this.namespace);
|
|
|
|
this.$emit('update:value', value);
|
|
},
|
|
|
|
fromValuesFrom(data: ValueFrom[]): ValuesFrom[] {
|
|
return (data || [])
|
|
.map((elem) => {
|
|
const out = { id: this.id++ } as ValuesFrom;
|
|
|
|
const cm = elem?.configMapKeyRef;
|
|
|
|
if (cm) {
|
|
out.valueFrom = {
|
|
configMapKeyRef: {
|
|
key: cm.key || '',
|
|
name: cm.name || '',
|
|
}
|
|
};
|
|
}
|
|
|
|
const sc = elem?.secretKeyRef;
|
|
|
|
if (sc) {
|
|
out.valueFrom = {
|
|
secretKeyRef: {
|
|
key: sc.key || '',
|
|
name: sc.name || '',
|
|
}
|
|
};
|
|
}
|
|
|
|
return out;
|
|
})
|
|
.filter((el) => !isEmpty(el || {}));
|
|
},
|
|
|
|
toValuesFrom(data: { valueFrom: ValueFrom }[], namespace: string): ValueFrom[] | undefined {
|
|
const res = (data || [])
|
|
.map((elem) => {
|
|
const cm = elem?.valueFrom?.configMapKeyRef;
|
|
const sc = elem?.valueFrom?.secretKeyRef;
|
|
|
|
const out = {} as ValueFrom;
|
|
|
|
if (cm?.name) {
|
|
out.configMapKeyRef = {
|
|
key: cm.key,
|
|
name: cm.name,
|
|
namespace
|
|
};
|
|
}
|
|
|
|
if (sc?.name) {
|
|
out.secretKeyRef = {
|
|
key: sc.key,
|
|
name: sc.name,
|
|
namespace
|
|
};
|
|
}
|
|
|
|
return out;
|
|
})
|
|
.filter((el) => !isEmpty(el || {}));
|
|
|
|
return res.length ? res : undefined;
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
v-if="!allConfigMaps || !allSecrets"
|
|
data-testid="fleet-values-from-loading"
|
|
>
|
|
<i
|
|
class="icon icon-lg icon-spinner icon-spin"
|
|
/>
|
|
<label class="text-label ml-10">
|
|
{{ t('fleet.helmOp.values.valuesFrom.loading') }}
|
|
</label>
|
|
</div>
|
|
<div
|
|
v-else
|
|
class="values-from-container"
|
|
data-testid="fleet-values-from-list"
|
|
>
|
|
<h2
|
|
v-t="'fleet.helmOp.values.valuesFrom.selectLabel'"
|
|
class="m-0"
|
|
/>
|
|
<div
|
|
v-for="row in valuesFrom"
|
|
:key="row.id + '-' + row?.valueFrom?.configMapKeyRef?.key + '-' + row?.valueFrom?.secretKeyRef?.key"
|
|
class="mmt-4"
|
|
>
|
|
<ValueFromResource
|
|
:data-testid="`fleet-values-from-item-${ row.id }`"
|
|
:value="row"
|
|
:options="valueFromOptions"
|
|
:all-secrets="allSecrets"
|
|
:all-config-maps="allConfigMaps"
|
|
:namespaced="true"
|
|
:mode="mode"
|
|
:show-variable-name="true"
|
|
@remove="removeValueFrom(row.id)"
|
|
@update:value="updateValueFrom(row.id, $event)"
|
|
/>
|
|
</div>
|
|
<RcButton
|
|
v-if="!isView"
|
|
ref="add-button"
|
|
small
|
|
secondary
|
|
class="mmt-6"
|
|
data-testid="fleet-values-from-add"
|
|
@click="addValueFrom"
|
|
>
|
|
<i class="icon icon-add" />
|
|
{{ t('workload.container.command.addEnvVar') }}
|
|
</RcButton>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.var-row {
|
|
margin-bottom: 0;
|
|
}
|
|
</style>
|