mirror of https://github.com/rancher/dashboard.git
fix linkFor error on create retry
add/remove resources reactively
This commit is contained in:
parent
37a29d2d2a
commit
9e95b3b9ad
|
|
@ -65,11 +65,10 @@ export default {
|
|||
} else {
|
||||
headers = this.$store.getters['type-map/headersFor'](this.schema);
|
||||
}
|
||||
|
||||
// If only one namespace is selected, replace the namespace_name
|
||||
// column with the just name one.
|
||||
if ( !showNamespace ) {
|
||||
let idx = headers.indexOf(NAMESPACE_NAME);
|
||||
let idx = headers.findIndex(header => header.value === NAMESPACE_NAME.value);
|
||||
|
||||
if ( idx >= 0 ) {
|
||||
headers.splice(idx, 1, NAME);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default {
|
|||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
type: [String, Object],
|
||||
default: null,
|
||||
},
|
||||
options: {
|
||||
|
|
@ -40,6 +40,16 @@ export default {
|
|||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
reduce: {
|
||||
type: Function,
|
||||
default: (e) => {
|
||||
if ( e && typeof e === 'object' && e.value !== undefined ) {
|
||||
return e.value;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
@ -67,16 +77,6 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
get,
|
||||
|
||||
reduce(e) {
|
||||
if ( e && typeof e === 'object' && e.value !== undefined ) {
|
||||
return e.value;
|
||||
}
|
||||
|
||||
return e;
|
||||
},
|
||||
|
||||
onFocus() {
|
||||
this.selectedVisibility = 'hidden';
|
||||
this.onFocusLabeled();
|
||||
|
|
@ -145,6 +145,14 @@ export default {
|
|||
*/
|
||||
return () => popper.destroy();
|
||||
},
|
||||
open() {
|
||||
const input = this.$refs.input;
|
||||
|
||||
if (input) {
|
||||
input.open = true;
|
||||
}
|
||||
},
|
||||
get
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -169,9 +177,9 @@ export default {
|
|||
<v-select
|
||||
v-if="!isView"
|
||||
ref="input"
|
||||
:value="value ? value : ' '"
|
||||
class="inline"
|
||||
:disabled="disabled"
|
||||
:value="value"
|
||||
:disabled="isView || disabled"
|
||||
:options="options"
|
||||
:get-option-label="opt=>getOptionLabel(opt)"
|
||||
:get-option-key="opt=>optionKey ? get(opt, optionKey) : getOptionLabel(opt)"
|
||||
|
|
@ -180,9 +188,9 @@ export default {
|
|||
v-bind="$attrs"
|
||||
:append-to-body="!!placement"
|
||||
:calculate-position="placement ? withPopper : undefined"
|
||||
@input="x => $emit('input', reduce(x))"
|
||||
@search:focus="onFocus"
|
||||
@search:blur="onBlur"
|
||||
@input="e=>$emit('input', e)"
|
||||
>
|
||||
<template v-slot:selected-option-container>
|
||||
<span style="display: none"></span>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ export default {
|
|||
if ( this.namespaced && !metadata.namespace ) {
|
||||
metadata.namespace = this.$store.getters['defaultNamespace'];
|
||||
}
|
||||
|
||||
const description = metadata.annotations?.[DESCRIPTION];
|
||||
|
||||
return {
|
||||
|
|
@ -159,7 +158,7 @@ export default {
|
|||
select-label="Namespace"
|
||||
:text-value="name"
|
||||
:text-required="true"
|
||||
select-value="default"
|
||||
:select-value="namespace"
|
||||
:mode="mode"
|
||||
:disabled="nameDisabled"
|
||||
@input="changeNameAndNamespace($event)"
|
||||
|
|
|
|||
|
|
@ -101,7 +101,11 @@ export default function(store) {
|
|||
width: 100,
|
||||
formatter: 'SecretType'
|
||||
},
|
||||
KEYS,
|
||||
{
|
||||
name: 'data',
|
||||
label: 'Data',
|
||||
value: 'dataPreview'
|
||||
},
|
||||
AGE
|
||||
]);
|
||||
headers(INGRESS, [STATE, NAME, INGRESS_TARGET, AGE]);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ export default {
|
|||
}
|
||||
|
||||
if (this.value._type === TLS) {
|
||||
// remove private key on edit page
|
||||
key = this.mode === 'edit' ? '' : base64Decode((this.value.data || {})['tls.key']);
|
||||
crt = base64Decode((this.value.data || {})['tls.crt']);
|
||||
}
|
||||
|
|
@ -81,9 +82,10 @@ export default {
|
|||
registryFQDN,
|
||||
toUpload: null,
|
||||
key,
|
||||
crt
|
||||
crt,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
dockerconfigjson() {
|
||||
let dockerServer = this.registryProvider === 'DockerHub' ? 'index.dockerhub.io/v1/' : 'quay.io';
|
||||
|
|
@ -131,6 +133,8 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
watch: { 'value.data': () => {} },
|
||||
|
||||
methods: {
|
||||
saveSecret(buttonCb) {
|
||||
if (this.isRegistry) {
|
||||
|
|
@ -216,7 +220,7 @@ export default {
|
|||
<LabeledInput v-model="username" label="Username" :mode="mode" />
|
||||
</div>
|
||||
<div class="col span-6">
|
||||
<LabeledInput v-model="password" label="Password" :mode="mode" />
|
||||
<LabeledInput v-model="password" label="Password" :mode="mode" :type="mode==='edit' ? 'password':'text'" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<script>
|
||||
import { get } from '../../utils/object';
|
||||
import LabeledInput from '@/components/form/LabeledInput';
|
||||
import ShellInput from '@/components/form/ShellInput';
|
||||
import UnitInput from '@/components/form/UnitInput';
|
||||
|
|
@ -92,15 +91,6 @@ export default {
|
|||
|
||||
addFromReference() {
|
||||
this.referencedValues.push({ name: '', valueFrom: {} });
|
||||
|
||||
this.$nextTick(() => {
|
||||
const newRow = this.$refs.referenced[this.referencedValues.length - 1];
|
||||
const input = get(newRow, '$refs.typeSelect.$refs.input');
|
||||
|
||||
if (input) {
|
||||
input.open = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,12 +42,12 @@ export default {
|
|||
{ value: 'fieldRef', label: 'Field' },
|
||||
{ value: 'secretRef', label: 'Secret' }];
|
||||
|
||||
let type = Object.keys((this.row.valueFrom || {}))[0];
|
||||
let type = this.row.secretRef ? 'secretRef' : Object.keys((this.row.valueFrom))[0];
|
||||
|
||||
let refName;
|
||||
let name;
|
||||
let fieldPath;
|
||||
let referenced = {};
|
||||
let referenced;
|
||||
let key;
|
||||
|
||||
switch (type) {
|
||||
|
|
@ -63,33 +63,19 @@ export default {
|
|||
type = Object.keys(this.row.valueFrom)[0];
|
||||
key = this.row.valueFrom[type].key || '';
|
||||
refName = this.row.valueFrom[type].name;
|
||||
if (!refName.includes('/')) {
|
||||
refName = `${ this.namespace }/${ refName }`;
|
||||
}
|
||||
|
||||
this.getReferenced(refName, CONFIG_MAP);
|
||||
break;
|
||||
case 'secretRef':
|
||||
name = this.row.prefix;
|
||||
type = 'secretRef';
|
||||
refName = this.row[type].name;
|
||||
if (!refName.includes('/')) {
|
||||
refName = `${ this.namespace }/${ refName }`;
|
||||
}
|
||||
this.getReferenced(refName, SECRET);
|
||||
break;
|
||||
case 'secretKeyRef':
|
||||
name = this.row.name;
|
||||
type = Object.keys(this.row.valueFrom)[0];
|
||||
key = this.row.valueFrom[type].key || '';
|
||||
refName = this.row.valueFrom[type].name;
|
||||
if (!refName.includes('/')) {
|
||||
refName = `${ this.namespace }/${ refName }`;
|
||||
}
|
||||
this.getReferenced(refName, SECRET);
|
||||
break;
|
||||
case 'fieldRef':
|
||||
referenced = {};
|
||||
fieldPath = get(this.row.valueFrom, `${ type }.fieldPath`) || '';
|
||||
name = this.row.name;
|
||||
break;
|
||||
|
|
@ -98,7 +84,7 @@ export default {
|
|||
}
|
||||
|
||||
return {
|
||||
typeOpts, type, refName, referenced, secrets: this.allSecrets, keys: [], key, fieldPath, name
|
||||
typeOpts, type, refName, referenced: refName, secrets: this.allSecrets, keys: [], key, fieldPath, name
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -122,31 +108,34 @@ export default {
|
|||
return [];
|
||||
}
|
||||
},
|
||||
referencedID: {
|
||||
get() {
|
||||
return this.referenced.id;
|
||||
},
|
||||
set(neu) {
|
||||
this.referenced = { id: neu };
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
type() {
|
||||
this.referenced = {};
|
||||
this.referenced = null;
|
||||
},
|
||||
|
||||
referenced(neu, old) {
|
||||
if (Object.keys(old).length) {
|
||||
if (old) {
|
||||
this.key = '';
|
||||
}
|
||||
if (neu) {
|
||||
if (neu.type === SECRET || neu.type === CONFIG_MAP) {
|
||||
this.keys = Object.keys(neu.data);
|
||||
}
|
||||
this.refName = neu?.metadata?.name;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const typeSelect = this.$refs.typeSelect;
|
||||
|
||||
if (typeSelect && this.mode === 'create') {
|
||||
typeSelect.open();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async getReferenced(name, type) {
|
||||
const resource = await this.$store.dispatch('cluster/find', { id: name, type });
|
||||
|
|
@ -155,7 +144,7 @@ export default {
|
|||
},
|
||||
|
||||
updateRow() {
|
||||
const out = { name: this.name };
|
||||
const out = { name: this.name || this.refName };
|
||||
const old = { ...this.row };
|
||||
|
||||
switch (this.type) {
|
||||
|
|
@ -163,7 +152,7 @@ export default {
|
|||
case 'secretKeyRef':
|
||||
out.valueFrom = {
|
||||
[this.type]: {
|
||||
key: this.key, name: this.referencedID, optional: false
|
||||
key: this.key, name: this.refName, optional: false
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
|
@ -180,10 +169,11 @@ export default {
|
|||
default:
|
||||
delete out.name;
|
||||
out.prefix = this.name;
|
||||
out[this.type] = { name: this.referencedID, optional: false };
|
||||
out[this.type] = { name: this.refName, optional: false };
|
||||
}
|
||||
this.$emit('input', { value: out, old });
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -210,6 +200,7 @@ export default {
|
|||
:multiple="false"
|
||||
label="Source"
|
||||
option-label="metadata.name"
|
||||
option-key
|
||||
:mode="mode"
|
||||
@input="updateRow"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ export default {
|
|||
url = url || this.schema.linkFor('collection');
|
||||
|
||||
if ( this.value?.metadata?.namespace ) {
|
||||
this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, value: this.value.metadata.namespace }, { root: true });
|
||||
this.value.$dispatch('prefs/set', { key: LAST_NAMESPACE, val: this.value.metadata.namespace }, { root: true });
|
||||
}
|
||||
|
||||
const res = await this.value.save({ url });
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { KUBERNETES } from '@/config/labels-annotations';
|
||||
import { base64Decode } from '@/utils/crypto';
|
||||
|
||||
export const OPAQUE = 'Opaque';
|
||||
export const SERVICE_ACCT = 'kubernetes.io/service-account-token';
|
||||
|
|
@ -23,6 +24,24 @@ const DISPLAY_TYPES = {
|
|||
};
|
||||
|
||||
export default {
|
||||
// TODO find out if you should be able ot edit service account tokens
|
||||
// // remove edit option for service acct tokens
|
||||
// _availableActions() {
|
||||
// let out = this._standardActions;
|
||||
|
||||
// if (this.secretType === SERVICE_ACCT) {
|
||||
// const toFilter = ['goToEdit', 'goToEditYaml'];
|
||||
|
||||
// out = out.filter((action) => {
|
||||
// if (!toFilter.includes(action.action)) {
|
||||
// return action;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// return out;
|
||||
// },
|
||||
|
||||
keysDisplay() {
|
||||
const keys = [
|
||||
...Object.keys(this.data || []),
|
||||
|
|
@ -40,6 +59,33 @@ export default {
|
|||
return keys.join(', ');
|
||||
},
|
||||
|
||||
// decode some secret data to show in list view
|
||||
dataPreview() {
|
||||
if (this._type === DOCKER_JSON) {
|
||||
const encodedJSON = this.data['.dockerconfigjson'];
|
||||
|
||||
if (encodedJSON) {
|
||||
const decodedJSON = base64Decode(encodedJSON);
|
||||
|
||||
try {
|
||||
const auths = JSON.parse(decodedJSON).auths;
|
||||
const out = [];
|
||||
|
||||
for (const domain in auths) {
|
||||
out.push(domain);
|
||||
}
|
||||
|
||||
return out.join(', ');
|
||||
} catch (e) {
|
||||
// if the dockerconfigjson somehow isn't valid json, give up :(
|
||||
return decodedJSON;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.keysDisplay;
|
||||
}
|
||||
},
|
||||
|
||||
secretType() {
|
||||
return this._type;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ export default {
|
|||
// use it instead of making a new proxy
|
||||
entry = existing;
|
||||
Object.assign(entry, data);
|
||||
// if no entry for this id in cache, add it
|
||||
if (!cache.map.get(id)) {
|
||||
addObject(cache.list, entry);
|
||||
}
|
||||
cache.map.set(id, entry);
|
||||
} else if ( entry ) {
|
||||
// There's already an entry in the store, update it
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ export function cleanForNew(obj) {
|
|||
delete m.resourceVersion;
|
||||
delete m.selfLink;
|
||||
delete m.creationTimestamp;
|
||||
delete m.deletionTimestamp;
|
||||
delete m.state;
|
||||
dropKeys(m.annotations);
|
||||
dropKeys(m.labels);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -613,11 +613,11 @@ export default {
|
|||
}
|
||||
|
||||
// @TODO remove this once the API maps steve _type <-> k8s type in both directions
|
||||
if (this._type) {
|
||||
this.type = this._type;
|
||||
}
|
||||
opt.data = { ...this };
|
||||
|
||||
opt.data = this;
|
||||
if (opt?.data._type) {
|
||||
opt.data.type = opt.data._type;
|
||||
}
|
||||
|
||||
const res = await this.$dispatch('request', opt);
|
||||
|
||||
|
|
@ -803,5 +803,5 @@ export default {
|
|||
url = `${ url.slice(0, url.indexOf('/v1')) }/apis/${ group }/namespaces/${ namespace }/${ resource }`;
|
||||
|
||||
return url;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -171,7 +171,9 @@ export const getters = {
|
|||
}
|
||||
}
|
||||
|
||||
return all[0] || 'default';
|
||||
console.log('7', all[0]); // eslint-disable-line no-console
|
||||
|
||||
return all[0];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { xor } from 'lodash';
|
|||
import { get } from '@/utils/object';
|
||||
|
||||
export function removeObject(ary, obj) {
|
||||
const idx = ary.indexOf(obj);
|
||||
const idx = ary.findIndex(resource => resource.id === obj.id);
|
||||
|
||||
if ( idx >= 0 ) {
|
||||
ary.splice(idx, 1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue