Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Highlighting in SCM Tree #8929

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

- [plugin] added `createDeployQuickOpenItem` method to create `DeployQuickOpenItem` in order to make extension deploy command extensible [#8919] (https://github.com/eclipse-theia/theia/pull/8919)
- [dependencies] updated to use fixed versions when publishing, `"x.y.z"` instead of `"^x.y.z"` in dependencies [#8880](https://github.com/eclipse-theia/theia/pull/8880)
- [scm] update code required to highlight nodes on search in the `ScmTreeWidget` [#8929](https://github.com/eclipse-theia/theia/pull/8929)

<a name="breaking_changes_1.10.0">[Breaking Changes:](#breaking_changes_1.10.0)</a>

- [scm] add `caption` field to `ScmTreeWidget.Props` interface. Remove `name` from `ScmResourceComponent.Props`, `groupLabel` from `ScmResourceGroupComponent.Props`, and `path` from `ScmResourceFolderElement.Props` interfaces. [#8929](https://github.com/eclipse-theia/theia/pull/8929)


## v1.9.0 - 16/12/2020

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/browser/tree/tree-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -608,10 +608,10 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
backgroundColor: highlight.backgroundColor
};
}
const createChildren = (fragment: TreeDecoration.CaptionHighlight.Fragment) => {
const createChildren = (fragment: TreeDecoration.CaptionHighlight.Fragment, index: number) => {
colin-grant-work marked this conversation as resolved.
Show resolved Hide resolved
const { data } = fragment;
if (fragment.highlight) {
return <mark className={TreeDecoration.Styles.CAPTION_HIGHLIGHT_CLASS} style={style}>{data}</mark>;
return <mark className={TreeDecoration.Styles.CAPTION_HIGHLIGHT_CLASS} style={style} key={index}>{data}</mark>;
} else {
return data;
}
Expand Down
15 changes: 12 additions & 3 deletions packages/scm/src/browser/scm-tree-label-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,27 @@ import { inject, injectable } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { LabelProviderContribution, LabelProvider } from '@theia/core/lib/browser/label-provider';
import { TreeNode } from '@theia/core/lib/browser/tree';
import { ScmFileChangeFolderNode, ScmFileChangeNode } from './scm-tree-model';
import { ScmFileChangeFolderNode, ScmFileChangeNode, ScmFileChangeGroupNode } from './scm-tree-model';

@injectable()
export class ScmTreeLabelProvider implements LabelProviderContribution {

@inject(LabelProvider) protected readonly labelProvider: LabelProvider;

canHandle(element: object): number {
return TreeNode.is(element) && (ScmFileChangeFolderNode.is(element) || ScmFileChangeNode.is(element)) ? 60 : 0;
return TreeNode.is(element) && (ScmFileChangeGroupNode.is(element) || ScmFileChangeFolderNode.is(element) || ScmFileChangeNode.is(element)) ? 60 : 0;
}

getName(node: ScmFileChangeFolderNode | ScmFileChangeNode): string {
return this.labelProvider.getName(new URI(node.sourceUri));
if (ScmFileChangeGroupNode.is(node)) {
return node.groupLabel;
}
if (ScmFileChangeFolderNode.is(node)) {
return node.path;
}
if (ScmFileChangeNode.is(node)) {
return this.labelProvider.getName(new URI(node.sourceUri));
}
return '';
}
}
33 changes: 18 additions & 15 deletions packages/scm/src/browser/scm-tree-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,25 @@ export class ScmTreeWidget extends TreeWidget {
}

const attributes = this.createNodeAttributes(node, props);
const label = this.labelProvider.getName(node);
const searchHighlights = this.searchHighlights?.get(node.id);
// The group nodes should not be subject to highlighting.
const caption = (searchHighlights && !ScmFileChangeGroupNode.is(node)) ? this.toReactNode(label, searchHighlights) : label;

if (ScmFileChangeGroupNode.is(node)) {
const content = <ScmResourceGroupElement
key={`${node.groupId}`}
model={this.model}
treeNode={node}
groupLabel={node.groupLabel}
renderExpansionToggle={() => this.renderExpansionToggle(node, props)}
contextMenuRenderer={this.contextMenuRenderer}
commands={this.commands}
menus={this.menus}
contextKeys={this.contextKeys}
labelProvider={this.labelProvider}
corePreferences={this.corePreferences} />;
corePreferences={this.corePreferences}
caption={caption}
/>;

return React.createElement('div', attributes, content);

Expand All @@ -113,20 +118,20 @@ export class ScmTreeWidget extends TreeWidget {
key={String(node.sourceUri)}
model={this.model}
treeNode={node}
path={node.path}
sourceUri={node.sourceUri}
renderExpansionToggle={() => this.renderExpansionToggle(node, props)}
contextMenuRenderer={this.contextMenuRenderer}
commands={this.commands}
menus={this.menus}
contextKeys={this.contextKeys}
labelProvider={this.labelProvider}
corePreferences={this.corePreferences} />;
corePreferences={this.corePreferences}
caption={caption}
/>;

return React.createElement('div', attributes, content);
}
if (ScmFileChangeNode.is(node)) {
const name = this.labelProvider.getName(new URI(node.sourceUri));
const parentPath =
(node.parent && ScmFileChangeFolderNode.is(node.parent))
? new URI(node.parent.sourceUri) : new URI(this.model.rootUri);
Expand All @@ -141,9 +146,9 @@ export class ScmTreeWidget extends TreeWidget {
contextKeys={this.contextKeys}
labelProvider={this.labelProvider}
corePreferences={this.corePreferences}
caption={caption}
{...{
...this.props,
name,
parentPath,
sourceUri: node.sourceUri,
decorations: node.decorations,
Expand Down Expand Up @@ -442,6 +447,7 @@ export namespace ScmTreeWidget {
labelProvider: LabelProvider;
contextMenuRenderer: ContextMenuRenderer;
corePreferences?: CorePreferences;
caption: React.ReactNode;
}
}

Expand Down Expand Up @@ -509,7 +515,7 @@ export class ScmResourceComponent extends ScmElement<ScmResourceComponent.Props>

render(): JSX.Element | undefined {
const { hover } = this.state;
const { name, model, treeNode, parentPath, sourceUri, decorations, labelProvider, commands, menus, contextKeys } = this.props;
const { model, treeNode, parentPath, sourceUri, decorations, labelProvider, commands, menus, contextKeys, caption } = this.props;
const resourceUri = new URI(sourceUri);

const icon = labelProvider.getIcon(resourceUri);
Expand All @@ -529,7 +535,7 @@ export class ScmResourceComponent extends ScmElement<ScmResourceComponent.Props>
<span className={icon + ' file-icon'} />
{this.props.renderExpansionToggle()}
<div className={`noWrapInfo ${TREE_NODE_SEGMENT_GROW_CLASS}`} >
<span className='name'>{name}</span>
<span className='name'>{caption}</span>
<span className='path'>{path}</span>
</div>
<ScmInlineActions {...{
Expand Down Expand Up @@ -607,7 +613,6 @@ export class ScmResourceComponent extends ScmElement<ScmResourceComponent.Props>
export namespace ScmResourceComponent {
export interface Props extends ScmElement.Props {
treeNode: ScmFileChangeNode;
name: string;
parentPath: URI;
sourceUri: string;
decorations?: ScmResourceDecorations;
Expand All @@ -618,14 +623,14 @@ export class ScmResourceGroupElement extends ScmElement<ScmResourceGroupComponen

render(): JSX.Element {
const { hover } = this.state;
const { model, treeNode, groupLabel, menus, commands, contextKeys } = this.props;
const { model, treeNode, menus, commands, contextKeys, caption } = this.props;
return <div className={`theia-header scm-theia-header ${TREE_NODE_SEGMENT_GROW_CLASS}`}
onContextMenu={this.renderContextMenu}
onMouseEnter={this.showHover}
onMouseLeave={this.hideHover}
ref={this.detectHover}>
{this.props.renderExpansionToggle()}
<div className={`noWrapInfo ${TREE_NODE_SEGMENT_GROW_CLASS}`}>{groupLabel}</div>
<div className={`noWrapInfo ${TREE_NODE_SEGMENT_GROW_CLASS}`}>{caption}</div>
<ScmInlineActions {...{
hover,
args: this.contextMenuArgs,
Expand Down Expand Up @@ -661,15 +666,14 @@ export class ScmResourceGroupElement extends ScmElement<ScmResourceGroupComponen
export namespace ScmResourceGroupComponent {
export interface Props extends ScmElement.Props {
treeNode: ScmFileChangeGroupNode;
groupLabel: string;
colin-grant-work marked this conversation as resolved.
Show resolved Hide resolved
}
}

export class ScmResourceFolderElement extends ScmElement<ScmResourceFolderElement.Props> {

render(): JSX.Element {
const { hover } = this.state;
const { model, treeNode, sourceUri, path, labelProvider, commands, menus, contextKeys } = this.props;
const { model, treeNode, sourceUri, labelProvider, commands, menus, contextKeys, caption } = this.props;
const sourceFileStat: FileStat = { uri: sourceUri, isDirectory: true, lastModification: 0 };
const icon = labelProvider.getIcon(sourceFileStat);

Expand All @@ -683,7 +687,7 @@ export class ScmResourceFolderElement extends ScmElement<ScmResourceFolderElemen
{this.props.renderExpansionToggle()}
<span className={icon + ' file-icon'} />
<div className={`noWrapInfo ${TREE_NODE_SEGMENT_GROW_CLASS}`} >
<span className='name'>{path}</span>
<span className='name'>{caption}</span>
</div>
<ScmInlineActions {...{
hover,
Expand Down Expand Up @@ -718,7 +722,6 @@ export namespace ScmResourceFolderElement {
export interface Props extends ScmElement.Props {
treeNode: ScmFileChangeFolderNode;
sourceUri: string;
path: string;
colin-grant-work marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down