diff --git a/precomputer/src/job.ts b/precomputer/src/job.ts index 2d33cbc..4121989 100644 --- a/precomputer/src/job.ts +++ b/precomputer/src/job.ts @@ -2,7 +2,7 @@ import { PromisePool } from '@supercharge/promise-pool' import { getClusterIndex } from './tasks/cluster-index.ts' import { getClusterPackage } from './tasks/cluster.ts' import { getFinalReviewIndex } from './tasks/final-review-index.ts' -import { getQueue } from './tasks/queue.ts' +import { getQueueIndex } from './tasks/queue-index.ts' import { getApiClient } from './utils/api.ts' import { CLUSTER_INDEX_PATH, clusterPathBuilder, deleteFromS3, FINAL_REVIEW_INDEX_PATH, listS3Files, QUEUE_INDEX_PATH, saveToS3 } from './utils/s3.ts' import { type ClusterPackageCommon } from '../../website/app/utils/validators.ts' @@ -19,8 +19,8 @@ const NUMBER_OF_CONCURRENT_S3_USAGES = 4 const main = async (): Promise => { const api = getApiClient() - const [queueCommon, clusterIndex, finalReviewIndex] = await Promise.all([ - getQueue({ api }), + const [queueIndex, clusterIndex, finalReviewIndex] = await Promise.all([ + getQueueIndex({ api }), getClusterIndex({ api }), getFinalReviewIndex({ api }) ]) @@ -50,7 +50,7 @@ const main = async (): Promise => { console.log(`[Clusters] Successfully fetched ALL cluster API data for ${clusterPackages.length} cluster(s).`) const uploadTasks: S3UploadTask[] = [ - { key: QUEUE_INDEX_PATH, contents: JSON.stringify(queueCommon) }, + { key: QUEUE_INDEX_PATH, contents: JSON.stringify(queueIndex) }, { key: CLUSTER_INDEX_PATH, contents: JSON.stringify(clusterIndex) }, { key: FINAL_REVIEW_INDEX_PATH, contents: JSON.stringify(finalReviewIndex) }, ...clusterPackages.map((clusterPackage): S3UploadTask => { diff --git a/precomputer/src/tasks/cluster-index.ts b/precomputer/src/tasks/cluster-index.ts index 536aef4..1b1b362 100644 --- a/precomputer/src/tasks/cluster-index.ts +++ b/precomputer/src/tasks/cluster-index.ts @@ -2,6 +2,7 @@ import { PurpleApi } from "../../generated/purple_client/index.ts"; import { type ClusterIndexCommon, type ClusterItemCommon, ClusterIndexCommonSchema } from '../../../website/app/utils/validators.ts' import { clusterMemberToClusterDocumentCommon } from "../utils/converters.ts"; +import { DateTime } from "luxon"; type Props = { api: PurpleApi @@ -11,6 +12,7 @@ export const getClusterIndex = async ({ api }: Props): Promise item.isActive).map((cluster): ClusterItemCommon => { const { number, documents } = cluster const clusterItems = documents?.map((clusterMember) => clusterMemberToClusterDocumentCommon(number, clusterMember)) ?? [] diff --git a/precomputer/src/tasks/cluster.ts b/precomputer/src/tasks/cluster.ts index d8fbfb9..527e3b3 100644 --- a/precomputer/src/tasks/cluster.ts +++ b/precomputer/src/tasks/cluster.ts @@ -2,6 +2,7 @@ import { PurpleApi } from "../../generated/purple_client/index.ts"; import { type ClusterPackageCommon, ClusterPackageCommonSchema } from '../../../website/app/utils/validators.ts' import { clusterMemberToClusterDocumentCommon } from "../utils/converters.ts"; +import { DateTime } from "luxon"; type Props = { api: PurpleApi @@ -19,6 +20,7 @@ export const getClusterPackage = async ({ api, clusterNumber }: Props): Promise< const clusterDocuments = cluster.documents?.map(clusterMember => clusterMemberToClusterDocumentCommon(cluster.number, clusterMember)) ?? [] const clusterPackage: ClusterPackageCommon = { + generatedAtIso: DateTime.now().toISO(), cluster: { number: cluster.number, allPublished: clusterDocuments.length > 0 ? clusterDocuments.every(document => document.disposition === 'published') : false, diff --git a/precomputer/src/tasks/queue.ts b/precomputer/src/tasks/queue-index.ts similarity index 70% rename from precomputer/src/tasks/queue.ts rename to precomputer/src/tasks/queue-index.ts index bc7c14e..df61784 100644 --- a/precomputer/src/tasks/queue.ts +++ b/precomputer/src/tasks/queue-index.ts @@ -6,4 +6,4 @@ type Props = { api: PurpleApi } -export const getQueue = async (props: Props): Promise => getQueueCommon(props) \ No newline at end of file +export const getQueueIndex = async (props: Props): Promise => getQueueCommon(props) \ No newline at end of file diff --git a/precomputer/src/utils/dev-api-server.ts b/precomputer/src/utils/dev-api-server.ts index 1a1ede0..15fa1e0 100644 --- a/precomputer/src/utils/dev-api-server.ts +++ b/precomputer/src/utils/dev-api-server.ts @@ -1,6 +1,6 @@ import Fastify from 'fastify' import { getApiClient } from './api.ts' -import { getQueue } from '../tasks/queue.ts' +import { getQueueIndex } from '../tasks/queue-index.ts' import { getClusterPackage } from '../tasks/cluster.ts' import { getClusterIndex } from '../tasks/cluster-index.ts' import { getFinalReviewIndex } from '../tasks/final-review-index.ts' @@ -11,7 +11,7 @@ const fastify = Fastify({ fastify.get('/api/v1/queue.json', async () => { const api = getApiClient('dev') - const queueCommon = await getQueue({ api }) + const queueCommon = await getQueueIndex({ api }) return queueCommon }) diff --git a/precomputer/src/utils/queue.ts b/precomputer/src/utils/queue.ts index 3fe59b9..35f903f 100644 --- a/precomputer/src/utils/queue.ts +++ b/precomputer/src/utils/queue.ts @@ -1,3 +1,4 @@ +import { DateTime } from 'luxon' import { PurpleApi, type ApiPubqQueueListRequest } from "../../generated/purple_client/index.ts"; import { type QueueCommon, type QueueCommonItem, QueueCommonSchema, type BlockingReason } from '../../../website/app/utils/validators.ts' import { assertIsString } from "../utils/typescript.ts"; @@ -15,6 +16,7 @@ export const getQueueCommon = async ({ api, params }: Props): Promise { const { name, diff --git a/website/app/components/ClusterPage.vue b/website/app/components/ClusterPage.vue index 9e3e464..9be4645 100644 --- a/website/app/components/ClusterPage.vue +++ b/website/app/components/ClusterPage.vue @@ -28,7 +28,7 @@ const { data: clusterPackage, error, status } = await useAsyncData( () => `cluster-${props.clusterNumber}`, () => getClusterPackage(url.hostname, props.clusterNumber), { - server: false, + server: true, // rendering on the server to generate real 404s for missing content lazy: true, } ) diff --git a/website/app/components/ClustersIndex.vue b/website/app/components/ClustersIndex.vue index d7e6165..5d2792b 100644 --- a/website/app/components/ClustersIndex.vue +++ b/website/app/components/ClustersIndex.vue @@ -30,6 +30,10 @@ +

+ Updated + +

@@ -45,11 +49,10 @@ import { getSortedRowModel, } from '@tanstack/vue-table' import { getVNodeText } from '../utils/vue' +import { DateTime } from 'luxon' const url = useRequestURL() -const emptyArray: ClusterItemCommon[] = [] - const { data, status, @@ -59,11 +62,12 @@ const { () => getClusterIndex(url.hostname), { server: false, - lazy: true, - default: () => emptyArray + lazy: true } ) +const generatedAt = computed(() => data.value?.generatedAtIso ? DateTime.fromISO(data.value.generatedAtIso) : undefined) + const columnHelper = createColumnHelper() const sorting = ref([]) @@ -96,8 +100,12 @@ const columns = [ }), ] +const emptyArray: ClusterItemCommon[] = [] + const table = useVueTable({ - data, + get data() { + return data.value?.list ?? emptyArray // Need a const emptyArray rather than a new array every data(){} to prevent unnecessary rerenders / freezing + }, columns, state: { get sorting() { diff --git a/website/app/components/FinalReviewIndexTable.vue b/website/app/components/FinalReviewIndexTable.vue index 6f19cc6..7e10dab 100644 --- a/website/app/components/FinalReviewIndexTable.vue +++ b/website/app/components/FinalReviewIndexTable.vue @@ -49,8 +49,6 @@ import { getFinalReviewIndex } from '~/utils/api' import Label from './Label.vue' import { finalReviewPathBuilder } from '~/utils/url' -const emptyArray: QueueCommonItem[] = [] - const url = useRequestURL() const { @@ -62,8 +60,7 @@ const { () => getFinalReviewIndex(url.hostname), { server: false, - lazy: true, - default: () => emptyArray + lazy: true } ) @@ -95,8 +92,12 @@ const columns = [ }), ] +const emptyArray: QueueCommonItem[] = [] + const table = useVueTable({ - data, + get data() { + return data.value?.items ?? emptyArray // Need a const emptyArray rather than a new array every data(){} to prevent unnecessary rerenders / freezing + }, columns, state: { get globalFilter() { diff --git a/website/app/components/FinalReviewPage.vue b/website/app/components/FinalReviewPage.vue index 385a082..1169fed 100644 --- a/website/app/components/FinalReviewPage.vue +++ b/website/app/components/FinalReviewPage.vue @@ -13,10 +13,17 @@ class="flex flex-col gap-2">
  • -

    Posted

    +

    Posted + +

  • No logs available

    + +

    + Updated + +

    @@ -60,8 +64,6 @@ const url = useRequestURL() const props = defineProps() -const emptyArray: QueueCommonItem[] = [] - const { data, status, @@ -71,11 +73,12 @@ const { () => getQueueIndex(url.hostname), { server: false, - lazy: true, - default: () => emptyArray + lazy: true } ) +const generatedAt = computed(() => data.value?.generatedAtIso ? DateTime.fromISO(data.value.generatedAtIso) : undefined) + const columnHelper = createColumnHelper() const sorting = ref([]) @@ -224,11 +227,14 @@ const columns = [ return a - b }, }), - ] +const emptyArray: QueueCommonItem[] = [] + const table = useVueTable({ - data, + get data() { + return data.value?.items ?? emptyArray // Need a const emptyArray rather than a new array every data(){} to prevent unnecessary rerenders / freezing + }, columns, state: { get globalFilter() { diff --git a/website/app/utils/api.ts b/website/app/utils/api.ts index 69c293f..b021a25 100644 --- a/website/app/utils/api.ts +++ b/website/app/utils/api.ts @@ -10,7 +10,7 @@ export const getQueueIndex = async (hostName: string) => { console.error('Queue fetch succeeded but data failed validation', path, unverifiedData, error) throw Error('Queue fetch failed. Try again later.') } - return data.items + return data } export const getFinalReviewIndex = async (hostName: string) => { @@ -22,7 +22,7 @@ export const getFinalReviewIndex = async (hostName: string) => { console.error('Final review index fetch succeeded but data failed validation', path, unverifiedData, error) throw Error('Final review index fetch failed. Try again later.') } - return data.items + return data } export const getClusterIndex = async (hostName:string) => { @@ -34,7 +34,7 @@ export const getClusterIndex = async (hostName:string) => { console.error('Cluster index fetch succeeded but data failed validation', path, unverifiedData, error) throw Error('Cluster index fetch failed. Try again later.') } - return data.list + return data } export const getClusterPackage = async (hostName: string, clusterNumber: number) => { diff --git a/website/app/utils/validators.ts b/website/app/utils/validators.ts index 45f9065..408bb6e 100644 --- a/website/app/utils/validators.ts +++ b/website/app/utils/validators.ts @@ -103,6 +103,7 @@ export const QueueCommonItemSchema = z.object({ export type QueueCommonItem = z.infer export const QueueCommonSchema = z.object({ + generatedAtIso: z.string(), items: z.array(QueueCommonItemSchema) }) @@ -154,12 +155,14 @@ const ClusterRfcToBeCommonSchema = z.object({ export type ClusterRfcToBeCommon = z.infer export const ClusterPackageCommonSchema = z.object({ + generatedAtIso: z.string(), cluster: ClusterItemCommonSchema }) export type ClusterPackageCommon = z.infer export const ClusterIndexCommonSchema = z.object({ + generatedAtIso: z.string(), list: ClusterItemCommonSchema.array() })