proxmox-backup/www/datastore/OptionView.js
Dominik Csapak 3e44935af7 ui: re-format code, replace mixed tab/spaces with spaces only.
Use `proxmox-biome format --write`, which is a small wrapper around
[Biome] that sets the desired config options for matching the Proxmox
style guide as close as possible.

Note that the space between function key word and parameter
parenthesis for anonymous functions or function names and parameter
parenthesis for named functions is rather odd and not per our style
guide, but this is not configurable and while it would be relatively
simple to change in the formatter code of biome, we would like to avoid
doing so for both maintenance reason and as this is seemingly the
default in the "web" industry, as prettier–one of the most popular
formatters for web projects–uses this and Biome copied the style
mostly from there.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
 [TL: add commit message with some background]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2025-06-16 13:59:27 +02:00

322 lines
11 KiB
JavaScript

Ext.define('PBS.window.SafeDatastoreDestroy', {
extend: 'Proxmox.window.SafeDestroy',
xtype: 'pbsDatastoreSafeDestroy',
mixins: ['Proxmox.Mixin.CBind'],
cbind: {
url: `/config/datastore/{datastore}`,
item: (get) => ({ id: get('datastore') }),
},
viewModel: {
data: {
destroyData: 0,
keepJobConfigs: 0,
},
formulas: {
destroyNote: (get) =>
get('destroyData')
? gettext('All backup snapshots and their data will be permanently destroyed!')
: gettext('Configuration change only, no data will be deleted.'),
destroyNoteCls: (get) => (get('destroyData') ? 'pmx-hint' : ''),
},
},
autoShow: true,
taskName: 'delete-datastore',
apiCallDone: function (success) {
if (success) {
let navtree = Ext.ComponentQuery.query('navigationtree')[0];
navtree.rstore.load();
let mainview = Ext.ComponentQuery.query('mainview')[0];
mainview.getController().redirectTo('pbsDataStores');
}
},
getParams: function () {
let viewModel = this.getViewModel();
let params = {
'destroy-data': viewModel.get('destroyData'),
'keep-job-configs': viewModel.get('keepJobConfigs'),
};
return `?${Ext.Object.toQueryString(params)}`;
},
additionalItems: [
{
xtype: 'proxmoxcheckbox',
name: 'destroy-data',
boxLabel: gettext('Destroy all data (dangerous!)'),
defaultValue: false,
bind: {
value: '{destroyData}',
},
},
{
xtype: 'proxmoxcheckbox',
name: 'keep-job-configs',
boxLabel: gettext('Keep configured jobs and permissions'),
defaultValue: false,
bind: {
value: '{keepJobConfigs}',
},
},
{
xtype: 'component',
reference: 'noteCmp',
bind: {
html: '{destroyNote}',
userCls: '{destroyNoteCls}',
},
},
],
});
Ext.define('PBS.Datastore.Options', {
extend: 'Proxmox.grid.ObjectGrid',
xtype: 'pbsDatastoreOptionView',
mixins: ['Proxmox.Mixin.CBind'],
cbindData: function (initial) {
let me = this;
me.maintenanceActiveTasks = {
read: 0,
write: 0,
};
me.datastore = encodeURIComponent(me.datastore);
me.url = `/api2/json/config/datastore/${me.datastore}`;
me.editorConfig = {
url: `/api2/extjs/config/datastore/${me.datastore}`,
datastore: me.datastore,
};
return {};
},
controller: {
xclass: 'Ext.app.ViewController',
init: function (view) {
let me = this;
me.activeOperationsRstore = Ext.create('Proxmox.data.ObjectStore', {
url: `/api2/json/admin/datastore/${view.datastore}/active-operations`,
interval: 3000,
});
me.activeOperationsRstore.startUpdate();
view.mon(me.activeOperationsRstore, 'load', (store, data, success) => {
let activeTasks = me.getView().maintenanceActiveTasks;
activeTasks.read = data?.[0]?.data.value ?? 0;
activeTasks.write = data?.[1]?.data.value ?? 0;
});
},
edit: function () {
this.getView().run_editor();
},
removeDatastore: function () {
let me = this;
Ext.create('PBS.window.SafeDatastoreDestroy', {
datastore: me.getView().datastore,
});
},
stopUpdates: function () {
let me = this;
let view = me.getView();
view.rstore.stopUpdate();
me.activeOperationsRstore.stopUpdate();
},
startUpdates: function () {
let me = this;
let view = me.getView();
view.rstore.startUpdate();
me.activeOperationsRstore.startUpdate();
},
},
tbar: [
{
xtype: 'proxmoxButton',
text: gettext('Edit'),
disabled: true,
handler: 'edit',
},
'->',
{
xtype: 'proxmoxButton',
selModel: null,
iconCls: 'fa fa-trash-o',
text: gettext('Remove Datastore'),
handler: 'removeDatastore',
},
],
listeners: {
activate: 'startUpdates',
beforedestroy: 'stopUpdates',
deactivate: 'stopUpdates',
itemdblclick: 'edit',
},
rows: {
'notification-mode': {
required: true,
defaultValue: 'legacy-sendmail',
header: gettext('Notification mode'),
renderer: function (value) {
if (value === 'notification-system') {
return gettext('Notification system');
} else {
return gettext('Email (legacy)');
}
},
editor: {
xtype: 'pbsNotifyOptionEdit',
},
},
notify: {
required: true,
header: gettext('Notify'),
renderer: (value) => {
let notify = PBS.Utils.parsePropertyString(value);
let res = [];
for (const k of ['Verify', 'Sync', 'GC', 'Prune']) {
let fallback = k === 'Prune' ? 'Error' : 'Always';
let v = Ext.String.capitalize(notify[k.toLowerCase()]) || fallback;
res.push(`${k}=${v}`);
}
return res.join(', ');
},
editor: {
xtype: 'pbsNotifyOptionEdit',
},
},
'notify-user': {
required: true,
defaultValue: 'root@pam',
header: gettext('Notify User'),
editor: {
xtype: 'pbsNotifyOptionEdit',
},
},
'verify-new': {
required: true,
header: gettext('Verify New Snapshots'),
defaultValue: false,
renderer: Proxmox.Utils.format_boolean,
editor: {
xtype: 'proxmoxWindowEdit',
title: gettext('Verify New'),
width: 350,
items: {
xtype: 'proxmoxcheckbox',
name: 'verify-new',
boxLabel: gettext('Verify new backups immediately after completion'),
defaultValue: false,
deleteDefaultValue: true,
deleteEmpty: true,
},
},
},
'maintenance-mode': {
required: true,
header: gettext('Maintenance mode'),
renderer: function (v) {
return PBS.Utils.renderMaintenance(v, this.maintenanceActiveTasks);
},
editor: {
xtype: 'pbsMaintenanceOptionEdit',
},
},
tuning: {
required: true,
header: gettext('Tuning Options'),
renderer: (v) => PBS.Utils.render_tuning_options(PBS.Utils.parsePropertyString(v)),
editor: {
xtype: 'proxmoxWindowEdit',
title: gettext('Tuning Options'),
onlineHelp: 'datastore_tuning_options',
width: 500,
items: {
xtype: 'inputpanel',
onGetValues: function (values) {
if (!Ext.isArray(values.delete ?? [])) {
values.delete = [values.delete];
}
for (const k of values.delete ?? []) {
delete values[k];
}
delete values.delete;
let tuning = PBS.Utils.printPropertyString(values);
if (!tuning) {
return { delete: 'tuning' };
}
return { tuning };
},
onSetValues: (values) => PBS.Utils.parsePropertyString(values?.tuning),
items: [
{
xtype: 'proxmoxKVComboBox',
name: 'chunk-order',
fieldLabel: gettext('Chunk Iteration Order'),
labelWidth: 200,
comboItems: Object.entries(PBS.Utils.tuningOptions['chunk-order']),
deleteEmpty: true,
value: '__default__',
},
{
xtype: 'proxmoxKVComboBox',
name: 'sync-level',
fieldLabel: gettext('Data Sync Level'),
labelWidth: 200,
comboItems: Object.entries(PBS.Utils.tuningOptions['sync-level']),
deleteEmpty: true,
value: '__default__',
},
{
xtype: 'proxmoxcheckbox',
name: 'gc-atime-safety-check',
fieldLabel: gettext('GC Access-Time Support Check'),
labelWidth: 200,
autoEl: {
tag: 'div',
'data-qtip': gettext(
'Ensure underlying storage honors access time updates',
),
},
value: 1,
uncheckedValue: 0,
defaultValue: 1,
deleteDefaultValue: true,
},
{
xtype: 'proxmoxintegerfield',
name: 'gc-atime-cutoff',
fieldLabel: gettext('GC Access-Time Cutoff (minutes)'),
labelWidth: 200,
emptyText: gettext('1445 (24 hours 5 minutes)'),
deleteEmpty: true,
},
{
xtype: 'proxmoxintegerfield',
name: 'gc-cache-capacity',
fieldLabel: gettext('GC Cache Capacity (# chunks)'),
labelWidth: 200,
emptyText: gettext('1048576 (0 disables cache)'),
minValue: 0,
maxValue: 8 * 1024 * 1024,
deleteEmpty: true,
step: 1024,
},
],
},
},
},
},
});