mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-05-30 22:55:40 +02:00
Merge pull request #1116 from ogmaresca/createTab-utility-function
Add a utility function to create tabs with lazy loading functionality
This commit is contained in:
commit
382dee1fd1
@ -720,9 +720,140 @@ Array.prototype.addEventListener = function(method, callback) {
|
|||||||
const originalFunction = this[method]
|
const originalFunction = this[method]
|
||||||
if (originalFunction) {
|
if (originalFunction) {
|
||||||
this[method] = function() {
|
this[method] = function() {
|
||||||
console.log(`Array.${method}()`, arguments)
|
|
||||||
originalFunction.apply(this, arguments)
|
originalFunction.apply(this, arguments)
|
||||||
callback.apply(this, arguments)
|
callback.apply(this, arguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} TabOpenDetails
|
||||||
|
* @property {HTMLElement} contentElement
|
||||||
|
* @property {HTMLElement} labelElement
|
||||||
|
* @property {number} timesOpened
|
||||||
|
* @property {boolean} firstOpen
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} CreateTabRequest
|
||||||
|
* @property {string} id
|
||||||
|
* @property {string | Node | (() => (string | Node))} label
|
||||||
|
* Label text or an HTML element
|
||||||
|
* @property {string} icon
|
||||||
|
* @property {string | Node | Promise<string | Node> | (() => (string | Node | Promise<string | Node>)) | undefined} content
|
||||||
|
* HTML string or HTML element
|
||||||
|
* @property {((TabOpenDetails, Event) => (undefined | string | Node | Promise<string | Node>)) | undefined} onOpen
|
||||||
|
* If an HTML string or HTML element is returned, then that will replace the tab content
|
||||||
|
* @property {string | undefined} css
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {CreateTabRequest} request
|
||||||
|
*/
|
||||||
|
function createTab(request) {
|
||||||
|
if (!request?.id) {
|
||||||
|
console.error('createTab() error - id is required', Error().stack)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request.label) {
|
||||||
|
console.error('createTab() error - label is required', Error().stack)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request.icon) {
|
||||||
|
console.error('createTab() error - icon is required', Error().stack)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request.content && !request.onOpen) {
|
||||||
|
console.error('createTab() error - content or onOpen required', Error().stack)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabsContainer = document.querySelector('.tab-container')
|
||||||
|
if (!tabsContainer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabsContentWrapper = document.querySelector('#tab-content-wrapper')
|
||||||
|
if (!tabsContentWrapper) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug('creating tab: ', request)
|
||||||
|
|
||||||
|
if (request.css) {
|
||||||
|
document.querySelector('body').insertAdjacentElement(
|
||||||
|
'beforeend',
|
||||||
|
createElement('style', { id: `tab-${request.id}-css` }, undefined, request.css),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = typeof request.label === 'function' ? request.label() : request.label
|
||||||
|
const labelElement = label instanceof Node ? label : createElement('span', undefined, undefined, label)
|
||||||
|
|
||||||
|
const tab = createElement(
|
||||||
|
'span',
|
||||||
|
{ id: `tab-${request.id}`, 'data-times-opened': 0 },
|
||||||
|
['tab'],
|
||||||
|
createElement(
|
||||||
|
'span',
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
createElement(
|
||||||
|
'i',
|
||||||
|
{ style: 'margin-right: 0.25em' },
|
||||||
|
['fa-solid', `${request.icon.startsWith('fa-') ? '' : 'fa-'}${request.icon}`, 'icon'],
|
||||||
|
),
|
||||||
|
labelElement,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
tabsContainer.insertAdjacentElement('beforeend', tab)
|
||||||
|
|
||||||
|
const wrapper = createElement('div', { id: request.id }, ['tab-content-inner'], 'Loading..')
|
||||||
|
|
||||||
|
const tabContent = createElement('div', { id: `tab-content-${request.id}` }, ['tab-content'], wrapper)
|
||||||
|
tabsContentWrapper.insertAdjacentElement('beforeend', tabContent)
|
||||||
|
|
||||||
|
linkTabContents(tab)
|
||||||
|
|
||||||
|
function replaceContent(resultFactory) {
|
||||||
|
if (resultFactory === undefined || resultFactory === null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const result = typeof resultFactory === 'function' ? resultFactory() : resultFactory
|
||||||
|
if (result instanceof Promise) {
|
||||||
|
result.then(replaceContent)
|
||||||
|
} else if (result instanceof Node) {
|
||||||
|
wrapper.replaceChildren(result)
|
||||||
|
} else {
|
||||||
|
wrapper.innerHTML = result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceContent(request.content)
|
||||||
|
|
||||||
|
tab.addEventListener('click', (e) => {
|
||||||
|
const timesOpened = +(tab.dataset.timesOpened || 0) + 1
|
||||||
|
tab.dataset.timesOpened = timesOpened
|
||||||
|
|
||||||
|
if (request.onOpen) {
|
||||||
|
const result = request.onOpen(
|
||||||
|
{
|
||||||
|
contentElement: wrapper,
|
||||||
|
labelElement,
|
||||||
|
timesOpened,
|
||||||
|
firstOpen: timesOpened === 1,
|
||||||
|
},
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
|
||||||
|
replaceContent(result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -130,34 +130,11 @@
|
|||||||
}
|
}
|
||||||
drawDiagram(fn)
|
drawDiagram(fn)
|
||||||
}
|
}
|
||||||
|
createTab({
|
||||||
/////////////////////// Tab implementation
|
id: 'merge',
|
||||||
document.querySelector('.tab-container')?.insertAdjacentHTML('beforeend', `
|
icon: 'fa-code-merge',
|
||||||
<span id="tab-merge" class="tab">
|
label: 'Merge models',
|
||||||
<span><i class="fa fa-code-merge icon"></i> Merge models</span>
|
css: `
|
||||||
</span>
|
|
||||||
`)
|
|
||||||
|
|
||||||
document.querySelector('#tab-content-wrapper')?.insertAdjacentHTML('beforeend', `
|
|
||||||
<div id="tab-content-merge" class="tab-content">
|
|
||||||
<div id="merge" class="tab-content-inner">
|
|
||||||
Loading..
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`)
|
|
||||||
|
|
||||||
const tabMerge = document.querySelector('#tab-merge')
|
|
||||||
if (tabMerge) {
|
|
||||||
linkTabContents(tabMerge)
|
|
||||||
}
|
|
||||||
const merge = document.querySelector('#merge')
|
|
||||||
if (!merge) {
|
|
||||||
// merge tab not found, dont exec plugin code.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelector('body').insertAdjacentHTML('beforeend', `
|
|
||||||
<style>
|
|
||||||
#tab-content-merge .tab-content-inner {
|
#tab-content-merge .tab-content-inner {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
padding: 10pt;
|
padding: 10pt;
|
||||||
@ -233,11 +210,8 @@
|
|||||||
}
|
}
|
||||||
.merge-container #merge-warning {
|
.merge-container #merge-warning {
|
||||||
color: rgb(153, 153, 153);
|
color: rgb(153, 153, 153);
|
||||||
}
|
}`,
|
||||||
</style>
|
content: `
|
||||||
`)
|
|
||||||
|
|
||||||
merge.innerHTML = `
|
|
||||||
<div class="merge-container panel-box">
|
<div class="merge-container panel-box">
|
||||||
<div class="merge-input">
|
<div class="merge-input">
|
||||||
<p><label for="#mergeModelA">Select Model A:</label></p>
|
<p><label for="#mergeModelA">Select Model A:</label></p>
|
||||||
@ -327,7 +301,11 @@
|
|||||||
<div class="merge-buttons">
|
<div class="merge-buttons">
|
||||||
<button id="merge-button" class="primaryButton">Merge models</button>
|
<button id="merge-button" class="primaryButton">Merge models</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`,
|
||||||
|
onOpen: ({ firstOpen }) => {
|
||||||
|
if (!firstOpen) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const tabSettingsSingle = document.querySelector('#tab-merge-opts-single')
|
const tabSettingsSingle = document.querySelector('#tab-merge-opts-single')
|
||||||
const tabSettingsBatch = document.querySelector('#tab-merge-opts-batch')
|
const tabSettingsBatch = document.querySelector('#tab-merge-opts-batch')
|
||||||
@ -454,5 +432,7 @@
|
|||||||
hypernetworkModelField.innerHTML = ''
|
hypernetworkModelField.innerHTML = ''
|
||||||
await getModels()
|
await getModels()
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
})()
|
})()
|
||||||
|
@ -9,41 +9,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('.tab-container')?.insertAdjacentHTML('beforeend', `
|
createTab({
|
||||||
<span id="tab-news" class="tab">
|
id: 'news',
|
||||||
<span><i class="fa fa-bolt icon"></i> What's new?</span>
|
icon: 'fa-bolt',
|
||||||
</span>
|
label: "What's new",
|
||||||
`)
|
css: `
|
||||||
|
|
||||||
document.querySelector('#tab-content-wrapper')?.insertAdjacentHTML('beforeend', `
|
|
||||||
<div id="tab-content-news" class="tab-content">
|
|
||||||
<div id="news" class="tab-content-inner">
|
|
||||||
Loading..
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`)
|
|
||||||
|
|
||||||
const tabNews = document.querySelector('#tab-news')
|
|
||||||
if (tabNews) {
|
|
||||||
linkTabContents(tabNews)
|
|
||||||
}
|
|
||||||
const news = document.querySelector('#news')
|
|
||||||
if (!news) {
|
|
||||||
// news tab not found, dont exec plugin code.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelector('body').insertAdjacentHTML('beforeend', `
|
|
||||||
<style>
|
|
||||||
#tab-content-news .tab-content-inner {
|
#tab-content-news .tab-content-inner {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 10pt;
|
padding: 10pt;
|
||||||
}
|
}
|
||||||
</style>
|
`,
|
||||||
`)
|
onOpen: async ({ firstOpen }) => {
|
||||||
|
if (firstOpen) {
|
||||||
|
const loadMarkedScriptPromise = loadScript('/media/js/marked.min.js')
|
||||||
|
|
||||||
loadScript('/media/js/marked.min.js').then(async function() {
|
|
||||||
let appConfig = await fetch('/get/app_config')
|
let appConfig = await fetch('/get/app_config')
|
||||||
if (!appConfig.ok) {
|
if (!appConfig.ok) {
|
||||||
console.error('[release-notes] Failed to get app_config.')
|
console.error('[release-notes] Failed to get app_config.')
|
||||||
@ -59,6 +39,11 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
releaseNotes = await releaseNotes.text()
|
releaseNotes = await releaseNotes.text()
|
||||||
news.innerHTML = marked.parse(releaseNotes)
|
|
||||||
|
await loadMarkedScriptPromise
|
||||||
|
|
||||||
|
return marked.parse(releaseNotes)
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
})()
|
})()
|
Loading…
x
Reference in New Issue
Block a user