mirror of https://github.com/rancher/dashboard.git
265 lines
5.9 KiB
Vue
265 lines
5.9 KiB
Vue
<script>
|
|
import AsyncButton from '@shell/components/AsyncButton';
|
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
|
|
import { UI_PLUGIN } from '@shell/config/types';
|
|
import { UI_PLUGIN_CHART_ANNOTATIONS, UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
|
|
|
|
export default {
|
|
emits: ['close'],
|
|
|
|
components: {
|
|
AsyncButton,
|
|
Checkbox,
|
|
LabeledInput
|
|
},
|
|
props: {
|
|
/**
|
|
* Callback when modal is closed
|
|
*/
|
|
closed: {
|
|
type: Function,
|
|
default: () => {},
|
|
required: true
|
|
},
|
|
resources: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
registerBackgroundClosing: {
|
|
type: Function,
|
|
default: () => {}
|
|
}
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
name: '',
|
|
location: '',
|
|
persist: false,
|
|
canModifyName: true,
|
|
canModifyLocation: true
|
|
};
|
|
},
|
|
|
|
watch: {
|
|
name(neu) {
|
|
if (this.canModifyLocation) {
|
|
this.location = `/pkg/${ neu }/${ neu }.umd.min.js`;
|
|
}
|
|
},
|
|
location(neu, old) {
|
|
if (this.canModifyName) {
|
|
const names = neu.split('/');
|
|
let last = names[names.length - 1];
|
|
let index = last.indexOf('.umd.min.js');
|
|
|
|
if (index !== -1) {
|
|
last = last.substr(0, index);
|
|
} else {
|
|
index = last.indexOf('.umd.js');
|
|
if (index !== -1) {
|
|
last = last.substr(0, index);
|
|
}
|
|
}
|
|
|
|
this.name = last;
|
|
}
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
closeDialog(result) {
|
|
this.closed(result);
|
|
this.$emit('close');
|
|
},
|
|
|
|
updateName(v) {
|
|
this.canModifyName = v.length === 0;
|
|
},
|
|
|
|
updateLocation(v) {
|
|
this.canModifyLocation = v.length === 0;
|
|
},
|
|
|
|
async loadPlugin(btnCb) {
|
|
let name = this.name;
|
|
const url = this.location;
|
|
|
|
if (!name) {
|
|
const parts = url.split('/');
|
|
const n = parts[parts.length - 1];
|
|
|
|
// Split on '.'
|
|
name = n.split('.')[0];
|
|
}
|
|
|
|
// Try and parse version number from the name
|
|
let version = '0.0.1';
|
|
let crdName = name;
|
|
|
|
const parts = name.split('-');
|
|
|
|
if (parts.length >= 2) {
|
|
version = parts.pop();
|
|
crdName = parts.join('-');
|
|
}
|
|
|
|
if (this.persist) {
|
|
const pluginCR = await this.$store.dispatch('management/create', {
|
|
type: UI_PLUGIN,
|
|
metadata: {
|
|
name,
|
|
namespace: UI_PLUGIN_NAMESPACE
|
|
},
|
|
spec: {
|
|
plugin: {
|
|
name: crdName,
|
|
version,
|
|
endpoint: url,
|
|
noCache: true,
|
|
metadata: {
|
|
developer: 'true',
|
|
direct: 'true',
|
|
[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>= 3',
|
|
},
|
|
noAuth: true
|
|
}
|
|
}
|
|
});
|
|
|
|
try {
|
|
await pluginCR.save({ url: `/v1/${ UI_PLUGIN }`, method: 'POST' });
|
|
} catch (e) {
|
|
console.error('Could not create CRD for plugin', e); // eslint-disable-line no-console
|
|
btnCb(false);
|
|
}
|
|
}
|
|
|
|
this.$plugin.loadAsync(name, url).then(() => {
|
|
this.closeDialog(true);
|
|
|
|
this.$store.dispatch('growl/success', {
|
|
title: this.t('plugins.success.title', { name }),
|
|
message: this.t('plugins.success.message'),
|
|
timeout: 3000,
|
|
}, { root: true });
|
|
|
|
btnCb(true);
|
|
}).catch((error) => {
|
|
btnCb(false);
|
|
|
|
const message = typeof error === 'object' ? this.t('plugins.error.message') : error;
|
|
|
|
this.$store.dispatch('growl/error', {
|
|
title: this.t('plugins.error.title'),
|
|
message,
|
|
timeout: 5000
|
|
}, { root: true });
|
|
});
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="plugin-install-dialog">
|
|
<h4>
|
|
{{ t('plugins.developer.title') }}
|
|
</h4>
|
|
<p>
|
|
{{ t('plugins.developer.prompt') }}
|
|
</p>
|
|
<div class="custom mt-10">
|
|
<div class="fields">
|
|
<LabeledInput
|
|
v-model:value="location"
|
|
v-focus
|
|
label-key="plugins.developer.fields.url"
|
|
@update:value="updateLocation"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="custom mt-10">
|
|
<div class="fields">
|
|
<LabeledInput
|
|
v-model:value="name"
|
|
label-key="plugins.developer.fields.name"
|
|
@update:value="updateName"
|
|
/>
|
|
</div>
|
|
<div class="fields mt-10">
|
|
<Checkbox
|
|
v-model:value="persist"
|
|
label-key="plugins.developer.fields.persist"
|
|
/>
|
|
</div>
|
|
<div class="dialog-buttons mt-20">
|
|
<button
|
|
class="btn role-secondary"
|
|
data-testid="dev-install-ext-modal-cancel-btn"
|
|
@click="closeDialog()"
|
|
>
|
|
{{ t('generic.cancel') }}
|
|
</button>
|
|
<AsyncButton
|
|
mode="load"
|
|
data-testid="dev-install-ext-modal-install-btn"
|
|
@click="loadPlugin"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.plugin-install-dialog {
|
|
padding: 10px;
|
|
|
|
h4 {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.dialog-panel {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 100px;
|
|
|
|
p {
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.dialog-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.toggle-advanced {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
margin: 10px 0;
|
|
|
|
&:hover {
|
|
text-decoration: none;
|
|
color: var(--link);
|
|
}
|
|
}
|
|
|
|
.version-selector {
|
|
margin: 0 10px 10px 10px;
|
|
width: auto;
|
|
}
|
|
}
|
|
|
|
.dialog-buttons {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
margin-top: 10px;
|
|
|
|
> *:not(:last-child) {
|
|
margin-right: 10px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|