Skip to content

Commit

Permalink
Merge 6628c55 into 191e184
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyanziano committed Jul 24, 2018
2 parents 191e184 + 6628c55 commit 2f95628
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 18 deletions.
25 changes: 20 additions & 5 deletions packages/app/client/src/ui/editor/emulator/parts/log/log.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@
height: 100%;
overflow: auto;
user-select: text;
padding: 0 16px 0 16px;
padding: 0;
box-sizing: border-box;

& > .entry {
padding: 0 16px;
font-family: var(--monospace-font-family);
cursor: pointer;

&:hover {
background-color: var(--log-panel-entry-hover-bg);
}

&.inspected {
background-color: var(--log-panel-entry-inspected-bg);
}

& > .source {
color: var(--neutral-6);
}
Expand All @@ -26,19 +38,22 @@

// info
& .level0 {
color: var(--neutral-16);
color: var(--log-panel-item-info);
}

// debug
& .level1 {
color: var(--neutral-7);
color: var(--log-panel-item-debug);
}

// warn
& .level2 {
color: var(--warning-outline);
color: var(--log-panel-item-warn);
}

// error
& .level3 {
color: var(--error-text);
color: var(--log-panel-item-error);
}

& .spaced {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is a generated file. Changes are likely to result in being overwritten
export const log: string;
export const entry: string;
export const inspected: string;
export const source: string;
export const timestamp: string;
export const srcDst: string;
Expand Down
139 changes: 127 additions & 12 deletions packages/app/client/src/ui/editor/emulator/parts/log/log.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import store from '../../../../../data/store';
import { ExtensionManager, InspectorAPI } from '../../../../../extensions';
import { LogEntry, LogItem, LogLevel, SharedConstants } from '@bfemulator/app-shared';
import { CommandServiceImpl } from '../../../../../platform/commands/commandServiceImpl';
import { Subscription } from 'rxjs';

function number2(n: number) {
return ('0' + n).slice(-2);
Expand Down Expand Up @@ -67,6 +68,14 @@ function logLevelToClassName(level: LogLevel): string {
}
}

/** One of these will always be "nexted" to the selectedActivity$
* subscription when called from within the log
*/
export interface ActivitySelectionFromLog {
/** Differentiates between just hovering an activity or clicking to inspect */
clicked: boolean;
}

export interface LogProps {
document: any;
}
Expand All @@ -76,7 +85,10 @@ export interface LogState {
}

export default class Log extends React.Component<LogProps, LogState> {
scrollMe: Element;
public scrollMe: Element;
public selectedActivitySubscription: Subscription;
public selectedActivity: any;
public currentlyInspectedActivity: any;

constructor(props: LogProps, context: LogState) {
super(props, context);
Expand All @@ -86,21 +98,57 @@ export default class Log extends React.Component<LogProps, LogState> {
}

componentDidUpdate(): void {
if (this.props.document.log.entries.length !== this.state.count) {
this.scrollMe.scrollTop = this.scrollMe.scrollHeight;
let { props, scrollMe, selectedActivitySubscription, state } = this;
// set up selected activity subscription once it's available
if (props.document && props.document.selectedActivity$ && !selectedActivitySubscription) {
selectedActivitySubscription =
props.document.selectedActivity$.subscribe(obj => {
if (obj) {
if (obj.activity) {
// this activity came from webchat (activities from webchat are wrapped)
// ex: { activity: { id: , from: , ... } }
const { activity } = obj;
this.selectedActivity = activity;
this.currentlyInspectedActivity = activity;
} else {
// this activity came from the log (activities from the log are raw)
// ex: { id: , from: , to: , ... }
const activity = obj;
this.selectedActivity = activity;
const { fromLog = {} } = activity;
// check if it was clicked or hovered
const { clicked } = fromLog;
if (clicked) {
this.currentlyInspectedActivity = activity;
}
}
}
});
}
if (props.document.log.entries.length !== state.count) {
scrollMe.scrollTop = scrollMe.scrollHeight;
this.setState({
count: this.props.document.log.entries.length
count: props.document.log.entries.length
});
}
}

componentWillUnmount(): void {
// clean up activity subscription
if (this.selectedActivitySubscription) {
this.selectedActivitySubscription.unsubscribe();
}
}

render() {
let key = 0;
return (
<div className={ styles.log } ref={ ref => this.scrollMe = ref }>
{
this.props.document.log.entries.map(entry =>
<LogEntryComponent key={ `entry-${key++}` } entry={ entry } document={ this.props.document }/>
<LogEntryComponent key={ `entry-${key++}` } entry={ entry } document={ this.props.document }
selectedActivity={ this.selectedActivity }
currentlyInspectedActivity={ this.currentlyInspectedActivity }/>
)
}
</div>
Expand All @@ -111,27 +159,87 @@ export default class Log extends React.Component<LogProps, LogState> {
export interface LogEntryProps {
document: any;
entry: LogEntry;
selectedActivity?: any;
currentlyInspectedActivity?: any;
}

class LogEntryComponent extends React.Component<LogEntryProps> {
/** Allows <LogEntry />'s to highlight themselves based on their log item children */
private inspectableObjects: { [id: string]: boolean };

/** Sends obj to the inspector panel
* @param obj Can be a conversation activity or network request
*/
inspect(obj: {}) {
this.props.document.selectedActivity$.next({});
const fromLog: ActivitySelectionFromLog = { clicked: true };
this.props.document.selectedActivity$.next({ fromLog });
store.dispatch(ChatActions.setInspectorObjects(this.props.document.documentId, obj));
}

inspectAndHighlight(obj: any) {
/** Sends obj to the inspector panel and highlights the activity in Webchat
* (triggered by click in log)
* @param obj Conversation activity to be highlighted in the WebChat control
*/
inspectAndHighlightInWebchat(obj: any) {
this.inspect(obj);
if (obj.id) {
this.props.document.selectedActivity$.next(obj);
const fromLog: ActivitySelectionFromLog = { clicked: true };
this.props.document.selectedActivity$.next({ ...obj, fromLog });
}
}

/** Highlights an activity in webchat (triggered by hover in log) */
highlightInWebchat(obj: any) {
if (obj.id) {
const fromLog: ActivitySelectionFromLog = { clicked: false };
this.props.document.selectedActivity$.next({ ...obj, fromLog });
}
}

/** Removes an activity's highlighting in webchat */
removeHighlightInWebchat(obj: any) {
if (obj.id) {
// re-highlight last-selected activity if possible
const { currentlyInspectedActivity } = this.props;
if (currentlyInspectedActivity && currentlyInspectedActivity.id) {
const fromLog: ActivitySelectionFromLog = { clicked: true };
this.props.document.selectedActivity$.next({
...currentlyInspectedActivity,
fromLog
});
} else {
const fromLog: ActivitySelectionFromLog = { clicked: false };
this.props.document.selectedActivity$.next({ fromLog });
}
}
}

render() {
return (
<div key="entry" className={ styles.entry }>
// reset the inspectable objects lookup
this.inspectableObjects = {};

// render the timestamp and any items to be displayed within the entry;
// any rendered inspectable items will add themselves to this.inspectableObjects
const innerJsx = (
<>
{ this.renderTimestamp(this.props.entry.timestamp) }
{ this.props.entry.items.map((item, key) => this.renderItem(item, '' + key)) }
</>
);

// if the currently selected activity matches any of this item's inner inspectable
// objects, append an 'inspected' class name to the log entry to highlight it
const { currentlyInspectedActivity } = this.props;
let inspectedActivityClass = '';
if (currentlyInspectedActivity && currentlyInspectedActivity.id) {
if (this.inspectableObjects[currentlyInspectedActivity.id]) {
inspectedActivityClass = styles.inspected;
}
}

return (
<div key="entry" className={[styles.entry, inspectedActivityClass].join(' ')}>
{ innerJsx }
</div>
);
}
Expand Down Expand Up @@ -213,15 +321,22 @@ class LogEntryComponent extends React.Component<LogEntryProps> {
}

renderInspectableItem(obj: any, key: string) {
// add self to inspectable object lookup
if (obj.id) {
this.inspectableObjects[obj.id] = true;
}

let title = 'inspect';
if (typeof obj.type === 'string') {
title = obj.type;
}
let summaryText = this.summaryText(obj) || '';
return (
<span key={ key }>
<span key={ key }
onMouseOver={ () => this.highlightInWebchat(obj) }
onMouseLeave={ () => this.removeHighlightInWebchat(obj) }>
<span className={ `${styles.spaced} ${styles.level0}` }>
<a onClick={ () => this.inspectAndHighlight(obj) }>{ title }</a>
<a onClick={ () => this.inspectAndHighlightInWebchat(obj) }>{ title }</a>
</span>
<span className={ `${styles.spaced} ${styles.level0}` }>
{ summaryText }
Expand Down
6 changes: 6 additions & 0 deletions packages/app/client/src/ui/styles/themes/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ html {
/* Log panel custom colors */
--log-panel-timestamp: #47B07F;
--log-panel-link: #9CDCFE;
--log-panel-entry-hover-bg: var(--neutral-9);
--log-panel-entry-inspected-bg: var(--neutral-10);
--log-panel-item-info: var(--neutral-2);
--log-panel-item-debug: var(--neutral-5);
--log-panel-item-warn: var(--warning-outline);
--log-panel-item-error: var(--error-text);

/* nav bar custom colors */
--nav-bar-bg: var(--neutral-13);
Expand Down
6 changes: 6 additions & 0 deletions packages/app/client/src/ui/styles/themes/high-contrast.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ html {
/* Log panel custom colors */
--log-panel-timestamp: #47B07F;
--log-panel-link: #9CDCFE;
--log-panel-entry-hover-bg: var(--neutral-10);
--log-panel-entry-inspected-bg: var(--neutral-8);
--log-panel-item-info: var(--neutral-1);
--log-panel-item-debug: var(--neutral-6);
--log-panel-item-warn: var(--warning-outline);
--log-panel-item-error: var(--error-text);

/* nav bar custom colors */
--nav-bar-bg: var(--neutral-16);
Expand Down
6 changes: 6 additions & 0 deletions packages/app/client/src/ui/styles/themes/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ html {
/* Log panel custom colors */
--log-panel-timestamp: #47B07F;
--log-panel-link: #007acc;
--log-panel-entry-hover-bg: var(--neutral-4);
--log-panel-entry-inspected-bg: var(--neutral-5);
--log-panel-item-info: var(--neutral-16);
--log-panel-item-debug: var(--neutral-7);
--log-panel-item-warn: var(--warning-outline);
--log-panel-item-error: var(--error-text);

/* nav bar custom colors */
--nav-bar-bg: var(--neutral-15);
Expand Down
2 changes: 1 addition & 1 deletion packages/app/client/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const defaultConfig = {
sass: false,
namedExport: true,
sourcemaps: true,
camelCase: true,
banner: '// This is a generated file. Changes are likely to result in being overwritten'
}
},
Expand Down Expand Up @@ -204,4 +205,3 @@ module.exports = function (env, argv) {
return buildConfig(argv.mode);
}
};

0 comments on commit 2f95628

Please sign in to comment.