Some checks failed
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled
126 lines
3.5 KiB
JavaScript
126 lines
3.5 KiB
JavaScript
const containerCustomizationsManager = {
|
|
apiBase: window.location.origin,
|
|
_initialized: false,
|
|
_loadPromise: null,
|
|
|
|
byKey: new Map(),
|
|
listeners: new Set(),
|
|
|
|
getAuthHeaders() {
|
|
const token = localStorage.getItem('accessToken');
|
|
const apiKey = localStorage.getItem('apiKey');
|
|
|
|
const headers = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
|
|
if (token) {
|
|
headers['Authorization'] = `Bearer ${token}`;
|
|
} else if (apiKey) {
|
|
headers['X-API-Key'] = apiKey;
|
|
}
|
|
|
|
return headers;
|
|
},
|
|
|
|
async fetchAPI(endpoint, options = {}) {
|
|
const response = await fetch(`${this.apiBase}${endpoint}`, {
|
|
...options,
|
|
headers: {
|
|
...this.getAuthHeaders(),
|
|
...(options.headers || {})
|
|
}
|
|
});
|
|
|
|
if (!response.ok) {
|
|
if (response.status === 401) {
|
|
if (window.dashboard?.logout) {
|
|
window.dashboard.logout();
|
|
}
|
|
return null;
|
|
}
|
|
throw new Error(`API Error: ${response.status}`);
|
|
}
|
|
|
|
if (response.status === 204) return null;
|
|
return response.json();
|
|
},
|
|
|
|
_key(hostId, containerId) {
|
|
return `${hostId}::${containerId}`;
|
|
},
|
|
|
|
setData(items) {
|
|
this.byKey.clear();
|
|
(items || []).forEach((c) => {
|
|
if (!c?.host_id || !c?.container_id) return;
|
|
this.byKey.set(this._key(c.host_id, c.container_id), c);
|
|
});
|
|
this._emitChange();
|
|
},
|
|
|
|
async load() {
|
|
const res = await this.fetchAPI('/api/docker/container-customizations');
|
|
this.setData(res?.customizations || []);
|
|
},
|
|
|
|
async ensureInit() {
|
|
if (this._initialized) return;
|
|
if (this._loadPromise) {
|
|
await this._loadPromise;
|
|
return;
|
|
}
|
|
|
|
this._loadPromise = (async () => {
|
|
try {
|
|
await this.load();
|
|
} finally {
|
|
this._initialized = true;
|
|
}
|
|
})();
|
|
|
|
await this._loadPromise;
|
|
},
|
|
|
|
onChange(callback) {
|
|
this.listeners.add(callback);
|
|
return () => this.listeners.delete(callback);
|
|
},
|
|
|
|
_emitChange() {
|
|
for (const cb of this.listeners) {
|
|
try {
|
|
cb();
|
|
} catch (e) {
|
|
console.error('containerCustomizationsManager listener error:', e);
|
|
}
|
|
}
|
|
},
|
|
|
|
get(hostId, containerId) {
|
|
return this.byKey.get(this._key(hostId, containerId)) || null;
|
|
},
|
|
|
|
async upsert(hostId, containerId, { icon_key = null, icon_color = null, bg_color = null }) {
|
|
const payload = { icon_key, icon_color, bg_color };
|
|
const res = await this.fetchAPI(`/api/docker/container-customizations/${encodeURIComponent(hostId)}/${encodeURIComponent(containerId)}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(payload)
|
|
});
|
|
if (!res) return null;
|
|
this.byKey.set(this._key(hostId, containerId), res);
|
|
this._emitChange();
|
|
return res;
|
|
},
|
|
|
|
async remove(hostId, containerId) {
|
|
await this.fetchAPI(`/api/docker/container-customizations/${encodeURIComponent(hostId)}/${encodeURIComponent(containerId)}`, {
|
|
method: 'DELETE'
|
|
});
|
|
this.byKey.delete(this._key(hostId, containerId));
|
|
this._emitChange();
|
|
}
|
|
};
|
|
|
|
window.containerCustomizationsManager = containerCustomizationsManager;
|