mirror of
https://github.com/linuxserver/fleet.git
synced 2026-02-20 05:11:08 +08:00
Initial switchable view for image list.
This commit is contained in:
parent
e0c9317225
commit
11798d6464
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.v2.client.docker;
|
||||
|
||||
public abstract class AbstractDockerApiClient implements DockerApiClient {
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.v2.client.docker;
|
||||
|
||||
public interface DockerApiClient {
|
||||
|
||||
<RESPONSE, REQUEST extends DockerApiRequest<RESPONSE>> RESPONSE executeRequest(REQUEST request);
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.v2.client.docker;
|
||||
|
||||
public interface DockerApiRequest<RESPONSE_TYPE> {
|
||||
|
||||
RESPONSE_TYPE performRequest();
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.v2.client.docker.converter;
|
||||
|
||||
public interface DockerResponseConverter<DOCKER_MODEL, INTERNAL_MODEL> {
|
||||
|
||||
INTERNAL_MODEL convert(final DOCKER_MODEL dockerModel);
|
||||
}
|
||||
@ -31,6 +31,8 @@ import java.util.TreeSet;
|
||||
|
||||
public class Image extends AbstractSyncItem<ImageKey, Image> {
|
||||
|
||||
private static final DateTimeFormatter DefaultImageTimeFormat = DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss");
|
||||
|
||||
private final ImageCountData countData;
|
||||
private final String description;
|
||||
private final LocalDateTime lastUpdated;
|
||||
@ -102,7 +104,7 @@ public class Image extends AbstractSyncItem<ImageKey, Image> {
|
||||
public final String getLastUpdatedAsString() {
|
||||
|
||||
final LocalDateTime lastUpdated = parseDateTime(this.lastUpdated);
|
||||
return null == lastUpdated ? null : DateTimeFormatter.ISO_DATE_TIME.format(lastUpdated);
|
||||
return null == lastUpdated ? null : DefaultImageTimeFormat.format(lastUpdated);
|
||||
}
|
||||
|
||||
public final List<TagBranch> getTagBranches() {
|
||||
|
||||
@ -23,8 +23,6 @@ import io.linuxserver.fleet.v2.service.RepositoryManager;
|
||||
import io.linuxserver.fleet.v2.types.Repository;
|
||||
import io.linuxserver.fleet.v2.web.PageModelSpec;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class HomeController extends AbstractPageHandler {
|
||||
|
||||
private final RepositoryManager repositoryManager;
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2019 LinuxServer.io
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.linuxserver.fleet.v2.web.routes;
|
||||
|
||||
import io.javalin.http.Context;
|
||||
import io.linuxserver.fleet.v2.key.ImageLookupKey;
|
||||
import io.linuxserver.fleet.v2.service.RepositoryManager;
|
||||
import io.linuxserver.fleet.v2.web.PageModelSpec;
|
||||
|
||||
public class ImageController extends AbstractPageHandler {
|
||||
|
||||
private final RepositoryManager repositoryManager;
|
||||
|
||||
public ImageController(final RepositoryManager repositoryManager) {
|
||||
this.repositoryManager = repositoryManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PageModelSpec handlePageLoad(final Context ctx) {
|
||||
|
||||
final String imageLookupParam = ctx.queryParam("name");
|
||||
if (null != imageLookupParam) {
|
||||
|
||||
final PageModelSpec modelSpec = new PageModelSpec("views/pages/image.ftl");
|
||||
modelSpec.addModelAttribute("image", repositoryManager.lookupImage(new ImageLookupKey(imageLookupParam)));
|
||||
return modelSpec;
|
||||
|
||||
} else {
|
||||
return new PageModelSpec("views/pages/not-found.ftl");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PageModelSpec handleFormSubmission(final Context ctx) {
|
||||
return new PageModelSpec("views/pages/unsupported.ftl");
|
||||
}
|
||||
}
|
||||
@ -158,4 +158,17 @@ input:checked + .slider:before {
|
||||
|
||||
table tbody th.is-half {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
table tbody tr td.is-vcentered {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#ImageTable tr td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table tr th.tablesorter-header {
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -19,49 +19,36 @@
|
||||
<#import "../ui/components/message.ftl" as message />
|
||||
<#import "../ui/elements/box.ftl" as box />
|
||||
<#import "../prebuilt/base.ftl" as base />
|
||||
<#import "../prebuilt/image-list-item.ftl" as imageListItem />
|
||||
<#import "../ui/elements/table.ftl" as table />
|
||||
<#import "../ui/elements/button.ftl" as button />
|
||||
|
||||
<#import "../prebuilt/image-list-table-item.ftl" as imageListTableItem />
|
||||
<#import "../prebuilt/image-list-item.ftl" as imageListBoxItem />
|
||||
|
||||
<@base.base title="Images" context="home" showTitle=false>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
|
||||
<div class="columns is-multiline is-centered">
|
||||
<div class="column is-8-desktop">
|
||||
<@input.text id="SearchImages" icon="search" placeholder="Search..." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section is-paddingless-top">
|
||||
<div class="container">
|
||||
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<#if availableRepositories?has_content && availableRepositories?size > 0>
|
||||
<@input.dropdown id="RepositorySelection" size="normal" icon="cubes">
|
||||
<#list availableRepositories as repository>
|
||||
<option value="${repository.key}"<#if repository.name==selectedRepository.name> selected</#if>>${repository.name}</option>
|
||||
</#list>
|
||||
</@input.dropdown>
|
||||
<#else>
|
||||
There are currently no available repositories.
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
<#-- <div class="columns">-->
|
||||
<#-- <div class="column is-12 has-text-right">-->
|
||||
<#-- <#if availableRepositories?has_content && availableRepositories?size > 0>-->
|
||||
<#-- <@input.dropdown id="RepositorySelection" size="normal" icon="cubes">-->
|
||||
<#-- <#list availableRepositories as repository>-->
|
||||
<#-- <option value="${repository.key}"<#if repository.name==selectedRepository.name> selected</#if>>${repository.name}</option>-->
|
||||
<#-- </#list>-->
|
||||
<#-- </@input.dropdown>-->
|
||||
<#-- <#else>-->
|
||||
<#-- There are currently no available repositories.-->
|
||||
<#-- </#if>-->
|
||||
<#-- </div>-->
|
||||
<#-- </div>-->
|
||||
|
||||
<#if selectedRepository?has_content>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-12">
|
||||
<h2 class="title is-4 repository-title">
|
||||
<i class="fas fa-cubes"></i> ${selectedRepository.name}<span class="has-text-primary">.</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="column is-12">
|
||||
<div class="column is-12 has-margin-top">
|
||||
<nav class="level">
|
||||
<div class="level-item has-text-centered">
|
||||
<div>
|
||||
@ -83,16 +70,69 @@
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="column is-12 has-margin-top">
|
||||
<h2 class="title is-3 repository-title">
|
||||
<i class="fas fa-cubes"></i> ${selectedRepository.name}<span class="has-text-primary">.</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="column is-12 has-margin-top">
|
||||
<@input.text id="SearchImages" icon="search" placeholder="Search..." />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="columns is-centered is-multiline has-margin-top">
|
||||
<#if selectedRepository.images?has_content>
|
||||
<div class="columns has-margin-top">
|
||||
|
||||
<div class="column is-12">
|
||||
<@button.buttons isGrouped=true isRightAligned=true>
|
||||
<@button.button id="DisplayImageTable" colour="normal-colour" title="Display as table" extraClasses="is-active">
|
||||
<i class="fas fa-table is-marginless"></i>
|
||||
</@button.button>
|
||||
<@button.button id="DisplayImageGrid" colour="normal-colour" title="Display as grid">
|
||||
<i class="fas fa-th-large is-marginless"></i>
|
||||
</@button.button>
|
||||
</@button.buttons>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<#if selectedRepository.images?has_content>
|
||||
|
||||
<div id="ImageTableHolder" class="columns is-multiline">
|
||||
|
||||
<div class="column is-12">
|
||||
<@table.table id="ImageTable" isFullWidth=true isScrollable=true extraClasses="table--sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
<th>Latest Version</th>
|
||||
<th>Build Time</th>
|
||||
<th class="sorter-pullCount">Pulls</th>
|
||||
<th>Stars</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#list selectedRepository.images as image>
|
||||
<@imageListTableItem.imageListItem image=image />
|
||||
</#list>
|
||||
</tbody>
|
||||
</@table.table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="ImageGridHolder" class="columns is-multiline is-hidden">
|
||||
<#list selectedRepository.images as image>
|
||||
<@imageListItem.imageListItem image=image />
|
||||
<@imageListBoxItem.imageListItem image=image />
|
||||
</#list>
|
||||
<#else>
|
||||
</div>
|
||||
|
||||
<#else>
|
||||
<div class="column is-12">
|
||||
No images
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
</#if>
|
||||
|
||||
|
||||
76
src/main/resources/views/pages/image.ftl
Normal file
76
src/main/resources/views/pages/image.ftl
Normal file
@ -0,0 +1,76 @@
|
||||
<#--
|
||||
Copyright (c) 2019 LinuxServer.io
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<#import "../prebuilt/base.ftl" as base />
|
||||
<#import "../ui/layout/section.ftl" as section />
|
||||
<#import "../ui/layout/container.ftl" as container />
|
||||
<#import "../ui/elements/box.ftl" as box />
|
||||
<#import "../ui/elements/table.ftl" as table />
|
||||
<#import "../ui/elements/tag.ftl" as tag />
|
||||
|
||||
<@base.base title="${image.fullName}" context="image">
|
||||
|
||||
<@section.section>
|
||||
<@container.container>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
|
||||
<div class="column is-12">
|
||||
<h2 class="title is-3 repository-title">
|
||||
<i class="fas fa-cube"></i> <span class="has-text-weight-light">${image.repositoryName}/</span>${image.name}<span class="has-text-primary">.</span>
|
||||
<#if image.deprecated>
|
||||
<@tag.tag colour="warning" value="Deprecated" />
|
||||
</#if>
|
||||
</h2>
|
||||
<div class="tags is-right">
|
||||
<@tag.tag colour="light" value='<i class="fas fa-download"></i> ${image.pullCount}' extraAttributes='title="Pulls"' />
|
||||
<@tag.tag colour="light" value='<i class="fas fa-star"></i> ${image.starCount}' extraAttributes='title="Stars"' />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="column is-6-desktop is-12-tablet">
|
||||
<@box.box extraClasses="is-paddingless is-clipped">
|
||||
|
||||
<h2 class="title is-5 has-text-centered has-margin-top">Build Information</h2>
|
||||
<@table.table isFullWidth=true isNarrow=true isStriped=true>
|
||||
<tbody>
|
||||
<@table.halfDisplayRow title="Repository" value='<a href="/?key=${image.repositoryKey}">${image.repositoryName}</a>' />
|
||||
<@table.halfDisplayRow title="Build Time" value=image.lastUpdatedAsString />
|
||||
<@table.halfDisplayRow title="Stable" value=image.stable?string("Yes", "No") />
|
||||
<@table.halfDisplayRow title="Synchronised" value=image.syncEnabled?string("Yes", "No") />
|
||||
</tbody>
|
||||
</@table.table>
|
||||
|
||||
<h2 class="title is-5 has-text-centered has-margin-top">Tracked Tags</h2>
|
||||
<@table.table isFullWidth=true isNarrow=true isStriped=true>
|
||||
<tbody>
|
||||
<#list image.tagBranches as tagBranch>
|
||||
<@table.halfDisplayRow title='<i class="fas fa-tag"></i> ${tagBranch.branchName}' value=(tagBranch.latestTag).version!"" />
|
||||
</#list>
|
||||
</tbody>
|
||||
</@table.table>
|
||||
|
||||
</@box.box>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</@container.container>
|
||||
</@section.section>
|
||||
|
||||
</@base.base>
|
||||
@ -57,6 +57,7 @@
|
||||
<#nested>
|
||||
|
||||
<script type="text/javascript" src="assets/js/jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/jquery.tablesorter.js"></script>
|
||||
<script type="text/javascript" src="assets/js/app.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
@ -67,6 +68,21 @@
|
||||
formValidationManager.init();
|
||||
bulmaManager.init();
|
||||
|
||||
jQuery.tablesorter.addParser({
|
||||
id: "pullCount",
|
||||
is: function(s) {
|
||||
return /^[0-9]?[0-9,.]*$/.test(s);
|
||||
},
|
||||
format: function(s) {
|
||||
return jQuery.tablesorter.formatFloat( s.replace(/,/g,'') );
|
||||
},
|
||||
type: "numeric"
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$("table.table--sortable").tablesorter();
|
||||
});
|
||||
|
||||
}, false);
|
||||
})();
|
||||
|
||||
|
||||
@ -20,40 +20,50 @@
|
||||
<#macro imageListItem image>
|
||||
|
||||
<#if !image.hidden>
|
||||
<div class="column has-margin-top is-12 is-12-tablet is-8-desktop">
|
||||
<article class="media">
|
||||
<figure class="media-left">
|
||||
<p class="icon has-text-centered">
|
||||
<i class="fas fa-cube"></i>
|
||||
</p>
|
||||
</figure>
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
<div class="column is-12-mobile is-6-tablet is-4-desktop" data-image-name="${image.name}">
|
||||
<div class="box">
|
||||
<article class="media">
|
||||
<figure class="media-left">
|
||||
<p class="icon has-text-centered">
|
||||
<i class="fas fa-cube"></i>
|
||||
</p>
|
||||
</figure>
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
|
||||
<h4 class="title is-6">
|
||||
<a class="has-text-grey-dark" href="/image?name=${image.fullName}">
|
||||
<span class="has-text-weight-light">${image.repositoryKey.name}/</span><span class="has-text-weight-500">${image.name}</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4 class="title is-6 is-marginless">
|
||||
<a class="has-text-grey-dark" href="/image?name=${image.fullName}">
|
||||
<span class="has-text-weight-light">${image.repositoryKey.name}/</span><span class="has-text-weight-500">${image.name}</span>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
${image.description!""}
|
||||
<small>
|
||||
<em>
|
||||
${image.lastUpdatedAsString}
|
||||
</em>
|
||||
</small>
|
||||
|
||||
<div class="tags has-margin-top">
|
||||
<#list image.tagBranches as tagBranch>
|
||||
<@tag.tag colour="light" value='<i class="fas fa-tag"></i> ${tagBranch.latestTag.version}' extraAttributes='title="Latest Version"' />
|
||||
</#list>
|
||||
<div class="tags has-margin-top">
|
||||
<#list image.tagBranches as tagBranch>
|
||||
<@tag.tag colour="light" value='<i class="fas fa-tag"></i> ${tagBranch.latestTag.version}' extraAttributes='title="Latest Version"' />
|
||||
</#list>
|
||||
|
||||
<@tag.tag colour="light" value='<i class="fas fa-download"></i> ${image.pullCount}' extraAttributes='title="Pulls"' />
|
||||
<@tag.tag colour="light" value='<i class="fas fa-star"></i> ${image.starCount}' />
|
||||
<@tag.tag colour="light" value='<i class="fas fa-download"></i> ${image.pullCount}' extraAttributes='title="Pulls"' />
|
||||
<@tag.tag colour="light" value='<i class="fas fa-star"></i> ${image.starCount}' />
|
||||
|
||||
<#if image.deprecated>
|
||||
<@tag.tag colour="warning" value='<i class="fas fa-exclamation-circle"></i> Deprecated' />
|
||||
</#if>
|
||||
|
||||
<#if !image.stable>
|
||||
<@tag.tag colour="danger" value='<i class="fas fa-exclamation-triangle"></i> Unstable!' />
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<#if image.deprecated>
|
||||
<@tag.tag colour="warning" value='<i class="fas fa-exclamation-circle"></i> Deprecated' />
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
|
||||
55
src/main/resources/views/prebuilt/image-list-table-item.ftl
Normal file
55
src/main/resources/views/prebuilt/image-list-table-item.ftl
Normal file
@ -0,0 +1,55 @@
|
||||
<#--
|
||||
Copyright (c) 2019 LinuxServer.io
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<#import "../ui/elements/tag.ftl" as tag />
|
||||
|
||||
<#macro imageListItem image>
|
||||
|
||||
<#if !image.hidden>
|
||||
|
||||
<tr data-image-name="${image.name}">
|
||||
<td class="is-vcentered">
|
||||
<h4 class="title is-6">
|
||||
<a class="has-text-grey-dark" href="/image?name=${image.fullName}">
|
||||
<span class="has-text-weight-light">${image.repositoryKey.name}/</span><span class="has-text-weight-500">${image.name}</span>
|
||||
</a>
|
||||
</h4>
|
||||
</td>
|
||||
<td>
|
||||
<#if image.deprecated>
|
||||
<@tag.tag colour="warning" value='<i class="fas fa-exclamation-circle"></i> Deprecated' />
|
||||
</#if>
|
||||
<#if !image.stable>
|
||||
<@tag.tag colour="danger" value='<i class="fas fa-exclamation-triangle"></i> Unstable!' />
|
||||
</#if>
|
||||
</td>
|
||||
<td class="is-vcentered">
|
||||
<@tag.tag colour="light" value='<i class="fas fa-tag"></i> ${image.latestTag.version}' extraAttributes='title="Latest Version"' />
|
||||
</td>
|
||||
<td class="is-vcentered">
|
||||
${image.lastUpdatedAsString!""}
|
||||
</td>
|
||||
<td class="is-vcentered">
|
||||
${image.pullCount}
|
||||
</td>
|
||||
<td class="is-vcentered">
|
||||
${image.starCount}
|
||||
</td>
|
||||
</tr>
|
||||
</#if>
|
||||
|
||||
</#macro>
|
||||
@ -1,54 +1,54 @@
|
||||
<#--
|
||||
Resource: https://bulma.io/documentation/elements/button/
|
||||
|
||||
The classic button, in different colors, sizes, and states
|
||||
|
||||
id:String - The unique identifier for this element
|
||||
type:enum(button, submit) - Sets the type of button. If "submit", it will interact with its parent form.
|
||||
title:String - A description of the button to give further context.
|
||||
extraClasses:String - Any additional classes that this element should have
|
||||
extraAttributes:String - Any additional attributes that this element should have (e.g. disabled, data-*)
|
||||
colour:enum(primary, warning, info, danger, success, light, dark) - Sets the main colour of the button. Default: primary
|
||||
size:enum(small, normal, medium, large) - Sets the size of the button.
|
||||
isWide:boolean - If set to true, will fill available horizontal space.
|
||||
isOutlined:boolean - If set to true, will set colour on button outline rather than background.
|
||||
isInverted:boolean - If set to true, will set the text colour rather than background.
|
||||
isRounded:boolean - If set to true, will fully round the edges of the button.
|
||||
-->
|
||||
<#macro button id="" type="button" title="" extraClasses="" extraAttributes="" colour="primary" size="normal" modal="" isDisabled=false isWide=false isOutlined=false isInverted=false isRounded=false>
|
||||
|
||||
<button type="${type}"<#if id?has_content> id="${id}"</#if><#if title?has_content> title="${title}"</#if> class="button is-${size} is-${colour}<#if isWide> is-fullwidth</#if><#if isOutlined> is-outlined</#if><#if isInverted> is-inverted</#if><#if isRounded> is-rounded</#if><#if extraClasses?has_content> ${extraClasses}</#if><#if modal?has_content> is-modal-trigger</#if>"<#if modal?has_content> data-modal="${modal}"</#if><#if extraAttributes?has_content> ${extraAttributes}</#if><#if isDisabled> disabled</#if>>
|
||||
<#nested />
|
||||
</button>
|
||||
|
||||
</#macro>
|
||||
|
||||
<#--
|
||||
A convenience macro to generate a submit button.
|
||||
-->
|
||||
<#macro submit id="" extraClasses="" title="" extraAttributes="" colour="primary" size="normal" isWide=false isOutlined=false isInverted=false isRounded=false>
|
||||
|
||||
<@button id=id type="submit" title=title extraClasses=extraClasses extraAttributes=extraAttributes colour=colour size=size isWide=isWide isOutlined=isOutlined isInverted=isInverted isRounded=isRounded>
|
||||
<#nested />
|
||||
</@button>
|
||||
|
||||
</#macro>
|
||||
|
||||
<#--
|
||||
Generates an anchor link with the same styling as a button.
|
||||
-->
|
||||
<#macro link id="" link="" title="" extraClasses="" extraAttributes="" colour="primary" size="normal" modal="" isWide=false isOutlined=false isInverted=false isRounded=false>
|
||||
|
||||
<a<#if link?has_content> href="${link}"</#if><#if title?has_content> title="${title}"</#if> class="button is-${size} is-${colour}<#if isWide> is-fullwidth</#if><#if isOutlined> is-outlined</#if><#if isInverted> is-inverted</#if><#if isRounded> is-rounded</#if><#if extraClasses?has_content> ${extraClasses}</#if><#if modal?has_content> is-modal-trigger</#if>"<#if modal?has_content> data-modal="${modal}"</#if><#if extraAttributes?has_content> ${extraAttributes}</#if>>
|
||||
<#nested />
|
||||
</a>
|
||||
|
||||
</#macro>
|
||||
|
||||
<#macro buttons isGrouped=false size="normal">
|
||||
|
||||
<div class="buttons<#if isGrouped> has-addons</#if> are-${size}">
|
||||
<#nested />
|
||||
</div>
|
||||
|
||||
<#--
|
||||
Resource: https://bulma.io/documentation/elements/button/
|
||||
|
||||
The classic button, in different colors, sizes, and states
|
||||
|
||||
id:String - The unique identifier for this element
|
||||
type:enum(button, submit) - Sets the type of button. If "submit", it will interact with its parent form.
|
||||
title:String - A description of the button to give further context.
|
||||
extraClasses:String - Any additional classes that this element should have
|
||||
extraAttributes:String - Any additional attributes that this element should have (e.g. disabled, data-*)
|
||||
colour:enum(primary, warning, info, danger, success, light, dark) - Sets the main colour of the button. Default: primary
|
||||
size:enum(small, normal, medium, large) - Sets the size of the button.
|
||||
isWide:boolean - If set to true, will fill available horizontal space.
|
||||
isOutlined:boolean - If set to true, will set colour on button outline rather than background.
|
||||
isInverted:boolean - If set to true, will set the text colour rather than background.
|
||||
isRounded:boolean - If set to true, will fully round the edges of the button.
|
||||
-->
|
||||
<#macro button id="" type="button" title="" extraClasses="" extraAttributes="" colour="primary" size="normal" modal="" isDisabled=false isWide=false isOutlined=false isInverted=false isRounded=false>
|
||||
|
||||
<button type="${type}"<#if id?has_content> id="${id}"</#if><#if title?has_content> title="${title}"</#if> class="button is-${size} is-${colour}<#if isWide> is-fullwidth</#if><#if isOutlined> is-outlined</#if><#if isInverted> is-inverted</#if><#if isRounded> is-rounded</#if><#if extraClasses?has_content> ${extraClasses}</#if><#if modal?has_content> is-modal-trigger</#if>"<#if modal?has_content> data-modal="${modal}"</#if><#if extraAttributes?has_content> ${extraAttributes}</#if><#if isDisabled> disabled</#if>>
|
||||
<#nested />
|
||||
</button>
|
||||
|
||||
</#macro>
|
||||
|
||||
<#--
|
||||
A convenience macro to generate a submit button.
|
||||
-->
|
||||
<#macro submit id="" extraClasses="" title="" extraAttributes="" colour="primary" size="normal" isWide=false isOutlined=false isInverted=false isRounded=false>
|
||||
|
||||
<@button id=id type="submit" title=title extraClasses=extraClasses extraAttributes=extraAttributes colour=colour size=size isWide=isWide isOutlined=isOutlined isInverted=isInverted isRounded=isRounded>
|
||||
<#nested />
|
||||
</@button>
|
||||
|
||||
</#macro>
|
||||
|
||||
<#--
|
||||
Generates an anchor link with the same styling as a button.
|
||||
-->
|
||||
<#macro link id="" link="" title="" extraClasses="" extraAttributes="" colour="primary" size="normal" modal="" isWide=false isOutlined=false isInverted=false isRounded=false>
|
||||
|
||||
<a<#if link?has_content> href="${link}"</#if><#if title?has_content> title="${title}"</#if> class="button is-${size} is-${colour}<#if isWide> is-fullwidth</#if><#if isOutlined> is-outlined</#if><#if isInverted> is-inverted</#if><#if isRounded> is-rounded</#if><#if extraClasses?has_content> ${extraClasses}</#if><#if modal?has_content> is-modal-trigger</#if>"<#if modal?has_content> data-modal="${modal}"</#if><#if extraAttributes?has_content> ${extraAttributes}</#if>>
|
||||
<#nested />
|
||||
</a>
|
||||
|
||||
</#macro>
|
||||
|
||||
<#macro buttons isGrouped=false size="normal" isRightAligned=false>
|
||||
|
||||
<div class="buttons<#if isGrouped> has-addons</#if><#if isRightAligned> is-right</#if> are-${size}">
|
||||
<#nested />
|
||||
</div>
|
||||
|
||||
</#macro>
|
||||
Loading…
x
Reference in New Issue
Block a user