]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/StateProvider.js
fix #5251: login: set autocomplete on password and user
[pve-manager.git] / www / manager6 / StateProvider.js
1 /* This state provider keeps part of the state inside the browser history.
2 *
3 * We compress (shorten) url using dictionary based compression, i.e., we use
4 * column separated list instead of url encoded hash:
5 * #v\d* version/format
6 * := indicates string values
7 * :\d+ lookup value in dictionary hash
8 * #v1:=value1:5:=value2:=value3:...
9 */
10
11 Ext.define('PVE.StateProvider', {
12 extend: 'Ext.state.LocalStorageProvider',
13
14 // private
15 setHV: function(name, newvalue, fireEvents) {
16 let me = this;
17
18 let changes = false;
19 let oldtext = Ext.encode(me.UIState[name]);
20 let newtext = Ext.encode(newvalue);
21 if (newtext !== oldtext) {
22 changes = true;
23 me.UIState[name] = newvalue;
24 if (fireEvents) {
25 me.fireEvent("statechange", me, name, { value: newvalue });
26 }
27 }
28 return changes;
29 },
30
31 // private
32 hslist: [
33 // order is important for notifications
34 // [ name, default ]
35 ['view', 'server'],
36 ['rid', 'root'],
37 ['ltab', 'tasks'],
38 ['nodetab', ''],
39 ['storagetab', ''],
40 ['sdntab', ''],
41 ['pooltab', ''],
42 ['kvmtab', ''],
43 ['lxctab', ''],
44 ['dctab', ''],
45 ],
46
47 hprefix: 'v1',
48
49 compDict: {
50 tfa: 54,
51 sdn: 53,
52 cloudinit: 52,
53 replication: 51,
54 system: 50,
55 monitor: 49,
56 'ha-fencing': 48,
57 'ha-groups': 47,
58 'ha-resources': 46,
59 'ceph-log': 45,
60 'ceph-crushmap': 44,
61 'ceph-pools': 43,
62 'ceph-osdtree': 42,
63 'ceph-disklist': 41,
64 'ceph-monlist': 40,
65 'ceph-config': 39,
66 ceph: 38,
67 'firewall-fwlog': 37,
68 'firewall-options': 36,
69 'firewall-ipset': 35,
70 'firewall-aliases': 34,
71 'firewall-sg': 33,
72 firewall: 32,
73 apt: 31,
74 members: 30,
75 snapshot: 29,
76 ha: 28,
77 support: 27,
78 pools: 26,
79 syslog: 25,
80 ubc: 24,
81 initlog: 23,
82 openvz: 22,
83 backup: 21,
84 resources: 20,
85 content: 19,
86 root: 18,
87 domains: 17,
88 roles: 16,
89 groups: 15,
90 users: 14,
91 time: 13,
92 dns: 12,
93 network: 11,
94 services: 10,
95 options: 9,
96 console: 8,
97 hardware: 7,
98 permissions: 6,
99 summary: 5,
100 tasks: 4,
101 clog: 3,
102 storage: 2,
103 folder: 1,
104 server: 0,
105 },
106
107 decodeHToken: function(token) {
108 let me = this;
109
110 let state = {};
111 if (!token) {
112 me.hslist.forEach(([k, v]) => { state[k] = v; });
113 return state;
114 }
115
116 let [prefix, ...items] = token.split(':');
117
118 if (prefix !== me.hprefix) {
119 return me.decodeHToken();
120 }
121
122 Ext.Array.each(me.hslist, function(rec) {
123 let value = items.shift();
124 if (value) {
125 if (value[0] === '=') {
126 value = decodeURIComponent(value.slice(1));
127 }
128 for (const [key, hash] of Object.entries(me.compDict)) {
129 if (String(value) === String(hash)) {
130 value = key;
131 break;
132 }
133 }
134 }
135 state[rec[0]] = value;
136 });
137
138 return state;
139 },
140
141 encodeHToken: function(state) {
142 let me = this;
143
144 let ctoken = me.hprefix;
145 Ext.Array.each(me.hslist, function(rec) {
146 let value = state[rec[0]];
147 if (!Ext.isDefined(value)) {
148 value = rec[1];
149 }
150 value = encodeURIComponent(value);
151 if (!value) {
152 ctoken += ':';
153 } else if (Ext.isDefined(me.compDict[value])) {
154 ctoken += ":" + me.compDict[value];
155 } else {
156 ctoken += ":=" + value;
157 }
158 });
159
160 return ctoken;
161 },
162
163 constructor: function(config) {
164 let me = this;
165
166 me.callParent([config]);
167
168 me.UIState = me.decodeHToken(); // set default
169
170 let history_change_cb = function(token) {
171 if (!token) {
172 Ext.History.back();
173 return;
174 }
175
176 let newstate = me.decodeHToken(token);
177 Ext.Array.each(me.hslist, function(rec) {
178 if (typeof newstate[rec[0]] === "undefined") {
179 return;
180 }
181 me.setHV(rec[0], newstate[rec[0]], true);
182 });
183 };
184
185 let start_token = Ext.History.getToken();
186 if (start_token) {
187 history_change_cb(start_token);
188 } else {
189 let htext = me.encodeHToken(me.UIState);
190 Ext.History.add(htext);
191 }
192
193 Ext.History.on('change', history_change_cb);
194 },
195
196 get: function(name, defaultValue) {
197 let me = this;
198
199 let data;
200 if (typeof me.UIState[name] !== "undefined") {
201 data = { value: me.UIState[name] };
202 } else {
203 data = me.callParent(arguments);
204 if (!data && name === 'GuiCap') {
205 data = {
206 vms: {},
207 storage: {},
208 access: {},
209 nodes: {},
210 dc: {},
211 sdn: {},
212 };
213 }
214 }
215 return data;
216 },
217
218 clear: function(name) {
219 let me = this;
220
221 if (typeof me.UIState[name] !== "undefined") {
222 me.UIState[name] = null;
223 }
224 me.callParent(arguments);
225 },
226
227 set: function(name, value, fireevent) {
228 let me = this;
229
230 if (typeof me.UIState[name] !== "undefined") {
231 var newvalue = value ? value.value : null;
232 if (me.setHV(name, newvalue, fireevent)) {
233 let htext = me.encodeHToken(me.UIState);
234 Ext.History.add(htext);
235 }
236 } else {
237 me.callParent(arguments);
238 }
239 },
240 });