Skip to content

Commit

Permalink
✨ CF images API enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
ikesau committed Nov 26, 2024
1 parent deda2e9 commit 1e3940b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 65 deletions.
39 changes: 18 additions & 21 deletions adminSiteClient/ImagesIndexPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type ImageEditorApi = {
patch: Partial<DbEnrichedImage>
) => void
deleteImage: (image: DbEnrichedImage) => void
getImages: () => Promise<DbEnrichedImage[]>
getImages: () => void
}

function AltTextEditor({
Expand Down Expand Up @@ -164,7 +164,7 @@ function ImageUploadButton({
setImages,
admin,
}: {
setImages: (images: DbEnrichedImage[]) => void
setImages: React.Dispatch<React.SetStateAction<DbEnrichedImage[]>>
admin: Admin
}) {
function uploadImage({ file }: { file: string | Blob | RcFile }) {
Expand All @@ -180,13 +180,12 @@ function ImageUploadButton({
type: file.type,
}

const response = await admin.requestJSON(
"/api/image",
payload,
"POST"
)
const { image } = await admin.requestJSON<{
sucess: true
image: DbEnrichedImage
}>("/api/image", payload, "POST")

setImages(response.images)
setImages((images) => [image, ...images])
}
reader.readAsDataURL(file)
}
Expand All @@ -206,25 +205,23 @@ export function ImageIndexPage() {
const api = useMemo(
(): ImageEditorApi => ({
deleteImage: async (image) => {
const response = await admin.requestJSON(
`/api/images/${image.id}`,
{},
"DELETE"
)
setImages(response.images)
await admin.requestJSON(`/api/images/${image.id}`, {}, "DELETE")
setImages((images) => images.filter((i) => i.id !== image.id))
},
getImages: async () => {
const json = await admin.getJSON("/api/images.json")
const json = await admin.getJSON<{
images: DbEnrichedImage[]
}>("/api/images.json")
setImages(json.images)
return json.images
},
patchImage: async (image, patch) => {
const response = await admin.requestJSON(
`/api/images/${image.id}`,
patch,
"PATCH"
const response = await admin.requestJSON<{
success: true
image: DbEnrichedImage
}>(`/api/images/${image.id}`, patch, "PATCH")
setImages((images) =>
images.map((i) => (i.id === image.id ? response.image : i))
)
setImages(response.images)
},
}),
[admin]
Expand Down
71 changes: 27 additions & 44 deletions adminSiteServer/apiRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3122,43 +3122,35 @@ postRouteWithRWTransaction(apiRouter, "/image", async (req, res, trx) => {
}
}

await db.knexRaw(
trx,
`-- sql
INSERT INTO images
(filename, originalWidth, originalHeight, cloudflareId, defaultAlt, googleId, updatedAt)
VALUES
(?, ?, ?, ?, ?, ?, ?)`,
[
filename,
dimensions.width,
dimensions.height,
cloudflareId,
// TODO: make defaultAlt nullable
"Default alt text",
// TODO: drop googleId
String(Math.random()).slice(2),
new Date().getTime(),
]
)
await trx<DbEnrichedImage>("images").insert({
filename,
originalWidth: dimensions.width,
originalHeight: dimensions.height,
cloudflareId,
// TODO: make defaultAlt nullable
defaultAlt: "Default alt text",
// TODO: drop googleId
googleId: String(Math.random()).slice(2),
updatedAt: new Date().getTime(),
})

const images = await db.getCloudflareImages(trx)
const image = await trx<DbEnrichedImage>("images")
.where("cloudflareId", "=", cloudflareId)
.first()

return {
success: true,
images,
image,
}
})

// Update alt text via patch
patchRouteWithRWTransaction(apiRouter, "/images/:id", async (req, res, trx) => {
const { id } = req.params
const image = await db.knexRawFirst<DbEnrichedImage>(
trx,
`-- sql
SELECT * FROM images WHERE id = ?`,
[id]
)

const image = await trx<DbEnrichedImage>("images")
.where("id", "=", id)
.first()

if (!image) {
throw new JsonError(`No image found for id ${id}`, 404)
Expand All @@ -3173,11 +3165,13 @@ patchRouteWithRWTransaction(apiRouter, "/images/:id", async (req, res, trx) => {

await trx("images").where({ id }).update(patch)

const images = await db.getCloudflareImages(trx)
const updated = await trx<DbEnrichedImage>("images")
.where("id", "=", id)
.first()

return {
success: true,
images,
image: updated,
}
})

Expand All @@ -3187,12 +3181,9 @@ deleteRouteWithRWTransaction(
async (req, res, trx) => {
const { id } = req.params

const image = await db.knexRawFirst<{ cloudflareId: string }>(
trx,
`-- sql
SELECT cloudflareId FROM images WHERE id = ?`,
[id]
)
const image = await trx<DbEnrichedImage>("images")
.where("id", "=", id)
.first()

if (!image) {
throw new JsonError(`No image found for id ${id}`, 404)
Expand All @@ -3216,18 +3207,10 @@ deleteRouteWithRWTransaction(
throw new JsonError(JSON.stringify(response.errors))
}

await db.knexRaw(
trx,
`-- sql
DELETE FROM images WHERE id = ?`,
[id]
)

const images = await db.getCloudflareImages(trx)
await trx("images").where({ id }).delete()

return {
success: true,
images,
}
}
)
Expand Down
1 change: 1 addition & 0 deletions packages/@ourworldindata/types/src/dbTypes/Images.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const ImagesTableName = "images"
export interface DbInsertImage {
googleId: string
defaultAlt: string
filename: string
id?: number
Expand Down

0 comments on commit 1e3940b

Please sign in to comment.