public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property
@ 2021-04-08 11:39 Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 2/7] ui: tape/ChangerStatus: save assigned drives Dominik Csapak
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Dominik Csapak @ 2021-04-08 11:39 UTC (permalink / raw)
  To: pbs-devel

it will actually not fail, but we declare it nonetheless to indicate
that it exists

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/tape/ChangerStatus.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/www/tape/ChangerStatus.js b/www/tape/ChangerStatus.js
index 68316345..f8bff531 100644
--- a/www/tape/ChangerStatus.js
+++ b/www/tape/ChangerStatus.js
@@ -370,6 +370,7 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 	},
 
 	free_slots: [],
+	free_ie_slots: [],
 
 	updateFreeSlots: function(free_slots, free_ie_slots) {
 	    let me = this;
-- 
2.20.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 2/7] ui: tape/ChangerStatus: save assigned drives
  2021-04-08 11:39 [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property Dominik Csapak
@ 2021-04-08 11:39 ` Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 3/7] ui: tape/ChangerStatus: rework EraseWindow Dominik Csapak
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Dominik Csapak @ 2021-04-08 11:39 UTC (permalink / raw)
  To: pbs-devel

so that we can shortcut later if we only have one

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/tape/ChangerStatus.js | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/www/tape/ChangerStatus.js b/www/tape/ChangerStatus.js
index f8bff531..fb4ad1e3 100644
--- a/www/tape/ChangerStatus.js
+++ b/www/tape/ChangerStatus.js
@@ -369,6 +369,13 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 	    me.reload_full(false);
 	},
 
+	drives: [],
+
+	updateDrives: function(drives) {
+	    let me = this;
+	    me.drives = drives;
+	},
+
 	free_slots: [],
 	free_ie_slots: [],
 
@@ -440,11 +447,15 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 		let free_slots = [];
 		let free_ie_slots = [];
 
+		let valid_drives = [];
+
 		for (let entry of status.result.data) {
 		    let type = entry['entry-kind'];
+		    let id = entry['entry-id'];
 
-		    if (type === 'drive' && drive_entries[entry['entry-id']] !== undefined) {
-			entry = Ext.applyIf(entry, drive_entries[entry['entry-id']]);
+		    if (type === 'drive' && drive_entries[id] !== undefined) {
+			entry = Ext.applyIf(entry, drive_entries[id]);
+			valid_drives.push(drive_entries[id].name);
 		    }
 
 		    if (tapes[entry['label-text']] !== undefined) {
@@ -458,12 +469,12 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 		    if (!entry['label-text'] && type !== 'drive') {
 			if (type === 'slot') {
 			    free_slots.push({
-				id: entry['entry-id'],
+				id,
 				type,
 			    });
 			} else {
 			    free_ie_slots.push({
-				id: entry['entry-id'],
+				id,
 				type,
 			    });
 			}
@@ -488,6 +499,7 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 		me.lookup('drives').getSelectionModel().fireEvent('selectionchange', me);
 
 		me.updateFreeSlots(free_slots, free_ie_slots);
+		me.updateDrives(valid_drives);
 
 		if (!use_cache) {
 		    Proxmox.Utils.setErrorMask(view);
-- 
2.20.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 3/7] ui: tape/ChangerStatus: rework EraseWindow
  2021-04-08 11:39 [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 2/7] ui: tape/ChangerStatus: save assigned drives Dominik Csapak
@ 2021-04-08 11:39 ` Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 4/7] ui: tape/ChangerStatus: shortcut 'load-media' for single drive Dominik Csapak
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Dominik Csapak @ 2021-04-08 11:39 UTC (permalink / raw)
  To: pbs-devel

to make it more like a 'dangerous' remove window
also works in the singleDrive logic to hide/show the driveselector

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
i am not completely happy with the code, but i did not want
to completely rewrite neither the editwindow nor the safedestroy window,
and i did not want to reimplement the editwindow functions...

if someone has a better idea/suggestions how to implement this
(especially the layout...), please do so

 www/tape/ChangerStatus.js |  2 +
 www/tape/window/Erase.js  | 90 +++++++++++++++++++++++++++++----------
 2 files changed, 69 insertions(+), 23 deletions(-)

diff --git a/www/tape/ChangerStatus.js b/www/tape/ChangerStatus.js
index fb4ad1e3..dadb2a6e 100644
--- a/www/tape/ChangerStatus.js
+++ b/www/tape/ChangerStatus.js
@@ -144,9 +144,11 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 	    let label = record.data['label-text'];
 
 	    let changer = encodeURIComponent(view.changer);
+	    let singleDrive = me.drives.length === 1 ? me.drives[0] : undefined;
 	    Ext.create('PBS.TapeManagement.EraseWindow', {
 		label,
 		changer,
+		singleDrive,
 		listeners: {
 		    destroy: function() {
 			me.reload();
diff --git a/www/tape/window/Erase.js b/www/tape/window/Erase.js
index 1177dfeb..8b166d30 100644
--- a/www/tape/window/Erase.js
+++ b/www/tape/window/Erase.js
@@ -8,7 +8,11 @@ Ext.define('PBS.TapeManagement.EraseWindow', {
 
     cbindData: function(config) {
 	let me = this;
-	return {};
+	return {
+	    singleDrive: me.singleDrive,
+	    hasSingleDrive: !!me.singleDrive,
+	    warning: Ext.String.format(gettext("Are you sure you want to erase tape '{0}' ?"), me.label),
+	};
     },
 
     title: gettext('Format/Erase'),
@@ -20,32 +24,72 @@ Ext.define('PBS.TapeManagement.EraseWindow', {
 	return `${url}/${drive}/format-media`;
     },
 
+    layout: 'hbox',
+    width: 400,
     method: 'POST',
+    isCreate: true,
+    submitText: gettext('Ok'),
     items: [
 	{
-	    xtype: 'displayfield',
-	    cls: 'pmx-hint',
-	    value: gettext('Make sure to insert the tape into the selected drive.'),
-	    cbind: {
-		hidden: '{changer}',
-	    },
-	},
-	{
-	    xtype: 'displayfield',
-	    name: 'label-text',
-	    submitValue: true,
-	    fieldLabel: gettext('Media'),
-	    cbind: {
-		value: '{label}',
-	    },
-	},
-	{
-	    xtype: 'pbsDriveSelector',
-	    fieldLabel: gettext('Drive'),
-	    name: 'drive',
-	    cbind: {
-		changer: '{changer}',
+	    xtype: 'container',
+	    padding: 0,
+	    layout: {
+		type: 'hbox',
+		align: 'stretch',
 	    },
+	    items: [
+		{
+		    xtype: 'component',
+		    cls: [Ext.baseCSSPrefix + 'message-box-icon',
+			Ext.baseCSSPrefix + 'message-box-warning',
+			Ext.baseCSSPrefix + 'dlg-icon'],
+		},
+		{
+		    xtype: 'container',
+		    flex: 1,
+		    items: [
+			{
+			    xtype: 'displayfield',
+			    cbind: {
+				value: '{warning}',
+			    },
+			},
+			{
+			    xtype: 'displayfield',
+			    cls: 'pmx-hint',
+			    value: gettext('Make sure to insert the tape into the selected drive.'),
+			    cbind: {
+				hidden: '{changer}',
+			    },
+			},
+			{
+			    xtype: 'hidden',
+			    name: 'label-text',
+			    cbind: {
+				value: '{label}',
+			    },
+			},
+			{
+			    xtype: 'hidden',
+			    name: 'drive',
+			    cbind: {
+				disabled: '{!hasSingleDrive}',
+				value: '{singleDrive}',
+			    },
+			},
+			{
+			    xtype: 'pbsDriveSelector',
+			    fieldLabel: gettext('Drive'),
+			    name: 'drive',
+			    cbind: {
+				changer: '{changer}',
+				disabled: '{hasSingleDrive}',
+				hidden: '{hasSingleDrive}',
+			    },
+			},
+		    ],
+		},
+	    ],
 	},
     ],
 });
-- 
2.20.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 4/7] ui: tape/ChangerStatus: shortcut 'load-media' for single drive
  2021-04-08 11:39 [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 2/7] ui: tape/ChangerStatus: save assigned drives Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 3/7] ui: tape/ChangerStatus: rework EraseWindow Dominik Csapak
@ 2021-04-08 11:39 ` Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 5/7] ui: tape/ChangerStatus: shortcut Inventory for single drives Dominik Csapak
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Dominik Csapak @ 2021-04-08 11:39 UTC (permalink / raw)
  To: pbs-devel

if a changer only has a single drive, there is no point in showing
a window with a DriveSelector, just do want the user wanted.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/tape/ChangerStatus.js | 82 +++++++++++++++++++++++++--------------
 1 file changed, 52 insertions(+), 30 deletions(-)

diff --git a/www/tape/ChangerStatus.js b/www/tape/ChangerStatus.js
index dadb2a6e..22330d3b 100644
--- a/www/tape/ChangerStatus.js
+++ b/www/tape/ChangerStatus.js
@@ -163,40 +163,62 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 	    let label = record.data['label-text'];
 
 	    let changer = encodeURIComponent(view.changer);
+	    let singleDrive = me.drives.length === 1 ? me.drives[0] : undefined;
 
-	    Ext.create('Proxmox.window.Edit', {
-		isCreate: true,
-		autoShow: true,
-		submitText: gettext('OK'),
-		title: gettext('Load Media into Drive'),
-		url: `/api2/extjs/tape/drive`,
-		method: 'POST',
-		submitUrl: function(url, values) {
-		    let drive = values.drive;
-		    delete values.drive;
-		    return `${url}/${encodeURIComponent(drive)}/load-media`;
-		},
-		items: [
-		    {
-			xtype: 'displayfield',
-			name: 'label-text',
-			value: label,
-			submitValue: true,
-			fieldLabel: gettext('Media'),
+	    if (singleDrive !== undefined) {
+		Proxmox.Utils.API2Request({
+		    method: 'POST',
+		    params: {
+			'label-text': label,
 		    },
-		    {
-			xtype: 'pbsDriveSelector',
-			fieldLabel: gettext('Drive'),
-			changer: changer,
-			name: 'drive',
+		    url: `/api2/extjs/tape/drive/${singleDrive}/load-media`,
+		    success: function(response, opt) {
+			Ext.create('Proxmox.window.TaskProgress', {
+			    upid: response.result.data,
+			    taskDone: function(success) {
+				me.reload();
+			    },
+			}).show();
 		    },
-		],
-		listeners: {
-		    destroy: function() {
-			me.reload();
+		    failure: function(response, opt) {
+			Ext.Msg.alert(gettext('Error'), response.htmlStatus);
 		    },
-		},
-	    });
+		});
+	    } else {
+		Ext.create('Proxmox.window.Edit', {
+		    isCreate: true,
+		    autoShow: true,
+		    submitText: gettext('OK'),
+		    title: gettext('Load Media into Drive'),
+		    url: `/api2/extjs/tape/drive`,
+		    method: 'POST',
+		    submitUrl: function(url, values) {
+			let drive = values.drive;
+			delete values.drive;
+			return `${url}/${encodeURIComponent(drive)}/load-media`;
+		    },
+		    items: [
+			{
+			    xtype: 'displayfield',
+			    name: 'label-text',
+			    value: label,
+			    submitValue: true,
+			    fieldLabel: gettext('Media'),
+			},
+			{
+			    xtype: 'pbsDriveSelector',
+			    fieldLabel: gettext('Drive'),
+			    changer: changer,
+			    name: 'drive',
+			},
+		    ],
+		    listeners: {
+			destroy: function() {
+			    me.reload();
+			},
+		    },
+		});
+	    }
 	},
 
 	unload: async function(v, rI, cI, button, el, record) {
-- 
2.20.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 5/7] ui: tape/ChangerStatus: shortcut Inventory for single drives
  2021-04-08 11:39 [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property Dominik Csapak
                   ` (2 preceding siblings ...)
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 4/7] ui: tape/ChangerStatus: shortcut 'load-media' for single drive Dominik Csapak
@ 2021-04-08 11:39 ` Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 6/7] ui: tape/ChangerStatus: hide selector for single drives in barcode-label Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 7/7] ui: tape/DriveStatus: improve status grid a bit Dominik Csapak
  5 siblings, 0 replies; 7+ messages in thread
From: Dominik Csapak @ 2021-04-08 11:39 UTC (permalink / raw)
  To: pbs-devel

like 'load-media'

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/tape/ChangerStatus.js | 56 ++++++++++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/www/tape/ChangerStatus.js b/www/tape/ChangerStatus.js
index 22330d3b..9b1d8c47 100644
--- a/www/tape/ChangerStatus.js
+++ b/www/tape/ChangerStatus.js
@@ -339,26 +339,46 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 		return;
 	    }
 
-	    Ext.create('Proxmox.window.Edit', {
-		title: gettext('Inventory'),
-		showTaskViewer: true,
-		method: 'PUT',
-		url: '/api2/extjs/tape/drive',
-		submitUrl: function(url, values) {
-		    let drive = values.drive;
-		    delete values.drive;
-		    return `${url}/${encodeURIComponent(drive)}/inventory`;
-		},
+	    let singleDrive = me.drives.length === 1 ? me.drives[0] : undefined;
 
-		items: [
-		    {
-			xtype: 'pbsDriveSelector',
-			fieldLabel: gettext('Drive'),
-			name: 'drive',
-			changer: changer,
+	    if (singleDrive !== undefined) {
+		Proxmox.Utils.API2Request({
+		    method: 'PUT',
+		    url: `/api2/extjs/tape/drive/${singleDrive}/inventory`,
+		    success: function(response, opt) {
+			Ext.create('Proxmox.window.TaskViewer', {
+			    upid: response.result.data,
+			    taskDone: function(success) {
+				me.reload();
+			    },
+			}).show();
 		    },
-		],
-	    }).show();
+		    failure: function(response, opt) {
+			Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+		    },
+		});
+	    } else {
+		Ext.create('Proxmox.window.Edit', {
+		    title: gettext('Inventory'),
+		    showTaskViewer: true,
+		    method: 'PUT',
+		    url: '/api2/extjs/tape/drive',
+		    submitUrl: function(url, values) {
+			let drive = values.drive;
+			delete values.drive;
+			return `${url}/${encodeURIComponent(drive)}/inventory`;
+		    },
+
+		    items: [
+			{
+			    xtype: 'pbsDriveSelector',
+			    fieldLabel: gettext('Drive'),
+			    name: 'drive',
+			    changer: changer,
+			},
+		    ],
+		}).show();
+	    }
 	},
 
 	scheduleReload: function(time) {
-- 
2.20.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 6/7] ui: tape/ChangerStatus: hide selector for single drives in barcode-label
  2021-04-08 11:39 [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property Dominik Csapak
                   ` (3 preceding siblings ...)
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 5/7] ui: tape/ChangerStatus: shortcut Inventory for single drives Dominik Csapak
@ 2021-04-08 11:39 ` Dominik Csapak
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 7/7] ui: tape/DriveStatus: improve status grid a bit Dominik Csapak
  5 siblings, 0 replies; 7+ messages in thread
From: Dominik Csapak @ 2021-04-08 11:39 UTC (permalink / raw)
  To: pbs-devel

it is rather pointless to let the user select something were there
is no choice. We have to keep the window though, since the user may
want to choose a pool

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/tape/ChangerStatus.js | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/www/tape/ChangerStatus.js b/www/tape/ChangerStatus.js
index 9b1d8c47..2f6e29df 100644
--- a/www/tape/ChangerStatus.js
+++ b/www/tape/ChangerStatus.js
@@ -302,6 +302,8 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 		return;
 	    }
 
+	    let singleDrive = me.drives.length === 1 ? me.drives[0] : undefined;
+
 	    Ext.create('Proxmox.window.Edit', {
 		title: gettext('Barcode Label'),
 		showTaskViewer: true,
@@ -315,9 +317,11 @@ Ext.define('PBS.TapeManagement.ChangerStatus', {
 
 		items: [
 		    {
-			xtype: 'pbsDriveSelector',
+			xtype: singleDrive === undefined ? 'pbsDriveSelector' : 'displayfield',
 			fieldLabel: gettext('Drive'),
+			submitValue: true,
 			name: 'drive',
+			value: singleDrive,
 			changer: changer,
 		    },
 		    {
-- 
2.20.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 7/7] ui: tape/DriveStatus: improve status grid a bit
  2021-04-08 11:39 [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property Dominik Csapak
                   ` (4 preceding siblings ...)
  2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 6/7] ui: tape/ChangerStatus: hide selector for single drives in barcode-label Dominik Csapak
@ 2021-04-08 11:39 ` Dominik Csapak
  5 siblings, 0 replies; 7+ messages in thread
From: Dominik Csapak @ 2021-04-08 11:39 UTC (permalink / raw)
  To: pbs-devel

by using format_boolean for compression/write protect,
combining file/block posiition into one (saves a line)

and adding the missing alert-flags

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/tape/DriveStatus.js | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/www/tape/DriveStatus.js b/www/tape/DriveStatus.js
index e965bac1..cd001bff 100644
--- a/www/tape/DriveStatus.js
+++ b/www/tape/DriveStatus.js
@@ -317,6 +317,7 @@ Ext.define('PBS.TapeManagement.DriveStatusGrid', {
 	    required: true,
 	    header: gettext('Write Protect'),
 	    defaultValue: false,
+	    renderer: Proxmox.Utils.format_boolean,
 	},
 	'buffer-mode': {
 	    required: true,
@@ -325,12 +326,23 @@ Ext.define('PBS.TapeManagement.DriveStatusGrid', {
 	'compression': {
 	    required: true,
 	    header: gettext('Compression'),
+	    renderer: Proxmox.Utils.format_boolean,
 	},
 	'file-number': {
-	    header: gettext('File Number'),
+	    header: gettext('Tape Position'),
+	    renderer: function(value, mD, r, rI, cI, store) {
+		let me = this;
+		let filenr = value;
+		let rec = store.getById('block-number');
+		if (rec) {
+		    let blocknr = rec.data.value;
+		    return `File ${filenr}, Block ${blocknr}`;
+		}
+		return `File ${filenr}`;
+	    },
 	},
 	'block-number': {
-	    header: gettext('Block Number'),
+	    visible: false,
 	},
 	'manufactured': {
 	    header: gettext('Tape Manufacture Date'),
@@ -361,6 +373,9 @@ Ext.define('PBS.TapeManagement.DriveStatusGrid', {
 		return value;
 	    },
 	},
+	'alert-flags': {
+	    header: gettext('Alert Flags'),
+	},
     },
 });
 
-- 
2.20.1





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-04-08 11:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-08 11:39 [pbs-devel] [PATCH proxmox-backup 1/7] ui: tape/ChangerStatus: add missing property Dominik Csapak
2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 2/7] ui: tape/ChangerStatus: save assigned drives Dominik Csapak
2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 3/7] ui: tape/ChangerStatus: rework EraseWindow Dominik Csapak
2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 4/7] ui: tape/ChangerStatus: shortcut 'load-media' for single drive Dominik Csapak
2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 5/7] ui: tape/ChangerStatus: shortcut Inventory for single drives Dominik Csapak
2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 6/7] ui: tape/ChangerStatus: hide selector for single drives in barcode-label Dominik Csapak
2021-04-08 11:39 ` [pbs-devel] [PATCH proxmox-backup 7/7] ui: tape/DriveStatus: improve status grid a bit Dominik Csapak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal