]>
Commit | Line | Data |
---|---|---|
33083447 | 1 | /* This state provider keeps part of the state inside the browser history. |
f6dd72c1 | 2 | * |
33083447 TL |
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:... | |
f6dd72c1 DM |
9 | */ |
10 | ||
11 | Ext.define('PVE.StateProvider', { | |
12 | extend: 'Ext.state.LocalStorageProvider', | |
13 | ||
14 | // private | |
15 | setHV: function(name, newvalue, fireEvents) { | |
2f6cf848 | 16 | let me = this; |
f6dd72c1 | 17 | |
2f6cf848 TL |
18 | let changes = false; |
19 | let oldtext = Ext.encode(me.UIState[name]); | |
20 | let newtext = Ext.encode(newvalue); | |
21 | if (newtext !== oldtext) { | |
f6dd72c1 DM |
22 | changes = true; |
23 | me.UIState[name] = newvalue; | |
f6dd72c1 DM |
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', ''], | |
9233148b | 40 | ['sdntab', ''], |
f6dd72c1 DM |
41 | ['pooltab', ''], |
42 | ['kvmtab', ''], | |
ca966b7e | 43 | ['lxctab', ''], |
f6710aac | 44 | ['dctab', ''], |
f6dd72c1 DM |
45 | ], |
46 | ||
47 | hprefix: 'v1', | |
48 | ||
49 | compDict: { | |
e90127be | 50 | tfa: 54, |
9233148b | 51 | sdn: 53, |
4c507192 | 52 | cloudinit: 52, |
a0f3e8e3 | 53 | replication: 51, |
e62ebded | 54 | system: 50, |
e4731dcb | 55 | monitor: 49, |
ca966b7e DC |
56 | 'ha-fencing': 48, |
57 | 'ha-groups': 47, | |
58 | 'ha-resources': 46, | |
59 | 'ceph-log': 45, | |
8058410f | 60 | 'ceph-crushmap': 44, |
ca966b7e DC |
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, | |
f6dd72c1 DM |
75 | snapshot: 29, |
76 | ha: 28, | |
77 | support: 27, | |
ca966b7e | 78 | pools: 26, |
f6dd72c1 DM |
79 | syslog: 25, |
80 | ubc: 24, | |
81 | initlog: 23, | |
82 | openvz: 22, | |
83 | backup: 21, | |
ca966b7e | 84 | resources: 20, |
f6dd72c1 DM |
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, | |
f6710aac | 104 | server: 0, |
f6dd72c1 DM |
105 | }, |
106 | ||
107 | decodeHToken: function(token) { | |
2f6cf848 | 108 | let me = this; |
f6dd72c1 | 109 | |
2f6cf848 | 110 | let state = {}; |
f6dd72c1 | 111 | if (!token) { |
2f6cf848 | 112 | me.hslist.forEach(([k, v]) => { state[k] = v; }); |
f6dd72c1 DM |
113 | return state; |
114 | } | |
115 | ||
2f6cf848 | 116 | let [prefix, ...items] = token.split(':'); |
f6dd72c1 | 117 | |
2f6cf848 | 118 | if (prefix !== me.hprefix) { |
f6dd72c1 DM |
119 | return me.decodeHToken(); |
120 | } | |
121 | ||
122 | Ext.Array.each(me.hslist, function(rec) { | |
2f6cf848 | 123 | let value = items.shift(); |
f6dd72c1 DM |
124 | if (value) { |
125 | if (value[0] === '=') { | |
126 | value = decodeURIComponent(value.slice(1)); | |
d6b66187 TL |
127 | } |
128 | for (const [key, hash] of Object.entries(me.compDict)) { | |
129 | if (String(value) === String(hash)) { | |
130 | value = key; | |
131 | break; | |
2f6cf848 | 132 | } |
f6dd72c1 DM |
133 | } |
134 | } | |
135 | state[rec[0]] = value; | |
136 | }); | |
137 | ||
138 | return state; | |
139 | }, | |
140 | ||
141 | encodeHToken: function(state) { | |
2f6cf848 | 142 | let me = this; |
f6dd72c1 | 143 | |
2f6cf848 | 144 | let ctoken = me.hprefix; |
f6dd72c1 | 145 | Ext.Array.each(me.hslist, function(rec) { |
2f6cf848 | 146 | let value = state[rec[0]]; |
f6dd72c1 DM |
147 | if (!Ext.isDefined(value)) { |
148 | value = rec[1]; | |
149 | } | |
150 | value = encodeURIComponent(value); | |
151 | if (!value) { | |
152 | ctoken += ':'; | |
2f6cf848 TL |
153 | } else if (Ext.isDefined(me.compDict[value])) { |
154 | ctoken += ":" + me.compDict[value]; | |
f6dd72c1 | 155 | } else { |
2f6cf848 | 156 | ctoken += ":=" + value; |
f6dd72c1 DM |
157 | } |
158 | }); | |
159 | ||
160 | return ctoken; | |
161 | }, | |
162 | ||
8058410f | 163 | constructor: function(config) { |
2f6cf848 | 164 | let me = this; |
f6dd72c1 DM |
165 | |
166 | me.callParent([config]); | |
167 | ||
168 | me.UIState = me.decodeHToken(); // set default | |
169 | ||
2f6cf848 | 170 | let history_change_cb = function(token) { |
f6dd72c1 | 171 | if (!token) { |
265f10dd | 172 | Ext.History.back(); |
f6dd72c1 DM |
173 | return; |
174 | } | |
175 | ||
2f6cf848 | 176 | let newstate = me.decodeHToken(token); |
f6dd72c1 | 177 | Ext.Array.each(me.hslist, function(rec) { |
2f6cf848 | 178 | if (typeof newstate[rec[0]] === "undefined") { |
f6dd72c1 DM |
179 | return; |
180 | } | |
181 | me.setHV(rec[0], newstate[rec[0]], true); | |
182 | }); | |
183 | }; | |
184 | ||
2f6cf848 | 185 | let start_token = Ext.History.getToken(); |
f6dd72c1 DM |
186 | if (start_token) { |
187 | history_change_cb(start_token); | |
188 | } else { | |
2f6cf848 | 189 | let htext = me.encodeHToken(me.UIState); |
f6dd72c1 DM |
190 | Ext.History.add(htext); |
191 | } | |
192 | ||
193 | Ext.History.on('change', history_change_cb); | |
194 | }, | |
195 | ||
8058410f | 196 | get: function(name, defaultValue) { |
2f6cf848 | 197 | let me = this; |
f6dd72c1 | 198 | |
2f6cf848 TL |
199 | let data; |
200 | if (typeof me.UIState[name] !== "undefined") { | |
f6dd72c1 DM |
201 | data = { value: me.UIState[name] }; |
202 | } else { | |
203 | data = me.callParent(arguments); | |
204 | if (!data && name === 'GuiCap') { | |
2f6cf848 TL |
205 | data = { |
206 | vms: {}, | |
207 | storage: {}, | |
208 | access: {}, | |
209 | nodes: {}, | |
210 | dc: {}, | |
211 | sdn: {}, | |
212 | }; | |
f6dd72c1 DM |
213 | } |
214 | } | |
f6dd72c1 DM |
215 | return data; |
216 | }, | |
217 | ||
8058410f | 218 | clear: function(name) { |
2f6cf848 | 219 | let me = this; |
f6dd72c1 | 220 | |
2f6cf848 | 221 | if (typeof me.UIState[name] !== "undefined") { |
f6dd72c1 DM |
222 | me.UIState[name] = null; |
223 | } | |
f6dd72c1 DM |
224 | me.callParent(arguments); |
225 | }, | |
226 | ||
8058410f | 227 | set: function(name, value, fireevent) { |
2f6cf848 | 228 | let me = this; |
f6dd72c1 | 229 | |
2f6cf848 | 230 | if (typeof me.UIState[name] !== "undefined") { |
f6dd72c1 | 231 | var newvalue = value ? value.value : null; |
71c8e23f | 232 | if (me.setHV(name, newvalue, fireevent)) { |
2f6cf848 | 233 | let htext = me.encodeHToken(me.UIState); |
f6dd72c1 DM |
234 | Ext.History.add(htext); |
235 | } | |
236 | } else { | |
237 | me.callParent(arguments); | |
238 | } | |
f6710aac | 239 | }, |
f6dd72c1 | 240 | }); |