Skip to content

Commit

Permalink
Address PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
rakyi committed Feb 12, 2025
1 parent f158ace commit b5e73ed
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 43 deletions.
44 changes: 20 additions & 24 deletions adminSiteClient/MultiDimIndexPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
useQuery,
useQueryClient,
} from "@tanstack/react-query"
import { createContext, useContext, useEffect, useMemo, useState } from "react"
import { useContext, useEffect, useMemo, useState } from "react"
import {
Input,
Popconfirm,
Expand Down Expand Up @@ -46,7 +46,7 @@ function SlugField({
id: number
slug: string
slugMutation: UseMutationResult<
unknown,
MultiDim,
unknown,
{ id: number; slug: string },
unknown
Expand All @@ -65,13 +65,13 @@ function SlugField({

function createColumns(
slugMutation: UseMutationResult<
unknown,
MultiDim,
unknown,
{ id: number; slug: string },
unknown
>,
publishMutation: UseMutationResult<
unknown,
MultiDim,
unknown,
{ id: number; published: boolean },
unknown
Expand Down Expand Up @@ -131,7 +131,7 @@ function createColumns(
render: (slug, { id }) => (
<SlugField id={id} slug={slug} slugMutation={slugMutation} />
),
sorter: (a, b) => a.title.localeCompare(b.title),
sorter: (a, b) => a.slug.localeCompare(b.slug),
},
{
title: "Last updated",
Expand Down Expand Up @@ -198,8 +198,6 @@ async function patchMultiDim(admin: Admin, id: number, data: Json) {
return deserializeMultiDim(multiDim)
}

const NotificationContext = createContext(null)

export function MultiDimIndexPage() {
const { admin } = useContext(AdminAppContext)
const [notificationApi, notificationContextHolder] =
Expand Down Expand Up @@ -260,23 +258,21 @@ export function MultiDimIndexPage() {

return (
<AdminLayout title="Multidimensional Data Pages">
<NotificationContext.Provider value={null}>
{notificationContextHolder}
<main>
<Input
placeholder="Search by title or slug"
value={search}
onChange={(e) => setSearch(e.target.value)}
style={{ width: 500, marginBottom: 20 }}
autoFocus
/>
<Table
columns={columns}
dataSource={filteredMdims}
rowKey={(x) => x.id}
/>
</main>
</NotificationContext.Provider>
{notificationContextHolder}
<main>
<Input
placeholder="Search by title or slug"
value={search}
onChange={(e) => setSearch(e.target.value)}
style={{ width: 500, marginBottom: 20 }}
autoFocus
/>
<Table
columns={columns}
dataSource={filteredMdims}
rowKey={(x) => x.id}
/>
</main>
</AdminLayout>
)
}
4 changes: 1 addition & 3 deletions adminSiteServer/apiRoutes/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,7 @@ export const saveGrapher = async (

// When a chart is published, check for conflicts
if (newConfig.isPublished) {
if (newConfig.slug) {
await validateGrapherSlug(knex, newConfig.slug, existingConfig?.id)
}
await validateGrapherSlug(knex, newConfig.slug, existingConfig?.id)
if (
existingConfig &&
existingConfig.isPublished &&
Expand Down
4 changes: 3 additions & 1 deletion adminSiteServer/apiRoutes/mdims.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { triggerStaticBuild } from "./routeUtils.js"
import { Request } from "../authentication.js"
import * as db from "../../db/db.js"
import { validateGrapherSlug } from "../validation.js"
import { validateGrapherSlug, validateMultiDimSlug } from "../validation.js"
import e from "express"

export async function handleGetMultiDims(
Expand Down Expand Up @@ -72,6 +72,7 @@ export async function handlePutMultiDim(
FEATURE_FLAGS.has(FeatureFlagFeature.MultiDimDataPage) &&
(await multiDimDataPageExists(trx, { slug, published: true }))
) {
await validateMultiDimSlug(trx, slug)
await triggerStaticBuild(
res.locals.user,
`Publishing multidimensional chart ${slug}`
Expand Down Expand Up @@ -104,6 +105,7 @@ export async function handlePatchMultiDim(
}
}
if (action) {
await validateMultiDimSlug(trx, multiDim.slug)
await triggerStaticBuild(
res.locals.user,
`${action === "publish" ? "Publishing" : "Unpublishing"} multidimensional chart ${multiDim.slug}`
Expand Down
29 changes: 27 additions & 2 deletions adminSiteServer/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async function isSlugUsedInOtherGrapher(

export async function validateGrapherSlug(
knex: db.KnexReadonlyTransaction,
slug: string,
slug?: string,
existingConfigId?: number
) {
if (!isValidSlug(slug)) {
Expand All @@ -65,7 +65,32 @@ export async function validateGrapherSlug(
}
if (await multiDimDataPageExists(knex, { slug })) {
throw new JsonError(
`This slug is in use by a multi-dimensional data page: ${slug}`
`This slug is in use by a multidimensional data page: ${slug}`
)
}
return slug
}

/**
* Validates an existing slug of a multidimensional data page,
* e.g. before publishing.
*/
export async function validateMultiDimSlug(
knex: db.KnexReadonlyTransaction,
slug: string,
existingConfigId?: number
) {
if (!isValidSlug(slug)) {
throw new JsonError(`Invalid chart slug ${slug}`)
}
if (await isSlugUsedInRedirect(knex, slug, existingConfigId)) {
throw new JsonError(
`This chart slug was previously used by another chart: ${slug}`
)
}
if (await isSlugUsedInOtherGrapher(knex, slug, existingConfigId)) {
throw new JsonError(
`This chart slug is in use by another published chart: ${slug}`
)
}
return slug
Expand Down
11 changes: 0 additions & 11 deletions db/model/MultiDimDataPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,6 @@ export async function upsertMultiDimDataPage(
return result[0]
}

export async function isMultiDimDataPagePublished(
knex: KnexReadonlyTransaction,
slug: string
): Promise<boolean> {
const result = await knex(MultiDimDataPagesTableName)
.select(knex.raw("1"))
.where({ slug, published: true })
.first()
return Boolean(result)
}

export async function multiDimDataPageExists(
knex: KnexReadonlyTransaction,
data: Partial<DbPlainMultiDimDataPage>
Expand Down
4 changes: 2 additions & 2 deletions serverUtils/serverUtil.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export const renderToHtmlPage = (element: any) =>
`<!doctype html>${ReactDOMServer.renderToStaticMarkup(element)}`

// Determine if input is suitable for use as a url slug
export const isValidSlug = (slug: any) =>
lodash.isString(slug) && slug.length > 1 && slug.match(/^[\w-]+$/)
export const isValidSlug = (slug: any): slug is string =>
lodash.isString(slug) && slug.length > 1 && slug.match(/^[\w-]+$/) !== null

export function base64ToBytes(base64: Base64String): Uint8Array {
return Buffer.from(base64, "base64")
Expand Down

0 comments on commit b5e73ed

Please sign in to comment.