dooke/usr/lib/dooke/webapp/views/home.js

194 lines
4.2 KiB
JavaScript

/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/08/08 18:19:17
*/
import { html, css, Component, classMap, nextTick, outsideClick } from 'wkit'
import { noop, getContainers } from '../utils/index.js'
class Home extends Component {
static props = {
containers: []
}
static styles = [
css`
:host {
display: block;
width: 100%;
height: 100%;
color: var(--color-dark-1);
background: #fff;
}
.visible {
display: block;
}
ul li {
list-style: none;
}
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
`,
css`
.main {
display: flex;
flex-direction: column;
height: 100%;
padding: 16px;
}
.main .toolbar {
height: 48px;
border-bottom: 1px solid var(--color-plain-3);
}
.main .list {
overflow: hidden;
flex: 1;
display: flex;
flex-direction: column;
gap: 3px;
width: 100%;
padding: 12px 0;
}
.item {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
height: 48px;
padding: 0 12px;
line-height: 1.25;
border-radius: 24px;
--wc-icon-size: 16px;
&:hover {
background: var(--color-plain-1);
}
.field {
overflow: hidden;
flex: 1;
&.flex-2 {
flex: 2;
}
&.name {
display: flex;
flex-direction: column;
}
&.center {
text-align: center;
}
.text-ell {
overflow: hidden;
display: block;
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
color: var(--color-teal-1);
}
}
}
`
]
#input = ''
#all = true
mounted() {
this.#all = +localStorage.getItem('container_mode') === 1
console.log('<><><>', this.#all)
this.#fetch()
}
async #fetch() {
let list = await getContainers(this.#all)
list.forEach(it => {
it.port = it.port.replace('0.0.0.0:', '').replace(':::', '')
})
this.containers = list
}
async #filter(ev) {
let val = ev.currentTarget.value
if (ev.type === 'input') {
let txt = val.trim()
if (this.#input === txt) {
return
}
this.#input = txt
} else {
this.#all = val
localStorage.setItem('container_mode', val ^ 0)
await this.#fetch()
}
this.$requestUpdate()
}
render() {
let list = this.containers
let txt = this.#input
if (txt) {
list = list.filter(it => it.name.includes(txt))
}
return html`
<main class="main noselect">
<wc-space class="toolbar">
<wc-input
size="small"
round
placeholder="搜索容器"
@input=${this.#filter}
></wc-input>
<wc-switch :value=${this.#all} @change=${this.#filter}
>显示非运行中的容器</wc-switch
>
</wc-space>
<ul class="list">
${list.map(
it => html`
<li class="item">
<section class="field flex-2 name">
<wc-tooltip title=${it.name}>
<span class="text-ell">${it.name}</span>
</wc-tooltip>
<code>${it.id}</code>
</section>
<section class="field flex-2">
<wc-tooltip title=${it.image}>
<span class="text-ell">${it.image}</span>
</wc-tooltip>
</section>
<section class="field center">${it.state}</section>
<section class="field">
<wc-tooltip title=${it.port}>
<span class="text-ell">${it.port}</span>
</wc-tooltip>
</section>
<section class="field center">
<wc-icon name="trash"></wc-icon>
</section>
</li>
`
)}
</ul>
</main>
`
}
}
Home.reg('containers')
docker 管理面板。
JavaScript 72%
Python 17.4%
CSS 7%
HTML 1.9%
Shell 1.7%