Skip to content

Commit

Permalink
bump to newest master (#1129)
Browse files Browse the repository at this point in the history
* 906 Fix freezing UI (#1066)

* Manually assign results for each simulator

* Revert "Manually assign results for each simulator"

This reverts commit d5c3175.

* Log and limit output for debugging

* Limit output for big files

* Increase large file limits

Co-authored-by: Leszek Grzanka <grzanka@agh.edu.pl>

* Decrease number of lines

* Restore onChange handler for small files

* Do not use specific language syntax highlight

* Update converter version

* Truncate single long line

* Refactoring

* Update src/WrapperApp/components/InputEditor/InputFilesEditor.tsx

Co-authored-by: Leszek Grzanka <grzanka@agh.edu.pl>

---------

Co-authored-by: Leszek Grzanka <grzanka@agh.edu.pl>

* Set setPixelRatio to 1 (#1112)

* build(deps): bump @uiw/react-textarea-code-editor from 2.1.6 to 2.1.7 (#1118)

Bumps [@uiw/react-textarea-code-editor](https://github.com/uiwjs/react-textarea-code-editor) from 2.1.6 to 2.1.7.
- [Release notes](https://github.com/uiwjs/react-textarea-code-editor/releases)
- [Commits](uiwjs/react-textarea-code-editor@v2.1.6...v2.1.7)

---
updated-dependencies:
- dependency-name: "@uiw/react-textarea-code-editor"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump semver from 5.7.1 to 5.7.2 (#1123)

Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](npm/node-semver@v5.7.1...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump word-wrap from 1.2.3 to 1.2.4 (#1125)

Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](jonschlinkert/word-wrap@1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* keycloak integration (#1086)

* keycloak attempts

# Conflicts:
#	src/WrapperApp/components/Panels/LoginPanel.tsx

* test

* Print token for debug purposes

* hardcoding

* update

* test

* Update src/keycloak.js

Co-authored-by: Jakub Niechaj <quban123@gmail.com>

* test suggested by Mieszko

* Add token refresh to keycloak

* Add comunication with yaptide backend

* Add interval async

* Document ambiguous literal number values.

---------

Co-authored-by: Dominik Hendzel <128628266+hendzeld@users.noreply.github.com>
Co-authored-by: Jakub Niechaj <quban123@gmail.com>

* build(deps): bump tough-cookie from 4.1.2 to 4.1.3 (#1120)

Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.1.2 to 4.1.3.
- [Release notes](https://github.com/salesforce/tough-cookie/releases)
- [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md)
- [Commits](salesforce/tough-cookie@v4.1.2...v4.1.3)

---
updated-dependencies:
- dependency-name: tough-cookie
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump @mui/lab from 5.0.0-alpha.133 to 5.0.0-alpha.137 (#1126)

Bumps [@mui/lab](https://github.com/mui/material-ui/tree/HEAD/packages/mui-lab) from 5.0.0-alpha.133 to 5.0.0-alpha.137.
- [Release notes](https://github.com/mui/material-ui/releases)
- [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui/material-ui/commits/HEAD/packages/mui-lab)

---
updated-dependencies:
- dependency-name: "@mui/lab"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Dominik Hendzel <128628266+hendzeld@users.noreply.github.com>
Co-authored-by: Szymon Kania <26521377+ostatni5@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jakub Niechaj <quban123@gmail.com>
  • Loading branch information
5 people authored Jul 29, 2023
1 parent e3acc0c commit 27310c6
Show file tree
Hide file tree
Showing 9 changed files with 366 additions and 218 deletions.
368 changes: 201 additions & 167 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@emotion/styled": "^11.11.0",
"@minoru/react-dnd-treeview": "^3.4.4",
"@mui/icons-material": "^5.13.7",
"@mui/lab": "^5.0.0-alpha.133",
"@mui/lab": "^5.0.0-alpha.137",
"@mui/material": "^5.11.13",
"@mui/x-data-grid": "^6.9.0",
"@testing-library/jest-dom": "^5.16.5",
Expand All @@ -20,7 +20,7 @@
"@types/react-dom": "^17.0.11",
"@types/signals": "^1.0.1",
"@types/throttle-debounce": "^5.0.0",
"@uiw/react-textarea-code-editor": "^2.1.6",
"@uiw/react-textarea-code-editor": "^2.1.7",
"comlink": "^4.3.1",
"command-exists": "^1.2.9",
"convert-units": "^3.0.0-beta.5",
Expand All @@ -47,7 +47,8 @@
"typescript": "^4.9.5",
"use-interval": "^1.4.0",
"usehooks-ts": "^2.9.1",
"web-vitals": "^3.3.1"
"web-vitals": "^3.3.1",
"keycloak-js": "^21.1.1"
},
"scripts": {
"format": "prettier --ignore-path .gitignore --ignore-path .prettierignore --write --plugin-search-dir=. .",
Expand Down
2 changes: 1 addition & 1 deletion src/ThreeEditor/js/viewport/ViewportManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ function ViewManager(editor) {
);
}

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setPixelRatio(1);
renderer.setSize(container.dom.offsetWidth, container.dom.offsetHeight);

pmremGenerator = new THREE.PMREMGenerator(renderer);
Expand Down
53 changes: 45 additions & 8 deletions src/WrapperApp/components/InputEditor/InputFilesEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export function InputFilesEditor(props: InputFilesEditorProps) {
const { demoMode } = useConfig();
const inputFiles = props.inputFiles ?? _defaultShInputFiles;
const theme = useTheme();
const largeFileSize = 100_000;
const largeFileLinesLimit = 500;

const canBeDeleted = (name: string) => {
switch (props.simulator) {
Expand All @@ -48,6 +50,25 @@ export function InputFilesEditor(props: InputFilesEditorProps) {
props.onChange?.call(null, updateFn(inputFiles));
};

const truncateFile = (file: string) => {
var result: string[] = [];
var lines = file.split('\n').slice(0, largeFileLinesLimit);
let totalLength = 0;

for (const line of lines) {
if (totalLength + line.length <= largeFileSize) {
totalLength += line.length;
result.push(line);
} else {
result.push(line.substring(0, largeFileSize - totalLength));
break;
}
}

result.push("\n\n... Output truncated ...");
return result.join('\n');
};

return (
<Card sx={{ minHeight: '100%' }}>
<CardActions
Expand Down Expand Up @@ -108,6 +129,10 @@ export function InputFilesEditor(props: InputFilesEditorProps) {
return index1 - index2;
})
.map(([name, value]) => {
const isLargeFile = value.length > largeFileSize;
const content = !isLargeFile
? value
: truncateFile(value);
return (
<Box key={name}>
<h2>
Expand Down Expand Up @@ -151,18 +176,30 @@ export function InputFilesEditor(props: InputFilesEditorProps) {
Delete
</Button>
)}
{isLargeFile && (
<Box
color='error.main'
sx={{
ml: 1,
display: 'inline-flex',
fontSize: 'initial'
}}>
File is to large, displaying first few lines...
</Box>
)}
</h2>

<CodeEditor
aria-label={name + ' text field'}
value={value}
language='sql'
value={content}
placeholder={`Please enter ${name} content.`}
onChange={evn =>
updateInputFiles(old => {
return { ...old, [name]: evn.target.value };
})
}
onChange={evn => {
if (!isLargeFile) {
updateInputFiles(old => {
return { ...old, [name]: evn.target.value };
})
}
}}
disabled={isLargeFile}
data-color-mode={theme.palette.mode}
padding={15}
style={{
Expand Down
4 changes: 2 additions & 2 deletions src/WrapperApp/components/Panels/LoginPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useAuth } from '../../../services/AuthService';

export default function LoginPanel() {
const { altAuth } = useConfig();
const { login } = useAuth();
const { login, tokenLogin } = useAuth();
const theme = useTheme();

const [username, setUsername] = useState('');
Expand Down Expand Up @@ -95,7 +95,7 @@ export default function LoginPanel() {
color='info'
fullWidth
variant={theme.palette.mode === 'dark' ? 'outlined' : 'contained'}
onClick={() => login('demo', 'demo')}>
onClick={tokenLogin}>
Connect with PLGrid
</Button>
</>
Expand Down
35 changes: 15 additions & 20 deletions src/WrapperApp/components/Simulation/SimulationPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Box, Fade, Modal } from '@mui/material';
import { ChangeEvent, useCallback, useEffect, useState } from 'react';
import useInterval from 'use-interval';

import { useConfig } from '../../../config/ConfigService';
import { isFullSimulationData } from '../../../services/LoaderService';
Expand All @@ -15,6 +14,7 @@ import {
SimulationInputFiles,
StatusState
} from '../../../types/ResponseTypes';
import useIntervalAsync from '../../../util/hooks/useIntervalAsync';
import { InputFilesEditor } from '../InputEditor/InputFilesEditor';
import { DemoCardGrid, PaginatedSimulationsFromBackend } from './SimulationCardGrid';
import { PageNavigationProps, PageParamProps } from './SimulationPanelBar';
Expand Down Expand Up @@ -70,7 +70,7 @@ export default function SimulationPanel({
const [simulationInfo, setSimulationInfo] = useState<SimulationInfo[]>([]);
const [simulationsStatusData, setSimulationsStatusData] = useState<JobStatusData[]>([]);

const [simulationIDInterval, setSimulationIDInterval] = useState<number | null>(null);
const [simulationIDInterval, setSimulationIDInterval] = useState<number>();
const [controller] = useState(new AbortController());

const updateSimulationInfo = useCallback(
Expand All @@ -95,24 +95,23 @@ export default function SimulationPanel({
[controller.signal, getFullSimulationData, setResultsSimulationData, trackedId]
);

const updateSimulationData = useCallback(
() =>
!demoMode &&
getPageStatus(simulationInfo, true, handleBeforeCacheWrite, controller.signal).then(
s => {
setSimulationsStatusData([...s]);
}
),
[demoMode, getPageStatus, simulationInfo, handleBeforeCacheWrite, controller.signal]
);
const updateSimulationData = useCallback(() => {
if (demoMode) return Promise.resolve();

return getPageStatus(simulationInfo, true, handleBeforeCacheWrite, controller.signal).then(
s => {
setSimulationsStatusData([...s]);
}
);
}, [demoMode, getPageStatus, simulationInfo, handleBeforeCacheWrite, controller.signal]);

useEffect(() => {
if (!demoMode)
getHelloWorld(controller.signal)
.then(() => {
setBackendAlive(true);
updateSimulationInfo();
setSimulationIDInterval(10000);
setSimulationIDInterval(30000);
})
.catch(() => {
setBackendAlive(false);
Expand All @@ -121,7 +120,7 @@ export default function SimulationPanel({

return () => {
controller.abort();
setSimulationIDInterval(null);
setSimulationIDInterval(undefined);
};
}, [
controller.signal,
Expand All @@ -134,13 +133,9 @@ export default function SimulationPanel({
controller
]);

useInterval(updateSimulationInfo, simulationIDInterval, true);
useIntervalAsync(updateSimulationInfo, simulationIDInterval);

useInterval(
updateSimulationData,
simulationIDInterval !== null && simulationInfo.length > 0 ? 1000 : null,
true
);
useIntervalAsync(updateSimulationData, simulationInfo.length > 0 ? 1000 : simulationIDInterval);

const handleLoadResults = async (taskId: string | null, simulation: unknown) => {
if (taskId === null) return goToResults?.call(null);
Expand Down
108 changes: 91 additions & 17 deletions src/services/AuthService.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Keycloak from 'keycloak-js';
import ky, { HTTPError } from 'ky';
import { KyInstance } from 'ky/distribution/types/ky';
import { useSnackbar } from 'notistack';
Expand All @@ -15,8 +16,9 @@ import { hasFields } from '../util/customGuards';
import useIntervalAsync from '../util/hooks/useIntervalAsync';
import { snakeToCamelCase } from '../util/Notation/Notation';
import { createGenericContext, GenericContextProviderProps } from './GenericContext';
import { keycloakConfig } from './keycloakConfig';

type AuthUser = Pick<ResponseAuthStatus, 'username'>;
type AuthUser = Pick<ResponseAuthStatus, 'username' | 'source'>;

const isAuthUser = (obj: unknown): obj is AuthUser => {
return hasFields<string>(obj, 'username') && typeof obj.username === 'string';
Expand Down Expand Up @@ -64,18 +66,21 @@ export interface AuthContext {
isAuthorized: boolean;
isServerReachable: boolean;
login: (...args: RequestAuthLogin) => void;
tokenLogin: () => void;
logout: (...args: RequestAuthLogout) => void;
refresh: (...args: RequestAuthRefresh) => void;
authKy: KyInstance;
}

const [useAuth, AuthContextProvider] = createGenericContext<AuthContext>();
const keycloak = new Keycloak(keycloakConfig);

const Auth = ({ children }: GenericContextProviderProps) => {
const { backendUrl, demoMode } = useConfig();
const [user, setUser] = useState<AuthUser | null>(load(StorageKey.USER, isAuthUser));
const [reachInterval, setReachInterval] = useState<number | undefined>(undefined);
const [refreshInterval, setRefreshInterval] = useState<number | undefined>(180000);
const [reachInterval, setReachInterval] = useState<number>();
const [refreshInterval, setRefreshInterval] = useState<number | undefined>(180000); // 3 minutes in ms default interval for refresh token
const [keyCloakInterval, setKeyCloakInterval] = useState<number>();
const [isServerReachable, setIsServerReachable] = useState<boolean | null>(null);
const { enqueueSnackbar } = useSnackbar();

Expand Down Expand Up @@ -174,21 +179,52 @@ const Auth = ({ children }: GenericContextProviderProps) => {
reachServer();
}, [reachServer]);

const refresh = useCallback(() => {
if (demoMode || !isServerReachable) return Promise.resolve(setRefreshInterval(undefined));

return kyIntervalRef
.get(`auth/refresh`)
.json<ResponseAuthRefresh>()
.then(({ accessExp }) => setRefreshInterval(getRefreshDelay(accessExp)))
useEffect(() => {
if (user !== null && user.source !== 'keycloak' && isServerReachable)
setRefreshInterval(prev => (prev === undefined ? 3000 : prev));
// 3 seconds in ms default interval for refresh when logged in with username and password
else if (!isServerReachable || !user?.source) setRefreshInterval(undefined);
}, [isServerReachable, user]);

const tokenLogin = useCallback(() => {
const username = keycloak.tokenParsed?.preferred_username;
kyRef
.post(`auth/keycloak`, {
headers: {
Authorization: `Bearer ${keycloak.token}`
},
json: {
username
}
})
.then(() => {
setUser({
username,
source: 'keycloak'
});
})
.catch((_: HTTPError) => {});
}, [demoMode, isServerReachable, kyIntervalRef]);
}, [kyRef]);

useEffect(() => {
if (user !== null && refreshInterval === undefined && isServerReachable)
setRefreshInterval(3000);
else if (!isServerReachable || user === null) setRefreshInterval(undefined);
}, [isServerReachable, refreshInterval, user]);
keycloak
.init({
pkceMethod: 'S256',
checkLoginIframe: false
})
.then(auth => {
console.log('after init', auth);

if (auth) {
setKeyCloakInterval(
keycloak.tokenParsed?.exp !== undefined
? getRefreshDelay(keycloak.tokenParsed.exp * 1000)
: undefined
);
tokenLogin();
}
});
}, [tokenLogin]);

const login = useCallback(
(...[username, password]: RequestAuthLogin) => {
Expand All @@ -208,13 +244,50 @@ const Auth = ({ children }: GenericContextProviderProps) => {
);

const logout = useCallback(() => {
keycloak.logout();
kyRef
.delete(`auth/logout`)
.json<YaptideResponse>()
.then(_response => setUser(null))
.catch((_: HTTPError) => {});
.catch((_: HTTPError) => {})
.finally(() => setUser(null));
}, [kyRef]);

const tokenRefresh = useCallback(() => {
if (!keycloak.authenticated) {
setKeyCloakInterval(undefined);

return Promise.resolve();
}

return keycloak
.updateToken(300) // 5 minutes in seconds minimum remaining lifetime for token before refresh is allowed
.then(refreshed => {
if (refreshed)
console.log(
`Token refreshed ${keycloak.tokenParsed?.exp} -> ${keycloak.tokenParsed?.exp}`
);
})
.catch(() => {
console.log('Failed to refresh token');
logout();
});
}, [logout]);

useIntervalAsync(tokenRefresh, keycloak.authenticated ? keyCloakInterval : undefined);

const refresh = useCallback(async () => {
if (user?.source === 'keycloak') return tokenLogin();
if (demoMode || !isServerReachable) return Promise.resolve(setRefreshInterval(undefined));

try {
const { accessExp } = await kyIntervalRef
.get(`auth/refresh`)
.json<ResponseAuthRefresh>();

return setRefreshInterval(getRefreshDelay(accessExp));
} catch (_) {}
}, [demoMode, isServerReachable, kyIntervalRef, tokenLogin, user?.source]);

const authKy = useMemo(() => kyRef, [kyRef]);
const isAuthorized = useMemo(() => user !== null || demoMode, [demoMode, user]);

Expand All @@ -231,6 +304,7 @@ const Auth = ({ children }: GenericContextProviderProps) => {
isAuthorized,
isServerReachable: Boolean(isServerReachable),
login,
tokenLogin: keycloak.login,
logout,
authKy,
refresh
Expand Down
6 changes: 6 additions & 0 deletions src/services/keycloakConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const keycloakConfig = {
url: 'https://sso.pre.plgrid.pl/auth/',
realm: 'PLGrid',
clientId: 'yaptide-staging',
enableLogging: true
};
Loading

0 comments on commit 27310c6

Please sign in to comment.