feat: Add basic import screen (#1056)

Co-authored-by: Chris Hunt <chris.hunt@kasmweb.com>
This commit is contained in:
Attila Kerekes
2022-12-04 21:12:54 +00:00
committed by GitHub
parent 45cc84c99c
commit 8f9b2959b2
10 changed files with 128 additions and 48 deletions

View File

@@ -3,33 +3,27 @@ const APP_LOAD_URL = "appload";
/**
*
* @param {string|null} appId
* @returns {Promise<{}>|Promise<any>}
* @param {object} item
* @param {array} errors
*/
const fetchAppDetails = (appId) => {
if (appId === null) {
return Promise.resolve({});
const updateStatus = ({ item, errors }) => {
console.log(item, errors);
let statusLine;
if (errors.length === 0) {
statusLine = `<li class="success"><i class="fas fa-circle-check"></i> Imported: ${item.title} </li>`;
} else {
statusLine = `<li class="fail"><i class="fas fa-circle-xmark"></i> Failed: ${item.title} - ${errors[0]} </li>`;
}
return fetch(APP_LOAD_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ app: appId }),
})
.then((response) => response.json())
.catch(() => ({}));
document.querySelector(".import-status").innerHTML += statusLine;
};
/**
*
* @returns {string}
*/
const getCSRFToken = () => {
const tokenSelector = 'input[name="_token"]';
return document.querySelector(tokenSelector).value;
};
function clearStatus() {
const statusContainer = document.querySelector(".import-status");
statusContainer.innerHTML = "";
}
/**
*
@@ -48,11 +42,20 @@ const postToApi = (data, csrfToken) =>
body: JSON.stringify(data),
});
/**
*
* @returns {string}
*/
const getCSRFToken = () => {
const tokenSelector = 'input[name="_token"]';
return document.querySelector(tokenSelector).value;
};
/**
*
* @param {object} item
* @param {object} appDetails
* @returns {undefined}
* @returns {object}
*/
const mergeItemWithAppDetails = (item, appDetails) => ({
pinned: 1,
@@ -72,21 +75,51 @@ const mergeItemWithAppDetails = (item, appDetails) => ({
config: item.description ? JSON.parse(item.description) : null,
});
/**
*
* @param {string|null} appId
* @returns {Promise<{}>|Promise<any>}
*/
const fetchAppDetails = (appId) => {
if (appId === null || appId === "null") {
return Promise.resolve({});
}
return fetch(APP_LOAD_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ app: appId }),
}).then((response) => response.json());
};
/**
*
* @param {array} items
*/
const importItems = (items) => {
items.forEach((item) => {
const errors = [];
fetchAppDetails(item.appid)
.catch(() =>
errors.push(new Error(`Failed to find app id: ${item.appid}`))
)
.then((appDetails) => {
const itemWithAppDetails = mergeItemWithAppDetails(item, appDetails);
const csrfToken = getCSRFToken();
return postToApi(itemWithAppDetails, csrfToken);
})
.then((response) => {
console.log(response);
.catch(() =>
errors.push(new Error(`Failed to create item: ${item.title}`))
)
.finally(() => {
updateStatus({
item,
errors,
});
});
});
};
@@ -97,32 +130,47 @@ const importItems = (items) => {
* @returns {Promise<unknown>}
*/
const readJSON = (file) =>
new Promise((resolve) => {
const reader = new FileReader();
new Promise((resolve, reject) => {
try {
const reader = new FileReader();
reader.onload = (e) => {
const contents = e.target.result;
resolve(JSON.parse(contents));
};
reader.onload = (event) => {
const contents = event.target.result;
resolve(JSON.parse(contents));
};
reader.readAsText(file);
reader.readAsText(file);
} catch (e) {
reject(new Error("Unable to read file"));
}
});
/**
*
* @param {Event} event
*/
const openFileForImport = (event) => {
const file = event.target.files[0];
if (!file) {
return;
}
const openFileForImport = (file) => {
clearStatus();
readJSON(file).then(importItems);
return readJSON(file)
.catch((error) => {
console.error(error);
})
.then(importItems);
};
const fileInput = document.querySelector("input[name='import']");
const importButton = document.querySelectorAll(".import-button");
if (fileInput) {
if (fileInput && importButton) {
importButton.forEach((importButton) => {
importButton.addEventListener("click", () => {
const file = fileInput.files[0];
if (!file) {
return;
}
openFileForImport(file);
});
});
fileInput.addEventListener("change", openFileForImport, false);
}