]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/form/TagEdit.js
1 Ext
.define('PVE.panel.TagEditContainer', {
2 extend
: 'Ext.container.Container',
3 alias
: 'widget.pveTagEditContainer',
10 // set to false to hide the 'no tags' field and the edit button
15 xclass
: 'Ext.app.ViewController',
17 loadTags: function(tagstring
= '', force
= false) {
19 let view
= me
.getView();
21 if (me
.oldTags
=== tagstring
&& !force
) {
25 view
.suspendLayout
= true;
26 me
.forEachTag((tag
) => {
29 me
.getViewModel().set('tagCount', 0);
30 let newtags
= tagstring
.split(/[;, ]/).filter((t
) => !!t
) || [];
31 newtags
.forEach((tag
) => {
34 view
.suspendLayout
= false;
37 me
.oldTags
= tagstring
;
42 onRender: function(v
) {
44 let view
= me
.getView();
45 view
.toggleCls('hide-handles', PVE
.UIOptions
.shouldSortTags());
47 view
.dragzone
= Ext
.create('Ext.dd.DragZone', v
.getEl(), {
48 getDragData: function(e
) {
49 let source
= e
.getTarget('.handle');
53 let sourceId
= source
.parentNode
.id
;
54 let cmp
= Ext
.getCmp(sourceId
);
55 let ddel
= document
.createElement('div');
56 ddel
.classList
.add('proxmox-tags-full');
57 ddel
.innerHTML
= Proxmox
.Utils
.getTagElement(cmp
.tag
, PVE
.UIOptions
.tagOverrides
);
58 let repairXY
= Ext
.fly(source
).getXY();
59 cmp
.setDisabled(true);
67 onMouseUp: function(target
, e
, id
) {
68 let cmp
= Ext
.getCmp(this.dragData
.sourceId
);
69 if (cmp
&& !cmp
.isDestroyed
) {
70 cmp
.setDisabled(false);
73 getRepairXY: function() {
74 return this.dragData
.repairXY
;
76 beforeInvalidDrop: function(target
, e
, id
) {
77 let cmp
= Ext
.getCmp(this.dragData
.sourceId
);
78 if (cmp
&& !cmp
.isDestroyed
) {
79 cmp
.setDisabled(false);
83 view
.dropzone
= Ext
.create('Ext.dd.DropZone', v
.getEl(), {
84 getTargetFromEvent: function(e
) {
85 return e
.getTarget('.proxmox-tag-dark,.proxmox-tag-light');
87 getIndicator: function() {
88 if (!view
.indicator
) {
89 view
.indicator
= Ext
.create('Ext.Component', {
91 html
: '<i class="fa fa-long-arrow-up"></i>',
96 return view
.indicator
;
98 onContainerOver: function() {
99 this.getIndicator().setVisible(false);
101 notifyOut: function() {
102 this.getIndicator().setVisible(false);
104 onNodeOver: function(target
, dd
, e
, data
) {
105 let indicator
= this.getIndicator();
106 indicator
.setVisible(true);
107 indicator
.alignTo(Ext
.getCmp(target
.id
), 't50-bl', [-1, -2]);
108 return this.dropAllowed
;
110 onNodeDrop: function(target
, dd
, e
, data
) {
111 this.getIndicator().setVisible(false);
112 let sourceCmp
= Ext
.getCmp(data
.sourceId
);
116 sourceCmp
.setDisabled(false);
117 let targetCmp
= Ext
.getCmp(target
.id
);
118 view
.remove(sourceCmp
, { destroy
: false });
119 view
.insert(view
.items
.indexOf(targetCmp
), sourceCmp
);
125 forEachTag: function(func
) {
127 let view
= me
.getView();
128 view
.items
.each((field
) => {
129 if (field
.getXType() === 'pveTag') {
136 toggleEdit: function(cancel
) {
138 let vm
= me
.getViewModel();
139 let view
= me
.getView();
140 let editMode
= !vm
.get('editMode');
141 vm
.set('editMode', editMode
);
143 // get a current tag list for editing
145 PVE
.UIOptions
.update();
148 me
.forEachTag((tag
) => {
149 tag
.setMode(editMode
? 'editable' : 'normal');
152 if (!vm
.get('editMode')) {
155 me
.loadTags(me
.oldTags
, true);
158 me
.forEachTag((cmp
) => {
159 if (cmp
.isVisible() && cmp
.tag
) {
165 toRemove
.forEach(cmp
=> view
.remove(cmp
));
166 tags
= tags
.join(',');
167 if (me
.oldTags
!== tags
) {
169 me
.loadTags(tags
, true);
170 me
.getView().fireEvent('change', tags
);
174 me
.getView().updateLayout();
177 tagsChanged: function() {
180 me
.forEachTag(cmp
=> {
185 me
.getViewModel().set('isDirty', me
.oldTags
!== tags
.join(','));
186 me
.forEachTag(cmp
=> {
187 cmp
.updateFilter(tags
);
191 addTag: function(tag
, isNew
) {
193 let view
= me
.getView();
194 let vm
= me
.getViewModel();
195 let index
= view
.items
.length
- 5;
196 if (PVE
.UIOptions
.shouldSortTags() && !isNew
) {
197 index
= view
.items
.findIndexBy(tagField
=> {
198 if (tagField
.reference
=== 'noTagsField') {
201 if (tagField
.xtype
!== 'pveTag') {
204 let a
= tagField
.tag
.toLowerCase();
205 let b
= tag
.toLowerCase();
206 return a
> b
? true : a
< b
? false : tagField
.tag
.localeCompare(tag
) > 0;
209 let tagField
= view
.insert(index
, {
212 mode
: vm
.get('editMode') ? 'editable' : 'normal',
214 change
: 'tagsChanged',
215 destroy: function() {
216 vm
.set('tagCount', vm
.get('tagCount') - 1);
219 keypress: function(key
) {
220 if (vm
.get('hideFinishButtons')) {
223 if (key
=== 'Enter') {
225 } else if (key
=== 'Escape') {
234 tagField
.selectText();
237 vm
.set('tagCount', vm
.get('tagCount') + 1);
240 addTagClick: function(event
) {
242 me
.lookup('noTagsField').setVisible(false);
246 cancelClick: function() {
247 this.toggleEdit(true);
250 editClick: function() {
251 this.toggleEdit(false);
254 init: function(view
) {
257 me
.loadTags(view
.tags
);
259 me
.getViewModel().set('canEdit', view
.canEdit
);
260 me
.getViewModel().set('editOnly', view
.editOnly
);
262 me
.mon(Ext
.GlobalEvents
, 'loadedUiOptions', () => {
263 let vm
= me
.getViewModel();
264 view
.toggleCls('hide-handles', PVE
.UIOptions
.shouldSortTags());
265 me
.loadTags(me
.oldTags
, !vm
.get('editMode')); // refresh tag colors and order
274 getTags: function() {
276 let controller
= me
.getController();
278 controller
.forEachTag((cmp
) => {
279 if (cmp
.tag
.length
) {
297 hideNoTags: function(get) {
298 return get('tagCount') !== 0 || !get('canEdit');
300 hideEditBtn: function(get) {
301 return get('editMode') || !get('canEdit');
303 hideFinishButtons: function(get) {
304 return !get('editMode') || get('editOnly');
309 loadTags: function() {
310 return this.getController().loadTags(...arguments
);
316 reference
: 'noTagsField',
318 hidden
: '{hideNoTags}',
320 html
: gettext('No Tags'),
327 iconCls
: 'fa fa-plus',
328 tooltip
: gettext('Add Tag'),
330 hidden
: '{!editMode}',
334 ui
: 'default-toolbar',
335 handler
: 'addTagClick',
338 xtype
: 'tbseparator',
341 hidden
: '{hideFinishButtons}',
347 iconCls
: 'fa fa-times',
348 tooltip
: gettext('Cancel Edit'),
350 hidden
: '{hideFinishButtons}',
354 ui
: 'default-toolbar',
355 handler
: 'cancelClick',
359 iconCls
: 'fa fa-check',
360 tooltip
: gettext('Finish Edit'),
362 hidden
: '{hideFinishButtons}',
363 disabled
: '{!isDirty}',
366 handler
: 'editClick',
370 cls
: 'pve-tag-inline-button',
371 html
: `<i data-qtip="${gettext('Edit Tags')}" class="fa fa-pencil"></i>`,
373 hidden
: '{hideEditBtn}',
386 destroy: function() {
388 Ext
.destroy(me
.dragzone
);
389 Ext
.destroy(me
.dropzone
);
390 Ext
.destroy(me
.indicator
);