mirror of
https://github.com/sasjs/server.git
synced 2026-01-15 18:00:05 +00:00
chore(log): used css module to declare classes
This commit is contained in:
888
web/package-lock.json
generated
888
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -61,6 +61,7 @@
|
|||||||
"style-loader": "^3.3.1",
|
"style-loader": "^3.3.1",
|
||||||
"ts-loader": "^9.2.6",
|
"ts-loader": "^9.2.6",
|
||||||
"typescript": "^4.5.2",
|
"typescript": "^4.5.2",
|
||||||
|
"typescript-plugin-css-modules": "^5.0.1",
|
||||||
"webpack": "5.64.3",
|
"webpack": "5.64.3",
|
||||||
"webpack-cli": "^4.9.2",
|
"webpack-cli": "^4.9.2",
|
||||||
"webpack-dev-server": "4.7.4"
|
"webpack-dev-server": "4.7.4"
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
.ChunkHeader {
|
||||||
|
color: #444;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 18px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
transition: 0.4s;
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 1px -1px,
|
||||||
|
rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ChunkDetails {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ChunkExpandIcon {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ChunkBody {
|
||||||
|
background-color: white;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ChunksContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LogContainer {
|
||||||
|
background-color: #fbfbfb;
|
||||||
|
border: 1px solid #e2e2e2;
|
||||||
|
border-radius: 3px;
|
||||||
|
min-height: 50px;
|
||||||
|
padding: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-family: Monaco, Courier, monospace;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LogWrapper {
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: calc(100vh - 130px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.LogBody {
|
||||||
|
overflow: auto;
|
||||||
|
height: calc(100vh - 220px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.TreeContainer {
|
||||||
|
background-color: white;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TabContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TabDownloadIcon {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.HighlightedLine {
|
||||||
|
background-color: #f6e30599;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Icon {
|
||||||
|
font-size: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GreenIcon {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy'
|
|||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
||||||
import CheckIcon from '@mui/icons-material/Check'
|
import CheckIcon from '@mui/icons-material/Check'
|
||||||
import FileDownloadIcon from '@mui/icons-material/FileDownload'
|
import FileDownloadIcon from '@mui/icons-material/FileDownload'
|
||||||
import { makeStyles } from '@mui/styles'
|
|
||||||
import {
|
import {
|
||||||
defaultChunkSize,
|
defaultChunkSize,
|
||||||
parseErrorsAndWarnings,
|
parseErrorsAndWarnings,
|
||||||
@@ -14,27 +13,8 @@ import {
|
|||||||
clearErrorsAndWarningsHtmlWrapping,
|
clearErrorsAndWarningsHtmlWrapping,
|
||||||
download
|
download
|
||||||
} from '../../../../../utils'
|
} from '../../../../../utils'
|
||||||
|
import { logStyles } from './logComponent'
|
||||||
const useStyles: any = makeStyles((theme: any) => ({
|
import classes from './log.module.css'
|
||||||
expansionDescription: {
|
|
||||||
backgroundColor: '#fbfbfb',
|
|
||||||
border: '1px solid #e2e2e2',
|
|
||||||
borderRadius: '3px',
|
|
||||||
minHeight: '50px',
|
|
||||||
padding: '10px',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
whiteSpace: 'pre-wrap',
|
|
||||||
fontFamily: 'Monaco, Courier, monospace',
|
|
||||||
position: 'relative',
|
|
||||||
width: '100%',
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
|
||||||
fontSize: theme.typography.pxToRem(12)
|
|
||||||
},
|
|
||||||
[theme.breakpoints.up('md')]: {
|
|
||||||
fontSize: theme.typography.pxToRem(16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
interface LogChunkProps {
|
interface LogChunkProps {
|
||||||
id: number
|
id: number
|
||||||
@@ -51,7 +31,7 @@ const LogChunk = (props: LogChunkProps) => {
|
|||||||
props.scrollToLogInstance
|
props.scrollToLogInstance
|
||||||
)
|
)
|
||||||
const rowText = clearErrorsAndWarningsHtmlWrapping(text)
|
const rowText = clearErrorsAndWarningsHtmlWrapping(text)
|
||||||
const classes = useStyles()
|
const styles = logStyles()
|
||||||
const [expanded, setExpanded] = useState(props.expanded)
|
const [expanded, setExpanded] = useState(props.expanded)
|
||||||
const [copied, setCopied] = useState(false)
|
const [copied, setCopied] = useState(false)
|
||||||
|
|
||||||
@@ -93,35 +73,17 @@ const LogChunk = (props: LogChunkProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div onClick={(evt) => props.onClick(evt, id)}>
|
<div onClick={(evt) => props.onClick(evt, id)}>
|
||||||
<button
|
<button className={classes.ChunkHeader}>
|
||||||
style={{
|
|
||||||
color: '#444',
|
|
||||||
cursor: 'pointer',
|
|
||||||
padding: '18px',
|
|
||||||
width: '100%',
|
|
||||||
textAlign: 'left',
|
|
||||||
border: 'none',
|
|
||||||
outline: 'none',
|
|
||||||
transition: '0.4s',
|
|
||||||
boxShadow:
|
|
||||||
'rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography variant="subtitle1">
|
<Typography variant="subtitle1">
|
||||||
<div
|
<div className={classes.ChunkDetails}>
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
gap: 6,
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>{`Lines: ${getLineRange()}`}</span>
|
<span>{`Lines: ${getLineRange()}`}</span>
|
||||||
{copied ? (
|
{copied ? (
|
||||||
<CheckIcon style={{ fontSize: 20, color: 'green' }} />
|
<CheckIcon
|
||||||
|
className={[classes.Icon, classes.GreenIcon].join(' ')}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ContentCopyIcon
|
<ContentCopyIcon
|
||||||
style={{ fontSize: 20 }}
|
className={classes.Icon}
|
||||||
onClick={(evt: SyntheticEvent) => {
|
onClick={(evt: SyntheticEvent) => {
|
||||||
evt.stopPropagation()
|
evt.stopPropagation()
|
||||||
|
|
||||||
@@ -143,7 +105,7 @@ const LogChunk = (props: LogChunkProps) => {
|
|||||||
{errors && errors.length !== 0 && (
|
{errors && errors.length !== 0 && (
|
||||||
<ErrorOutline
|
<ErrorOutline
|
||||||
color="error"
|
color="error"
|
||||||
style={{ fontSize: 20 }}
|
className={classes.Icon}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setScrollToLogInstance(errors[0])
|
setScrollToLogInstance(errors[0])
|
||||||
}}
|
}}
|
||||||
@@ -151,15 +113,17 @@ const LogChunk = (props: LogChunkProps) => {
|
|||||||
)}
|
)}
|
||||||
{warnings && warnings.length !== 0 && (
|
{warnings && warnings.length !== 0 && (
|
||||||
<Warning
|
<Warning
|
||||||
style={{ fontSize: 20, color: 'green' }}
|
className={[classes.Icon, classes.GreenIcon].join(' ')}
|
||||||
onClick={() => {
|
onClick={(evt) => {
|
||||||
|
if (expanded) evt.stopPropagation()
|
||||||
|
|
||||||
setScrollToLogInstance(warnings[0])
|
setScrollToLogInstance(warnings[0])
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}{' '}
|
)}{' '}
|
||||||
<ExpandMoreIcon
|
<ExpandMoreIcon
|
||||||
|
className={classes.ChunkExpandIcon}
|
||||||
style={{
|
style={{
|
||||||
marginLeft: 'auto',
|
|
||||||
transform: expanded ? 'rotate(180deg)' : 'unset'
|
transform: expanded ? 'rotate(180deg)' : 'unset'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -167,13 +131,17 @@ const LogChunk = (props: LogChunkProps) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
|
className={classes.ChunkBody}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: 'white',
|
display: expanded ? 'block' : 'none'
|
||||||
display: expanded ? 'block' : 'none',
|
|
||||||
overflow: 'hidden'
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div id={`log_container`} className={classes.expansionDescription}>
|
<div
|
||||||
|
id={`log_container`}
|
||||||
|
className={[styles.expansionDescription, classes.LogContainer].join(
|
||||||
|
' '
|
||||||
|
)}
|
||||||
|
>
|
||||||
<Highlight className={'html'} innerHTML={true}>
|
<Highlight className={'html'} innerHTML={true}>
|
||||||
{expanded ? text : ''}
|
{expanded ? text : ''}
|
||||||
</Highlight>
|
</Highlight>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, SyntheticEvent } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import TreeView from '@mui/lab/TreeView'
|
import TreeView from '@mui/lab/TreeView'
|
||||||
import TreeItem from '@mui/lab/TreeItem'
|
import TreeItem from '@mui/lab/TreeItem'
|
||||||
import { ChevronRight, ExpandMore } from '@mui/icons-material'
|
import { ChevronRight, ExpandMore } from '@mui/icons-material'
|
||||||
@@ -8,28 +8,12 @@ import { makeStyles } from '@mui/styles'
|
|||||||
import Highlight from 'react-highlight'
|
import Highlight from 'react-highlight'
|
||||||
import { LogObject, defaultChunkSize } from '../../../../../utils'
|
import { LogObject, defaultChunkSize } from '../../../../../utils'
|
||||||
import { RunTimeType } from '../../../../../context/appContext'
|
import { RunTimeType } from '../../../../../context/appContext'
|
||||||
import {
|
import { splitIntoChunks, LogInstance } from '../../../../../utils'
|
||||||
splitIntoChunks,
|
|
||||||
LogInstance,
|
|
||||||
clearErrorsAndWarningsHtmlWrapping,
|
|
||||||
download
|
|
||||||
} from '../../../../../utils'
|
|
||||||
import LogChunk from './logChunk'
|
import LogChunk from './logChunk'
|
||||||
import FileDownloadIcon from '@mui/icons-material/FileDownload'
|
import classes from './log.module.css'
|
||||||
import { Button } from '@mui/material'
|
|
||||||
|
|
||||||
const useStyles: any = makeStyles((theme: any) => ({
|
export const logStyles: any = makeStyles((theme: any) => ({
|
||||||
expansionDescription: {
|
expansionDescription: {
|
||||||
backgroundColor: '#fbfbfb',
|
|
||||||
border: '1px solid #e2e2e2',
|
|
||||||
borderRadius: '3px',
|
|
||||||
minHeight: '50px',
|
|
||||||
padding: '10px',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
whiteSpace: 'pre-wrap',
|
|
||||||
fontFamily: 'Monaco, Courier, monospace',
|
|
||||||
position: 'relative',
|
|
||||||
width: '100%',
|
|
||||||
[theme.breakpoints.down('sm')]: {
|
[theme.breakpoints.down('sm')]: {
|
||||||
fontSize: theme.typography.pxToRem(12)
|
fontSize: theme.typography.pxToRem(12)
|
||||||
},
|
},
|
||||||
@@ -57,7 +41,7 @@ const LogComponent = (props: LogComponentProps) => {
|
|||||||
)
|
)
|
||||||
const maxOpenedChunks = 2
|
const maxOpenedChunks = 2
|
||||||
|
|
||||||
const classes = useStyles()
|
const styles = logStyles()
|
||||||
|
|
||||||
const goToLogLine = (logInstance: LogInstance, ind: number) => {
|
const goToLogLine = (logInstance: LogInstance, ind: number) => {
|
||||||
let chunkNumber = 0
|
let chunkNumber = 0
|
||||||
@@ -145,26 +129,13 @@ const LogComponent = (props: LogComponentProps) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{selectedRunTime === RunTimeType.SAS && logObject.body ? (
|
{selectedRunTime === RunTimeType.SAS && logObject.body ? (
|
||||||
<div
|
<div id="logWrapper" className={classes.LogWrapper}>
|
||||||
id="logWrapper"
|
<div>
|
||||||
style={{ overflowY: 'auto', maxHeight: 'calc(100vh - 130px)' }}
|
|
||||||
>
|
|
||||||
<div style={{ backgroundColor: 'white' }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 10
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
{hasErrorsOrWarnings && (
|
{hasErrorsOrWarnings && (
|
||||||
<div>
|
<div className={classes.TreeContainer}>
|
||||||
<TreeView
|
<TreeView
|
||||||
defaultCollapseIcon={<ExpandMore />}
|
defaultCollapseIcon={<ExpandMore />}
|
||||||
defaultExpandIcon={<ChevronRight />}
|
defaultExpandIcon={<ChevronRight />}
|
||||||
style={{ paddingBottom: 10 }}
|
|
||||||
>
|
>
|
||||||
{logObject.errors && logObject.errors.length !== 0 && (
|
{logObject.errors && logObject.errors.length !== 0 && (
|
||||||
<TreeItem
|
<TreeItem
|
||||||
@@ -208,8 +179,7 @@ const LogComponent = (props: LogComponentProps) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className={classes.ChunksContainer}>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
|
|
||||||
{Array.isArray(logChunks) ? (
|
{Array.isArray(logChunks) ? (
|
||||||
logChunks.map((chunk: string, id: number) => (
|
logChunks.map((chunk: string, id: number) => (
|
||||||
<LogChunk
|
<LogChunk
|
||||||
@@ -245,7 +215,10 @@ const LogComponent = (props: LogComponentProps) => {
|
|||||||
<Typography
|
<Typography
|
||||||
id={`log_container`}
|
id={`log_container`}
|
||||||
variant="h5"
|
variant="h5"
|
||||||
className={classes.expansionDescription}
|
className={[
|
||||||
|
styles.expansionDescription,
|
||||||
|
classes.LogContainer
|
||||||
|
].join(' ')}
|
||||||
>
|
>
|
||||||
<Highlight className={'html'} innerHTML={true}>
|
<Highlight className={'html'} innerHTML={true}>
|
||||||
{logChunks}
|
{logChunks}
|
||||||
@@ -257,10 +230,7 @@ const LogComponent = (props: LogComponentProps) => {
|
|||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<h2>Log</h2>
|
<h2>Log</h2>
|
||||||
<pre
|
<pre id="log" className={classes.LogBody}>
|
||||||
id="log"
|
|
||||||
style={{ overflow: 'auto', height: 'calc(100vh - 220px)' }}
|
|
||||||
>
|
|
||||||
{logBody}
|
{logBody}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
clearErrorsAndWarningsHtmlWrapping
|
clearErrorsAndWarningsHtmlWrapping
|
||||||
} from '../../../../../utils'
|
} from '../../../../../utils'
|
||||||
import Tooltip from '@mui/material/Tooltip'
|
import Tooltip from '@mui/material/Tooltip'
|
||||||
|
import classes from './log.module.css'
|
||||||
|
|
||||||
interface LogTabProps {
|
interface LogTabProps {
|
||||||
log: LogObject
|
log: LogObject
|
||||||
@@ -15,28 +16,23 @@ const LogTabWithIcons = (props: LogTabProps) => {
|
|||||||
const { errors, warnings, body } = props.log
|
const { errors, warnings, body } = props.log
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={classes.TabContainer}>
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
gap: 6,
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>log</span>
|
<span>log</span>
|
||||||
{errors && errors.length !== 0 && (
|
{errors && errors.length !== 0 && (
|
||||||
<ErrorOutline color="error" style={{ fontSize: 20 }} />
|
<ErrorOutline color="error" className={classes.Icon} />
|
||||||
)}
|
)}
|
||||||
{warnings && warnings.length !== 0 && (
|
{warnings && warnings.length !== 0 && (
|
||||||
<Warning style={{ fontSize: 20, color: 'green' }} />
|
<Warning className={[classes.Icon, classes.GreenIcon].join(' ')} />
|
||||||
)}{' '}
|
)}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title="Download entire log"
|
title="Download entire log"
|
||||||
onClick={(evt) => {
|
onClick={(evt) => {
|
||||||
download(evt, clearErrorsAndWarningsHtmlWrapping(body))
|
download(evt, clearErrorsAndWarningsHtmlWrapping(body))
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FileDownloadIcon style={{ fontSize: 20, marginLeft: 20 }} />
|
<FileDownloadIcon
|
||||||
|
className={[classes.Icon, classes.TabDownloadIcon].join(' ')}
|
||||||
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
4
web/src/types/declaration.d.ts
vendored
Normal file
4
web/src/types/declaration.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
declare module '*.module.css' {
|
||||||
|
const classes: { [key: string]: string }
|
||||||
|
export default classes
|
||||||
|
}
|
||||||
@@ -14,7 +14,8 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx",
|
||||||
|
"plugins": [{ "name": "typescript-plugin-css-modules" }]
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,9 +32,18 @@ const config: Configuration = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/i,
|
||||||
exclude: ['/node_modules/'],
|
use: [
|
||||||
use: ['style-loader', 'css-loader']
|
'style-loader',
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: {
|
||||||
|
modules: {
|
||||||
|
localIdentName: '[local]--[hash:base64:5]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.scss$/,
|
test: /\.scss$/,
|
||||||
|
|||||||
Reference in New Issue
Block a user