dashboard/shell/dialog/DeveloperLoadExtensionDialo...

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>