diff --git a/src/libs/opensearch-lib.ts b/src/libs/opensearch-lib.ts index 34a3e03005..6d194adf9d 100644 --- a/src/libs/opensearch-lib.ts +++ b/src/libs/opensearch-lib.ts @@ -7,7 +7,7 @@ import * as aws4 from "aws4"; import axios from "axios"; import { aws4Interceptor } from "aws4-axios"; import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts"; -import { OsIndex } from "shared-types"; +import { opensearch } from "shared-types"; let client: Client; export async function getClient(host: string) { @@ -40,7 +40,7 @@ export async function updateData(host: string, indexObject: any) { export async function bulkUpdateData( host: string, - index: OsIndex, + index: opensearch.Index, arrayOfDocuments: any ) { client = client || (await getClient(host)); @@ -60,7 +60,7 @@ export async function bulkUpdateData( console.log(response); } -export async function deleteIndex(host: string, index: OsIndex) { +export async function deleteIndex(host: string, index: opensearch.Index) { client = client || (await getClient(host)); var response = await client.indices.delete({ index }); } @@ -111,7 +111,7 @@ export async function mapRole( } } -export async function search(host: string, index: OsIndex, query: any) { +export async function search(host: string, index: opensearch.Index, query: any) { client = client || (await getClient(host)); try { const response = await client.search({ @@ -124,7 +124,7 @@ export async function search(host: string, index: OsIndex, query: any) { } } -export async function getItem(host: string, index: OsIndex, id: string) { +export async function getItem(host: string, index: opensearch.Index, id: string) { client = client || (await getClient(host)); try { const response = await client.get({ id, index }); @@ -135,7 +135,7 @@ export async function getItem(host: string, index: OsIndex, id: string) { } // check it exists - then create -export async function createIndex(host: string, index: OsIndex) { +export async function createIndex(host: string, index: opensearch.Index) { client = client || (await getClient(host)); try { const exists = await client.indices.exists({ index }); @@ -150,7 +150,7 @@ export async function createIndex(host: string, index: OsIndex) { export async function updateFieldMapping( host: string, - index: OsIndex, + index: opensearch.Index, properties: object ) { client = client || (await getClient(host)); diff --git a/src/packages/shared-types/index.ts b/src/packages/shared-types/index.ts index df749505fd..f8af01976a 100644 --- a/src/packages/shared-types/index.ts +++ b/src/packages/shared-types/index.ts @@ -4,7 +4,7 @@ export * from "./errors"; export * from "./seatool"; export * from "./onemac"; export * from "./onemacLegacy"; -export * from "./opensearch"; +export * as opensearch from "./opensearch"; export * from "./uploads"; export * from "./actions"; export * from "./attachments"; diff --git a/src/packages/shared-types/opensearch.ts b/src/packages/shared-types/opensearch.ts deleted file mode 100644 index 8e704c6b53..0000000000 --- a/src/packages/shared-types/opensearch.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { - SeaToolTransform, - OnemacTransform, - OnemacLegacyTransform, - RaiIssueTransform, - RaiResponseTransform, - RaiWithdrawTransform, - WithdrawPackageTransform, - ToggleWithdrawRaiEnabledTransform, -} from "./"; - -export type OsHit = { - _index: string; - _id: string; - _score: number; - _source: T; - sort: Array; -}; -export type OsHits = { - hits: OsHit[]; - max_score: number; - total: { value: number; relation: "eq" }; -}; - -export type OsResponse = { - _shards: { - total: number; - failed: number; - successful: number; - skipped: number; - }; - hits: OsHits; - total: { - value: number; - }; - max_score: number | null; - took: number; - timed_out: boolean; - aggregations?: OsAggResult; -}; - -export type OsMainSourceItem = OnemacTransform & - OnemacLegacyTransform & - SeaToolTransform & - RaiIssueTransform & - RaiResponseTransform & - RaiWithdrawTransform & - WithdrawPackageTransform & - ToggleWithdrawRaiEnabledTransform; -export type OsMainSearchResponse = OsResponse; -export type SearchData = OsHits; -export type ItemResult = OsHit & { - found: boolean; -}; - -export type OsFilterType = - | "term" - | "terms" - | "match" - | "range" - | "search" - | "global_search" - | "exists"; - -export type OsRangeValue = { gte?: string; lte?: string }; -export type OsFilterValue = string | string[] | number | boolean | OsRangeValue; -export type OsField = - | keyof OsMainSourceItem - | `${keyof OsMainSourceItem}.keyword`; - -export type OsFilterable = { - type: OsFilterType; - label?: string; - component?: string; - field: OsField; - value: OsFilterValue; - prefix: "must" | "must_not" | "should" | "filter"; -}; - -export type OsQueryState = { - sort: { field: OsField; order: "asc" | "desc" }; - pagination: { number: number; size: number }; - filters: OsFilterable[]; - search?: string; -}; - -export type OsAggQuery = { - name: string; - type: OsFilterType; - field: OsField; - size: number; -}; - -export type OsAggBucket = { key: string; doc_count: number }; - -export type OsAggResult = Record< - string, - { - doc_count_error_upper_bound: number; - sum_other_doc_count: number; - buckets: OsAggBucket[]; - } ->; - -export type OsExportHeaderOptions = { - transform: (data: TData) => string; - name: string; -}; - -export type OsIndex = "main" | "seatool" | "changelog"; diff --git a/src/packages/shared-types/opensearch/_.ts b/src/packages/shared-types/opensearch/_.ts new file mode 100644 index 0000000000..f16e3ce65c --- /dev/null +++ b/src/packages/shared-types/opensearch/_.ts @@ -0,0 +1,82 @@ +export type Hit = { + _index: string; + _id: string; + _score: number; + _source: T; + sort: Array; +}; +export type Hits = { + hits: Hit[]; + max_score: number; + total: { value: number; relation: "eq" }; +}; + +export type Response = { + _shards: { + total: number; + failed: number; + successful: number; + skipped: number; + }; + hits: Hits; + total: { + value: number; + }; + max_score: number | null; + took: number; + timed_out: boolean; + aggregations?: AggResult; +}; + +export type FilterType = + | "term" + | "terms" + | "match" + | "range" + | "search" + | "global_search" + | "exists"; + +export type RangeValue = { gte?: string; lte?: string }; +export type FilterValue = string | string[] | number | boolean | RangeValue; + +export type Filterable<_FIELD> = { + type: FilterType; + label?: string; + component?: string; + field: _FIELD; + value: FilterValue; + prefix: "must" | "must_not" | "should" | "filter"; +}; + +export type QueryState<_FIELD> = { + sort: { field: _FIELD; order: "asc" | "desc" }; + pagination: { number: number; size: number }; + filters: Filterable<_FIELD>[]; + search?: string; +}; + +export type AggQuery<_FIELD> = { + name: string; + type: FilterType; + field: _FIELD; + size: number; +}; + +export type AggBucket = { key: string; doc_count: number }; + +export type AggResult = Record< + string, + { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: AggBucket[]; + } +>; + +export type ExportHeaderOptions = { + transform: (data: TData) => string; + name: string; +}; + +export type Index = "main" | "seatool" | "changelog"; diff --git a/src/packages/shared-types/opensearch/changelog.ts b/src/packages/shared-types/opensearch/changelog.ts new file mode 100644 index 0000000000..97bd59cf27 --- /dev/null +++ b/src/packages/shared-types/opensearch/changelog.ts @@ -0,0 +1,43 @@ +import { + Response as Res, + Hit, + Filterable as FIL, + QueryState, + AggQuery, +} from "./_"; + +export type Document = { + actionType: string; + additionalInformation: string; + attachments?: { + bucket: string; + filename: string; + key: string; + title: string; + uploadDate: number; + }[]; + timestamp: string; + authority: string; + id: string; + origin: string; + packageId: string; + proposedEffectiveDate: number; + raiWithdrawEnabled: boolean; + rais: any; + requestedDate: number; + responseDate: number; + state: string; + submitterEmail: string; + submitterName: string; + withdrawnDate: number; +}; + +export type Response = Res; +export type ItemResult = Hit & { + found: boolean; +}; + +export type Field = keyof Document | `${keyof Document}.keyword`; +export type Filterable = FIL; +export type State = QueryState; +export type Aggs = AggQuery; diff --git a/src/packages/shared-types/opensearch/index.ts b/src/packages/shared-types/opensearch/index.ts new file mode 100644 index 0000000000..36c6bf521b --- /dev/null +++ b/src/packages/shared-types/opensearch/index.ts @@ -0,0 +1,3 @@ +export * as changelog from "./changelog"; +export * as main from "./main"; +export * from "./_"; diff --git a/src/packages/shared-types/opensearch/main.ts b/src/packages/shared-types/opensearch/main.ts new file mode 100644 index 0000000000..79c38048b0 --- /dev/null +++ b/src/packages/shared-types/opensearch/main.ts @@ -0,0 +1,38 @@ +import { + SeaToolTransform, + OnemacTransform, + OnemacLegacyTransform, + RaiIssueTransform, + RaiResponseTransform, + RaiWithdrawTransform, + WithdrawPackageTransform, + ToggleWithdrawRaiEnabledTransform, +} from ".."; + +import { + Response as Res, + Hit, + Filterable as FIL, + QueryState, + AggQuery, +} from "./_"; +import { ItemResult as Changelog } from "./changelog"; + +export type Document = OnemacTransform & + OnemacLegacyTransform & + SeaToolTransform & + RaiIssueTransform & + RaiResponseTransform & + RaiWithdrawTransform & + WithdrawPackageTransform & + ToggleWithdrawRaiEnabledTransform & { changelog?: Changelog[] }; + +export type Response = Res; +export type ItemResult = Hit & { + found: boolean; +}; + +export type Field = keyof Document | `${keyof Document}.keyword`; +export type Filterable = FIL; +export type State = QueryState; +export type Aggs = AggQuery; diff --git a/src/packages/shared-utils/package-actions/getAvailableActions.ts b/src/packages/shared-utils/package-actions/getAvailableActions.ts index 2cd1d41acc..c31844708d 100644 --- a/src/packages/shared-utils/package-actions/getAvailableActions.ts +++ b/src/packages/shared-utils/package-actions/getAvailableActions.ts @@ -1,14 +1,14 @@ import { CognitoUserAttributes, - OsMainSourceItem, PlanType, + opensearch } from "../../shared-types"; import rules from "./rules"; import { PackageCheck } from "../packageCheck"; export const getAvailableActions = ( user: CognitoUserAttributes, - result: OsMainSourceItem + result: opensearch.main.Document ) => { const checks = PackageCheck(result); return checks.planTypeIs([PlanType.MED_SPA]) diff --git a/src/packages/shared-utils/packageCheck.ts b/src/packages/shared-utils/packageCheck.ts index 9afcbf44c7..8ea974f06b 100644 --- a/src/packages/shared-utils/packageCheck.ts +++ b/src/packages/shared-utils/packageCheck.ts @@ -1,4 +1,4 @@ -import { OsMainSourceItem, PlanType, SEATOOL_STATUS } from "../shared-types"; +import { opensearch, PlanType, SEATOOL_STATUS } from "../shared-types"; import { getLatestRai } from "./rai-helper"; const secondClockStatuses = [ @@ -24,7 +24,7 @@ export const PackageCheck = ({ rais, raiWithdrawEnabled, planType, -}: OsMainSourceItem) => { +}: opensearch.main.Document) => { const latestRai = getLatestRai(rais); const planChecks = { isSpa: checkPlan(planType, [PlanType.MED_SPA, PlanType.CHIP_SPA]), diff --git a/src/services/api/handlers/getAttachmentUrl.ts b/src/services/api/handlers/getAttachmentUrl.ts index 45cd592dae..df73631731 100644 --- a/src/services/api/handlers/getAttachmentUrl.ts +++ b/src/services/api/handlers/getAttachmentUrl.ts @@ -6,7 +6,7 @@ import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import * as os from "./../../../libs/opensearch-lib"; import { getStateFilter } from "../libs/auth/user"; -import { OsMainSourceItem, OsResponse } from "shared-types"; +import { opensearch } from "shared-types"; if (!process.env.osDomain) { throw "ERROR: osDomain env variable is required,"; } @@ -52,7 +52,7 @@ export const handler = async (event: APIGatewayEvent) => { process.env.osDomain, "main", query - )) as OsResponse; + )) as opensearch.Response; if (!results) { return response({ diff --git a/src/services/api/handlers/item.ts b/src/services/api/handlers/item.ts index 55ca1543c7..de71ae87ab 100644 --- a/src/services/api/handlers/item.ts +++ b/src/services/api/handlers/item.ts @@ -1,8 +1,7 @@ import { response } from "../libs/handler"; import { APIGatewayEvent } from "aws-lambda"; import { getStateFilter } from "../libs/auth/user"; -import { getPackage } from "../libs/package/getPackage"; - +import { getPackage, getPackageChangelog } from "../libs/package"; if (!process.env.osDomain) { throw "ERROR: osDomain env variable is required,"; } @@ -17,13 +16,13 @@ export const getItemData = async (event: APIGatewayEvent) => { try { const body = JSON.parse(event.body); const stateFilter = await getStateFilter(event); - const result = await getPackage(body.id); - + const packageResult = await getPackage(body.id); + const changelog = await getPackageChangelog(body.id); if ( stateFilter && - (!result._source.state || + (!packageResult._source.state || !stateFilter.terms.state.includes( - result._source.state.toLocaleLowerCase() + packageResult._source.state.toLocaleLowerCase() )) ) { return response({ @@ -32,17 +31,20 @@ export const getItemData = async (event: APIGatewayEvent) => { }); } - if (!result.found) { + if (!packageResult.found) { return response({ statusCode: 404, body: { message: "No record found for the given id" }, }); - } else { - return response({ - statusCode: 200, - body: result, - }); } + + return response({ + statusCode: 200, + body: { + ...packageResult, + _source: { ...packageResult._source, changelog: changelog.hits.hits }, + }, + }); } catch (error) { console.error({ error }); return response({ diff --git a/src/services/api/handlers/search.ts b/src/services/api/handlers/search.ts index 813b3bd97e..cceec30006 100644 --- a/src/services/api/handlers/search.ts +++ b/src/services/api/handlers/search.ts @@ -8,6 +8,12 @@ if (!process.env.osDomain) { // Handler function to search index export const getSearchData = async (event: APIGatewayEvent) => { + if (!event.pathParameters || !event.pathParameters.index) { + return response({ + statusCode: 400, + body: { message: "Index path parameter required" }, + }); + } try { let query: any = {}; if (event.body) { @@ -35,7 +41,11 @@ export const getSearchData = async (event: APIGatewayEvent) => { }); } - const results = await os.search(process.env.osDomain, "main", query); + const results = await os.search( + process.env.osDomain, + event.pathParameters.index as any, + query + ); return response({ statusCode: 200, body: results, diff --git a/src/services/api/libs/package/changelog.ts b/src/services/api/libs/package/changelog.ts new file mode 100644 index 0000000000..578ffaaf59 --- /dev/null +++ b/src/services/api/libs/package/changelog.ts @@ -0,0 +1,15 @@ +import * as os from "../../../../libs/opensearch-lib"; +import { opensearch } from "shared-types"; + +export const getPackageChangelog = async (packageId: string) => { + if (!process.env.osDomain) { + throw new Error("process.env.osDomain must be defined"); + } + + return (await os.search(process.env.osDomain, "changelog", { + from: 0, + size: 200, + sort: [{ timestamp: "desc" }], + query: { bool: { must: [{ term: { "packageId.keyword": packageId } }] } }, + })) as opensearch.changelog.Response; +}; diff --git a/src/services/api/libs/package/getPackage.ts b/src/services/api/libs/package/getPackage.ts index 887000a4f7..92c824667f 100644 --- a/src/services/api/libs/package/getPackage.ts +++ b/src/services/api/libs/package/getPackage.ts @@ -1,9 +1,13 @@ import * as os from "../../../../libs/opensearch-lib"; -import { ItemResult } from "shared-types"; +import { opensearch } from "shared-types"; export const getPackage = async (id: string) => { if (!process.env.osDomain) { throw new Error("process.env.osDomain must be defined"); } - return (await os.getItem(process.env.osDomain, "main", id)) as ItemResult; + return (await os.getItem( + process.env.osDomain, + "main", + id + )) as opensearch.main.ItemResult; }; diff --git a/src/services/api/libs/package/index.ts b/src/services/api/libs/package/index.ts new file mode 100644 index 0000000000..a82b6b308d --- /dev/null +++ b/src/services/api/libs/package/index.ts @@ -0,0 +1,2 @@ +export * from "./changelog"; +export * from "./getPackage"; diff --git a/src/services/api/serverless.yml b/src/services/api/serverless.yml index 38b30a7db1..4862087167 100644 --- a/src/services/api/serverless.yml +++ b/src/services/api/serverless.yml @@ -107,7 +107,7 @@ functions: osDomain: ${param:osDomain} events: - http: - path: /search + path: /search/{index} method: post cors: true authorizer: aws_iam diff --git a/src/services/data/handlers/index.ts b/src/services/data/handlers/index.ts index c63596f2ba..e2804e89d3 100644 --- a/src/services/data/handlers/index.ts +++ b/src/services/data/handlers/index.ts @@ -2,7 +2,7 @@ import { Handler } from "aws-lambda"; import { send, SUCCESS, FAILED } from "cfn-response-async"; type ResponseStatus = typeof SUCCESS | typeof FAILED; import * as os from "./../../../libs/opensearch-lib"; -import { OsIndex } from "shared-types"; +import { opensearch } from "shared-types"; export const customResourceWrapper: Handler = async (event, context) => { console.log("request:", JSON.stringify(event, undefined, 2)); @@ -26,7 +26,7 @@ export const handler: Handler = async () => { }; const manageIndexResource = async (resource: { - index: OsIndex; + index: opensearch.Index; update?: object; }) => { if (!process.env.osDomain) { @@ -53,12 +53,12 @@ async function manageIndex() { try { await manageIndexResource({ index: "main", + // TODO: remove after rai transform update: { rais: { type: "object", enabled: false } }, }); - await manageIndexResource({ - index: "changelog", - }); + await manageIndexResource({ index: "changelog" }); + await manageIndexResource({ index: "seatool" }); } catch (error) { console.log(error); throw "ERROR: Error occured during index management."; diff --git a/src/services/data/handlers/reindex.ts b/src/services/data/handlers/reindex.ts index 419c0bb2f9..c79b4e04aa 100644 --- a/src/services/data/handlers/reindex.ts +++ b/src/services/data/handlers/reindex.ts @@ -133,6 +133,8 @@ export const deleteIndex: Handler = async () => { throw "process.env.osDomain cannot be undefined"; } await os.deleteIndex(process.env.osDomain, "main"); + await os.deleteIndex(process.env.osDomain, "changelog"); + await os.deleteIndex(process.env.osDomain, "seatool"); } catch (error: any) { if (error.meta.body.error.type == "index_not_found_exception") { console.log("Index does not exist."); diff --git a/src/services/data/handlers/sink.ts b/src/services/data/handlers/sink.ts index 4992ae377e..aca0548aad 100644 --- a/src/services/data/handlers/sink.ts +++ b/src/services/data/handlers/sink.ts @@ -146,17 +146,22 @@ export const onemacDataTransform = (props: { key: string; value?: string }) => { const record = { id, ...JSON.parse(decode(props.value)) }; // is Legacy - if (record?.origin !== "micro") { - if (record?.sk !== "Package") return null; - if (!record.submitterName) return null; - if (record.submitterName === "-- --") return null; + const isLegacy = record?.origin !== "micro"; + if (isLegacy) { + const notPackageView = record?.sk !== "Package"; + if (notPackageView) return null; + + const notOriginatingFromOnemacLegacy = + !record.submitterName || record.submitterName === "-- --"; + if (notOriginatingFromOnemacLegacy) return null; const result = transformOnemacLegacy(id).safeParse(record); return result.success ? result.data : null; } - // is new create - if (!record?.actionType) { + // NOTE: Make official decision on initial type by MVP - timebomb + const isNewRecord = !record?.actionType; + if (isNewRecord) { const result = transformOnemac(id).safeParse(record); return result.success ? result.data : null; } @@ -164,32 +169,31 @@ export const onemacDataTransform = (props: { key: string; value?: string }) => { // --------- Package-Actions ---------// // TODO: remove transform package-action below - //ENABLE_RAI_WITHDRAW if (record.actionType === Action.ENABLE_RAI_WITHDRAW) { const result = transformToggleWithdrawRaiEnabled(id).safeParse(record); return result.success ? result.data : null; } - //DISABLE_RAI_WITHDRAW + if (record.actionType === Action.DISABLE_RAI_WITHDRAW) { const result = transformToggleWithdrawRaiEnabled(id).safeParse(record); return result.success ? result.data : null; } - //ISSUE_RAI + if (record.actionType === Action.ISSUE_RAI) { const result = transformRaiIssue(id).safeParse(record); return result.success ? result.data : null; } - //RESPOND_TO_RAI + if (record.actionType === Action.RESPOND_TO_RAI) { const result = transformRaiResponse(id).safeParse(record); return result.success ? result.data : null; } - //WITHDRAW_RAI + if (record.actionType === Action.WITHDRAW_RAI) { const result = transformRaiWithdraw(id).safeParse(record); return result.success ? result.data : null; } - //WITHDRAW_PACKAGE + if (record.actionType === Action.WITHDRAW_PACKAGE) { const result = transformWithdrawPackage(id).safeParse(record); return result.success ? result.data : null; @@ -219,11 +223,11 @@ export const onemac_main = async (event: Event) => { export const onemac_changelog = async (event: Event) => { const data = Object.values(event.records).reduce((ACC, RECORDS) => { RECORDS.forEach((REC) => { - // omit delete + // omit delete event if (!REC.value) return; const record = JSON.parse(decode(REC.value)); - // omit legacy + // omit legacy record if (record?.origin !== "micro") return; // include package actions @@ -231,6 +235,7 @@ export const onemac_changelog = async (event: Event) => { ACC.push({ ...record, ...(!record?.actionType && { actionType: "new-submission" }), // new-submission custom actionType + timestamp: REC.timestamp, id: `${packageId}-${REC.offset}`, packageId, }); diff --git a/src/services/ui/src/api/useGetItem.ts b/src/services/ui/src/api/useGetItem.ts index 12371aeae5..0d65819f93 100644 --- a/src/services/ui/src/api/useGetItem.ts +++ b/src/services/ui/src/api/useGetItem.ts @@ -1,8 +1,10 @@ import { useQuery, UseQueryOptions } from "@tanstack/react-query"; import { API } from "aws-amplify"; -import { ItemResult, ReactQueryApiError } from "shared-types"; +import { opensearch, ReactQueryApiError } from "shared-types"; -export const getItem = async (id: string): Promise => +export const getItem = async ( + id: string +): Promise => await API.post("os", "/item", { body: { id } }); export const idIsUnique = async (id: string) => { @@ -16,9 +18,9 @@ export const idIsUnique = async (id: string) => { export const useGetItem = ( id: string, - options?: UseQueryOptions + options?: UseQueryOptions ) => { - return useQuery( + return useQuery( ["record", id], () => getItem(id), options diff --git a/src/services/ui/src/api/useSearch.ts b/src/services/ui/src/api/useSearch.ts index 5e5f9504b9..992268d490 100644 --- a/src/services/ui/src/api/useSearch.ts +++ b/src/services/ui/src/api/useSearch.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ import { aggQueryBuilder, filterQueryBuilder, @@ -6,26 +7,23 @@ import { } from "@/components/Opensearch/utils"; import { useMutation, UseMutationOptions } from "@tanstack/react-query"; import { API } from "aws-amplify"; -import type { - OsQueryState, - ReactQueryApiError, - OsFilterable, - OsAggQuery, - OsMainSearchResponse, - OsMainSourceItem, -} from "shared-types"; +import type { ReactQueryApiError, opensearch } from "shared-types"; -type QueryProps = { - filters: OsQueryState["filters"]; - sort?: OsQueryState["sort"]; - pagination: OsQueryState["pagination"]; - aggs?: OsAggQuery[]; +type QueryProps = { + index: opensearch.Index; + filters: opensearch.QueryState["filters"]; + sort?: opensearch.QueryState["sort"]; + pagination: opensearch.QueryState["pagination"]; + aggs?: opensearch.AggQuery[]; }; -export const getSearchData = async ( - props: QueryProps -): Promise => { - const searchData = await API.post("os", "/search", { +export const getOsData = async < + TProps, + TResponse extends opensearch.Response +>( + props: QueryProps +): Promise => { + const searchData = await API.post("os", `/search/${props.index}`, { body: { ...filterQueryBuilder(props.filters), ...paginationQueryBuilder(props.pagination), @@ -38,17 +36,19 @@ export const getSearchData = async ( return searchData; }; -export const getAllSearchData = async (filters?: OsFilterable[]) => { +export const getMainExportData = async ( + filters?: opensearch.main.Filterable[] +) => { if (!filters) return []; const recursiveSearch = async ( startPage: number - ): Promise => { + ): Promise => { if (startPage * 1000 >= 10000) { return []; } - const searchData = await API.post("os", "/search", { + const searchData = await API.post("os", "/search/main", { body: { ...filterQueryBuilder(filters), ...paginationQueryBuilder({ number: startPage, size: 1000 }), @@ -69,15 +69,30 @@ export const getAllSearchData = async (filters?: OsFilterable[]) => { return await recursiveSearch(0); }; -export const useOsSearch = ( +export const useOsSearch = ( options?: UseMutationOptions< - OsMainSearchResponse, + TResponse, ReactQueryApiError, - QueryProps + QueryProps > ) => { - return useMutation( - (props) => getSearchData(props), + //@ts-ignore + return useMutation>( + (props) => getOsData(props), options ); }; + +export const useChangelogSearch = ( + options?: UseMutationOptions< + opensearch.changelog.Response, + ReactQueryApiError, + QueryProps + > +) => { + return useMutation< + opensearch.changelog.Response, + ReactQueryApiError, + QueryProps + >((props) => getOsData(props), options); +}; diff --git a/src/services/ui/src/components/AdditionalInfo/index.tsx b/src/services/ui/src/components/AdditionalInfo/index.tsx index 5c7600a9f2..e27edc3871 100644 --- a/src/services/ui/src/components/AdditionalInfo/index.tsx +++ b/src/services/ui/src/components/AdditionalInfo/index.tsx @@ -1,9 +1,9 @@ -import { OsMainSourceItem } from "shared-types"; +import { opensearch } from "shared-types"; export const AdditionalInfo = ({ additionalInformation, }: { - additionalInformation: OsMainSourceItem["additionalInformation"]; + additionalInformation: opensearch.main.Document["additionalInformation"]; }) => { return (
diff --git a/src/services/ui/src/components/AttachmentsList/index.tsx b/src/services/ui/src/components/AttachmentsList/index.tsx index ffd2d9c837..b5afd69640 100644 --- a/src/services/ui/src/components/AttachmentsList/index.tsx +++ b/src/services/ui/src/components/AttachmentsList/index.tsx @@ -4,7 +4,7 @@ import { BLANK_VALUE } from "@/consts"; import { DownloadIcon } from "lucide-react"; import JSZip from "jszip"; import { saveAs } from "file-saver"; -import { OsMainSourceItem } from "shared-types"; +import { opensearch } from "shared-types"; import { useState } from "react"; import { Button } from "../Inputs/button"; import { @@ -122,7 +122,7 @@ export const Attachmentslist = (data: AttachmentList) => { }; async function downloadAll( - attachments: OsMainSourceItem["attachments"], + attachments: opensearch.main.Document["attachments"], id: string ) { if (!attachments) return null; diff --git a/src/services/ui/src/components/DetailsSection/index.tsx b/src/services/ui/src/components/DetailsSection/index.tsx index c3e1ccf9f1..c3f22d0a88 100644 --- a/src/services/ui/src/components/DetailsSection/index.tsx +++ b/src/services/ui/src/components/DetailsSection/index.tsx @@ -1,6 +1,6 @@ interface DetailsSectionProps { children: React.ReactNode; - title: string; + title: React.ReactNode; id: string; description?: string; } @@ -12,8 +12,10 @@ export const DetailsSection: React.FC = ({ id, }: DetailsSectionProps) => { return ( -
+

{title}

+
+ {description &&

{description}

} {children} diff --git a/src/services/ui/src/components/ExportButton/index.tsx b/src/services/ui/src/components/ExportButton/index.tsx index 1a0a30b497..9465a2aeaa 100644 --- a/src/services/ui/src/components/ExportButton/index.tsx +++ b/src/services/ui/src/components/ExportButton/index.tsx @@ -4,12 +4,12 @@ import { Download, Loader } from "lucide-react"; import { useState } from "react"; import { motion } from "framer-motion"; import { format } from "date-fns"; -import { useOsUrl } from "../Opensearch"; -import { OsExportHeaderOptions } from "shared-types"; +import { useOsUrl } from "@/components/Opensearch/main"; +import { opensearch } from "shared-types"; type Props> = { data: TData[] | (() => Promise); - headers: OsExportHeaderOptions[]; + headers: opensearch.ExportHeaderOptions[]; // | Record> }; diff --git a/src/services/ui/src/components/Opensearch/changelog/index.ts b/src/services/ui/src/components/Opensearch/changelog/index.ts new file mode 100644 index 0000000000..c50c39f0c2 --- /dev/null +++ b/src/services/ui/src/components/Opensearch/changelog/index.ts @@ -0,0 +1 @@ +export const _ = "filler "; diff --git a/src/services/ui/src/components/Opensearch/index.ts b/src/services/ui/src/components/Opensearch/index.ts index aecfc92713..178cd64f81 100644 --- a/src/services/ui/src/components/Opensearch/index.ts +++ b/src/services/ui/src/components/Opensearch/index.ts @@ -1,5 +1 @@ -export * from "./useOpensearch"; -export * from "./types"; -export * from "./Table"; -export * from "./Filtering"; -export * from "./Provider"; +export * from "./utils"; diff --git a/src/services/ui/src/components/Opensearch/Filtering/FilterChips.tsx b/src/services/ui/src/components/Opensearch/main/Filtering/FilterChips.tsx similarity index 83% rename from src/services/ui/src/components/Opensearch/Filtering/FilterChips.tsx rename to src/services/ui/src/components/Opensearch/main/Filtering/FilterChips.tsx index c24f768079..a49871565a 100644 --- a/src/services/ui/src/components/Opensearch/Filtering/FilterChips.tsx +++ b/src/services/ui/src/components/Opensearch/main/Filtering/FilterChips.tsx @@ -1,17 +1,17 @@ import { type FC, useCallback, Fragment } from "react"; import { Chip } from "@/components/Chip"; -import { useOsUrl } from "@/components/Opensearch"; -import { OsFilterable, OsRangeValue } from "shared-types"; +import { useOsUrl } from "@/components/Opensearch/main"; +import { opensearch } from "shared-types"; import { useFilterDrawerContext } from "./FilterProvider"; -import { checkMultiFilter, resetFilters } from "../utils"; +import { checkMultiFilter } from "@/components/Opensearch"; import { useLabelMapping } from "@/hooks"; interface RenderProp { - filter: OsFilterable; + filter: opensearch.main.Filterable; index: number; openDrawer: () => void; - clearFilter: (filter: OsFilterable, valIndex?: number) => void; + clearFilter: (filter: opensearch.main.Filterable, valIndex?: number) => void; } // simple date range chips @@ -21,7 +21,7 @@ const DateChip: FC = ({ openDrawer, clearFilter, }) => { - const value = filter.value as OsRangeValue; + const value = filter.value as opensearch.RangeValue; return ( { const openDrawer = useCallback(() => setDrawerState(true), [setDrawerState]); const twoOrMoreFiltersApplied = checkMultiFilter(url.state.filters, 2); - const clearFilter = (filter: OsFilterable, valIndex?: number) => { + const clearFilter = ( + filter: opensearch.main.Filterable, + valIndex?: number + ) => { url.onSet((s) => { let filters = s.filters; const filterIndex = filters.findIndex((f) => f.field === filter.field); @@ -98,7 +101,12 @@ export const FilterChips: FC = () => { }); }; - const handleChipClick = () => resetFilters(url.onSet); + const handleChipClick = () => + url.onSet((s) => ({ + ...s, + filters: [], + pagination: { ...s.pagination, number: 0 }, + })); return (
diff --git a/src/services/ui/src/components/Opensearch/Filtering/FilterDrawer.tsx b/src/services/ui/src/components/Opensearch/main/Filtering/FilterDrawer.tsx similarity index 86% rename from src/services/ui/src/components/Opensearch/Filtering/FilterDrawer.tsx rename to src/services/ui/src/components/Opensearch/main/Filtering/FilterDrawer.tsx index 59afaf7f08..d87efa6ac6 100644 --- a/src/services/ui/src/components/Opensearch/Filtering/FilterDrawer.tsx +++ b/src/services/ui/src/components/Opensearch/main/Filtering/FilterDrawer.tsx @@ -1,5 +1,5 @@ import { FilterIcon } from "lucide-react"; -import { OsRangeValue } from "shared-types"; +import { opensearch } from "shared-types"; import { Sheet, @@ -19,15 +19,20 @@ import { FilterableDateRange } from "./FilterableDateRange"; import { FilterableCheckbox } from "./FilterableCheckbox"; import { useFilterDrawer } from "./useFilterDrawer"; import { Button } from "@/components/Inputs"; -import { checkMultiFilter, resetFilters } from "../utils"; -import { useOsUrl } from "../useOpensearch"; +import { checkMultiFilter } from "@/components/Opensearch"; +import { useOsUrl } from "@/components/Opensearch/main"; export const OsFilterDrawer = () => { const hook = useFilterDrawer(); const url = useOsUrl(); const filtersApplied = checkMultiFilter(url.state.filters, 1); - const handleFilterReset = () => resetFilters(url.onSet); + const handleFilterReset = () => + url.onSet((s) => ({ + ...s, + filters: [], + pagination: { ...s.pagination, number: 0 }, + })); return ( @@ -78,7 +83,9 @@ export const OsFilterDrawer = () => { )} {PK.component === "dateRange" && ( )} diff --git a/src/services/ui/src/components/Opensearch/Filtering/FilterProvider.tsx b/src/services/ui/src/components/Opensearch/main/Filtering/FilterProvider.tsx similarity index 100% rename from src/services/ui/src/components/Opensearch/Filtering/FilterProvider.tsx rename to src/services/ui/src/components/Opensearch/main/Filtering/FilterProvider.tsx diff --git a/src/services/ui/src/components/Opensearch/Filtering/FilterableCheckbox.tsx b/src/services/ui/src/components/Opensearch/main/Filtering/FilterableCheckbox.tsx similarity index 100% rename from src/services/ui/src/components/Opensearch/Filtering/FilterableCheckbox.tsx rename to src/services/ui/src/components/Opensearch/main/Filtering/FilterableCheckbox.tsx diff --git a/src/services/ui/src/components/Opensearch/Filtering/FilterableDateRange.tsx b/src/services/ui/src/components/Opensearch/main/Filtering/FilterableDateRange.tsx similarity index 96% rename from src/services/ui/src/components/Opensearch/Filtering/FilterableDateRange.tsx rename to src/services/ui/src/components/Opensearch/main/Filtering/FilterableDateRange.tsx index 7d624208f6..9aa3e61775 100644 --- a/src/services/ui/src/components/Opensearch/Filtering/FilterableDateRange.tsx +++ b/src/services/ui/src/components/Opensearch/main/Filtering/FilterableDateRange.tsx @@ -18,14 +18,14 @@ import { DateRange } from "react-day-picker"; import { cn } from "@/lib/utils"; import { Button, Calendar, Input } from "@/components/Inputs"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/Popover"; -import { OsRangeValue } from "shared-types"; +import { opensearch } from "shared-types"; type Props = Omit< React.HTMLAttributes, "onChange" | "value" | "onSelect" > & { - value: OsRangeValue; - onChange: (val: OsRangeValue) => void; + value: opensearch.RangeValue; + onChange: (val: opensearch.RangeValue) => void; className?: string; }; @@ -113,7 +113,10 @@ export function FilterableDateRange({ value, onChange, ...props }: Props) { } }; - const getDateRange = (startDate: Date, endDate: Date): OsRangeValue => { + const getDateRange = ( + startDate: Date, + endDate: Date + ): opensearch.RangeValue => { return { gte: startDate.toISOString(), lte: endDate.toISOString(), diff --git a/src/services/ui/src/components/Opensearch/Filtering/FilterableSelect.tsx b/src/services/ui/src/components/Opensearch/main/Filtering/FilterableSelect.tsx similarity index 100% rename from src/services/ui/src/components/Opensearch/Filtering/FilterableSelect.tsx rename to src/services/ui/src/components/Opensearch/main/Filtering/FilterableSelect.tsx diff --git a/src/services/ui/src/components/Opensearch/Filtering/consts.ts b/src/services/ui/src/components/Opensearch/main/Filtering/consts.ts similarity index 95% rename from src/services/ui/src/components/Opensearch/Filtering/consts.ts rename to src/services/ui/src/components/Opensearch/main/Filtering/consts.ts index b0f92db23c..25a53009d6 100644 --- a/src/services/ui/src/components/Opensearch/Filtering/consts.ts +++ b/src/services/ui/src/components/Opensearch/main/Filtering/consts.ts @@ -1,9 +1,4 @@ -import { - OsExportHeaderOptions, - OsField, - OsFilterable, - OsMainSourceItem, -} from "shared-types"; +import { opensearch } from "shared-types"; import { OsFilterComponentType, OsTab } from "../types"; import { UserRoles } from "shared-types"; import { BLANK_VALUE } from "@/consts"; @@ -15,7 +10,10 @@ type DrawerFilterableGroup = { component: OsFilterComponentType; }; type FilterGroup = Partial< - Record + Record< + opensearch.main.Field, + opensearch.main.Filterable & DrawerFilterableGroup + > >; const SPA_FILTER_GROUP = (isCms: boolean): FilterGroup => { @@ -175,10 +173,10 @@ export const FILTER_GROUPS = (user?: any, tab?: OsTab): FilterGroup => { export const EXPORT_GROUPS = ( tab: OsTab, user?: any -): OsExportHeaderOptions[] => { +): opensearch.ExportHeaderOptions[] => { const idFieldName = tab === "spas" ? "SPA ID" : tab === "waivers" ? "Waiver Number" : ""; - const actionField: OsExportHeaderOptions[] = + const actionField: opensearch.ExportHeaderOptions[] = tab === "waivers" ? [ { diff --git a/src/services/ui/src/components/Opensearch/Filtering/index.tsx b/src/services/ui/src/components/Opensearch/main/Filtering/index.tsx similarity index 91% rename from src/services/ui/src/components/Opensearch/Filtering/index.tsx rename to src/services/ui/src/components/Opensearch/main/Filtering/index.tsx index c0a88b43cb..6d6c71d7d8 100644 --- a/src/services/ui/src/components/Opensearch/Filtering/index.tsx +++ b/src/services/ui/src/components/Opensearch/main/Filtering/index.tsx @@ -4,7 +4,7 @@ import { DEFAULT_FILTERS, useOsUrl } from "../useOpensearch"; import { ExportButton } from "@/components/ExportButton"; import { useOsContext } from "../Provider"; import { OsFilterDrawer } from "./FilterDrawer"; -import { getAllSearchData } from "@/api"; +import { getMainExportData } from "@/api"; import { useGetUser } from "@/api/useGetUser"; import { EXPORT_GROUPS } from "./consts"; @@ -35,7 +35,7 @@ export const OsFiltering: FC<{ />
getAllSearchData([...url.state.filters, ...filters])} + data={() => getMainExportData([...url.state.filters, ...filters])} headers={EXPORT_GROUPS(url.state.tab, user)} /> diff --git a/src/services/ui/src/components/Opensearch/Filtering/useFilterDrawer.ts b/src/services/ui/src/components/Opensearch/main/Filtering/useFilterDrawer.ts similarity index 88% rename from src/services/ui/src/components/Opensearch/Filtering/useFilterDrawer.ts rename to src/services/ui/src/components/Opensearch/main/Filtering/useFilterDrawer.ts index 296d4bea1b..1bd98cc9ba 100644 --- a/src/services/ui/src/components/Opensearch/Filtering/useFilterDrawer.ts +++ b/src/services/ui/src/components/Opensearch/main/Filtering/useFilterDrawer.ts @@ -1,8 +1,8 @@ import { useState, useEffect, useMemo } from "react"; -import type { OsField } from "../types"; + import * as Consts from "./consts"; import { useOsAggregate, useOsUrl } from "../useOpensearch"; -import { OsFilterValue, OsRangeValue } from "shared-types"; +import { opensearch } from "shared-types"; import { useLabelMapping } from "@/hooks"; import { useFilterDrawerContext } from "./FilterProvider"; import { useGetUser } from "@/api/useGetUser"; @@ -18,8 +18,8 @@ export const useFilterDrawer = () => { const labelMap = useLabelMapping(); const _aggs = useOsAggregate(); - const onFilterChange = (field: OsField) => { - return (value: OsFilterValue) => { + const onFilterChange = (field: opensearch.main.Field) => { + return (value: opensearch.FilterValue) => { setFilters((state) => { const updateState = { ...state, [field]: { ...state[field], value } }; const updateFilters = Object.values(updateState).filter((FIL) => { @@ -29,7 +29,7 @@ export const useFilterDrawer = () => { } if (FIL.type === "range") { - const value = FIL.value as OsRangeValue; + const value = FIL.value as opensearch.RangeValue; return !!value?.gte && !!value?.lte; } @@ -66,7 +66,7 @@ export const useFilterDrawer = () => { return updateFilter.value; } if (VAL.type === "terms") return [] as string[]; - return { gte: undefined, lte: undefined } as OsRangeValue; + return { gte: undefined, lte: undefined } as opensearch.RangeValue; })(); STATE[KEY] = { ...VAL, value }; @@ -91,7 +91,7 @@ export const useFilterDrawer = () => { value: BUCK.key, })), }; - }, {} as Record); + }, {} as Record); }, [_aggs]); return { diff --git a/src/services/ui/src/components/Opensearch/Provider/index.tsx b/src/services/ui/src/components/Opensearch/main/Provider/index.tsx similarity index 80% rename from src/services/ui/src/components/Opensearch/Provider/index.tsx rename to src/services/ui/src/components/Opensearch/main/Provider/index.tsx index b89793547c..750b00d57d 100644 --- a/src/services/ui/src/components/Opensearch/Provider/index.tsx +++ b/src/services/ui/src/components/Opensearch/main/Provider/index.tsx @@ -1,9 +1,9 @@ import { ReactNode } from "react"; import { createContextProvider } from "@/utils"; -import { ReactQueryApiError, SearchData } from "shared-types"; +import { ReactQueryApiError, opensearch } from "shared-types"; type ContextState = { - data: SearchData | undefined; + data: opensearch.main.Response["hits"] | undefined; isLoading: boolean; error: ReactQueryApiError | null; }; diff --git a/src/services/ui/src/components/Opensearch/Settings/Visibility.tsx b/src/services/ui/src/components/Opensearch/main/Settings/Visibility.tsx similarity index 100% rename from src/services/ui/src/components/Opensearch/Settings/Visibility.tsx rename to src/services/ui/src/components/Opensearch/main/Settings/Visibility.tsx diff --git a/src/services/ui/src/components/Opensearch/Settings/index.ts b/src/services/ui/src/components/Opensearch/main/Settings/index.ts similarity index 100% rename from src/services/ui/src/components/Opensearch/Settings/index.ts rename to src/services/ui/src/components/Opensearch/main/Settings/index.ts diff --git a/src/services/ui/src/components/Opensearch/Table/index.tsx b/src/services/ui/src/components/Opensearch/main/Table/index.tsx similarity index 95% rename from src/services/ui/src/components/Opensearch/Table/index.tsx rename to src/services/ui/src/components/Opensearch/main/Table/index.tsx index 1b614d5668..9032ce8e20 100644 --- a/src/services/ui/src/components/Opensearch/Table/index.tsx +++ b/src/services/ui/src/components/Opensearch/main/Table/index.tsx @@ -3,10 +3,10 @@ import { LoadingSpinner } from "@/components/LoadingSpinner"; import { FC, useState } from "react"; import { OsTableColumn } from "./types"; import { useOsContext } from "../Provider"; -import { useOsUrl } from "../useOpensearch"; +import { useOsUrl } from "@/components/Opensearch/main"; import { VisibilityPopover } from "../Settings"; import { BLANK_VALUE } from "@/consts"; -import { OsField } from "shared-types"; +import { opensearch } from "shared-types"; export const OsTable: FC<{ columns: OsTableColumn[]; @@ -59,7 +59,7 @@ export const OsTable: FC<{ url.onSet((s) => ({ ...s, sort: { - field: TH.field as OsField, + field: TH.field as opensearch.main.Field, order: s.sort.order === "desc" ? "asc" : "desc", }, })); diff --git a/src/services/ui/src/components/Opensearch/Table/types.ts b/src/services/ui/src/components/Opensearch/main/Table/types.ts similarity index 52% rename from src/services/ui/src/components/Opensearch/Table/types.ts rename to src/services/ui/src/components/Opensearch/main/Table/types.ts index c365e3b020..6d34056de0 100644 --- a/src/services/ui/src/components/Opensearch/Table/types.ts +++ b/src/services/ui/src/components/Opensearch/main/Table/types.ts @@ -1,12 +1,12 @@ -import type { OsField, OsHit, OsMainSourceItem } from "shared-types"; +import type { opensearch } from "shared-types"; import type { ReactNode } from "react"; export type OsTableColumn = { - field?: OsField; + field?: opensearch.main.Field; label: string; visible?: boolean; locked?: boolean; isSystem?: boolean; props?: any; - cell: (data: OsHit["_source"]) => ReactNode; + cell: (data: opensearch.main.Document) => ReactNode; }; diff --git a/src/services/ui/src/components/Opensearch/main/index.ts b/src/services/ui/src/components/Opensearch/main/index.ts new file mode 100644 index 0000000000..aecfc92713 --- /dev/null +++ b/src/services/ui/src/components/Opensearch/main/index.ts @@ -0,0 +1,5 @@ +export * from "./useOpensearch"; +export * from "./types"; +export * from "./Table"; +export * from "./Filtering"; +export * from "./Provider"; diff --git a/src/services/ui/src/components/Opensearch/types.ts b/src/services/ui/src/components/Opensearch/main/types.ts similarity index 51% rename from src/services/ui/src/components/Opensearch/types.ts rename to src/services/ui/src/components/Opensearch/main/types.ts index 4541d7170b..84e9981808 100644 --- a/src/services/ui/src/components/Opensearch/types.ts +++ b/src/services/ui/src/components/Opensearch/main/types.ts @@ -1,13 +1,13 @@ -import type { OsField, OsFilterable } from "shared-types"; +import type { opensearch } from "shared-types"; -export type OsDrawerFilterable = OsFilterable & { open: boolean }; +export type OsDrawerFilterable = opensearch.main.Filterable & { open: boolean }; export type OsFilterComponentType = "multiSelect" | "multiCheck" | "dateRange"; export type OsFilterGroup = { label: string; - field: OsField; + field: opensearch.main.Field; type: OsFilterComponentType; }; export type OsTab = "waivers" | "spas"; -export { OsField }; +export * from "./Table/types"; diff --git a/src/services/ui/src/components/Opensearch/useOpensearch.ts b/src/services/ui/src/components/Opensearch/main/useOpensearch.ts similarity index 85% rename from src/services/ui/src/components/Opensearch/useOpensearch.ts rename to src/services/ui/src/components/Opensearch/main/useOpensearch.ts index f0560115f6..804de56434 100644 --- a/src/services/ui/src/components/Opensearch/useOpensearch.ts +++ b/src/services/ui/src/components/Opensearch/main/useOpensearch.ts @@ -1,8 +1,8 @@ -import { getSearchData, useOsSearch } from "@/api"; +import { getOsData, useOsSearch } from "@/api"; import { useLzUrl } from "@/hooks/useParams"; import { useEffect, useState } from "react"; -import { OsQueryState, SearchData, UserRoles } from "shared-types"; -import { createSearchFilterable } from "./utils"; +import { UserRoles, opensearch } from "shared-types"; +import { createSearchFilterable } from "../utils"; import { useQuery } from "@tanstack/react-query"; import { useGetUser } from "@/api/useGetUser"; import { OsTab } from "./types"; @@ -39,12 +39,16 @@ Comments */ export const useOsData = () => { const params = useOsUrl(); - const [data, setData] = useState(); - const { mutateAsync, isLoading, error } = useOsSearch(); - const onRequest = async (query: OsQueryState, options?: any) => { + const [data, setData] = useState(); + const { mutateAsync, isLoading, error } = useOsSearch< + opensearch.main.Field, + opensearch.main.Response + >(); + const onRequest = async (query: opensearch.main.State, options?: any) => { try { await mutateAsync( { + index: "main", pagination: query.pagination, ...(!query.search && { sort: query.sort }), filters: [ @@ -71,7 +75,8 @@ export const useOsAggregate = () => { refetchOnWindowFocus: false, queryKey: [state.tab], queryFn: (props) => { - return getSearchData({ + return getOsData({ + index: "main", aggs: [ { field: "state.keyword", @@ -125,7 +130,7 @@ export const useOsAggregate = () => { }); return aggs.data?.aggregations; }; -export type OsUrlState = OsQueryState & { tab: OsTab }; +export type OsUrlState = opensearch.main.State & { tab: OsTab }; export const useOsUrl = () => { return useLzUrl({ key: "os", diff --git a/src/services/ui/src/components/Opensearch/utils.ts b/src/services/ui/src/components/Opensearch/utils.ts index d2b3f21f7d..3bff8d8377 100644 --- a/src/services/ui/src/components/Opensearch/utils.ts +++ b/src/services/ui/src/components/Opensearch/utils.ts @@ -1,9 +1,8 @@ -import { OsAggQuery, OsFilterable, OsQueryState } from "shared-types"; -import { OsUrlState } from "./useOpensearch"; +import { opensearch } from "shared-types"; const filterMapQueryReducer = ( - state: Record, - filter: OsFilterable + state: Record["prefix"], any[]>, + filter: opensearch.Filterable ) => { if (!filter.value) return state; @@ -40,7 +39,7 @@ const filterMapQueryReducer = ( return state; }; -export const filterQueryBuilder = (filters: OsFilterable[]) => { +export const filterQueryBuilder = (filters: opensearch.Filterable[]) => { if (!filters?.length) return {}; return { @@ -56,7 +55,7 @@ export const filterQueryBuilder = (filters: OsFilterable[]) => { }; export const paginationQueryBuilder = ( - pagination: OsQueryState["pagination"] + pagination: opensearch.QueryState["pagination"] ) => { const from = (() => { if (!pagination.number) return 0; @@ -69,11 +68,11 @@ export const paginationQueryBuilder = ( }; }; -export const sortQueryBuilder = (sort: OsQueryState["sort"]) => { +export const sortQueryBuilder = (sort: opensearch.QueryState["sort"]) => { return { sort: [{ [sort.field]: sort.order }] }; }; -export const aggQueryBuilder = (aggs: OsAggQuery[]) => { +export const aggQueryBuilder = (aggs: opensearch.AggQuery[]) => { return { aggs: aggs.reduce((STATE, AGG) => { STATE[AGG.name] = { @@ -96,24 +95,14 @@ export const createSearchFilterable = (value?: string) => { field: "", value, prefix: "must", - } as unknown as OsFilterable, + } as unknown as opensearch.Filterable, ]; }; -export const resetFilters = ( - onSet: ( - arg: (arg: OsUrlState) => OsUrlState, - shouldIsolate?: boolean | undefined - ) => void +export const checkMultiFilter = ( + filters: opensearch.Filterable[], + val: number ) => { - onSet((s) => ({ - ...s, - filters: [], - pagination: { ...s.pagination, number: 0 }, - })); -}; - -export const checkMultiFilter = (filters: OsFilterable[], val: number) => { return ( filters.length >= val || filters.some( diff --git a/src/services/ui/src/components/RaiList/index.tsx b/src/services/ui/src/components/RaiList/index.tsx index 6da50ba497..7144a672da 100644 --- a/src/services/ui/src/components/RaiList/index.tsx +++ b/src/services/ui/src/components/RaiList/index.tsx @@ -1,4 +1,4 @@ -import { OsMainSourceItem } from "shared-types"; +import { opensearch } from "shared-types"; import { DetailsSection } from "../DetailsSection"; import { format } from "date-fns"; import { @@ -10,7 +10,7 @@ import { } from "@/components"; import { BLANK_VALUE } from "@/consts"; -export const RaiList = (data: OsMainSourceItem) => { +export const RaiList = (data: opensearch.main.Document) => { if (!data.rais) return null; return ( diff --git a/src/services/ui/src/pages/actions/IssueRai.tsx b/src/services/ui/src/pages/actions/IssueRai.tsx index 71d4522abf..8a35d9ba2b 100644 --- a/src/services/ui/src/pages/actions/IssueRai.tsx +++ b/src/services/ui/src/pages/actions/IssueRai.tsx @@ -5,7 +5,7 @@ import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { Alert, LoadingSpinner } from "@/components"; import { FAQ_TARGET } from "@/routes"; -import { ItemResult, PlanType } from "shared-types"; +import { opensearch, PlanType } from "shared-types"; import { useGetUser } from "@/api/useGetUser"; import { submit } from "@/api/submissionService"; import { buildActionUrl } from "@/lib"; @@ -53,7 +53,7 @@ const FormDescriptionText = () => { ); }; -export const RaiIssue = ({ item }: { item: ItemResult }) => { +export const RaiIssue = ({ item }: { item: opensearch.main.ItemResult }) => { const { id, type } = useParams("/action/:id/:type"); const authority = item?._source.authority as PlanType; const { setCancelModalOpen, setSuccessModalOpen, setErrorModalOpen } = diff --git a/src/services/ui/src/pages/actions/RespondToRai.tsx b/src/services/ui/src/pages/actions/RespondToRai.tsx index 0c3bcf563b..5b3bbbca88 100644 --- a/src/services/ui/src/pages/actions/RespondToRai.tsx +++ b/src/services/ui/src/pages/actions/RespondToRai.tsx @@ -5,7 +5,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { Alert, LoadingSpinner } from "@/components"; import { FAQ_TARGET } from "@/routes"; import { Link, useParams } from "@/components/Routing"; -import { ItemResult, PlanType } from "shared-types"; +import { opensearch, PlanType } from "shared-types"; import { useGetUser } from "@/api/useGetUser"; import { submit } from "@/api/submissionService"; import { buildActionUrl } from "@/lib"; @@ -51,7 +51,11 @@ const FormDescriptionText = () => { ); }; -export const RespondToRai = ({ item }: { item: ItemResult }) => { +export const RespondToRai = ({ + item, +}: { + item: opensearch.main.ItemResult; +}) => { const { id, type } = useParams("/action/:id/:type"); const authority = item?._source.authority as PlanType; const { setCancelModalOpen, setErrorModalOpen, setSuccessModalOpen } = diff --git a/src/services/ui/src/pages/actions/ToggleRaiResponseWithdraw.tsx b/src/services/ui/src/pages/actions/ToggleRaiResponseWithdraw.tsx index 315d3d8db2..16252cfdac 100644 --- a/src/services/ui/src/pages/actions/ToggleRaiResponseWithdraw.tsx +++ b/src/services/ui/src/pages/actions/ToggleRaiResponseWithdraw.tsx @@ -1,15 +1,19 @@ import { Navigate, useParams } from "@/components/Routing"; import { Alert, LoadingSpinner } from "@/components"; -import { Action, PlanType, ItemResult } from "shared-types"; +import { Action, PlanType, opensearch } from "shared-types"; import { Button } from "@/components/Inputs"; -import { useEffect, useMemo } from "react"; +import { FC, useEffect, useMemo } from "react"; import { useSubmissionService } from "@/api/submissionService"; import { buildActionUrl } from "@/lib"; import { useGetUser } from "@/api/useGetUser"; import { ActionFormIntro, PackageInfo } from "@/pages/actions/common"; import { useModalContext } from "@/pages/form/modals"; -export const ToggleRaiResponseWithdraw = ({ item }: { item?: ItemResult }) => { +export const ToggleRaiResponseWithdraw = ({ + item, +}: { + item?: opensearch.main.ItemResult; +}) => { const { id, type } = useParams("/action/:id/:type"); const { data: user } = useGetUser(); const authority = item?._source.authority as PlanType; diff --git a/src/services/ui/src/pages/actions/WithdrawPackage.tsx b/src/services/ui/src/pages/actions/WithdrawPackage.tsx index 4304fa23c0..9f4302afde 100644 --- a/src/services/ui/src/pages/actions/WithdrawPackage.tsx +++ b/src/services/ui/src/pages/actions/WithdrawPackage.tsx @@ -1,7 +1,7 @@ import { Navigate, useParams } from "@/components/Routing"; import { Button } from "@/components/Inputs"; -import { useState } from "react"; -import { PlanType, ItemResult } from "shared-types"; +import { FC, useState } from "react"; +import { PlanType, opensearch } from "shared-types"; import { ActionFormIntro, PackageInfo } from "./common"; import { z } from "zod"; import { SubmitHandler, useForm } from "react-hook-form"; @@ -34,7 +34,11 @@ const attachments: AttachmentRecipe[] = [ } as const, ]; -export const WithdrawPackage = ({ item }: { item?: ItemResult }) => { +export const WithdrawPackage = ({ + item, +}: { + item: opensearch.main.ItemResult; +}) => { const { id, type } = useParams("/action/:id/:type"); const { cancelModalOpen, diff --git a/src/services/ui/src/pages/actions/WithdrawRai.tsx b/src/services/ui/src/pages/actions/WithdrawRai.tsx index 743e254a9f..5f776f51e1 100644 --- a/src/services/ui/src/pages/actions/WithdrawRai.tsx +++ b/src/services/ui/src/pages/actions/WithdrawRai.tsx @@ -4,7 +4,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { SubmitHandler, useForm } from "react-hook-form"; import { z } from "zod"; import { Link, useParams } from "@/components/Routing"; -import { ItemResult, PlanType } from "shared-types"; +import { opensearch, PlanType } from "shared-types"; import { useGetUser } from "@/api/useGetUser"; import { submit } from "@/api/submissionService"; import { useState } from "react"; @@ -28,7 +28,7 @@ const attachmentList = [ }, ] as const; -export const WithdrawRai = ({ item }: { item: ItemResult }) => { +export const WithdrawRai = ({ item }: { item: opensearch.main.ItemResult }) => { const { id } = useParams("/action/:id/:type"); const { setCancelModalOpen, setSuccessModalOpen, setErrorModalOpen } = useModalContext(); diff --git a/src/services/ui/src/pages/actions/common.tsx b/src/services/ui/src/pages/actions/common.tsx index d21e2bf3f8..0fb14afc11 100644 --- a/src/services/ui/src/pages/actions/common.tsx +++ b/src/services/ui/src/pages/actions/common.tsx @@ -1,6 +1,6 @@ import { removeUnderscoresAndCapitalize } from "@/utils"; import { PropsWithChildren } from "react"; -import { ItemResult } from "shared-types"; +import { opensearch } from "shared-types"; // Keeps aria stuff and classes condensed const SectionTemplate = ({ @@ -18,7 +18,7 @@ const SectionTemplate = ({
); -export const PackageInfo = ({ item }: { item: ItemResult }) => ( +export const PackageInfo = ({ item }: { item: opensearch.main.ItemResult }) => (
- function Cell(data: OsMainSourceItem) { +export const renderCellDate = (key: keyof opensearch.main.Document) => + function Cell(data: opensearch.main.Document) { if (!data[key]) return null; return format(new Date(data[key] as string), "MM/dd/yyyy"); }; export const renderCellIdLink = (pathResolver: (id: string) => string) => - function Cell(data: OsMainSourceItem) { + function Cell(data: opensearch.main.Document) { if (!data.authority) return <>; const path = pathResolver(encodeURIComponent(data.id)); return ( @@ -25,7 +25,7 @@ export const renderCellIdLink = (pathResolver: (id: string) => string) => }; export const renderCellActions = (user: CognitoUserAttributes | null) => - function Cell(data: OsMainSourceItem) { + function Cell(data: opensearch.main.Document) { if (!user) return <>; const actions = getAvailableActions(user, data); return ( diff --git a/src/services/ui/src/pages/dashboard/Lists/spas/consts.tsx b/src/services/ui/src/pages/dashboard/Lists/spas/consts.tsx index be3b2ddf11..735e612ebf 100644 --- a/src/services/ui/src/pages/dashboard/Lists/spas/consts.tsx +++ b/src/services/ui/src/pages/dashboard/Lists/spas/consts.tsx @@ -1,6 +1,6 @@ import { format } from "date-fns"; import { removeUnderscoresAndCapitalize } from "@/utils"; -import { OsTableColumn } from "@/components/Opensearch/Table/types"; +import { OsTableColumn } from "@/components/Opensearch/main"; import { CMS_READ_ONLY_ROLES, UserRoles } from "shared-types"; import { useGetUser } from "@/api/useGetUser"; import { diff --git a/src/services/ui/src/pages/dashboard/Lists/spas/index.tsx b/src/services/ui/src/pages/dashboard/Lists/spas/index.tsx index f42c767a53..7abab8c31c 100644 --- a/src/services/ui/src/pages/dashboard/Lists/spas/index.tsx +++ b/src/services/ui/src/pages/dashboard/Lists/spas/index.tsx @@ -1,4 +1,4 @@ -import { ErrorAlert, LoadingSpinner } from "@/components"; +import { ErrorAlert } from "@/components"; import { Pagination } from "@/components/Pagination"; import { @@ -6,7 +6,7 @@ import { OsFiltering, useOsContext, useOsUrl, -} from "@/components/Opensearch"; +} from "@/components/Opensearch/main"; import { useSpaTableColumns } from "./consts"; export const SpasList = () => { diff --git a/src/services/ui/src/pages/dashboard/Lists/waivers/consts.tsx b/src/services/ui/src/pages/dashboard/Lists/waivers/consts.tsx index e5a9f472ee..ef5712f07b 100644 --- a/src/services/ui/src/pages/dashboard/Lists/waivers/consts.tsx +++ b/src/services/ui/src/pages/dashboard/Lists/waivers/consts.tsx @@ -1,5 +1,5 @@ import { removeUnderscoresAndCapitalize } from "@/utils"; -import { OsTableColumn } from "@/components/Opensearch/Table/types"; +import { OsTableColumn } from "@/components/Opensearch/main"; import { LABELS } from "@/lib"; import { BLANK_VALUE } from "@/consts"; import { CMS_READ_ONLY_ROLES, UserRoles } from "shared-types"; diff --git a/src/services/ui/src/pages/dashboard/Lists/waivers/index.tsx b/src/services/ui/src/pages/dashboard/Lists/waivers/index.tsx index b4a37254e2..37baa4bf99 100644 --- a/src/services/ui/src/pages/dashboard/Lists/waivers/index.tsx +++ b/src/services/ui/src/pages/dashboard/Lists/waivers/index.tsx @@ -5,7 +5,7 @@ import { OsFiltering, useOsContext, useOsUrl, -} from "@/components/Opensearch"; +} from "@/components/Opensearch/main"; import { useWaiverTableColumns } from "./consts"; export const WaiversList = () => { diff --git a/src/services/ui/src/pages/dashboard/index.tsx b/src/services/ui/src/pages/dashboard/index.tsx index 603b1984f9..fa7d48545c 100644 --- a/src/services/ui/src/pages/dashboard/index.tsx +++ b/src/services/ui/src/pages/dashboard/index.tsx @@ -10,7 +10,7 @@ import { useOsData, FilterChips, FilterDrawerProvider, -} from "@/components/Opensearch"; +} from "@/components/Opensearch/main"; import { Button } from "@/components/Inputs"; import { useUserContext } from "@/components/Context/userContext"; import { useMemo } from "react"; diff --git a/src/services/ui/src/pages/detail/admin-changes/AdminChanges.tsx b/src/services/ui/src/pages/detail/admin-changes/AdminChanges.tsx new file mode 100644 index 0000000000..a855c0d2ac --- /dev/null +++ b/src/services/ui/src/pages/detail/admin-changes/AdminChanges.tsx @@ -0,0 +1,71 @@ +import { + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components"; +import { opensearch } from "shared-types"; +import { FC, useMemo } from "react"; +import { BLANK_VALUE } from "@/consts"; +import { format } from "date-fns"; + +export const AC_WithdrawEnabled: FC = ( + props +) => { + return ( +

+ {props.submitterName} has enabled package action to submit formal RAI + response +

+ ); +}; + +export const AC_WithdrawDisabled: FC = ( + props +) => { + return ( +

+ {props.submitterName} has disabled package action to submit formal RAI + response +

+ ); +}; + +export const AC_Update: FC = () => { + return

Coming Soon

; +}; + +const useAdminChange = ( + doc: opensearch.changelog.Document +): [string, FC] => { + return useMemo(() => { + switch (doc.actionType) { + case "disable-rai-withdraw": + return ["Disabled formal RAI response withdraw", AC_WithdrawDisabled]; + case "enable-rai-withdraw": + return ["Enabled formal RAI response withdraw", AC_WithdrawEnabled]; + case "update": + return ["SPA ID update", AC_Update]; + default: + return [BLANK_VALUE, AC_Update]; + } + }, [doc.actionType]); +}; + +export const AdminChange: FC = (props) => { + const [label, Content] = useAdminChange(props); + + return ( + + +

+ {label as string} + {" - "} + {format(new Date(props.timestamp), "eee, MMM d, yyyy hh:mm:ss a OOO")} +

+
+ + + +
+ ); +}; diff --git a/src/services/ui/src/pages/detail/admin-changes/index.tsx b/src/services/ui/src/pages/detail/admin-changes/index.tsx new file mode 100644 index 0000000000..5311a86c0a --- /dev/null +++ b/src/services/ui/src/pages/detail/admin-changes/index.tsx @@ -0,0 +1,26 @@ +import { Accordion, DetailsSection } from "@/components"; +import { opensearch } from "shared-types"; +import { FC } from "react"; +import { AdminChange } from "./AdminChanges"; + +export const ACTIONS_ADMIN = ["disable-rai-withdraw", "enable-rai-withdraw"]; + +export const AdminChanges: FC = (props) => { + const data = props.changelog?.filter((CL) => + ACTIONS_ADMIN.includes(CL._source.actionType) + ); + return ( + + {!data?.length &&

-- no logs --

} + + {data?.map((CL) => ( + + ))} + +
+ ); +}; diff --git a/src/services/ui/src/pages/detail/index.tsx b/src/services/ui/src/pages/detail/index.tsx index 772f5ccfa7..affc597d72 100644 --- a/src/services/ui/src/pages/detail/index.tsx +++ b/src/services/ui/src/pages/detail/index.tsx @@ -1,20 +1,18 @@ import { AdditionalInfo, Alert, - Attachmentslist, CardWithTopBorder, ConfirmationModal, DetailItemsGrid, DetailsSection, ErrorAlert, LoadingSpinner, - RaiList, } from "@/components"; import { useGetUser } from "@/api/useGetUser"; -import { Action, ItemResult, OsMainSourceItem, UserRoles } from "shared-types"; +import { Action, opensearch, UserRoles } from "shared-types"; import { PackageCheck } from "shared-utils"; import { useQuery } from "@/hooks"; -import { useGetItem } from "@/api"; +import { getAttachmentUrl, useGetItem } from "@/api"; import { BreadCrumbs } from "@/components/BreadCrumb"; import { mapActionLabel } from "@/utils"; import { useLocation } from "react-router-dom"; @@ -25,6 +23,8 @@ import { API } from "aws-amplify"; import { getStatus } from "shared-types/statusHelper"; import { spaDetails, submissionDetails } from "@/pages/detail/setup/spa"; import { Link } from "@/components/Routing"; +import { PackageActivities } from "./package-activity"; +import { AdminChanges } from "./admin-changes"; const DetailCardWrapper = ({ title, @@ -39,7 +39,7 @@ const DetailCardWrapper = ({
); -const StatusCard = (data: OsMainSourceItem) => { +const StatusCard = (data: opensearch.main.Document) => { const transformedStatuses = getStatus(data.seatoolStatus); const checker = PackageCheck(data); const { data: user } = useGetUser(); @@ -155,7 +155,11 @@ const PackageActionsCard = ({ id }: { id: string }) => { ); }; -export const DetailsContent = ({ data }: { data?: ItemResult }) => { +export const DetailsContent = ({ + data, +}: { + data?: opensearch.main.ItemResult; +}) => { const { state } = useLocation(); if (!data?._source) return ; return ( @@ -195,20 +199,14 @@ export const DetailsContent = ({ data }: { data?: ItemResult }) => { -

{"Package Details"}

- - - {/* Below is used for spacing. Keep it simple */} -
- - - - - - - +
+ + + + + + +
); diff --git a/src/services/ui/src/pages/detail/package-activity/PackageActivity.tsx b/src/services/ui/src/pages/detail/package-activity/PackageActivity.tsx new file mode 100644 index 0000000000..23b0d052d5 --- /dev/null +++ b/src/services/ui/src/pages/detail/package-activity/PackageActivity.tsx @@ -0,0 +1,205 @@ +import { + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components"; +import { opensearch } from "shared-types"; +import { getAttachmentUrl } from "@/api"; +import { FC, useMemo } from "react"; +import { Button } from "@/components/Inputs"; +import * as Table from "@/components/Table"; +import { BLANK_VALUE } from "@/consts"; +import { format } from "date-fns"; + +export const PA_InitialSubmission: FC = ( + props +) => { + return ( +
+ <> + + + + + Document Type + + Attached File + + + + {props.attachments?.map((ATC) => { + return ( + + {ATC.title} + + + + + ); + })} + + + + +
+

Additional Information

+

{props.additionalInformation || "No information submitted"}

+
+
+ ); +}; + +export const PA_ResponseSubmitted: FC = ( + props +) => { + return ( +
+
+

Attached File

+ {!props.attachments?.length &&

No information submitted

} + {props.attachments?.map((ATC) => ( + + ))} +
+
+

Additional Information

+

{props.additionalInformation || "No information submitted"}

+
+
+ ); +}; + +export const PA_ResponseWithdrawn: FC = ( + props +) => { + return ( +
+
+

Attached File

+ {!props.attachments?.length &&

No information submitted

} + {props.attachments?.map((ATC) => ( + + ))} +
+
+

Additional Information

+

{props.additionalInformation || "No information submitted"}

+
+
+ ); +}; + +export const PA_RaiIssued: FC = (props) => { + return ( +
+
+

Attached File

+ {!props.attachments?.length &&

No information submitted

} + {props.attachments?.map((ATC) => ( + + ))} +
+
+

Additional Information

+

{props.additionalInformation || "No information submitted"}

+
+
+ ); +}; + +const usePackageActivity = (doc: opensearch.changelog.Document) => { + return useMemo(() => { + switch (doc.actionType) { + case "new-submission": + return ["Initial package submitted", PA_InitialSubmission]; + case "withdraw-rai": + return ["RAI response withdrawn", PA_ResponseWithdrawn]; + case "withdraw-package": + return ["RAI package withdrawn", PA_ResponseWithdrawn]; + case "issue-rai": + return ["RAI issued", PA_RaiIssued]; + case "respond-to-rai": + return ["RAI response submitted", PA_ResponseSubmitted]; + default: + return [BLANK_VALUE, PA_ResponseSubmitted]; + } + }, [doc.actionType]); +}; + +export const PackageActivity: FC = (props) => { + const [label, Content] = usePackageActivity(props); + + return ( + + +

+ {label as string} + {" - "} + {format(new Date(props.timestamp), "eee, MMM d, yyyy hh:mm:ss a OOO")} +

+
+ + + +
+ ); +}; diff --git a/src/services/ui/src/pages/detail/package-activity/index.tsx b/src/services/ui/src/pages/detail/package-activity/index.tsx new file mode 100644 index 0000000000..1d96d4c2c6 --- /dev/null +++ b/src/services/ui/src/pages/detail/package-activity/index.tsx @@ -0,0 +1,43 @@ +import { Accordion, DetailsSection } from "@/components"; +import { opensearch } from "shared-types"; +import { FC } from "react"; +import { PackageActivity } from "./PackageActivity"; +import { Button } from "@/components/Inputs"; + +export const ACTIONS_PA = [ + "new-submission", + "withdraw-rai", + "withdraw-package", + "issue-rai", + "respond-to-rai", +]; + +export const PackageActivities: FC = (props) => { + const data = props.changelog?.filter((CL) => + ACTIONS_PA.includes(CL._source.actionType) + ); + + // TODO: OY2-26538 + const onDownloadAll = () => null; + + return ( + + {`Package Activity (${data?.length})`} + +
+ } + > + {!data?.length &&

-- no logs --

} + + {data?.map((CL) => ( + + ))} + + + ); +}; diff --git a/src/services/ui/src/pages/detail/setup/spa.tsx b/src/services/ui/src/pages/detail/setup/spa.tsx index eba58b8ba6..f84cfbdca3 100644 --- a/src/services/ui/src/pages/detail/setup/spa.tsx +++ b/src/services/ui/src/pages/detail/setup/spa.tsx @@ -3,7 +3,7 @@ import { isCmsUser } from "shared-utils"; import { LABELS } from "@/lib"; import { BLANK_VALUE } from "@/consts"; import { format } from "date-fns"; -import { OsMainSourceItem } from "shared-types"; +import { opensearch } from "shared-types"; import { ReactNode } from "react"; import { OneMacUser } from "@/api/useGetUser"; import { ReviewTeamList } from "@/components/PackageDetails/ReviewTeamList"; @@ -13,7 +13,9 @@ export type DetailSectionItem = { value: ReactNode; canView: (u: OneMacUser | undefined) => boolean; }; -export const spaDetails = (data: OsMainSourceItem): DetailSectionItem[] => [ +export const spaDetails = ( + data: opensearch.main.Document +): DetailSectionItem[] => [ { label: "Submission ID", value: data.id, @@ -69,7 +71,7 @@ export const spaDetails = (data: OsMainSourceItem): DetailSectionItem[] => [ ]; export const submissionDetails = ( - data: OsMainSourceItem + data: opensearch.main.Document ): DetailSectionItem[] => [ { label: "Submitted By",