diff --git a/scm-ui/ui-components/src/repos/DiffExpander.test.ts b/scm-ui/ui-components/src/repos/DiffExpander.test.ts index 37f7e825ef..b97609299e 100644 --- a/scm-ui/ui-components/src/repos/DiffExpander.test.ts +++ b/scm-ui/ui-components/src/repos/DiffExpander.test.ts @@ -239,6 +239,18 @@ describe("with hunks the diff expander", () => { expect(newFile.hunks[1].changes[5].oldLineNumber).toBe(14); expect(newFile.hunks[1].changes[5].newLineNumber).toBe(14); }); + it("should set fully expanded to true if expanded completely", async () => { + fetchMock.get( + "http://localhost:8081/scm/api/v2/content/abc/CommitMessage.js?start=40&end=50", + "new line 40\nnew line 41\nnew line 42" + ); + let newFile; + diffExpander.getHunk(3).expandBottom(10, file => { + newFile = file; + }); + await fetchMock.flush(true); + expect(newFile.hunks[3].fullyExpanded).toBe(true); + }); }); describe("for a new file with text input the diff expander", () => { diff --git a/scm-ui/ui-components/src/repos/DiffExpander.ts b/scm-ui/ui-components/src/repos/DiffExpander.ts index 779c43c27c..3dfd91a738 100644 --- a/scm-ui/ui-components/src/repos/DiffExpander.ts +++ b/scm-ui/ui-components/src/repos/DiffExpander.ts @@ -61,7 +61,7 @@ class DiffExpander { if (this.file.type === "add" || this.file.type === "delete") { return 0; } else if (n === this.file!.hunks!.length - 1) { - return Number.MAX_SAFE_INTEGER; + return this.file!.hunks![this.file!.hunks!.length - 1].fullyExpanded ? 0 : Number.MAX_SAFE_INTEGER; } return this.minLineNumber(n + 1) - this.maxLineNumber(n) - 1; }; @@ -85,7 +85,7 @@ class DiffExpander { .get(lineRequestUrl) .then(response => response.text()) .then(text => text.split("\n")) - .then(lines => this.expandHunkAtBottom(n, lines, callback)); + .then(lines => this.expandHunkAtBottom(n, count, lines, callback)); }; expandHunkAtHead = (n: number, lines: string[], callback: (newFile: File) => void) => { @@ -130,7 +130,7 @@ class DiffExpander { callback(newFile); }; - expandHunkAtBottom = (n: number, lines: string[], callback: (newFile: File) => void) => { + expandHunkAtBottom = (n: number, requestedLines: number, lines: string[], callback: (newFile: File) => void) => { const hunk = this.file.hunks![n]; if (lines[lines.length - 1] === "") { lines.pop(); @@ -155,7 +155,8 @@ class DiffExpander { ...hunk, oldLines: hunk.oldLines + lines.length, newLines: hunk.newLines + lines.length, - changes: newChanges + changes: newChanges, + fullyExpanded: lines.length < requestedLines }; const newHunks: Hunk[] = []; this.file.hunks.forEach((oldHunk: Hunk, i: number) => { diff --git a/scm-ui/ui-components/src/repos/DiffFile.tsx b/scm-ui/ui-components/src/repos/DiffFile.tsx index 0ae70c764b..88f62cfecf 100644 --- a/scm-ui/ui-components/src/repos/DiffFile.tsx +++ b/scm-ui/ui-components/src/repos/DiffFile.tsx @@ -211,6 +211,25 @@ class DiffFile extends React.Component { return ; }; + createLastHunkFooter = (expandableHunk: ExpandableHunk) => { + if (expandableHunk.maxExpandBottomRange > 0) { + return ( + + + expandableHunk.expandBottom(10, this.diffExpanded)}> + {this.props.t("diff.expandLastBottomByLines")} + {" "} + expandableHunk.expandBottom(expandableHunk.maxExpandBottomRange, this.diffExpanded)}> + {this.props.t("diff.expandLastBottomComplete")} + + + + ); + } + // hunk header must be defined + return ; + }; + collectHunkAnnotations = (hunk: HunkType) => { const { annotationFactory } = this.props; const { file } = this.state; @@ -267,7 +286,11 @@ class DiffFile extends React.Component { /> ); if (file._links?.lines) { - items.push(this.createHunkFooter(expandableHunk)); + if (i === file.hunks!.length - 1) { + items.push(this.createLastHunkFooter(expandableHunk)); + } else { + items.push(this.createHunkFooter(expandableHunk)); + } } return items; }; diff --git a/scm-ui/ui-components/src/repos/DiffTypes.ts b/scm-ui/ui-components/src/repos/DiffTypes.ts index 56d225d85f..54fb642e61 100644 --- a/scm-ui/ui-components/src/repos/DiffTypes.ts +++ b/scm-ui/ui-components/src/repos/DiffTypes.ts @@ -57,6 +57,7 @@ export type Hunk = { newStart?: number; oldLines?: number; newLines?: number; + fullyExpanded?: boolean; }; export type ChangeType = "insert" | "delete" | "normal" | "conflict"; diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index 53d1de79b7..fa97c7d6cf 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -206,7 +206,9 @@ "expandBottomByLines": "> load {{count}} more line", "expandBottomByLines_plural": "> load {{count}} more lines", "expandBottomComplete": ">> load {{count}} line", - "expandBottomComplete_plural": ">> load all {{count}} lines" + "expandBottomComplete_plural": ">> load all {{count}} lines", + "expandLastBottomByLines": "> load up to 10 more lines", + "expandLastBottomComplete": ">> load all remaining lines" }, "fileUpload": { "clickHere": "Click here to select your file",