2020-05-29 10:53:41 +02:00
Ext . define ( 'PBS.window.SyncJobEdit' , {
extend : 'Proxmox.window.Edit' ,
alias : 'widget.pbsSyncJobEdit' ,
mixins : [ 'Proxmox.Mixin.CBind' ] ,
userid : undefined ,
2020-09-11 10:35:28 +02:00
onlineHelp : 'syncjobs' ,
2020-05-29 10:53:41 +02:00
isAdd : true ,
2024-11-11 16:43:49 +01:00
subject : gettext ( 'Sync Job - Pull Direction' ) ,
2020-05-29 10:53:41 +02:00
2021-11-29 15:39:43 +01:00
bodyPadding : 0 ,
2020-05-29 10:53:41 +02:00
fieldDefaults : { labelWidth : 120 } ,
2020-11-04 19:05:46 +01:00
defaultFocus : 'proxmoxtextfield[name=comment]' ,
2020-05-29 10:53:41 +02:00
cbindData : function ( initialConfig ) {
let me = this ;
let baseurl = '/api2/extjs/config/sync' ;
let id = initialConfig . id ;
me . isCreate = ! id ;
me . url = id ? ` ${ baseurl } / ${ id } ` : baseurl ;
me . method = id ? 'PUT' : 'POST' ;
me . autoLoad = ! ! id ;
2020-11-04 19:04:06 +01:00
me . scheduleValue = id ? null : 'hourly' ;
2020-11-06 13:01:57 +01:00
me . authid = id ? null : Proxmox . UserName ;
2020-11-09 16:01:25 +01:00
me . editDatastore = me . datastore === undefined && me . isCreate ;
2024-11-11 16:43:49 +01:00
if ( me . syncDirection === 'push' ) {
me . subject = gettext ( 'Sync Job - Push Direction' ) ;
me . syncDirectionPush = true ;
me . syncRemoteLabel = gettext ( 'Target Remote' ) ;
me . syncRemoteDatastore = gettext ( 'Target Datastore' ) ;
me . syncRemoteNamespace = gettext ( 'Target Namespace' ) ;
me . syncLocalOwner = gettext ( 'Local User' ) ;
// Sync direction request parameter is only required for creating new jobs,
// for edit and delete it is derived from the job config given by it's id.
if ( me . isCreate ) {
me . extraRequestParams = {
"sync-direction" : 'push' ,
} ;
}
} else {
me . subject = gettext ( 'Sync Job - Pull Direction' ) ;
me . syncDirectionPush = false ;
me . syncRemoteLabel = gettext ( 'Source Remote' ) ;
me . syncRemoteDatastore = gettext ( 'Source Datastore' ) ;
me . syncRemoteNamespace = gettext ( 'Source Namespace' ) ;
me . syncLocalOwner = gettext ( 'Local Owner' ) ;
}
2020-05-29 10:53:41 +02:00
return { } ;
} ,
2022-05-11 17:44:58 +02:00
controller : {
xclass : 'Ext.app.ViewController' ,
control : {
'pbsDataStoreSelector[name=store]' : {
change : 'storeChange' ,
} ,
} ,
storeChange : function ( field , value ) {
let view = this . getView ( ) ;
let nsSelector = view . down ( 'pbsNamespaceSelector[name=ns]' ) ;
nsSelector . setDatastore ( value ) ;
} ,
2024-11-25 12:03:23 +01:00
init : function ( ) {
let view = this . getView ( ) ;
if ( view . syncDirectionPush && view . datastore !== undefined ) {
let localNs = view . down ( 'pbsNamespaceSelector[name=ns]' ) . getValue ( ) ;
view . down ( 'pbsGroupFilter' ) . setLocalNamespace ( view . datastore , localNs ) ;
}
} ,
2022-05-11 17:44:58 +02:00
} ,
2023-11-21 15:31:55 +01:00
setValues : function ( values ) {
let me = this ;
if ( values . id && ! values . remote ) {
values . location = 'local' ;
} else {
values . location = 'remote' ;
}
me . callParent ( [ values ] ) ;
} ,
2022-05-11 17:44:58 +02:00
2020-05-29 10:53:41 +02:00
items : {
2021-11-29 15:39:43 +01:00
xtype : 'tabpanel' ,
bodyPadding : 10 ,
border : 0 ,
items : [
2020-05-29 10:53:41 +02:00
{
2021-11-29 15:39:43 +01:00
title : 'Options' ,
xtype : 'inputpanel' ,
onGetValues : function ( values ) {
let me = this ;
if ( ! values . id && me . up ( 'pbsSyncJobEdit' ) . isCreate ) {
values . id = 's-' + Ext . data . identifier . Uuid . Global . generate ( ) . slice ( 0 , 13 ) ;
}
if ( ! me . isCreate ) {
PBS . Utils . delete _if _default ( values , 'rate-in' ) ;
2023-11-28 15:16:54 +01:00
PBS . Utils . delete _if _default ( values , 'remote' ) ;
2021-11-29 15:39:43 +01:00
if ( typeof values . delete === 'string' ) {
values . delete = values . delete . split ( ',' ) ;
}
}
return values ;
2020-11-04 19:07:07 +01:00
} ,
2024-03-06 12:21:03 +01:00
cbind : {
isCreate : '{isCreate}' , // pass it through
} ,
2021-11-29 15:39:43 +01:00
column1 : [
{
xtype : 'pmxDisplayEditField' ,
fieldLabel : gettext ( 'Local Datastore' ) ,
name : 'store' ,
submitValue : true ,
cbind : {
editable : '{editDatastore}' ,
value : '{datastore}' ,
} ,
editConfig : {
xtype : 'pbsDataStoreSelector' ,
allowBlank : false ,
} ,
2024-11-25 12:03:23 +01:00
listeners : {
change : function ( field , localStore ) {
let me = this ;
let view = me . up ( 'pbsSyncJobEdit' ) ;
if ( view . syncDirectionPush ) {
let localNs = view . down ( 'pbsNamespaceSelector[name=ns]' ) . getValue ( ) ;
view . down ( 'pbsGroupFilter' ) . setLocalNamespace ( localStore , localNs ) ;
}
} ,
} ,
2021-11-29 15:39:43 +01:00
} ,
2022-05-10 15:02:23 +02:00
{
2022-05-11 17:44:58 +02:00
xtype : 'pbsNamespaceSelector' ,
2022-05-10 15:02:23 +02:00
fieldLabel : gettext ( 'Local Namespace' ) ,
name : 'ns' ,
cbind : {
datastore : '{datastore}' ,
} ,
2022-05-13 11:55:54 +02:00
listeners : {
2022-05-13 13:14:53 +02:00
change : function ( field , localNs ) {
2022-05-13 11:55:54 +02:00
let me = this ;
2022-05-13 13:14:53 +02:00
let view = me . up ( 'pbsSyncJobEdit' ) ;
2024-11-25 12:03:23 +01:00
if ( view . syncDirectionPush ) {
let localStore = view . down ( 'field[name=store]' ) . getValue ( ) ;
view . down ( 'pbsGroupFilter' ) . setLocalNamespace ( localStore , localNs ) ;
}
2022-05-13 13:14:53 +02:00
let remoteNs = view . down ( 'pbsRemoteNamespaceSelector[name=remote-ns]' ) . getValue ( ) ;
let maxDepthField = view . down ( 'field[name=max-depth]' ) ;
maxDepthField . setLimit ( localNs , remoteNs ) ;
2022-05-13 11:55:54 +02:00
maxDepthField . validate ( ) ;
} ,
} ,
2022-05-10 15:02:23 +02:00
} ,
2021-11-29 15:39:43 +01:00
{
xtype : 'pbsAuthidSelector' ,
name : 'owner' ,
cbind : {
2024-11-11 16:43:49 +01:00
fieldLabel : '{syncLocalOwner}' ,
2021-11-29 15:39:43 +01:00
value : '{authid}' ,
deleteEmpty : '{!isCreate}' ,
} ,
} ,
{
2022-05-10 15:02:23 +02:00
fieldLabel : gettext ( 'Sync Schedule' ) ,
xtype : 'pbsCalendarEvent' ,
name : 'schedule' ,
emptyText : gettext ( 'none (disabled)' ) ,
cbind : {
2024-07-15 12:15:42 +02:00
deleteEmpty : '{!isCreate}' ,
value : '{scheduleValue}' ,
2021-11-29 15:39:43 +01:00
} ,
2022-05-10 15:02:23 +02:00
} ,
{
xtype : 'pmxBandwidthField' ,
name : 'rate-in' ,
fieldLabel : gettext ( 'Rate Limit' ) ,
emptyText : gettext ( 'Unlimited' ) ,
submitAutoScaledSizeUnit : true ,
// NOTE: handle deleteEmpty in onGetValues due to bandwidth field having a cbind too
2021-11-29 15:39:43 +01:00
} ,
] ,
2020-11-04 19:05:46 +01:00
2021-11-29 15:39:43 +01:00
column2 : [
2023-11-21 15:31:55 +01:00
{
xtype : 'radiogroup' ,
fieldLabel : gettext ( 'Location' ) ,
defaultType : 'radiofield' ,
2024-11-11 16:43:49 +01:00
cbind : {
disabled : '{syncDirectionPush}' ,
} ,
2023-11-21 15:31:55 +01:00
items : [
{
boxLabel : 'Local' ,
name : 'location' ,
inputValue : 'local' ,
submitValue : false ,
} ,
{
boxLabel : 'Remote' ,
name : 'location' ,
inputValue : 'remote' ,
submitValue : false ,
checked : true ,
} ,
] ,
listeners : {
change : function ( _group , radio ) {
let me = this ;
let form = me . up ( 'pbsSyncJobEdit' ) ;
let nsField = form . down ( 'field[name=remote-ns]' ) ;
let rateLimitField = form . down ( 'field[name=rate-in]' ) ;
let remoteField = form . down ( 'field[name=remote]' ) ;
let storeField = form . down ( 'field[name=remote-store]' ) ;
if ( ! storeField . value ) {
nsField . clearValue ( ) ;
nsField . setDisabled ( true ) ;
}
let isLocalSync = radio . location === 'local' ;
2023-11-29 10:56:58 +01:00
rateLimitField . setDisabled ( isLocalSync ) ;
2023-11-21 15:31:55 +01:00
remoteField . allowBlank = isLocalSync ;
remoteField . setDisabled ( isLocalSync ) ;
storeField . setDisabled ( ! isLocalSync && ! remoteField . value ) ;
if ( isLocalSync === ! ! remoteField . value ) {
remoteField . clearValue ( ) ;
}
if ( isLocalSync ) {
storeField . setDisabled ( false ) ;
rateLimitField . setValue ( null ) ;
2023-11-28 14:01:24 +01:00
storeField . setRemote ( null , true ) ;
2023-11-21 15:31:55 +01:00
} else {
2023-11-28 14:01:24 +01:00
storeField . clearValue ( ) ;
2023-11-21 15:31:55 +01:00
remoteField . validate ( ) ;
}
} ,
} ,
} ,
2021-11-29 15:39:43 +01:00
{
2024-11-11 16:43:49 +01:00
cbind : {
fieldLabel : '{syncRemoteLabel}' ,
} ,
2021-11-29 15:39:43 +01:00
xtype : 'pbsRemoteSelector' ,
allowBlank : false ,
name : 'remote' ,
2023-11-21 15:31:55 +01:00
skipEmptyText : true ,
2021-11-29 15:39:43 +01:00
listeners : {
change : function ( f , value ) {
let me = this ;
let remoteStoreField = me . up ( 'pbsSyncJobEdit' ) . down ( 'field[name=remote-store]' ) ;
remoteStoreField . setRemote ( value ) ;
2023-11-21 15:31:55 +01:00
let rateLimitField = me . up ( 'pbsSyncJobEdit' ) . down ( 'field[name=rate-in]' ) ;
rateLimitField . setDisabled ( ! value ) ;
if ( ! value ) {
rateLimitField . setValue ( null ) ;
}
2022-05-10 15:02:23 +02:00
let remoteNamespaceField = me . up ( 'pbsSyncJobEdit' ) . down ( 'field[name=remote-ns]' ) ;
remoteNamespaceField . setRemote ( value ) ;
2021-11-29 15:39:43 +01:00
} ,
} ,
2020-11-05 12:12:24 +01:00
} ,
2021-11-29 15:39:43 +01:00
{
xtype : 'pbsRemoteStoreSelector' ,
allowBlank : false ,
autoSelect : false ,
name : 'remote-store' ,
2023-11-29 08:57:28 +01:00
cbind : {
datastore : '{datastore}' ,
2024-11-11 16:43:49 +01:00
fieldLabel : '{syncRemoteDatastore}' ,
2023-11-29 08:57:28 +01:00
} ,
2021-11-29 15:39:43 +01:00
listeners : {
change : function ( field , value ) {
let me = this ;
let remoteField = me . up ( 'pbsSyncJobEdit' ) . down ( 'field[name=remote]' ) ;
let remote = remoteField . getValue ( ) ;
2022-05-10 15:02:23 +02:00
let remoteNamespaceField = me . up ( 'pbsSyncJobEdit' ) . down ( 'field[name=remote-ns]' ) ;
remoteNamespaceField . setRemote ( remote ) ;
remoteNamespaceField . setRemoteStore ( value ) ;
2024-11-11 16:43:47 +01:00
2024-11-25 12:03:23 +01:00
let view = me . up ( 'pbsSyncJobEdit' ) ;
if ( ! view . syncDirectionPush ) {
2024-11-11 16:43:47 +01:00
me . up ( 'tabpanel' ) . down ( 'pbsGroupFilter' ) . setRemoteDatastore ( remote , value ) ;
} else {
let localStore = me . up ( 'pbsSyncJobEdit' ) . down ( 'field[name=store]' ) . getValue ( ) ;
me . up ( 'tabpanel' ) . down ( 'pbsGroupFilter' ) . setLocalDatastore ( localStore ) ;
}
2021-11-29 15:39:43 +01:00
} ,
} ,
} ,
{
2024-11-11 16:43:49 +01:00
cbind : {
fieldLabel : '{syncRemoteNamespace}' ,
} ,
2022-05-10 15:02:23 +02:00
xtype : 'pbsRemoteNamespaceSelector' ,
allowBlank : true ,
autoSelect : false ,
name : 'remote-ns' ,
disabled : true ,
listeners : {
2022-05-13 13:14:53 +02:00
change : function ( field , remoteNs ) {
2022-05-10 15:02:23 +02:00
let me = this ;
2022-05-13 13:14:53 +02:00
let view = me . up ( 'pbsSyncJobEdit' ) ;
let remote = view . down ( 'field[name=remote]' ) . getValue ( ) ;
let remoteStore = view . down ( 'field[name=remote-store]' ) . getValue ( ) ;
2024-11-25 12:03:23 +01:00
if ( ! view . syncDirectionPush ) {
me . up ( 'tabpanel' ) . down ( 'pbsGroupFilter' ) . setRemoteNamespace ( remote , remoteStore , remoteNs ) ;
}
2022-05-13 13:14:53 +02:00
let localNs = view . down ( 'pbsNamespaceSelector[name=ns]' ) . getValue ( ) ;
let maxDepthField = view . down ( 'field[name=max-depth]' ) ;
maxDepthField . setLimit ( localNs , remoteNs ) ;
2022-05-13 11:55:54 +02:00
maxDepthField . validate ( ) ;
2022-05-10 15:02:23 +02:00
} ,
2021-11-29 15:39:43 +01:00
} ,
} ,
{
2022-05-13 11:55:54 +02:00
xtype : 'pbsNamespaceMaxDepthReduced' ,
2022-05-10 15:02:23 +02:00
name : 'max-depth' ,
fieldLabel : gettext ( 'Max. Depth' ) ,
2024-03-06 12:21:03 +01:00
cbind : {
deleteEmpty : '{!isCreate}' ,
} ,
2022-05-10 15:02:23 +02:00
} ,
{
fieldLabel : gettext ( 'Remove vanished' ) ,
xtype : 'proxmoxcheckbox' ,
name : 'remove-vanished' ,
autoEl : {
tag : 'div' ,
2024-11-28 11:01:10 +01:00
'data-qtip' : gettext ( 'Remove snapshots from sync target datastore if they vanished from source datastore?' ) ,
2022-05-10 15:02:23 +02:00
} ,
uncheckedValue : false ,
value : false ,
2021-11-29 15:39:43 +01:00
} ,
] ,
2020-05-29 10:53:41 +02:00
2021-11-29 15:39:43 +01:00
columnB : [
{
fieldLabel : gettext ( 'Comment' ) ,
xtype : 'proxmoxtextfield' ,
name : 'comment' ,
cbind : {
deleteEmpty : '{!isCreate}' ,
} ,
} ,
] ,
2022-05-16 18:48:44 +02:00
advancedColumn1 : [
{
2022-05-17 09:47:15 +02:00
xtype : 'pmxDisplayEditField' ,
2022-05-16 18:48:44 +02:00
fieldLabel : gettext ( 'Job ID' ) ,
emptyText : gettext ( 'Autogenerate' ) ,
name : 'id' ,
allowBlank : true ,
regex : PBS . Utils . SAFE _ID _RE ,
2022-05-17 09:05:22 +02:00
cbind : {
2022-05-17 09:47:15 +02:00
editable : '{isCreate}' ,
2022-05-17 09:05:22 +02:00
} ,
2022-05-16 18:48:44 +02:00
} ,
2023-04-18 16:59:47 +02:00
{
fieldLabel : gettext ( 'Transfer Last' ) ,
xtype : 'pbsPruneKeepInput' ,
name : 'transfer-last' ,
emptyText : gettext ( 'all' ) ,
autoEl : {
tag : 'div' ,
'data-qtip' : gettext ( 'The maximum amount of snapshots to be transferred (per group)' ) ,
} ,
cbind : {
deleteEmpty : '{!isCreate}' ,
} ,
} ,
2024-11-22 13:16:16 +01:00
{
fieldLabel : gettext ( 'Re-sync corrupt snapshots' ) ,
xtype : 'proxmoxcheckbox' ,
name : 'resync-corrupt' ,
autoEl : {
tag : 'div' ,
'data-qtip' : gettext ( 'Re-sync snapshots, whose verification failed.' ) ,
} ,
cbind : {
disabled : '{syncDirectionPush}' ,
} ,
uncheckedValue : false ,
value : false ,
} ,
2022-05-16 18:48:44 +02:00
] ,
2021-10-28 15:00:54 +02:00
} ,
2020-05-29 10:53:41 +02:00
{
2021-11-29 15:39:43 +01:00
xtype : 'inputpanel' ,
onGetValues : function ( values ) {
2024-03-06 12:21:03 +01:00
let me = this ;
2021-11-29 15:39:43 +01:00
PBS . Utils . delete _if _default ( values , 'group-filter' ) ;
2021-12-01 14:30:38 +01:00
if ( Ext . isArray ( values [ 'group-filter' ] ) ) {
if ( values [ 'group-filter' ] . length === 0 ) {
delete values [ 'group-filter' ] ;
values . delete = 'group-filter' ;
} else {
// merge duplicates
values [ 'group-filter' ] = [ ... new Set ( values [ 'group-filter' ] ) ] ;
}
2021-11-29 15:39:43 +01:00
}
2024-03-06 12:21:03 +01:00
if ( me . isCreate ) {
delete values . delete ;
}
2021-11-29 15:39:43 +01:00
return values ;
2020-06-23 15:29:57 +02:00
} ,
2024-03-06 12:21:03 +01:00
cbind : {
isCreate : '{isCreate}' , // pass it through
} ,
2021-11-29 15:39:43 +01:00
title : gettext ( 'Group Filter' ) ,
items : [
{
xtype : 'pbsGroupFilter' ,
name : 'group-filter' ,
} ,
] ,
2020-05-29 10:53:41 +02:00
} ,
] ,
} ,
} ) ;