1
0
mirror of https://github.com/sasjs/server.git synced 2025-12-10 11:24:35 +00:00

chore(log): used css module to declare classes

This commit is contained in:
Yury Shkoda
2023-04-27 17:52:57 +03:00
parent 777b3a55be
commit 87e9172cfc
9 changed files with 856 additions and 297 deletions

888
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -61,6 +61,7 @@
"style-loader": "^3.3.1",
"ts-loader": "^9.2.6",
"typescript": "^4.5.2",
"typescript-plugin-css-modules": "^5.0.1",
"webpack": "5.64.3",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "4.7.4"

View File

@@ -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;
}

View File

@@ -6,7 +6,6 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import CheckIcon from '@mui/icons-material/Check'
import FileDownloadIcon from '@mui/icons-material/FileDownload'
import { makeStyles } from '@mui/styles'
import {
defaultChunkSize,
parseErrorsAndWarnings,
@@ -14,27 +13,8 @@ import {
clearErrorsAndWarningsHtmlWrapping,
download
} from '../../../../../utils'
const useStyles: any = makeStyles((theme: any) => ({
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)
}
}
}))
import { logStyles } from './logComponent'
import classes from './log.module.css'
interface LogChunkProps {
id: number
@@ -51,7 +31,7 @@ const LogChunk = (props: LogChunkProps) => {
props.scrollToLogInstance
)
const rowText = clearErrorsAndWarningsHtmlWrapping(text)
const classes = useStyles()
const styles = logStyles()
const [expanded, setExpanded] = useState(props.expanded)
const [copied, setCopied] = useState(false)
@@ -93,35 +73,17 @@ const LogChunk = (props: LogChunkProps) => {
return (
<div onClick={(evt) => props.onClick(evt, id)}>
<button
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'
}}
>
<button className={classes.ChunkHeader}>
<Typography variant="subtitle1">
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: 6,
alignItems: 'center'
}}
>
<div className={classes.ChunkDetails}>
<span>{`Lines: ${getLineRange()}`}</span>
{copied ? (
<CheckIcon style={{ fontSize: 20, color: 'green' }} />
<CheckIcon
className={[classes.Icon, classes.GreenIcon].join(' ')}
/>
) : (
<ContentCopyIcon
style={{ fontSize: 20 }}
className={classes.Icon}
onClick={(evt: SyntheticEvent) => {
evt.stopPropagation()
@@ -143,7 +105,7 @@ const LogChunk = (props: LogChunkProps) => {
{errors && errors.length !== 0 && (
<ErrorOutline
color="error"
style={{ fontSize: 20 }}
className={classes.Icon}
onClick={() => {
setScrollToLogInstance(errors[0])
}}
@@ -151,15 +113,17 @@ const LogChunk = (props: LogChunkProps) => {
)}
{warnings && warnings.length !== 0 && (
<Warning
style={{ fontSize: 20, color: 'green' }}
onClick={() => {
className={[classes.Icon, classes.GreenIcon].join(' ')}
onClick={(evt) => {
if (expanded) evt.stopPropagation()
setScrollToLogInstance(warnings[0])
}}
/>
)}{' '}
<ExpandMoreIcon
className={classes.ChunkExpandIcon}
style={{
marginLeft: 'auto',
transform: expanded ? 'rotate(180deg)' : 'unset'
}}
/>
@@ -167,13 +131,17 @@ const LogChunk = (props: LogChunkProps) => {
</Typography>
</button>
<div
className={classes.ChunkBody}
style={{
backgroundColor: 'white',
display: expanded ? 'block' : 'none',
overflow: 'hidden'
display: expanded ? 'block' : 'none'
}}
>
<div id={`log_container`} className={classes.expansionDescription}>
<div
id={`log_container`}
className={[styles.expansionDescription, classes.LogContainer].join(
' '
)}
>
<Highlight className={'html'} innerHTML={true}>
{expanded ? text : ''}
</Highlight>

View File

@@ -1,4 +1,4 @@
import { useEffect, useState, SyntheticEvent } from 'react'
import { useEffect, useState } from 'react'
import TreeView from '@mui/lab/TreeView'
import TreeItem from '@mui/lab/TreeItem'
import { ChevronRight, ExpandMore } from '@mui/icons-material'
@@ -8,28 +8,12 @@ import { makeStyles } from '@mui/styles'
import Highlight from 'react-highlight'
import { LogObject, defaultChunkSize } from '../../../../../utils'
import { RunTimeType } from '../../../../../context/appContext'
import {
splitIntoChunks,
LogInstance,
clearErrorsAndWarningsHtmlWrapping,
download
} from '../../../../../utils'
import { splitIntoChunks, LogInstance } from '../../../../../utils'
import LogChunk from './logChunk'
import FileDownloadIcon from '@mui/icons-material/FileDownload'
import { Button } from '@mui/material'
import classes from './log.module.css'
const useStyles: any = makeStyles((theme: any) => ({
export const logStyles: any = makeStyles((theme: any) => ({
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)
},
@@ -57,7 +41,7 @@ const LogComponent = (props: LogComponentProps) => {
)
const maxOpenedChunks = 2
const classes = useStyles()
const styles = logStyles()
const goToLogLine = (logInstance: LogInstance, ind: number) => {
let chunkNumber = 0
@@ -145,26 +129,13 @@ const LogComponent = (props: LogComponentProps) => {
return (
<>
{selectedRunTime === RunTimeType.SAS && logObject.body ? (
<div
id="logWrapper"
style={{ overflowY: 'auto', maxHeight: 'calc(100vh - 130px)' }}
>
<div style={{ backgroundColor: 'white' }}>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: 10
}}
></div>
<div id="logWrapper" className={classes.LogWrapper}>
<div>
{hasErrorsOrWarnings && (
<div>
<div className={classes.TreeContainer}>
<TreeView
defaultCollapseIcon={<ExpandMore />}
defaultExpandIcon={<ChevronRight />}
style={{ paddingBottom: 10 }}
>
{logObject.errors && logObject.errors.length !== 0 && (
<TreeItem
@@ -208,8 +179,7 @@ const LogComponent = (props: LogComponentProps) => {
</div>
)}
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
<div className={classes.ChunksContainer}>
{Array.isArray(logChunks) ? (
logChunks.map((chunk: string, id: number) => (
<LogChunk
@@ -245,7 +215,10 @@ const LogComponent = (props: LogComponentProps) => {
<Typography
id={`log_container`}
variant="h5"
className={classes.expansionDescription}
className={[
styles.expansionDescription,
classes.LogContainer
].join(' ')}
>
<Highlight className={'html'} innerHTML={true}>
{logChunks}
@@ -257,10 +230,7 @@ const LogComponent = (props: LogComponentProps) => {
) : (
<div>
<h2>Log</h2>
<pre
id="log"
style={{ overflow: 'auto', height: 'calc(100vh - 220px)' }}
>
<pre id="log" className={classes.LogBody}>
{logBody}
</pre>
</div>

View File

@@ -6,6 +6,7 @@ import {
clearErrorsAndWarningsHtmlWrapping
} from '../../../../../utils'
import Tooltip from '@mui/material/Tooltip'
import classes from './log.module.css'
interface LogTabProps {
log: LogObject
@@ -15,28 +16,23 @@ const LogTabWithIcons = (props: LogTabProps) => {
const { errors, warnings, body } = props.log
return (
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: 6,
alignItems: 'center'
}}
>
<div className={classes.TabContainer}>
<span>log</span>
{errors && errors.length !== 0 && (
<ErrorOutline color="error" style={{ fontSize: 20 }} />
<ErrorOutline color="error" className={classes.Icon} />
)}
{warnings && warnings.length !== 0 && (
<Warning style={{ fontSize: 20, color: 'green' }} />
)}{' '}
<Warning className={[classes.Icon, classes.GreenIcon].join(' ')} />
)}
<Tooltip
title="Download entire log"
onClick={(evt) => {
download(evt, clearErrorsAndWarningsHtmlWrapping(body))
}}
>
<FileDownloadIcon style={{ fontSize: 20, marginLeft: 20 }} />
<FileDownloadIcon
className={[classes.Icon, classes.TabDownloadIcon].join(' ')}
/>
</Tooltip>
</div>
)

4
web/src/types/declaration.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module '*.module.css' {
const classes: { [key: string]: string }
export default classes
}

View File

@@ -14,7 +14,8 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"plugins": [{ "name": "typescript-plugin-css-modules" }]
},
"include": ["src"]
}

View File

@@ -32,9 +32,18 @@ const config: Configuration = {
]
},
{
test: /\.css$/,
exclude: ['/node_modules/'],
use: ['style-loader', 'css-loader']
test: /\.css$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]--[hash:base64:5]'
}
}
}
]
},
{
test: /\.scss$/,