[arvados-workbench2] created: 2.4.0-154-gf21357c3
git repository hosting
git at public.arvados.org
Mon Jul 11 16:19:12 UTC 2022
at f21357c3af5f040b020b6363b4adff5762566b5c (commit)
commit f21357c3af5f040b020b6363b4adff5762566b5c
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Tue Jul 5 11:12:14 2022 -0300
18975: Improves word wrapping status indication on log viewer.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/src/components/icon/icon.tsx b/src/components/icon/icon.tsx
index 19b4beea..db603597 100644
--- a/src/components/icon/icon.tsx
+++ b/src/components/icon/icon.tsx
@@ -77,6 +77,7 @@ import NotInterested from '@material-ui/icons/NotInterested';
// Import FontAwesome icons
import { library } from '@fortawesome/fontawesome-svg-core';
import { faPencilAlt, faSlash, faUsers, faEllipsisH } from '@fortawesome/free-solid-svg-icons';
+import { FormatAlignLeft } from '@material-ui/icons';
library.add(
faPencilAlt,
faSlash,
@@ -180,7 +181,8 @@ export const CanReadIcon: IconType = (props) => <RemoveRedEye {...props} />;
export const CanWriteIcon: IconType = (props) => <Edit {...props} />;
export const CanManageIcon: IconType = (props) => <Computer {...props} />;
export const AddUserIcon: IconType = (props) => <PersonAdd {...props} />;
-export const WordWrapIcon: IconType = (props) => <WrapText {...props} />;
+export const WordWrapOnIcon: IconType = (props) => <WrapText {...props} />;
+export const WordWrapOffIcon: IconType = (props) => <FormatAlignLeft {...props} />;
export const TextIncreaseIcon: IconType = (props) => <TextIncrease {...props} />;
export const TextDecreaseIcon: IconType = (props) => <TextDecrease {...props} />;
export const DeactivateUserIcon: IconType = (props) => <NotInterested {...props} />;
diff --git a/src/views/process-panel/process-log-card.tsx b/src/views/process-panel/process-log-card.tsx
index ac409ec1..936b31a5 100644
--- a/src/views/process-panel/process-log-card.tsx
+++ b/src/views/process-panel/process-log-card.tsx
@@ -24,7 +24,8 @@ import {
MaximizeIcon,
TextDecreaseIcon,
TextIncreaseIcon,
- WordWrapIcon
+ WordWrapOffIcon,
+ WordWrapOnIcon,
} from 'components/icon/icon';
import { Process } from 'store/processes/process';
import { MPVPanelProps } from 'components/multi-panel-view/multi-panel-view';
@@ -92,7 +93,7 @@ export const ProcessLogsCard = withStyles(styles)(
({ classes, process, filters, selectedFilter, lines,
onLogFilterChange, navigateToLog, onCopy,
doHidePanel, doMaximizePanel, panelMaximized, panelName }: ProcessLogsCardProps) => {
- const [wordWrapToggle, setWordWrapToggle] = useState<boolean>(true);
+ const [wordWrap, setWordWrap] = useState<boolean>(true);
const [fontSize, setFontSize] = useState<number>(3);
const fontBaseSize = 10;
const fontStepSize = 1;
@@ -130,9 +131,9 @@ export const ProcessLogsCard = withStyles(styles)(
</Tooltip>
</Grid>
<Grid item>
- <Tooltip title="Toggle word wrapping" disableFocusListener>
- <IconButton onClick={() => setWordWrapToggle(!wordWrapToggle)}>
- <WordWrapIcon />
+ <Tooltip title={`${wordWrap ? 'Disable' : 'Enable'} word wrapping`} disableFocusListener>
+ <IconButton onClick={() => setWordWrap(!wordWrap)}>
+ {wordWrap ? <WordWrapOffIcon /> : <WordWrapOnIcon />}
</IconButton>
</Tooltip>
</Grid>
@@ -166,7 +167,7 @@ export const ProcessLogsCard = withStyles(styles)(
spacing={24}
direction='column'>
<Grid className={classes.logViewer} item xs>
- <ProcessLogCodeSnippet fontSize={fontBaseSize+(fontStepSize*fontSize)} wordWrap={wordWrapToggle} lines={lines} />
+ <ProcessLogCodeSnippet fontSize={fontBaseSize+(fontStepSize*fontSize)} wordWrap={wordWrap} lines={lines} />
</Grid>
</Grid>
: <DefaultView
commit 991f6bf39cad15d07a11e794dc8344764218d990
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Thu Jul 7 19:16:17 2022 -0300
18975: Makes UUID & PDH clicking on log viewer to open a new tab.
In those cases where there isn't a valid route, it'll still show a
snackbar with an error.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts
index c8811bf4..146530ca 100644
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@ -14,7 +14,7 @@ import { pluginConfig } from 'plugins';
import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
import { USERS_PANEL_LABEL, MY_ACCOUNT_PANEL_LABEL } from 'store/breadcrumbs/breadcrumbs-actions';
-const navigationNotAvailable = (id: string) =>
+export const navigationNotAvailable = (id: string) =>
snackbarActions.OPEN_SNACKBAR({
message: `${id} not available`,
hideDuration: 3000,
diff --git a/src/views/process-panel/process-log-code-snippet.tsx b/src/views/process-panel/process-log-code-snippet.tsx
index 92e4ffba..2b7391c2 100644
--- a/src/views/process-panel/process-log-code-snippet.tsx
+++ b/src/views/process-panel/process-log-code-snippet.tsx
@@ -13,10 +13,12 @@ import {
import grey from '@material-ui/core/colors/grey';
import { ArvadosTheme } from 'common/custom-theme';
import { Link, Typography } from '@material-ui/core';
-import { navigateTo } from 'store/navigation/navigation-action';
+import { navigationNotAvailable } from 'store/navigation/navigation-action';
import { Dispatch } from 'redux';
import { connect, DispatchProp } from 'react-redux';
import classNames from 'classnames';
+import { FederationConfig, getNavUrl } from 'routes/routes';
+import { RootState } from 'store/store';
type CssRules = 'root' | 'wordWrap' | 'logText';
@@ -58,7 +60,11 @@ interface ProcessLogCodeSnippetProps {
wordWrap?: boolean;
}
-const renderLinks = (fontSize: number, dispatch: Dispatch) => (text: string) => {
+interface ProcessLogCodeSnippetAuthProps {
+ auth: FederationConfig;
+}
+
+const renderLinks = (fontSize: number, auth: FederationConfig, dispatch: Dispatch) => (text: string) => {
// Matches UUIDs & PDHs
const REGEX = /[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}|[0-9a-f]{32}\+\d+/g;
const links = text.match(REGEX);
@@ -70,7 +76,14 @@ const renderLinks = (fontSize: number, dispatch: Dispatch) => (text: string) =>
<React.Fragment key={index}>
{part}
{links[index] &&
- <Link onClick={() => dispatch<any>(navigateTo(links[index]))}
+ <Link onClick={() => {
+ const url = getNavUrl(links[index], auth)
+ if (url) {
+ window.open(`${window.location.origin}${url}`, '_blank');
+ } else {
+ dispatch(navigationNotAvailable(links[index]));
+ }
+ }}
style={ {cursor: 'pointer'} }>
{links[index]}
</Link>}
@@ -79,8 +92,12 @@ const renderLinks = (fontSize: number, dispatch: Dispatch) => (text: string) =>
</Typography>;
};
-export const ProcessLogCodeSnippet = withStyles(styles)(connect()(
- ({classes, lines, fontSize, dispatch, wordWrap}: ProcessLogCodeSnippetProps & WithStyles<CssRules> & DispatchProp) => {
+const mapStateToProps = (state: RootState): ProcessLogCodeSnippetAuthProps => ({
+ auth: state.auth,
+});
+
+export const ProcessLogCodeSnippet = withStyles(styles)(connect(mapStateToProps)(
+ ({classes, lines, fontSize, auth, dispatch, wordWrap}: ProcessLogCodeSnippetProps & WithStyles<CssRules> & ProcessLogCodeSnippetAuthProps & DispatchProp) => {
const [followMode, setFollowMode] = useState<boolean>(true);
const scrollRef = useRef<HTMLDivElement>(null);
@@ -104,7 +121,7 @@ export const ProcessLogCodeSnippet = withStyles(styles)(connect()(
{ lines.map((line: string, index: number) =>
<Typography key={index} component="pre"
className={classNames(classes.logText, wordWrap ? classes.wordWrap : undefined)}>
- {renderLinks(fontSize, dispatch)(line)}
+ {renderLinks(fontSize, auth, dispatch)(line)}
</Typography>
) }
</div>
commit 104cdcd12eefc2a0de085acda96c59566973a499
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Thu Jul 7 17:47:01 2022 -0300
18975: Fixes log viewer's follow mode when maximized.
Added a 10% of scroll margin so that it's guaranteed that follow mode is
enabled no matter the log viewer's height.
The side effect is that the scrolling gets a "snap effect" when the user
gets close to the end of the log.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/src/views/process-panel/process-log-code-snippet.tsx b/src/views/process-panel/process-log-code-snippet.tsx
index 261075c0..92e4ffba 100644
--- a/src/views/process-panel/process-log-code-snippet.tsx
+++ b/src/views/process-panel/process-log-code-snippet.tsx
@@ -95,7 +95,7 @@ export const ProcessLogCodeSnippet = withStyles(styles)(connect()(
<div ref={scrollRef} className={classes.root}
onScroll={(e) => {
const elem = e.target as HTMLDivElement;
- if (elem.scrollTop + elem.clientHeight >= elem.scrollHeight) {
+ if (elem.scrollTop + (elem.clientHeight*1.1) >= elem.scrollHeight) {
setFollowMode(true);
} else {
setFollowMode(false);
commit ff6acf21a55947ef4c4d4740710f84bac2fa71c3
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Thu Jul 7 17:23:56 2022 -0300
18975: Adds keepstore logs to the log viewer filters.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/src/models/log.ts b/src/models/log.ts
index 63e953bb..f5d351ac 100644
--- a/src/models/log.ts
+++ b/src/models/log.ts
@@ -17,6 +17,7 @@ export enum LogEventType {
STDOUT = 'stdout',
STDERR = 'stderr',
CONTAINER = 'container',
+ KEEPSTORE = 'keepstore',
}
export interface LogResource extends Resource, ResourceWithProperties {
diff --git a/src/store/process-logs-panel/process-logs-panel-actions.ts b/src/store/process-logs-panel/process-logs-panel-actions.ts
index ca950ffe..d4f5ab59 100644
--- a/src/store/process-logs-panel/process-logs-panel-actions.ts
+++ b/src/store/process-logs-panel/process-logs-panel-actions.ts
@@ -141,4 +141,5 @@ const PROCESS_PANEL_LOG_EVENT_TYPES = [
LogEventType.STDERR,
LogEventType.STDOUT,
LogEventType.CONTAINER,
+ LogEventType.KEEPSTORE,
];
commit be4106e10460b7a0bc0e3a2ab30573c4a8d2a6ff
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Thu Jul 7 17:16:47 2022 -0300
18975: Adds 'Main logs' filter selection. Fixes filter dynamic population.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/cypress/integration/process.spec.js b/cypress/integration/process.spec.js
index faf70c49..55290fa3 100644
--- a/cypress/integration/process.spec.js
+++ b/cypress/integration/process.spec.js
@@ -168,8 +168,15 @@ describe('Process tests', function() {
cy.getAll('@stdoutLogs', '@nodeInfoLogs', '@crunchRunLogs').then(function() {
cy.loginAs(activeUser);
cy.goToPath(`/processes/${containerRequest.uuid}`);
- // Should should all logs
- cy.get('[data-cy=process-logs-filter]').should('contain', 'All logs');
+ // Should show main logs by default
+ cy.get('[data-cy=process-logs-filter]').should('contain', 'Main logs');
+ cy.get('[data-cy=process-logs]')
+ .should('contain', stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
+ .and('not.contain', nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
+ .and('contain', crunchRunLogs[Math.floor(Math.random() * crunchRunLogs.length)]);
+ // Select 'All logs'
+ cy.get('[data-cy=process-logs-filter]').click();
+ cy.get('body').contains('li', 'All logs').click();
cy.get('[data-cy=process-logs]')
.should('contain', stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)])
.and('contain', nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)])
diff --git a/src/models/log.ts b/src/models/log.ts
index 20060f88..63e953bb 100644
--- a/src/models/log.ts
+++ b/src/models/log.ts
@@ -23,6 +23,6 @@ export interface LogResource extends Resource, ResourceWithProperties {
kind: ResourceKind.LOG;
objectUuid: string;
eventAt: string;
- eventType: string;
+ eventType: LogEventType;
summary: string;
}
diff --git a/src/store/process-logs-panel/process-logs-panel-actions.ts b/src/store/process-logs-panel/process-logs-panel-actions.ts
index b0ddd7ee..ca950ffe 100644
--- a/src/store/process-logs-panel/process-logs-panel-actions.ts
+++ b/src/store/process-logs-panel/process-logs-panel-actions.ts
@@ -45,21 +45,25 @@ export const addProcessLogsPanelItem = (message: ResourceEventMessage<{ text: st
async (dispatch: Dispatch, getState: () => RootState, { logService }: ServiceRepository) => {
if (PROCESS_PANEL_LOG_EVENT_TYPES.indexOf(message.eventType) > -1) {
const uuid = getProcessLogsPanelCurrentUuid(getState().router);
- if (uuid) {
- const process = getProcess(uuid)(getState().resources);
- if (process) {
- const { containerRequest, container } = process;
- if (message.objectUuid === containerRequest.uuid
- || (container && message.objectUuid === container.uuid)) {
- dispatch(processLogsPanelActions.ADD_PROCESS_LOGS_PANEL_ITEM({
- logType: COMBINED_FILTER_TYPE,
- log: message.properties.text
- }));
- dispatch(processLogsPanelActions.ADD_PROCESS_LOGS_PANEL_ITEM({
- logType: message.eventType,
- log: message.properties.text
- }));
- }
+ if (!uuid) { return }
+ const process = getProcess(uuid)(getState().resources);
+ if (!process) { return }
+ const { containerRequest, container } = process;
+ if (message.objectUuid === containerRequest.uuid
+ || (container && message.objectUuid === container.uuid)) {
+ dispatch(processLogsPanelActions.ADD_PROCESS_LOGS_PANEL_ITEM({
+ logType: ALL_FILTER_TYPE,
+ log: message.properties.text
+ }));
+ dispatch(processLogsPanelActions.ADD_PROCESS_LOGS_PANEL_ITEM({
+ logType: message.eventType,
+ log: message.properties.text
+ }));
+ if (MAIN_EVENT_TYPES.indexOf(message.eventType) > -1) {
+ dispatch(processLogsPanelActions.ADD_PROCESS_LOGS_PANEL_ITEM({
+ logType: MAIN_FILTER_TYPE,
+ log: message.properties.text
+ }));
}
}
}
@@ -84,6 +88,9 @@ const loadContainerLogs = async (containerUuid: string, logService: LogService)
const createInitialLogPanelState = (logResources: LogResource[]) => {
const allLogs = logsToLines(logResources);
+ const mainLogs = logsToLines(logResources.filter(
+ e => MAIN_EVENT_TYPES.indexOf(e.eventType) > -1
+ ));
const groupedLogResources = groupBy(logResources, log => log.eventType);
const groupedLogs = Object
.keys(groupedLogResources)
@@ -91,8 +98,12 @@ const createInitialLogPanelState = (logResources: LogResource[]) => {
...grouped,
[key]: logsToLines(groupedLogResources[key])
}), {});
- const filters = [COMBINED_FILTER_TYPE, ...Object.keys(groupedLogs)];
- const logs = { [COMBINED_FILTER_TYPE]: allLogs, ...groupedLogs };
+ const filters = [MAIN_FILTER_TYPE, ALL_FILTER_TYPE, ...Object.keys(groupedLogs)];
+ const logs = {
+ [MAIN_FILTER_TYPE]: mainLogs,
+ [ALL_FILTER_TYPE]: allLogs,
+ ...groupedLogs
+ };
return { filters, logs };
};
@@ -111,7 +122,14 @@ export const navigateToLogCollection = (uuid: string) =>
const MAX_AMOUNT_OF_LOGS = 10000;
-const COMBINED_FILTER_TYPE = 'All logs';
+const ALL_FILTER_TYPE = 'All logs';
+
+const MAIN_FILTER_TYPE = 'Main logs';
+const MAIN_EVENT_TYPES = [
+ LogEventType.CRUNCH_RUN,
+ LogEventType.STDERR,
+ LogEventType.STDOUT,
+];
const PROCESS_PANEL_LOG_EVENT_TYPES = [
LogEventType.ARV_MOUNT,
diff --git a/src/store/process-logs-panel/process-logs-panel-reducer.ts b/src/store/process-logs-panel/process-logs-panel-reducer.ts
index c7d694c0..c502f1b1 100644
--- a/src/store/process-logs-panel/process-logs-panel-reducer.ts
+++ b/src/store/process-logs-panel/process-logs-panel-reducer.ts
@@ -24,10 +24,13 @@ export const processLogsPanelReducer = (state = initialState, action: ProcessLog
selectedFilter
}),
ADD_PROCESS_LOGS_PANEL_ITEM: ({ logType, log }) => {
+ const filters = state.filters.indexOf(logType) > -1
+ ? state.filters
+ : [...state.filters, logType];
const currentLogs = state.logs[logType] || [];
const logsOfType = [...currentLogs, log];
const logs = { ...state.logs, [logType]: logsOfType };
- return { ...state, logs };
+ return { ...state, logs, filters };
},
default: () => state,
});
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list