diff --git a/app/pages/project/images/ImagesPage.tsx b/app/pages/project/images/ImagesPage.tsx
index b670a7dc1b..aaebf195f5 100644
--- a/app/pages/project/images/ImagesPage.tsx
+++ b/app/pages/project/images/ImagesPage.tsx
@@ -1,5 +1,16 @@
import React from 'react'
+import { useParams } from 'app/hooks'
+import { SizeCell, DateCell, useQueryTable } from '@oxide/table'
export const ImagesPage = () => {
- return
Not implemented
+ const projectParams = useParams('orgName', 'projectName')
+ const { Table, Column } = useQueryTable('projectImagesGet', projectParams)
+ return (
+
+ )
}
diff --git a/app/pages/project/snapshots/SnapshotsPage.tsx b/app/pages/project/snapshots/SnapshotsPage.tsx
index d4f774ad5b..1200ca4b95 100644
--- a/app/pages/project/snapshots/SnapshotsPage.tsx
+++ b/app/pages/project/snapshots/SnapshotsPage.tsx
@@ -1,5 +1,16 @@
import React from 'react'
+import { useParams } from 'app/hooks'
+import { SizeCell, DateCell, useQueryTable } from '@oxide/table'
export const SnapshotsPage = () => {
- return Not implemented
+ const projectParams = useParams('orgName', 'projectName')
+ const { Table, Column } = useQueryTable('projectSnapshotsGet', projectParams)
+ return (
+
+ )
}
diff --git a/libs/api-mocks/image.ts b/libs/api-mocks/image.ts
new file mode 100644
index 0000000000..65b9d051b5
--- /dev/null
+++ b/libs/api-mocks/image.ts
@@ -0,0 +1,42 @@
+import type { Image } from '@oxide/api'
+import type { Json } from './json-type'
+import { project } from './project'
+
+export const images: Json[] = [
+ {
+ id: 'image-id-1',
+ name: 'image-1',
+ description: "it's an image",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 1024,
+ },
+ {
+ id: 'image-id-2',
+ name: 'image-2',
+ description: "it's a second image",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 2048,
+ },
+ {
+ id: 'image-id-3',
+ name: 'image-3',
+ description: "it's a third image",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 3072,
+ },
+ {
+ id: 'image-id-4',
+ name: 'image-4',
+ description: "it's a fourth image",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 4096,
+ },
+]
diff --git a/libs/api-mocks/index.ts b/libs/api-mocks/index.ts
index 52b0ba2c25..7947daee3b 100644
--- a/libs/api-mocks/index.ts
+++ b/libs/api-mocks/index.ts
@@ -1,8 +1,10 @@
export * from './disk'
+export * from './image'
export * from './instance'
export * from './org'
export * from './project'
export * from './session'
+export * from './snapshot'
export * from './vpc'
export { handlers, json } from './msw/handlers'
diff --git a/libs/api-mocks/msw/db.ts b/libs/api-mocks/msw/db.ts
index fba12845ab..9a38ab02a4 100644
--- a/libs/api-mocks/msw/db.ts
+++ b/libs/api-mocks/msw/db.ts
@@ -125,6 +125,8 @@ const initDb = {
projects: [mock.project],
instances: [mock.instance],
disks: [...mock.disks],
+ images: [...mock.images],
+ snapshots: [...mock.snapshots],
vpcs: [mock.vpc],
vpcSubnets: [mock.vpcSubnet],
vpcFirewallRules: [...mock.defaultFirewallRules],
diff --git a/libs/api-mocks/msw/handlers.ts b/libs/api-mocks/msw/handlers.ts
index 0b262fc562..614f67b66b 100644
--- a/libs/api-mocks/msw/handlers.ts
+++ b/libs/api-mocks/msw/handlers.ts
@@ -288,6 +288,26 @@ export const handlers = [
}
),
+ rest.get | GetErr>(
+ '/api/organizations/:orgName/projects/:projectName/images',
+ (req, res) => {
+ const [project, err] = lookupProject(req)
+ if (err) return res(err)
+ const images = db.images.filter((i) => i.project_id === project.id)
+ return res(json({ items: images }))
+ }
+ ),
+
+ rest.get | GetErr>(
+ '/api/organizations/:orgName/projects/:projectName/snapshots',
+ (req, res) => {
+ const [project, err] = lookupProject(req)
+ if (err) return res(err)
+ const snapshots = db.snapshots.filter((i) => i.project_id === project.id)
+ return res(json({ items: snapshots }))
+ }
+ ),
+
rest.get | GetErr>(
'/api/organizations/:orgName/projects/:projectName/vpcs',
(req, res) => {
diff --git a/libs/api-mocks/snapshot.ts b/libs/api-mocks/snapshot.ts
new file mode 100644
index 0000000000..b8482d081f
--- /dev/null
+++ b/libs/api-mocks/snapshot.ts
@@ -0,0 +1,46 @@
+import type { Snapshot } from '@oxide/api'
+import type { Json } from './json-type'
+import { project } from './project'
+
+export const snapshots: Json[] = [
+ {
+ id: 'snapshot-id-1',
+ name: 'snapshot-1',
+ description: "it's a snapshot",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 1024,
+ disk_id: 'disk-id-1',
+ },
+ {
+ id: 'snapshot-id-2',
+ name: 'snapshot-2',
+ description: "it's a second snapshot",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 2048,
+ disk_id: 'disk-id-1',
+ },
+ {
+ id: 'snapshot-id-3',
+ name: 'snapshot-3',
+ description: "it's a third snapshot",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 3072,
+ disk_id: 'disk-id-1',
+ },
+ {
+ id: 'snapshot-id-4',
+ name: 'snapshot-4',
+ description: "it's a fourth snapshot",
+ project_id: project.id,
+ time_created: new Date().toISOString(),
+ time_modified: new Date().toISOString(),
+ size: 4096,
+ disk_id: 'disk-id-1',
+ },
+]
diff --git a/libs/table/cells/InstanceResourceCell.tsx b/libs/table/cells/InstanceResourceCell.tsx
index 04ee363422..6785e3780c 100644
--- a/libs/table/cells/InstanceResourceCell.tsx
+++ b/libs/table/cells/InstanceResourceCell.tsx
@@ -13,7 +13,7 @@ export const InstanceResourceCell = ({
- {value.ncpus} vCPU {slash} {fileSize(value.memory)} SSD
+ {value.ncpus} vCPU {slash} {fileSize(value.memory, { base: 2 })} SSD
,
FakeOS 12.04
diff --git a/libs/table/cells/SizeCell.tsx b/libs/table/cells/SizeCell.tsx
new file mode 100644
index 0000000000..e843608cef
--- /dev/null
+++ b/libs/table/cells/SizeCell.tsx
@@ -0,0 +1,8 @@
+import React from 'react'
+import fileSize from 'filesize'
+import type { Cell } from './Cell'
+
+/** Human-readable format for size in bytes */
+export const SizeCell = ({ value: bytes }: Cell) => (
+ {fileSize(bytes, { base: 2 })}
+)
diff --git a/libs/table/cells/index.ts b/libs/table/cells/index.ts
index b7c6df9f55..fc5d2216aa 100644
--- a/libs/table/cells/index.ts
+++ b/libs/table/cells/index.ts
@@ -7,6 +7,7 @@ export * from './InstanceResourceCell'
export * from './InstanceStatusCell'
export * from './LabelCell'
export * from './LinkCell'
+export * from './SizeCell'
export * from './TwoLineCell'
export * from './TypeValueCell'
export * from './TypeValueListCell'