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

perf(Component UI): lazy load component logs #7346

Draft
wants to merge 26 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1501d14
lazy load component logs
luvkapur May 1, 2023
eea4fd1
Merge branch 'master' into ui/lazy-load-logs
GiladShoham May 2, 2023
bcc9af0
Merge branch 'master' into ui/lazy-load-logs
GiladShoham May 2, 2023
c1aff40
simplify lazily fetching component logs
luvkapur May 2, 2023
adb8e7a
Merge remote-tracking branch 'origin/master' into ui/lazy-load-logs
luvkapur May 2, 2023
28d6c8f
lazy load version in version dropdown
luvkapur May 2, 2023
3ae0466
import code view
luvkapur May 2, 2023
7a0f346
lazy load snaps and tags separately in a single query + optimize comp…
luvkapur May 3, 2023
c6b8491
lazy load versions until dropdown is opened
luvkapur May 4, 2023
e61fac9
fix component compare to lazy load
luvkapur May 4, 2023
a1e492b
fix tests
luvkapur May 5, 2023
239adc2
fix loader - when lazy loading versions
luvkapur May 8, 2023
2ae24b0
query from head when on a version + fix loading state
luvkapur May 9, 2023
f7679a1
Merge remote-tracking branch 'origin/master' into ui/lazy-load-logs
luvkapur May 11, 2023
9e14c51
refator getLogs to allow fetching versions with advanced filters
luvkapur May 12, 2023
1fa4b10
clean up
luvkapur May 12, 2023
93c92d6
lint fix
luvkapur May 12, 2023
ae77ed8
fix updating offset while lazy loading
luvkapur May 12, 2023
72b64f2
allow lazy loading by type
luvkapur May 15, 2023
9027cd6
fix lazy loading backwards
luvkapur May 16, 2023
b95d6e4
refactor: extract to useComponentLogs
luvkapur May 16, 2023
3516bf5
clean up
luvkapur May 16, 2023
2c1ebd1
clean up
luvkapur May 16, 2023
09acbaf
clean up
luvkapur May 16, 2023
46ba4ba
fix handling getting logs for lane components without head filter
luvkapur May 17, 2023
5007b17
Merge branch 'master' into ui/lazy-load-logs
luvkapur May 17, 2023
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 .bitmap
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,12 @@
"mainFile": "index.ts",
"rootDir": "scopes/code/ui/code-tab-tree"
},
"ui/code-view": {
"scope": "teambit.code",
"version": "5e2b49420c500d4d88e1b05aa232061abc0fa0a7",
"mainFile": "index.ts",
"rootDir": "components/ui/code-view"
},
"ui/compare/lane-compare": {
"scope": "teambit.lanes",
"version": "0.0.84",
Expand Down
44 changes: 44 additions & 0 deletions components/ui/code-view/code-view.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.codeView {
padding: 24px 40px;
width: 100%;
overflow: hidden;
box-sizing: border-box;

.codeSnippetWrapper {
width: 100%;
max-width: 100%;
.codeSnippet {
display: block;
overflow: auto;
height: calc(100vh - 200px);
> code {
> code {
// this is to design the line numbers culumn
border-right: 1px solid #323232;
padding-right: 16px !important;
margin-right: 16px;
}
}
}
// TODO - fix this in code snippet component. it breaks when the component renders in different places
> span {
top: 13px !important;
}
}
}

.img {
width: 20px;
margin-right: 10px;
}

.fileName {
display: flex;
align-items: baseline;
}

.emptyCodeView {
margin: auto;
text-align: center;
font-size: 24px;
}
76 changes: 76 additions & 0 deletions components/ui/code-view/code-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { H1 } from '@teambit/documenter.ui.heading';
import classNames from 'classnames';
import React, { HTMLAttributes, useMemo } from 'react';
import { CodeSnippet } from '@teambit/documenter.ui.code-snippet';
import { useFileContent } from '@teambit/code.ui.queries.get-file-content';
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light';
import markDownSyntax from 'react-syntax-highlighter/dist/esm/languages/prism/markdown';
import { staticStorageUrl } from '@teambit/base-ui.constants.storage';
import { ComponentID } from '@teambit/component';
import styles from './code-view.module.scss';

export type CodeViewProps = {
componentId: ComponentID;
currentFile?: string;
currentFileContent?: string;
icon?: string;
loading?: boolean;
codeSnippetClassName?: string;
} & HTMLAttributes<HTMLDivElement>;

SyntaxHighlighter.registerLanguage('md', markDownSyntax);

export function CodeView({
className,
componentId,
currentFile,
icon,
currentFileContent,
codeSnippetClassName,
loading: loadingFromProps,
}: CodeViewProps) {
const { fileContent: downloadedFileContent, loading: loadingFileContent } = useFileContent(
componentId,
currentFile,
!!currentFileContent
);
const loading = loadingFromProps || loadingFileContent;
const fileContent = currentFileContent || downloadedFileContent;
const title = useMemo(() => currentFile?.split('/').pop(), [currentFile]);
const lang = useMemo(() => {
const langFromFileEnding = currentFile?.split('.').pop();

// for some reason, SyntaxHighlighter doesnt support scss or sass highlighting, only css. I need to check how to fix this properly
if (langFromFileEnding === 'scss' || langFromFileEnding === 'sass') return 'css';
if (langFromFileEnding === 'mdx') return 'md';
return langFromFileEnding;
}, [fileContent]);

if (!fileContent && !loading && currentFile) return <EmptyCodeView />;

return (
<div className={classNames(styles.codeView, className)}>
<H1 size="sm" className={styles.fileName}>
{currentFile && <img className={styles.img} src={icon} />}
<span>{title}</span>
</H1>
<CodeSnippet
className={styles.codeSnippetWrapper}
frameClass={classNames(styles.codeSnippet, codeSnippetClassName)}
showLineNumbers
language={lang}
>
{fileContent || ''}
</CodeSnippet>
</div>
);
}

function EmptyCodeView() {
return (
<div className={styles.emptyCodeView}>
<img src={`${staticStorageUrl}/harmony/empty-code-view.svg`} />
<div>Nothing to show</div>
</div>
);
}
2 changes: 2 additions & 0 deletions components/ui/code-view/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { CodeView } from './code-view';
export type { CodeViewProps } from './code-view';
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,27 @@ export function ComponentCompare(props: ComponentCompareProps) {
component: base,
loading: loadingBase,
componentDescriptor: baseComponentDescriptor,
} = useComponent(host, baseId.toString(), { customUseComponent });
} = useComponent(host, baseId.toString(), {
customUseComponent,
logFilters: {
log: {
logLimit: 3,
},
},
});

const {
component: compareComponent,
loading: loadingCompare,
componentDescriptor: compareComponentDescriptor,
} = useComponent(host, _compareId?.toString() || '', {
skip: !_compareId,
customUseComponent,
logFilters: {
log: {
logLimit: 3,
},
},
});

const loading = loadingBase || loadingCompare;
Expand Down Expand Up @@ -170,7 +183,11 @@ function RenderCompareScreen(props: ComponentCompareProps) {
return (
<>
{showVersionPicker && (
<div className={styles.top}>{state?.versionPicker?.element || <ComponentCompareVersionPicker />}</div>
<div className={styles.top}>
{state?.versionPicker?.element || (
<ComponentCompareVersionPicker host={props.host} customUseComponent={props.customUseComponent} />
)}
</div>
)}
<div className={styles.bottom}>
<CompareMenuNav {...props} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,57 @@
import React, { HTMLAttributes, useMemo } from 'react';
import { DropdownComponentVersion, VersionDropdown } from '@teambit/component.ui.version-dropdown';
import React, { HTMLAttributes } from 'react';
import { VersionDropdown } from '@teambit/component.ui.version-dropdown';
import { useUpdatedUrlFromQuery } from '@teambit/component.ui.component-compare.hooks.use-component-compare-url';
import { useComponentCompare } from '@teambit/component.ui.component-compare.context';
import { UseComponentType, useComponent } from '@teambit/component';
import classNames from 'classnames';

import styles from './component-compare-version-picker.module.scss';

export type ComponentCompareVersionPickerProps = {} & HTMLAttributes<HTMLDivElement>;
export type ComponentCompareVersionPickerProps = {
customUseComponent?: UseComponentType;
host: string;
} & HTMLAttributes<HTMLDivElement>;

export function ComponentCompareVersionPicker({ className }: ComponentCompareVersionPickerProps) {
export function ComponentCompareVersionPicker({
className,
host,
customUseComponent,
}: ComponentCompareVersionPickerProps) {
const componentCompare = useComponentCompare();
const compare = componentCompare?.compare?.model;

const logs =
(compare?.logs || []).filter((log) => {
const version = log.tag || log.hash;
return componentCompare?.compare?.hasLocalChanges || version !== compare?.id.version;
}) || [];

const [tags, snaps] = useMemo(() => {
return (logs || []).reduce(
([_tags, _snaps], log) => {
if (!log.tag) {
_snaps.push({ ...log, version: log.hash });
} else {
_tags.push({ ...log, version: log.tag as string });
}
return [_tags, _snaps];
const componentId = compare?.id.toString();
const componentWithLogsOptions = {
logFilters: {
snapLog: {
logLimit: 10,
},
[new Array<DropdownComponentVersion>(), new Array<DropdownComponentVersion>()]
);
}, [logs]);
tagLog: {
logLimit: 10,
},
fetchLogsByTypeSeparately: true,
},
customUseComponent,
};

const useVersions = () => {
const { componentLogs = {}, loading: loadingLogs } = useComponent(host, componentId, componentWithLogsOptions);
return {
loading: loadingLogs,
...componentLogs,
snaps: (componentLogs.snaps || [])
.map((snap) => ({ ...snap, version: snap.hash }))
.filter((log) => {
const version = log.tag || log.hash;
return componentCompare?.compare?.hasLocalChanges || version !== compare?.id.version;
}),
tags: (componentLogs.tags || [])
.map((tag) => ({ ...tag, version: tag.tag as string }))
.filter((log) => {
const version = log.tag || log.hash;
return componentCompare?.compare?.hasLocalChanges || version !== compare?.id.version;
}),
};
};

const compareVersion = componentCompare?.compare?.hasLocalChanges ? 'workspace' : compare?.version;

Expand All @@ -47,24 +68,22 @@ export function ComponentCompareVersionPicker({ className }: ComponentCompareVer
dropdownClassName={styles.componentCompareDropdown}
placeholderClassName={styles.componentCompareVersionPlaceholder}
menuClassName={classNames(styles.componentCompareVersionMenu, styles.showMenuOverNav)}
snaps={snaps}
tags={tags}
currentVersion={baseVersion as string}
loading={componentCompare?.loading}
overrideVersionHref={(_baseVersion) => {
return useUpdatedUrlFromQuery({ baseVersion: _baseVersion });
}}
disabled={snaps.concat(tags).length < 2}
disabled={(compare?.logs?.length ?? 0) < 2}
hasMoreVersions={(compare?.logs?.length ?? 0) > 1}
showVersionDetails={true}
useComponentVersions={useVersions}
/>
<div className={styles.titleText}>with</div>
<VersionDropdown
className={classNames(styles.componentCompareVersionContainer, styles.right)}
dropdownClassName={styles.componentCompareDropdown}
placeholderClassName={styles.componentCompareVersionPlaceholder}
menuClassName={styles.componentCompareVersionMenu}
snaps={snaps}
tags={tags}
disabled={true}
loading={componentCompare?.loading}
currentVersion={compareVersion as string}
Expand Down
6 changes: 6 additions & 0 deletions components/ui/inputs/lane-selector/lane-placeholder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,25 @@ export type LanePlaceholderProps = {
selectedLaneId?: LaneId;
disabled?: boolean;
showScope?: boolean;
loading?: boolean;
} & HTMLAttributes<HTMLDivElement>;

export function LanePlaceholder({
selectedLaneId,
disabled,
className,
showScope = true,
loading,
...rest
}: LanePlaceholderProps) {
const laneIdStr = selectedLaneId?.isDefault()
? selectedLaneId.name
: (showScope && selectedLaneId?.toString()) || selectedLaneId?.name;

if (loading) {
return null;
}

return (
<div {...rest} className={classnames(styles.placeholder, className, disabled && styles.disabled)}>
<LaneIcon className={styles.icon} />
Expand Down
3 changes: 3 additions & 0 deletions components/ui/inputs/lane-selector/lane-selector-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function LaneSelectorList({
listNavigator,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
forceCloseOnEnter,
loading,
...rest
}: LaneSelectorListProps) {
const navigate = useNavigate();
Expand Down Expand Up @@ -156,6 +157,8 @@ export function LaneSelectorList({
}
}, [selectedLaneId?.toString()]);

if (loading) return null;

return (
<div {...rest} className={classnames(className, styles.laneSelectorList)}>
{groupByScope &&
Expand Down
9 changes: 8 additions & 1 deletion components/ui/inputs/lane-selector/lane-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type LaneSelectorProps = {
sortOptions?: LaneSelectorSortBy[];
scopeIconLookup?: Map<string, React.ReactNode>;
forceCloseOnEnter?: boolean;
loading?: boolean;
} & HTMLAttributes<HTMLDivElement>;

export type GroupedLaneDropdownItem = [scope: string, lanes: LaneModel[]];
Expand Down Expand Up @@ -61,6 +62,7 @@ export function LaneSelector(props: LaneSelectorProps) {
scopeIcon,
scopeIconLookup,
forceCloseOnEnter,
loading,
...rest
} = props;

Expand Down Expand Up @@ -235,7 +237,12 @@ export function LaneSelector(props: LaneSelectorProps) {
});
}}
placeholderContent={
<LanePlaceholder disabled={!multipleLanes} selectedLaneId={selectedLaneId} showScope={groupByScope} />
<LanePlaceholder
loading={loading}
disabled={!multipleLanes}
selectedLaneId={selectedLaneId}
showScope={groupByScope}
/>
}
className={classnames(styles.dropdown, !multipleLanes && styles.disabled)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,12 @@
flex: 0;
width: 36px;
}

.loader {
color: var(--bit-bg-dent, #f6f6f6);
padding: 4px 0px;

> span {
padding: 8px;
}
}
Loading