Model download support multiple selection

This commit is contained in:
cenfun 2024-06-22 17:55:42 +08:00
parent 46963440df
commit 9d6cd0a58d
2 changed files with 123 additions and 35 deletions

View File

@ -256,7 +256,7 @@ const pageCss = `
left: 0;
}
100% {
left: -100px;
left: -105px;
}
}
@ -281,7 +281,7 @@ const pageCss = `
transparent 10px,
transparent 15px
);
animation: cn-btn-loading-bg 3s linear infinite;
animation: cn-btn-loading-bg 2s linear infinite;
}
.cn-manager-light .cn-node-name a {

View File

@ -87,6 +87,13 @@ const pageCss = `
overflow: hidden;
}
.cmm-manager-selection {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
.cmm-manager-message {
}
@ -167,7 +174,7 @@ const pageCss = `
left: 0;
}
100% {
left: -100px;
left: -105px;
}
}
@ -192,7 +199,7 @@ const pageCss = `
transparent 10px,
transparent 15px
);
animation: cmm-btn-loading-bg 3s linear infinite;
animation: cmm-btn-loading-bg 2s linear infinite;
}
.cmm-manager-light .cmm-node-name a {
@ -225,6 +232,7 @@ const pageHtml = `
<div class="cmm-flex-auto"></div>
</div>
<div class="cmm-manager-grid"></div>
<div class="cmm-manager-selection"></div>
<div class="cmm-manager-message"></div>
<div class="cmm-manager-footer">
<button class="cmm-manager-close">Close</button>
@ -347,6 +355,16 @@ export class ModelManager {
focus: (e) => e.target.select()
},
".cmm-manager-selection": {
click: (e) => {
const target = e.target;
const mode = target.getAttribute("mode");
if (mode === "install") {
this.installModels(this.selectedModels, target);
}
}
},
".cmm-manager-close": {
click: (e) => this.close()
},
@ -376,6 +394,10 @@ export class ModelManager {
this.showStatus(`${grid.viewRows.length.toLocaleString()} external models`);
});
grid.bind('onSelectChanged', (e, changes) => {
this.renderSelected();
});
grid.bind('onClick', (e, d) => {
@ -383,7 +405,7 @@ export class ModelManager {
const target = d.e.target;
const mode = target.getAttribute("mode");
if (mode === "install") {
this.installModel(rowItem, target);
this.installModels([rowItem], target);
}
});
@ -391,6 +413,10 @@ export class ModelManager {
grid.setOption({
theme: 'dark',
selectVisible: true,
selectMultiple: true,
selectAllVisible: true,
textSelectable: true,
scrollbarRound: true,
@ -505,14 +531,14 @@ export class ModelManager {
width: 400,
maxWidth: 5000,
classMap: 'cmm-node-desc'
}, {
id: 'filename',
name: 'Filename',
width: 200
}, {
id: "save_path",
name: 'Save Path',
width: 200
}, {
id: 'filename',
name: 'Filename',
width: 200
}];
this.grid.setData({
@ -533,36 +559,88 @@ export class ModelManager {
// ===========================================================================================
async installModel(item, btn) {
this.showLoading();
this.showError("");
this.showStatus(`Install ${item.name} ...`);
btn.classList.add("cmm-btn-loading");
const data = item.originalData;
const res = await fetchData('/model/install', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.error) {
const errorMsg = `Install failed: ${item.name} ${res.error.message}`;
this.showError(errorMsg);
this.hideLoading();
renderSelected() {
const selectedList = this.grid.getSelectedRows();
if (!selectedList.length) {
this.showSelection("");
this.selectedModels = [];
return;
}
item.refresh = true;
this.grid.updateCell(item, "installed");
this.selectedModels = selectedList;
this.showSelection(`<span>Selected <b>${selectedList.length}</b> models <button class="cmm-btn-install" mode="install">Install</button>`);
}
focusInstall(item) {
const cellNode = this.grid.getCellNode(item, "installed");
if (cellNode) {
const cellBtn = cellNode.querySelector(`button[mode="install"]`);
if (cellBtn) {
cellBtn.classList.add("cmm-btn-loading");
return true
}
}
}
async installModels(list, btn) {
btn.classList.add("cmm-btn-loading");
this.showLoading();
this.showError("");
let needRestart = false;
let errorMsg = "";
for (const item of list) {
this.grid.scrollRowIntoView(item);
if (!this.focusInstall(item)) {
this.grid.onNextUpdated(() => {
this.focusInstall(item);
});
}
this.showStatus(`Install ${item.name} ...`);
const data = item.originalData;
const res = await fetchData('/model/install', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (res.error) {
errorMsg = `Install failed: ${item.name} ${res.error.message}`;
break;;
}
needRestart = true;
this.grid.setRowSelected(item, false);
item.refresh = true;
item.selectable = false;
this.grid.updateCell(item, "installed");
this.grid.updateCell(item, "tg-column-select");
this.showStatus(`Install ${item.name} successfully`);
}
this.hideLoading();
btn.classList.remove("cmm-btn-loading");
this.showStatus(`Install ${item.name} successfully`);
this.showMessage(`To apply the installed model, please click the 'Refresh' button on the main menu.`, "red")
if (errorMsg) {
this.showError(errorMsg);
} else {
this.showStatus(`Install ${list.length} models successfully`);
}
if (needRestart) {
this.showMessage(`To apply the installed model, please click the 'Refresh' button on the main menu.`, "red")
}
}
@ -572,11 +650,15 @@ export class ModelManager {
const baseMap = new Map();
models.forEach((item, i) => {
const { type, base, name, reference } = item;
const { type, base, name, reference, installed } = item;
item.originalData = JSON.parse(JSON.stringify(item));
item.hash = md5(name + reference);
item.id = i + 1;
if (installed === "True") {
item.selectable = false;
}
typeMap.set(type, type);
baseMap.set(base, base);
@ -658,6 +740,10 @@ export class ModelManager {
// ===========================================================================================
showSelection(msg) {
this.element.querySelector(".cmm-manager-selection").innerHTML = msg;
}
showError(err) {
this.showMessage(err, "red");
}
@ -701,7 +787,8 @@ export class ModelManager {
const list = [
".cmm-manager-header input",
".cmm-manager-header select",
".cmm-manager-footer button"
".cmm-manager-footer button",
".cmm-manager-selection button"
].map(s => {
return Array.from(this.element.querySelectorAll(s));
})
@ -732,6 +819,7 @@ export class ModelManager {
show() {
this.element.style.display = "flex";
this.setKeywords("");
this.showSelection("");
this.showMessage("");
this.loadData();
}