From 02a350201687ec9802236e97ccc3617a7021ad89 Mon Sep 17 00:00:00 2001 From: Mats Johansen Date: Thu, 5 Sep 2024 14:32:42 +0200 Subject: [PATCH] feat(negotiate): add config to change negotiation service bbmri still wip --- docker-compose.yml | 2 +- packages/demo/public/options-dev.json | 1 + packages/demo/src/AppCCP.svelte | 2 +- .../NegotiateButtonComponent.wc.svelte | 2 +- packages/lib/src/stores/negotiate.ts | 134 ++++++++++++------ packages/lib/src/styles/negotiate-button.css | 8 +- packages/lib/src/types/options.schema.json | 5 + 7 files changed, 104 insertions(+), 50 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7b170f72..fc58d58c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -76,7 +76,7 @@ services: CATALOGUE_URL: "${CATALOGUE_URL}" BIND_ADDR: 0.0.0.0:8055 PRISM_URL: http://prism:8066 - RUST_LOG: "info" + # RUST_LOG: "info" LOG_FILE: /requests.log volumes: - ./requests.log:/requests.log diff --git a/packages/demo/public/options-dev.json b/packages/demo/public/options-dev.json index a32aa816..df858980 100644 --- a/packages/demo/public/options-dev.json +++ b/packages/demo/public/options-dev.json @@ -281,6 +281,7 @@ ] }, "negotiateOptions": { + "negotiateApp": "project-manager", "newProjectUrl": "http://localhost:8097/create-query-and-design-project", "editProjectUrl": "http://localhost:8097/edit-project", "siteMapping": [ diff --git a/packages/demo/src/AppCCP.svelte b/packages/demo/src/AppCCP.svelte index c76d8856..dbca66e1 100644 --- a/packages/demo/src/AppCCP.svelte +++ b/packages/demo/src/AppCCP.svelte @@ -150,7 +150,7 @@ >Diagramme repräsentieren nicht mehr die aktuelle Suche! - +
diff --git a/packages/lib/src/stores/negotiate.ts b/packages/lib/src/stores/negotiate.ts index 83fbfd9a..65ad74f4 100644 --- a/packages/lib/src/stores/negotiate.ts +++ b/packages/lib/src/stores/negotiate.ts @@ -106,12 +106,14 @@ export const getHumanReadableQuery = (): string => { * sets all options needed for the negotiator */ type NegotiateOptions = { + negotiateApp: "negotiator" | "project-manager"; siteMapping: { site: string; collection: string }[]; - negotiatorURL: string; newProjectUrl: string; editProjectUrl: string; }; +type NegotiatorResponse = Response & { url?: string; redirect_uri?: string }; + let negotiateOptions: NegotiateOptions; const siteCollectionMap: Map = new Map(); const urlParams: URLSearchParams = new URLSearchParams(window.location.search); @@ -181,8 +183,9 @@ export const getCollections = (sitesToNegotiate: string[]): Collection[] => { * @param sitesToNegotiate the sites to negotiate with */ export const negotiate = async (sitesToNegotiate: string[]): Promise => { - //TODO: get auth token here console.log("enter negotiate"); + console.log("currentMeasures", currentMeasures); + let sendableQuery!: SendableQuery; queryStore.subscribe((value: QueryItem[][]) => { const uuid = uuidv4(); @@ -196,7 +199,7 @@ export const negotiate = async (sitesToNegotiate: string[]): Promise => { const humanReadable: string = getHumanReadableQuery(); const collections: Collection[] = getCollections(sitesToNegotiate); // TODO: Implement proper configuration option for the switch between negotiator and project manager - const negotiatorResponse = false + const negotiatorResponse = true ? await sendRequestToNegotiator( sendableQuery, humanReadable, @@ -210,24 +213,48 @@ export const negotiate = async (sitesToNegotiate: string[]): Promise => { queryBase64String, ); - const indexOfQuestionMark: number = negotiatorResponse.redirect_uri - .toString() - .indexOf("?"); + console.log(negotiatorResponse); - if (!negotiatorResponse.redirect_uri) { - console.error("Negotiator response does not contain redirect uri"); - return; - } + /** + * handle redirect to project manager url + */ + if (negotiateOptions.negotiateApp === "project-manager") { + // project manager + + if (!negotiatorResponse.redirect_uri) { + console.error("Negotiator response does not contain redirect uri"); + return; + } - const subpage = "/project-view"; - const negotiationURI = - negotiatorResponse.redirect_uri + const indexOfQuestionMark: number = negotiatorResponse.redirect_uri .toString() - .slice(0, indexOfQuestionMark) + - `${subpage}` + - negotiatorResponse.redirect_uri.toString().slice(indexOfQuestionMark); + .indexOf("?"); + + const subpage = "/project-view"; + const negotiationURI = + negotiatorResponse.redirect_uri + .toString() + .slice(0, indexOfQuestionMark) + + `${subpage}` + + negotiatorResponse.redirect_uri + .toString() + .slice(indexOfQuestionMark); + + window.location.href = negotiationURI; + } - window.location.href = negotiationURI; + /** + * handle redirect to negotiator url + */ + if (negotiateOptions.negotiateApp === "negotiator") { + // negotiator + if (!negotiatorResponse.url) { + console.error("Negotiator response does not contain redirect uri"); + return; + } + + window.location.href = `https://negotiator.bbmri-eric.eu/requests/${sendableQuery.id}`; + } }; /** @@ -243,31 +270,39 @@ async function sendRequestToNegotiator( humanReadable: string, collections: Collection[], queryBase64String: string, -): Promise { +): Promise { const base64Query: string = btoa(JSON.stringify(sendableQuery.query)); const returnURL: string = `${window.location.protocol}//${window.location.host}/?nToken=${sendableQuery.id}&query=${base64Query}`; - const response: Response & { redirect_uri: string } = (await fetch( - `${negotiateOptions.negotiatorURL}?nToken=${sendableQuery.id}`, - { - method: "POST", - headers: { - Accept: "application/json; charset=utf-8", - "Content-Type": "application/json", - Authorization: - "Basic YmJtcmktZGlyZWN0b3J5Omw5RFJLVUROcTBTbDAySXhaUGQ2", + let response!: Response; + + try { + response = await fetch( + `${negotiateOptions.newProjectUrl}?nToken=${sendableQuery.id}`, + { + method: "POST", + headers: { + Accept: "application/json; charset=utf-8", + "Content-Type": "application/json", + Authorization: + "Basic YmJtcmktZGlyZWN0b3J5Omw5RFJLVUROcTBTbDAySXhaUGQ2", + }, + body: JSON.stringify({ + humanReadable: humanReadable, + URL: returnURL, + collections: collections, + nToken: sendableQuery.id, + query: queryBase64String, + }), }, - body: JSON.stringify({ - humanReadable: humanReadable, - URL: returnURL, - collections: collections, - nToken: sendableQuery.id, - query: queryBase64String, - }), - }, - )) as Response & { redirect_uri: string }; - return response; + ); + + return response as NegotiatorResponse; + } catch (error) { + console.log("error", error); + return new Response() as NegotiatorResponse; + } } /** @@ -283,7 +318,7 @@ async function sendRequestToProjectManager( humanReadable: string, collections: Collection[], queryBase64String: string, -): Promise { +): Promise { /** * get temporary token from oauth2 */ @@ -322,7 +357,7 @@ async function sendRequestToProjectManager( ? negotiateOptions.editProjectUrl : negotiateOptions.newProjectUrl; - let response!: Response & { redirect_uri: string }; + let response!: NegotiatorResponse; /** * send request to project manager @@ -355,7 +390,7 @@ async function sendRequestToProjectManager( return response; } catch (error) { console.log("error", error); - return new Response() as Response & { redirect_uri: string }; + return new Response() as NegotiatorResponse; } } @@ -363,14 +398,27 @@ async function sendRequestToProjectManager( * @returns a base64 encoded CQL query */ function getCql(): string { - // NOTE: $ only works within svelte components const ast = buildAstFromQuery(currentQuery); - const cql = translateAstToCql(ast, false, backendMeasures); + + /** + * TODO: + * For now backenMeasures is hardcoded because + * this function only needed for dktk project manager so far. + * Change if needed for negotiator. + * + * should be configurable via options other than spot/blaze, so custom backends can be used + */ + const cql = translateAstToCql( + ast, + false, + "DKTK_STRAT_DEF_IN_INITIAL_POPULATION", + currentMeasures[0].measures, + ); const library = buildLibrary(`${cql}`); const measure = buildMeasure( library.url, - currentMeasures.map((measureItem) => measureItem.measure), + currentMeasures[0].measures.map((measureItem) => measureItem.measure), ); const query = { lang: "cql", lib: library, measure: measure }; diff --git a/packages/lib/src/styles/negotiate-button.css b/packages/lib/src/styles/negotiate-button.css index f1bd8e48..a45c2c9d 100644 --- a/packages/lib/src/styles/negotiate-button.css +++ b/packages/lib/src/styles/negotiate-button.css @@ -2,7 +2,7 @@ * stand alone result button */ -lens-result-summary::part(lens-negotiate-button) { +lens-negotiate-button::part(lens-negotiate-button) { color: var(--white); border: none; border-radius: var(--border-radius-small); @@ -15,14 +15,14 @@ lens-result-summary::part(lens-negotiate-button) { font-family: var(--font-family); } -lens-result-summary::part(lens-negotiate-button-active) { +lens-negotiate-button::part(lens-negotiate-button-active) { background-color: var(--blue); } -lens-result-summary::part(lens-negotiate-button-disabled) { +lens-negotiate-button::part(lens-negotiate-button-disabled) { background-color: var(--gray); } -lens-result-summary::part(lens-negotiate-button-active):hover { +lens-negotiate-button::part(lens-negotiate-button-active):hover { background-color: var(--light-blue); } diff --git a/packages/lib/src/types/options.schema.json b/packages/lib/src/types/options.schema.json index 60c3bc6e..0fc9f14a 100644 --- a/packages/lib/src/types/options.schema.json +++ b/packages/lib/src/types/options.schema.json @@ -338,6 +338,11 @@ "negotiateOptions": { "type": "object", "properties": { + "negotiateApp": { + "type": "string", + "pattern": "^.+$", + "description": "The URL of the negotiate app" + }, "newProjectUrl": { "type": "string", "pattern": "^.+$",