proxmox-backup/www/window/DataStoreEdit.js
Thomas Lamprecht ad28d9ed75 ui: s3 datastore: use tech preview wording
As this is far from being experimental, but relaying that it's rather
new and might have some rough edges won't hurt.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2025-07-22 21:58:45 +02:00

242 lines
9.6 KiB
JavaScript

Ext.define('PBS.DataStoreEdit', {
extend: 'Proxmox.window.Edit',
alias: 'widget.pbsDataStoreEdit',
mixins: ['Proxmox.Mixin.CBind'],
subject: gettext('Datastore'),
isAdd: true,
bodyPadding: 0,
showProgress: true,
cbindData: function (initialConfig) {
var me = this;
let name = initialConfig.name;
let baseurl = '/api2/extjs/config/datastore';
me.isCreate = !name;
if (!me.isCreate) {
me.defaultFocus = 'textfield[name=comment]';
}
me.url = name ? baseurl + '/' + name : baseurl;
me.method = name ? 'PUT' : 'POST';
me.scheduleValue = name ? null : 'daily';
me.autoLoad = !!name;
return {};
},
items: {
xtype: 'tabpanel',
bodyPadding: 10,
listeners: {
tabchange: function (tb, newCard) {
Ext.GlobalEvents.fireEvent('proxmoxShowHelp', newCard.onlineHelp);
},
},
items: [
{
title: gettext('General'),
xtype: 'inputpanel',
onlineHelp: 'datastore_intro',
cbind: {
isCreate: '{isCreate}',
},
column1: [
{
xtype: 'pmxDisplayEditField',
cbind: {
editable: '{isCreate}',
},
name: 'name',
allowBlank: false,
fieldLabel: gettext('Name'),
},
{
xtype: 'proxmoxKVComboBox',
name: 'datastore-type',
fieldLabel: gettext('Datastore Type'),
value: '__default__',
submitValue: false,
comboItems: [
['__default__', gettext('Local')],
['removable', gettext('Removable')],
['s3', gettext('S3 (tech preview)')],
],
cbind: {
disabled: '{!isCreate}',
},
listeners: {
change: function (checkbox, selected) {
let isRemovable = selected === 'removable';
let isS3 = selected === 's3';
let inputPanel = checkbox.up('inputpanel');
let pathField = inputPanel.down('[name=path]');
let uuidEditField = inputPanel.down('[name=backing-device]');
let bucketField = inputPanel.down('[name=bucket]');
let s3ClientSelector = inputPanel.down('[name=s3client]');
let overwriteInUseField =
inputPanel.down('[name=overwrite-in-use]');
let reuseDatastore =
inputPanel.down('[name=reuse-datastore]').getValue();
uuidEditField.setDisabled(!isRemovable);
uuidEditField.allowBlank = !isRemovable;
uuidEditField.setValue('');
bucketField.setDisabled(!isS3);
bucketField.allowBlank = !isS3;
bucketField.setValue('');
s3ClientSelector.setDisabled(!isS3);
s3ClientSelector.allowBlank = !isS3;
s3ClientSelector.setValue('');
overwriteInUseField.setHidden(!isS3);
overwriteInUseField.setDisabled(!reuseDatastore);
overwriteInUseField.setValue(false);
if (isRemovable) {
pathField.setFieldLabel(gettext('Path on Device'));
pathField.setEmptyText(gettext('A relative path'));
} else if (isS3) {
pathField.setFieldLabel(gettext('Local Cache'));
pathField.setEmptyText(gettext('An absolute path'));
} else {
pathField.setFieldLabel(gettext('Backing Path'));
pathField.setEmptyText(gettext('An absolute path'));
}
},
},
},
{
xtype: 'pmxDisplayEditField',
cbind: {
editable: '{isCreate}',
},
name: 'path',
allowBlank: false,
fieldLabel: gettext('Backing Path'),
emptyText: gettext('An absolute path'),
validator: (val) => val?.trim() !== '/',
},
{
xtype: 'pbsS3ClientSelector',
name: 's3client',
fieldLabel: gettext('S3 Endpoint ID'),
disabled: true,
cbind: {
editable: '{isCreate}',
},
},
],
column2: [
{
xtype: 'pbsCalendarEvent',
name: 'gc-schedule',
fieldLabel: gettext('GC Schedule'),
emptyText: gettext('none'),
cbind: {
deleteEmpty: '{!isCreate}',
value: '{scheduleValue}',
},
},
{
xtype: 'pbsCalendarEvent',
name: 'prune-schedule',
fieldLabel: gettext('Prune Schedule'),
value: 'daily',
emptyText: gettext('none'),
cbind: {
deleteEmpty: '{!isCreate}',
value: '{scheduleValue}',
},
},
{
xtype: 'pbsPartitionSelector',
fieldLabel: gettext('Device'),
name: 'backing-device',
disabled: true,
allowBlank: true,
cbind: {
editable: '{isCreate}',
},
emptyText: gettext('Device path'),
},
{
xtype: 'proxmoxtextfield',
name: 'bucket',
fieldLabel: gettext('Bucket'),
allowBlank: false,
disabled: true,
},
],
columnB: [
{
xtype: 'textfield',
name: 'comment',
fieldLabel: gettext('Comment'),
},
],
advancedColumn1: [
{
xtype: 'checkbox',
name: 'reuse-datastore',
fieldLabel: gettext('Reuse existing datastore'),
listeners: {
change: function (checkbox, selected) {
let inputPanel = checkbox.up('inputpanel');
let overwriteInUseField =
inputPanel.down('[name=overwrite-in-use]');
overwriteInUseField.setDisabled(!selected);
overwriteInUseField.setValue(false);
},
},
},
],
advancedColumn2: [
{
xtype: 'checkbox',
name: 'overwrite-in-use',
fieldLabel: gettext('Overwrite in-use marker'),
hidden: true,
disabled: true,
},
],
onGetValues: function (values) {
let me = this;
if (me.isCreate) {
// New datastores default to using the notification system
values['notification-mode'] = 'notification-system';
if (values.s3client) {
let s3BackendConf = {
type: 's3',
client: values.s3client,
bucket: values.bucket,
};
values.backend = PBS.Utils.printPropertyString(s3BackendConf);
}
}
delete values.s3client;
delete values.bucket;
return values;
},
},
{
title: gettext('Prune Options'),
xtype: 'pbsPruneInputPanel',
cbind: {
isCreate: '{isCreate}',
},
onlineHelp: 'backup_pruning',
},
],
},
});