mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-30 02:58:05 +08:00
Merge pull request #6882 from nwind/feat-log-ansi-color
feat: log 组件支持简单 ansi 颜色,可配置 credentials 设置 Closes #6039
This commit is contained in:
commit
6b978cc2dc
@ -93,7 +93,6 @@ public class StreamingResponseBodyController {
|
||||
2. 设置 `maxLength`,限制最大显示行数
|
||||
- 优点:某一行日志很长的时候会自动折行
|
||||
- 缺点:无法查看之前的日志
|
||||
3. 试试通过 `"disableColor": false` 关闭 ANSI 颜色
|
||||
|
||||
## 自动滚动到底部
|
||||
|
||||
@ -160,14 +159,16 @@ public class StreamingResponseBodyController {
|
||||
|
||||
## 属性表
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ----------- | --------- | ------ | -------------------------------------------------------- |
|
||||
| height | `number` | 500 | 展示区域高度 |
|
||||
| className | `string` | | 外层 CSS 类名 |
|
||||
| autoScroll | `boolean` | true | 是否自动滚动 |
|
||||
| placeholder | `string` | | 加载中的文字 |
|
||||
| encoding | `string` | utf-8 | 返回内容的字符编码 |
|
||||
| source | `string` | | 接口 |
|
||||
| rowHeight | `number` | | 设置每行高度,将会开启虚拟渲染 |
|
||||
| maxLength | `number` | | 最大显示行数 |
|
||||
| operation | `Array` | | 可选日志操作:['stop','restart',clear','showLineNumber','filter'] |
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ------------ | --------- | --------- | ----------------------------------------------------------------- |
|
||||
| height | `number` | 500 | 展示区域高度 |
|
||||
| className | `string` | | 外层 CSS 类名 |
|
||||
| autoScroll | `boolean` | true | 是否自动滚动 |
|
||||
| disableColor | `boolean` | false | 是否禁用 ansi 颜色支持 |
|
||||
| placeholder | `string` | | 加载中的文字 |
|
||||
| encoding | `string` | utf-8 | 返回内容的字符编码 |
|
||||
| source | `string` | | 接口 |
|
||||
| credentials | `string` | 'include' | fetch 的 credentials 设置 |
|
||||
| rowHeight | `number` | | 设置每行高度,将会开启虚拟渲染 |
|
||||
| maxLength | `number` | | 最大显示行数 |
|
||||
| operation | `Array` | | 可选日志操作:['stop','restart',clear','showLineNumber','filter'] |
|
||||
|
@ -6,6 +6,29 @@ import {buildApi, isApiOutdated, Renderer, RendererProps} from 'amis-core';
|
||||
import {BaseSchema} from '../Schema';
|
||||
import {Icon, SearchBox, VirtualList} from 'amis-ui';
|
||||
|
||||
const foregroundColors = {
|
||||
'30': 'black',
|
||||
'31': 'red',
|
||||
'32': 'green',
|
||||
'33': 'yellow',
|
||||
'34': 'blue',
|
||||
'35': 'magenta',
|
||||
'36': 'cyan',
|
||||
'37': 'white',
|
||||
'90': 'grey'
|
||||
} as {[key: string]: string};
|
||||
|
||||
const backgroundColors = {
|
||||
'40': 'black',
|
||||
'41': 'red',
|
||||
'42': 'green',
|
||||
'43': 'yellow',
|
||||
'44': 'blue',
|
||||
'45': 'magenta',
|
||||
'46': 'cyan',
|
||||
'47': 'white'
|
||||
} as {[key: string]: string};
|
||||
|
||||
export type LogOperation =
|
||||
| 'stop'
|
||||
| 'restart'
|
||||
@ -62,6 +85,11 @@ export interface LogSchema extends BaseSchema {
|
||||
* 一些可操作选项
|
||||
*/
|
||||
operation?: Array<LogOperation>;
|
||||
|
||||
/**
|
||||
* credentials 配置
|
||||
*/
|
||||
credentials?: string;
|
||||
}
|
||||
|
||||
export interface LogProps
|
||||
@ -179,14 +207,10 @@ export class Log extends React.Component<LogProps, LogState> {
|
||||
filterWord = (logs: string[], lastLine: string, word: string) => {
|
||||
let originLogs = logs;
|
||||
let originLastLine = lastLine;
|
||||
if (
|
||||
word !== '' &&
|
||||
word !== undefined &&
|
||||
word !== null &&
|
||||
word.length > 0) {
|
||||
if (word !== '' && word !== undefined && word !== null && word.length > 0) {
|
||||
logs = logs.filter(line => line.includes(word));
|
||||
if (!lastLine.includes(word)) {
|
||||
lastLine = "";
|
||||
lastLine = '';
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
@ -194,12 +218,20 @@ export class Log extends React.Component<LogProps, LogState> {
|
||||
lastLine: lastLine,
|
||||
logs: logs,
|
||||
originLogs: originLogs,
|
||||
originLastLine: originLastLine,
|
||||
originLastLine: originLastLine
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
async loadLogs() {
|
||||
const {source, data, env, translate: __, encoding, maxLength} = this.props;
|
||||
const {
|
||||
source,
|
||||
data,
|
||||
env,
|
||||
translate: __,
|
||||
encoding,
|
||||
maxLength,
|
||||
credentials = 'include'
|
||||
} = this.props;
|
||||
// 因为这里返回结果是流式的,和普通 api 请求不一样,如果直接用 fetcher 经过 responseAdaptor 可能会导致出错,所以就直接 fetch 了
|
||||
const api = buildApi(source, data);
|
||||
if (!api.url) {
|
||||
@ -209,7 +241,7 @@ export class Log extends React.Component<LogProps, LogState> {
|
||||
method: api.method?.toLocaleUpperCase() || 'GET',
|
||||
headers: (api.headers as Record<string, string>) || undefined,
|
||||
body: api.data ? JSON.stringify(api.data) : undefined,
|
||||
credentials: 'include'
|
||||
credentials: credentials as RequestCredentials
|
||||
});
|
||||
if (res.status === 200) {
|
||||
const body = res.body;
|
||||
@ -262,18 +294,46 @@ export class Log extends React.Component<LogProps, LogState> {
|
||||
}
|
||||
}
|
||||
|
||||
// 简单支持 ansi 颜色,只支持一行,不支持嵌套
|
||||
ansiColrToHtml(line: string) {
|
||||
const {disableColor} = this.props;
|
||||
if (disableColor === true) {
|
||||
return line;
|
||||
}
|
||||
const match = line.match(/\u001b\[([^m]+)m/);
|
||||
if (match) {
|
||||
const colorNumber = match[1];
|
||||
if (colorNumber) {
|
||||
line = line.replace(/\u001b[^m]*?m/g, '');
|
||||
if (colorNumber in foregroundColors) {
|
||||
return (
|
||||
<span style={{color: foregroundColors[colorNumber]}}>{line}</span>
|
||||
);
|
||||
} else if (colorNumber in backgroundColors) {
|
||||
return (
|
||||
<span style={{backgroundColor: backgroundColors[colorNumber]}}>
|
||||
{line.replace(/\u001b[^m]*?m/g, '')}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
renderHighlightWord(line: string) {
|
||||
const {classnames: cx} = this.props;
|
||||
let {filterWord} = this.state;
|
||||
if (filterWord === '') {
|
||||
return line;
|
||||
return this.ansiColrToHtml(line);
|
||||
}
|
||||
let items = line.split(filterWord);
|
||||
return items.map((item, index) => {
|
||||
if (index < items.length - 1) {
|
||||
return (
|
||||
<span>
|
||||
{item}
|
||||
{this.ansiColrToHtml(item)}
|
||||
<span className={cx('Log-line-highlight')}>{filterWord}</span>
|
||||
</span>
|
||||
);
|
||||
@ -404,7 +464,13 @@ export class Log extends React.Component<LogProps, LogState> {
|
||||
<SearchBox
|
||||
className={cx('Log-filter-box')}
|
||||
placeholder="过滤词"
|
||||
onChange={(value) => this.filterWord(this.state.originLogs, this.state.lastLine, value)}
|
||||
onChange={value =>
|
||||
this.filterWord(
|
||||
this.state.originLogs,
|
||||
this.state.lastLine,
|
||||
value
|
||||
)
|
||||
}
|
||||
value={this.state.filterWord}
|
||||
/>
|
||||
)}
|
||||
|
BIN
packages/ooxml-viewer/__tests__/xlsx/simple/init.xlsx
Normal file
BIN
packages/ooxml-viewer/__tests__/xlsx/simple/init.xlsx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user