diff --git a/src/main/java/io/linuxserver/fleet/v2/client/docker/AbstractDockerApiClient.java b/src/main/java/io/linuxserver/fleet/v2/client/docker/AbstractDockerApiClient.java
new file mode 100644
index 0000000..5c73f42
--- /dev/null
+++ b/src/main/java/io/linuxserver/fleet/v2/client/docker/AbstractDockerApiClient.java
@@ -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 .
+ */
+
+package io.linuxserver.fleet.v2.client.docker;
+
+public abstract class AbstractDockerApiClient implements DockerApiClient {
+
+
+}
diff --git a/src/main/java/io/linuxserver/fleet/v2/client/docker/DockerApiClient.java b/src/main/java/io/linuxserver/fleet/v2/client/docker/DockerApiClient.java
new file mode 100644
index 0000000..2e3d6a3
--- /dev/null
+++ b/src/main/java/io/linuxserver/fleet/v2/client/docker/DockerApiClient.java
@@ -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 .
+ */
+
+package io.linuxserver.fleet.v2.client.docker;
+
+public interface DockerApiClient {
+
+ > RESPONSE executeRequest(REQUEST request);
+}
diff --git a/src/main/java/io/linuxserver/fleet/v2/client/docker/DockerApiRequest.java b/src/main/java/io/linuxserver/fleet/v2/client/docker/DockerApiRequest.java
new file mode 100644
index 0000000..dab9c85
--- /dev/null
+++ b/src/main/java/io/linuxserver/fleet/v2/client/docker/DockerApiRequest.java
@@ -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 .
+ */
+
+package io.linuxserver.fleet.v2.client.docker;
+
+public interface DockerApiRequest {
+
+ RESPONSE_TYPE performRequest();
+}
diff --git a/src/main/java/io/linuxserver/fleet/v2/client/docker/converter/DockerResponseConverter.java b/src/main/java/io/linuxserver/fleet/v2/client/docker/converter/DockerResponseConverter.java
new file mode 100644
index 0000000..a6df17f
--- /dev/null
+++ b/src/main/java/io/linuxserver/fleet/v2/client/docker/converter/DockerResponseConverter.java
@@ -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 .
+ */
+
+package io.linuxserver.fleet.v2.client.docker.converter;
+
+public interface DockerResponseConverter {
+
+ INTERNAL_MODEL convert(final DOCKER_MODEL dockerModel);
+}
diff --git a/src/main/java/io/linuxserver/fleet/v2/types/Image.java b/src/main/java/io/linuxserver/fleet/v2/types/Image.java
index 598a3f4..28435e2 100644
--- a/src/main/java/io/linuxserver/fleet/v2/types/Image.java
+++ b/src/main/java/io/linuxserver/fleet/v2/types/Image.java
@@ -31,6 +31,8 @@ import java.util.TreeSet;
public class Image extends AbstractSyncItem {
+ 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 {
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 getTagBranches() {
diff --git a/src/main/java/io/linuxserver/fleet/v2/web/routes/HomeController.java b/src/main/java/io/linuxserver/fleet/v2/web/routes/HomeController.java
index 1e8c871..cc34329 100644
--- a/src/main/java/io/linuxserver/fleet/v2/web/routes/HomeController.java
+++ b/src/main/java/io/linuxserver/fleet/v2/web/routes/HomeController.java
@@ -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;
diff --git a/src/main/java/io/linuxserver/fleet/v2/web/routes/ImageController.java b/src/main/java/io/linuxserver/fleet/v2/web/routes/ImageController.java
new file mode 100644
index 0000000..f4436c7
--- /dev/null
+++ b/src/main/java/io/linuxserver/fleet/v2/web/routes/ImageController.java
@@ -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 .
+ */
+
+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");
+ }
+}
diff --git a/src/main/resources/static/assets/css/app.css b/src/main/resources/static/assets/css/app.css
index 1bdb5aa..39376ea 100644
--- a/src/main/resources/static/assets/css/app.css
+++ b/src/main/resources/static/assets/css/app.css
@@ -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;
}
\ No newline at end of file
diff --git a/src/main/resources/views/pages/home.ftl b/src/main/resources/views/pages/home.ftl
index 0c18b9e..28fce3e 100644
--- a/src/main/resources/views/pages/home.ftl
+++ b/src/main/resources/views/pages/home.ftl
@@ -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>
-
-
+ #if>
#if>
diff --git a/src/main/resources/views/pages/image.ftl b/src/main/resources/views/pages/image.ftl
new file mode 100644
index 0000000..8cae3ed
--- /dev/null
+++ b/src/main/resources/views/pages/image.ftl
@@ -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 .
+-->
+
+<#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>
+
+