Skip to content

Commit

Permalink
Merge pull request #44 from johnoliver/merge-ui
Browse files Browse the repository at this point in the history
Sync UI with python
  • Loading branch information
dantelmomsft authored Oct 27, 2023
2 parents 0e728a8 + 17678c2 commit 0119649
Show file tree
Hide file tree
Showing 24 changed files with 1,030 additions and 961 deletions.
2 changes: 2 additions & 0 deletions app/frontend/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore JSON
**/*.json
20 changes: 10 additions & 10 deletions app/frontend/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GPT + Enterprise data | Java Sample</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
1,637 changes: 843 additions & 794 deletions app/frontend/package-lock.json

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions app/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@
"scripts": {
"dev": "vite --port=8080",
"build": "tsc && vite build",
"watch": "tsc && vite build --watch"
"preview": "vite preview"
},
"dependencies": {
"@azure/msal-react": "^2.0.4",
"@azure/msal-browser": "^3.1.0",
"@fluentui/react": "^8.112.2",
"@fluentui/react-components": "^9.34.2",
"@fluentui/react-icons": "^2.0.219",
"@fluentui/react": "^8.112.3",
"@fluentui/react-components": "^9.35.0",
"@fluentui/react-icons": "^2.0.220",
"@react-spring/web": "^9.7.3",
"dompurify": "^3.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.16.0",
"ndjson-readablestream": "^1.0.7"
"ndjson-readablestream": "^1.0.7",
"scheduler": "^0.20.2"
},
"devDependencies": {
"@types/dompurify": "^3.0.3",
"@types/react": "^18.2.27",
"@types/react-dom": "^18.2.12",
"@types/react": "^18.2.28",
"@types/react-dom": "^18.2.13",
"@vitejs/plugin-react": "^4.1.0",
"prettier": "^3.0.3",
"typescript": "^5.2.2",
Expand Down
2 changes: 1 addition & 1 deletion app/frontend/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useLogin } from "../authConfig";
const BACKEND_URI = import.meta.env.VITE_BACKEND_URI ? import.meta.env.VITE_BACKEND_URI : "";

function getHeaders(idToken: string | undefined, stream:boolean): Record<string, string> {
var headers : Record<string, string> = {
var headers: Record<string, string> = {
"Content-Type": "application/json"
};
// If using login, add the id token of the logged in account as the authorization
Expand Down
8 changes: 5 additions & 3 deletions app/frontend/src/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,18 @@ export type ChatAppRequestOverrides = {
export type ResponseMessage = {
content: string;
role: string;
}
};

export type ResponseContext = {
thoughts: string | null;
data_points: string[];
}
};

export type ResponseChoice = {
index: number;
message: ResponseMessage;
context: ResponseContext;
session_state: any;
};

export type ChatAppResponseOrError = {
Expand All @@ -58,11 +59,12 @@ export type ChatAppResponse = {

export type ChatAppRequestContext = {
overrides?: ChatAppRequestOverrides;
}
};

export type ChatAppRequest = {
messages: ResponseMessage[];
approach: Approaches;
context?: ChatAppRequestContext;
stream?: boolean;
session_state: any;
};
53 changes: 30 additions & 23 deletions app/frontend/src/authConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Refactored from https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/blob/main/1-Authentication/1-sign-in/SPA/src/authConfig.js

import { AuthenticationResult, IPublicClientApplication } from "@azure/msal-browser";

const BACKEND_URI = import.meta.env.VITE_BACKEND_URI ? import.meta.env.VITE_BACKEND_URI : "";
Expand All @@ -13,29 +14,29 @@ interface AuthSetup {
*/
msalConfig: {
auth: {
clientId: string, // Client app id used for login
authority: string, // Directory to use for login https://learn.microsoft.com/azure/active-directory/develop/msal-client-application-configuration#authority
redirectUri: string, // Points to window.location.origin. You must register this URI on Azure Portal/App Registration.
postLogoutRedirectUri: string, // Indicates the page to navigate after logout.
navigateToLoginRequestUrl: boolean // If "true", will navigate back to the original request location before processing the auth code response.
},
clientId: string; // Client app id used for login
authority: string; // Directory to use for login https://learn.microsoft.com/azure/active-directory/develop/msal-client-application-configuration#authority
redirectUri: string; // Points to window.location.origin. You must register this URI on Azure Portal/App Registration.
postLogoutRedirectUri: string; // Indicates the page to navigate after logout.
navigateToLoginRequestUrl: boolean; // If "true", will navigate back to the original request location before processing the auth code response.
};
cache: {
cacheLocation: string, // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
storeAuthStateInCookie: boolean // Set this to "true" if you are having issues on IE11 or Edge
}
},
cacheLocation: string; // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
storeAuthStateInCookie: boolean; // Set this to "true" if you are having issues on IE11 or Edge
};
};
loginRequest: {
/**
* Scopes you add here will be prompted for user consent during sign-in.
* By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
* For more information about OIDC scopes, visit:
* https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
scopes: Array<string>
},
scopes: Array<string>;
};
tokenRequest: {
scopes: Array<string>
}
scopes: Array<string>;
};
}

// Fetch the auth setup JSON data from the API if not already cached
Expand Down Expand Up @@ -68,15 +69,21 @@ export const loginRequest = authSetup.loginRequest;

const tokenRequest = authSetup.tokenRequest;

// Build an absolute redirect URI using the current window's location and the relative redirect URI from auth setup
export const getRedirectUri = () => {
return window.location.origin + authSetup.msalConfig.auth.redirectUri;
};

// Get an access token for use with the API server.
// ID token received when logging in may not be used for this purpose because it has the incorrect audience
export const getToken = (client: IPublicClientApplication): Promise<AuthenticationResult | undefined> => {
return client.acquireTokenSilent({
...tokenRequest,
redirectUri: authSetup.msalConfig.auth.redirectUri
})
.catch((error) => {
console.log(error);
return undefined;
})
}
return client
.acquireTokenSilent({
...tokenRequest,
redirectUri: getRedirectUri()
})
.catch(error => {
console.log(error);
return undefined;
});
};
4 changes: 3 additions & 1 deletion app/frontend/src/components/Answer/Answer.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
padding: 20px;
background: rgb(249, 249, 249);
border-radius: 8px;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.14), 0px 0px 2px rgba(0, 0, 0, 0.12);
box-shadow:
0px 2px 4px rgba(0, 0, 0, 0.14),
0px 0px 2px rgba(0, 0, 0, 0.12);
outline: transparent solid 1px;
}

Expand Down
2 changes: 1 addition & 1 deletion app/frontend/src/components/Answer/Answer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const Answer = ({
showFollowupQuestions
}: Props) => {
const messageContent = answer.choices[0].message.content;
const parsedAnswer = useMemo(() => parseAnswerToHtml(messageContent, isStreaming, onCitationClicked ), [answer]);
const parsedAnswer = useMemo(() => parseAnswerToHtml(messageContent, isStreaming, onCitationClicked), [answer]);

const sanitizedAnswerHtml = DOMPurify.sanitize(parsedAnswer.answerHtml);

Expand Down
8 changes: 4 additions & 4 deletions app/frontend/src/components/Answer/AnswerParser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ export function parseAnswerToHtml(answer: string, isStreaming: boolean, onCitati
parsedAnswer = parsedAnswer.trim();

// Omit a citation that is still being typed during streaming
if (isStreaming){
if (isStreaming) {
let lastIndex = parsedAnswer.length;
for (let i = parsedAnswer.length - 1; i >= 0; i--) {
if (parsedAnswer[i] === ']') {
if (parsedAnswer[i] === "]") {
break;
} else if (parsedAnswer[i] === '[') {
} else if (parsedAnswer[i] === "[") {
lastIndex = i;
break;
}
}
const truncatedAnswer = parsedAnswer.substring(0, lastIndex);
parsedAnswer = truncatedAnswer;
}
}

const parts = parsedAnswer.split(/\[([^\]]+)\]/g);

Expand Down
4 changes: 3 additions & 1 deletion app/frontend/src/components/Example/Example.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
}

.example:hover {
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.14), 0px 0px 2px rgba(0, 0, 0, 0.12);
box-shadow:
0px 8px 16px rgba(0, 0, 0, 0.14),
0px 0px 2px rgba(0, 0, 0, 0.12);
outline: 2px solid rgba(115, 118, 225, 1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
border-radius: 5px;
padding: 30px 30px;
font-weight: 100;
}
}
69 changes: 34 additions & 35 deletions app/frontend/src/components/LoginButton/LoginButton.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
import { DefaultButton } from '@fluentui/react';
import { useMsal } from '@azure/msal-react';
import { DefaultButton } from "@fluentui/react";
import { useMsal } from "@azure/msal-react";

import styles from "./LoginButton.module.css";
import { loginRequest } from '../../authConfig';

import { getRedirectUri, loginRequest } from "../../authConfig";

export const LoginButton = () => {
const { instance } = useMsal();
const activeAccount = instance.getActiveAccount();
const handleLoginPopup = () => {
/**
* When using popup and silent APIs, we recommend setting the redirectUri to a blank page or a page
* that does not implement MSAL. Keep in mind that all redirect routes must be registered with the application
* For more information, please follow this link: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/login-user.md#redirecturi-considerations
*/
instance
.loginPopup({
...loginRequest,
redirectUri: '/redirect',
})
.catch((error) => console.log(error));
};
const handleLogoutPopup = () => {
instance
.logoutPopup({
mainWindowRedirectUri: '/', // redirects the top level app after logout
account: instance.getActiveAccount(),
})
.catch((error) => console.log(error));
};
const logoutText = `Logout\n${activeAccount?.username}`
return (
<DefaultButton
text={activeAccount ? logoutText : "Login"}
className={styles.loginButton}
onClick={activeAccount ? handleLogoutPopup : handleLoginPopup}>
</DefaultButton>
)
const { instance } = useMsal();
const activeAccount = instance.getActiveAccount();
const handleLoginPopup = () => {
/**
* When using popup and silent APIs, we recommend setting the redirectUri to a blank page or a page
* that does not implement MSAL. Keep in mind that all redirect routes must be registered with the application
* For more information, please follow this link: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/login-user.md#redirecturi-considerations
*/
instance
.loginPopup({
...loginRequest,
redirectUri: getRedirectUri()
})
.catch(error => console.log(error));
};
const handleLogoutPopup = () => {
instance
.logoutPopup({
mainWindowRedirectUri: "/", // redirects the top level app after logout
account: instance.getActiveAccount()
})
.catch(error => console.log(error));
};
const logoutText = `Logout\n${activeAccount?.username}`;
return (
<DefaultButton
text={activeAccount ? logoutText : "Login"}
className={styles.loginButton}
onClick={activeAccount ? handleLogoutPopup : handleLoginPopup}
></DefaultButton>
);
};
2 changes: 1 addition & 1 deletion app/frontend/src/components/LoginButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "./LoginButton"
export * from "./LoginButton";
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.questionInputContainer {
border-radius: 8px;
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.14), 0px 0px 2px rgba(0, 0, 0, 0.12);
box-shadow:
0px 8px 16px rgba(0, 0, 0, 0.14),
0px 0px 2px rgba(0, 0, 0, 0.12);
height: 90px;
width: 100%;
padding: 15px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
word-break: break-word;
background: rgb(249, 249, 249);
border-radius: 8px;
box-shadow: rgb(0 0 0 / 5%) 0px 0px 0px 1px, rgb(0 0 0 / 10%) 0px 2px 3px 0px;
box-shadow:
rgb(0 0 0 / 5%) 0px 0px 0px 1px,
rgb(0 0 0 / 10%) 0px 2px 3px 0px;
outline: transparent solid 1px;

display: flex;
Expand Down
Loading

0 comments on commit 0119649

Please sign in to comment.