add markdown option to logs page
parent
d2ae4ff300
commit
c7c2a57749
|
@ -991,6 +991,14 @@ ul {
|
|||
@media screen and (max-width: 974px) {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
.fa-2x {
|
||||
float: right;
|
||||
font-size: 1rem;
|
||||
color: $dark_gray;
|
||||
}
|
||||
.fa-ban {
|
||||
color: $medium_gray;
|
||||
}
|
||||
}
|
||||
|
||||
.logs-settings-menu {
|
||||
|
@ -1024,6 +1032,18 @@ ul {
|
|||
box-shadow: inset 1px 0 0 0 $gray !important;
|
||||
color: $dark_gray !important;
|
||||
word-break: break-word;
|
||||
.markdown {
|
||||
p {
|
||||
display: block;
|
||||
color: $dark_gray;
|
||||
font: inherit;
|
||||
font-size: inherit;
|
||||
text-overflow: inherit;
|
||||
overflow: inherit;
|
||||
width: inherit;
|
||||
white-space: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
td:nth-child(1),
|
||||
td:nth-child(4) {
|
||||
|
|
|
@ -156,4 +156,21 @@ describe("<Logs />", () => {
|
|||
wrapper.instance().setFilterLevel(MessageType.warn)(2);
|
||||
expect(wrapper.instance().state.warn).toEqual(2);
|
||||
});
|
||||
|
||||
it("toggles raw text display", () => {
|
||||
const wrapper = mount<Logs>(<Logs {...fakeProps()} />);
|
||||
expect(wrapper.state().markdown).toBeFalsy();
|
||||
wrapper.find(".fa-stack").simulate("click");
|
||||
expect(wrapper.state().markdown).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders formatted messages", () => {
|
||||
const p = fakeProps();
|
||||
p.logs[0].body.message = "`message`";
|
||||
const wrapper = mount<Logs>(<Logs {...p} />);
|
||||
expect(wrapper.state().markdown).toBeFalsy();
|
||||
expect(wrapper.html()).not.toContain("<code>message</code>");
|
||||
wrapper.setState({ markdown: true });
|
||||
expect(wrapper.html()).toContain("<code>message</code>");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ const logTypes = MESSAGE_TYPES;
|
|||
|
||||
describe("<LogsFilterMenu />", () => {
|
||||
const fakeState: LogsState = {
|
||||
autoscroll: true, success: 1, busy: 1, warn: 1,
|
||||
autoscroll: true, markdown: false, success: 1, busy: 1, warn: 1,
|
||||
error: 1, info: 1, fun: 1, debug: 1, assertion: 1,
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,8 @@ describe("<LogsFilterMenu />", () => {
|
|||
const wrapper = mount(<LogsFilterMenu {...fakeProps()} />);
|
||||
logTypes.filter(x => x !== "assertion").map(string =>
|
||||
expect(wrapper.text().toLowerCase()).toContain(string.toLowerCase()));
|
||||
expect(wrapper.text().toLowerCase()).not.toContain("autoscroll");
|
||||
["autoscroll", "markdown"].map(string =>
|
||||
expect(wrapper.text().toLowerCase()).not.toContain(string));
|
||||
});
|
||||
|
||||
it("renders new types", () => {
|
||||
|
@ -33,7 +34,8 @@ describe("<LogsFilterMenu />", () => {
|
|||
const wrapper = mount(<LogsFilterMenu {...p} />);
|
||||
logTypes.map(string =>
|
||||
expect(wrapper.text().toLowerCase()).toContain(string.toLowerCase()));
|
||||
expect(wrapper.text().toLowerCase()).not.toContain("autoscroll");
|
||||
["autoscroll", "markdown"].map(string =>
|
||||
expect(wrapper.text().toLowerCase()).not.toContain(string));
|
||||
});
|
||||
|
||||
it("filters logs", () => {
|
||||
|
|
|
@ -28,7 +28,7 @@ const menuSort = (a: string, b: string) =>
|
|||
export const filterStateKeys =
|
||||
(state: LogsState, shouldDisplay: ShouldDisplay) =>
|
||||
Object.keys(state)
|
||||
.filter(key => key !== "autoscroll")
|
||||
.filter(key => !["autoscroll", "markdown"].includes(key))
|
||||
.filter(key => shouldDisplay(Feature.assertion_block)
|
||||
|| key !== "assertion");
|
||||
|
||||
|
|
|
@ -7,10 +7,12 @@ import { isNumber, startCase } from "lodash";
|
|||
import { t } from "../../i18next_wrapper";
|
||||
import { TimeSettings } from "../../interfaces";
|
||||
import { UUID } from "../../resources/interfaces";
|
||||
import { Markdown } from "../../ui";
|
||||
|
||||
interface LogsRowProps {
|
||||
tlog: TaggedLog;
|
||||
dispatch: Function;
|
||||
markdown: boolean;
|
||||
timeSettings: TimeSettings;
|
||||
}
|
||||
|
||||
|
@ -37,7 +39,7 @@ const LogVerbositySaucer = (props: LogVerbositySaucerProps) =>
|
|||
</div>;
|
||||
|
||||
/** A log is displayed in a single row of the logs table. */
|
||||
const LogsRow = ({ tlog, timeSettings, dispatch }: LogsRowProps) => {
|
||||
const LogsRow = ({ tlog, timeSettings, dispatch, markdown }: LogsRowProps) => {
|
||||
const { uuid } = tlog;
|
||||
const { x, y, z, verbosity, type, created_at, message, id } = tlog.body;
|
||||
const time = formatLogTime(created_at || NaN, timeSettings);
|
||||
|
@ -48,7 +50,7 @@ const LogsRow = ({ tlog, timeSettings, dispatch }: LogsRowProps) => {
|
|||
{t(startCase(type))}
|
||||
</td>
|
||||
<td>
|
||||
{message || t("Loading")}
|
||||
{markdown ? <Markdown>{message}</Markdown> : message || t("Loading")}
|
||||
</td>
|
||||
<td>
|
||||
{xyzTableEntry(x, y, z)}
|
||||
|
@ -83,6 +85,7 @@ export const LogsTable = (props: LogsTableProps) => {
|
|||
key={log.uuid}
|
||||
tlog={log}
|
||||
dispatch={props.dispatch}
|
||||
markdown={props.state.markdown}
|
||||
timeSettings={props.timeSettings} />)}
|
||||
</tbody>
|
||||
</table>;
|
||||
|
|
|
@ -50,6 +50,7 @@ export class Logs extends React.Component<LogsProps, Partial<LogsState>> {
|
|||
fun: this.initialize(NumericSetting.fun_log, 1),
|
||||
debug: this.initialize(NumericSetting.debug_log, 1),
|
||||
assertion: this.initialize(NumericSetting.assertion_log, 1),
|
||||
markdown: false,
|
||||
};
|
||||
|
||||
/** Toggle display of a log type. Verbosity level 0 hides all, 3 shows all.*/
|
||||
|
@ -113,6 +114,12 @@ export class Logs extends React.Component<LogsProps, Partial<LogsState>> {
|
|||
setFilterLevel={this.setFilterLevel} />
|
||||
</Popover>
|
||||
</div>
|
||||
<div className="fa-stack fa-2x"
|
||||
title={this.state.markdown ? t("display raw") : t("display markdown")}
|
||||
onClick={() => this.setState({ markdown: !this.state.markdown })}>
|
||||
<i className="fa fa-font fa-stack-1x" />
|
||||
{this.state.markdown && <i className="fa fa-ban fa-stack-2x" />}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
|
|
|
@ -16,6 +16,7 @@ export type Filters = Record<ALLOWED_MESSAGE_TYPES, number>;
|
|||
|
||||
export interface LogsState extends Filters {
|
||||
autoscroll: boolean;
|
||||
markdown: boolean;
|
||||
}
|
||||
|
||||
export interface LogsTableProps {
|
||||
|
|
Loading…
Reference in New Issue