Files
cloudron-box/dashboard/src/components/DockerRegistryDialog.vue
T
2025-12-10 18:04:07 +01:00

127 lines
4.3 KiB
Vue

<script setup>
import { useI18n } from 'vue-i18n';
const i18n = useI18n();
const t = i18n.t;
import { ref, useTemplateRef } from 'vue';
import { Dialog, TextInput, FormGroup, SingleSelect, MaskedInput } from '@cloudron/pankow';
import DockerRegistriesModel from '../models/DockerRegistriesModel.js';
const dockerRegistriesModel = DockerRegistriesModel.create();
const providers = [
{ name: 'AWS', value: 'aws' },
{ name: 'Cloudron', value: 'cloudron' },
{ name: 'Digital Ocean', value: 'digitalocean' },
{ name: 'DockerHub', value: 'dockerhub' },
{ name: 'Google Cloud', value: 'google-cloud' },
{ name: 'Linode', value: 'linode' },
{ name: 'Quay', value: 'quay' },
{ name: t('settings.registryConfig.providerOther') || 'Other', value: 'other' },
];
const emit = defineEmits([ 'success' ]);
const dialog = useTemplateRef('dialog');
const busy = ref(false);
const formError = ref({});
const registry = ref(null);
const provider = ref('');
const serverAddress = ref('');
const username = ref('');
const email = ref('');
const password = ref('');
const form = useTemplateRef('form');
const isFormValid = ref(false);
function checkValidity() {
isFormValid.value = form.value ? form.value.checkValidity() : false;
}
async function onSubmit() {
if (!form.value.reportValidity()) return;
busy.value = true;
formError.value = {};
let error;
if (registry.value) [error] = await dockerRegistriesModel.update(registry.value.id, provider.value, serverAddress.value, username.value, email.value, password.value);
else [error] = await dockerRegistriesModel.add(provider.value, serverAddress.value, username.value, email.value, password.value);
if (error) {
busy.value = false;
formError.value.generic = error.body ? error.body.message : 'Internal error';
return console.error(error);
}
emit('success');
dialog.value.close();
busy.value = false;
}
defineExpose({
async open(r = null) {
r = r ? JSON.parse(JSON.stringify(r)) : null; // make a copy
busy.value = false;
formError.value = {};
registry.value = r;
provider.value = r ? r.provider : '';
serverAddress.value = r ? r.serverAddress : '';
username.value = r ? r.username : '';
email.value = (r && typeof r.email === 'string') ? r.email : '';
password.value = r ? r.password : '';
dialog.value.open();
setTimeout(checkValidity, 100); // update state of the confirm button
}
});
</script>
<template>
<Dialog ref="dialog"
:title="registry ? $t('dockerRegistries.dialog.editTitle') : $t('dockerRegistries.dialog.addTitle')"
:confirm-label="registry ? $t('main.dialog.save') : $t('main.action.add')"
:confirm-busy="busy"
:confirm-active="!busy && isFormValid"
:reject-label="$t('main.dialog.cancel')"
reject-style="secondary"
@confirm="onSubmit()"
>
<form ref="form" @submit.prevent="onSubmit()" autocomplete="off" @input="checkValidity()">
<fieldset :disabled="busy">
<input style="display: none" type="submit" :disabled="busy"/>
<div class="error-label" v-if="formError.generic">{{ formError.generic }}</div>
<FormGroup>
<label for="providerInput">{{ $t('settings.registryConfig.provider') }} <sup><a href="https://docs.cloudron.io/settings/#private-docker-registry" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<SingleSelect id="providerInput" v-model="provider" :options="providers" option-key="value" option-label="name" required />
</FormGroup>
<FormGroup>
<label for="serverAddressInput">{{ $t('dockerRegistries.server') }}</label>
<TextInput id="serverAddressInput" v-model="serverAddress" placeholder="docker.io" required />
</FormGroup>
<FormGroup>
<label for="usernameInput">{{ $t('dockerRegistries.username') }}</label>
<TextInput id="usernameInput" v-model="username" required />
</FormGroup>
<FormGroup>
<label for="emailInput">{{ $t('dockerRegistries.email') }} (optional)</label>
<TextInput id="emailInput" v-model="email" />
</FormGroup>
<FormGroup>
<label for="passwordInput">{{ $t('dockerRegistries.passwordToken') }}</label>
<MaskedInput id="passwordInput" v-model="password" required />
</FormGroup>
</fieldset>
</form>
</Dialog>
</template>