From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 4E23EB005; Wed, 6 Apr 2022 10:27:29 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 425F927FF9; Wed, 6 Apr 2022 10:26:59 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 5FB6C27FEE; Wed, 6 Apr 2022 10:26:58 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 34D6341DF6; Wed, 6 Apr 2022 10:26:58 +0200 (CEST) Message-ID: Date: Wed, 6 Apr 2022 10:26:43 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Content-Language: en-US To: pbs-devel@lists.proxmox.com, pve-devel@lists.proxmox.com References: <20220401101908.1154385-1-s.sterz@proxmox.com> <20220401101908.1154385-3-s.sterz@proxmox.com> From: Stefan Sterz In-Reply-To: <20220401101908.1154385-3-s.sterz@proxmox.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.315 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment NICE_REPLY_A -0.631 Looks like a legit reply (A) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: Re: [pve-devel] [PATCH widget-toolkit v4 2/4] toolkit: add markdown based NotesView and NotesEdit X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Apr 2022 08:27:29 -0000 I realized that there are some more improvements to be made here, I'll send an updated version in a bit. Sorry for the inconvenience. On 01.04.22 12:19, Stefan Sterz wrote: > adds a universal version of NotesView and NotesEdit to the widget > toolkit that is compatible with pve and pbs. this avoids maintaining > duplicate code in pve and pbs, but since the original versions were > very tightly integrated with pve-manager, changes are required to > make them compatible with pbs. changes include: making the tbar > configurable, setting the url differently in a pbs context, and > allowing the caller to set the onlineHelp field. > > Signed-off-by: Stefan Sterz > --- > src/Makefile | 2 + > src/panel/NotesView.js | 149 ++++++++++++++++++++++++++++++++++++++++ > src/window/NotesEdit.js | 38 ++++++++++ > 3 files changed, 189 insertions(+) > create mode 100644 src/panel/NotesView.js > create mode 100644 src/window/NotesEdit.js > > diff --git a/src/Makefile b/src/Makefile > index abafc2c..dd7729e 100644 > --- a/src/Makefile > +++ b/src/Makefile > @@ -66,6 +66,7 @@ JSSRC= \ > panel/ACMEDomains.js \ > panel/StatusView.js \ > panel/TfaView.js \ > + panel/NotesView.js \ > window/Edit.js \ > window/PasswordEdit.js \ > window/SafeDestroy.js \ > @@ -87,6 +88,7 @@ JSSRC= \ > window/AddWebauthn.js \ > window/AddYubico.js \ > window/TfaEdit.js \ > + window/NotesEdit.js \ > node/APT.js \ > node/APTRepositories.js \ > node/NetworkEdit.js \ > diff --git a/src/panel/NotesView.js b/src/panel/NotesView.js > new file mode 100644 > index 0000000..d1c902f > --- /dev/null > +++ b/src/panel/NotesView.js > @@ -0,0 +1,149 @@ > +Ext.define('Proxmox.panel.NotesView', { > + extend: 'Ext.panel.Panel', > + xtype: 'pmxNotesView', > + mixins: ['Proxmox.Mixin.CBind'], > + > + title: gettext("Notes"), > + bodyPadding: 10, > + scrollable: true, > + animCollapse: false, > + maxLength: 64 * 1024, > + enableTBar: false, > + onlineHelp: 'markdown_basics', > + > + tbar: { > + itemId: 'tbar', > + hidden: true, > + items: [ > + { > + text: gettext('Edit'), > + handler: function() { > + let view = this.up('panel'); > + view.run_editor(); > + }, > + }, > + ], > + }, > + > + cbindData: function(initalConfig) { > + let me = this; > + let type = ''; > + > + if (me.node) { > + me.url = `/api2/extjs/nodes/${me.node}/config`; > + } else if (me.pveSelNode?.data?.id === 'root') { > + me.url = '/api2/extjs/cluster/options'; > + type = me.pveSelNode?.data?.type; > + } else { > + const nodename = me.pveSelNode?.data?.node; > + type = me.pveSelNode?.data?.type; > + > + if (!nodename) { > + throw "no node name specified"; > + } > + > + if (!Ext.Array.contains(['node', 'qemu', 'lxc'], type)) { > + throw 'invalid type specified'; > + } > + > + const vmid = me.pveSelNode?.data?.vmid; > + > + if (!vmid && type !== 'node') { > + throw "no VM ID specified"; > + } > + > + me.url = `/api2/extjs/nodes/${nodename}/`; > + > + // add the type specific path if qemu/lxc and set the backend's maxLen > + if (type === 'qemu' || type === 'lxc') { > + me.url += `${type}/${vmid}/`; > + me.maxLength = 8 * 1024; > + } > + > + me.url += 'config'; > + } > + > + me.pveType = type; > + return {}; > + }, > + > + run_editor: function() { > + let me = this; > + Ext.create('Proxmox.window.NotesEdit', { > + url: me.url, > + onlineHelp: me.onlineHelp, > + listeners: { > + destroy: () => me.load(), > + }, > + autoShow: true, > + }).setMaxLength(me.maxLength); > + }, > + > + setNotes: function(value) { > + let me = this; > + > + let mdHtml = Proxmox.Markdown.parse(value || ''); > + me.update(mdHtml); > + > + if (me.collapsible && me.collapseMode === 'auto') { > + me.setCollapsed(!value); > + } > + }, > + > + load: function() { > + var me = this; > + > + Proxmox.Utils.API2Request({ > + url: me.url, > + waitMsgTarget: me, > + failure: function(response, opts) { > + me.update(gettext('Error') + " " + response.htmlStatus); > + me.setCollapsed(false); > + }, > + success: ({ result }) => me.setNotes(result.data.description), > + }); > + }, > + > + listeners: { > + render: function(c) { > + var me = this; > + me.getEl().on('dblclick', me.run_editor, me); > + }, > + afterlayout: function() { > + let me = this; > + if (me.collapsible && !me.getCollapsed() && me.collapseMode === 'always') { > + me.setCollapsed(true); > + me.collapseMode = ''; // only once, on initial load! > + } > + }, > + }, > + > + tools: [{ > + type: 'gear', > + handler: function() { > + this.up('panel').run_editor(); > + }, > + }], > + > + initComponent: function() { > + const me = this; > + me.callParent(); > + > + // '' is for datacenter > + if (me.enableTBar === true || me.pveType === 'node' || me.pveType === '') { > + me.down('#tbar').setVisible(true); > + } else if (me.pveSelNode?.data?.template !== 1) { > + me.setCollapsible(true); > + me.collapseDirection = 'right'; > + > + let sp = Ext.state.Manager.getProvider(); > + me.collapseMode = sp.get('guest-notes-collapse', 'never'); > + > + if (me.collapseMode === 'auto') { > + me.setCollapsed(true); > + } > + } > + > + me.load(); > + }, > +}); > diff --git a/src/window/NotesEdit.js b/src/window/NotesEdit.js > new file mode 100644 > index 0000000..ab5254d > --- /dev/null > +++ b/src/window/NotesEdit.js > @@ -0,0 +1,38 @@ > +Ext.define('Proxmox.window.NotesEdit', { > + extend: 'Proxmox.window.Edit', > + > + title: gettext('Notes'), > + onlineHelp: 'markdown_basics', > + > + width: 800, > + height: '600px', > + > + resizable: true, > + layout: 'fit', > + > + autoLoad: true, > + defaultButton: undefined, > + > + setMaxLength: function(maxLength) { > + let me = this; > + > + let area = me.down('textarea[name="description"]'); > + area.maxLength = maxLength; > + area.validate(); > + > + return me; > + }, > + > + items: { > + xtype: 'textarea', > + name: 'description', > + height: '100%', > + value: '', > + hideLabel: true, > + emptyText: gettext('You can use Markdown for rich text formatting.'), > + fieldStyle: { > + 'white-space': 'pre-wrap', > + 'font-family': 'monospace', > + }, > + }, > +});