Skip to content

Commit 68b7b2f

Browse files
authored
Merge pull request #4 from DevelopmentFinanceObservatory/release/website
Sync dfo-website@aabd42253459
2 parents 2ee2168 + 0c5db44 commit 68b7b2f

88 files changed

Lines changed: 5669 additions & 3422 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎db/schema.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ export const shareRef = pgTable(
9191
specId: text('spec_id').notNull(),
9292
identity: jsonb('identity').notNull(),
9393
variableText: text('variable_text'),
94-
resolvedStatVarDcids: jsonb('resolved_stat_var_dcids'),
9594
contentVersion: text('content_version'),
9695
// Null for a live share and for snapshots stored before the column.
9796
artifactDigest: text('artifact_digest'),

‎src/app/(site)/page.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import BuildTools from '@/components/organisms/BuildTools/BuildTools';
2-
import BuiltWith from '@/components/organisms/BuiltWith/BuiltWith';
32
import CreateCanvas from '@/components/organisms/CreateCanvas/CreateCanvas';
43
import DownloadDataset from '@/components/organisms/DownloadDataset/DownloadDataset';
54
import Hero from '@/components/organisms/Hero/Hero';
@@ -29,7 +28,9 @@ const Home = async () => {
2928
<CreateCanvas />
3029
<DownloadDataset catalogue={catalogue} />
3130
<BuildTools />
32-
<BuiltWith />
31+
{/* "Get inspired by what others are building" is out until there
32+
is real work to show: the component stays in
33+
components/organisms/BuiltWith, ready to mount again. */}
3334
</main>
3435
);
3536
};

‎src/app/api/download-pin/route.ts‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import { searchApiBase } from '@/lib/searchApi';
1111
// its own timeout (see lib/search/snapshot).
1212
const CAPTURE_POLL_DEADLINE_MS = 50_000;
1313

14-
// POST /api/download-pin { specId, contentVersion, definition,
15-
// resolvedStatVarDcids } → 204
14+
// POST /api/download-pin { specId, contentVersion, definition } → 204
1615
// The search page posts here after a download's mint returns, without waiting
1716
// on the answer. The route pins one artifact per version: the first the
1817
// version lists, minted when it lists none. That keeps the version link in
@@ -70,7 +69,6 @@ export const POST = async (req: NextRequest) => {
7069
specId: body.specId,
7170
contentVersion: body.contentVersion,
7271
definition: body.definition,
73-
resolvedStatVarDcids: body.resolvedStatVarDcids,
7472
principal,
7573
pollDeadlineMs: CAPTURE_POLL_DEADLINE_MS,
7674
}),

‎src/app/api/share/route.ts‎

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,36 @@ import { NextResponse } from 'next/server';
44
import { getUser } from '@/lib/auth/session';
55
import type { SavedConversation } from '@/lib/chat/history';
66
import { createShare, ShareKind } from '@/lib/chat/shareStore';
7-
import {
8-
createSearchShare,
9-
isSearchSharePart,
10-
type SearchShareMode,
11-
} from '@/lib/search/searchShare';
7+
import { createSearchShare } from '@/lib/search/searchShare';
8+
import { readSearchShareRequest } from '@/lib/search/searchShareRequest';
129

1310
const KINDS: ShareKind[] = ['conversation', 'canvas', 'card'];
14-
const MODES: SearchShareMode[] = ['live', 'snapshot'];
1511

1612
// POST /api/share { kind: 'search', mode, query, parts } → { id }
1713
// A search result's link: dataset references only, no numbers. The search
1814
// page is public, so an account is optional here (the share is simply
1915
// unowned without one).
2016
const shareSearch = async (body: any) => {
21-
const parts = Array.isArray(body?.parts) ? body.parts : [];
22-
const query = typeof body?.query === 'string' ? body.query.trim().slice(0, 500) : '';
17+
const request = readSearchShareRequest(body);
2318

24-
if (
25-
!MODES.includes(body?.mode) ||
26-
!query ||
27-
parts.length === 0 ||
28-
!parts.every(isSearchSharePart)
29-
) {
19+
if (!request) {
3020
return NextResponse.json({ error: 'bad_request' }, { status: 400 });
3121
}
3222

3323
const user = await getUser();
3424

3525
try {
3626
return NextResponse.json(
37-
await createSearchShare(user?.id ?? null, body.mode, query, parts),
27+
await createSearchShare(user?.id ?? null, request.mode, request.query, request.parts),
3828
);
3929
} catch (error) {
4030
// The platform refused the register/mint — say which, don't store a
4131
// link that can't open. The log names the datasets and the cause.
4232
const { message, cause } = error as Error;
4333

4434
console.error('share: search share capture failed', {
45-
mode: body.mode,
46-
specIds: parts.map((part: { specId: string }) => part.specId),
35+
mode: request.mode,
36+
specIds: request.parts.map((part) => part.specId),
4737
error: message,
4838
cause: cause instanceof Error ? cause.message : undefined,
4939
});

‎src/app/s/[id]/download/preparing/PreparingDownload.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ const PreparingDownload = ({
6969
specId,
7070
contentVersion: manifest.content_version,
7171
definition: null,
72-
resolvedStatVarDcids: undefined,
7372
});
7473
}
7574

‎src/components/organisms/DataSearch/DataSearch.module.scss‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ span.slotMarked {
514514
}
515515

516516
// Pinned to .slotMenuBody's own scroll area so a long list (hundreds of CRS
517-
// donor/recipient rows) doesn't scroll Apply out of reach; background
517+
// provider/recipient rows) doesn't scroll Apply out of reach; background
518518
// matches the menu so a scrolling row underneath doesn't show through.
519519
.multiSelectApply {
520520
position: sticky;
@@ -752,7 +752,7 @@ span.slotMarked {
752752
color: var(--color-stone);
753753
}
754754

755-
// A place picker or window/donor fetch that failed outright (a refused or
755+
// A place picker or window/provider fetch that failed outright (a refused or
756756
// dropped request), rather than one that simply came back with nothing —
757757
// the note names what the door said, the button re-runs it.
758758
.slotFailed {

‎src/components/organisms/DataSearch/DataSearch.tsx‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import {
3636
} from '@/lib/search/catalogue';
3737
import { decodePermalinkState, encodePermalinkState } from '@/lib/search/permalink';
3838
import { track } from '@/lib/events/client';
39-
import { promoteFromSpec } from '@/lib/search/promote';
4039
import {
4140
createSearchShare,
4241
fetchSearchShare,
@@ -322,7 +321,6 @@ const DataSearch = ({ catalogue }: { catalogue: SearchCatalogue | null }) => {
322321
// include_observations: without it the engine skips the
323322
// materialise pass and coverage counts come back empty.
324323
response_options: {
325-
include_sentence: true,
326324
include_option_coverage: false,
327325
include_observations: true,
328326
},
@@ -725,7 +723,6 @@ const DataSearch = ({ catalogue }: { catalogue: SearchCatalogue | null }) => {
725723
variableText: part.variableText,
726724
specId: spec.spec_id,
727725
identity: spec.identity,
728-
resolvedStatVarDcids: promoteFromSpec(spec).resolved_stat_var_dcids ?? null,
729726
operations: part.part?.operations ?? [],
730727
definition: spec.definition,
731728
};

‎src/components/organisms/DataSearch/DownloadOptions.module.scss‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
width: 100%;
3636
}
3737

38-
// One entity column's extras under the role it plays (Donor, Recipient).
38+
// One entity column's extras under the role it plays (Provider, Recipient).
3939
.role {
4040
@include flex(column, flex-start, stretch);
4141

‎src/components/organisms/DataSearch/GraphInfo.tsx‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ import styles from './DataSearch.module.scss';
1616
import { OptionRowInfo } from './SlotMenu';
1717

1818
import Icon from '@/components/atoms/Icon/Icon';
19+
import {
20+
definitionMembersReader,
21+
type MemberSpec,
22+
type MembersRead,
23+
} from '@/lib/search/definitionMembers';
1924
import { graphReader } from '@/lib/search/graphReads';
2025
import { graphNodeDescription } from '@/lib/search/measureMenu';
2126
import { notePosition, noteShown } from '@/lib/search/notePosition';
@@ -28,6 +33,8 @@ const readNoNote = () => null;
2833

2934
const graph = graphReader({ fetchImpl: (url, init) => fetch(url, init) });
3035

36+
const readMembers = definitionMembersReader();
37+
3138
// The graph's own documentation for a source (the same door the Sources
3239
// pages read), shared by every row that asks. A source with no page (the
3340
// catalogue excludes it, or the read failed) resolves to null.
@@ -336,6 +343,27 @@ export const useNodeDescriptions = (dcids: string[]): (string | null)[] => {
336343
return useSettled(pending) ?? dcids.map(() => null);
337344
};
338345

346+
// Settles to null, so a hook given no Spec reads nothing.
347+
const NO_MEMBERS: Promise<MembersRead | null> = Promise.resolve(null);
348+
349+
/** The StatVars `spec` serves, from the Datasets members door, null while
350+
* unread and for a null `spec`. A caller passes the Spec only once its
351+
* panel is open, so a closed panel asks nothing. */
352+
export const useDefinitionMembers = (spec: MemberSpec | null): MembersRead | null => {
353+
const specId = spec?.spec_id ?? null;
354+
const definition = spec?.definition;
355+
const digest = spec?.shape?.member_digest ?? null;
356+
const pending = useMemo(
357+
() =>
358+
specId
359+
? readMembers({ spec_id: specId, definition, shape: { member_digest: digest } })
360+
: NO_MEMBERS,
361+
[specId, definition, digest],
362+
);
363+
364+
return useSettled(pending);
365+
};
366+
339367
/** Each source's description from its documentation page, and whether the
340368
* catalogue has that page to link to, in order. Each reads null and false
341369
* until the reads settle. */

‎src/components/organisms/DataSearch/SearchPanel.tsx‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { useDatasetDownload } from './useDatasetDownload';
1111

1212
import Button from '@/components/atoms/Button/Button';
1313
import { usePrefersReducedMotion } from '@/hooks/usePrefersReducedMotion';
14-
import { promoteFromSpec } from '@/lib/search/promote';
1514
import { detailRows, downloadRowCount, formatCount } from '@/lib/search/view';
1615

1716
import { SourceName } from './WhyPanel';
@@ -71,7 +70,6 @@ const SearchPanel = ({
7170
const download = useDatasetDownload({
7271
specId: spec?.spec_id,
7372
definition: spec?.definition,
74-
resolvedStatVarDcids: spec ? promoteFromSpec(spec).resolved_stat_var_dcids : undefined,
7573
entities: spec?.entities,
7674
});
7775

0 commit comments

Comments
 (0)