Files
cloudron-box/dashboard/src/components/PrivateRegistry.vue
2025-01-31 21:02:48 +01:00

171 lines
6.0 KiB
Vue

<script setup>
import { useI18n } from 'vue-i18n';
const i18n = useI18n();
const t = i18n.t;
import { ref, useTemplateRef, onMounted, computed } from 'vue';
import { Button, Dialog, FormGroup, PasswordInput, TextInput, Dropdown } from 'pankow';
import { isValidDomainOrURL } from 'pankow/utils';
import Section from '../components/Section.vue';
import CloudronModel from '../models/CloudronModel.js';
const cloudronModel = CloudronModel.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: 'Treescale', value: 'treescale' },
{ name: t('settings.registryConfig.providerOther') || 'Other', value: 'other' },
{ name: t('settings.registryConfig.providerDisabled') || 'Disabled', value: 'noop' }
];
const provider = ref('');
const serverAddress = ref('');
const username = ref('');
const email = ref('');
const password = ref('');
// configure
const dialog = useTemplateRef('dialog');
const configureBusy = ref(false);
const configureError = ref('');
const configureProvider = ref('');
const configureServerAddress = ref('');
const configureUsername = ref('');
const configureEmail = ref('');
const configurePassword = ref('');
const isValid = computed(() => {
if (configureProvider.value === 'noop') return true;
if (!configureServerAddress.value) return false;
if (!configureUsername.value) return false;
if (!configurePassword.value) return false;
if (!isValidDomainOrURL(configureServerAddress.value)) return false;
return true;
});
function onShowConfigure() {
configureBusy.value = false;
configureError.value = '';
configureProvider.value = provider.value;
configureServerAddress.value = serverAddress.value;
configureUsername.value = username.value;
configureEmail.value = email.value;
configurePassword.value = password.value;
dialog.value.open();
}
async function onSubmitConfigure() {
if (!isValid.value) return;
configureBusy.value = true;
configureError.value = '';
const data = {
provider: configureProvider.value
};
if (configureProvider.value !== 'noop') {
data.serverAddress = configureServerAddress.value;
data.username = configureUsername.value;
data.email = configureEmail.value;
data.password = configurePassword.value;
};
const [error] = await cloudronModel.setRegistryConfig(data);
if (error) {
configureError.value = error.body ? error.body.message : 'Internal error';
configureBusy.value = false;
return console.error(error);
}
await refresh();
dialog.value.close();
configureBusy.value = false;
}
async function refresh() {
const [error, result] = await cloudronModel.getRegistryConfig();
if (error) return console.error(error);
provider.value = result.provider;
serverAddress.value = result.serverAddress;
email.value = result.email;
username.value = result.username;
password.value = result.password;
}
onMounted(async () => {
await refresh();
});
</script>
<template>
<Dialog ref="dialog"
:title="$t('settings.privateDockerRegistryDialog.title')"
:confirm-label="$t('main.dialog.save')"
:confirm-busy="configureBusy"
:confirm-active="!configureBusy && isValid"
:reject-label="$t('main.dialog.cancel')"
reject-style="secondary"
@confirm="onSubmitConfigure()"
>
<p class="has-error text-center" v-show="configureError">{{ configureError }}</p>
<form novalidate @submit.prevent="onSubmitConfigure()" autocomplete="off">
<fieldset :disabled="configureBusy">
<input style="display: none" type="submit" :disabled="!isValid"/>
<FormGroup>
<label for="providerInput">{{ $t('settings.registryConfig.provider') }} <sup><a ng-href="https://docs.cloudron.io/settings/#private-docker-registry" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<Dropdown id="providerInput" v-model="configureProvider" :options="providers" option-key="value" option-label="name" />
</FormGroup>
<FormGroup v-if="configureProvider !== 'noop'">
<label for="serverAddressInput">{{ $t('settings.privateDockerRegistry.server') }}</label>
<TextInput id="serverAddressInput" v-model="configureServerAddress" placeholder="docker.io" required />
</FormGroup>
<FormGroup v-if="configureProvider !== 'noop'">
<label for="usernameInput">{{ $t('settings.privateDockerRegistry.username') }}</label>
<TextInput id="usernameInput" v-model="configureUsername" required />
</FormGroup>
<FormGroup v-if="configureProvider !== 'noop'">
<label for="emailInput">{{ $t('settings.privateDockerRegistryDialog.email') }}</label>
<TextInput id="emailInput" v-model="configureEmail" />
</FormGroup>
<FormGroup v-if="configureProvider !== 'noop'">
<label for="passwordInput">{{ $t('settings.privateDockerRegistryDialog.passwordToken') }}</label>
<PasswordInput id="passwordInput" v-model="configurePassword" required />
</FormGroup>
</fieldset>
</form>
</Dialog>
<Section :title="$t('settings.privateDockerRegistry.title')">
<p v-html="$t('settings.privateDockerRegistry.description', { customAppsLink: 'https://docs.cloudron.io/custom-apps/tutorial/' })"></p>
<div class="info-row">
<div class="info-label">{{ $t('settings.privateDockerRegistry.server') }}</div>
<div class="info-value">{{ serverAddress || $t('settings.privateDockerRegistry.serverNotSet') }}</div>
</div>
<div class="info-row">
<div class="info-label">{{ $t('settings.privateDockerRegistry.username') }}</div>
<div class="info-value">{{ username || email || $t('settings.privateDockerRegistry.usernameNotSet') }}</div>
</div>
<Button @click="onShowConfigure()">{{ $t('settings.privateDockerRegistry.configureAction') }}</Button>
</Section>
</template>